Implemented selection for showText()
This commit is contained in:
		
							parent
							
								
									46a48a56b7
								
							
						
					
					
						commit
						9ebec03ddc
					
				
							
								
								
									
										153
									
								
								src/canvas.js
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								src/canvas.js
									
									
									
									
									
								
							@ -453,7 +453,58 @@ var CanvasGraphics = (function canvasGraphics() {
 | 
				
			|||||||
    nextLine: function canvasGraphicsNextLine() {
 | 
					    nextLine: function canvasGraphicsNextLine() {
 | 
				
			||||||
      this.moveText(0, this.current.leading);
 | 
					      this.moveText(0, this.current.leading);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    showText: function canvasGraphicsShowText(text) {
 | 
					    applyTextTransforms: function canvasApplyTransforms() {
 | 
				
			||||||
 | 
					      var ctx = this.ctx;
 | 
				
			||||||
 | 
					      var current = this.current;
 | 
				
			||||||
 | 
					      var textHScale = current.textHScale;
 | 
				
			||||||
 | 
					      var font = current.font;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ctx.transform.apply(ctx, current.textMatrix);
 | 
				
			||||||
 | 
					      ctx.scale(1, -1);
 | 
				
			||||||
 | 
					      ctx.translate(current.x, -1 * current.y);
 | 
				
			||||||
 | 
					      ctx.transform.apply(ctx, font.fontMatrix || IDENTITY_MATRIX);
 | 
				
			||||||
 | 
					      ctx.scale(1 / textHScale, 1);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getTextGeometry: function canvasGetTextGeometry() {
 | 
				
			||||||
 | 
					      var geom = {};
 | 
				
			||||||
 | 
					      var ctx = this.ctx;
 | 
				
			||||||
 | 
					      var font = this.current.font;
 | 
				
			||||||
 | 
					      var ctxMatrix = ctx.mozCurrentTransform;
 | 
				
			||||||
 | 
					      if (ctxMatrix) {
 | 
				
			||||||
 | 
					        var bl = Util.applyTransform([0, 0], ctxMatrix);
 | 
				
			||||||
 | 
					        var tr = Util.applyTransform([1, 1], ctxMatrix);
 | 
				
			||||||
 | 
					        geom.x = bl[0];
 | 
				
			||||||
 | 
					        geom.y = bl[1];
 | 
				
			||||||
 | 
					        geom.hScale = tr[0] - bl[0];
 | 
				
			||||||
 | 
					        geom.vScale = tr[1] - bl[1];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      var spaceGlyph = font.charsToGlyphs(' ', true);
 | 
				
			||||||
 | 
					      // Hack (sometimes space is not encoded)
 | 
				
			||||||
 | 
					      if (spaceGlyph.length === 0 || spaceGlyph[0].width === 0)
 | 
				
			||||||
 | 
					        spaceGlyph = font.charsToGlyphs('i', true);
 | 
				
			||||||
 | 
					      // Fallback
 | 
				
			||||||
 | 
					      if (spaceGlyph.length === 0 || spaceGlyph[0].width === 0)
 | 
				
			||||||
 | 
					        spaceGlyph = [ {width:0} ];
 | 
				
			||||||
 | 
					      geom.spaceWidth = spaceGlyph[0].width;
 | 
				
			||||||
 | 
					      return geom;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    pushTextDivs: function canvasGraphicsPushTextDivs(text) {
 | 
				
			||||||
 | 
					      var div = document.createElement('div');
 | 
				
			||||||
 | 
					      var fontSize = this.current.fontSize;
 | 
				
			||||||
 | 
					      var fontHeight = text.geom.vScale * fontSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      div.style.fontSize = fontHeight + 'px';
 | 
				
			||||||
 | 
					      // TODO: family should be '= font.loadedName', but some fonts don't 
 | 
				
			||||||
 | 
					      // have spacing info (cf. fonts.js > Font > fields > htmx)
 | 
				
			||||||
 | 
					      div.style.fontFamily = 'serif'; 
 | 
				
			||||||
 | 
					      div.style.left = text.geom.x + 'px';
 | 
				
			||||||
 | 
					      div.style.top = (text.geom.y - fontHeight) + 'px';
 | 
				
			||||||
 | 
					      div.innerHTML = text.str;
 | 
				
			||||||
 | 
					      div.dataset.canvasWidth = text.canvasWidth * text.geom.hScale;
 | 
				
			||||||
 | 
					      div.dataset.textLength = text.length;
 | 
				
			||||||
 | 
					      this.textDivs.push(div);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    showText: function canvasGraphicsShowText(str, skipTextSelection) {
 | 
				
			||||||
      function unicodeToChar(unicode) {
 | 
					      function unicodeToChar(unicode) {
 | 
				
			||||||
        return (unicode >= 0x10000) ?
 | 
					        return (unicode >= 0x10000) ?
 | 
				
			||||||
          String.fromCharCode(0xD800 | ((unicode - 0x10000) >> 10),
 | 
					          String.fromCharCode(0xD800 | ((unicode - 0x10000) >> 10),
 | 
				
			||||||
@ -463,14 +514,24 @@ var CanvasGraphics = (function canvasGraphics() {
 | 
				
			|||||||
      var ctx = this.ctx;
 | 
					      var ctx = this.ctx;
 | 
				
			||||||
      var current = this.current;
 | 
					      var current = this.current;
 | 
				
			||||||
      var font = current.font;
 | 
					      var font = current.font;
 | 
				
			||||||
      var glyphs = font.charsToGlyphs(text);
 | 
					      var glyphs = font.charsToGlyphs(str);
 | 
				
			||||||
      var fontSize = current.fontSize;
 | 
					      var fontSize = current.fontSize;
 | 
				
			||||||
      var charSpacing = current.charSpacing;
 | 
					      var charSpacing = current.charSpacing;
 | 
				
			||||||
      var wordSpacing = current.wordSpacing;
 | 
					      var wordSpacing = current.wordSpacing;
 | 
				
			||||||
      var textHScale = current.textHScale;
 | 
					      var textHScale = current.textHScale;
 | 
				
			||||||
      var glyphsLength = glyphs.length;
 | 
					      var glyphsLength = glyphs.length;
 | 
				
			||||||
      var text = { chars:'', width:0 };
 | 
					      var textLayer = this.textLayer;
 | 
				
			||||||
 | 
					      var text = { str:'', length:0, canvasWidth:0, geom:{}};
 | 
				
			||||||
 | 
					      var textSelection = textLayer && !skipTextSelection ? true : false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (textSelection) {
 | 
				
			||||||
 | 
					        ctx.save();
 | 
				
			||||||
 | 
					        this.applyTextTransforms();
 | 
				
			||||||
 | 
					        text.geom = this.getTextGeometry();
 | 
				
			||||||
 | 
					        ctx.restore();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					      // Type3 fonts - each glyph is a "mini-PDF"
 | 
				
			||||||
      if (font.coded) {
 | 
					      if (font.coded) {
 | 
				
			||||||
        ctx.save();
 | 
					        ctx.save();
 | 
				
			||||||
        ctx.transform.apply(ctx, current.textMatrix);
 | 
					        ctx.transform.apply(ctx, current.textMatrix);
 | 
				
			||||||
@ -498,17 +559,14 @@ var CanvasGraphics = (function canvasGraphics() {
 | 
				
			|||||||
          ctx.translate(charWidth, 0);
 | 
					          ctx.translate(charWidth, 0);
 | 
				
			||||||
          current.x += charWidth;
 | 
					          current.x += charWidth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          text.chars += unicodeToChar(glyph.unicode);
 | 
					          text.str += unicodeToChar(glyph.unicode);
 | 
				
			||||||
          text.width += charWidth;
 | 
					          text.canvasWidth += charWidth;
 | 
				
			||||||
 | 
					          text.length++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ctx.restore();
 | 
					        ctx.restore();
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        ctx.save();
 | 
					        ctx.save();
 | 
				
			||||||
        ctx.transform.apply(ctx, current.textMatrix);
 | 
					        this.applyTextTransforms();
 | 
				
			||||||
        ctx.scale(1, -1);
 | 
					 | 
				
			||||||
        ctx.translate(current.x, -1 * current.y);
 | 
					 | 
				
			||||||
        ctx.transform.apply(ctx, font.fontMatrix || IDENTITY_MATRIX);
 | 
					 | 
				
			||||||
        ctx.scale(1 / textHScale, 1);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var width = 0;
 | 
					        var width = 0;
 | 
				
			||||||
        for (var i = 0; i < glyphsLength; ++i) {
 | 
					        for (var i = 0; i < glyphsLength; ++i) {
 | 
				
			||||||
@ -524,12 +582,18 @@ var CanvasGraphics = (function canvasGraphics() {
 | 
				
			|||||||
          ctx.fillText(char, width, 0);
 | 
					          ctx.fillText(char, width, 0);
 | 
				
			||||||
          width += charWidth;
 | 
					          width += charWidth;
 | 
				
			||||||
          
 | 
					          
 | 
				
			||||||
          text.chars += char;
 | 
					          text.str += char;
 | 
				
			||||||
          text.width += charWidth;
 | 
					          text.canvasWidth += charWidth;
 | 
				
			||||||
 | 
					          text.length++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        current.x += width;
 | 
					        current.x += width;
 | 
				
			||||||
        ctx.restore();
 | 
					        ctx.restore();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (textSelection) 
 | 
				
			||||||
 | 
					        this.pushTextDivs(text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return text;
 | 
					      return text;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    showSpacedText: function canvasGraphicsShowSpacedText(arr) {
 | 
					    showSpacedText: function canvasGraphicsShowSpacedText(arr) {
 | 
				
			||||||
@ -540,32 +604,13 @@ var CanvasGraphics = (function canvasGraphics() {
 | 
				
			|||||||
      var arrLength = arr.length;
 | 
					      var arrLength = arr.length;
 | 
				
			||||||
      var textLayer = this.textLayer;
 | 
					      var textLayer = this.textLayer;
 | 
				
			||||||
      var font = current.font;
 | 
					      var font = current.font;
 | 
				
			||||||
      var text = {str:'', length:0, canvasWidth:0, spaceWidth:0, geom:{}};
 | 
					      var text = {str:'', length:0, canvasWidth:0, geom:{}};
 | 
				
			||||||
 | 
					      var textSelection = textLayer ? true : false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (textLayer) {
 | 
					      if (textSelection) {
 | 
				
			||||||
        text.spaceWidth = this.current.font.charsToGlyphs(' ')[0].width;
 | 
					 | 
				
			||||||
        if (!text.spaceWidth>0) {
 | 
					 | 
				
			||||||
          // Hack (space is sometimes not encoded)
 | 
					 | 
				
			||||||
          text.spaceWidth = this.current.font.charsToGlyphs('i')[0].width;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Compute text.geom
 | 
					 | 
				
			||||||
        // TODO: refactor the series of transformations below, and share it with showText()
 | 
					 | 
				
			||||||
        ctx.save();
 | 
					        ctx.save();
 | 
				
			||||||
        ctx.transform.apply(ctx, current.textMatrix);
 | 
					        this.applyTextTransforms();
 | 
				
			||||||
        ctx.scale(1, -1);
 | 
					        text.geom = this.getTextGeometry();
 | 
				
			||||||
        ctx.translate(current.x, -1 * current.y);
 | 
					 | 
				
			||||||
        ctx.transform.apply(ctx, font.fontMatrix || IDENTITY_MATRIX);
 | 
					 | 
				
			||||||
        ctx.scale(1 / textHScale, 1);
 | 
					 | 
				
			||||||
        var ctxMatrix = ctx.mozCurrentTransform;
 | 
					 | 
				
			||||||
        if (ctxMatrix) {
 | 
					 | 
				
			||||||
          var bl = Util.applyTransform([0, 0], ctxMatrix);
 | 
					 | 
				
			||||||
          var tr = Util.applyTransform([1, 1], ctxMatrix);
 | 
					 | 
				
			||||||
          text.geom.x = bl[0];
 | 
					 | 
				
			||||||
          text.geom.y = bl[1];
 | 
					 | 
				
			||||||
          text.geom.xFactor = tr[0] - bl[0];
 | 
					 | 
				
			||||||
          text.geom.yFactor = tr[1] - bl[1];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ctx.restore();
 | 
					        ctx.restore();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
@ -575,47 +620,35 @@ var CanvasGraphics = (function canvasGraphics() {
 | 
				
			|||||||
          var spacingLength = -e * 0.001 * fontSize * textHScale;
 | 
					          var spacingLength = -e * 0.001 * fontSize * textHScale;
 | 
				
			||||||
          current.x += spacingLength;
 | 
					          current.x += spacingLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (textLayer) {
 | 
					          if (textSelection) {
 | 
				
			||||||
            // Emulate precise spacing via HTML spaces
 | 
					            // Emulate precise spacing via HTML spaces
 | 
				
			||||||
            text.canvasWidth += spacingLength;
 | 
					            text.canvasWidth += spacingLength;
 | 
				
			||||||
            if (e<0 && text.spaceWidth>0) { // avoid div by zero
 | 
					            if (e<0 && text.geom.spaceWidth>0) { // avoid div by zero
 | 
				
			||||||
              var numFakeSpaces = Math.round(-e / text.spaceWidth);
 | 
					              var numFakeSpaces = Math.round(-e / text.geom.spaceWidth);
 | 
				
			||||||
              for (var j = 0; j < numFakeSpaces; ++j)
 | 
					              for (var j = 0; j < numFakeSpaces; ++j)
 | 
				
			||||||
                text.str += ' ';
 | 
					                text.str += ' ';
 | 
				
			||||||
              text.length += numFakeSpaces>0 ? 1 : 0;
 | 
					              text.length += numFakeSpaces>0 ? 1 : 0;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        } else if (isString(e)) {
 | 
					        } else if (isString(e)) {
 | 
				
			||||||
          var shownText = this.showText(e);
 | 
					          var shownText = this.showText(e, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (textLayer) {
 | 
					          if (textSelection) {
 | 
				
			||||||
            if (shownText.chars === ' ') {
 | 
					            if (shownText.str === ' ') {
 | 
				
			||||||
              text.str += ' ';        
 | 
					              text.str += ' ';
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              text.str += shownText.chars;
 | 
					              text.str += shownText.str;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            text.canvasWidth += shownText.width;
 | 
					            text.canvasWidth += shownText.canvasWidth;
 | 
				
			||||||
            text.length += e.length;
 | 
					            text.length += e.length;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          malformed('TJ array element ' + e + ' is not string or num');
 | 
					          malformed('TJ array element ' + e + ' is not string or num');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
      if (textLayer) {
 | 
					      if (textSelection) 
 | 
				
			||||||
        var div = document.createElement('div');
 | 
					        this.pushTextDivs(text);
 | 
				
			||||||
        var fontHeight = text.geom.yFactor * fontSize;
 | 
					 | 
				
			||||||
        div.style.fontSize = fontHeight + 'px';
 | 
					 | 
				
			||||||
        // TODO: family should be '= font.loadedName', but some fonts don't 
 | 
					 | 
				
			||||||
        // have spacing info (cf. fonts.js > Font > fields > htmx)
 | 
					 | 
				
			||||||
        div.style.fontFamily = 'serif'; 
 | 
					 | 
				
			||||||
        div.style.left = text.geom.x + 'px';
 | 
					 | 
				
			||||||
        div.style.top = (text.geom.y - fontHeight) + 'px';
 | 
					 | 
				
			||||||
        div.innerHTML = text.str;
 | 
					 | 
				
			||||||
        div.dataset.canvasWidth = text.canvasWidth * text.geom.xFactor;
 | 
					 | 
				
			||||||
        div.dataset.textLength = text.length;
 | 
					 | 
				
			||||||
        this.textDivs.push(div);                
 | 
					 | 
				
			||||||
      }      
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    nextLineShowText: function canvasGraphicsNextLineShowText(text) {
 | 
					    nextLineShowText: function canvasGraphicsNextLineShowText(text) {
 | 
				
			||||||
      this.nextLine();
 | 
					      this.nextLine();
 | 
				
			||||||
 | 
				
			|||||||
@ -1797,7 +1797,7 @@ var Font = (function Font() {
 | 
				
			|||||||
      return rule;
 | 
					      return rule;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    charsToGlyphs: function fonts_chars2Glyphs(chars) {
 | 
					    charsToGlyphs: function fonts_chars2Glyphs(chars, suppressWarnings) {
 | 
				
			||||||
      var charsCache = this.charsCache;
 | 
					      var charsCache = this.charsCache;
 | 
				
			||||||
      var glyphs;
 | 
					      var glyphs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1830,7 +1830,8 @@ var Font = (function Font() {
 | 
				
			|||||||
          var charcode = int16([chars.charCodeAt(i++), chars.charCodeAt(i)]);
 | 
					          var charcode = int16([chars.charCodeAt(i++), chars.charCodeAt(i)]);
 | 
				
			||||||
          var glyph = encoding[charcode];
 | 
					          var glyph = encoding[charcode];
 | 
				
			||||||
          if ('undefined' == typeof(glyph)) {
 | 
					          if ('undefined' == typeof(glyph)) {
 | 
				
			||||||
            warn('Unencoded charcode ' + charcode);
 | 
					            if (!suppressWarnings)
 | 
				
			||||||
 | 
					              warn('Unencoded charcode ' + charcode);
 | 
				
			||||||
            glyph = {
 | 
					            glyph = {
 | 
				
			||||||
              unicode: charcode,
 | 
					              unicode: charcode,
 | 
				
			||||||
              width: this.defaultWidth
 | 
					              width: this.defaultWidth
 | 
				
			||||||
@ -1847,7 +1848,8 @@ var Font = (function Font() {
 | 
				
			|||||||
          var charcode = chars.charCodeAt(i);
 | 
					          var charcode = chars.charCodeAt(i);
 | 
				
			||||||
          var glyph = encoding[charcode];
 | 
					          var glyph = encoding[charcode];
 | 
				
			||||||
          if ('undefined' == typeof(glyph)) {
 | 
					          if ('undefined' == typeof(glyph)) {
 | 
				
			||||||
            warn('Unencoded charcode ' + charcode);
 | 
					            if (!suppressWarnings)
 | 
				
			||||||
 | 
					              warn('Unencoded charcode ' + charcode);
 | 
				
			||||||
            glyph = {
 | 
					            glyph = {
 | 
				
			||||||
              unicode: charcode,
 | 
					              unicode: charcode,
 | 
				
			||||||
              width: this.defaultWidth
 | 
					              width: this.defaultWidth
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user