Creating pages with the ILayout class
📌 Overview
It has always been possible to add text and images to a page with Mako, but it required the use of some fairly low-level APIs to do so. Laying out an entire page could be an onerous task.
Enter the ILayout class. Backed by a layout engine, it is designed to simplify creating new page content, making it far easier to add left, right or fully justified paragraphs of text. Control is provided over fonts, their color, spacing and more. Images can be added too.
ℹ️ Key Concepts
The basic process is to:
1. Create an instance of the
ILayoutclass (not to be confused with theIPageLayoutclass, which is concerned with text extraction 🙂)2. Add to this one or more rectangular containers to hold content, each an instance of
ILayoutFrame3. Create a vector of one or more paragraphs, each an instance of
ILayoutParagraph
A paragraph has several properties to control default font, line spacing, justification, space before/after and default text color
4. Add text by creating one or more instances of
ILayoutTextRunwith text to be laid out, adding each to a paragraph
When creating an ILayoutTextRun, you can specify letter spacing and properties that override the defaults inherited from the paragraph, i.e. choice of font, font size and text color.
5. Add an image by creating an
ILayoutImageRunwith a reference to anIDOMImage, specifying the size required; this too is added to a paragraph
This implies that only inline images are supported, which is the case, but it’s easy to control placement as the layout engine will not place an image unless there is sufficient room in the current frame for the image at the specified size. By choosing your frame sizes carefully, it’s straightforward to place an image into the correct frame.
With these objects ready, a call to ILayout::layout() generates Mako DOM that can be appended to a page.
💪 Usage
Simple API
The process described above is explained in detail in Step-by-step code example, below, and worth following if there is a lot of content to lay out. But what if you just want to add a line of text to a page? There is a way to shortcut the process. The code in the table below will do everything to add text to a page that looks like this:

Text created with ILayout
C++ | C# |
|---|---|
CPP
|
C#
|
Step-by-step code example
Sample code associated with each of the steps described in the introduction are given here, in C++ & C#.
Create an ILayout instance
The process begins by creating an instance of the ILayout class:
const IJawsMakoPtr mako = IJawsMako::create();
IJawsMako::enableAllFeatures(mako);
...
// Create a layout
ILayoutPtr layout = ILayout::create(mako);
var mako = IJawsMako.create();
IJawsMako.enableAllFeatures(mako);
...
// Create a layout
var layout = ILayout.create(mako);
Add ILayoutFrames to hold content
This code makes use of a conversion method to convert millimeters to XPS units (1/96th inch), the unit used in Mako. These are coded as a C++ macro of C# method:
#define M2X(value) ((value) / 25.4 * 96.0)
public static double M2X(double value)
{
return value / 25.4 * 96.0;
}
The dimensions of a frame are defined by an FRect(x, y, dX, dY) struct that defines the top-left corner coordinates (x, y) and its width and height (dX, dY).
The process continues by adding frames.
// Add some frames to hold content
const double margin = M2X(12);
const auto widthWithMargins = fixedPage->getWidth() - margin * 2;
layout->addFrame(ILayoutFrame::create(FRect(margin, margin, widthWithMargins, M2X(40)))); // Banner
layout->addFrame(ILayoutFrame::create(FRect(margin, margin + M2X(40), widthWithMargins / 3 - M2X(2), M2X(83)))); // Sidebar with 2mm right margin
layout->addFrame(ILayoutFrame::create(FRect(margin + widthWithMargins / 3, margin + M2X(40), widthWithMargins / 3 * 2, M2X(83)))); // Pic
layout->addFrame(ILayoutFrame::create(FRect(margin, margin + M2X(125), widthWithMargins, M2X(155)))); // Body
// Add some frames to hold content
var margin = M2X(12);
var widthWithMargins = fixedPage.getWidth() - margin * 2;
layout.addFrame( ILayoutFrame.create(new FRect(margin, margin, widthWithMargins, M2X(40)))); // Banner
layout.addFrame( ILayoutFrame.create(new FRect(margin, margin + M2X(40), widthWithMargins / 3 - M2X(2), M2X(83)))); // Sidebar with 2mm right margin
layout.addFrame( ILayoutFrame.create(new FRect(margin + widthWithMargins / 3, margin + M2X(40), widthWithMargins / 3 * 2, M2X(83)))); // Pic
layout.addFrame( ILayoutFrame.create(new FRect(margin, margin + M2X(125), widthWithMargins, M2X(155)))); // Body
Add layout to page
The final step is to generate Mako DOM (Document Object Model) objects from the layout, which can be added to an IDOMFixedPage().
// Add to the page
fixedPage->appendChild(layout->layout(paragraphs));
⌨️ Complete examples
Complete examples are available on our GitHub Gists page. See ILayoutExample.cpp, ILayoutExample.cs, ILayoutExample.java.
☑️ Conclusion
The ILayout class significantly simplifies the process of creating and managing page layouts in Mako. By providing a structured approach to adding text and images, it allows for greater control over the appearance and formatting of content. Whether you are laying out complex documents or simply adding a line of text, the ILayout class offers the flexibility and functionality needed to achieve professional results. For further exploration, refer to the complete examples and additional resources provided.
📚 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.