Skip to main content
Skip table of contents

Mako 5.0.0 Release Notes


New feature work

These are the principal new or improved features of Mako 5.0

MAKO-846      Integrate Jaws 4 into Mako to replace the Jaws 3.x components

Mako incorporates the Jaws RIP to interpret PDF (and now PostScript) and to render content to a bitmap from the Mako DOM (Document Object Model). Updating to the latest version of Jaws improves accuracy and performance.

MAKO-1227   Jaws 4 integration: PostScript Input

Mako 5.0 supports PostScript as an input format directly, adding a new input class, IPSInput. This eliminates the need to first convert to PDF with a separate component (Jaws PDFLib).

MAKO-1357   Transition DOM APIs to exceptions for error handling instead of a simple bool pass/fail

This work simplifies a huge number of Mako APIs, and provides more detail when an exception is triggered. It also resulted in classes, enumerations, typedefs and more being renamed for consistency.

Note: These are breaking changes, meaning existing code will have to be modified. Additional information is provided later in this document.

MAKO-1465   Update development tools

Mako 5.0 is built with more recent compiler versions on all platforms. For example, on Windows, Visual Studio 2019 is now supported (and recommended). Mac and iOS builds use the latest SDKs (macOS 10.15, iOS 13.2).

MAKO-1469   EDS (Error Diffusion Screens)

A new class, IJawsRenderer::CEDSHalftone is added, enabling images to be rendered using a halftone representing an error diffusion screen. Allows the production of results containing a variable number of gray levels per channel using a range of error diffusion screens.

This class may be used for both monochrome and color rendering with renderScreened() and renderScreenedToFrameBuffers(). The existing renderMonochrome() and renderMonochromeToFrameBuffer() are still available, they simply call the new APIs.

Rather than simply offer typical EDS screens such as Floyd-Steinberg and Stucki, the class allows the user to specify parameters that describe the algorithm.

For example:

Floyd-Steinberg

CPP
// The halftone - this example is Floyd-Steinberg with drop sizes of 3,
// serpentine enabled and no perturbation
IJawsRenderer::CEDSHalftone halftone;
halftone.dropSizes = 3;
halftone.rows = 2;
halftone.columns = 3;
halftone.pixelColumn = 1;
halftone.denominator = 16;
halftone.weights[0] = 0;  halftone.weights[1] = 0;  halftone.weights[2] = 7;  halftone.weights[3] = 0;  halftone.weights[4] = 0;
halftone.weights[5] = 3;  halftone.weights[6] = 5;  halftone.weights[7] = 1;  halftone.weights[8] = 0;  halftone.weights[9] = 0;
halftone.weights[10] = 0; halftone.weights[11] = 0; halftone.weights[12] = 0; halftone.weights[13] = 0; halftone.weights[14] = 0;
halftone.weights[15] = 0; halftone.weights[16] = 0; halftone.weights[17] = 0; halftone.weights[18] = 0; halftone.weights[19] = 0;
halftone.useSerpentine = true;
halftone.perturbation = 0.0;

To facilitate creating these parameters, a Windows-based utility, Mako EDS Workbench, is available. Learn more and download an installer from the documentation page.

MAKO-1788   Provide a method to retain and edit property values attached to form and image XObjects

In PDF, OEMs can put extra key value pairs into PDF XObject dictionaries. This is often used to store in application-specific data, as well as for things like variable data tags.

Until now, Mako has not been preserving these; with this change it will.

Additionally, there are new member functions in IDOMImageBrush and IDOMForm to get and set the properties:

CODE
IDOMForm::getPdfPropertiesDictionary()
IDOMForm::setPdfPropertiesDictionary()
IDOMImageBrush::getPdfPropertiesDictionary()
IDOMImageBrush::setPdfPropertiesDictionary()

While meeting the requirement expressed in the title of this story, this feature has developed into a generalized method for adding/querying custom entries at the catalog and page levels.

