1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-22 16:18:08 +02:00

Correctly render the glyph outline when it has a stroke pattern

It fixes #19360.

Each glyph in the test case has a fill and a stroke pattern, so the current transform used
to scale the glyph outline must be the same.
In setting the stroke color to green, I noticed that the last outline contains some non-closed
subpaths, so when generating the glyph outline, every time we 'moveTo', we close the previous
subpath.
This commit is contained in:
Calixte Denizet 2025-01-21 10:25:58 +01:00
parent 23dc3ff49f
commit 1ccf6ed976
5 changed files with 37 additions and 2 deletions

View file

@ -170,6 +170,11 @@ function lookupCmap(ranges, unicode) {
function compileGlyf(code, cmds, font) {
function moveTo(x, y) {
if (firstPoint) {
// Close the current subpath in adding a straight line to the first point.
cmds.add("L", firstPoint);
}
firstPoint = [x, y];
cmds.add("M", [x, y]);
}
function lineTo(x, y) {
@ -182,6 +187,7 @@ function compileGlyf(code, cmds, font) {
let i = 0;
const numberOfContours = getInt16(code, i);
let flags;
let firstPoint = null;
let x = 0,
y = 0;
i += 10;
@ -350,6 +356,11 @@ function compileGlyf(code, cmds, font) {
function compileCharString(charStringCode, cmds, font, glyphId) {
function moveTo(x, y) {
if (firstPoint) {
// Close the current subpath in adding a straight line to the first point.
cmds.add("L", firstPoint);
}
firstPoint = [x, y];
cmds.add("M", [x, y]);
}
function lineTo(x, y) {
@ -363,6 +374,7 @@ function compileCharString(charStringCode, cmds, font, glyphId) {
let x = 0,
y = 0;
let stems = 0;
let firstPoint = null;
function parse(code) {
let i = 0;

View file

@ -2043,12 +2043,13 @@ class CanvasGraphics {
ctx.save();
ctx.translate(x, y);
ctx.scale(fontSize, -fontSize);
let currentTransform;
if (
fillStrokeMode === TextRenderingMode.FILL ||
fillStrokeMode === TextRenderingMode.FILL_STROKE
) {
if (patternFillTransform) {
const currentTransform = ctx.getTransform();
currentTransform = ctx.getTransform();
ctx.setTransform(...patternFillTransform);
ctx.fill(
this.#getScaledPath(path, currentTransform, patternFillTransform)
@ -2062,8 +2063,22 @@ class CanvasGraphics {
fillStrokeMode === TextRenderingMode.FILL_STROKE
) {
if (patternStrokeTransform) {
const currentTransform = ctx.getTransform();
currentTransform ||= ctx.getTransform();
ctx.setTransform(...patternStrokeTransform);
const { a, b, c, d } = currentTransform;
const invPatternTransform = Util.inverseTransform(
patternStrokeTransform
);
const transf = Util.transform(
[a, b, c, d, 0, 0],
invPatternTransform
);
const [sx, sy] = Util.singularValueDecompose2dScale(transf);
// Cancel the pattern scaling of the line width.
// If sx and sy are different, unfortunately we can't do anything and
// we'll have a rendering bug.
ctx.lineWidth *= Math.max(sx, sy) / fontSize;
ctx.stroke(
this.#getScaledPath(path, currentTransform, patternStrokeTransform)
);