@@ -453,7 +453,58 @@ var CanvasGraphics = (function canvasGraphics() {
453
453
nextLine : function canvasGraphicsNextLine () {
454
454
this .moveText (0 , this .current .leading );
455
455
},
456
- showText : function canvasGraphicsShowText (text ) {
456
+ applyTextTransforms : function canvasApplyTransforms () {
457
+ var ctx = this .ctx ;
458
+ var current = this .current ;
459
+ var textHScale = current .textHScale ;
460
+ var font = current .font ;
461
+
462
+ ctx .transform .apply (ctx , current .textMatrix );
463
+ ctx .scale (1 , -1 );
464
+ ctx .translate (current .x , -1 * current .y );
465
+ ctx .transform .apply (ctx , font .fontMatrix || IDENTITY_MATRIX );
466
+ ctx .scale (1 / textHScale , 1 );
467
+ },
468
+ getTextGeometry : function canvasGetTextGeometry () {
469
+ var geom = {};
470
+ var ctx = this .ctx ;
471
+ var font = this .current .font ;
472
+ var ctxMatrix = ctx .mozCurrentTransform ;
473
+ if (ctxMatrix ) {
474
+ var bl = Util .applyTransform ([0 , 0 ], ctxMatrix );
475
+ var tr = Util .applyTransform ([1 , 1 ], ctxMatrix );
476
+ geom .x = bl [0 ];
477
+ geom .y = bl [1 ];
478
+ geom .hScale = tr [0 ] - bl [0 ];
479
+ geom .vScale = tr [1 ] - bl [1 ];
480
+ }
481
+ var spaceGlyph = font .charsToGlyphs (' ' , true );
482
+ // Hack (sometimes space is not encoded)
483
+ if (spaceGlyph .length === 0 || spaceGlyph [0 ].width === 0 )
484
+ spaceGlyph = font .charsToGlyphs ('i' , true );
485
+ // Fallback
486
+ if (spaceGlyph .length === 0 || spaceGlyph [0 ].width === 0 )
487
+ spaceGlyph = [ {width :0 } ];
488
+ geom .spaceWidth = spaceGlyph [0 ].width ;
489
+ return geom ;
490
+ },
491
+ pushTextDivs : function canvasGraphicsPushTextDivs (text ) {
492
+ var div = document .createElement ('div' );
493
+ var fontSize = this .current .fontSize ;
494
+ var fontHeight = text .geom .vScale * fontSize ;
495
+
496
+ div .style .fontSize = fontHeight + 'px' ;
497
+ // TODO: family should be '= font.loadedName', but some fonts don't
498
+ // have spacing info (cf. fonts.js > Font > fields > htmx)
499
+ div .style .fontFamily = 'serif' ;
500
+ div .style .left = text .geom .x + 'px' ;
501
+ div .style .top = (text .geom .y - fontHeight ) + 'px' ;
502
+ div .innerHTML = text .str ;
503
+ div .dataset .canvasWidth = text .canvasWidth * text .geom .hScale ;
504
+ div .dataset .textLength = text .length ;
505
+ this .textDivs .push (div );
506
+ },
507
+ showText : function canvasGraphicsShowText (str , skipTextSelection ) {
457
508
function unicodeToChar (unicode ) {
458
509
return (unicode >= 0x10000 ) ?
459
510
String .fromCharCode (0xD800 | ((unicode - 0x10000 ) >> 10 ),
@@ -463,14 +514,24 @@ var CanvasGraphics = (function canvasGraphics() {
463
514
var ctx = this .ctx ;
464
515
var current = this .current ;
465
516
var font = current .font ;
466
- var glyphs = font .charsToGlyphs (text );
517
+ var glyphs = font .charsToGlyphs (str );
467
518
var fontSize = current .fontSize ;
468
519
var charSpacing = current .charSpacing ;
469
520
var wordSpacing = current .wordSpacing ;
470
521
var textHScale = current .textHScale ;
471
522
var glyphsLength = glyphs .length ;
472
- var text = { chars :'', width:0 };
523
+ var textLayer = this .textLayer ;
524
+ var text = { str :'', length:0, canvasWidth:0, geom:{}};
525
+ var textSelection = textLayer && !skipTextSelection ? true : false ;
526
+
527
+ if (textSelection ) {
528
+ ctx .save ();
529
+ this .applyTextTransforms ();
530
+ text .geom = this .getTextGeometry ();
531
+ ctx .restore ();
532
+ }
473
533
534
+ // Type3 fonts - each glyph is a "mini-PDF"
474
535
if (font .coded ) {
475
536
ctx .save ();
476
537
ctx .transform .apply (ctx , current .textMatrix );
@@ -498,17 +559,14 @@ var CanvasGraphics = (function canvasGraphics() {
498
559
ctx .translate (charWidth , 0 );
499
560
current .x += charWidth ;
500
561
501
- text .chars += unicodeToChar (glyph .unicode );
502
- text .width += charWidth ;
562
+ text .str += unicodeToChar (glyph .unicode );
563
+ text .canvasWidth += charWidth ;
564
+ text .length ++;
503
565
}
504
566
ctx .restore ();
505
567
} else {
506
568
ctx .save ();
507
- ctx .transform .apply (ctx , current .textMatrix );
508
- ctx .scale (1 , -1 );
509
- ctx .translate (current .x , -1 * current .y );
510
- ctx .transform .apply (ctx , font .fontMatrix || IDENTITY_MATRIX );
511
- ctx .scale (1 / textHScale , 1 );
569
+ this .applyTextTransforms ();
512
570
513
571
var width = 0 ;
514
572
for (var i = 0 ; i < glyphsLength ; ++i ) {
@@ -524,12 +582,18 @@ var CanvasGraphics = (function canvasGraphics() {
524
582
ctx .fillText (char , width , 0 );
525
583
width += charWidth ;
526
584
527
- text .chars += char ;
528
- text .width += charWidth ;
585
+ text .str += char ;
586
+ text .canvasWidth += charWidth ;
587
+ text .length ++;
529
588
}
589
+
530
590
current .x += width ;
531
591
ctx .restore ();
532
592
}
593
+
594
+ if (textSelection )
595
+ this .pushTextDivs (text );
596
+
533
597
return text ;
534
598
},
535
599
showSpacedText : function canvasGraphicsShowSpacedText (arr ) {
@@ -540,32 +604,13 @@ var CanvasGraphics = (function canvasGraphics() {
540
604
var arrLength = arr .length ;
541
605
var textLayer = this .textLayer ;
542
606
var font = current .font ;
543
- var text = {str :'', length:0, canvasWidth:0, spaceWidth:0, geom:{}};
544
-
545
- if (textLayer ) {
546
- text .spaceWidth = this .current .font .charsToGlyphs (' ' )[0 ].width ;
547
- if (!text .spaceWidth >0 ) {
548
- // Hack (space is sometimes not encoded)
549
- text .spaceWidth = this .current .font .charsToGlyphs ('i' )[0 ].width ;
550
- }
607
+ var text = {str :'', length:0, canvasWidth:0, geom:{}};
608
+ var textSelection = textLayer ? true : false ;
551
609
552
- // Compute text.geom
553
- // TODO: refactor the series of transformations below, and share it with showText()
610
+ if (textSelection ) {
554
611
ctx .save ();
555
- ctx .transform .apply (ctx , current .textMatrix );
556
- ctx .scale (1 , -1 );
557
- ctx .translate (current .x , -1 * current .y );
558
- ctx .transform .apply (ctx , font .fontMatrix || IDENTITY_MATRIX );
559
- ctx .scale (1 / textHScale , 1 );
560
- var ctxMatrix = ctx .mozCurrentTransform ;
561
- if (ctxMatrix ) {
562
- var bl = Util .applyTransform ([0 , 0 ], ctxMatrix );
563
- var tr = Util .applyTransform ([1 , 1 ], ctxMatrix );
564
- text .geom .x = bl [0 ];
565
- text .geom .y = bl [1 ];
566
- text .geom .xFactor = tr [0 ] - bl [0 ];
567
- text .geom .yFactor = tr [1 ] - bl [1 ];
568
- }
612
+ this .applyTextTransforms ();
613
+ text .geom = this .getTextGeometry ();
569
614
ctx .restore ();
570
615
}
571
616
@@ -575,47 +620,35 @@ var CanvasGraphics = (function canvasGraphics() {
575
620
var spacingLength = -e * 0.001 * fontSize * textHScale ;
576
621
current .x += spacingLength ;
577
622
578
- if (textLayer ) {
623
+ if (textSelection ) {
579
624
// Emulate precise spacing via HTML spaces
580
625
text .canvasWidth += spacingLength ;
581
- if (e <0 && text .spaceWidth >0 ) { // avoid div by zero
582
- var numFakeSpaces = Math .round (-e / text .spaceWidth );
626
+ if (e <0 && text .geom . spaceWidth >0 ) { // avoid div by zero
627
+ var numFakeSpaces = Math .round (-e / text .geom . spaceWidth );
583
628
for (var j = 0 ; j < numFakeSpaces ; ++j )
584
629
text .str += ' ' ;
585
630
text .length += numFakeSpaces >0 ? 1 : 0 ;
586
631
}
587
632
}
588
633
} else if (isString (e )) {
589
- var shownText = this .showText (e );
634
+ var shownText = this .showText (e , true );
590
635
591
- if (textLayer ) {
592
- if (shownText .chars === ' ' ) {
593
- text .str += ' ' ;
636
+ if (textSelection ) {
637
+ if (shownText .str === ' ' ) {
638
+ text .str += ' ' ;
594
639
} else {
595
- text .str += shownText .chars ;
640
+ text .str += shownText .str ;
596
641
}
597
- text .canvasWidth += shownText .width ;
642
+ text .canvasWidth += shownText .canvasWidth ;
598
643
text .length += e .length ;
599
644
}
600
645
} else {
601
646
malformed ('TJ array element ' + e + ' is not string or num' );
602
647
}
603
648
}
604
-
605
- if (textLayer ) {
606
- var div = document .createElement ('div' );
607
- var fontHeight = text .geom .yFactor * fontSize ;
608
- div .style .fontSize = fontHeight + 'px' ;
609
- // TODO: family should be '= font.loadedName', but some fonts don't
610
- // have spacing info (cf. fonts.js > Font > fields > htmx)
611
- div .style .fontFamily = 'serif' ;
612
- div .style .left = text .geom .x + 'px' ;
613
- div .style .top = (text .geom .y - fontHeight ) + 'px' ;
614
- div .innerHTML = text .str ;
615
- div .dataset .canvasWidth = text .canvasWidth * text .geom .xFactor ;
616
- div .dataset .textLength = text .length ;
617
- this .textDivs .push (div );
618
- }
649
+
650
+ if (textSelection )
651
+ this .pushTextDivs (text );
619
652
},
620
653
nextLineShowText : function canvasGraphicsNextLineShowText (text ) {
621
654
this .nextLine ();
0 commit comments