diff --git a/src/display/svg.js b/src/display/svg.js index 2d210f9fc..3fa536cf7 100644 --- a/src/display/svg.js +++ b/src/display/svg.js @@ -409,9 +409,7 @@ var SVGGraphics = (function SVGGraphicsClosure() { this.transformMatrix = this.transformStack.pop(); this.current = this.extraStack.pop(); - this.tgrp = document.createElementNS(NS, 'svg:g'); - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - this.pgrp.appendChild(this.tgrp); + this.tgrp = null; }, group: function SVGGraphics_group(items) { @@ -453,9 +451,7 @@ var SVGGraphics = (function SVGGraphicsClosure() { var transformMatrix = [a, b, c, d, e, f]; this.transformMatrix = Util.transform(this.transformMatrix, transformMatrix); - - this.tgrp = document.createElementNS(NS, 'svg:g'); - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); + this.tgrp = null; }, getSVG: function SVGGraphics_getSVG(operatorList, viewport) { @@ -464,14 +460,9 @@ var SVGGraphics = (function SVGGraphicsClosure() { return this.loadDependencies(operatorList).then(function () { this.transformMatrix = IDENTITY_MATRIX; - this.pgrp = document.createElementNS(NS, 'svg:g'); // Parent group - this.pgrp.setAttributeNS(null, 'transform', pm(viewport.transform)); - this.tgrp = document.createElementNS(NS, 'svg:g'); // Transform group - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); this.defs = document.createElementNS(NS, 'svg:defs'); - this.pgrp.appendChild(this.defs); - this.pgrp.appendChild(this.tgrp); - this.svg.appendChild(this.pgrp); + this.svg.setAttributeNS(null, 'transform', pm(viewport.transform)); + this.svg.appendChild(this.defs); var opTree = this.convertOpList(operatorList); this.executeOpTree(opTree); return this.svg; @@ -633,7 +624,7 @@ var SVGGraphics = (function SVGGraphicsClosure() { this.group(opTree[x].items); break; default: - warn('Unimplemented method '+ fn); + warn('Unimplemented operator ' + fn); break; } } @@ -759,8 +750,7 @@ var SVGGraphics = (function SVGGraphicsClosure() { current.txtElement.appendChild(current.tspan); current.txtgrp.appendChild(current.txtElement); - this.tgrp.appendChild(current.txtElement); - + this._ensureTransformGroup().appendChild(current.txtElement); }, setLeadingMoveText: function SVGGraphics_setLeadingMoveText(x, y) { @@ -817,16 +807,7 @@ var SVGGraphics = (function SVGGraphicsClosure() { current.xcoords = []; }, - endText: function SVGGraphics_endText() { - if (this.current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } - this.tgrp = document.createElementNS(NS, 'svg:g'); - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - }, + endText: function SVGGraphics_endText() {}, // Path properties setLineWidth: function SVGGraphics_setLineWidth(width) { @@ -924,30 +905,15 @@ var SVGGraphics = (function SVGGraphicsClosure() { pf(current.dashPhase) + 'px'); current.path.setAttributeNS(null, 'fill', 'none'); - this.tgrp.appendChild(current.path); - if (current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } + this._ensureTransformGroup().appendChild(current.path); + // Saving a reference in current.element so that it can be addressed // in 'fill' and 'stroke' current.element = current.path; current.setCurrentPoint(x, y); }, - endPath: function SVGGraphics_endPath() { - var current = this.current; - if (current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } - this.tgrp = document.createElementNS(NS, 'svg:g'); - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - }, + endPath: function SVGGraphics_endPath() {}, clip: function SVGGraphics_clip(type) { var current = this.current; @@ -966,12 +932,12 @@ var SVGGraphics = (function SVGGraphicsClosure() { this.clippath.appendChild(clipElement); this.defs.appendChild(this.clippath); - // Create a new group with that attribute + // Create a clipping group that references the clipping path. current.pendingClip = true; this.cgrp = document.createElementNS(NS, 'svg:g'); this.cgrp.setAttributeNS(null, 'clip-path', 'url(#' + current.clipId + ')'); - this.pgrp.appendChild(this.cgrp); + this.svg.appendChild(this.cgrp); }, closePath: function SVGGraphics_closePath() { @@ -1015,20 +981,11 @@ var SVGGraphics = (function SVGGraphicsClosure() { case 'D': this.setDash(value[0], value[1]); break; - case 'RI': - break; - case 'FL': - break; case 'Font': this.setFont(value); break; - case 'CA': - break; - case 'ca': - break; - case 'BM': - break; - case 'SMask': + default: + warn('Unimplemented graphic state ' + key); break; } } @@ -1082,11 +1039,11 @@ var SVGGraphics = (function SVGGraphicsClosure() { rect.setAttributeNS(null, 'width', '1px'); rect.setAttributeNS(null, 'height', '1px'); rect.setAttributeNS(null, 'fill', current.fillColor); - this.tgrp.appendChild(rect); + + this._ensureTransformGroup().appendChild(rect); }, paintJpegXObject: function SVGGraphics_paintJpegXObject(objId, w, h) { - var current = this.current; var imgObj = this.objs.get(objId); var imgEl = document.createElementNS(NS, 'svg:image'); imgEl.setAttributeNS(XLINK_NS, 'xlink:href', imgObj.src); @@ -1097,13 +1054,7 @@ var SVGGraphics = (function SVGGraphicsClosure() { imgEl.setAttributeNS(null, 'transform', 'scale(' + pf(1 / w) + ' ' + pf(-1 / h) + ')'); - this.tgrp.appendChild(imgEl); - if (current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } + this._ensureTransformGroup().appendChild(imgEl); }, paintImageXObject: function SVGGraphics_paintImageXObject(objId) { @@ -1117,7 +1068,6 @@ var SVGGraphics = (function SVGGraphicsClosure() { paintInlineImageXObject: function SVGGraphics_paintInlineImageXObject(imgData, mask) { - var current = this.current; var width = imgData.width; var height = imgData.height; @@ -1127,7 +1077,7 @@ var SVGGraphics = (function SVGGraphicsClosure() { cliprect.setAttributeNS(null, 'y', '0'); cliprect.setAttributeNS(null, 'width', pf(width)); cliprect.setAttributeNS(null, 'height', pf(height)); - current.element = cliprect; + this.current.element = cliprect; this.clip('nonzero'); var imgEl = document.createElementNS(NS, 'svg:image'); imgEl.setAttributeNS(XLINK_NS, 'xlink:href', imgSrc); @@ -1141,13 +1091,7 @@ var SVGGraphics = (function SVGGraphicsClosure() { if (mask) { mask.appendChild(imgEl); } else { - this.tgrp.appendChild(imgEl); - } - if (current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); + this._ensureTransformGroup().appendChild(imgEl); } }, @@ -1170,15 +1114,14 @@ var SVGGraphics = (function SVGGraphicsClosure() { rect.setAttributeNS(null, 'fill', fillColor); rect.setAttributeNS(null, 'mask', 'url(#' + current.maskId +')'); this.defs.appendChild(mask); - this.tgrp.appendChild(rect); + + this._ensureTransformGroup().appendChild(rect); this.paintInlineImageXObject(imgData, mask); }, paintFormXObjectBegin: function SVGGraphics_paintFormXObjectBegin(matrix, bbox) { - this.save(); - if (isArray(matrix) && matrix.length === 6) { this.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); @@ -1200,8 +1143,23 @@ var SVGGraphics = (function SVGGraphicsClosure() { }, paintFormXObjectEnd: - function SVGGraphics_paintFormXObjectEnd() { - this.restore(); + function SVGGraphics_paintFormXObjectEnd() {}, + + /** + * @private + */ + _ensureTransformGroup: function SVGGraphics_ensureTransformGroup() { + if (!this.tgrp) { + this.tgrp = document.createElementNS(NS, 'svg:g'); + this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); + + if (this.current.pendingClip) { + this.cgrp.appendChild(this.tgrp); + } else { + this.svg.appendChild(this.tgrp); + } + } + return this.tgrp; } }; return SVGGraphics;