Work in progress — this reference is being written in the open. Unfinished pages are excluded from search engines.
Paged · IDML Reference
Geometry & coordinates

PathGeometry

PathGeometry is the anchor-point outline of an IDML page item — nested GeometryPathType, PathPointArray, and PathPointType elements with Bézier handles, plus the PathOpen flag.

Pro· reference

PathGeometry is how IDML records a page item's actual outline — anchor by anchor, with Bézier handles.

In short: PathGeometry is how IDML records the actual outline of a page item. While GeometricBounds gives only the bounding box, PathGeometry carries the real shape — anchor by anchor, with Bézier control points — and real InDesign exports serialise it for every shape, including plain rectangles. It nests four elements deep: PathGeometry holds one or more GeometryPathType contours, each contour holds a PathPointArray, and each array holds PathPointType points with an on-curve anchor and two Bézier handles. A per-contour PathOpen flag decides whether each loop is sealed. It lives inside the item's <Properties> element.

The element nesting

The outline is four elements deep, each with a single job:

<PathGeometry>
  <GeometryPathType PathOpen="false">
    <PathPointArray>
      <PathPointType Anchor="0 0" LeftDirection="0 0" RightDirection="0 0"/>
      <PathPointType Anchor="0 120" LeftDirection="0 120" RightDirection="0 120"/>
      ...
    </PathPointArray>
  </GeometryPathType>
</PathGeometry>
  • PathGeometry — the container; holds one or more contours.
  • GeometryPathType — one contour (one closed or open loop). More than one of these makes a compound path.
  • PathPointArray — the ordered list of points for that contour.
  • PathPointType — one point on the outline, with its on-curve anchor and two Bézier handles.

PathPointType: anchor and handles

Each point carries three coordinate pairs, every one written x y (note: this is plain x y order, unlike GeometricBounds):

Attribute · PathPointTypeType / valuesSupportNotes
Anchor"x y" (pt)SupportedThe on-curve point the outline passes through.
LeftDirection"x y" (pt)SupportedIncoming Bézier control handle. Equal to Anchor for a corner (no curve in).
RightDirection"x y" (pt)SupportedOutgoing Bézier control handle. Equal to Anchor for a corner (no curve out).

The parser reads Anchor first; if it is missing the point is dropped. When LeftDirection or RightDirection is absent, that handle defaults to the anchor itself — i.e. a straight corner. A rectangle's four points therefore set all three pairs equal per point, which the renderer reads as four straight corners.

All three pairs are in the item's inner coordinate space, the same space its bounds use, placed onto the page by the item's ItemTransform.

GeometryPathType: one contour, open or closed

A single GeometryPathType is one contour. Its one attribute decides whether the loop is sealed:

Attribute · GeometryPathTypeType / valuesSupportNotes
PathOpenboolean ("true" | "false")Supportedtrue → the contour is left open (no closing segment back to the first anchor). false (default) → closed. Unparseable / missing is treated as false.

When PathOpen is false (or absent), the renderer closes the contour by joining the last anchor back to the first. When it is true, that closing segment is omitted — the path is a stroke that starts and ends where its anchors do. The parser lifts this flag onto a per-contour subpath_open record so the renderer knows, contour by contour, whether to auto-close.

An open path

The shape below is a three-anchor contour with PathOpen="true" — a chevron. Because the path is open, the renderer draws only the two segments between the three anchors and does not add a third segment closing the "V" into a triangle.

A three-anchor open contour: PathOpen="true" leaves the loop unclosed.

