geometry.hScale = tr[0] - bl[0];
geometry.vScale = tr[1] - bl[1];
}
- var spaceGlyph = font.charsToGlyphs(' ');
-
- // Hack (sometimes space is not encoded)
- if (spaceGlyph.length === 0 || spaceGlyph[0].width === 0)
- spaceGlyph = font.charsToGlyphs('i');
-
- // Fallback
- if (spaceGlyph.length === 0 || spaceGlyph[0].width === 0)
- spaceGlyph = [{width: 0}];
-
- geometry.spaceWidth = spaceGlyph[0].width;
+ geometry.spaceWidth = font.spaceWidth;
return geometry;
},
var textSelection = textLayer && !skipTextSelection ? true : false;
var textRenderingMode = current.textRenderingMode;
- if (textSelection) {
- ctx.save();
- this.applyTextTransforms();
- text.geom = this.getTextGeometry();
- ctx.restore();
- }
-
// Type3 fonts - each glyph is a "mini-PDF"
if (font.coded) {
ctx.save();
ctx.translate(current.x, current.y);
ctx.scale(textHScale, 1);
+
+ if (textSelection) {
+ this.save();
+ ctx.scale(fontSize, fontSize);
+ ctx.transform.apply(ctx, fontMatrix);
+ text.geom = this.getTextGeometry();
+ this.restore();
+ }
for (var i = 0; i < glyphsLength; ++i) {
var glyph = glyphs[i];
var width = transformed[0] * fontSize + charSpacing;
ctx.translate(width, 0);
- current.x += width * textHScale2;
+ current.x += width * textHScale;
text.str += glyph.unicode;
text.length++;
} else {
ctx.save();
this.applyTextTransforms();
+ if (textSelection)
+ text.geom = this.getTextGeometry();
var width = 0;
for (var i = 0; i < glyphsLength; ++i) {
showSpacedText: function canvasGraphicsShowSpacedText(arr) {
var ctx = this.ctx;
var current = this.current;
+ var font = current.font;
var fontSize = current.fontSize;
- var textHScale2 = current.textHScale *
- (current.font.fontMatrix || IDENTITY_MATRIX)[0];
+ var textHScale = current.textHScale;
+ if (!font.coded)
+ textHScale *= (font.fontMatrix || IDENTITY_MATRIX)[0];
var arrLength = arr.length;
var textLayer = this.textLayer;
- var font = current.font;
var text = {str: '', length: 0, canvasWidth: 0, geom: {}};
var textSelection = textLayer ? true : false;
if (textSelection) {
ctx.save();
- this.applyTextTransforms();
+ if (font.coded) {
+ ctx.transform.apply(ctx, current.textMatrix);
+ ctx.scale(1, -1);
+ ctx.translate(current.x, -1 * current.y);
+ ctx.scale(textHScale, 1);
+ } else
+ this.applyTextTransforms();
text.geom = this.getTextGeometry();
ctx.restore();
}
for (var i = 0; i < arrLength; ++i) {
var e = arr[i];
if (isNum(e)) {
- var spacingLength = -e * 0.001 * fontSize * textHScale2;
+ var spacingLength = -e * 0.001 * fontSize * textHScale;
current.x += spacingLength;
if (textSelection) {
text.canvasWidth += spacingLength;
if (e < 0 && text.geom.spaceWidth > 0) { // avoid div by zero
var numFakeSpaces = Math.round(-e / text.geom.spaceWidth);
- for (var j = 0; j < numFakeSpaces; ++j)
+ if (numFakeSpaces > 0) {
text.str += ' ';
- text.length += numFakeSpaces > 0 ? 1 : 0;
+ text.length++;
+ }
}
}
} else if (isString(e)) {
return rule;
},
+ get spaceWidth() {
+ // trying to estimate space character width
+ var possibleSpaceReplacements = ['space', 'minus', '1', 'i'];
+ var width;
+ for (var i = 0, ii = possibleSpaceReplacements.length; i < ii; i++) {
+ var glyphName = possibleSpaceReplacements[i];
+ // if possible, getting width by glyph name
+ if (glyphName in this.widths) {
+ width = this.widths[glyphName];
+ break;
+ }
+ var glyphUnicode = GlyphsUnicode[glyphName];
+ // finding the charcode via unicodeToCID map
+ var charcode = 0;
+ if (this.composite)
+ charcode = this.unicodeToCID[glyphUnicode];
+ // ... via toUnicode map
+ if (!charcode && 'toUnicode' in this)
+ charcode = this.toUnicode.indexOf(glyphUnicode);
+ // setting it to unicode if negative or undefined
+ if (!(charcode > 0))
+ charcode = glyphUnicode;
+ // trying to get width via charcode
+ width = this.widths[charcode];
+ if (width)
+ break; // the non-zero width found
+ }
+ width = (width || this.defaultWidth) * this.widthMultiplier;
+ return shadow(this, 'spaceWidth', width);
+ },
+
charToGlyph: function fonts_charToGlyph(charcode) {
var unicode, width, codeIRQueue;