Page tree
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »


Mako ITransforms provide a method of applying common operations on DOM objects such as brushes, colors, colorspaces, glyphs or paths. They can operate on individual nodes or entire trees.

For example, there are many built-in transforms in Mako for:

  • Image downsampling (IImageDownsamplerTransform)
  • Color conversion (IColorConverterTransform)
  • Color simplification (IComplexColorSimplifierTransform)
  • Image merging (IImageMergerTransform)
  • Remove non-visible Optional Content (IOptionalContentFixerTransformPtr)

Thus, transforms simplify complex operations to be applied to a number of DOM objects in one go.

A custom transform enables a Mako SDK developer to take advantage of the ITransforms framework for their own purposes.

Custom Transform header

A framework to enable development of custom transforms is provided as a header, customtransform.h.

It's not part of the standard distribution, but can be downloaded from the link shown on the right of this page. Note that there are two versions, one for pre-Mako 4.8 and another for Mako 4.8. Mako 4.8 introduces a mechanism for aborting a transform operation, so the Mako 4.8 header must be used with Mako 4.8.

A custom transform implements call backs for the DOM objects listed below. All you need do is override the cases you are interested in, providing one or more methods for actually doing the work

For example, let's say you wanted to find out information for every image in a document. You could write a custom transform to override transformImageBrush(). Your code will be called every time an imagebrush (IDOMImageBush) is encountered, and from there get to the image (IDOMImage) and its frame (IDOMFrame) to obtain all the information you need - size, resolution, colorspace etc. You would run the transform on a page and repeat for all pages in a document.

A more likely scenario is one where you want to change the object in some way. Your implementation can do this, returning the updated object or a NULL if you want it removed from the DOM tree.

IDOM objectDescription
IDOM objectDescription


Annotation appearance


The children of this node type comprise the contents of a PDF/PS style form. (XForm)




A node whose content must be an IDOMForm


Color space


The parent class for the many brush types. Brushes are used to fill paths, ie a defined geometric region on the page


Base class describing an image


A solid color brush is used to fill a path with a solid color


Base class for the many DOM node types


The parent class for linear and radial gradient brushes


The contents of a page


A linear gradient brush is used to specify a gradient along a vector


A DOM node representing Group Elements. A group of IDOMNodes that share common properties such as a clipping path or render transform


A radial gradient brush defines an ellipse to be filled with a gradient


A DOM node representing Group Elements that consist of stroked text


A visual brush is used to fill a path with a vector drawing


A DOM node representing Group Elements that share common transparency settings. Analogous to PDF Transparency Groups.


An image brush is used to fill a path with an image


A canvas is a special form of an isolated, non-knockout, normal blended transparency group. It groups elements of a page together.


A tiling pattern brush is used to fill a path with a PS-style tiling pattern.


Glyphs nodes are used to represent a run of uniformly formatted text from a single font


A shading pattern brush is used to fill a defined geometric region with a PS-style shading pattern.


Font base class


A soft mask brush provides a way of representing a PDF-style soft mask in its entirety. It will contain a suitable IDOMTransparency group as well as the necessary soft mask details


A path node specifies geometry that can be filled with a brush


A masked brush describes a generalization of a masked image


Special node type used by XPS for the root node inside a visual brush (normally tiling patterns)


A null brush


Class for tracking the graphics state leading to the point where a transform is applied.

Consider for example the IImageDownsamplerTransform described elsewhere. In order to determine how to downsample an image, the transform needs to know how large the image will eventually be. The CTransformState provides this information by providing the combined transform that applies to the image based on the RenderTransforms of all the nodes entered leading to the point where the image is actually encountered.

Other transforms need access to other information, such as the approximate clip area, the current group color space, the renderingIntent (if present), the current antialiasing mode (edge mode) and/or how a brush is used.


New to Mako 4.8.0, this member can be used to track extra information needed by the transform process. Use it as you wish.

Implementing a custom transform

This example of a custom transform implementation converts glyphs to paths.

It is instantiated by the calling program:

Creating the transform instance
		// Create a transform to convert glyphs to paths
		GlyphTransformImplementation implementation(jawsMako, strokeWidth, solidBrush);
		ITransformPtr outliner = ICustomTransform::create(jawsMako, &implementation, abort, true, true, true, true, true, true);

And subsequently called for each page:

Calling the transform
        // Apply the transform to every page
        for (uint32 pageNum = 0; pageNum < pageCount; pageNum++)
			IPagePtr page = document->getPage(pageNum);
        	IDOMFixedPagePtr fixedPage = page->edit();

			// Convert any glyphs
			bool result = false;
			outliner->transform(fixedPage, result);

One advantage of custom transforms is that they can hide away complexity. Remember that you can implement call backs for as many objects types as you wish, in the one transform.

What are all those Booleans in the call to the transform?

They control cacheing behavior. Depending on the nature of the transform, it may not be necessary to process the same transform repeatedly. Setting one or more of these values to false may speed up a custom transform by allowing Mako to return a reference to a cached copy. Each relates to the properties of various object types, seen here in this except from customtransform.h:

Custom transform call parameters
static JAWSMAKO_API ICustomTransformPtr create(const IJawsMakoPtr &jawsMako, 
                                                IImplementation *implementation,
                                                const IAbortPtr &abort = IAbortPtr (),
                                                bool dependsOnClipBounds = true,
                                                bool dependsOnGroupSpace = true,
                                                bool dependsOnRenderingIntent = true,
                                                bool dependsOnTransform = true,
                                                bool dependsOnBrushUsage = true,
                                                bool dependsOnEdgeMode = true,
                                                bool dependsOnUncoloredTilingBrush = true);

We recommend you experiment with these to determine their applicability to your implementation.

Custom Transform headers

Mako 4.7 or earlierMako 4.8
  • No labels