1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-26 10:08:06 +02:00

Better spacing in text layer.

This commit is contained in:
Yury Delendik 2015-11-02 08:54:15 -06:00
parent bc33ae2fc4
commit fa46b73c47
3 changed files with 57 additions and 58 deletions

View file

@ -350,9 +350,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
for (var i = 0, ii = glyphs.length; i < ii; i++) {
var glyph = glyphs[i];
if (glyph === null) {
continue;
}
buildPath(glyph.fontChar);
// If the glyph has an accent we need to build a path for its
@ -1012,10 +1009,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var defaultVMetrics = font.defaultVMetrics;
for (var i = 0; i < glyphs.length; i++) {
var glyph = glyphs[i];
if (!glyph) { // Previous glyph was a space.
width += textState.wordSpacing * textState.textHScale;
continue;
}
var vMetricX = null;
var vMetricY = null;
var glyphWidth = null;
@ -1051,11 +1044,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
// var x = pt[0];
// var y = pt[1];
var charSpacing = 0;
if (textChunk.str.length > 0) {
// Apply char spacing only when there are chars.
// As a result there is only spacing between glyphs.
charSpacing = textState.charSpacing;
var charSpacing = textState.charSpacing;
if (glyph.isSpace) {
var wordSpacing = textState.wordSpacing;
charSpacing += wordSpacing;
if (wordSpacing > 0) {
addFakeSpaces(wordSpacing * 1000 / textState.fontSize,
textChunk.str);
}
}
var tx = 0;
@ -1089,6 +1085,22 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return textChunk;
}
function addFakeSpaces(width, strBuf) {
var spaceWidth = textState.font.spaceWidth;
if (spaceWidth <= 0) {
return;
}
var fakeSpaces = width / spaceWidth;
if (fakeSpaces > MULTI_SPACE_FACTOR) {
fakeSpaces = Math.round(fakeSpaces);
while (fakeSpaces--) {
strBuf.push(' ');
}
} else if (fakeSpaces > SPACE_FACTOR) {
strBuf.push(' ');
}
}
var timeSlotManager = new TimeSlotManager();
return new Promise(function next(resolve, reject) {
@ -1167,29 +1179,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
// In the default coordinate system, a positive adjustment
// has the effect of moving the next glyph painted either to
// the left or down by the given amount.
var val = items[j] * textState.fontSize / 1000;
var advance = items[j];
var val = advance * textState.fontSize / 1000;
if (textState.font.vertical) {
offset = val * textState.textMatrix[3];
textState.translateTextMatrix(0, offset);
offset = val *
(textState.textHScale * textState.textMatrix[2] +
textState.textMatrix[3]);
textState.translateTextMatrix(0, val);
// Value needs to be added to height to paint down.
textChunk.height += offset;
} else {
offset = val * textState.textHScale *
textState.textMatrix[0];
textState.translateTextMatrix(offset, 0);
offset = val * (
textState.textHScale * textState.textMatrix[0] +
textState.textMatrix[1]);
textState.translateTextMatrix(-val, 0);
// Value needs to be subtracted from width to paint left.
textChunk.width -= offset;
advance = -advance;
}
if (items[j] < 0 && textState.font.spaceWidth > 0) {
var fakeSpaces = -items[j] / textState.font.spaceWidth;
if (fakeSpaces > MULTI_SPACE_FACTOR) {
fakeSpaces = Math.round(fakeSpaces);
while (fakeSpaces--) {
textChunk.str.push(' ');
}
} else if (fakeSpaces > SPACE_FACTOR) {
textChunk.str.push(' ');
}
if (advance > 0) {
addFakeSpaces(advance, textChunk.str);
}
}
}

View file

@ -2170,23 +2170,26 @@ function getFontType(type, subtype) {
}
var Glyph = (function GlyphClosure() {
function Glyph(fontChar, unicode, accent, width, vmetric, operatorListId) {
function Glyph(fontChar, unicode, accent, width, vmetric, operatorListId,
isSpace) {
this.fontChar = fontChar;
this.unicode = unicode;
this.accent = accent;
this.width = width;
this.vmetric = vmetric;
this.operatorListId = operatorListId;
this.isSpace = isSpace;
}
Glyph.prototype.matchesForCache =
function(fontChar, unicode, accent, width, vmetric, operatorListId) {
Glyph.prototype.matchesForCache = function(fontChar, unicode, accent, width,
vmetric, operatorListId, isSpace) {
return this.fontChar === fontChar &&
this.unicode === unicode &&
this.accent === accent &&
this.width === width &&
this.vmetric === vmetric &&
this.operatorListId === operatorListId;
this.operatorListId === operatorListId &&
this.isSpace === isSpace;
};
return Glyph;
@ -4701,7 +4704,7 @@ var Font = (function FontClosure() {
return width;
},
charToGlyph: function Font_charToGlyph(charcode) {
charToGlyph: function Font_charToGlyph(charcode, isSpace) {
var fontCharCode, width, operatorListId;
var widthCode = charcode;
@ -4744,9 +4747,9 @@ var Font = (function FontClosure() {
var glyph = this.glyphCache[charcode];
if (!glyph ||
!glyph.matchesForCache(fontChar, unicode, accent, width, vmetric,
operatorListId)) {
operatorListId, isSpace)) {
glyph = new Glyph(fontChar, unicode, accent, width, vmetric,
operatorListId);
operatorListId, isSpace);
this.glyphCache[charcode] = glyph;
}
return glyph;
@ -4782,22 +4785,16 @@ var Font = (function FontClosure() {
charcode = c.charcode;
var length = c.length;
i += length;
glyph = this.charToGlyph(charcode);
// Space is char with code 0x20 and length 1 in multiple-byte codes.
var isSpace = length === 1 && chars.charCodeAt(i - 1) === 0x20;
glyph = this.charToGlyph(charcode, isSpace);
glyphs.push(glyph);
// placing null after each word break charcode (ASCII SPACE)
// Ignore occurences of 0x20 in multiple-byte codes.
if (length === 1 && chars.charCodeAt(i - 1) === 0x20) {
glyphs.push(null);
}
}
} else {
for (i = 0, ii = chars.length; i < ii; ++i) {
charcode = chars.charCodeAt(i);
glyph = this.charToGlyph(charcode);
glyph = this.charToGlyph(charcode, charcode === 0x20);
glyphs.push(glyph);
if (charcode === 0x20) {
glyphs.push(null);
}
}
}