paged.IDML Reference
Geometry & coordinates

Compound paths

A compound path packs several GeometryPathType contours into one IDML shape — how a hole is punched with opposite winding, and why each contour closes alone.

Tier: ProProIIIexplanation

A compound path is one IDML shape built from several contours: the way a hole is punched into a fill.

In short A PathGeometry can hold more than one GeometryPathType. Together the contours form one shape, filled and stroked as one: a ring, the counter of a letter, a panel with a window. Nothing marks a contour as outer or inner. Whether an inner contour cuts a hole depends on its winding direction under the nonzero rule. Each contour is a separate closed (or open) loop.

Two contours, one shape

The outer contour defines the filled region; an inner contour wound the opposite way cancels it where they overlap, leaving a hole. Under the nonzero winding rule, loops wound the same way add up to a solid shape instead.

An outer square and an inner square wound the opposite way: the overlap cancels into a hole.

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="upoly" ItemTransform="1 0 0 1 150 250" FillColor="Color/Red" StrokeColor="Swatch/None" StrokeWeight="0">
      <Properties>
        <PathGeometry>
          <GeometryPathType PathOpen="false">
            <PathPointArray>
              <PathPointType Anchor="0 0" LeftDirection="0 0" RightDirection="0 0"/>
              <PathPointType Anchor="240 0" LeftDirection="240 0" RightDirection="240 0"/>
              <PathPointType Anchor="240 240" LeftDirection="240 240" RightDirection="240 240"/>
              <PathPointType Anchor="0 240" LeftDirection="0 240" RightDirection="0 240"/>
            </PathPointArray>
          </GeometryPathType>
          <GeometryPathType PathOpen="false">
            <PathPointArray>
              <PathPointType Anchor="80 80" LeftDirection="80 80" RightDirection="80 80"/>
              <PathPointType Anchor="80 160" LeftDirection="80 160" RightDirection="80 160"/>
              <PathPointType Anchor="160 160" LeftDirection="160 160" RightDirection="160 160"/>
              <PathPointType Anchor="160 80" LeftDirection="160 80" RightDirection="160 80"/>
            </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>

The outer contour runs 0,0 → 240,0 → 240,240 → 0,240; the inner one runs the reverse way. Reverse the inner contour's points so both wind the same way and the hole fills in.

Each contour is its own loop

Every GeometryPathType starts a new loop. A reader must close each contour back to its own first point, not run on from the end of one contour into the start of the next. A consumer that merges all points into one list and draws it as a single polygon joins the outer and inner squares with a stray segment, and the hole never forms.

Each contour also carries its own PathOpen. A compound path can therefore mix closed contours with open ones; each closes, or stays open, on its own terms.

Where compound paths come from

Compound paths come from InDesign's Make Compound Path command and from Pathfinder operations such as subtract and exclude overlap. Any shape element can hold several contours; a reader should not assume only <Polygon> does.

In Paged: each contour is closed separately and filled with the nonzero rule.

Supported · verified

Frequently asked questions

What is a compound path in IDML? A single PathGeometry with more than one GeometryPathType. The contours form one shape with several loops, which is how holes are made.

How does a compound path punch a hole? By winding. Under the nonzero rule, an inner contour wound opposite to the outer one cancels the fill where they overlap. The file has no flag for "inner".

Is each contour closed separately? Yes. Each GeometryPathType is its own loop with its own PathOpen. Joining the end of one contour to the start of the next is a reader error that fills the hole in.

On this page