Simplify the ColorSpaceUtils.singletons handling (PR 19564 follow-up)

With the changes in PR 19564 the actual `ColorSpace`-classes where separated from the various static "helper" methods.
Hence it seems that we can now simplify/shorten this old code to instead cache the "standard" ColorSpaces directly on the `ColorSpaceUtils`-class.
This commit is contained in:
Jonas Jenwald 2025-03-05 11:18:06 +01:00
parent fedfdf9d10
commit d8d7235876
5 changed files with 56 additions and 91 deletions

View File

@ -552,15 +552,15 @@ function getRgbColor(color, defaultColor = new Uint8ClampedArray(3)) {
return null; return null;
case 1: // Convert grayscale to RGB case 1: // Convert grayscale to RGB
ColorSpaceUtils.singletons.gray.getRgbItem(color, 0, rgbColor, 0); ColorSpaceUtils.gray.getRgbItem(color, 0, rgbColor, 0);
return rgbColor; return rgbColor;
case 3: // Convert RGB percentages to RGB case 3: // Convert RGB percentages to RGB
ColorSpaceUtils.singletons.rgb.getRgbItem(color, 0, rgbColor, 0); ColorSpaceUtils.rgb.getRgbItem(color, 0, rgbColor, 0);
return rgbColor; return rgbColor;
case 4: // Convert CMYK to RGB case 4: // Convert CMYK to RGB
ColorSpaceUtils.singletons.cmyk.getRgbItem(color, 0, rgbColor, 0); ColorSpaceUtils.cmyk.getRgbItem(color, 0, rgbColor, 0);
return rgbColor; return rgbColor;
default: default:

View File

@ -357,7 +357,7 @@ class Catalog {
isNumberArray(color, 3) && isNumberArray(color, 3) &&
(color[0] !== 0 || color[1] !== 0 || color[2] !== 0) (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)
) { ) {
rgbColor = ColorSpaceUtils.singletons.rgb.getRgb(color, 0); rgbColor = ColorSpaceUtils.rgb.getRgb(color, 0);
} }
const outlineItem = { const outlineItem = {

View File

@ -133,15 +133,15 @@ class ColorSpaceUtils {
switch (cs.name) { switch (cs.name) {
case "G": case "G":
case "DeviceGray": case "DeviceGray":
return this.singletons.gray; return this.gray;
case "RGB": case "RGB":
case "DeviceRGB": case "DeviceRGB":
return this.singletons.rgb; return this.rgb;
case "DeviceRGBA": case "DeviceRGBA":
return this.singletons.rgba; return this.rgba;
case "CMYK": case "CMYK":
case "DeviceCMYK": case "DeviceCMYK":
return this.singletons.cmyk; return this.cmyk;
case "Pattern": case "Pattern":
return new PatternCS(/* baseCS = */ null); return new PatternCS(/* baseCS = */ null);
default: default:
@ -160,7 +160,7 @@ class ColorSpaceUtils {
} }
// Fallback to the default gray color space. // Fallback to the default gray color space.
warn(`Unrecognized ColorSpace: ${cs.name}`); warn(`Unrecognized ColorSpace: ${cs.name}`);
return this.singletons.gray; return this.gray;
} }
} }
if (Array.isArray(cs)) { if (Array.isArray(cs)) {
@ -170,13 +170,13 @@ class ColorSpaceUtils {
switch (mode) { switch (mode) {
case "G": case "G":
case "DeviceGray": case "DeviceGray":
return this.singletons.gray; return this.gray;
case "RGB": case "RGB":
case "DeviceRGB": case "DeviceRGB":
return this.singletons.rgb; return this.rgb;
case "CMYK": case "CMYK":
case "DeviceCMYK": case "DeviceCMYK":
return this.singletons.cmyk; return this.cmyk;
case "CalGray": case "CalGray":
params = xref.fetchIfRef(cs[1]); params = xref.fetchIfRef(cs[1]);
whitePoint = params.getArray("WhitePoint"); whitePoint = params.getArray("WhitePoint");
@ -229,11 +229,11 @@ class ColorSpaceUtils {
warn("ICCBased color space: Ignoring incorrect /Alternate entry."); warn("ICCBased color space: Ignoring incorrect /Alternate entry.");
} }
if (numComps === 1) { if (numComps === 1) {
return this.singletons.gray; return this.gray;
} else if (numComps === 3) { } else if (numComps === 3) {
return this.singletons.rgb; return this.rgb;
} else if (numComps === 4) { } else if (numComps === 4) {
return this.singletons.cmyk; return this.cmyk;
} }
break; break;
case "Pattern": case "Pattern":
@ -264,29 +264,28 @@ class ColorSpaceUtils {
default: default:
// Fallback to the default gray color space. // Fallback to the default gray color space.
warn(`Unimplemented ColorSpace object: ${mode}`); warn(`Unimplemented ColorSpace object: ${mode}`);
return this.singletons.gray; return this.gray;
} }
} }
// Fallback to the default gray color space. // Fallback to the default gray color space.
warn(`Unrecognized ColorSpace object: ${cs}`); warn(`Unrecognized ColorSpace object: ${cs}`);
return this.singletons.gray; return this.gray;
} }
static get singletons() { static get gray() {
return shadow(this, "singletons", { return shadow(this, "gray", new DeviceGrayCS());
get gray() { }
return shadow(this, "gray", new DeviceGrayCS());
}, static get rgb() {
get rgb() { return shadow(this, "rgb", new DeviceRgbCS());
return shadow(this, "rgb", new DeviceRgbCS()); }
},
get rgba() { static get rgba() {
return shadow(this, "rgba", new DeviceRgbaCS()); return shadow(this, "rgba", new DeviceRgbaCS());
}, }
get cmyk() {
return shadow(this, "cmyk", new DeviceCmykCS()); static get cmyk() {
}, return shadow(this, "cmyk", new DeviceCmykCS());
});
} }
} }

