Use FDSelect and FDArray when converting CFF CID font to paths
This commit is contained in:
parent
2275485cec
commit
8ea505545a
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
bytesToString, FormatError, unreachable, Util
|
||||
bytesToString, FONT_IDENTITY_MATRIX, FormatError, unreachable, Util, warn
|
||||
} from '../shared/util';
|
||||
import { CFFParser } from './cff_parser';
|
||||
import { getGlyphsUnicode } from './glyphlist';
|
||||
@ -91,6 +91,9 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
subrs: (cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex &&
|
||||
cff.topDict.privateDict.subrsIndex.objects),
|
||||
gsubrs: cff.globalSubrIndex && cff.globalSubrIndex.objects,
|
||||
isCFFCIDFont: cff.isCIDFont,
|
||||
fdSelect: cff.fdSelect,
|
||||
fdArray: cff.fdArray,
|
||||
};
|
||||
}
|
||||
|
||||
@ -293,7 +296,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
function compileCharString(code, cmds, font) {
|
||||
function compileCharString(code, cmds, font, glyphId) {
|
||||
var stack = [];
|
||||
var x = 0, y = 0;
|
||||
var stems = 0;
|
||||
@ -366,8 +369,28 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
}
|
||||
break;
|
||||
case 10: // callsubr
|
||||
n = stack.pop() + font.subrsBias;
|
||||
subrCode = font.subrs[n];
|
||||
n = stack.pop();
|
||||
subrCode = null;
|
||||
if (font.isCFFCIDFont) {
|
||||
let fdIndex = font.fdSelect.getFDIndex(glyphId);
|
||||
if (fdIndex >= 0 && fdIndex < font.fdArray.length) {
|
||||
let fontDict = font.fdArray[fdIndex], subrs;
|
||||
if (fontDict.privateDict && fontDict.privateDict.subrsIndex) {
|
||||
subrs = fontDict.privateDict.subrsIndex.objects;
|
||||
}
|
||||
if (subrs) {
|
||||
let numSubrs = subrs.length;
|
||||
// Add subroutine bias.
|
||||
n += numSubrs < 1240 ? 107 :
|
||||
(numSubrs < 33900 ? 1131 : 32768);
|
||||
subrCode = subrs[n];
|
||||
}
|
||||
} else {
|
||||
warn('Invalid fd index for glyph index.');
|
||||
}
|
||||
} else {
|
||||
subrCode = font.subrs[n + font.subrsBias];
|
||||
}
|
||||
if (subrCode) {
|
||||
parse(subrCode);
|
||||
}
|
||||
@ -438,12 +461,14 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
cmds.push({ cmd: 'translate', args: [x, y], });
|
||||
var cmap = lookupCmap(font.cmap, String.fromCharCode(
|
||||
font.glyphNameMap[StandardEncoding[achar]]));
|
||||
compileCharString(font.glyphs[cmap.glyphId], cmds, font);
|
||||
compileCharString(font.glyphs[cmap.glyphId], cmds, font,
|
||||
cmap.glyphId);
|
||||
cmds.push({ cmd: 'restore', });
|
||||
|
||||
cmap = lookupCmap(font.cmap, String.fromCharCode(
|
||||
font.glyphNameMap[StandardEncoding[bchar]]));
|
||||
compileCharString(font.glyphs[cmap.glyphId], cmds, font);
|
||||
compileCharString(font.glyphs[cmap.glyphId], cmds, font,
|
||||
cmap.glyphId);
|
||||
}
|
||||
return;
|
||||
case 18: // hstemhm
|
||||
@ -603,7 +628,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
var cmap = lookupCmap(this.cmap, unicode);
|
||||
var fn = this.compiledGlyphs[cmap.glyphId];
|
||||
if (!fn) {
|
||||
fn = this.compileGlyph(this.glyphs[cmap.glyphId]);
|
||||
fn = this.compileGlyph(this.glyphs[cmap.glyphId], cmap.glyphId);
|
||||
this.compiledGlyphs[cmap.glyphId] = fn;
|
||||
}
|
||||
if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) {
|
||||
@ -612,17 +637,30 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
return fn;
|
||||
},
|
||||
|
||||
compileGlyph(code) {
|
||||
compileGlyph(code, glyphId) {
|
||||
if (!code || code.length === 0 || code[0] === 14) {
|
||||
return noop;
|
||||
}
|
||||
|
||||
let fontMatrix = this.fontMatrix;
|
||||
if (this.isCFFCIDFont) {
|
||||
// Top DICT's FontMatrix can be ignored because CFFCompiler always
|
||||
// removes it and copies to FDArray DICTs.
|
||||
let fdIndex = this.fdSelect.getFDIndex(glyphId);
|
||||
if (fdIndex >= 0 && fdIndex < this.fdArray.length) {
|
||||
let fontDict = this.fdArray[fdIndex];
|
||||
fontMatrix = fontDict.getByName('FontMatrix') || FONT_IDENTITY_MATRIX;
|
||||
} else {
|
||||
warn('Invalid fd index for glyph index.');
|
||||
}
|
||||
}
|
||||
|
||||
var cmds = [];
|
||||
cmds.push({ cmd: 'save', });
|
||||
cmds.push({ cmd: 'transform', args: this.fontMatrix.slice(), });
|
||||
cmds.push({ cmd: 'transform', args: fontMatrix.slice(), });
|
||||
cmds.push({ cmd: 'scale', args: ['size', '-size'], });
|
||||
|
||||
this.compileGlyphImpl(code, cmds);
|
||||
this.compileGlyphImpl(code, cmds, glyphId);
|
||||
|
||||
cmds.push({ cmd: 'restore', });
|
||||
|
||||
@ -668,11 +706,15 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
107 : (this.gsubrs.length < 33900 ? 1131 : 32768));
|
||||
this.subrsBias = (this.subrs.length < 1240 ?
|
||||
107 : (this.subrs.length < 33900 ? 1131 : 32768));
|
||||
|
||||
this.isCFFCIDFont = cffInfo.isCFFCIDFont;
|
||||
this.fdSelect = cffInfo.fdSelect;
|
||||
this.fdArray = cffInfo.fdArray;
|
||||
}
|
||||
|
||||
Util.inherit(Type2Compiled, CompiledFont, {
|
||||
compileGlyphImpl(code, cmds) {
|
||||
compileCharString(code, cmds, this);
|
||||
compileGlyphImpl(code, cmds, glyphId) {
|
||||
compileCharString(code, cmds, this, glyphId);
|
||||
},
|
||||
});
|
||||
|
||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -262,6 +262,7 @@
|
||||
!issue4573.pdf
|
||||
!issue4722.pdf
|
||||
!issue4800.pdf
|
||||
!text_clip_cff_cid.pdf
|
||||
!issue4801.pdf
|
||||
!issue5334.pdf
|
||||
!bug1186827.pdf
|
||||
|
BIN
test/pdfs/text_clip_cff_cid.pdf
Normal file
BIN
test/pdfs/text_clip_cff_cid.pdf
Normal file
Binary file not shown.
@ -2261,6 +2261,12 @@
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "text_clip_cff_cid",
|
||||
"file": "pdfs/text_clip_cff_cid.pdf",
|
||||
"md5": "92d4920586f177cc0e83326e5b5d2ee1",
|
||||
"rounds": 1,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "preistabelle",
|
||||
"file": "pdfs/preistabelle.pdf",
|
||||
"md5": "d2f0b2086160d4f3d325c79a5dc1fb4d",
|
||||
|
Loading…
Reference in New Issue
Block a user