Skip to main content
Skip table of contents

Converting strokes to filled paths - IStrokerTransform

📌 Overview

Different rendering engines have different stroking abilities. XPS for example supports several stroking capabilities that PDF or SVG support, such as triangular line caps, using different start and end line caps, and the ability to mark sections of a path as non-stroking.

Further, XPS and most other renderers differ in how miters are treated, with XPS “clipping” miters to the miter limit where PDF and SVG renderers would simply bevel instead.

📗 Instructions

The IStrokerTransform filter provides a method for converting strokes to plain fills in all cases or only in certain circumstances, with the aim of modifying content so that it is reliably reproduced when subject to third-party conversion or rendering.

🪜 Steps

  1. Create the transform: Simply use IStrokerTransform::create().

  2. Apply settings if needed: For example you may want to set the following depending on your use case.

CPP
strokerTransform->setupForPDFStyleOutput();
strokerTransform->setConvertAllStrokes(true);
  1. Apply the transform to the page: Simply use strokerTransform->transformPage(page);

⌨️ Code Examples

Two examples are reproduced here in C++ and C#. You can also find them on our GitHub Gists page. See StrokerTransform.cpp, StrokerTransform.cs.

C++
CPP
/* -----------------------------------------------------------------------
 * <copyright file="StrokerTransform.cpp" company="Global Graphics Software Ltd">
 *  Copyright (c) 2025 Global Graphics Software Ltd. All rights reserved.
 * </copyright>
 * <summary>
 *  This example is provided on an "as is" basis and without warranty of any kind.
 *  Global Graphics Software Ltd. does not warrant or make any representations
 *  regarding the use or results of use of this example.
 * </summary>
 * -----------------------------------------------------------------------
 */

#include <iostream>

#include <jawsmako/jawsmako.h>
#include <jawsmako/pdfoutput.h>

using namespace JawsMako;
using namespace EDL;

int main()
{
    U8String testFilePath = R"(..\..\TestFiles\)";

    try
    {
        const auto mako = IJawsMako::create();
        mako->enableAllFeatures(mako);
        const auto assembly = IInput::create(mako, eFFPDF)->open(testFilePath + "MyFile.pdf");
        const auto document = assembly->getDocument();
        const auto page = document->getPage(0);

        // Apply stroker transform to convert strokes to filled paths
        const auto strokerTransform = IStrokerTransform::create(mako);
        strokerTransform->setupForPDFStyleOutput();
        strokerTransform->setConvertAllStrokes(true);
        strokerTransform->transformPage(page);

        IPDFOutput::create(mako)->writeAssembly(assembly, "test.pdf");
    }
    catch (IError& e)
    {
        const String errorFormatString = getEDLErrorString(e.getErrorCode());
        std::wcerr << L"Exception thrown: " << e.getErrorDescription(errorFormatString) << std::endl;
        return static_cast<int>(e.getErrorCode());
    }
    catch (std::exception& e)
    {
        std::wcerr << L"std::exception thrown: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}
C#
CODE
/* --------------------------------------------------------------------------------
 *  <copyright file="StrokerTransform.cs" company="Global Graphics Software Ltd">
 *    Copyright (c) 2025 Global Graphics Software Ltd. All rights reserved.
 *  </copyright>
 *  <summary>
 *    This example is provided on an "as is" basis and without warranty of any kind.
 *    Global Graphics Software Ltd. does not warrant or make any representations
 *    regarding the use or results of use of this example.
 *  </summary>
 * ---------------------------------------------------------------------------------
 */

using JawsMako;

namespace ConvertStrokesToFilledPaths;

internal class Program
{
    static int Main(string[] args)
    {
        try
        {
            var testFilepath = @"..\..\..\..\TestFiles\";

            var mako = IJawsMako.create();
            IJawsMako.enableAllFeatures(mako);

            // Input
            var pdfInput = IPDFInput.create(mako);
            using var assembly = pdfInput.open(testFilepath + "MyFile.pdf");
            using var page = assembly.getDocument().getPage();

            // Apply stroker transform to convert strokes to filled paths
            using var strokerTransform = IStrokerTransform.create(mako);
            strokerTransform.setupForPDFStyleOutput();
            strokerTransform.setConvertAllStrokes(true);
            strokerTransform.transformPage(page);
            
            IPDFOutput.create(mako).writeAssembly(assembly, IOutputStream.createToFile(mako, "test.pdf"));
        }
        catch (MakoException e)
        {
            Console.WriteLine($"Exception thrown: {e.m_errorCode}: {e.m_msg}");
        }
        catch (Exception e)
        {
            Console.WriteLine($"Exception thrown: {e}");
        }

        return 0;
    }
}

☑️ Conclusion

The IStrokerTransform filter is an essential tool for converting strokes to filled paths, ensuring consistent rendering across different platforms. By following the outlined steps and utilizing the provided code examples, users can effectively manage and transform stroke data for reliable reproduction.

📚 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.