Skip to content

Commit

Permalink
Merge pull request #9501 from janpe2/text-clip-cff-cid
Browse files Browse the repository at this point in the history
Use FDSelect and FDArray when converting CFF CID font to paths
  • Loading branch information
brendandahl committed Apr 11, 2018
2 parents 2275485 + 8ea5055 commit 7d7bc80
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 12 deletions.
66 changes: 54 additions & 12 deletions src/core/font_renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
};
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -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', });

Expand Down Expand Up @@ -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);
},
});

Expand Down
1 change: 1 addition & 0 deletions test/pdfs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@
!issue4573.pdf
!issue4722.pdf
!issue4800.pdf
!text_clip_cff_cid.pdf
!issue4801.pdf
!issue5334.pdf
!bug1186827.pdf
Expand Down
Binary file added test/pdfs/text_clip_cff_cid.pdf
Binary file not shown.
6 changes: 6 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 7d7bc80

Please sign in to comment.