I need to be able to convert text and a specific font to svg path data, and happened to come across opentype.js and maker.js, independent of each other, seeing that maker.js uses opentype.js. When I use opentype.js by itself, it doesn't render the font path correctly... when I give it a fill it doesn't display it properly. When I use maker.js, it is significantly better, but still incorrect.
TO BE ABSOLUTELY CLEAR ON THE PROBLEM DESCRIPTION: I need a way to translate text with a given font to svg path data that is then "flattened" (any black overlaps are unioned and any elements that are inside of the unioned text that is white is kept - for instance look at the letter "P"... If I union it, it removes the white part inside of the "P", of which I need). At this point I don't care about the means... it just needs to be compatible with php (it can't use imagemagick or other 3rd party software ran from the terminal - like inkscape... I don't have access to run shell_exec() or exec()) or javascript
I have had many trashed attempts, so... Help very much appreciated!
---maker.js---
This is one attempt... running this snippet causes my browser to crash, but in its own file works fine.
Here is the result and the code:
window.onload = function()
{
var makerjs = require('makerjs');
var url = 'https://staging-gumcreekboards.temp312.kinsta.cloud/wp-content/themes/Divi-child/CanvEsIntegration/static/CreekWareFonts/woff/work_in_progress-updated.woff';
var text = 'Shane';
var size = 72;
var union = true;
var bezierAccuracy = 0;
var svg = document.createElement('div');
opentype.load(url, (err, font) => {
textModel = new makerjs.models.Text(font, text, size, union, true, bezierAccuracy);
//console.log(textModel.models, makerjs.model.simplify);
svg.innerHTML = makerjs.exporter.toSVG((textModel));
document.getElementById('svgcontainer').innerHTML = svg.innerHTML;
});
};
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/makerjs@0/target/js/browser.maker.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bezier-js@2/bezier.js"></script>
<script src="https://cdn.jsdelivr.net/npm/opentype.js@0/dist/opentype.js"></script>
</head>
<body>
<style>path {stroke: red; stroke-width: 1px; stroke-linejoin: round; fill: black !important;}</style>
<div id="svgcontainer">
</div>
</body>
</html>
---opentype.js---
This one won't run on SO, but it works fine on the console on the website I am programming on.
Here is the result and the code:
svgD = "";
font = await opentype.load("https://staging-gumcreekboards.temp312.kinsta.cloud/wp-content/themes/Divi-child/CanvEsIntegration/static/CreekWareFonts/woff/ARRUS BT BOLD.ttf");
pathsArray = font.getPaths("Shane", 0, 0, 72);
svgDArray = [];
svgPaths = "";
for (var i = 0; i < pathsArray.length; i++)
{
svgDArray = [];
svgD = "";
path = pathsArray[i].commands;
for (var j = 0; j < path.length; j++)
{
for (each in path[j])
{
svgDArray.push(path[j][each])
}
svgD += svgDArray.join(" ") + " ";
}
if (svgD.length > 0)
{
svgPaths += "<path fill='black' d='" + svgD + "' />";
}
};
document.getElementById("svgcontainer").innerHTML = "<?xml version='1.0' encoding='UTF-8' standalone='no'?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3/org/1999/xlink' version='1.1' width='665' height='554' viewBox='0 0 665 554' xml:space='preserve'><style>path {stroke: red; stroke-width: 1px; stroke-linejoin: 'round'; fill: black;}</style><g transform='matrix(0.95 0 0 0.95 300 275)'>" + svgPaths + "</g></svg>";
<html>
<head>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/opentype.js@latest/dist/opentype.min.js"></script>
</head>
<body>
<div id="svgcontainer">
</div>
</body>
</html>


The culprit is a faulty font definition. In fontforge, the character
ais shown as having intersecting paths. If you look at the path data output of opentype.js for this glyph, it looks like this (formatted for reading convenience):The first line represents a closed line going from one point to a second, and then back. It coincides with part of the following path and somehow leads to an error in the maker.js processing.
I have ripped apart your script to get at the underlying data for each glyph, and then patched in path data for the letter
athat are shortened by the first line.The result is an error-free SVG: