P.positionTextDecoration = function () {
const correctCoordinates = function (out, back, start, width) {
if (out.length && out.length === back.length && width) {
const workOut = requestArray(),
workBack = requestArray(),
workHold = requestArray();
let i, iz, itemOut, itemBack,
fullLen, topLen, baseRatio;
workOut.push(...out);
workBack.push(...back);
for (i = 0, iz = workOut.length; i < iz; i++) {
itemOut = workOut[i];
itemBack = workBack[i];
workHold.length = 0;
fullLen = coord.setFromArray(itemBack).subtract(itemOut).getMagnitude();
topLen = coord.scalarMultiply(start).getMagnitude();
workHold.push(...coord.add(itemOut));
baseRatio = (topLen + (width * currentScale)) / fullLen;
coord.setFromArray(itemBack).subtract(itemOut).scalarMultiply(baseRatio).add(itemOut);
itemOut[0] = workHold[0];
itemOut[1] = workHold[1];
itemBack[0] = coord[0];
itemBack[1] = coord[1];
}
out.length = 0;
out.push(...workOut);
back.length = 0;
back.push(...workBack);
releaseArray(workOut, workBack, workHold);
}
};
const buildPath = function (out, back, style, paths) {
const iOut = out.length,
iBack = back.length;
let i, dx, dy;
if (iOut && iBack) {
dx = out[0][0] - currentStampPosition[0];
dy = out[0][1] - currentStampPosition[1];
path = `m ${(dx.toFixed(2))}, ${(dy.toFixed(2))} `;
for (i = 1; i < iOut; i++) {
dx = out[i][0] - out[i - 1][0];
dy = out[i][1] - out[i - 1][1];
path += `${(dx.toFixed(2))}, ${(dy.toFixed(2))} `;
}
dx = back[back.length - 1][0] - out[out.length - 1][0];
dy = back[back.length - 1][1] - out[out.length - 1][1];
path += `${(dx.toFixed(2))}, ${(dy.toFixed(2))} `;
for (i = iBack - 2; i >= 0; i--) {
dx = back[i][0] - back[i + 1][0];
dy = back[i][1] - back[i + 1][1];
path += `${(dx.toFixed(2))}, ${(dy.toFixed(2))} `;
}
path += 'z';
paths.push([style, new Path2D(path), [...currentStampPosition]]);
}
};
const buildUnderline = function (skipLocal = false) {
if (underlineOut.length) {
realisedStyle = underlineStyle;
realisedOffset = underlineOffset;
realisedWidth = underlineWidth;
if (!skipLocal) {
if (localStyle.underlineStyle) realisedStyle = localStyle.underlineStyle;
if (localStyle.underlineOffset) realisedOffset = localStyle.underlineOffset;
if (localStyle.underlineWidth) realisedWidth = localStyle.underlineWidth;
}
correctCoordinates(underlineOut, underlineBack, realisedOffset, realisedWidth);
buildPath(underlineOut, underlineBack, realisedStyle, underlinePaths);
underlineOut.length = 0;
underlineBack.length = 0;
}
};
const buildOverline = function (skipLocal = false) {
if (overlineOut.length) {
realisedStyle = overlineStyle;
realisedOffset = overlineOffset;
realisedWidth = overlineWidth;
if (!skipLocal) {
if (localStyle.overlineStyle) realisedStyle = localStyle.overlineStyle;
if (localStyle.overlineOffset) realisedOffset = localStyle.overlineOffset;
if (localStyle.overlineWidth) realisedWidth = localStyle.overlineWidth;
}
correctCoordinates(overlineOut, overlineBack, realisedOffset, realisedWidth);
buildPath(overlineOut, overlineBack, realisedStyle, overlinePaths);
overlineOut.length = 0;
overlineBack.length = 0;
}
};
const buildHighlight = function (skipLocal = false) {
if (highlightOut.length) {
realisedStyle = highlightStyle;
if (!skipLocal) {
if (localStyle.highlightStyle) realisedStyle = localStyle.highlightStyle;
}
buildPath(highlightOut, highlightBack, realisedStyle, highlightPaths);
highlightOut.length = 0;
highlightBack.length = 0;
}
};
const {
breakTextOnSpaces,
defaultTextStyle,
highlightPaths,
layoutTemplate,
lines,
overlinePaths,
textUnitFlow,
textUnits,
underlinePaths,
useLayoutTemplateAsPath,
} = this;
let unitData, unit, style, boxData, tl, tr, br, bl, path, charType,
includeUnderline, underlineStyle, underlineOffset, underlineWidth,
includeOverline, overlineStyle, overlineOffset, overlineWidth,
includeHighlight, highlightStyle,
lineStart, localStyle, realisedStyle, realisedOffset, realisedWidth;
const underlineOut = requestArray();
const underlineBack = requestArray();
const overlineOut = requestArray();
const overlineBack = requestArray();
const highlightOut = requestArray();
const highlightBack = requestArray();
const coord = requestCoordinate();
const {currentScale, currentStampPosition} = layoutTemplate;
underlinePaths.length = 0;
overlinePaths.length = 0;
highlightPaths.length = 0;
const currentTextStyle = this.makeWorkingTextStyle(defaultTextStyle);
this.updateWorkingTextStyle(currentTextStyle, Ωempty);
({
includeUnderline, underlineStyle, underlineOffset, underlineWidth,
includeOverline, overlineStyle, overlineOffset, overlineWidth,
includeHighlight, highlightStyle,
} = currentTextStyle);