Merge pull request #10022 from janpe2/svg-Tr
Implement text rendering modes in SVG backend
This commit is contained in:
		
						commit
						283f2dfcc3
					
				@ -16,7 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  createObjectURL, FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageKind, isNum, OPS,
 | 
					  createObjectURL, FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageKind, isNum, OPS,
 | 
				
			||||||
  Util, warn
 | 
					  TextRenderingMode, Util, warn
 | 
				
			||||||
} from '../shared/util';
 | 
					} from '../shared/util';
 | 
				
			||||||
import { DOMSVGFactory } from './dom_utils';
 | 
					import { DOMSVGFactory } from './dom_utils';
 | 
				
			||||||
import isNodeJS from '../shared/is_node';
 | 
					import isNodeJS from '../shared/is_node';
 | 
				
			||||||
@ -281,6 +281,7 @@ var SVGExtraState = (function SVGExtraStateClosure() {
 | 
				
			|||||||
    this.textMatrix = IDENTITY_MATRIX;
 | 
					    this.textMatrix = IDENTITY_MATRIX;
 | 
				
			||||||
    this.fontMatrix = FONT_IDENTITY_MATRIX;
 | 
					    this.fontMatrix = FONT_IDENTITY_MATRIX;
 | 
				
			||||||
    this.leading = 0;
 | 
					    this.leading = 0;
 | 
				
			||||||
 | 
					    this.textRenderingMode = TextRenderingMode.FILL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Current point (in user coordinates)
 | 
					    // Current point (in user coordinates)
 | 
				
			||||||
    this.x = 0;
 | 
					    this.x = 0;
 | 
				
			||||||
@ -570,6 +571,9 @@ SVGGraphics = (function SVGGraphicsClosure() {
 | 
				
			|||||||
          case OPS.setTextRise:
 | 
					          case OPS.setTextRise:
 | 
				
			||||||
            this.setTextRise(args[0]);
 | 
					            this.setTextRise(args[0]);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					          case OPS.setTextRenderingMode:
 | 
				
			||||||
 | 
					            this.setTextRenderingMode(args[0]);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
          case OPS.setLineWidth:
 | 
					          case OPS.setLineWidth:
 | 
				
			||||||
            this.setLineWidth(args[0]);
 | 
					            this.setLineWidth(args[0]);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@ -789,9 +793,30 @@ SVGGraphics = (function SVGGraphicsClosure() {
 | 
				
			|||||||
      if (current.fontWeight !== SVG_DEFAULTS.fontWeight) {
 | 
					      if (current.fontWeight !== SVG_DEFAULTS.fontWeight) {
 | 
				
			||||||
        current.tspan.setAttributeNS(null, 'font-weight', current.fontWeight);
 | 
					        current.tspan.setAttributeNS(null, 'font-weight', current.fontWeight);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const fillStrokeMode = current.textRenderingMode &
 | 
				
			||||||
 | 
					        TextRenderingMode.FILL_STROKE_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (fillStrokeMode === TextRenderingMode.FILL ||
 | 
				
			||||||
 | 
					          fillStrokeMode === TextRenderingMode.FILL_STROKE) {
 | 
				
			||||||
        if (current.fillColor !== SVG_DEFAULTS.fillColor) {
 | 
					        if (current.fillColor !== SVG_DEFAULTS.fillColor) {
 | 
				
			||||||
          current.tspan.setAttributeNS(null, 'fill', current.fillColor);
 | 
					          current.tspan.setAttributeNS(null, 'fill', current.fillColor);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (current.fillAlpha < 1) {
 | 
				
			||||||
 | 
					          current.tspan.setAttributeNS(null, 'fill-opacity', current.fillAlpha);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else if (current.textRenderingMode === TextRenderingMode.ADD_TO_PATH) {
 | 
				
			||||||
 | 
					        // Workaround for Firefox: We must set fill="transparent" because
 | 
				
			||||||
 | 
					        // fill="none" would generate an empty clipping path.
 | 
				
			||||||
 | 
					        current.tspan.setAttributeNS(null, 'fill', 'transparent');
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        current.tspan.setAttributeNS(null, 'fill', 'none');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (fillStrokeMode === TextRenderingMode.STROKE ||
 | 
				
			||||||
 | 
					          fillStrokeMode === TextRenderingMode.FILL_STROKE) {
 | 
				
			||||||
 | 
					        this._setStrokeAttributes(current.tspan);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Include the text rise in the text matrix since the `pm` function
 | 
					      // Include the text rise in the text matrix since the `pm` function
 | 
				
			||||||
      // creates the SVG element's `translate` entry (work on a copy to avoid
 | 
					      // creates the SVG element's `translate` entry (work on a copy to avoid
 | 
				
			||||||
@ -865,7 +890,16 @@ SVGGraphics = (function SVGGraphicsClosure() {
 | 
				
			|||||||
      current.xcoords = [];
 | 
					      current.xcoords = [];
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    endText: function SVGGraphics_endText() {},
 | 
					    endText() {
 | 
				
			||||||
 | 
					      const current = this.current;
 | 
				
			||||||
 | 
					      if ((current.textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG) &&
 | 
				
			||||||
 | 
					          current.txtElement && current.txtElement.hasChildNodes()) {
 | 
				
			||||||
 | 
					        // If no glyphs are shown (i.e. no child nodes), no clipping occurs.
 | 
				
			||||||
 | 
					        current.element = current.txtElement;
 | 
				
			||||||
 | 
					        this.clip('nonzero');
 | 
				
			||||||
 | 
					        this.endPath();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Path properties
 | 
					    // Path properties
 | 
				
			||||||
    setLineWidth: function SVGGraphics_setLineWidth(width) {
 | 
					    setLineWidth: function SVGGraphics_setLineWidth(width) {
 | 
				
			||||||
@ -978,7 +1012,8 @@ SVGGraphics = (function SVGGraphicsClosure() {
 | 
				
			|||||||
      var clipPath = this.svgFactory.createElement('svg:clipPath');
 | 
					      var clipPath = this.svgFactory.createElement('svg:clipPath');
 | 
				
			||||||
      clipPath.setAttributeNS(null, 'id', clipId);
 | 
					      clipPath.setAttributeNS(null, 'id', clipId);
 | 
				
			||||||
      clipPath.setAttributeNS(null, 'transform', pm(this.transformMatrix));
 | 
					      clipPath.setAttributeNS(null, 'transform', pm(this.transformMatrix));
 | 
				
			||||||
      var clipElement = current.element.cloneNode();
 | 
					      // A deep clone is needed when text is used as a clipping path.
 | 
				
			||||||
 | 
					      const clipElement = current.element.cloneNode(true);
 | 
				
			||||||
      if (this.pendingClip === 'evenodd') {
 | 
					      if (this.pendingClip === 'evenodd') {
 | 
				
			||||||
        clipElement.setAttributeNS(null, 'clip-rule', 'evenodd');
 | 
					        clipElement.setAttributeNS(null, 'clip-rule', 'evenodd');
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
@ -1024,6 +1059,10 @@ SVGGraphics = (function SVGGraphicsClosure() {
 | 
				
			|||||||
      this.current.textRise = textRise;
 | 
					      this.current.textRise = textRise;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setTextRenderingMode(textRenderingMode) {
 | 
				
			||||||
 | 
					      this.current.textRenderingMode = textRenderingMode;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setHScale: function SVGGraphics_setHScale(scale) {
 | 
					    setHScale: function SVGGraphics_setHScale(scale) {
 | 
				
			||||||
      this.current.textHScale = scale / 100;
 | 
					      this.current.textHScale = scale / 100;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@ -1079,20 +1118,7 @@ SVGGraphics = (function SVGGraphicsClosure() {
 | 
				
			|||||||
      var current = this.current;
 | 
					      var current = this.current;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (current.element) {
 | 
					      if (current.element) {
 | 
				
			||||||
        current.element.setAttributeNS(null, 'stroke', current.strokeColor);
 | 
					        this._setStrokeAttributes(current.element);
 | 
				
			||||||
        current.element.setAttributeNS(null, 'stroke-opacity',
 | 
					 | 
				
			||||||
                                       current.strokeAlpha);
 | 
					 | 
				
			||||||
        current.element.setAttributeNS(null, 'stroke-miterlimit',
 | 
					 | 
				
			||||||
                                       pf(current.miterLimit));
 | 
					 | 
				
			||||||
        current.element.setAttributeNS(null, 'stroke-linecap', current.lineCap);
 | 
					 | 
				
			||||||
        current.element.setAttributeNS(null, 'stroke-linejoin',
 | 
					 | 
				
			||||||
                                       current.lineJoin);
 | 
					 | 
				
			||||||
        current.element.setAttributeNS(null, 'stroke-width',
 | 
					 | 
				
			||||||
                                       pf(current.lineWidth) + 'px');
 | 
					 | 
				
			||||||
        current.element.setAttributeNS(null, 'stroke-dasharray',
 | 
					 | 
				
			||||||
                                       current.dashArray.map(pf).join(' '));
 | 
					 | 
				
			||||||
        current.element.setAttributeNS(null, 'stroke-dashoffset',
 | 
					 | 
				
			||||||
                                       pf(current.dashPhase) + 'px');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        current.element.setAttributeNS(null, 'fill', 'none');
 | 
					        current.element.setAttributeNS(null, 'fill', 'none');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1100,6 +1126,25 @@ SVGGraphics = (function SVGGraphicsClosure() {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @private
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    _setStrokeAttributes(element) {
 | 
				
			||||||
 | 
					      const current = this.current;
 | 
				
			||||||
 | 
					      element.setAttributeNS(null, 'stroke', current.strokeColor);
 | 
				
			||||||
 | 
					      element.setAttributeNS(null, 'stroke-opacity', current.strokeAlpha);
 | 
				
			||||||
 | 
					      element.setAttributeNS(null, 'stroke-miterlimit',
 | 
				
			||||||
 | 
					                             pf(current.miterLimit));
 | 
				
			||||||
 | 
					      element.setAttributeNS(null, 'stroke-linecap', current.lineCap);
 | 
				
			||||||
 | 
					      element.setAttributeNS(null, 'stroke-linejoin', current.lineJoin);
 | 
				
			||||||
 | 
					      element.setAttributeNS(null, 'stroke-width',
 | 
				
			||||||
 | 
					                             pf(current.lineWidth) + 'px');
 | 
				
			||||||
 | 
					      element.setAttributeNS(null, 'stroke-dasharray',
 | 
				
			||||||
 | 
					                             current.dashArray.map(pf).join(' '));
 | 
				
			||||||
 | 
					      element.setAttributeNS(null, 'stroke-dashoffset',
 | 
				
			||||||
 | 
					                             pf(current.dashPhase) + 'px');
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eoFill: function SVGGraphics_eoFill() {
 | 
					    eoFill: function SVGGraphics_eoFill() {
 | 
				
			||||||
      if (this.current.element) {
 | 
					      if (this.current.element) {
 | 
				
			||||||
        this.current.element.setAttributeNS(null, 'fill-rule', 'evenodd');
 | 
					        this.current.element.setAttributeNS(null, 'fill-rule', 'evenodd');
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user