Browse Source

Draw glyphs one by one to position them correctly and remove all the scaling hack

Vivien Nicolas 14 years ago
parent
commit
13bf137220
  1. 61
      fonts.js
  2. 55
      pdf.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({

55
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;
if (charSpacing != 0 || wordSpacing != 0 || textHScale != 1) {
scaleFactorX *= textHScale;
ctx.scale(1 / textHScale, 1); ctx.scale(1 / textHScale, 1);
var width = 0; var width = 0;
for (var i = 0; i < text.length; i++) {
if (composite) {
var position = i * 2 + 1;
var charcode = (originalText.charCodeAt(position - 1) << 8) +
originalText.charCodeAt(position);
} else {
var charcode = originalText.charCodeAt(i);
}
for (var i = 0, ii = text.length; i < ii; ++i) { var charWidth = font.encoding[charcode].width * fontSize * 0.001;
ctx.fillText(text.charAt(i), 0, 0);
var c = originalText.charAt(i);
var charWidth = FontMeasure.measureText(c, font, size);
charWidth += charSpacing; charWidth += charSpacing;
if (c.charCodeAt(0) == 32) if (charcode == 32)
charWidth += wordSpacing; charWidth += wordSpacing;
ctx.translate(charWidth * scaleFactorX, 0);
ctx.fillText(text.charAt(i), 0, 0);
ctx.translate(charWidth, 0);
width += charWidth; width += charWidth;
} }
current.x += width; current.x += width;
} else {
ctx.fillText(text, 0, 0);
current.x += FontMeasure.measureText(originalText, font, size);
}
this.ctx.restore(); this.ctx.restore();
}, },

Loading…
Cancel
Save