5 Replies Latest reply on Jan 5, 2015 2:41 PM by Marc Autret

    Get the top left corner position?

    Stamm Level 1

      Hey guys,


      via geometricBounds[1] and geometricBounds[0] I can get the starting positions of my objects.


      In my case I need the top left corner position. When you rotate an object, the geometricBounds still reflect a bounding box so that I can't get the desired coordinates.


      How can I get the properties of the "starting points" (the top left corner of my Object)?


      Thank you really much!

        • 1. Re: Get the top left corner position?
          TᴀW Adobe Community Professional & MVP

          You're entering the complex ground of coordinate spaces here.


          Briefly, you can use resolve() to find any of the anchor points on an

          object. But you've got to decide in what coordinate space to get the



          Your best bet is probably to use Spread coordinates. The 0,0 point

          of that is the middle of the spread.


          So, given a pageItem i, try:


          i.resolve(AnchorPoint.TOP_LEFT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES);


          If you want to delve into this subject, Marc Autret has a good PDF guide

          about it.



          • 2. Re: Get the top left corner position?
            Stamm Level 1

            Hey, that did it for me! Your answer in combination with the guide from indiscripts( can be found here: http://www.indiscripts.com/blog/public/data/coordinate-spaces-and-transformations-1/Coordi nateSpacesTransfos01-02.pdf ).


            I now used i.resolve(AnchorPoint.TOP_LEFT_ANCHOR, CoordinateSpaces..pageCoordinates);


            Note: This will give you the coordinates of your object seen from the x = 0 , y = 0 coordinates of the page in POINTS. There are many sites in the web to convert this to other measurement units. I used this: Millimeters to Points (Computer) Conversion Calculator

            • 3. Re: Re: Get the top left corner position?
              Laubender Adobe Community Professional & MVP

              @Stamm – and there is UnitValue for this purpose:


              CS3 JS: UnitValue


              Here an example:


              //Input: 100 in points
              var myMillimetersValue = UnitValue(100, MeasurementUnits.POINTS).as(MeasurementUnits.MILLIMETERS);
              //Output: 35.2777777777778 in millimeters




              • 4. Re: Re: Get the top left corner position?
                Stamm Level 1

                Woah, all the time I just calculated MM. I feel stupid now.

                • 5. Re: Re: Get the top left corner position?
                  Marc Autret Level 5

                  Hi all,


                  Thanks for the mention :-)


                  However, I must clarify that bounding boxes and related topics have not been addressed yet. (Next chapters coming soon…)

                  So maybe it's the right place to bring some insights en primeur. In short, here is why Ariel's code does the job:


                  1. Although bounding boxes are not coordinate spaces in the strict sense, they provide additional coordinate systems (always related to coordinate spaces). A little known fact is that a given page item—say an Oval instance—has distinct bounding boxes depending on the coordinate space you consider along its hierarchy. Study the figure below. At a minimum, one can distinguish the inner space bounding box of the object (blue rectangle), and its spread-space-related bounding box (magenta).



                  So for the same object, there are as many distinct bounding boxes as coordinate spaces involved in the hierarchy: inner space, parent space(s)… spread (and page) space, and finally pasteboard space. Each bounding box reflects the orientation—in fact, the transformation state—of the coordinate space you consider. Two bounding boxes do not coincide as soon as the related coordinate spaces are connected through an affine map that contains some non trivial rotation and/or shearing parameter.


                  2. Another curious fact is, while InDesign's GUI shows the inner space bounding box of the selection (for a single object), the geometricBounds property always returns the coordinates of the pasteboard-related bounding box (which in most cases is equivalent to the spread-related bounding box). In addition, obj.geometricBounds returns the [top,left,bottom,right] values in a special coordinate system, the Ruler space system, which I will not explore here.


                  [To keep things simple, I just consider the basic situation depicted above—an oval rotated in its parent spread—and will handle coordinates in the pasteboard space, as already suggested.]


                  3. The PageItem.resolve() method has three parameters: location, inSpace, and consideringRulerUnits (optional). The most important one, location, has almost ten different forms (all are very poorly documented). Basically, location specify a point anywhere in any space. You can define as well a bounding box related location, a ruler space related location, or a coordinate space location. Here we only consider the first option. The full syntax of a bounding box location is as follows:

                  [ MyAnchorPoint, MyBoundingBoxLimits, MyCoordinateSpace ]


                  which means: "considering the bounding box relative to this coordinate space (3rd param), considering whether outer strokes are included or not in that box (2nd param), take this anchor point (1st param)."

                  Fortunately we have a shortcut: MyAnchorPoint alone is equivalent to [ MyAnchorPoint, BoundingBoxLimits.GEOMETRIC_PATH_BOUNDS, CoordinateSpaces.INNER_COORDINATES ]—that's the shortcut that Ariel uses.


                  Therefore, in the above figure:

                  • the location of the blue point is (fully encoded): [ AnchorPoint.TOP_LEFT_ANCHOR, BoundingBoxLimits.GEOMETRIC_PATH_BOUNDS, CoordinateSpaces.INNER_COORDINATES ]

                  • the location of the magenta point is: [ AnchorPoint.TOP_LEFT_ANCHOR, BoundingBoxLimits.GEOMETRIC_PATH_BOUNDS, CoordinateSpaces.SPREAD_COORDINATES ]


                  Finally, given a location, the inSpace parameter tells resolve() in which coordinate space that location must be expressed.


                  Now here is a simple code to check these rules:


                  // Assuming a pageitem is selected
                  // ---
                  var obj = app.selection[0];
                  // Boring constants
                  // ---
                  const AP_TOP_LEFT = +AnchorPoint.TOP_LEFT_ANCHOR,
                        BB_GEOMETRIC = +BoundingBoxLimits.GEOMETRIC_PATH_BOUNDS,
                        CS_SPREAD = +CoordinateSpaces.SPREAD_COORDINATES,
                        CS_INNER = +CoordinateSpaces.INNER_COORDINATES;
                  // Locations in the 'bounds space' format (full syntax)
                  // ---
                  var innerTopLeft = [AP_TOP_LEFT, BB_GEOMETRIC, CS_INNER],   // inner bbox corner
                      spreadTopLeft = [AP_TOP_LEFT, BB_GEOMETRIC, CS_SPREAD]; // spread-relative bbox corner
                  // Invoke resolve for both locations and
                  // return (x,y) results in spread coordinates
                  // ---
                  var xyInner = obj.resolve(innerTopLeft, CS_SPREAD)[0],
                      xySpread = obj.resolve(spreadTopLeft, CS_SPREAD)[0];
                      "INNER SPACE corner location in spread coordinates: " + xyInner,
                      "SPREAD SPACE corner location in spread coordinates: " + xySpread