Skip to content

Commit 7d7bc80

Browse files
authored
Merge pull request #9501 from janpe2/text-clip-cff-cid
Use FDSelect and FDArray when converting CFF CID font to paths
2 parents 2275485 + 8ea5055 commit 7d7bc80

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

src/core/font_renderer.js

+54-12
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515

1616
import {
17-
bytesToString, FormatError, unreachable, Util
17+
bytesToString, FONT_IDENTITY_MATRIX, FormatError, unreachable, Util, warn
1818
} from '../shared/util';
1919
import { CFFParser } from './cff_parser';
2020
import { getGlyphsUnicode } from './glyphlist';
@@ -91,6 +91,9 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
9191
subrs: (cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex &&
9292
cff.topDict.privateDict.subrsIndex.objects),
9393
gsubrs: cff.globalSubrIndex && cff.globalSubrIndex.objects,
94+
isCFFCIDFont: cff.isCIDFont,
95+
fdSelect: cff.fdSelect,
96+
fdArray: cff.fdArray,
9497
};
9598
}
9699

@@ -293,7 +296,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
293296
}
294297
}
295298

296-
function compileCharString(code, cmds, font) {
299+
function compileCharString(code, cmds, font, glyphId) {
297300
var stack = [];
298301
var x = 0, y = 0;
299302
var stems = 0;
@@ -366,8 +369,28 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
366369
}
367370
break;
368371
case 10: // callsubr
369-
n = stack.pop() + font.subrsBias;
370-
subrCode = font.subrs[n];
372+
n = stack.pop();
373+
subrCode = null;
374+
if (font.isCFFCIDFont) {
375+
let fdIndex = font.fdSelect.getFDIndex(glyphId);
376+
if (fdIndex >= 0 && fdIndex < font.fdArray.length) {
377+
let fontDict = font.fdArray[fdIndex], subrs;
378+
if (fontDict.privateDict && fontDict.privateDict.subrsIndex) {
379+
subrs = fontDict.privateDict.subrsIndex.objects;
380+
}
381+
if (subrs) {
382+
let numSubrs = subrs.length;
383+
// Add subroutine bias.
384+
n += numSubrs < 1240 ? 107 :
385+
(numSubrs < 33900 ? 1131 : 32768);
386+
subrCode = subrs[n];
387+
}
388+
} else {
389+
warn('Invalid fd index for glyph index.');
390+
}
391+
} else {
392+
subrCode = font.subrs[n + font.subrsBias];
393+
}
371394
if (subrCode) {
372395
parse(subrCode);
373396
}
@@ -438,12 +461,14 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
438461
cmds.push({ cmd: 'translate', args: [x, y], });
439462
var cmap = lookupCmap(font.cmap, String.fromCharCode(
440463
font.glyphNameMap[StandardEncoding[achar]]));
441-
compileCharString(font.glyphs[cmap.glyphId], cmds, font);
464+
compileCharString(font.glyphs[cmap.glyphId], cmds, font,
465+
cmap.glyphId);
442466
cmds.push({ cmd: 'restore', });
443467

444468
cmap = lookupCmap(font.cmap, String.fromCharCode(
445469
font.glyphNameMap[StandardEncoding[bchar]]));
446-
compileCharString(font.glyphs[cmap.glyphId], cmds, font);
470+
compileCharString(font.glyphs[cmap.glyphId], cmds, font,
471+
cmap.glyphId);
447472
}
448473
return;
449474
case 18: // hstemhm
@@ -603,7 +628,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
603628
var cmap = lookupCmap(this.cmap, unicode);
604629
var fn = this.compiledGlyphs[cmap.glyphId];
605630
if (!fn) {
606-
fn = this.compileGlyph(this.glyphs[cmap.glyphId]);
631+
fn = this.compileGlyph(this.glyphs[cmap.glyphId], cmap.glyphId);
607632
this.compiledGlyphs[cmap.glyphId] = fn;
608633
}
609634
if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) {
@@ -612,17 +637,30 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
612637
return fn;
613638
},
614639

615-
compileGlyph(code) {
640+
compileGlyph(code, glyphId) {
616641
if (!code || code.length === 0 || code[0] === 14) {
617642
return noop;
618643
}
619644

645+
let fontMatrix = this.fontMatrix;
646+
if (this.isCFFCIDFont) {
647+
// Top DICT's FontMatrix can be ignored because CFFCompiler always
648+
// removes it and copies to FDArray DICTs.
649+
let fdIndex = this.fdSelect.getFDIndex(glyphId);
650+
if (fdIndex >= 0 && fdIndex < this.fdArray.length) {
651+
let fontDict = this.fdArray[fdIndex];
652+
fontMatrix = fontDict.getByName('FontMatrix') || FONT_IDENTITY_MATRIX;
653+
} else {
654+
warn('Invalid fd index for glyph index.');
655+
}
656+
}
657+
620658
var cmds = [];
621659
cmds.push({ cmd: 'save', });
622-
cmds.push({ cmd: 'transform', args: this.fontMatrix.slice(), });
660+
cmds.push({ cmd: 'transform', args: fontMatrix.slice(), });
623661
cmds.push({ cmd: 'scale', args: ['size', '-size'], });
624662

625-
this.compileGlyphImpl(code, cmds);
663+
this.compileGlyphImpl(code, cmds, glyphId);
626664

627665
cmds.push({ cmd: 'restore', });
628666

@@ -668,11 +706,15 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
668706
107 : (this.gsubrs.length < 33900 ? 1131 : 32768));
669707
this.subrsBias = (this.subrs.length < 1240 ?
670708
107 : (this.subrs.length < 33900 ? 1131 : 32768));
709+
710+
this.isCFFCIDFont = cffInfo.isCFFCIDFont;
711+
this.fdSelect = cffInfo.fdSelect;
712+
this.fdArray = cffInfo.fdArray;
671713
}
672714

673715
Util.inherit(Type2Compiled, CompiledFont, {
674-
compileGlyphImpl(code, cmds) {
675-
compileCharString(code, cmds, this);
716+
compileGlyphImpl(code, cmds, glyphId) {
717+
compileCharString(code, cmds, this, glyphId);
676718
},
677719
});
678720

test/pdfs/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@
262262
!issue4573.pdf
263263
!issue4722.pdf
264264
!issue4800.pdf
265+
!text_clip_cff_cid.pdf
265266
!issue4801.pdf
266267
!issue5334.pdf
267268
!bug1186827.pdf

test/pdfs/text_clip_cff_cid.pdf

7.22 KB
Binary file not shown.

test/test_manifest.json

+6
Original file line numberDiff line numberDiff line change
@@ -2261,6 +2261,12 @@
22612261
"link": true,
22622262
"type": "eq"
22632263
},
2264+
{ "id": "text_clip_cff_cid",
2265+
"file": "pdfs/text_clip_cff_cid.pdf",
2266+
"md5": "92d4920586f177cc0e83326e5b5d2ee1",
2267+
"rounds": 1,
2268+
"type": "eq"
2269+
},
22642270
{ "id": "preistabelle",
22652271
"file": "pdfs/preistabelle.pdf",
22662272
"md5": "d2f0b2086160d4f3d325c79a5dc1fb4d",

0 commit comments

Comments
 (0)