mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
Refactors showText: split type3, remove showSpacedText
This commit is contained in:
parent
d2da73b8c4
commit
d53dc2e7d6
3 changed files with 181 additions and 192 deletions
|
@ -676,18 +676,31 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||
break;
|
||||
case OPS.showSpacedText:
|
||||
var arr = args[0];
|
||||
var combinedGlyphs = [];
|
||||
var arrLength = arr.length;
|
||||
for (i = 0; i < arrLength; ++i) {
|
||||
if (isString(arr[i])) {
|
||||
arr[i] = self.handleText(arr[i], stateManager.state);
|
||||
var arrItem = arr[i];
|
||||
if (isString(arrItem)) {
|
||||
Array.prototype.push.apply(combinedGlyphs,
|
||||
self.handleText(arrItem, stateManager.state));
|
||||
} else if (isNum(arrItem)) {
|
||||
combinedGlyphs.push(arrItem);
|
||||
}
|
||||
}
|
||||
args[0] = combinedGlyphs;
|
||||
fn = OPS.showText;
|
||||
break;
|
||||
case OPS.nextLineShowText:
|
||||
operatorList.addOp(OPS.nextLine);
|
||||
args[0] = self.handleText(args[0], stateManager.state);
|
||||
fn = OPS.showText;
|
||||
break;
|
||||
case OPS.nextLineSetSpacingShowText:
|
||||
args[2] = self.handleText(args[2], stateManager.state);
|
||||
operatorList.addOp(OPS.nextLine);
|
||||
operatorList.addOp(OPS.setWordSpacing, [args.shift()]);
|
||||
operatorList.addOp(OPS.setCharSpacing, [args.shift()]);
|
||||
args[0] = self.handleText(args[0], stateManager.state);
|
||||
fn = OPS.showText;
|
||||
break;
|
||||
case OPS.setTextRenderingMode:
|
||||
stateManager.state.textRenderingMode = args[0];
|
||||
|
|
|
@ -352,6 +352,7 @@ var CanvasExtraState = (function CanvasExtraStateClosure() {
|
|||
this.fontSize = 0;
|
||||
this.fontSizeScale = 1;
|
||||
this.textMatrix = IDENTITY_MATRIX;
|
||||
this.textMatrixScale = 1;
|
||||
this.fontMatrix = FONT_IDENTITY_MATRIX;
|
||||
this.leading = 0;
|
||||
// Current point (in user coordinates)
|
||||
|
@ -1129,6 +1130,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
// Text
|
||||
beginText: function CanvasGraphics_beginText() {
|
||||
this.current.textMatrix = IDENTITY_MATRIX;
|
||||
this.current.textMatrixScale = 1;
|
||||
this.current.x = this.current.lineX = 0;
|
||||
this.current.y = this.current.lineY = 0;
|
||||
},
|
||||
|
@ -1233,6 +1235,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
},
|
||||
setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) {
|
||||
this.current.textMatrix = [a, b, c, d, e, f];
|
||||
this.current.textMatrixScale = Math.sqrt(a * a + b * b);
|
||||
|
||||
this.current.x = this.current.lineX = 0;
|
||||
this.current.y = this.current.lineY = 0;
|
||||
|
@ -1240,24 +1243,13 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
nextLine: function CanvasGraphics_nextLine() {
|
||||
this.moveText(0, this.current.leading);
|
||||
},
|
||||
applyTextTransforms: function CanvasGraphics_applyTextTransforms() {
|
||||
var ctx = this.ctx;
|
||||
var current = this.current;
|
||||
ctx.transform.apply(ctx, current.textMatrix);
|
||||
ctx.translate(current.x, current.y + current.textRise);
|
||||
if (current.fontDirection > 0) {
|
||||
ctx.scale(current.textHScale, -1);
|
||||
} else {
|
||||
ctx.scale(-current.textHScale, 1);
|
||||
}
|
||||
},
|
||||
|
||||
paintChar: function CanvasGraphics_paintChar(character, x, y) {
|
||||
var ctx = this.ctx;
|
||||
var current = this.current;
|
||||
var font = current.font;
|
||||
var fontSize = current.fontSize / current.fontSizeScale;
|
||||
var textRenderingMode = current.textRenderingMode;
|
||||
var fontSize = current.fontSize / current.fontSizeScale;
|
||||
var fillStrokeMode = textRenderingMode &
|
||||
TextRenderingMode.FILL_STROKE_MASK;
|
||||
var isAddToPathSet = !!(textRenderingMode &
|
||||
|
@ -1323,181 +1315,182 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
},
|
||||
|
||||
showText: function CanvasGraphics_showText(glyphs) {
|
||||
var ctx = this.ctx;
|
||||
var current = this.current;
|
||||
var font = current.font;
|
||||
var fontSize = current.fontSize;
|
||||
var fontSizeScale = current.fontSizeScale;
|
||||
var charSpacing = current.charSpacing;
|
||||
var wordSpacing = current.wordSpacing;
|
||||
var textHScale = current.textHScale * current.fontDirection;
|
||||
var fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX;
|
||||
var glyphsLength = glyphs.length;
|
||||
var vertical = font.vertical;
|
||||
var defaultVMetrics = font.defaultVMetrics;
|
||||
var i, glyph, width;
|
||||
if (font.isType3Font) {
|
||||
return this.showType3Text(glyphs);
|
||||
}
|
||||
|
||||
var fontSize = current.fontSize;
|
||||
if (fontSize === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Type3 fonts - each glyph is a "mini-PDF"
|
||||
if (font.isType3Font) {
|
||||
ctx.save();
|
||||
ctx.transform.apply(ctx, current.textMatrix);
|
||||
ctx.translate(current.x, current.y);
|
||||
var ctx = this.ctx;
|
||||
var fontSizeScale = current.fontSizeScale;
|
||||
var charSpacing = current.charSpacing;
|
||||
var wordSpacing = current.wordSpacing;
|
||||
var fontDirection = current.fontDirection;
|
||||
var textHScale = current.textHScale * fontDirection;
|
||||
var glyphsLength = glyphs.length;
|
||||
var vertical = font.vertical;
|
||||
var defaultVMetrics = font.defaultVMetrics;
|
||||
var widthAdvanceScale = fontSize * current.fontMatrix[0];
|
||||
|
||||
ctx.scale(textHScale, 1);
|
||||
var simpleFillText =
|
||||
current.textRenderingMode === TextRenderingMode.FILL &&
|
||||
!font.disableFontFace;
|
||||
|
||||
for (i = 0; i < glyphsLength; ++i) {
|
||||
glyph = glyphs[i];
|
||||
if (glyph === null) {
|
||||
// word break
|
||||
this.ctx.translate(wordSpacing, 0);
|
||||
current.x += wordSpacing * textHScale;
|
||||
continue;
|
||||
}
|
||||
ctx.save();
|
||||
ctx.transform.apply(ctx, current.textMatrix);
|
||||
ctx.translate(current.x, current.y + current.textRise);
|
||||
|
||||
this.processingType3 = glyph;
|
||||
this.save();
|
||||
ctx.scale(fontSize, fontSize);
|
||||
ctx.transform.apply(ctx, fontMatrix);
|
||||
var operatorList = font.charProcOperatorList[glyph.operatorListId];
|
||||
this.executeOperatorList(operatorList);
|
||||
this.restore();
|
||||
|
||||
var transformed = Util.applyTransform([glyph.width, 0], fontMatrix);
|
||||
width = ((transformed[0] * fontSize + charSpacing) *
|
||||
current.fontDirection);
|
||||
|
||||
ctx.translate(width, 0);
|
||||
current.x += width * textHScale;
|
||||
}
|
||||
ctx.restore();
|
||||
this.processingType3 = null;
|
||||
if (fontDirection > 0) {
|
||||
ctx.scale(textHScale, -1);
|
||||
} else {
|
||||
ctx.save();
|
||||
this.applyTextTransforms();
|
||||
ctx.scale(textHScale, 1);
|
||||
}
|
||||
|
||||
var lineWidth = current.lineWidth;
|
||||
var a1 = current.textMatrix[0], b1 = current.textMatrix[1];
|
||||
var scale = Math.sqrt(a1 * a1 + b1 * b1);
|
||||
if (scale === 0 || lineWidth === 0) {
|
||||
lineWidth = this.getSinglePixelWidth();
|
||||
var lineWidth = current.lineWidth;
|
||||
var scale = current.textMatrixScale;
|
||||
if (scale === 0 || lineWidth === 0) {
|
||||
lineWidth = this.getSinglePixelWidth();
|
||||
} else {
|
||||
lineWidth /= scale;
|
||||
}
|
||||
|
||||
if (fontSizeScale != 1.0) {
|
||||
ctx.scale(fontSizeScale, fontSizeScale);
|
||||
lineWidth /= fontSizeScale;
|
||||
}
|
||||
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
||||
var x = 0, i;
|
||||
for (i = 0; i < glyphsLength; ++i) {
|
||||
var glyph = glyphs[i];
|
||||
if (glyph === null) {
|
||||
// word break
|
||||
x += fontDirection * wordSpacing;
|
||||
continue;
|
||||
} else if (isNum(glyph)) {
|
||||
x += -glyph * fontSize * 0.001;
|
||||
continue;
|
||||
}
|
||||
|
||||
var restoreNeeded = false;
|
||||
var character = glyph.fontChar;
|
||||
var accent = glyph.accent;
|
||||
var scaledX, scaledY, scaledAccentX, scaledAccentY;
|
||||
var width = glyph.width;
|
||||
if (vertical) {
|
||||
var vmetric, vx, vy;
|
||||
vmetric = glyph.vmetric || defaultVMetrics;
|
||||
vx = glyph.vmetric ? vmetric[1] : width * 0.5;
|
||||
vx = -vx * widthAdvanceScale;
|
||||
vy = vmetric[2] * widthAdvanceScale;
|
||||
|
||||
width = vmetric ? -vmetric[0] : width;
|
||||
scaledX = vx / fontSizeScale;
|
||||
scaledY = (x + vy) / fontSizeScale;
|
||||
} else {
|
||||
lineWidth /= scale;
|
||||
scaledX = x / fontSizeScale;
|
||||
scaledY = 0;
|
||||
}
|
||||
|
||||
if (fontSizeScale != 1.0) {
|
||||
ctx.scale(fontSizeScale, fontSizeScale);
|
||||
lineWidth /= fontSizeScale;
|
||||
if (font.remeasure && width > 0 && this.isFontSubpixelAAEnabled) {
|
||||
// some standard fonts may not have the exact width, trying to
|
||||
// rescale per character
|
||||
var measuredWidth = ctx.measureText(character).width * 1000 /
|
||||
fontSize * fontSizeScale;
|
||||
var characterScaleX = width / measuredWidth;
|
||||
restoreNeeded = true;
|
||||
ctx.save();
|
||||
ctx.scale(characterScaleX, 1);
|
||||
scaledX /= characterScaleX;
|
||||
}
|
||||
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
||||
var x = 0;
|
||||
for (i = 0; i < glyphsLength; ++i) {
|
||||
glyph = glyphs[i];
|
||||
if (glyph === null) {
|
||||
// word break
|
||||
x += current.fontDirection * wordSpacing;
|
||||
continue;
|
||||
}
|
||||
|
||||
var restoreNeeded = false;
|
||||
var character = glyph.fontChar;
|
||||
var vmetric = glyph.vmetric || defaultVMetrics;
|
||||
if (vertical) {
|
||||
var vx = glyph.vmetric ? vmetric[1] : glyph.width * 0.5;
|
||||
vx = -vx * fontSize * current.fontMatrix[0];
|
||||
var vy = vmetric[2] * fontSize * current.fontMatrix[0];
|
||||
}
|
||||
width = vmetric ? -vmetric[0] : glyph.width;
|
||||
var charWidth = width * fontSize * current.fontMatrix[0] +
|
||||
charSpacing * current.fontDirection;
|
||||
var accent = glyph.accent;
|
||||
|
||||
var scaledX, scaledY, scaledAccentX, scaledAccentY;
|
||||
|
||||
if (vertical) {
|
||||
scaledX = vx / fontSizeScale;
|
||||
scaledY = (x + vy) / fontSizeScale;
|
||||
} else {
|
||||
scaledX = x / fontSizeScale;
|
||||
scaledY = 0;
|
||||
}
|
||||
|
||||
if (font.remeasure && width > 0 && this.isFontSubpixelAAEnabled) {
|
||||
// some standard fonts may not have the exact width, trying to
|
||||
// rescale per character
|
||||
var measuredWidth = ctx.measureText(character).width * 1000 /
|
||||
current.fontSize * current.fontSizeScale;
|
||||
var characterScaleX = width / measuredWidth;
|
||||
restoreNeeded = true;
|
||||
ctx.save();
|
||||
ctx.scale(characterScaleX, 1);
|
||||
scaledX /= characterScaleX;
|
||||
if (accent) {
|
||||
scaledAccentX /= characterScaleX;
|
||||
}
|
||||
}
|
||||
|
||||
if (simpleFillText && !accent) {
|
||||
// common case
|
||||
ctx.fillText(character, scaledX, scaledY);
|
||||
} else {
|
||||
this.paintChar(character, scaledX, scaledY);
|
||||
if (accent) {
|
||||
scaledAccentX = scaledX + accent.offset.x / fontSizeScale;
|
||||
scaledAccentY = scaledY - accent.offset.y / fontSizeScale;
|
||||
this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY);
|
||||
}
|
||||
|
||||
x += charWidth;
|
||||
|
||||
if (restoreNeeded) {
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
if (vertical) {
|
||||
current.y -= x * textHScale;
|
||||
} else {
|
||||
current.x += x * textHScale;
|
||||
|
||||
var charWidth = width * widthAdvanceScale + charSpacing * fontDirection;
|
||||
x += charWidth;
|
||||
|
||||
if (restoreNeeded) {
|
||||
ctx.restore();
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
if (vertical) {
|
||||
current.y -= x * textHScale;
|
||||
} else {
|
||||
current.x += x * textHScale;
|
||||
}
|
||||
ctx.restore();
|
||||
},
|
||||
showSpacedText: function CanvasGraphics_showSpacedText(arr) {
|
||||
|
||||
showType3Text: function CanvasGraphics_showType3Text(glyphs) {
|
||||
// Type3 fonts - each glyph is a "mini-PDF"
|
||||
var ctx = this.ctx;
|
||||
var current = this.current;
|
||||
var font = current.font;
|
||||
var fontSize = current.fontSize;
|
||||
// TJ array's number is independent from fontMatrix
|
||||
var textHScale = current.textHScale * 0.001 * current.fontDirection;
|
||||
var arrLength = arr.length;
|
||||
var vertical = font.vertical;
|
||||
var fontDirection = current.fontDirection;
|
||||
var charSpacing = current.charSpacing;
|
||||
var wordSpacing = current.wordSpacing;
|
||||
var textHScale = current.textHScale * fontDirection;
|
||||
var fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX;
|
||||
var glyphsLength = glyphs.length;
|
||||
var i, glyph, width;
|
||||
|
||||
for (var i = 0; i < arrLength; ++i) {
|
||||
var e = arr[i];
|
||||
if (isNum(e)) {
|
||||
var spacingLength = -e * fontSize * textHScale;
|
||||
if (vertical) {
|
||||
current.y += spacingLength;
|
||||
} else {
|
||||
current.x += spacingLength;
|
||||
}
|
||||
|
||||
} else {
|
||||
this.showText(e);
|
||||
}
|
||||
if (fontSize === 0) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
nextLineShowText: function CanvasGraphics_nextLineShowText(text) {
|
||||
this.nextLine();
|
||||
this.showText(text);
|
||||
},
|
||||
nextLineSetSpacingShowText:
|
||||
function CanvasGraphics_nextLineSetSpacingShowText(wordSpacing,
|
||||
charSpacing,
|
||||
text) {
|
||||
this.setWordSpacing(wordSpacing);
|
||||
this.setCharSpacing(charSpacing);
|
||||
this.nextLineShowText(text);
|
||||
|
||||
ctx.save();
|
||||
ctx.transform.apply(ctx, current.textMatrix);
|
||||
ctx.translate(current.x, current.y);
|
||||
|
||||
ctx.scale(textHScale, 1);
|
||||
|
||||
for (i = 0; i < glyphsLength; ++i) {
|
||||
glyph = glyphs[i];
|
||||
if (glyph === null) {
|
||||
// word break
|
||||
this.ctx.translate(wordSpacing, 0);
|
||||
current.x += wordSpacing * textHScale;
|
||||
continue;
|
||||
} else if (isNum(glyph)) {
|
||||
var spacingLength = -glyph * 0.001 * fontSize;
|
||||
this.ctx.translate(spacingLength, 0);
|
||||
current.x += spacingLength * textHScale;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.processingType3 = glyph;
|
||||
this.save();
|
||||
ctx.scale(fontSize, fontSize);
|
||||
ctx.transform.apply(ctx, fontMatrix);
|
||||
var operatorList = font.charProcOperatorList[glyph.operatorListId];
|
||||
this.executeOperatorList(operatorList);
|
||||
this.restore();
|
||||
|
||||
var transformed = Util.applyTransform([glyph.width, 0], fontMatrix);
|
||||
width = ((transformed[0] * fontSize + charSpacing) * fontDirection);
|
||||
|
||||
ctx.translate(width, 0);
|
||||
current.x += width * textHScale;
|
||||
}
|
||||
ctx.restore();
|
||||
this.processingType3 = null;
|
||||
},
|
||||
|
||||
// Type3 fonts
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue