From 542c9c4c7a4c5fb67177f5c80cfb74bc63ca639b Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Wed, 21 May 2014 12:47:42 -0500 Subject: [PATCH] Moves ColorSpace logic into evaluator --- src/core/evaluator.js | 149 +++++++++++++++++++++++++--------- src/display/canvas.js | 106 +++--------------------- src/display/pattern_helper.js | 4 +- src/shared/util.js | 5 -- 4 files changed, 121 insertions(+), 143 deletions(-) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 2498d979a..90d26b275 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -131,13 +131,19 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { }; var groupSubtype = group.get('S'); + var colorSpace; if (isName(groupSubtype) && groupSubtype.name === 'Transparency') { groupOptions.isolated = (group.get('I') || false); groupOptions.knockout = (group.get('K') || false); - var colorSpace = group.get('CS'); - groupOptions.colorSpace = (colorSpace ? - ColorSpace.parseToIR(colorSpace, this.xref, resources) : null); + colorSpace = (group.has('CS') ? + ColorSpace.parse(group.get('CS'), this.xref, resources) : null); } + + if (smask && smask.backdrop) { + colorSpace = colorSpace || ColorSpace.singletons.rgb; + smask.backdrop = colorSpace.getRgb(smask.backdrop, 0); + } + operatorList.addOp(OPS.beginGroup, [groupOptions]); } @@ -552,6 +558,36 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } }, + handleColorN: function PartialEvaluator_handleColorN(operatorList, fn, args, + cs, patterns, resources, xref) { + // compile tiling patterns + var patternName = args[args.length - 1]; + // SCN/scn applies patterns along with normal colors + var pattern; + if (isName(patternName) && + (pattern = patterns.get(patternName.name))) { + var dict = (isStream(pattern) ? pattern.dict : pattern); + var typeNum = dict.get('PatternType'); + + if (typeNum == TILING_PATTERN) { + var color = cs.base ? cs.base.getRgb(args, 0) : null; + return this.handleTilingType(fn, color, resources, pattern, + dict, operatorList); + } else if (typeNum == SHADING_PATTERN) { + var shading = dict.get('Shading'); + var matrix = dict.get('Matrix'); + pattern = Pattern.parseShading(shading, matrix, xref, resources); + operatorList.addOp(fn, pattern.getIR()); + return Promise.resolve(); + } else { + return Promise.reject('Unknown PatternType: ' + typeNum); + } + } + // TODO shall we fail here? + operatorList.addOp(fn, args); + return Promise.resolve(); + }, + getOperatorList: function PartialEvaluator_getOperatorList(stream, resources, operatorList, @@ -568,49 +604,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var patterns = (resources.get('Pattern') || Dict.empty); var stateManager = new StateManager(initialState || new EvalState()); var preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager); - var shading; var timeSlotManager = new TimeSlotManager(); return new Promise(function next(resolve, reject) { timeSlotManager.reset(); - var stop, operation, i, ii; + var stop, operation, i, ii, cs; while (!(stop = timeSlotManager.check()) && (operation = preprocessor.read())) { var args = operation.args; var fn = operation.fn; switch (fn | 0) { - case OPS.setStrokeColorN: - case OPS.setFillColorN: - if (args[args.length - 1].code) { - break; - } - // compile tiling patterns - var patternName = args[args.length - 1]; - // SCN/scn applies patterns along with normal colors - var pattern; - if (isName(patternName) && - (pattern = patterns.get(patternName.name))) { - var dict = (isStream(pattern) ? pattern.dict : pattern); - var typeNum = dict.get('PatternType'); - - if (typeNum == TILING_PATTERN) { - return self.handleTilingType(fn, args, resources, pattern, - dict, operatorList).then( - function() { - next(resolve, reject); - }, reject); - } else if (typeNum == SHADING_PATTERN) { - shading = dict.get('Shading'); - var matrix = dict.get('Matrix'); - pattern = Pattern.parseShading(shading, matrix, xref, - resources); - args = pattern.getIR(); - } else { - error('Unknown PatternType ' + typeNum); - } - } - break; case OPS.paintXObject: if (args[0].code) { break; @@ -692,18 +696,83 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { case OPS.setTextRenderingMode: stateManager.state.textRenderingMode = args[0]; break; - // Parse the ColorSpace data to a raw format. + case OPS.setFillColorSpace: + stateManager.state.fillColorSpace = + ColorSpace.parse(args[0], xref, resources); + continue; case OPS.setStrokeColorSpace: - args = [ColorSpace.parseToIR(args[0], xref, resources)]; + stateManager.state.strokeColorSpace = + ColorSpace.parse(args[0], xref, resources); + continue; + case OPS.setFillColor: + cs = stateManager.state.fillColorSpace; + args = cs.getRgb(args, 0); + fn = OPS.setFillRGBColor; break; + case OPS.setStrokeColor: + cs = stateManager.state.strokeColorSpace; + args = cs.getRgb(args, 0); + fn = OPS.setStrokeRGBColor; + break; + case OPS.setFillGray: + stateManager.state.fillColorSpace = ColorSpace.singletons.gray; + args = ColorSpace.singletons.gray.getRgb(args, 0); + fn = OPS.setFillRGBColor; + break; + case OPS.setStrokeGray: + stateManager.state.strokeColorSpace = ColorSpace.singletons.gray; + args = ColorSpace.singletons.gray.getRgb(args, 0); + fn = OPS.setStrokeRGBColor; + break; + case OPS.setFillCMYKColor: + stateManager.state.fillColorSpace = ColorSpace.singletons.cmyk; + args = ColorSpace.singletons.cmyk.getRgb(args, 0); + fn = OPS.setFillRGBColor; + break; + case OPS.setStrokeCMYKColor: + stateManager.state.strokeColorSpace = ColorSpace.singletons.cmyk; + args = ColorSpace.singletons.cmyk.getRgb(args, 0); + fn = OPS.setStrokeRGBColor; + break; + case OPS.setFillRGBColor: + stateManager.state.fillColorSpace = ColorSpace.singletons.rgb; + args = ColorSpace.singletons.rgb.getRgb(args, 0); + break; + case OPS.setStrokeRGBColor: + stateManager.state.strokeColorSpace = ColorSpace.singletons.rgb; + args = ColorSpace.singletons.rgb.getRgb(args, 0); + break; + case OPS.setFillColorN: + cs = stateManager.state.fillColorSpace; + if (cs.name === 'Pattern') { + return self.handleColorN(operatorList, OPS.setFillColorN, + args, cs, patterns, resources, xref).then(function() { + next(resolve, reject); + }, reject); + } + args = cs.getRgb(args, 0); + fn = OPS.setFillRGBColor; + break; + case OPS.setStrokeColorN: + cs = stateManager.state.strokeColorSpace; + if (cs.name === 'Pattern') { + return self.handleColorN(operatorList, OPS.setStrokeColorN, + args, cs, patterns, resources, xref).then(function() { + next(resolve, reject); + }, reject); + } + args = cs.getRgb(args, 0); + fn = OPS.setStrokeRGBColor; + break; + case OPS.shadingFill: var shadingRes = resources.get('Shading'); if (!shadingRes) { error('No shading resource found'); } - shading = shadingRes.get(args[0].name); + var shading = shadingRes.get(args[0].name); if (!shading) { error('No shading object found'); } @@ -1840,6 +1909,8 @@ var EvalState = (function EvalStateClosure() { this.ctm = new Float32Array(IDENTITY_MATRIX); this.font = null; this.textRenderingMode = TextRenderingMode.FILL; + this.fillColorSpace = ColorSpace.singletons.gray; + this.strokeColorSpace = ColorSpace.singletons.gray; } EvalState.prototype = { clone: function CanvasExtraState_clone() { diff --git a/src/display/canvas.js b/src/display/canvas.js index 5566caceb..dca61455d 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -14,11 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals ColorSpace, DeviceCmykCS, DeviceGrayCS, DeviceRgbCS, error, PDFJS, +/* globals error, PDFJS, assert, info, shadow, TextRenderingMode, FONT_IDENTITY_MATRIX, Uint32ArrayView, IDENTITY_MATRIX, ImageData, ImageKind, isArray, isNum, TilingPattern, OPS, Promise, Util, warn, - assert, info, shadow, TextRenderingMode, getShadingPatternFromIR, - WebGLUtils */ + getShadingPatternFromIR, WebGLUtils */ 'use strict'; @@ -366,13 +365,6 @@ var CanvasExtraState = (function CanvasExtraStateClosure() { this.textHScale = 1; this.textRenderingMode = TextRenderingMode.FILL; this.textRise = 0; - // Color spaces - this.fillColorSpace = ColorSpace.singletons.gray; - this.fillColorSpaceObj = null; - this.strokeColorSpace = ColorSpace.singletons.gray; - this.strokeColorSpaceObj = null; - this.fillColorObj = null; - this.strokeColorObj = null; // Default fore and background colors this.fillColor = '#000000'; this.strokeColor = '#000000'; @@ -673,11 +665,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { ctx.setTransform(smask.scaleX, 0, 0, smask.scaleY, smask.offsetX, smask.offsetY); - var backdrop; - if (smask.backdrop) { - var cs = smask.colorSpace || ColorSpace.singletons.rgb; - backdrop = cs.getRgb(smask.backdrop, 0); - } + var backdrop = smask.backdrop || null; if (WebGLUtils.isEnabled) { var composed = WebGLUtils.composeSMask(layerCtx.canvas, mask, {subtype: smask.subtype, backdrop: backdrop}); @@ -1519,28 +1507,10 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { }, // Color - setStrokeColorSpace: function CanvasGraphics_setStrokeColorSpace(raw) { - this.current.strokeColorSpace = ColorSpace.fromIR(raw); - }, - setFillColorSpace: function CanvasGraphics_setFillColorSpace(raw) { - this.current.fillColorSpace = ColorSpace.fromIR(raw); - }, - setStrokeColor: function CanvasGraphics_setStrokeColor(/*...*/) { - var cs = this.current.strokeColorSpace; - var rgbColor = cs.getRgb(arguments, 0); - var color = Util.makeCssRgb(rgbColor); - this.ctx.strokeStyle = color; - this.current.strokeColor = color; - }, - getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR, cs) { + getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR) { var pattern; if (IR[0] == 'TilingPattern') { - var args = IR[1]; - var base = cs.base; - var color; - if (base) { - color = base.getRgb(args, 0); - } + var color = IR[1]; pattern = new TilingPattern(IR, color, this.ctx, this.objs, this.commonObjs, this.baseTransform); } else { @@ -1549,73 +1519,18 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { return pattern; }, setStrokeColorN: function CanvasGraphics_setStrokeColorN(/*...*/) { - var cs = this.current.strokeColorSpace; - - if (cs.name == 'Pattern') { - this.current.strokeColor = this.getColorN_Pattern(arguments, cs); - } else { - this.setStrokeColor.apply(this, arguments); - } - }, - setFillColor: function CanvasGraphics_setFillColor(/*...*/) { - var cs = this.current.fillColorSpace; - var rgbColor = cs.getRgb(arguments, 0); - var color = Util.makeCssRgb(rgbColor); - this.ctx.fillStyle = color; - this.current.fillColor = color; + this.current.strokeColor = this.getColorN_Pattern(arguments); }, setFillColorN: function CanvasGraphics_setFillColorN(/*...*/) { - var cs = this.current.fillColorSpace; - - if (cs.name == 'Pattern') { - this.current.fillColor = this.getColorN_Pattern(arguments, cs); - } else { - this.setFillColor.apply(this, arguments); - } - }, - setStrokeGray: function CanvasGraphics_setStrokeGray(gray) { - this.current.strokeColorSpace = ColorSpace.singletons.gray; - - var rgbColor = this.current.strokeColorSpace.getRgb(arguments, 0); - var color = Util.makeCssRgb(rgbColor); - this.ctx.strokeStyle = color; - this.current.strokeColor = color; - }, - setFillGray: function CanvasGraphics_setFillGray(gray) { - this.current.fillColorSpace = ColorSpace.singletons.gray; - - var rgbColor = this.current.fillColorSpace.getRgb(arguments, 0); - var color = Util.makeCssRgb(rgbColor); - this.ctx.fillStyle = color; - this.current.fillColor = color; + this.current.fillColor = this.getColorN_Pattern(arguments); }, setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) { - this.current.strokeColorSpace = ColorSpace.singletons.rgb; - - var rgbColor = this.current.strokeColorSpace.getRgb(arguments, 0); - var color = Util.makeCssRgb(rgbColor); + var color = Util.makeCssRgb(arguments); this.ctx.strokeStyle = color; this.current.strokeColor = color; }, setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) { - this.current.fillColorSpace = ColorSpace.singletons.rgb; - - var rgbColor = this.current.fillColorSpace.getRgb(arguments, 0); - var color = Util.makeCssRgb(rgbColor); - this.ctx.fillStyle = color; - this.current.fillColor = color; - }, - setStrokeCMYKColor: function CanvasGraphics_setStrokeCMYKColor(c, m, y, k) { - this.current.strokeColorSpace = ColorSpace.singletons.cmyk; - - var color = Util.makeCssCmyk(arguments); - this.ctx.strokeStyle = color; - this.current.strokeColor = color; - }, - setFillCMYKColor: function CanvasGraphics_setFillCMYKColor(c, m, y, k) { - this.current.fillColorSpace = ColorSpace.singletons.cmyk; - - var color = Util.makeCssCmyk(arguments); + var color = Util.makeCssRgb(arguments); this.ctx.fillStyle = color; this.current.fillColor = color; }, @@ -1774,8 +1689,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { scaleX: scaleX, scaleY: scaleY, subtype: group.smask.subtype, - backdrop: group.smask.backdrop, - colorSpace: group.colorSpace && ColorSpace.fromIR(group.colorSpace) + backdrop: group.smask.backdrop }); } else { // Setup the current ctx so when the group is popped we draw it at the diff --git a/src/display/pattern_helper.js b/src/display/pattern_helper.js index d2a8c79f7..2dcf08430 100644 --- a/src/display/pattern_helper.js +++ b/src/display/pattern_helper.js @@ -291,7 +291,6 @@ var TilingPattern = (function TilingPatternClosure() { var MAX_PATTERN_SIZE = 3000; // 10in @ 300dpi shall be enough function TilingPattern(IR, color, ctx, objs, commonObjs, baseTransform) { - this.name = IR[1][0].name; this.operatorList = IR[2]; this.matrix = IR[3] || [1, 0, 0, 1, 0, 0]; this.bbox = IR[4]; @@ -401,8 +400,7 @@ var TilingPattern = (function TilingPatternClosure() { context.strokeStyle = ctx.strokeStyle; break; case PaintType.UNCOLORED: - var rgbColor = ColorSpace.singletons.rgb.getRgb(color, 0); - var cssColor = Util.makeCssRgb(rgbColor); + var cssColor = Util.makeCssRgb(color); context.fillStyle = cssColor; context.strokeStyle = cssColor; break; diff --git a/src/shared/util.js b/src/shared/util.js index 1c3f21ca0..de115ce93 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -531,11 +531,6 @@ var Util = PDFJS.Util = (function UtilClosure() { return 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')'; }; - Util.makeCssCmyk = function Util_makeCssCmyk(cmyk) { - var rgb = ColorSpace.singletons.cmyk.getRgb(cmyk, 0); - return Util.makeCssRgb(rgb); - }; - // Concatenates two transformation matrices together and returns the result. Util.transform = function Util_transform(m1, m2) { return [