Support the vertical writing mode with SVG backend.
This commit is contained in:
parent
c218e94f66
commit
32f9cabf82
@ -744,6 +744,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
current.y = current.lineY = 0;
|
||||
|
||||
current.xcoords = [];
|
||||
current.ycoords = [];
|
||||
current.tspan = this.svgFactory.createElement("svg:tspan");
|
||||
current.tspan.setAttributeNS(null, "font-family", current.fontFamily);
|
||||
current.tspan.setAttributeNS(
|
||||
@ -768,6 +769,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
current.txtElement = this.svgFactory.createElement("svg:text");
|
||||
current.txtgrp = this.svgFactory.createElement("svg:g");
|
||||
current.xcoords = [];
|
||||
current.ycoords = [];
|
||||
}
|
||||
|
||||
moveText(x, y) {
|
||||
@ -776,6 +778,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
current.y = current.lineY += y;
|
||||
|
||||
current.xcoords = [];
|
||||
current.ycoords = [];
|
||||
current.tspan = this.svgFactory.createElement("svg:tspan");
|
||||
current.tspan.setAttributeNS(null, "font-family", current.fontFamily);
|
||||
current.tspan.setAttributeNS(
|
||||
@ -794,11 +797,14 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fontSizeScale = current.fontSizeScale;
|
||||
const charSpacing = current.charSpacing;
|
||||
const wordSpacing = current.wordSpacing;
|
||||
const fontDirection = current.fontDirection;
|
||||
const textHScale = current.textHScale * fontDirection;
|
||||
const vertical = font.vertical;
|
||||
const spacingDir = vertical ? 1 : -1;
|
||||
const defaultVMetrics = font.defaultVMetrics;
|
||||
const widthAdvanceScale = fontSize * current.fontMatrix[0];
|
||||
|
||||
let x = 0;
|
||||
@ -808,39 +814,72 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
x += fontDirection * wordSpacing;
|
||||
continue;
|
||||
} else if (isNum(glyph)) {
|
||||
x += -glyph * fontSize * 0.001;
|
||||
x += (spacingDir * glyph * fontSize) / 1000;
|
||||
continue;
|
||||
}
|
||||
|
||||
const width = glyph.width;
|
||||
const character = glyph.fontChar;
|
||||
const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;
|
||||
const charWidth = width * widthAdvanceScale + spacing * fontDirection;
|
||||
const character = glyph.fontChar;
|
||||
let scaledX, scaledY;
|
||||
let width = glyph.width;
|
||||
if (vertical) {
|
||||
let vx;
|
||||
const vmetric = glyph.vmetric || defaultVMetrics;
|
||||
vx = glyph.vmetric ? vmetric[1] : width * 0.5;
|
||||
vx = -vx * widthAdvanceScale;
|
||||
const vy = vmetric[2] * widthAdvanceScale;
|
||||
|
||||
if (!glyph.isInFont && !font.missingFile) {
|
||||
x += charWidth;
|
||||
width = vmetric ? -vmetric[0] : width;
|
||||
scaledX = vx / fontSizeScale;
|
||||
scaledY = (x + vy) / fontSizeScale;
|
||||
} else {
|
||||
scaledX = x / fontSizeScale;
|
||||
scaledY = 0;
|
||||
}
|
||||
|
||||
if (glyph.isInFont || font.missingFile) {
|
||||
current.xcoords.push(current.x + scaledX);
|
||||
if (vertical) {
|
||||
current.ycoords.push(-current.y + scaledY);
|
||||
}
|
||||
current.tspan.textContent += character;
|
||||
} else {
|
||||
// TODO: To assist with text selection, we should replace the missing
|
||||
// character with a space character if charWidth is not zero.
|
||||
// But we cannot just do "character = ' '", because the ' ' character
|
||||
// might actually map to a different glyph.
|
||||
continue;
|
||||
}
|
||||
current.xcoords.push(current.x + x);
|
||||
current.tspan.textContent += character;
|
||||
|
||||
let charWidth;
|
||||
if (vertical) {
|
||||
charWidth = width * widthAdvanceScale - spacing * fontDirection;
|
||||
} else {
|
||||
charWidth = width * widthAdvanceScale + spacing * fontDirection;
|
||||
}
|
||||
|
||||
x += charWidth;
|
||||
}
|
||||
if (vertical) {
|
||||
current.y -= x * textHScale;
|
||||
} else {
|
||||
current.x += x * textHScale;
|
||||
}
|
||||
|
||||
current.tspan.setAttributeNS(
|
||||
null,
|
||||
"x",
|
||||
current.xcoords.map(pf).join(" ")
|
||||
);
|
||||
current.tspan.setAttributeNS(null, "y", pf(-current.y));
|
||||
if (vertical) {
|
||||
current.tspan.setAttributeNS(
|
||||
null,
|
||||
"y",
|
||||
current.ycoords.map(pf).join(" ")
|
||||
);
|
||||
} else {
|
||||
current.tspan.setAttributeNS(null, "y", pf(-current.y));
|
||||
}
|
||||
|
||||
if (vertical) {
|
||||
current.y -= x;
|
||||
} else {
|
||||
current.x += x * textHScale;
|
||||
}
|
||||
|
||||
current.tspan.setAttributeNS(null, "font-family", current.fontFamily);
|
||||
current.tspan.setAttributeNS(
|
||||
null,
|
||||
@ -966,6 +1005,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
current.tspan = this.svgFactory.createElement("svg:tspan");
|
||||
current.tspan.setAttributeNS(null, "y", pf(-current.y));
|
||||
current.xcoords = [];
|
||||
current.ycoords = [];
|
||||
}
|
||||
|
||||
endText() {
|
||||
@ -1017,6 +1057,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
this.current.fillColor = Util.makeCssRgb(r, g, b);
|
||||
this.current.tspan = this.svgFactory.createElement("svg:tspan");
|
||||
this.current.xcoords = [];
|
||||
this.current.ycoords = [];
|
||||
}
|
||||
|
||||
setStrokeColorN(args) {
|
||||
|
Loading…
Reference in New Issue
Block a user