Draw glyphs one by one to position them correctly and remove all the scaling hack
This commit is contained in:
parent
26a6b9763b
commit
13bf137220
61
fonts.js
61
fonts.js
@ -114,60 +114,6 @@ var serifFonts = {
|
|||||||
'Wide Latin': true, 'Windsor': true, 'XITS': true
|
'Wide Latin': true, 'Windsor': true, 'XITS': true
|
||||||
};
|
};
|
||||||
|
|
||||||
var FontMeasure = (function FontMeasure() {
|
|
||||||
var kScalePrecision = 30;
|
|
||||||
var ctx = document.createElement('canvas').getContext('2d');
|
|
||||||
ctx.scale(1 / kScalePrecision, 1);
|
|
||||||
|
|
||||||
var current;
|
|
||||||
var measureCache;
|
|
||||||
|
|
||||||
return {
|
|
||||||
setActive: function fonts_setActive(font, size) {
|
|
||||||
if (current == font) {
|
|
||||||
var sizes = current.sizes;
|
|
||||||
if (!(measureCache = sizes[size]))
|
|
||||||
measureCache = sizes[size] = Object.create(null);
|
|
||||||
} else {
|
|
||||||
measureCache = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = font.loadedName;
|
|
||||||
var bold = font.bold ? 'bold' : 'normal';
|
|
||||||
var italic = font.italic ? 'italic' : 'normal';
|
|
||||||
size *= kScalePrecision;
|
|
||||||
var rule = italic + ' ' + bold + ' ' + size + 'px "' + name + '"';
|
|
||||||
ctx.font = rule;
|
|
||||||
current = font;
|
|
||||||
},
|
|
||||||
measureText: function fonts_measureText(text, font, size) {
|
|
||||||
var width;
|
|
||||||
if (measureCache && (width = measureCache[text]))
|
|
||||||
return width;
|
|
||||||
|
|
||||||
try {
|
|
||||||
width = 0.0;
|
|
||||||
var composite = font.composite;
|
|
||||||
for (var i = 0; i < text.length; i++) {
|
|
||||||
var charcode = composite ?
|
|
||||||
((text.charCodeAt(i++) << 8) + text.charCodeAt(i)) :
|
|
||||||
text.charCodeAt(i);
|
|
||||||
var charWidth = parseFloat(font.encoding[charcode].width);
|
|
||||||
width += charWidth;
|
|
||||||
}
|
|
||||||
// XXX should use the unit-per-em value from the embedded font
|
|
||||||
var unitsPerEm = 1000;
|
|
||||||
width = width * size / unitsPerEm;
|
|
||||||
} catch(e) {
|
|
||||||
width = ctx.measureText(text).width / kScalePrecision;
|
|
||||||
}
|
|
||||||
if (measureCache)
|
|
||||||
measureCache[text] = width;
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
var FontLoader = {
|
var FontLoader = {
|
||||||
listeningForFontLoad: false,
|
listeningForFontLoad: false,
|
||||||
|
|
||||||
@ -1142,9 +1088,10 @@ var Font = (function Font() {
|
|||||||
// so create an identity encoding
|
// so create an identity encoding
|
||||||
var widths = properties.widths;
|
var widths = properties.widths;
|
||||||
for (i = 0; i < numGlyphs; i++) {
|
for (i = 0; i < numGlyphs; i++) {
|
||||||
|
var width = widths[i];
|
||||||
encoding[i] = {
|
encoding[i] = {
|
||||||
unicode: i + kCmapGlyphOffset,
|
unicode: i + kCmapGlyphOffset,
|
||||||
width: widths[i] || properties.defaultWidth
|
width: IsNum(width) ? width : properties.defaultWidth
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2360,13 +2307,13 @@ var Type2CFF = (function() {
|
|||||||
if (code == -1)
|
if (code == -1)
|
||||||
index = code = mapping.unicode || index;
|
index = code = mapping.unicode || index;
|
||||||
|
|
||||||
var width = mapping.width || defaultWidth;
|
|
||||||
if (code <= 0x1f || (code >= 127 && code <= 255))
|
if (code <= 0x1f || (code >= 127 && code <= 255))
|
||||||
code += kCmapGlyphOffset;
|
code += kCmapGlyphOffset;
|
||||||
|
|
||||||
|
var width = mapping.width;
|
||||||
properties.glyphs[glyph] = properties.encoding[index] = {
|
properties.glyphs[glyph] = properties.encoding[index] = {
|
||||||
unicode: code,
|
unicode: code,
|
||||||
width: width
|
width: IsNum(width) ? width : defaultWidth
|
||||||
};
|
};
|
||||||
|
|
||||||
charstrings.push({
|
charstrings.push({
|
||||||
|
65
pdf.js
65
pdf.js
@ -4242,9 +4242,10 @@ var PartialEvaluator = (function() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var code = j >> 1;
|
var code = j >> 1;
|
||||||
|
var width = glyphsWidths[code];
|
||||||
encoding[code] = {
|
encoding[code] = {
|
||||||
unicode: glyphID,
|
unicode: glyphID,
|
||||||
width: glyphsWidths[code] || defaultWidth
|
width: IsNum(width) ? width : defaultWidth
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else if (type == 'CIDFontType0') {
|
} else if (type == 'CIDFontType0') {
|
||||||
@ -4316,7 +4317,7 @@ var PartialEvaluator = (function() {
|
|||||||
var width = properties.widths[i] || properties.widths[glyph];
|
var width = properties.widths[i] || properties.widths[glyph];
|
||||||
map[i] = {
|
map[i] = {
|
||||||
unicode: index,
|
unicode: index,
|
||||||
width: width || properties.defaultWidth
|
width: IsNum(width) ? width : properties.defaultWidth
|
||||||
};
|
};
|
||||||
|
|
||||||
if (glyph)
|
if (glyph)
|
||||||
@ -4615,9 +4616,6 @@ function ScratchCanvas(width, height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var CanvasGraphics = (function() {
|
var CanvasGraphics = (function() {
|
||||||
var kScalePrecision = 50.0;
|
|
||||||
var kRasterizerMin = 14;
|
|
||||||
|
|
||||||
function constructor(canvasCtx, imageCanvas) {
|
function constructor(canvasCtx, imageCanvas) {
|
||||||
this.ctx = canvasCtx;
|
this.ctx = canvasCtx;
|
||||||
this.current = new CanvasExtraState();
|
this.current = new CanvasExtraState();
|
||||||
@ -4878,22 +4876,13 @@ var CanvasGraphics = (function() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var fontObj = font.fontObj;
|
var fontObj = font.fontObj;
|
||||||
var name = fontObj.loadedName;
|
|
||||||
if (!name) {
|
|
||||||
// TODO: fontDescriptor is not available, fallback to default font
|
|
||||||
name = 'sans-serif';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.current.font = fontObj;
|
this.current.font = fontObj;
|
||||||
this.current.fontSize = size;
|
this.current.fontSize = size;
|
||||||
|
|
||||||
|
var name = fontObj.loadedName || 'sans-serif';
|
||||||
if (this.ctx.$setFont) {
|
if (this.ctx.$setFont) {
|
||||||
this.ctx.$setFont(name, size);
|
this.ctx.$setFont(name, size);
|
||||||
} else {
|
} else {
|
||||||
FontMeasure.setActive(fontObj, size);
|
|
||||||
|
|
||||||
size = (size <= kRasterizerMin) ? size * kScalePrecision : size;
|
|
||||||
|
|
||||||
var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') :
|
var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') :
|
||||||
(fontObj.bold ? 'bold' : 'normal');
|
(fontObj.bold ? 'bold' : 'normal');
|
||||||
|
|
||||||
@ -4944,42 +4933,40 @@ var CanvasGraphics = (function() {
|
|||||||
|
|
||||||
ctx.translate(current.x, -1 * current.y);
|
ctx.translate(current.x, -1 * current.y);
|
||||||
|
|
||||||
var scaleFactorX = 1, scaleFactorY = 1;
|
|
||||||
var font = current.font;
|
var font = current.font;
|
||||||
if (font) {
|
if (font) {
|
||||||
if (current.fontSize <= kRasterizerMin) {
|
|
||||||
scaleFactorX = scaleFactorY = kScalePrecision;
|
|
||||||
ctx.scale(1 / scaleFactorX, 1 / scaleFactorY);
|
|
||||||
}
|
|
||||||
ctx.transform.apply(ctx, font.textMatrix || IDENTITY_MATRIX);
|
ctx.transform.apply(ctx, font.textMatrix || IDENTITY_MATRIX);
|
||||||
text = font.charsToUnicode(text);
|
text = font.charsToUnicode(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
var size = current.fontSize;
|
var composite = font.composite;
|
||||||
|
var encoding = font.encoding;
|
||||||
|
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;
|
||||||
|
ctx.scale(1 / textHScale, 1);
|
||||||
|
|
||||||
if (charSpacing != 0 || wordSpacing != 0 || textHScale != 1) {
|
var width = 0;
|
||||||
scaleFactorX *= textHScale;
|
for (var i = 0; i < text.length; i++) {
|
||||||
ctx.scale(1 / textHScale, 1);
|
if (composite) {
|
||||||
var width = 0;
|
var position = i * 2 + 1;
|
||||||
|
var charcode = (originalText.charCodeAt(position - 1) << 8) +
|
||||||
for (var i = 0, ii = text.length; i < ii; ++i) {
|
originalText.charCodeAt(position);
|
||||||
ctx.fillText(text.charAt(i), 0, 0);
|
} else {
|
||||||
var c = originalText.charAt(i);
|
var charcode = originalText.charCodeAt(i);
|
||||||
var charWidth = FontMeasure.measureText(c, font, size);
|
|
||||||
charWidth += charSpacing;
|
|
||||||
if (c.charCodeAt(0) == 32)
|
|
||||||
charWidth += wordSpacing;
|
|
||||||
ctx.translate(charWidth * scaleFactorX, 0);
|
|
||||||
width += charWidth;
|
|
||||||
}
|
}
|
||||||
current.x += width;
|
|
||||||
} else {
|
var charWidth = font.encoding[charcode].width * fontSize * 0.001;
|
||||||
ctx.fillText(text, 0, 0);
|
charWidth += charSpacing;
|
||||||
current.x += FontMeasure.measureText(originalText, font, size);
|
if (charcode == 32)
|
||||||
|
charWidth += wordSpacing;
|
||||||
|
|
||||||
|
ctx.fillText(text.charAt(i), 0, 0);
|
||||||
|
ctx.translate(charWidth, 0);
|
||||||
|
width += charWidth;
|
||||||
}
|
}
|
||||||
|
current.x += width;
|
||||||
|
|
||||||
this.ctx.restore();
|
this.ctx.restore();
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user