Skip to content

Commit

Permalink
Merge pull request #19023 from calixteman/issue19022
Browse files Browse the repository at this point in the history
Apply gradient when stroking text
  • Loading branch information
calixteman authored Nov 11, 2024
2 parents 5524216 + 79e1f15 commit 2ad8782
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 10 deletions.
53 changes: 43 additions & 10 deletions src/display/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ class CanvasExtraState {
this.fillColor = "#000000";
this.strokeColor = "#000000";
this.patternFill = false;
this.patternStroke = false;
// Note: fill alpha applies to all non-stroking operations
this.fillAlpha = 1;
this.strokeAlpha = 1;
Expand Down Expand Up @@ -2001,7 +2002,7 @@ class CanvasGraphics {
this.moveText(0, this.current.leading);
}

paintChar(character, x, y, patternTransform) {
paintChar(character, x, y, patternFillTransform, patternStrokeTransform) {
const ctx = this.ctx;
const current = this.current;
const font = current.font;
Expand All @@ -2013,30 +2014,39 @@ class CanvasGraphics {
textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG
);
const patternFill = current.patternFill && !font.missingFile;
const patternStroke = current.patternStroke && !font.missingFile;

let addToPath;
if (font.disableFontFace || isAddToPathSet || patternFill) {
if (
font.disableFontFace ||
isAddToPathSet ||
patternFill ||
patternStroke
) {
addToPath = font.getPathGenerator(this.commonObjs, character);
}

if (font.disableFontFace || patternFill) {
if (font.disableFontFace || patternFill || patternStroke) {
ctx.save();
ctx.translate(x, y);
ctx.beginPath();
addToPath(ctx, fontSize);
if (patternTransform) {
ctx.setTransform(...patternTransform);
}
if (
fillStrokeMode === TextRenderingMode.FILL ||
fillStrokeMode === TextRenderingMode.FILL_STROKE
) {
if (patternFillTransform) {
ctx.setTransform(...patternFillTransform);
}
ctx.fill();
}
if (
fillStrokeMode === TextRenderingMode.STROKE ||
fillStrokeMode === TextRenderingMode.FILL_STROKE
) {
if (patternStrokeTransform) {
ctx.setTransform(...patternStrokeTransform);
}
ctx.stroke();
}
ctx.restore();
Expand Down Expand Up @@ -2127,7 +2137,7 @@ class CanvasGraphics {
ctx.scale(textHScale, 1);
}

let patternTransform;
let patternFillTransform, patternStrokeTransform;
if (current.patternFill) {
ctx.save();
const pattern = current.fillColor.getPattern(
Expand All @@ -2136,11 +2146,24 @@ class CanvasGraphics {
getCurrentTransformInverse(ctx),
PathType.FILL
);
patternTransform = getCurrentTransform(ctx);
patternFillTransform = getCurrentTransform(ctx);
ctx.restore();
ctx.fillStyle = pattern;
}

if (current.patternStroke) {
ctx.save();
const pattern = current.strokeColor.getPattern(
ctx,
this,
getCurrentTransformInverse(ctx),
PathType.STROKE
);
patternStrokeTransform = getCurrentTransform(ctx);
ctx.restore();
ctx.strokeStyle = pattern;
}

let lineWidth = current.lineWidth;
const scale = current.textMatrixScale;
if (scale === 0 || lineWidth === 0) {
Expand Down Expand Up @@ -2233,7 +2256,13 @@ class CanvasGraphics {
// common case
ctx.fillText(character, scaledX, scaledY);
} else {
this.paintChar(character, scaledX, scaledY, patternTransform);
this.paintChar(
character,
scaledX,
scaledY,
patternFillTransform,
patternStrokeTransform
);
if (accent) {
const scaledAccentX =
scaledX + (fontSize * accent.offset.x) / fontSizeScale;
Expand All @@ -2243,7 +2272,8 @@ class CanvasGraphics {
accent.fontChar,
scaledAccentX,
scaledAccentY,
patternTransform
patternFillTransform,
patternStrokeTransform
);
}
}
Expand Down Expand Up @@ -2379,6 +2409,7 @@ class CanvasGraphics {

setStrokeColorN() {
this.current.strokeColor = this.getColorN_Pattern(arguments);
this.current.patternStroke = true;
}

setFillColorN() {
Expand All @@ -2392,10 +2423,12 @@ class CanvasGraphics {
g,
b
);
this.current.patternStroke = false;
}

setStrokeTransparent() {
this.ctx.strokeStyle = this.current.strokeColor = "transparent";
this.current.patternStroke = false;
}

setFillRGBColor(r, g, b) {
Expand Down
3 changes: 3 additions & 0 deletions src/display/font_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,9 @@ class FontFaceObject {
break;
}
}
// From https://learn.microsoft.com/en-us/typography/opentype/spec/cff2#paths
// All contours must be closed with a lineto operation.
commands.push(ctx => ctx.closePath());

return (this.compiledGlyphs[character] = function glyphDrawer(ctx, size) {
commands[0](ctx);
Expand Down
1 change: 1 addition & 0 deletions test/pdfs/issue19022.pdf.link
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/user-attachments/files/17703776/linear-gradient-on-rect_text.pdf
8 changes: 8 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10757,5 +10757,13 @@
"md5": "73e8cd32bd063e42fcc4b270c78549b1",
"rounds": 1,
"type": "eq"
},
{
"id": "issue19022",
"file": "pdfs/issue19022.pdf",
"md5": "7d7a9c45f93a9db269800855ccffe7cd",
"rounds": 1,
"type": "eq",
"link": true
}
]

0 comments on commit 2ad8782

Please sign in to comment.