mirror of
https://github.com/zen-browser/pdf.js.git
synced 2025-07-09 17:55:37 +02:00
Add basic support for transparency groups.
This commit is contained in:
parent
3f195f3308
commit
725cd5407f
6 changed files with 2318 additions and 26 deletions
105
src/canvas.js
105
src/canvas.js
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
/* globals ColorSpace, DeviceCmykCS, DeviceGrayCS, DeviceRgbCS, error,
|
||||
FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageData, isArray, isNum,
|
||||
isString, Pattern, TilingPattern, TODO, Util, warn */
|
||||
isString, Pattern, TilingPattern, TODO, Util, warn, assert */
|
||||
|
||||
'use strict';
|
||||
|
||||
|
@ -225,6 +225,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
this.objs = objs;
|
||||
this.textLayer = textLayer;
|
||||
this.imageLayer = imageLayer;
|
||||
this.groupStack = [];
|
||||
if (canvasCtx) {
|
||||
addContextCurrentTransform(canvasCtx);
|
||||
}
|
||||
|
@ -357,6 +358,25 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
return tmpCanvas;
|
||||
}
|
||||
|
||||
function copyCtxState(sourceCtx, destCtx) {
|
||||
var properties = ['strokeStyle', 'fillStyle', 'fillRule', 'globalAlpha',
|
||||
'lineWidth', 'lineCap', 'lineJoin', 'miterLimit',
|
||||
'globalCompositeOperation', 'font'];
|
||||
for (var i = 0, ii = properties.length; i < ii; i++) {
|
||||
var property = properties[i];
|
||||
if (property in sourceCtx) {
|
||||
destCtx[property] = sourceCtx[property];
|
||||
}
|
||||
}
|
||||
if ('setLineDash' in sourceCtx) {
|
||||
destCtx.setLineDash(sourceCtx.getLineDash());
|
||||
destCtx.lineDashOffset = sourceCtx.lineDashOffset;
|
||||
} else if ('mozDash' in sourceCtx) {
|
||||
destCtx.mozDash = sourceCtx.mozDash;
|
||||
destCtx.mozDashOffset = sourceCtx.mozDashOffset;
|
||||
}
|
||||
}
|
||||
|
||||
var LINE_CAP_STYLES = ['butt', 'round', 'square'];
|
||||
var LINE_JOIN_STYLES = ['miter', 'round', 'bevel'];
|
||||
var NORMAL_CLIP = {};
|
||||
|
@ -1347,6 +1367,89 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
} while (this.current.paintFormXObjectDepth >= depth);
|
||||
},
|
||||
|
||||
beginGroup: function CanvasGraphics_beginGroup(group) {
|
||||
this.save();
|
||||
var currentCtx = this.ctx;
|
||||
// TODO non-isolated groups - according to Rik at adobe non-isolated
|
||||
// group results aren't usually that different and they even have tools
|
||||
// that ignore this setting. Notes from Rik on implmenting:
|
||||
// - When you encounter an transparency group, create a new canvas with
|
||||
// the dimensions of the bbox
|
||||
// - copy the content from the previous canvas to the new canvas
|
||||
// - draw as usual
|
||||
// - remove the backdrop alpha:
|
||||
// alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha
|
||||
// value of your transparency group and 'alphaBackdrop' the alpha of the
|
||||
// backdrop
|
||||
// - remove background color:
|
||||
// colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew)
|
||||
if (!group.isolated) {
|
||||
TODO('Support non-isolated groups.');
|
||||
}
|
||||
|
||||
// TODO knockout - supposedly possible with the clever use of compositing
|
||||
// modes.
|
||||
if (group.knockout) {
|
||||
TODO('Support knockout groups.');
|
||||
}
|
||||
|
||||
var currentTransform = currentCtx.mozCurrentTransform;
|
||||
if (group.matrix) {
|
||||
currentCtx.transform.apply(currentCtx, group.matrix);
|
||||
}
|
||||
assert(group.bbox, 'Bounding box is required.');
|
||||
|
||||
// Based on the current transform figure out how big the bounding box
|
||||
// will actually be.
|
||||
var bounds = Util.getAxialAlignedBoundingBox(
|
||||
group.bbox,
|
||||
currentCtx.mozCurrentTransform);
|
||||
// Use ceil in case we're between sizes so we don't create canvas that is
|
||||
// too small.
|
||||
var drawnWidth = Math.ceil(bounds[2] - bounds[0]);
|
||||
var drawnHeight = Math.ceil(bounds[3] - bounds[1]);
|
||||
var scratchCanvas = createScratchCanvas(drawnWidth, drawnHeight);
|
||||
var groupCtx = scratchCanvas.getContext('2d');
|
||||
addContextCurrentTransform(groupCtx);
|
||||
// Since we created a new canvas that is just the size of the bounding box
|
||||
// we have to translate the group ctx.
|
||||
var offsetX = bounds[0];
|
||||
var offsetY = bounds[1];
|
||||
groupCtx.translate(-offsetX, -offsetY);
|
||||
groupCtx.transform.apply(groupCtx, currentTransform);
|
||||
|
||||
// Setup the current ctx so when the group is popped we draw it the right
|
||||
// location.
|
||||
currentCtx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
currentCtx.translate(offsetX, offsetY);
|
||||
|
||||
// The transparency group inherits all off the current graphics state
|
||||
// except the blend mode, soft mask, and alpha constants.
|
||||
copyCtxState(currentCtx, groupCtx);
|
||||
this.ctx = groupCtx;
|
||||
this.setGState([
|
||||
['SMask', 'None'],
|
||||
['BM', 'Normal'],
|
||||
['ca', 1],
|
||||
['CA', 1]
|
||||
]);
|
||||
this.groupStack.push(currentCtx);
|
||||
},
|
||||
|
||||
endGroup: function CanvasGraphics_endGroup(group) {
|
||||
var groupCtx = this.ctx;
|
||||
this.ctx = this.groupStack.pop();
|
||||
// Turn off image smoothing to avoid sub pixel interpolation which can
|
||||
// look kind of blurry for some pdfs.
|
||||
if ('imageSmoothingEnabled' in this.ctx) {
|
||||
this.ctx.imageSmoothingEnabled = false;
|
||||
} else {
|
||||
this.ctx.mozImageSmoothingEnabled = false;
|
||||
}
|
||||
this.ctx.drawImage(groupCtx.canvas, 0, 0);
|
||||
this.restore();
|
||||
},
|
||||
|
||||
paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) {
|
||||
var domImage = this.objs.get(objId);
|
||||
if (!domImage) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue