Refactors fake space heuristics for speed.
This commit is contained in:
parent
376f8bde14
commit
fa423cfab0
@ -929,11 +929,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
lastAdvanceWidth: 0,
|
lastAdvanceWidth: 0,
|
||||||
lastAdvanceHeight: 0,
|
lastAdvanceHeight: 0,
|
||||||
textAdvanceScale: 0,
|
textAdvanceScale: 0,
|
||||||
|
spaceWidth: 0,
|
||||||
|
fakeSpaceMin: Infinity,
|
||||||
|
fakeMultiSpaceMin: Infinity,
|
||||||
|
fakeMultiSpaceMax: -0,
|
||||||
|
textRunBreakAllowed: false,
|
||||||
transform: null,
|
transform: null,
|
||||||
fontName: null
|
fontName: null
|
||||||
};
|
};
|
||||||
var SPACE_FACTOR = 0.3;
|
var SPACE_FACTOR = 0.3;
|
||||||
var MULTI_SPACE_FACTOR = 1.5;
|
var MULTI_SPACE_FACTOR = 1.5;
|
||||||
|
var MULTI_SPACE_FACTOR_MAX = 4;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var xref = this.xref;
|
var xref = this.xref;
|
||||||
@ -1001,6 +1007,24 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
textContentItem.lastAdvanceWidth = 0;
|
textContentItem.lastAdvanceWidth = 0;
|
||||||
textContentItem.lastAdvanceHeight = 0;
|
textContentItem.lastAdvanceHeight = 0;
|
||||||
|
|
||||||
|
var spaceWidth = font.spaceWidth / 1000 * textState.fontSize;
|
||||||
|
if (spaceWidth) {
|
||||||
|
textContentItem.spaceWidth = spaceWidth;
|
||||||
|
textContentItem.fakeSpaceMin = spaceWidth * SPACE_FACTOR;
|
||||||
|
textContentItem.fakeMultiSpaceMin = spaceWidth * MULTI_SPACE_FACTOR;
|
||||||
|
textContentItem.fakeMultiSpaceMax =
|
||||||
|
spaceWidth * MULTI_SPACE_FACTOR_MAX;
|
||||||
|
// It's okay for monospace fonts to fake as much space as needed.
|
||||||
|
textContentItem.textRunBreakAllowed = !font.isMonospace;
|
||||||
|
} else {
|
||||||
|
textContentItem.spaceWidth = 0;
|
||||||
|
textContentItem.fakeSpaceMin = Infinity;
|
||||||
|
textContentItem.fakeMultiSpaceMin = Infinity;
|
||||||
|
textContentItem.fakeMultiSpaceMax = 0;
|
||||||
|
textContentItem.textRunBreakAllowed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
textContentItem.initialized = true;
|
textContentItem.initialized = true;
|
||||||
return textContentItem;
|
return textContentItem;
|
||||||
}
|
}
|
||||||
@ -1076,8 +1100,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var wordSpacing = textState.wordSpacing;
|
var wordSpacing = textState.wordSpacing;
|
||||||
charSpacing += wordSpacing;
|
charSpacing += wordSpacing;
|
||||||
if (wordSpacing > 0) {
|
if (wordSpacing > 0) {
|
||||||
addFakeSpaces(wordSpacing * 1000 / textState.fontSize,
|
addFakeSpaces(wordSpacing, textChunk.str);
|
||||||
textChunk.str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1105,21 +1128,20 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
textChunk.lastAdvanceHeight = height;
|
textChunk.lastAdvanceHeight = height;
|
||||||
textChunk.height += Math.abs(height * textChunk.textAdvanceScale);
|
textChunk.height += Math.abs(height * textChunk.textAdvanceScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
return textChunk;
|
return textChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addFakeSpaces(width, strBuf) {
|
function addFakeSpaces(width, strBuf) {
|
||||||
var spaceWidth = textState.font.spaceWidth;
|
if (width < textContentItem.fakeSpaceMin) {
|
||||||
if (spaceWidth <= 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var fakeSpaces = width / spaceWidth;
|
if (width < textContentItem.fakeMultiSpaceMin) {
|
||||||
if (fakeSpaces > MULTI_SPACE_FACTOR) {
|
strBuf.push(' ');
|
||||||
fakeSpaces = Math.round(fakeSpaces);
|
return;
|
||||||
while (fakeSpaces--) {
|
}
|
||||||
strBuf.push(' ');
|
var fakeSpaces = Math.round(width / textContentItem.spaceWidth);
|
||||||
}
|
while (fakeSpaces-- > 0) {
|
||||||
} else if (fakeSpaces > SPACE_FACTOR) {
|
|
||||||
strBuf.push(' ');
|
strBuf.push(' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1177,16 +1199,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
// Optimization to treat same line movement as advance
|
// Optimization to treat same line movement as advance
|
||||||
var isSameTextLine = !textState.font ? false :
|
var isSameTextLine = !textState.font ? false :
|
||||||
((textState.font.vertical ? args[0] : args[1]) === 0);
|
((textState.font.vertical ? args[0] : args[1]) === 0);
|
||||||
if (isSameTextLine && textContentItem.initialized) {
|
advance = args[0] - args[1];
|
||||||
|
if (isSameTextLine && textContentItem.initialized &&
|
||||||
|
advance > 0 &&
|
||||||
|
advance <= textContentItem.fakeMultiSpaceMax) {
|
||||||
textState.translateTextLineMatrix(args[0], args[1]);
|
textState.translateTextLineMatrix(args[0], args[1]);
|
||||||
textContentItem.width +=
|
textContentItem.width +=
|
||||||
(args[0] - textContentItem.lastAdvanceWidth);
|
(args[0] - textContentItem.lastAdvanceWidth);
|
||||||
textContentItem.height +=
|
textContentItem.height +=
|
||||||
(args[1] - textContentItem.lastAdvanceHeight);
|
(args[1] - textContentItem.lastAdvanceHeight);
|
||||||
advance = (args[0] - args[1]) * 1000 / textState.fontSize;
|
var diff = (args[0] - textContentItem.lastAdvanceWidth) -
|
||||||
if (advance > 0) {
|
(args[1] - textContentItem.lastAdvanceHeight);
|
||||||
addFakeSpaces(advance, textContentItem.str);
|
addFakeSpaces(diff, textContentItem.str);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1229,9 +1253,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
if (typeof items[j] === 'string') {
|
if (typeof items[j] === 'string') {
|
||||||
buildTextContentItem(items[j]);
|
buildTextContentItem(items[j]);
|
||||||
} else {
|
} else {
|
||||||
if (j === 0) {
|
ensureTextContentItem();
|
||||||
ensureTextContentItem();
|
|
||||||
}
|
|
||||||
// PDF Specification 5.3.2 states:
|
// PDF Specification 5.3.2 states:
|
||||||
// The number is expressed in thousandths of a unit of text
|
// The number is expressed in thousandths of a unit of text
|
||||||
// space.
|
// space.
|
||||||
@ -1240,25 +1263,35 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
// In the default coordinate system, a positive adjustment
|
// In the default coordinate system, a positive adjustment
|
||||||
// has the effect of moving the next glyph painted either to
|
// has the effect of moving the next glyph painted either to
|
||||||
// the left or down by the given amount.
|
// the left or down by the given amount.
|
||||||
advance = items[j];
|
advance = items[j] * textState.fontSize / 1000;
|
||||||
var val = advance * textState.fontSize / 1000;
|
var breakTextRun = false;
|
||||||
if (textState.font.vertical) {
|
if (textState.font.vertical) {
|
||||||
offset = val *
|
offset = advance *
|
||||||
(textState.textHScale * textState.textMatrix[2] +
|
(textState.textHScale * textState.textMatrix[2] +
|
||||||
textState.textMatrix[3]);
|
textState.textMatrix[3]);
|
||||||
textState.translateTextMatrix(0, val);
|
textState.translateTextMatrix(0, advance);
|
||||||
// Value needs to be added to height to paint down.
|
breakTextRun = textContentItem.textRunBreakAllowed &&
|
||||||
textContentItem.height += offset;
|
advance > textContentItem.fakeMultiSpaceMax;
|
||||||
|
if (!breakTextRun) {
|
||||||
|
// Value needs to be added to height to paint down.
|
||||||
|
textContentItem.height += offset;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
offset = val * (
|
advance = -advance;
|
||||||
|
offset = advance * (
|
||||||
textState.textHScale * textState.textMatrix[0] +
|
textState.textHScale * textState.textMatrix[0] +
|
||||||
textState.textMatrix[1]);
|
textState.textMatrix[1]);
|
||||||
textState.translateTextMatrix(-val, 0);
|
textState.translateTextMatrix(advance, 0);
|
||||||
// Value needs to be subtracted from width to paint left.
|
breakTextRun = textContentItem.textRunBreakAllowed &&
|
||||||
textContentItem.width -= offset;
|
advance > textContentItem.fakeMultiSpaceMax;
|
||||||
advance = -advance;
|
if (!breakTextRun) {
|
||||||
|
// Value needs to be subtracted from width to paint left.
|
||||||
|
textContentItem.width += offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (advance > 0) {
|
if (breakTextRun) {
|
||||||
|
flushTextContentItem();
|
||||||
|
} else if (advance > 0) {
|
||||||
addFakeSpaces(advance, textContentItem.str);
|
addFakeSpaces(advance, textContentItem.str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user