Support the vertical writing mode with SVG backend.

This commit is contained in:
Takashi Tamura 2020-01-28 16:16:39 +09:00
parent c218e94f66
commit 32f9cabf82

View File

@ -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) {