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 {
|
import {
|
||||||
bytesToString, FormatError, unreachable, Util
|
bytesToString, FONT_IDENTITY_MATRIX, FormatError, unreachable, Util, warn
|
||||||
} from '../shared/util';
|
} from '../shared/util';
|
||||||
import { CFFParser } from './cff_parser';
|
import { CFFParser } from './cff_parser';
|
||||||
import { getGlyphsUnicode } from './glyphlist';
|
import { getGlyphsUnicode } from './glyphlist';
|
||||||
@ -91,6 +91,9 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||||||
subrs: (cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex &&
|
subrs: (cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex &&
|
||||||
cff.topDict.privateDict.subrsIndex.objects),
|
cff.topDict.privateDict.subrsIndex.objects),
|
||||||
gsubrs: cff.globalSubrIndex && cff.globalSubrIndex.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 stack = [];
|
||||||
var x = 0, y = 0;
|
var x = 0, y = 0;
|
||||||
var stems = 0;
|
var stems = 0;
|
||||||
@ -366,8 +369,28 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 10: // callsubr
|
case 10: // callsubr
|
||||||
n = stack.pop() + font.subrsBias;
|
n = stack.pop();
|
||||||
subrCode = font.subrs[n];
|
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) {
|
if (subrCode) {
|
||||||
parse(subrCode);
|
parse(subrCode);
|
||||||
}
|
}
|
||||||
@ -438,12 +461,14 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||||||
cmds.push({ cmd: 'translate', args: [x, y], });
|
cmds.push({ cmd: 'translate', args: [x, y], });
|
||||||
var cmap = lookupCmap(font.cmap, String.fromCharCode(
|
var cmap = lookupCmap(font.cmap, String.fromCharCode(
|
||||||
font.glyphNameMap[StandardEncoding[achar]]));
|
font.glyphNameMap[StandardEncoding[achar]]));
|
||||||
compileCharString(font.glyphs[cmap.glyphId], cmds, font);
|
compileCharString(font.glyphs[cmap.glyphId], cmds, font,
|
||||||
|
cmap.glyphId);
|
||||||
cmds.push({ cmd: 'restore', });
|
cmds.push({ cmd: 'restore', });
|
||||||
|
|
||||||
cmap = lookupCmap(font.cmap, String.fromCharCode(
|
cmap = lookupCmap(font.cmap, String.fromCharCode(
|
||||||
font.glyphNameMap[StandardEncoding[bchar]]));
|
font.glyphNameMap[StandardEncoding[bchar]]));
|
||||||
compileCharString(font.glyphs[cmap.glyphId], cmds, font);
|
compileCharString(font.glyphs[cmap.glyphId], cmds, font,
|
||||||
|
cmap.glyphId);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 18: // hstemhm
|
case 18: // hstemhm
|
||||||
@ -603,7 +628,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||||||
var cmap = lookupCmap(this.cmap, unicode);
|
var cmap = lookupCmap(this.cmap, unicode);
|
||||||
var fn = this.compiledGlyphs[cmap.glyphId];
|
var fn = this.compiledGlyphs[cmap.glyphId];
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
fn = this.compileGlyph(this.glyphs[cmap.glyphId]);
|
fn = this.compileGlyph(this.glyphs[cmap.glyphId], cmap.glyphId);
|
||||||
this.compiledGlyphs[cmap.glyphId] = fn;
|
this.compiledGlyphs[cmap.glyphId] = fn;
|
||||||
}
|
}
|
||||||
if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) {
|
if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) {
|
||||||
@ -612,17 +637,30 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||||||
return fn;
|
return fn;
|
||||||
},
|
},
|
||||||
|
|
||||||
compileGlyph(code) {
|
compileGlyph(code, glyphId) {
|
||||||
if (!code || code.length === 0 || code[0] === 14) {
|
if (!code || code.length === 0 || code[0] === 14) {
|
||||||
return noop;
|
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 = [];
|
var cmds = [];
|
||||||
cmds.push({ cmd: 'save', });
|
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'], });
|
cmds.push({ cmd: 'scale', args: ['size', '-size'], });
|
||||||
|
|
||||||
this.compileGlyphImpl(code, cmds);
|
this.compileGlyphImpl(code, cmds, glyphId);
|
||||||
|
|
||||||
cmds.push({ cmd: 'restore', });
|
cmds.push({ cmd: 'restore', });
|
||||||
|
|
||||||
@ -668,11 +706,15 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||||||
107 : (this.gsubrs.length < 33900 ? 1131 : 32768));
|
107 : (this.gsubrs.length < 33900 ? 1131 : 32768));
|
||||||
this.subrsBias = (this.subrs.length < 1240 ?
|
this.subrsBias = (this.subrs.length < 1240 ?
|
||||||
107 : (this.subrs.length < 33900 ? 1131 : 32768));
|
107 : (this.subrs.length < 33900 ? 1131 : 32768));
|
||||||
|
|
||||||
|
this.isCFFCIDFont = cffInfo.isCFFCIDFont;
|
||||||
|
this.fdSelect = cffInfo.fdSelect;
|
||||||
|
this.fdArray = cffInfo.fdArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
Util.inherit(Type2Compiled, CompiledFont, {
|
Util.inherit(Type2Compiled, CompiledFont, {
|
||||||
compileGlyphImpl(code, cmds) {
|
compileGlyphImpl(code, cmds, glyphId) {
|
||||||
compileCharString(code, cmds, this);
|
compileCharString(code, cmds, this, glyphId);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -262,6 +262,7 @@
|
|||||||
!issue4573.pdf
|
!issue4573.pdf
|
||||||
!issue4722.pdf
|
!issue4722.pdf
|
||||||
!issue4800.pdf
|
!issue4800.pdf
|
||||||
|
!text_clip_cff_cid.pdf
|
||||||
!issue4801.pdf
|
!issue4801.pdf
|
||||||
!issue5334.pdf
|
!issue5334.pdf
|
||||||
!bug1186827.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,
|
"link": true,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "text_clip_cff_cid",
|
||||||
|
"file": "pdfs/text_clip_cff_cid.pdf",
|
||||||
|
"md5": "92d4920586f177cc0e83326e5b5d2ee1",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "preistabelle",
|
{ "id": "preistabelle",
|
||||||
"file": "pdfs/preistabelle.pdf",
|
"file": "pdfs/preistabelle.pdf",
|
||||||
"md5": "d2f0b2086160d4f3d325c79a5dc1fb4d",
|
"md5": "d2f0b2086160d4f3d325c79a5dc1fb4d",
|
||||||
|
Loading…
Reference in New Issue
Block a user