1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-22 16:18:08 +02:00

Merge pull request #2686 from vyv03354/bug770409

Implement vertical writing
This commit is contained in:
Brendan Dahl 2013-02-25 12:47:47 -08:00
commit a13f7964b1
9 changed files with 112 additions and 29 deletions

View file

@ -139,16 +139,16 @@ var bidi = PDFJS.bidi = (function bidiClosure() {
}
}
function BidiResult(str, isLTR) {
function BidiResult(str, isLTR, vertical) {
this.str = str;
this.ltr = isLTR;
this.dir = vertical ? 'ttb' : isLTR ? 'ltr' : 'rtl';
}
function bidi(str, startLevel) {
function bidi(str, startLevel, vertical) {
var isLTR = true;
var strLength = str.length;
if (strLength === 0)
return new BidiResult(str, isLTR);
if (strLength === 0 || vertical)
return new BidiResult(str, isLTR, vertical);
// get types, fill arrays

View file

@ -896,6 +896,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var textSelection = textLayer && !skipTextSelection ? true : false;
var textRenderingMode = current.textRenderingMode;
var canvasWidth = 0.0;
var vertical = font.vertical;
var defaultVMetrics = font.defaultVMetrics;
// Type3 fonts - each glyph is a "mini-PDF"
if (font.coded) {
@ -969,25 +971,37 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
}
var character = glyph.fontChar;
var charWidth = glyph.width * fontSize * current.fontMatrix[0] +
var vmetric = glyph.vmetric || defaultVMetrics;
if (vertical) {
var vx = vmetric[1] * fontSize * current.fontMatrix[0];
var vy = vmetric[2] * fontSize * current.fontMatrix[0];
}
var width = vmetric ? -vmetric[0] : glyph.width;
var charWidth = width * fontSize * current.fontMatrix[0] +
charSpacing * current.fontDirection;
if (!glyph.disabled) {
var scaledX = x / fontSizeScale;
if (vertical) {
var scaledX = vx / fontSizeScale;
var scaledY = (x + vy) / fontSizeScale;
} else {
var scaledX = x / fontSizeScale;
var scaledY = 0;
}
switch (textRenderingMode) {
default: // other unsupported rendering modes
case TextRenderingMode.FILL:
case TextRenderingMode.FILL_ADD_TO_PATH:
ctx.fillText(character, scaledX, 0);
ctx.fillText(character, scaledX, scaledY);
break;
case TextRenderingMode.STROKE:
case TextRenderingMode.STROKE_ADD_TO_PATH:
ctx.strokeText(character, scaledX, 0);
ctx.strokeText(character, scaledX, scaledY);
break;
case TextRenderingMode.FILL_STROKE:
case TextRenderingMode.FILL_STROKE_ADD_TO_PATH:
ctx.fillText(character, scaledX, 0);
ctx.strokeText(character, scaledX, 0);
ctx.fillText(character, scaledX, scaledY);
ctx.strokeText(character, scaledX, scaledY);
break;
case TextRenderingMode.INVISIBLE:
case TextRenderingMode.ADD_TO_PATH:
@ -995,7 +1009,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
}
if (textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG) {
var clipCtx = this.getCurrentTextClipping();
clipCtx.fillText(character, scaledX, 0);
clipCtx.fillText(character, scaledX, scaledY);
}
}
@ -1003,12 +1017,23 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
canvasWidth += charWidth;
}
current.x += x * textHScale;
if (vertical) {
current.y -= x * textHScale;
} else {
current.x += x * textHScale;
}
ctx.restore();
}
if (textSelection) {
geom.canvasWidth = canvasWidth;
if (vertical) {
var vmetric = font.defaultVMetrics;
geom.x -= vmetric[1] * fontSize * current.fontMatrix[0] /
fontSizeScale * geom.hScale;
geom.y += vmetric[2] * fontSize * current.fontMatrix[0] /
fontSizeScale * geom.vScale;
}
this.textLayer.appendText(geom);
}
@ -1027,6 +1052,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var geom;
var canvasWidth = 0.0;
var textSelection = textLayer ? true : false;
var vertical = font.vertical;
if (textSelection) {
ctx.save();
@ -1039,7 +1065,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var e = arr[i];
if (isNum(e)) {
var spacingLength = -e * fontSize * textHScale;
current.x += spacingLength;
if (vertical) {
current.y += spacingLength;
} else {
current.x += spacingLength;
}
if (textSelection)
canvasWidth += spacingLength;
@ -1055,6 +1085,14 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
if (textSelection) {
geom.canvasWidth = canvasWidth;
if (vertical) {
var fontSizeScale = current.fontSizeScale;
var vmetric = font.defaultVMetrics;
geom.x -= vmetric[1] * fontSize * current.fontMatrix[0] /
fontSizeScale * geom.hScale;
geom.y += vmetric[2] * fontSize * current.fontMatrix[0] /
fontSizeScale * geom.vScale;
}
this.textLayer.appendText(geom);
}
},

View file

@ -796,7 +796,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} // switch
if (chunk !== '') {
bidiTexts.push(PDFJS.bidi(chunk, -1));
var bidiText = PDFJS.bidi(chunk, -1, font.vertical);
bidiTexts.push(bidiText);
chunk = '';
}
@ -831,10 +832,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
};
}
var cidEncoding = baseDict.get('Encoding');
if (isName(cidEncoding))
properties.cidEncoding = cidEncoding.name;
var cidToGidMap = dict.get('CIDToGIDMap');
if (isStream(cidToGidMap))
properties.cidToGidMap = this.readCidToGidMap(cidToGidMap);
@ -1031,6 +1028,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
properties) {
var glyphsWidths = [];
var defaultWidth = 0;
var glyphsVMetrics = [];
var defaultVMetrics;
if (properties.composite) {
defaultWidth = dict.get('DW') || 1000;
@ -1049,6 +1048,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
}
}
if (properties.vertical) {
var vmetrics = dict.get('DW2') || [880, -1000];
defaultVMetrics = [vmetrics[1], vmetrics[1] / 2, vmetrics[0]];
vmetrics = dict.get('W2');
if (vmetrics) {
for (var i = 0, ii = vmetrics.length; i < ii; i++) {
var start = vmetrics[i++];
var code = xref.fetchIfRef(vmetrics[i]);
if (isArray(code)) {
for (var j = 0, jj = code.length; j < jj; j++)
glyphsVMetrics[start++] = [code[j++], code[j++], code[j]];
} else {
var vmetric = [vmetrics[++i], vmetrics[++i], vmetrics[++i]];
for (var j = start; j <= code; j++)
glyphsVMetrics[j] = vmetric;
}
}
}
}
} else {
var firstChar = properties.firstChar;
var widths = dict.get('Widths');
@ -1089,6 +1108,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
properties.defaultWidth = defaultWidth;
properties.widths = glyphsWidths;
properties.defaultVMetrics = defaultVMetrics;
properties.vmetrics = glyphsVMetrics;
},
isSerifFont: function PartialEvaluator_isSerifFont(baseFontName) {
@ -1260,6 +1281,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
italicAngle: descriptor.get('ItalicAngle'),
coded: false
};
if (composite) {
var cidEncoding = baseDict.get('Encoding');
if (isName(cidEncoding)) {
properties.cidEncoding = cidEncoding.name;
properties.vertical = /-V$/.test(cidEncoding.name);
}
}
this.extractWidths(dict, xref, descriptor, properties);
this.extractDataStructures(dict, baseDict, xref, properties);