View File

@ -73,28 +73,13 @@ class DefaultAppearanceEvaluator extends EvaluatorPreprocessor {
} }
break; break;
case OPS.setFillRGBColor: case OPS.setFillRGBColor:
ColorSpaceUtils.singletons.rgb.getRgbItem( ColorSpaceUtils.rgb.getRgbItem(args, 0, result.fontColor, 0);
args,
0,
result.fontColor,
0
);
break; break;
case OPS.setFillGray: case OPS.setFillGray:
ColorSpaceUtils.singletons.gray.getRgbItem( ColorSpaceUtils.gray.getRgbItem(args, 0, result.fontColor, 0);
args,
0,
result.fontColor,
0
);
break; break;
case OPS.setFillCMYKColor: case OPS.setFillCMYKColor:
ColorSpaceUtils.singletons.cmyk.getRgbItem( ColorSpaceUtils.cmyk.getRgbItem(args, 0, result.fontColor, 0);
args,
0,
result.fontColor,
0
);
break; break;
} }
} }
@ -132,7 +117,7 @@ class AppearanceStreamEvaluator extends EvaluatorPreprocessor {
fontSize: 0, fontSize: 0,
fontName: "", fontName: "",
fontColor: /* black = */ new Uint8ClampedArray(3), fontColor: /* black = */ new Uint8ClampedArray(3),
fillColorSpace: ColorSpaceUtils.singletons.gray, fillColorSpace: ColorSpaceUtils.gray,
}; };
let breakLoop = false; let breakLoop = false;
const stack = []; const stack = [];
@ -186,28 +171,13 @@ class AppearanceStreamEvaluator extends EvaluatorPreprocessor {
cs.getRgbItem(args, 0, result.fontColor, 0); cs.getRgbItem(args, 0, result.fontColor, 0);
break; break;
case OPS.setFillRGBColor: case OPS.setFillRGBColor:
ColorSpaceUtils.singletons.rgb.getRgbItem( ColorSpaceUtils.rgb.getRgbItem(args, 0, result.fontColor, 0);
args,
0,
result.fontColor,
0
);
break; break;
case OPS.setFillGray: case OPS.setFillGray:
ColorSpaceUtils.singletons.gray.getRgbItem( ColorSpaceUtils.gray.getRgbItem(args, 0, result.fontColor, 0);
args,
0,
result.fontColor,
0
);
break; break;
case OPS.setFillCMYKColor: case OPS.setFillCMYKColor:
ColorSpaceUtils.singletons.cmyk.getRgbItem( ColorSpaceUtils.cmyk.getRgbItem(args, 0, result.fontColor, 0);
args,
0,
result.fontColor,
0
);
break; break;
case OPS.showText: case OPS.showText:
case OPS.showSpacedText: case OPS.showSpacedText:

View File

@ -501,7 +501,7 @@ class PartialEvaluator {
} }
if (smask?.backdrop) { if (smask?.backdrop) {
colorSpace ||= ColorSpaceUtils.singletons.rgb; colorSpace ||= ColorSpaceUtils.rgb;
smask.backdrop = colorSpace.getRgb(smask.backdrop, 0); smask.backdrop = colorSpace.getRgb(smask.backdrop, 0);
} }
@ -1992,7 +1992,7 @@ class PartialEvaluator {
next( next(
self._handleColorSpace(fillCS).then(colorSpace => { self._handleColorSpace(fillCS).then(colorSpace => {
stateManager.state.fillColorSpace = stateManager.state.fillColorSpace =
colorSpace || ColorSpaceUtils.singletons.gray; colorSpace || ColorSpaceUtils.gray;
}) })
); );
return; return;
@ -2011,7 +2011,7 @@ class PartialEvaluator {
next( next(
self._handleColorSpace(strokeCS).then(colorSpace => { self._handleColorSpace(strokeCS).then(colorSpace => {
stateManager.state.strokeColorSpace = stateManager.state.strokeColorSpace =
colorSpace || ColorSpaceUtils.singletons.gray; colorSpace || ColorSpaceUtils.gray;
}) })
); );
return; return;
@ -2027,41 +2027,38 @@ class PartialEvaluator {
fn = OPS.setStrokeRGBColor; fn = OPS.setStrokeRGBColor;
break; break;
case OPS.setFillGray: case OPS.setFillGray:
stateManager.state.fillColorSpace = ColorSpaceUtils.singletons.gray; stateManager.state.fillColorSpace = ColorSpaceUtils.gray;
args = ColorSpaceUtils.singletons.gray.getRgb(args, 0); args = ColorSpaceUtils.gray.getRgb(args, 0);
fn = OPS.setFillRGBColor; fn = OPS.setFillRGBColor;
break; break;
case OPS.setStrokeGray: case OPS.setStrokeGray:
stateManager.state.strokeColorSpace = stateManager.state.strokeColorSpace = ColorSpaceUtils.gray;
ColorSpaceUtils.singletons.gray; args = ColorSpaceUtils.gray.getRgb(args, 0);
args = ColorSpaceUtils.singletons.gray.getRgb(args, 0);
fn = OPS.setStrokeRGBColor; fn = OPS.setStrokeRGBColor;
break; break;
case OPS.setFillCMYKColor: case OPS.setFillCMYKColor:
stateManager.state.fillColorSpace = ColorSpaceUtils.singletons.cmyk; stateManager.state.fillColorSpace = ColorSpaceUtils.cmyk;
args = ColorSpaceUtils.singletons.cmyk.getRgb(args, 0); args = ColorSpaceUtils.cmyk.getRgb(args, 0);
fn = OPS.setFillRGBColor; fn = OPS.setFillRGBColor;
break; break;
case OPS.setStrokeCMYKColor: case OPS.setStrokeCMYKColor:
stateManager.state.strokeColorSpace = stateManager.state.strokeColorSpace = ColorSpaceUtils.cmyk;
ColorSpaceUtils.singletons.cmyk; args = ColorSpaceUtils.cmyk.getRgb(args, 0);
args = ColorSpaceUtils.singletons.cmyk.getRgb(args, 0);
fn = OPS.setStrokeRGBColor; fn = OPS.setStrokeRGBColor;
break; break;
case OPS.setFillRGBColor: case OPS.setFillRGBColor:
stateManager.state.fillColorSpace = ColorSpaceUtils.singletons.rgb; stateManager.state.fillColorSpace = ColorSpaceUtils.rgb;
args = ColorSpaceUtils.singletons.rgb.getRgb(args, 0); args = ColorSpaceUtils.rgb.getRgb(args, 0);
break; break;
case OPS.setStrokeRGBColor: case OPS.setStrokeRGBColor:
stateManager.state.strokeColorSpace = stateManager.state.strokeColorSpace = ColorSpaceUtils.rgb;
ColorSpaceUtils.singletons.rgb; args = ColorSpaceUtils.rgb.getRgb(args, 0);
args = ColorSpaceUtils.singletons.rgb.getRgb(args, 0);
break; break;
case OPS.setFillColorN: case OPS.setFillColorN:
cs = stateManager.state.patternFillColorSpace; cs = stateManager.state.patternFillColorSpace;
if (!cs) { if (!cs) {
if (isNumberArray(args, null)) { if (isNumberArray(args, null)) {
args = ColorSpaceUtils.singletons.gray.getRgb(args, 0); args = ColorSpaceUtils.gray.getRgb(args, 0);
fn = OPS.setFillRGBColor; fn = OPS.setFillRGBColor;
break; break;
} }
@ -2093,7 +2090,7 @@ class PartialEvaluator {
cs = stateManager.state.patternStrokeColorSpace; cs = stateManager.state.patternStrokeColorSpace;
if (!cs) { if (!cs) {
if (isNumberArray(args, null)) { if (isNumberArray(args, null)) {
args = ColorSpaceUtils.singletons.gray.getRgb(args, 0); args = ColorSpaceUtils.gray.getRgb(args, 0);
fn = OPS.setStrokeRGBColor; fn = OPS.setStrokeRGBColor;
break; break;
} }
@ -4884,8 +4881,7 @@ class EvalState {
this.ctm = new Float32Array(IDENTITY_MATRIX); this.ctm = new Float32Array(IDENTITY_MATRIX);
this.font = null; this.font = null;
this.textRenderingMode = TextRenderingMode.FILL; this.textRenderingMode = TextRenderingMode.FILL;
this._fillColorSpace = ColorSpaceUtils.singletons.gray; this._fillColorSpace = this._strokeColorSpace = ColorSpaceUtils.gray;
this._strokeColorSpace = ColorSpaceUtils.singletons.gray;
this.patternFillColorSpace = null; this.patternFillColorSpace = null;
this.patternStrokeColorSpace = null; this.patternStrokeColorSpace = null;
} }