Skip to content

Commit 2b9f621

Browse files
authored
Merge pull request #19953 from calixteman/rm_useless_arrays
[api-minor] Create the css color to use with the canvas in the worker
2 parents 60574fb + 5789afd commit 2b9f621

File tree

7 files changed

+82
-83
lines changed

7 files changed

+82
-83
lines changed

src/core/colorspace.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
MathClamp,
2222
shadow,
2323
unreachable,
24+
Util,
2425
warn,
2526
} from "../shared/util.js";
2627
import { BaseStream } from "./base_stream.js";
@@ -116,6 +117,8 @@ function copyRgbaImage(src, dest, alpha01) {
116117
}
117118

118119
class ColorSpace {
120+
static #rgbBuf = new Uint8ClampedArray(3);
121+
119122
constructor(name, numComps) {
120123
if (
121124
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
@@ -132,10 +135,14 @@ class ColorSpace {
132135
* located in the src array starting from the srcOffset. Returns the array
133136
* of the rgb components, each value ranging from [0,255].
134137
*/
135-
getRgb(src, srcOffset) {
136-
const rgb = new Uint8ClampedArray(3);
137-
this.getRgbItem(src, srcOffset, rgb, 0);
138-
return rgb;
138+
getRgb(src, srcOffset, output = new Uint8ClampedArray(3)) {
139+
this.getRgbItem(src, srcOffset, output, 0);
140+
return output;
141+
}
142+
143+
getRgbHex(src, srcOffset) {
144+
const buffer = this.getRgb(src, srcOffset, ColorSpace.#rgbBuf);
145+
return Util.makeHexColor(buffer[0], buffer[1], buffer[2]);
139146
}
140147

141148
/**

src/core/evaluator.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ class PartialEvaluator {
507507

508508
if (smask?.backdrop) {
509509
colorSpace ||= ColorSpaceUtils.rgb;
510-
smask.backdrop = colorSpace.getRgb(smask.backdrop, 0);
510+
smask.backdrop = colorSpace.getRgbHex(smask.backdrop, 0);
511511
}
512512

513513
operatorList.addOp(OPS.beginGroup, [groupOptions]);
@@ -1546,7 +1546,7 @@ class PartialEvaluator {
15461546
localTilingPatternCache.getByRef(rawPattern);
15471547
if (localTilingPattern) {
15481548
try {
1549-
const color = cs.base ? cs.base.getRgb(args, 0) : null;
1549+
const color = cs.base ? cs.base.getRgbHex(args, 0) : null;
15501550
const tilingPatternIR = getTilingPatternIR(
15511551
localTilingPattern.operatorListIR,
15521552
localTilingPattern.dict,
@@ -1565,7 +1565,7 @@ class PartialEvaluator {
15651565
const typeNum = dict.get("PatternType");
15661566

15671567
if (typeNum === PatternType.TILING) {
1568-
const color = cs.base ? cs.base.getRgb(args, 0) : null;
1568+
const color = cs.base ? cs.base.getRgbHex(args, 0) : null;
15691569
return this.handleTilingType(
15701570
fn,
15711571
color,
@@ -2000,47 +2000,47 @@ class PartialEvaluator {
20002000
}
20012001
case OPS.setFillColor:
20022002
cs = stateManager.state.fillColorSpace;
2003-
args = cs.getRgb(args, 0);
2003+
args = [cs.getRgbHex(args, 0)];
20042004
fn = OPS.setFillRGBColor;
20052005
break;
20062006
case OPS.setStrokeColor:
20072007
cs = stateManager.state.strokeColorSpace;
2008-
args = cs.getRgb(args, 0);
2008+
args = [cs.getRgbHex(args, 0)];
20092009
fn = OPS.setStrokeRGBColor;
20102010
break;
20112011
case OPS.setFillGray:
20122012
stateManager.state.fillColorSpace = ColorSpaceUtils.gray;
2013-
args = ColorSpaceUtils.gray.getRgb(args, 0);
2013+
args = [ColorSpaceUtils.gray.getRgbHex(args, 0)];
20142014
fn = OPS.setFillRGBColor;
20152015
break;
20162016
case OPS.setStrokeGray:
20172017
stateManager.state.strokeColorSpace = ColorSpaceUtils.gray;
2018-
args = ColorSpaceUtils.gray.getRgb(args, 0);
2018+
args = [ColorSpaceUtils.gray.getRgbHex(args, 0)];
20192019
fn = OPS.setStrokeRGBColor;
20202020
break;
20212021
case OPS.setFillCMYKColor:
20222022
stateManager.state.fillColorSpace = ColorSpaceUtils.cmyk;
2023-
args = ColorSpaceUtils.cmyk.getRgb(args, 0);
2023+
args = [ColorSpaceUtils.cmyk.getRgbHex(args, 0)];
20242024
fn = OPS.setFillRGBColor;
20252025
break;
20262026
case OPS.setStrokeCMYKColor:
20272027
stateManager.state.strokeColorSpace = ColorSpaceUtils.cmyk;
2028-
args = ColorSpaceUtils.cmyk.getRgb(args, 0);
2028+
args = [ColorSpaceUtils.cmyk.getRgbHex(args, 0)];
20292029
fn = OPS.setStrokeRGBColor;
20302030
break;
20312031
case OPS.setFillRGBColor:
20322032
stateManager.state.fillColorSpace = ColorSpaceUtils.rgb;
2033-
args = ColorSpaceUtils.rgb.getRgb(args, 0);
2033+
args = [ColorSpaceUtils.rgb.getRgbHex(args, 0)];
20342034
break;
20352035
case OPS.setStrokeRGBColor:
20362036
stateManager.state.strokeColorSpace = ColorSpaceUtils.rgb;
2037-
args = ColorSpaceUtils.rgb.getRgb(args, 0);
2037+
args = [ColorSpaceUtils.rgb.getRgbHex(args, 0)];
20382038
break;
20392039
case OPS.setFillColorN:
20402040
cs = stateManager.state.patternFillColorSpace;
20412041
if (!cs) {
20422042
if (isNumberArray(args, null)) {
2043-
args = ColorSpaceUtils.gray.getRgb(args, 0);
2043+
args = [ColorSpaceUtils.gray.getRgbHex(args, 0)];
20442044
fn = OPS.setFillRGBColor;
20452045
break;
20462046
}
@@ -2065,14 +2065,14 @@ class PartialEvaluator {
20652065
);
20662066
return;
20672067
}
2068-
args = cs.getRgb(args, 0);
2068+
args = [cs.getRgbHex(args, 0)];
20692069
fn = OPS.setFillRGBColor;
20702070
break;
20712071
case OPS.setStrokeColorN:
20722072
cs = stateManager.state.patternStrokeColorSpace;
20732073
if (!cs) {
20742074
if (isNumberArray(args, null)) {
2075-
args = ColorSpaceUtils.gray.getRgb(args, 0);
2075+
args = [ColorSpaceUtils.gray.getRgbHex(args, 0)];
20762076
fn = OPS.setStrokeRGBColor;
20772077
break;
20782078
}
@@ -2097,7 +2097,7 @@ class PartialEvaluator {
20972097
);
20982098
return;
20992099
}
2100-
args = cs.getRgb(args, 0);
2100+
args = [cs.getRgbHex(args, 0)];
21012101
fn = OPS.setStrokeRGBColor;
21022102
break;
21032103

src/core/pattern.js

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -198,19 +198,20 @@ class RadialAxialShading extends BaseShading {
198198

199199
const color = new Float32Array(cs.numComps),
200200
ratio = new Float32Array(1);
201-
let rgbColor;
202201

203202
let iBase = 0;
204203
ratio[0] = t0;
205204
fn(ratio, 0, color, 0);
206-
let rgbBase = cs.getRgb(color, 0);
207-
const cssColorBase = Util.makeHexColor(rgbBase[0], rgbBase[1], rgbBase[2]);
208-
colorStops.push([0, cssColorBase]);
205+
const rgbBuffer = new Uint8ClampedArray(3);
206+
cs.getRgb(color, 0, rgbBuffer);
207+
let [rBase, gBase, bBase] = rgbBuffer;
208+
colorStops.push([0, Util.makeHexColor(rBase, gBase, bBase)]);
209209

210210
let iPrev = 1;
211211
ratio[0] = t0 + step;
212212
fn(ratio, 0, color, 0);
213-
let rgbPrev = cs.getRgb(color, 0);
213+
cs.getRgb(color, 0, rgbBuffer);
214+
let [rPrev, gPrev, bPrev] = rgbBuffer;
214215

215216
// Slopes are rise / run.
216217
// A max slope is from the least value the base component could have been
@@ -221,63 +222,66 @@ class RadialAxialShading extends BaseShading {
221222
// so the conservative deltas are +-1 (+-.5 for base and -+.5 for current).
222223

223224
// The run is iPrev - iBase = 1, so omitted.
224-
let maxSlopeR = rgbPrev[0] - rgbBase[0] + 1;
225-
let maxSlopeG = rgbPrev[1] - rgbBase[1] + 1;
226-
let maxSlopeB = rgbPrev[2] - rgbBase[2] + 1;
227-
let minSlopeR = rgbPrev[0] - rgbBase[0] - 1;
228-
let minSlopeG = rgbPrev[1] - rgbBase[1] - 1;
229-
let minSlopeB = rgbPrev[2] - rgbBase[2] - 1;
225+
let maxSlopeR = rPrev - rBase + 1;
226+
let maxSlopeG = gPrev - gBase + 1;
227+
let maxSlopeB = bPrev - bBase + 1;
228+
let minSlopeR = rPrev - rBase - 1;
229+
let minSlopeG = gPrev - gBase - 1;
230+
let minSlopeB = bPrev - bBase - 1;
230231

231232
for (let i = 2; i < NUMBER_OF_SAMPLES; i++) {
232233
ratio[0] = t0 + i * step;
233234
fn(ratio, 0, color, 0);
234-
rgbColor = cs.getRgb(color, 0);
235+
cs.getRgb(color, 0, rgbBuffer);
236+
const [r, g, b] = rgbBuffer;
235237

236238
// Keep going if the maximum minimum slope <= the minimum maximum slope.
237239
// Otherwise add a rgbPrev color stop and make it the new base.
238240

239241
const run = i - iBase;
240-
maxSlopeR = Math.min(maxSlopeR, (rgbColor[0] - rgbBase[0] + 1) / run);
241-
maxSlopeG = Math.min(maxSlopeG, (rgbColor[1] - rgbBase[1] + 1) / run);
242-
maxSlopeB = Math.min(maxSlopeB, (rgbColor[2] - rgbBase[2] + 1) / run);
243-
minSlopeR = Math.max(minSlopeR, (rgbColor[0] - rgbBase[0] - 1) / run);
244-
minSlopeG = Math.max(minSlopeG, (rgbColor[1] - rgbBase[1] - 1) / run);
245-
minSlopeB = Math.max(minSlopeB, (rgbColor[2] - rgbBase[2] - 1) / run);
242+
maxSlopeR = Math.min(maxSlopeR, (r - rBase + 1) / run);
243+
maxSlopeG = Math.min(maxSlopeG, (g - gBase + 1) / run);
244+
maxSlopeB = Math.min(maxSlopeB, (b - bBase + 1) / run);
245+
minSlopeR = Math.max(minSlopeR, (r - rBase - 1) / run);
246+
minSlopeG = Math.max(minSlopeG, (g - gBase - 1) / run);
247+
minSlopeB = Math.max(minSlopeB, (b - bBase - 1) / run);
246248

247249
const slopesExist =
248250
minSlopeR <= maxSlopeR &&
249251
minSlopeG <= maxSlopeG &&
250252
minSlopeB <= maxSlopeB;
251253

252254
if (!slopesExist) {
253-
const cssColor = Util.makeHexColor(rgbPrev[0], rgbPrev[1], rgbPrev[2]);
255+
const cssColor = Util.makeHexColor(rPrev, gPrev, bPrev);
254256
colorStops.push([iPrev / NUMBER_OF_SAMPLES, cssColor]);
255257

256258
// TODO: When fn frequency is high (iPrev - iBase === 1 twice in a row),
257259
// send the color space and function to do the sampling display side.
258260

259261
// The run is i - iPrev = 1, so omitted.
260-
maxSlopeR = rgbColor[0] - rgbPrev[0] + 1;
261-
maxSlopeG = rgbColor[1] - rgbPrev[1] + 1;
262-
maxSlopeB = rgbColor[2] - rgbPrev[2] + 1;
263-
minSlopeR = rgbColor[0] - rgbPrev[0] - 1;
264-
minSlopeG = rgbColor[1] - rgbPrev[1] - 1;
265-
minSlopeB = rgbColor[2] - rgbPrev[2] - 1;
262+
maxSlopeR = r - rPrev + 1;
263+
maxSlopeG = g - gPrev + 1;
264+
maxSlopeB = b - bPrev + 1;
265+
minSlopeR = r - rPrev - 1;
266+
minSlopeG = g - gPrev - 1;
267+
minSlopeB = b - bPrev - 1;
266268

267269
iBase = iPrev;
268-
rgbBase = rgbPrev;
270+
rBase = rPrev;
271+
gBase = gPrev;
272+
bBase = bPrev;
269273
}
270274

271275
iPrev = i;
272-
rgbPrev = rgbColor;
276+
rPrev = r;
277+
gPrev = g;
278+
bPrev = b;
273279
}
274-
const cssColor = Util.makeHexColor(rgbPrev[0], rgbPrev[1], rgbPrev[2]);
275-
colorStops.push([1, cssColor]);
280+
colorStops.push([1, Util.makeHexColor(rPrev, gPrev, bPrev)]);
276281

277282
let background = "transparent";
278283
if (dict.has("Background")) {
279-
rgbColor = cs.getRgb(dict.get("Background"), 0);
280-
background = Util.makeHexColor(rgbColor[0], rgbColor[1], rgbColor[2]);
284+
background = cs.getRgbHex(dict.get("Background"), 0);
281285
}
282286

283287
if (!extendStart) {

src/display/canvas.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,6 @@ class CanvasGraphics {
13111311
let maskY = layerOffsetY - maskOffsetY;
13121312

13131313
if (backdrop) {
1314-
const backdropRGB = Util.makeHexColor(...backdrop);
13151314
if (
13161315
maskX < 0 ||
13171316
maskY < 0 ||
@@ -1326,7 +1325,7 @@ class CanvasGraphics {
13261325
const ctx = canvas.context;
13271326
ctx.drawImage(maskCanvas, -maskX, -maskY);
13281327
ctx.globalCompositeOperation = "destination-atop";
1329-
ctx.fillStyle = backdropRGB;
1328+
ctx.fillStyle = backdrop;
13301329
ctx.fillRect(0, 0, width, height);
13311330
ctx.globalCompositeOperation = "source-over";
13321331

@@ -1340,7 +1339,7 @@ class CanvasGraphics {
13401339
clip.rect(maskX, maskY, width, height);
13411340
maskCtx.clip(clip);
13421341
maskCtx.globalCompositeOperation = "destination-atop";
1343-
maskCtx.fillStyle = backdropRGB;
1342+
maskCtx.fillStyle = backdrop;
13441343
maskCtx.fillRect(maskX, maskY, width, height);
13451344
maskCtx.restore();
13461345
}
@@ -2193,12 +2192,8 @@ class CanvasGraphics {
21932192
this.current.patternFill = true;
21942193
}
21952194

2196-
setStrokeRGBColor(r, g, b) {
2197-
this.ctx.strokeStyle = this.current.strokeColor = Util.makeHexColor(
2198-
r,
2199-
g,
2200-
b
2201-
);
2195+
setStrokeRGBColor(color) {
2196+
this.ctx.strokeStyle = this.current.strokeColor = color;
22022197
this.current.patternStroke = false;
22032198
}
22042199

@@ -2207,8 +2202,8 @@ class CanvasGraphics {
22072202
this.current.patternStroke = false;
22082203
}
22092204

2210-
setFillRGBColor(r, g, b) {
2211-
this.ctx.fillStyle = this.current.fillColor = Util.makeHexColor(r, g, b);
2205+
setFillRGBColor(color) {
2206+
this.ctx.fillStyle = this.current.fillColor = color;
22122207
this.current.patternFill = false;
22132208
}
22142209

src/display/pattern_helper.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -694,19 +694,14 @@ class TilingPattern {
694694
current = graphics.current;
695695
switch (paintType) {
696696
case PaintType.COLORED:
697-
const ctx = this.ctx;
698-
context.fillStyle = ctx.fillStyle;
699-
context.strokeStyle = ctx.strokeStyle;
700-
current.fillColor = ctx.fillStyle;
701-
current.strokeColor = ctx.strokeStyle;
697+
const { fillStyle, strokeStyle } = this.ctx;
698+
context.fillStyle = current.fillColor = fillStyle;
699+
context.strokeStyle = current.strokeColor = strokeStyle;
702700
break;
703701
case PaintType.UNCOLORED:
704-
const cssColor = Util.makeHexColor(color[0], color[1], color[2]);
705-
context.fillStyle = cssColor;
706-
context.strokeStyle = cssColor;
702+
context.fillStyle = context.strokeStyle = color;
707703
// Set color needed by image masks (fixes issues 3226 and 8741).
708-
current.fillColor = cssColor;
709-
current.strokeColor = cssColor;
704+
current.fillColor = current.strokeColor = color;
710705
break;
711706
default:
712707
throw new FormatError(`Unsupported paint type: ${paintType}`);

0 commit comments

Comments
 (0)