Additionally, there is an API for reading raw PDF objects from a PDF document, which is added to allow developers to reach any object they may wish to pull into a property.

A new interface, IPDFObjectStore, gives access to Mako’s internal CObjectStore

Its APIs allow users to:

  • resolve objects
  • add objects
  • mark objects as dirty (for incremental update purposes)
  • create new indirect references (IPDFReference)
  • generate far references (IPDFFarReference) that allow the objects to be referred to from inside image and form properties

IPage and IDocument acquire new APIs to:

  • obtain the object store attached to the page or document
  • search the page or document for a given far reference (also locating the IPDFObjectStore where that object was present)

Example: A user wants to add a stream to attach to a form (maybe the contents of the document that was the source material). The steps they would take are:

  • Create the IPDFStream object for their stream
  • Store it in one of the object stores (probably the page but putting it in the document store is fine too) and obtain an indirect reference.
  • Create a far reference from that and store that reference in the pdf properties dictionary attached to the form.

The user can now put arbitrary indirect objects however they would like, and via the far reference mechanism can refer to the same objects in multiple places.

Conversely if they see a far reference inside a PDF form properties dictionary that they have loaded, they can ask the IPage or the IDocument to locate the object and return it to them (or they can look at the object stores themselves).

A new simple example (see custompdfentries.cpp), included in the SDK, demonstrates how they can do both things. The sample code also demonstrates how custom entries can be added to a page dictionary (the root object of the page store) or to the catalog (the root object of the document store).

MAKO-1470   Expanded bindings

Mako development in C# is introduced in Mako 5.0, implemented using SWIG, an interface compiler that connects programs written in C and C++ with scripting languages.

The Mako build for C# development will not be included in the Mako 5.0 release but is available as a preview version upon request. A NuGet package is available for Visual Studio on Windows. Support for other platforms, such as macOS and Linux, will follow. Getting started documentation can be found here.

MAKO-1736   Support 16-bit rendering

                            Jaws supports rendering to 16 bit-per-pixel images, but previously not exposed in the Mako IJawsRenderer class. For Mako 5.0, an additional parameter controls bit depth (8 or 16).

Support issues fixed