Spreads/Spread_uspread.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<idPkg:Spread xmlns:idPkg="http://ns.adobe.com/AdobeInDesign/idml/1.0/packaging" DOMVersion="20.0">
  <Spread Self="uspread" PageCount="1" BindingLocation="0" ShowMasterItems="true" AllowPageShuffle="true" ItemTransform="1 0 0 1 0 0">
    <Page Self="upage" Name="1" AppliedMaster="umaster" ItemTransform="1 0 0 1 0 0" GeometricBounds="0 0 841.89 595.276" MasterPageTransform="1 0 0 1 0 0"/>
    <Polygon Self="uline" ItemTransform="1 0 0 1 150 250" FillColor="Swatch/None" StrokeColor="Color/Black" StrokeWeight="4">
      <Properties>
        <PathGeometry>
          <GeometryPathType PathOpen="true">
            <PathPointArray>
              <PathPointType Anchor="0 0" LeftDirection="0 0" RightDirection="0 0"/>
              <PathPointType Anchor="150 200" LeftDirection="150 200" RightDirection="150 200"/>
              <PathPointType Anchor="300 0" LeftDirection="300 0" RightDirection="300 0"/>
            </PathPointArray>
          </GeometryPathType>
        </PathGeometry>
      </Properties>
    </Polygon>
    <TextFrame Self="uframe" ParentStory="ustory" PreviousTextFrame="n" NextTextFrame="n" ContentType="TextType" AppliedObjectStyle="ObjectStyle/$ID/[None]" Visible="true" Name="$ID/" ItemTransform="1 0 0 1 57.638 145.8237" FillColor="Swatch/None" StrokeColor="Swatch/None" StrokeWeight="0">
      <Properties>
        <PathGeometry>
          <GeometryPathType PathOpen="false">
            <PathPointArray>
              <PathPointType Anchor="0 0" LeftDirection="0 0" RightDirection="0 0"/>
              <PathPointType Anchor="0 400" LeftDirection="0 400" RightDirection="0 400"/>
              <PathPointType Anchor="480 400" LeftDirection="480 400" RightDirection="480 400"/>
              <PathPointType Anchor="480 0" LeftDirection="480 0" RightDirection="480 0"/>
            </PathPointArray>
          </GeometryPathType>
        </PathGeometry>
      </Properties>
    </TextFrame>
  </Spread>
</idPkg:Spread>

Flip PathOpen to false and the contour seals — the chevron would close into a triangle. That single boolean is the whole difference between a line and a region.

Corner options render as rounded

IDML can ask for decorative corner treatments on a rectangle via CornerOption (and the per-corner TopLeftCornerOption and siblings). The parser recognises the full set of names, but the renderer collapses every non-square variant to a plain rounded corner for now:

Attribute · CornerOption valuesType / valuesSupportNotes
NoneenumSupportedSquare corner. The default.
RoundedenumSupportedRounded corner — rendered as drawn.
Inverse / Inset / Bevel / FancyenumParsed, not yet renderedRecognised and treated as a rounded corner; the bespoke decorative shapes are not yet generated.
Parsed, not yet renderedDecorative corner shapes (Fancy / Bevel / Inset / Inverse) fall back to Rounded.

A second, related gap: decorative path and stroke treatments beyond the plain outline are not generated either — the path you get is the anchor outline as written, closed or open per PathOpen.

Frequently asked questions

How are PathGeometry elements nested? The outline is four elements deep: PathGeometry holds one or more GeometryPathType contours, each GeometryPathType holds a PathPointArray, and each PathPointArray holds PathPointType points. Every PathPointType carries an Anchor and two Bézier handles, LeftDirection and RightDirection.

What coordinate order do PathPointType anchors use? Each of Anchor, LeftDirection, and RightDirection is written x y — plain horizontal-then-vertical order, unlike GeometricBounds, which puts Y first. The parser reads Anchor first and drops the point if it is missing; an absent handle defaults to the anchor itself, which the renderer reads as a straight corner.

What does the PathOpen attribute do? PathOpen is a per-contour boolean on GeometryPathType. When it is false (or absent, the default) the renderer closes the contour by joining the last anchor back to the first; when it is true the closing segment is omitted and the contour stays an open stroke. The parser lifts the flag onto a per-contour subpath_open record so each contour can be closed on its own terms.

On this page