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

The Mako SDK is a simple C++ SDK. The beauty of the APIs is that simple operations are just that, really simple. As your experience grows, the APIs grow with you too, facilitating complex document manipulations, rendering and transforms.

Using the API

The Mako SDK APIs are all grouped under the JawsMako namespace. This can be referenced to reduce the verbosity of the code. Most of the Mako functionality is under the jawsmako.h header file, so don't forget to include that too.

#include <jawsmako/jawsmako.h>
using namespace JawsMako;

Pointers

The API makes extensive use of smart pointers. If an object uses a smart pointer, it'll end with the suffix Ptr. These can be a great help when developing in C++ as it reduces the burden of tracking ownership and ensuring correct memory de-allocation.

Opening a Document

Opening a document with the Mako SDK couldn't be simpler. All it takes is a few simple lines.

IJawsMakoPtr jawsMako = IJawsMako::create(getCurrentWorkingDir());
IJawsMako::enableAllFeatures(jawsMako);
IDocumentAssemblyPtr assembly = IPDFInput::create(jawsMako)->open(pdfPath);

In the case above, we create a new instance of JawsMako. From here, we enable all of it's features (including using PDF as in input format). The last step is to create an IPDFInput instance and open the pdf at the path specified by pdfPath.

Opening the path returns an IDocumentAssembly. 

You can access the document within the assembly by adding one additional line.

IDocumentPtr document = assembly->getDocument(0)

This gets the first document within the assembly.


Did you know?

An IDocumentAssembly can have more than one document inside it. PDF's will usually just have the one document, but the XPS format allows multiple documents, or 'Fixed Documents' within one XPS assembly.

Document Pages

Once you have an IDocument, enumerating or modifying the pages is easy.

for (uint32 pageIndex = 0; pageIndex < document->getNumPages(); pageIndex++)
{
	// Get the page and do something with it
	IPagePtr page = document.getPage(pageIndex);
}

Once you have an IPage, you can start querying the content.

Enumerating Page Content

Accessing the Page Content DOM

Once you have a page, you can enumerate it's content. A Mako page exposes it's content using a DOM. To get the root of the page, simply call either page::getContent(), or page::edit(), depending on whether you wish to read or edit the page data. This will return the root node of the DOM, which is an IDOMFixedPagePtr.

// Use this when you are reading the page content.
IDOMFixedPagePtr fixedPage = page->getContent();

// Use this when you want to edit the page content. This will give a hint to 
// mako to retain the page in memory, even under low memory conditions.
IDOMFixedPagePtr fixedPage = page->getContent();

// If a page has been edited, you can revert changes by:
page->revert();

Enumerating DOM Nodes

Once we have the root of the DOM, IDOMFixedPagePtr, you can access further nodes in the DOM by using a number of different methods, including:

IDOMNodePtr firstChild = node->getFirstChild();
IDOMNodePtr lastChild = node->getLastChild();

IDOMNodePtr nextChild = node->getNextChild(firstChild);
IDOMNodePtr previousChild = node->getPreviousChild(lastChild);

IDOMNodePtr nextSibling = node->getNextSibling();
IDOMNodePtr nextSibling = node->getPreviousSibling();

Once you have an IDOMNodePtr, you can see which type it is, and cast it appropriately, by calling node->getNodeType().

Below is an example of seeing whether a node is a path node, and casting it appropriately.

if (node->getNodeType() == eDOMPathNode)
{
	IDOMPathNode pathNode = edlobj2IDOMPathNode(node);
	// Do something with our path node...
}

For more details on casting, see the casting page.

There are also additional methods which allow all child nodes of a specific type to be returned in one call. 

For example, the following code can be used to get all child path nodes. 

IDOMFixedPagePtr fixedPage = page->getContent();

CEDLVector<IDOMNodePtr> pathNodes;
page->getContent()->findChildrenOfType(eDOMPathNode, pathNodes);

for (const auto& node : pathNodes)
{
    const auto pathNode = edlobj2IDOMPathNode(node);
	// Do something with our path node...
}

Custom Transforms

As an alternative, custom transforms can also be used to enumerate content. In this case, when a custom transform is implemented, you choose the methods to override, depending on which node types you want to review or edit.