MAKO-1558   (Mako Support Request #10237) Exception thrown from IPage::getContent
MAKO-1745   (Mako Support Request #10268) PlanetPDF Press PDF cannot be processed
MAKO-1926   (Mako Support Request #10311) Exception = Bad arguments passed to an API function
MAKO-1927   (Mako Support Request #10312) Exception = PCL5 Processing Error
MAKO-1929   (Mako Support Request #10310) Incorrect rendering of RGB colors
MAKO-1932   (Mako Support Request #10306) pcl to pdf issue
MAKO-1895   (Mako Support Request #10299) RGB and CMYK give different output
MAKO-1889   (Mako Support Request #10300) PDF causing "Internal RIP error: Rangecheck error"
MAKO-1623   (Mako Support Request #10241) Recovering from an error
MAKO-1986   (Mako Support Request #10320) Mako v4.8.0 - PCL5 - PJL Issue

Other changes

MAKO-1711   Add BigTIFF support to Mako and clean up Mako TIFF encoding

Mako now provides an option for OEMs to encode TIFF as bigtiff (see IDOMTIFFImage::encode()). Huge images can now be safely written.

MAKO-1831   Add abort to IPDFInput::scanPdfForInks

This process can now be safely aborted with IAbort::signalAbort()

MAKO-1859       Provide a method of querying and modifying a PDF MediaBox

New APIs, IPage::getMediaBox() and IPage::setMediaBox(), enable a developer to query or change a PDF document’s MediaBox. Unlike most Mako APIs which expect Mako units (1/96"), these APIs expect PDF units (1/72").

In this example the size of a page is increased by 25mm on all sides:

#define MM2PDFUNITS(value) value / 25.4 * 72.0

CPP
// Get the page
IPagePtr page = document->getPage(pageIndex);

// New API
FBox mediaBox = page->getMediaBox();

// Modify size
mediaBox.left -= MM2PDFUNITS(25);
mediaBox.top += MM2PDFUNITS(25);
mediaBox.right += MM2PDFUNITS(25);
mediaBox.bottom -= MM2PDFUNITS(25);
page->setMediaBox(mediaBox);
MAKO-1374   Add customtransform header to distribution

customtransform.h (see this page for more details) is now included in the standard distribution, with improved comments to guide developers using an IDE such as Visual Studio or XCode.

MAKO-1635   Make several previously internal-only transforms public

This opens access to private headers, prompted by a customer’s need to make use of the font processor. This change includes:

  • IPatternConverterTransform
  • IFontProcessorTransform and IFontProcessorDeferredTransform
  • IBlendSimplifierTransform
  • ISoftMaskConverterTransform

As they are included in the public interface, they are documented at https://api.globalgraphics.com/mako/5_0_x

MAKO-1713   Make the glyphs clusters API public
  • Header file: edl/iglyphsclusters.h
  • Defines the IGlyphsClusters class
  • IDOMGlyphs now offers getClusters() / setClusters() methods

As they are included in the public interface, they are documented at https://api.globalgraphics.com/mako/5_0_x

MAKO-716      Improve the “Web” preset to support byte serving

Presets that can be used with IPDFOutput::setPreset (or used on the makoconverter command line) are documented here:

The web preset has been improved to support byte serving, whereby the PDF cross-reference table is moved to the beginning of the file to allow web browsers random access to the PDF content. For large files this can significantly improve the responsiveness of web browsing

Breaking changes

We took the opportunity in the Mako 5.0 project to make changes aimed at making the APIs more consistent in their naming, behavior or return types. Developers new to Mako will be unaware of these changes, but existing code written for Mako 4.x may require refactoring to work with Mako 5.0.

Exceptions versus Boolean return values

The most extensive change to Mako classes is the use of exceptions to signal a problem, rather than a Boolean return value. Exceptions can provide more detail via an error code than the simple pass/fail of a Boolean.

In most cases, this means that their signature changes too. Instead of passing a pointer to an object that is updated by the call, the method returns the new object. For example, to obtain the colorspace from an IDOMColor object in Mako 4.x you would write:

CODE
IDOMColorSpacePtr inkColorSpace;
inkColor->getColorSpace(inkColorSpace);

Whereas in Mako 5.0, you write:

CPP
DOMColorSpacePtr inkColorSpace = inkColor->getColorSpace();

This change often results in simpler code.

Code written for Mako 4.x that tests the Boolean return value to check that the call was successful can be surrounded by a try-catch block. The examples provided with the SDK demonstrate this approach.

This change affects all the most commonly used classes:

IDOMNode

IDOMBrush

IDOMColor

IDOMPathGeometry

IDOMGroup

IDOMFont

IDOMImage and IImage

IDOMGlyphs

IDOMResource

IDOMFunction

IDOMPage

IDOMPath

IDOMShape

IEDLTempStore

MAKO-1771   Make CEDLVector usable with the C++11 for loop iterator syntax

Mako 5.0 now supports the loop iterator. The following “before and after” code snippets also highlights an example of where a Mako enumerator (IDOMFigureCollectionEnum) has been replaced by the more convenient vector, CDOMPathFigureVect.


Mako 4.8

CPP
uint32 getPathPointCount(const IDOMPathGeometryPtr& geometry)
{
    IDOMFigureCollectionEnumPtr figures = geometry->getFigureCollectionEnum();
    uint32 pointCount = 1;
    IDOMPathFigurePtr figure;
    while (figures->getNext(&figure))
    {
        IDOMSegmentCollectionEnumPtr segments = figure->getSegmentCollectionEnum();
        IDOMPathSegmentPtr segment;
        while (segments->getNext(&segment))
        {
            pointCount += edlobj2IDOMArcSegment(segment) ? 1 : 0;
            pointCount += edlobj2IDOMPolyLineSegment(segment) ?
                edlobj2IDOMPolyLineSegment(segment)->getPointsCount() : 0;
            pointCount += edlobj2IDOMPolyBezierSegment(segment) ?
                edlobj2IDOMPolyBezierSegment(segment)->getPointsCount() : 0;
            pointCount += edlobj2IDOMPolyQuadraticBezierSegment(segment) ?
                edlobj2IDOMPolyQuadraticBezierSegment(segment)->getPointsCount() : 0;
        }
    }
    return pointCount;
}


Compare to Mako 5.0:

Compare to Mako 5.0

CPP
uint32 getPathPointCount(const IDOMPathGeometryPtr& geometry)
{
    CDOMPathFigureVect figures = geometry->getFigures();
    uint32 pointCount = 1;
    for (const IDOMPathFigurePtr figure : figures)
    {
        CDOMPathSegmentVect segments = figure->getSegments();
        for (IDOMPathSegmentPtr segment : segments)
        {
            pointCount += edlobj2IDOMArcSegment(segment) ? 1 : 0;
            pointCount += edlobj2IDOMPolyLineSegment(segment) ?
                edlobj2IDOMPolyLineSegment(segment)->getPointsCount() : 0;
            pointCount += edlobj2IDOMPolyBezierSegment(segment) ?
                edlobj2IDOMPolyBezierSegment(segment)->getPointsCount() : 0;
            pointCount += edlobj2IDOMPolyQuadraticBezierSegment(segment) ?
                edlobj2IDOMPolyQuadraticBezierSegment(segment)->getPointsCount() : 0;
        }
    }
    return pointCount;
}

Known issues

PDF standards compliance

During testing it was found that PDF/X and PDF/A output was failing compliance testing due to the presence of OPI comments. As this issue can be solved with some additional code prior to writing an assembly to a new PDF/X or PDF/A document, it was decided to defer the fix to a later release.

The additional code takes the form of a custom transform. A version of the standard sample makoconverter that includes the additional code can be found on GitHub.

Note: In Mako 5.0, the custom transform is no longer a private header and is available as a regular #include. The inline documentation has been improved to make it easier to implement. The attached example code performs a useful function but also serves as an excellent example of custom transform implementation.

Over-italicization of emulated fonts on Ubuntu

During testing it was found that some test jobs with italic text that required an emulated font because the original font was unavailable over-italicized the glyphs, which is to say increased the skew angle excessively.

Other Linux platforms did not exhibit the problem. The workaround is to install the Microsoft TrueType core fonts package.

Tooling updates

MAKO-1708   Update Windows build for VS2019 (compiler version 142)
MAKO-1827   Update Mac and iOS builds to use the latest SDKs (macOS 10.15, iOS 13.2)

Both part of an initiative while developing Mako 5.0 to update tooling across platforms

MAKO-1746   Drop 32-bit support for macOS builds

As the last 32-bit Mac came out in 2011 we have dropped 32-bit support. The distribution retains its ‘UB’ label (universal binary) for now.

MAKO-1822   Deprecate 32-bit Windows builds in Mako 5.0

32-bit libraries have been dropped from the principal Windows distribution (Visual Studio 2019). They remain available in the VS2015 distribution but will be dropped altogether in a future release.

Distribution

Mako 5.0 is built for the following platforms:

  • Android
  • iOS
  • Linux (for Debian-based distributions, eg Ubuntu, Mint)
  • Linux (Centos)
  • Linux (for Debian Jessie)
  • Linux (for MUSL distributions, eg Alpine Linux)
  • macOS
  • Windows (static and non-static libs, VS 2019 (V142) x64 only)
  • Windows (static and non-static, VS2015 (V140), x86 and x64)
  • Windows SWIG (Preview release of C# libraries)
  • Windows UWP (Store apps, Windows 10 IoT)

 

JavaScript errors detected

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

If this problem persists, please contact our support.