Skip to main content
Skip table of contents

Converting strokes to filled paths - IStrokerTransform

Introduction

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

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

Example code

Two examples are reproduced here in C++ and C#.

C++
CPP
/* -----------------------------------------------------------------------
 * <copyright file="Main.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="Program.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;
    }
}
JavaScript errors detected

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

If this problem persists, please contact our support.