View file

@ -2363,6 +2363,11 @@ var Font = (function FontClosure() {
// Trying to fix encoding using glyph CIDSystemInfo.
this.loadCidToUnicode(properties);
this.cidEncoding = properties.cidEncoding;
this.vertical = properties.vertical;
if (this.vertical) {
this.vmetrics = properties.vmetrics;
this.defaultVMetrics = properties.defaultVMetrics;
}
if (properties.toUnicode)
this.toUnicode = properties.toUnicode;
@ -4449,17 +4454,15 @@ var Font = (function FontClosure() {
var fontCharCode, width, operatorList, disabled;
var width = this.widths[charcode];
var vmetric = this.vmetrics && this.vmetrics[charcode];
switch (this.type) {
case 'CIDFontType0':
if (this.noUnicodeAdaptation) {
width = this.widths[this.unicodeToCID[charcode] || charcode];
}
fontCharCode = this.toFontChar[charcode] || charcode;
break;
case 'CIDFontType2':
var cid = this.unicodeToCID[charcode] || charcode;
if (this.noUnicodeAdaptation) {
width = this.widths[this.unicodeToCID[charcode] || charcode];
width = this.widths[cid];
vmetric = this.vmetrics && this.vmetrics[cid];
}
fontCharCode = this.toFontChar[charcode] || charcode;
break;
@ -4523,6 +4526,7 @@ var Font = (function FontClosure() {
fontChar: String.fromCharCode(fontCharCode),
unicode: unicodeChars,
width: width,
vmetric: vmetric,
disabled: disabled,
operatorList: operatorList
};