Skip to main content
Skip table of contents

Converting Path to Points and Page Coordinates

📌 Overview

This knowledge base article describes how vector objects in Mako’s DOM are represented, and how to access them and retrieve information such as their dimensions or position on the page.

📗 Instructions

Vector paths in documents can be accessed by finding the path nodes on a page. Each path node will have the following structure:

  • Path Node (IDOMPathNode)

    • Geometry (IDOMPathGeometry)

      • Figures (IDOMPathFigure)

        • Segments (IDOMPathSegment)

🪜 Steps

  1. Find all path nodes on page: The following code finds all path nodes font anywhere within the content node.

C#
CEDLVectIDOMNode pathNodes = content.findChildrenOfType(eDOMNodeType.eDOMPathNode);

If the input PDF contains XObject forms then you can use the IFormUnpackerTransform or use a custom transform implementing transformPath to reach the path nodes inside forms.

  1. Work out the transform required to get the points in page coordinates: To convert the path points to points in page coordinates we need to use the CTransformState which tracks the graphics state up to the point the node transform is applied and post multiplying it with the geometry transform of the path node. Below is sample code which shows how this can be achieved.

C#
CTransformState pathState = new CTransformState(path);
IDOMPathGeometry geometry = path.getPathData();
FMatrix toPage = geometry.getRenderTransform();
toPage.postMul(pathState.transform);
  1. Establish the type of path segment: First get the path figures using geometry.getFigures(). Once you have a path figure you can then get the smallest unit of the path geometry, the path segment (IDOMPathSegment) and then establish the type of path segment (IDOMArcSegment, IDOMPolyBezierSegment, IDOMPolyLineSegment, IPolyQuadraticBezierSegment).

  2. Transform points to page coordinates: Once the type of path segment has been established, the points can be retrieved and transformed to page coordinates. Below is sample code showing how to do this.

⌨️ Sample Code

C#
CEDLVectIDOMNode pathNodes = content.findChildrenOfType(eDOMNodeType.eDOMPathNode);
for (uint pathcount = 1; pathcount < pathNodes.size(); pathcount++)
{
	IDOMPathNode path = IDOMPathNode.fromRCObject(pathNodes[pathcount]);

	// Work out the transform required to get the points in page coordinates
	CTransformState pathstate = new CTransformState(path);
	IDOMPathGeometry geometry = path.getPathData();
	FMatrix toPage = geometry.getRenderTransform();	
	toPage.postMul(pathstate.transform);

	CEDLVectIDOMPathFigure figures;
    figures = geometry.getFigures();

    IDOMPathFigure figure;
    CEDLVectIDOMPathSegment segments;
    IDOMPathSegment segment;
    IDOMPolyLineSegment lineSegment;
    IDOMPolyQuadraticBezierSegment quadSegment;
    IDOMPolyBezierSegment bezSegment;
    IDOMArcSegment arcSegment;
    CEDLVectFPoint points = new CEDLVectFPoint();

    for (uint i = 0; i < figures.size(); i++)
    {
         figure = figures[i];

         FPoint start = figure.getStartPoint();
         Console.WriteLine(String.Format("Before {0}|{1}", start.x, start.y));

         // Apply the page transform to the start point
         start = toPage.transform(start);
         Console.WriteLine(String.Format("After {0}|{1}", start.x, start.y));

         segments = figure.getSegments();
         for (uint segmentcount = 0; segmentcount < segments.size(); segmentcount++)
         {
             segment = segments[segmentcount];

			 // Establish the type of segment we are dealing and then get the points of the segment.
             lineSegment = IDOMPolyLineSegment.fromRCObject(segment.toRCObject());
             quadSegment = IDOMPolyQuadraticBezierSegment.fromRCObject(segment.toRCObject());
             bezSegment = IDOMPolyBezierSegment.fromRCObject(segment.toRCObject());
             arcSegment = IDOMArcSegment.fromRCObject(segment.toRCObject());

             if (lineSegment != null)
                  points = lineSegment.getPoints();
             if (quadSegment != null)
                  points = quadSegment.getPoints();
             if (bezSegment != null)
                  points = bezSegment.getPoints();
             if (arcSegment != null)
                  points[0] = arcSegment.getPoint();

             for (uint pointCount = 0; pointCount < points.size(); pointCount++)
             {
                  FPoint point = points[pointCount];
                  Console.WriteLine(String.Format("Before {0}|{1}", point.x, point.y));

                  // Apply the page transform to the point
                  point = toPage.transform(point);
                  Console.WriteLine(String.Format("After {0}|{1}", point.x, point.y));
             }
         }
     }
}

☑️ Conclusion

Converting paths to points and page coordinates in Mako involves accessing vector paths, determining their transformations, and applying these to convert path points accurately. By following the detailed steps and sample code provided, users can effectively manage and manipulate vector paths within PDFs. This capability is essential for precise graphic rendering and editing.

📚 Additional Resources

If you need additional help, see our API documentation for detailed information on class/method usage, or raise a support ticket via our customer portal.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.