Merge pull request #13300 from Snuffleupagus/canvas-class

Convert the code in `src/display/canvas.js` to use standard classes
This commit is contained in:
Tim van der Meij 2021-04-27 13:19:36 +02:00 committed by GitHub
commit ca668587c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -51,7 +51,9 @@ const LINEWIDTH_SCALE_FACTOR = 1.000001;
function addContextCurrentTransform(ctx) { function addContextCurrentTransform(ctx) {
// If the context doesn't expose a `mozCurrentTransform`, add a JS based one. // If the context doesn't expose a `mozCurrentTransform`, add a JS based one.
if (!ctx.mozCurrentTransform) { if (ctx.mozCurrentTransform) {
return;
}
ctx._originalSave = ctx.save; ctx._originalSave = ctx.save;
ctx._originalRestore = ctx.restore; ctx._originalRestore = ctx.restore;
ctx._originalRotate = ctx.rotate; ctx._originalRotate = ctx.rotate;
@ -98,14 +100,7 @@ function addContextCurrentTransform(ctx) {
// http://www.wolframalpha.com/input/? // http://www.wolframalpha.com/input/?
// i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}} // i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}}
const m = this._transformMatrix; const [a, b, c, d, e, f] = this._transformMatrix;
const a = m[0],
b = m[1],
c = m[2],
d = m[3],
e = m[4],
f = m[5];
const ad_bc = a * d - b * c; const ad_bc = a * d - b * c;
const bc_ad = b * c - a * d; const bc_ad = b * c - a * d;
@ -197,21 +192,14 @@ function addContextCurrentTransform(ctx) {
this._originalRotate(angle); this._originalRotate(angle);
}; };
} }
}
const CachedCanvases = (function CachedCanvasesClosure() { class CachedCanvases {
// eslint-disable-next-line no-shadow constructor(canvasFactory) {
function CachedCanvases(canvasFactory) {
this.canvasFactory = canvasFactory; this.canvasFactory = canvasFactory;
this.cache = Object.create(null); this.cache = Object.create(null);
} }
CachedCanvases.prototype = {
getCanvas: function CachedCanvases_getCanvas( getCanvas(id, width, height, trackTransform) {
id,
width,
height,
trackTransform
) {
let canvasEntry; let canvasEntry;
if (this.cache[id] !== undefined) { if (this.cache[id] !== undefined) {
canvasEntry = this.cache[id]; canvasEntry = this.cache[id];
@ -226,17 +214,16 @@ const CachedCanvases = (function CachedCanvasesClosure() {
addContextCurrentTransform(canvasEntry.context); addContextCurrentTransform(canvasEntry.context);
} }
return canvasEntry; return canvasEntry;
}, }
clear() { clear() {
for (const id in this.cache) { for (const id in this.cache) {
const canvasEntry = this.cache[id]; const canvasEntry = this.cache[id];
this.canvasFactory.destroy(canvasEntry); this.canvasFactory.destroy(canvasEntry);
delete this.cache[id]; delete this.cache[id];
} }
}, }
}; }
return CachedCanvases;
})();
function compileType3Glyph(imgData) { function compileType3Glyph(imgData) {
const POINT_TO_PROCESS_LIMIT = 1000; const POINT_TO_PROCESS_LIMIT = 1000;
@ -411,9 +398,8 @@ function compileType3Glyph(imgData) {
return drawOutline; return drawOutline;
} }
const CanvasExtraState = (function CanvasExtraStateClosure() { class CanvasExtraState {
// eslint-disable-next-line no-shadow constructor() {
function CanvasExtraState() {
// Are soft masks and alpha values shapes or opacities? // Are soft masks and alpha values shapes or opacities?
this.alphaIsShape = false; this.alphaIsShape = false;
this.fontSize = 0; this.fontSize = 0;
@ -447,17 +433,15 @@ const CanvasExtraState = (function CanvasExtraStateClosure() {
this.transferMaps = null; this.transferMaps = null;
} }
CanvasExtraState.prototype = { clone() {
clone: function CanvasExtraState_clone() {
return Object.create(this); return Object.create(this);
}, }
setCurrentPoint: function CanvasExtraState_setCurrentPoint(x, y) {
setCurrentPoint(x, y) {
this.x = x; this.x = x;
this.y = y; this.y = y;
}, }
}; }
return CanvasExtraState;
})();
/** /**
* @type {any} * @type {any}
@ -469,50 +453,6 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
// Defines the number of steps before checking the execution time // Defines the number of steps before checking the execution time
const EXECUTION_STEPS = 10; const EXECUTION_STEPS = 10;
// eslint-disable-next-line no-shadow
function CanvasGraphics(
canvasCtx,
commonObjs,
objs,
canvasFactory,
webGLContext,
imageLayer,
optionalContentConfig
) {
this.ctx = canvasCtx;
this.current = new CanvasExtraState();
this.stateStack = [];
this.pendingClip = null;
this.pendingEOFill = false;
this.res = null;
this.xobjs = null;
this.commonObjs = commonObjs;
this.objs = objs;
this.canvasFactory = canvasFactory;
this.webGLContext = webGLContext;
this.imageLayer = imageLayer;
this.groupStack = [];
this.processingType3 = null;
// Patterns are painted relative to the initial page/form transform, see pdf
// spec 8.7.2 NOTE 1.
this.baseTransform = null;
this.baseTransformStack = [];
this.groupLevel = 0;
this.smaskStack = [];
this.smaskCounter = 0;
this.tempSMask = null;
this.contentVisible = true;
this.markedContentStack = [];
this.optionalContentConfig = optionalContentConfig;
this.cachedCanvases = new CachedCanvases(this.canvasFactory);
if (canvasCtx) {
// NOTE: if mozCurrentTransform is polyfilled, then the current state of
// the transformation must already be set in canvasCtx._transformMatrix.
addContextCurrentTransform(canvasCtx);
}
this._cachedGetSinglePixelWidth = null;
}
function putBinaryImageData(ctx, imgData, transferMaps = null) { function putBinaryImageData(ctx, imgData, transferMaps = null) {
if (typeof ImageData !== "undefined" && imgData instanceof ImageData) { if (typeof ImageData !== "undefined" && imgData instanceof ImageData) {
ctx.putImageData(imgData, 0, 0); ctx.putImageData(imgData, 0, 0);
@ -912,7 +852,51 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
const NORMAL_CLIP = {}; const NORMAL_CLIP = {};
const EO_CLIP = {}; const EO_CLIP = {};
CanvasGraphics.prototype = { // eslint-disable-next-line no-shadow
class CanvasGraphics {
constructor(
canvasCtx,
commonObjs,
objs,
canvasFactory,
webGLContext,
imageLayer,
optionalContentConfig
) {
this.ctx = canvasCtx;
this.current = new CanvasExtraState();
this.stateStack = [];
this.pendingClip = null;
this.pendingEOFill = false;
this.res = null;
this.xobjs = null;
this.commonObjs = commonObjs;
this.objs = objs;
this.canvasFactory = canvasFactory;
this.webGLContext = webGLContext;
this.imageLayer = imageLayer;
this.groupStack = [];
this.processingType3 = null;
// Patterns are painted relative to the initial page/form transform, see
// PDF spec 8.7.2 NOTE 1.
this.baseTransform = null;
this.baseTransformStack = [];
this.groupLevel = 0;
this.smaskStack = [];
this.smaskCounter = 0;
this.tempSMask = null;
this.contentVisible = true;
this.markedContentStack = [];
this.optionalContentConfig = optionalContentConfig;
this.cachedCanvases = new CachedCanvases(this.canvasFactory);
if (canvasCtx) {
// NOTE: if mozCurrentTransform is polyfilled, then the current state of
// the transformation must already be set in canvasCtx._transformMatrix.
addContextCurrentTransform(canvasCtx);
}
this._cachedGetSinglePixelWidth = null;
}
beginDrawing({ beginDrawing({
transform, transform,
viewport, viewport,
@ -967,9 +951,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
if (this.imageLayer) { if (this.imageLayer) {
this.imageLayer.beginLayout(); this.imageLayer.beginLayout();
} }
}, }
executeOperatorList: function CanvasGraphics_executeOperatorList( executeOperatorList(
operatorList, operatorList,
executionStartIdx, executionStartIdx,
continueCallback, continueCallback,
@ -1038,9 +1022,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
// If the operatorList isn't executed completely yet OR the execution // If the operatorList isn't executed completely yet OR the execution
// time was short enough, do another execution round. // time was short enough, do another execution round.
} }
}, }
endDrawing: function CanvasGraphics_endDrawing() { endDrawing() {
// Finishing all opened operations such as SMask group painting. // Finishing all opened operations such as SMask group painting.
while (this.stateStack.length || this.current.activeSMask !== null) { while (this.stateStack.length || this.current.activeSMask !== null) {
this.restore(); this.restore();
@ -1063,36 +1047,43 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
if (this.imageLayer) { if (this.imageLayer) {
this.imageLayer.endLayout(); this.imageLayer.endLayout();
} }
}, }
// Graphics state // Graphics state
setLineWidth: function CanvasGraphics_setLineWidth(width) { setLineWidth(width) {
this.current.lineWidth = width; this.current.lineWidth = width;
this.ctx.lineWidth = width; this.ctx.lineWidth = width;
}, }
setLineCap: function CanvasGraphics_setLineCap(style) {
setLineCap(style) {
this.ctx.lineCap = LINE_CAP_STYLES[style]; this.ctx.lineCap = LINE_CAP_STYLES[style];
}, }
setLineJoin: function CanvasGraphics_setLineJoin(style) {
setLineJoin(style) {
this.ctx.lineJoin = LINE_JOIN_STYLES[style]; this.ctx.lineJoin = LINE_JOIN_STYLES[style];
}, }
setMiterLimit: function CanvasGraphics_setMiterLimit(limit) {
setMiterLimit(limit) {
this.ctx.miterLimit = limit; this.ctx.miterLimit = limit;
}, }
setDash: function CanvasGraphics_setDash(dashArray, dashPhase) {
setDash(dashArray, dashPhase) {
const ctx = this.ctx; const ctx = this.ctx;
if (ctx.setLineDash !== undefined) { if (ctx.setLineDash !== undefined) {
ctx.setLineDash(dashArray); ctx.setLineDash(dashArray);
ctx.lineDashOffset = dashPhase; ctx.lineDashOffset = dashPhase;
} }
}, }
setRenderingIntent(intent) { setRenderingIntent(intent) {
// This operation is ignored since we haven't found a use case for it yet. // This operation is ignored since we haven't found a use case for it yet.
}, }
setFlatness(flatness) { setFlatness(flatness) {
// This operation is ignored since we haven't found a use case for it yet. // This operation is ignored since we haven't found a use case for it yet.
}, }
setGState: function CanvasGraphics_setGState(states) {
setGState(states) {
for (let i = 0, ii = states.length; i < ii; i++) { for (let i = 0, ii = states.length; i < ii; i++) {
const state = states[i]; const state = states[i];
const key = state[0]; const key = state[0];
@ -1158,8 +1149,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.current.transferMaps = value; this.current.transferMaps = value;
} }
} }
}, }
beginSMaskGroup: function CanvasGraphics_beginSMaskGroup() {
beginSMaskGroup() {
const activeSMask = this.current.activeSMask; const activeSMask = this.current.activeSMask;
const drawnWidth = activeSMask.canvas.width; const drawnWidth = activeSMask.canvas.width;
const drawnHeight = activeSMask.canvas.height; const drawnHeight = activeSMask.canvas.height;
@ -1191,8 +1183,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
]); ]);
this.groupStack.push(currentCtx); this.groupStack.push(currentCtx);
this.groupLevel++; this.groupLevel++;
}, }
suspendSMaskGroup: function CanvasGraphics_endSMaskGroup() {
suspendSMaskGroup() {
// Similar to endSMaskGroup, the intermediate canvas has to be composed // Similar to endSMaskGroup, the intermediate canvas has to be composed
// and future ctx state restored. // and future ctx state restored.
const groupCtx = this.ctx; const groupCtx = this.ctx;
@ -1224,8 +1217,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
groupCtx.setTransform(1, 0, 0, 1, 0, 0); groupCtx.setTransform(1, 0, 0, 1, 0, 0);
groupCtx.clearRect(0, 0, groupCtx.canvas.width, groupCtx.canvas.height); groupCtx.clearRect(0, 0, groupCtx.canvas.width, groupCtx.canvas.height);
groupCtx.restore(); groupCtx.restore();
}, }
resumeSMaskGroup: function CanvasGraphics_resumeSMaskGroup() {
resumeSMaskGroup() {
// Resuming state saved by suspendSMaskGroup. We don't need to restore // Resuming state saved by suspendSMaskGroup. We don't need to restore
// any groupCtx state since restore() command (the only caller) will do // any groupCtx state since restore() command (the only caller) will do
// that for us. See also beginSMaskGroup. // that for us. See also beginSMaskGroup.
@ -1234,8 +1228,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.ctx = groupCtx; this.ctx = groupCtx;
this.groupStack.push(currentCtx); this.groupStack.push(currentCtx);
this.groupLevel++; this.groupLevel++;
}, }
endSMaskGroup: function CanvasGraphics_endSMaskGroup() {
endSMaskGroup() {
const groupCtx = this.ctx; const groupCtx = this.ctx;
this.groupLevel--; this.groupLevel--;
this.ctx = this.groupStack.pop(); this.ctx = this.groupStack.pop();
@ -1255,15 +1250,17 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
groupCtx.mozCurrentTransform groupCtx.mozCurrentTransform
); );
this.ctx.transform.apply(this.ctx, deltaTransform); this.ctx.transform.apply(this.ctx, deltaTransform);
}, }
save: function CanvasGraphics_save() {
save() {
this.ctx.save(); this.ctx.save();
const old = this.current; const old = this.current;
this.stateStack.push(old); this.stateStack.push(old);
this.current = old.clone(); this.current = old.clone();
this.current.resumeSMaskCtx = null; this.current.resumeSMaskCtx = null;
}, }
restore: function CanvasGraphics_restore() {
restore() {
// SMask was suspended, we just need to resume it. // SMask was suspended, we just need to resume it.
if (this.current.resumeSMaskCtx) { if (this.current.resumeSMaskCtx) {
this.resumeSMaskGroup(); this.resumeSMaskGroup();
@ -1291,15 +1288,16 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
// We've finished all the SMask groups, reflect that in our state. // We've finished all the SMask groups, reflect that in our state.
this.current.activeSMask = null; this.current.activeSMask = null;
} }
}, }
transform: function CanvasGraphics_transform(a, b, c, d, e, f) {
transform(a, b, c, d, e, f) {
this.ctx.transform(a, b, c, d, e, f); this.ctx.transform(a, b, c, d, e, f);
this._cachedGetSinglePixelWidth = null; this._cachedGetSinglePixelWidth = null;
}, }
// Path // Path
constructPath: function CanvasGraphics_constructPath(ops, args) { constructPath(ops, args) {
const ctx = this.ctx; const ctx = this.ctx;
const current = this.current; const current = this.current;
let x = current.x, let x = current.x,
@ -1373,11 +1371,13 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
} }
} }
current.setCurrentPoint(x, y); current.setCurrentPoint(x, y);
}, }
closePath: function CanvasGraphics_closePath() {
closePath() {
this.ctx.closePath(); this.ctx.closePath();
}, }
stroke: function CanvasGraphics_stroke(consumePath) {
stroke(consumePath) {
consumePath = typeof consumePath !== "undefined" ? consumePath : true; consumePath = typeof consumePath !== "undefined" ? consumePath : true;
const ctx = this.ctx; const ctx = this.ctx;
const strokeColor = this.current.strokeColor; const strokeColor = this.current.strokeColor;
@ -1428,12 +1428,14 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
} }
// Restore the global alpha to the fill alpha // Restore the global alpha to the fill alpha
ctx.globalAlpha = this.current.fillAlpha; ctx.globalAlpha = this.current.fillAlpha;
}, }
closeStroke: function CanvasGraphics_closeStroke() {
closeStroke() {
this.closePath(); this.closePath();
this.stroke(); this.stroke();
}, }
fill: function CanvasGraphics_fill(consumePath) {
fill(consumePath) {
consumePath = typeof consumePath !== "undefined" ? consumePath : true; consumePath = typeof consumePath !== "undefined" ? consumePath : true;
const ctx = this.ctx; const ctx = this.ctx;
const fillColor = this.current.fillColor; const fillColor = this.current.fillColor;
@ -1464,50 +1466,58 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
if (consumePath) { if (consumePath) {
this.consumePath(); this.consumePath();
} }
}, }
eoFill: function CanvasGraphics_eoFill() {
eoFill() {
this.pendingEOFill = true; this.pendingEOFill = true;
this.fill(); this.fill();
}, }
fillStroke: function CanvasGraphics_fillStroke() {
fillStroke() {
this.fill(false); this.fill(false);
this.stroke(false); this.stroke(false);
this.consumePath(); this.consumePath();
}, }
eoFillStroke: function CanvasGraphics_eoFillStroke() {
eoFillStroke() {
this.pendingEOFill = true; this.pendingEOFill = true;
this.fillStroke(); this.fillStroke();
}, }
closeFillStroke: function CanvasGraphics_closeFillStroke() {
closeFillStroke() {
this.closePath(); this.closePath();
this.fillStroke(); this.fillStroke();
}, }
closeEOFillStroke: function CanvasGraphics_closeEOFillStroke() {
closeEOFillStroke() {
this.pendingEOFill = true; this.pendingEOFill = true;
this.closePath(); this.closePath();
this.fillStroke(); this.fillStroke();
}, }
endPath: function CanvasGraphics_endPath() {
endPath() {
this.consumePath(); this.consumePath();
}, }
// Clipping // Clipping
clip: function CanvasGraphics_clip() { clip() {
this.pendingClip = NORMAL_CLIP; this.pendingClip = NORMAL_CLIP;
}, }
eoClip: function CanvasGraphics_eoClip() {
eoClip() {
this.pendingClip = EO_CLIP; this.pendingClip = EO_CLIP;
}, }
// Text // Text
beginText: function CanvasGraphics_beginText() { beginText() {
this.current.textMatrix = IDENTITY_MATRIX; this.current.textMatrix = IDENTITY_MATRIX;
this.current.textMatrixScale = 1; this.current.textMatrixScale = 1;
this.current.x = this.current.lineX = 0; this.current.x = this.current.lineX = 0;
this.current.y = this.current.lineY = 0; this.current.y = this.current.lineY = 0;
}, }
endText: function CanvasGraphics_endText() {
endText() {
const paths = this.pendingTextPaths; const paths = this.pendingTextPaths;
const ctx = this.ctx; const ctx = this.ctx;
if (paths === undefined) { if (paths === undefined) {
@ -1527,20 +1537,25 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
ctx.clip(); ctx.clip();
ctx.beginPath(); ctx.beginPath();
delete this.pendingTextPaths; delete this.pendingTextPaths;
}, }
setCharSpacing: function CanvasGraphics_setCharSpacing(spacing) {
setCharSpacing(spacing) {
this.current.charSpacing = spacing; this.current.charSpacing = spacing;
}, }
setWordSpacing: function CanvasGraphics_setWordSpacing(spacing) {
setWordSpacing(spacing) {
this.current.wordSpacing = spacing; this.current.wordSpacing = spacing;
}, }
setHScale: function CanvasGraphics_setHScale(scale) {
setHScale(scale) {
this.current.textHScale = scale / 100; this.current.textHScale = scale / 100;
}, }
setLeading: function CanvasGraphics_setLeading(leading) {
setLeading(leading) {
this.current.leading = -leading; this.current.leading = -leading;
}, }
setFont: function CanvasGraphics_setFont(fontRefName, size) {
setFont(fontRefName, size) {
const fontObj = this.commonObjs.get(fontRefName); const fontObj = this.commonObjs.get(fontRefName);
const current = this.current; const current = this.current;
@ -1595,31 +1610,37 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.current.fontSizeScale = size / browserFontSize; this.current.fontSizeScale = size / browserFontSize;
this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`; this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`;
}, }
setTextRenderingMode: function CanvasGraphics_setTextRenderingMode(mode) {
setTextRenderingMode(mode) {
this.current.textRenderingMode = mode; this.current.textRenderingMode = mode;
}, }
setTextRise: function CanvasGraphics_setTextRise(rise) {
setTextRise(rise) {
this.current.textRise = rise; this.current.textRise = rise;
}, }
moveText: function CanvasGraphics_moveText(x, y) {
moveText(x, y) {
this.current.x = this.current.lineX += x; this.current.x = this.current.lineX += x;
this.current.y = this.current.lineY += y; this.current.y = this.current.lineY += y;
}, }
setLeadingMoveText: function CanvasGraphics_setLeadingMoveText(x, y) {
setLeadingMoveText(x, y) {
this.setLeading(-y); this.setLeading(-y);
this.moveText(x, y); this.moveText(x, y);
}, }
setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) {
setTextMatrix(a, b, c, d, e, f) {
this.current.textMatrix = [a, b, c, d, e, f]; this.current.textMatrix = [a, b, c, d, e, f];
this.current.textMatrixScale = Math.hypot(a, b); this.current.textMatrixScale = Math.hypot(a, b);
this.current.x = this.current.lineX = 0; this.current.x = this.current.lineX = 0;
this.current.y = this.current.lineY = 0; this.current.y = this.current.lineY = 0;
}, }
nextLine: function CanvasGraphics_nextLine() {
nextLine() {
this.moveText(0, this.current.leading); this.moveText(0, this.current.leading);
}, }
paintChar(character, x, y, patternTransform, resetLineWidthToOne) { paintChar(character, x, y, patternTransform, resetLineWidthToOne) {
const ctx = this.ctx; const ctx = this.ctx;
@ -1698,7 +1719,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
addToPath, addToPath,
}); });
} }
}, }
get isFontSubpixelAAEnabled() { get isFontSubpixelAAEnabled() {
// Checks if anti-aliasing is enabled when scaled text is painted. // Checks if anti-aliasing is enabled when scaled text is painted.
@ -1719,9 +1740,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
} }
} }
return shadow(this, "isFontSubpixelAAEnabled", enabled); return shadow(this, "isFontSubpixelAAEnabled", enabled);
}, }
showText: function CanvasGraphics_showText(glyphs) { showText(glyphs) {
const current = this.current; const current = this.current;
const font = current.font; const font = current.font;
if (font.isType3Font) { if (font.isType3Font) {
@ -1891,9 +1912,10 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
current.x += x * textHScale; current.x += x * textHScale;
} }
ctx.restore(); ctx.restore();
}, return undefined;
}
showType3Text: function CanvasGraphics_showType3Text(glyphs) { showType3Text(glyphs) {
// Type3 fonts - each glyph is a "mini-PDF" // Type3 fonts - each glyph is a "mini-PDF"
const ctx = this.ctx; const ctx = this.ctx;
const current = this.current; const current = this.current;
@ -1953,30 +1975,24 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
} }
ctx.restore(); ctx.restore();
this.processingType3 = null; this.processingType3 = null;
}, }
// Type3 fonts // Type3 fonts
setCharWidth: function CanvasGraphics_setCharWidth(xWidth, yWidth) { setCharWidth(xWidth, yWidth) {
// We can safely ignore this since the width should be the same // We can safely ignore this since the width should be the same
// as the width in the Widths array. // as the width in the Widths array.
}, }
setCharWidthAndBounds: function CanvasGraphics_setCharWidthAndBounds(
xWidth, setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) {
yWidth,
llx,
lly,
urx,
ury
) {
// TODO According to the spec we're also suppose to ignore any operators // TODO According to the spec we're also suppose to ignore any operators
// that set color or include images while processing this type3 font. // that set color or include images while processing this type3 font.
this.ctx.rect(llx, lly, urx - llx, ury - lly); this.ctx.rect(llx, lly, urx - llx, ury - lly);
this.clip(); this.clip();
this.endPath(); this.endPath();
}, }
// Color // Color
getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR) { getColorN_Pattern(IR) {
let pattern; let pattern;
if (IR[0] === "TilingPattern") { if (IR[0] === "TilingPattern") {
const color = IR[1]; const color = IR[1];
@ -2004,27 +2020,31 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
pattern = getShadingPatternFromIR(IR); pattern = getShadingPatternFromIR(IR);
} }
return pattern; return pattern;
}, }
setStrokeColorN: function CanvasGraphics_setStrokeColorN() {
setStrokeColorN() {
this.current.strokeColor = this.getColorN_Pattern(arguments); this.current.strokeColor = this.getColorN_Pattern(arguments);
}, }
setFillColorN: function CanvasGraphics_setFillColorN() {
setFillColorN() {
this.current.fillColor = this.getColorN_Pattern(arguments); this.current.fillColor = this.getColorN_Pattern(arguments);
this.current.patternFill = true; this.current.patternFill = true;
}, }
setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) {
setStrokeRGBColor(r, g, b) {
const color = Util.makeHexColor(r, g, b); const color = Util.makeHexColor(r, g, b);
this.ctx.strokeStyle = color; this.ctx.strokeStyle = color;
this.current.strokeColor = color; this.current.strokeColor = color;
}, }
setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) {
setFillRGBColor(r, g, b) {
const color = Util.makeHexColor(r, g, b); const color = Util.makeHexColor(r, g, b);
this.ctx.fillStyle = color; this.ctx.fillStyle = color;
this.current.fillColor = color; this.current.fillColor = color;
this.current.patternFill = false; this.current.patternFill = false;
}, }
shadingFill: function CanvasGraphics_shadingFill(patternIR) { shadingFill(patternIR) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2062,20 +2082,18 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
} }
this.restore(); this.restore();
}, }
// Images // Images
beginInlineImage: function CanvasGraphics_beginInlineImage() { beginInlineImage() {
unreachable("Should not call beginInlineImage"); unreachable("Should not call beginInlineImage");
}, }
beginImageData: function CanvasGraphics_beginImageData() {
unreachable("Should not call beginImageData");
},
paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin( beginImageData() {
matrix, unreachable("Should not call beginImageData");
bbox }
) {
paintFormXObjectBegin(matrix, bbox) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2095,17 +2113,17 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.clip(); this.clip();
this.endPath(); this.endPath();
} }
}, }
paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() { paintFormXObjectEnd() {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
this.restore(); this.restore();
this.baseTransform = this.baseTransformStack.pop(); this.baseTransform = this.baseTransformStack.pop();
}, }
beginGroup: function CanvasGraphics_beginGroup(group) { beginGroup(group) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2228,9 +2246,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
// Resetting mask state, masks will be applied on restore of the group. // Resetting mask state, masks will be applied on restore of the group.
this.current.activeSMask = null; this.current.activeSMask = null;
}, }
endGroup: function CanvasGraphics_endGroup(group) { endGroup(group) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2250,24 +2268,20 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.ctx.drawImage(groupCtx.canvas, 0, 0); this.ctx.drawImage(groupCtx.canvas, 0, 0);
} }
this.restore(); this.restore();
}, }
beginAnnotations: function CanvasGraphics_beginAnnotations() { beginAnnotations() {
this.save(); this.save();
if (this.baseTransform) { if (this.baseTransform) {
this.ctx.setTransform.apply(this.ctx, this.baseTransform); this.ctx.setTransform.apply(this.ctx, this.baseTransform);
} }
}, }
endAnnotations: function CanvasGraphics_endAnnotations() { endAnnotations() {
this.restore(); this.restore();
}, }
beginAnnotation: function CanvasGraphics_beginAnnotation( beginAnnotation(rect, transform, matrix) {
rect,
transform,
matrix
) {
this.save(); this.save();
resetCtxToDefault(this.ctx); resetCtxToDefault(this.ctx);
this.current = new CanvasExtraState(); this.current = new CanvasExtraState();
@ -2282,13 +2296,13 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.transform.apply(this, transform); this.transform.apply(this, transform);
this.transform.apply(this, matrix); this.transform.apply(this, matrix);
}, }
endAnnotation: function CanvasGraphics_endAnnotation() { endAnnotation() {
this.restore(); this.restore();
}, }
paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject(img) { paintImageMaskXObject(img) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2333,7 +2347,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
maskCtx.restore(); maskCtx.restore();
this.paintInlineImageXObject(maskCanvas.canvas); this.paintInlineImageXObject(maskCanvas.canvas);
}, }
paintImageMaskXObjectRepeat( paintImageMaskXObjectRepeat(
imgData, imgData,
@ -2385,11 +2399,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1); ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1);
ctx.restore(); ctx.restore();
} }
}, }
paintImageMaskXObjectGroup: function CanvasGraphics_paintImageMaskXObjectGroup( paintImageMaskXObjectGroup(images) {
images
) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2427,9 +2439,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1); ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1);
ctx.restore(); ctx.restore();
} }
}, }
paintImageXObject: function CanvasGraphics_paintImageXObject(objId) { paintImageXObject(objId) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2442,14 +2454,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
} }
this.paintInlineImageXObject(imgData); this.paintInlineImageXObject(imgData);
}, }
paintImageXObjectRepeat: function CanvasGraphics_paintImageXObjectRepeat( paintImageXObjectRepeat(objId, scaleX, scaleY, positions) {
objId,
scaleX,
scaleY,
positions
) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2474,11 +2481,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
}); });
} }
this.paintInlineImageXObjectGroup(imgData, map); this.paintInlineImageXObjectGroup(imgData, map);
}, }
paintInlineImageXObject: function CanvasGraphics_paintInlineImageXObject( paintInlineImageXObject(imgData) {
imgData
) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2580,12 +2585,9 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
}); });
} }
this.restore(); this.restore();
}, }
paintInlineImageXObjectGroup: function CanvasGraphics_paintInlineImageXObjectGroup( paintInlineImageXObjectGroup(imgData, map) {
imgData,
map
) {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
@ -2625,32 +2627,32 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
} }
ctx.restore(); ctx.restore();
} }
}, }
paintSolidColorImageMask: function CanvasGraphics_paintSolidColorImageMask() { paintSolidColorImageMask() {
if (!this.contentVisible) { if (!this.contentVisible) {
return; return;
} }
this.ctx.fillRect(0, 0, 1, 1); this.ctx.fillRect(0, 0, 1, 1);
}, }
// Marked content // Marked content
markPoint: function CanvasGraphics_markPoint(tag) { markPoint(tag) {
// TODO Marked content. // TODO Marked content.
}, }
markPointProps: function CanvasGraphics_markPointProps(tag, properties) {
markPointProps(tag, properties) {
// TODO Marked content. // TODO Marked content.
}, }
beginMarkedContent: function CanvasGraphics_beginMarkedContent(tag) {
beginMarkedContent(tag) {
this.markedContentStack.push({ this.markedContentStack.push({
visible: true, visible: true,
}); });
}, }
beginMarkedContentProps: function CanvasGraphics_beginMarkedContentProps(
tag, beginMarkedContentProps(tag, properties) {
properties
) {
if (tag === "OC") { if (tag === "OC") {
this.markedContentStack.push({ this.markedContentStack.push({
visible: this.optionalContentConfig.isVisible(properties), visible: this.optionalContentConfig.isVisible(properties),
@ -2661,24 +2663,26 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
}); });
} }
this.contentVisible = this.isContentVisible(); this.contentVisible = this.isContentVisible();
}, }
endMarkedContent: function CanvasGraphics_endMarkedContent() {
endMarkedContent() {
this.markedContentStack.pop(); this.markedContentStack.pop();
this.contentVisible = this.isContentVisible(); this.contentVisible = this.isContentVisible();
}, }
// Compatibility // Compatibility
beginCompat: function CanvasGraphics_beginCompat() { beginCompat() {
// TODO ignore undefined operators (should we do that anyway?) // TODO ignore undefined operators (should we do that anyway?)
}, }
endCompat: function CanvasGraphics_endCompat() {
endCompat() {
// TODO stop ignoring undefined operators // TODO stop ignoring undefined operators
}, }
// Helper functions // Helper functions
consumePath: function CanvasGraphics_consumePath() { consumePath() {
const ctx = this.ctx; const ctx = this.ctx;
if (this.pendingClip) { if (this.pendingClip) {
if (this.pendingClip === EO_CLIP) { if (this.pendingClip === EO_CLIP) {
@ -2689,7 +2693,8 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.pendingClip = null; this.pendingClip = null;
} }
ctx.beginPath(); ctx.beginPath();
}, }
getSinglePixelWidth() { getSinglePixelWidth() {
if (this._cachedGetSinglePixelWidth === null) { if (this._cachedGetSinglePixelWidth === null) {
// If transform is [a b] then a pixel (square) is transformed // If transform is [a b] then a pixel (square) is transformed
@ -2734,24 +2739,25 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
} }
return this._cachedGetSinglePixelWidth; return this._cachedGetSinglePixelWidth;
}, }
getCanvasPosition: function CanvasGraphics_getCanvasPosition(x, y) {
getCanvasPosition(x, y) {
const transform = this.ctx.mozCurrentTransform; const transform = this.ctx.mozCurrentTransform;
return [ return [
transform[0] * x + transform[2] * y + transform[4], transform[0] * x + transform[2] * y + transform[4],
transform[1] * x + transform[3] * y + transform[5], transform[1] * x + transform[3] * y + transform[5],
]; ];
}, }
isContentVisible: function CanvasGraphics_isContentVisible() { isContentVisible() {
for (let i = this.markedContentStack.length - 1; i >= 0; i--) { for (let i = this.markedContentStack.length - 1; i >= 0; i--) {
if (!this.markedContentStack[i].visible) { if (!this.markedContentStack[i].visible) {
return false; return false;
} }
} }
return true; return true;
}, }
}; }
for (const op in OPS) { for (const op in OPS) {
CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op]; CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op];