Merge pull request #10591 from brendandahl/fix-charset
Add unique glyph names for CFF fonts.
This commit is contained in:
commit
34022d2fd1
@ -96,6 +96,8 @@ var CFFStandardStrings = [
|
||||
'Black', 'Bold', 'Book', 'Light', 'Medium', 'Regular', 'Roman', 'Semibold'
|
||||
];
|
||||
|
||||
const NUM_STANDARD_CFF_STRINGS = 391;
|
||||
|
||||
var CFFParser = (function CFFParserClosure() {
|
||||
var CharstringValidationData = [
|
||||
null,
|
||||
@ -931,16 +933,27 @@ var CFFStrings = (function CFFStringsClosure() {
|
||||
}
|
||||
CFFStrings.prototype = {
|
||||
get: function CFFStrings_get(index) {
|
||||
if (index >= 0 && index <= 390) {
|
||||
if (index >= 0 && index <= (NUM_STANDARD_CFF_STRINGS - 1)) {
|
||||
return CFFStandardStrings[index];
|
||||
}
|
||||
if (index - 391 <= this.strings.length) {
|
||||
return this.strings[index - 391];
|
||||
if (index - NUM_STANDARD_CFF_STRINGS <= this.strings.length) {
|
||||
return this.strings[index - NUM_STANDARD_CFF_STRINGS];
|
||||
}
|
||||
return CFFStandardStrings[0];
|
||||
},
|
||||
getSID: function CFFStrings_getSID(str) {
|
||||
let index = CFFStandardStrings.indexOf(str);
|
||||
if (index !== -1) {
|
||||
return index;
|
||||
}
|
||||
index = this.strings.indexOf(str);
|
||||
if (index !== -1) {
|
||||
return index + NUM_STANDARD_CFF_STRINGS;
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
add: function CFFStrings_add(value) {
|
||||
this.strings.push(value);
|
||||
return this.strings.push(value) + NUM_STANDARD_CFF_STRINGS - 1;
|
||||
},
|
||||
get count() {
|
||||
return this.strings.length;
|
||||
@ -1312,7 +1325,8 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
||||
output.add(encoding);
|
||||
}
|
||||
}
|
||||
var charset = this.compileCharset(cff.charset);
|
||||
var charset = this.compileCharset(cff.charset, cff.charStrings.count,
|
||||
cff.strings, cff.isCIDFont);
|
||||
topDictTracker.setEntryLocation('charset', [output.length], output);
|
||||
output.add(charset);
|
||||
|
||||
@ -1580,11 +1594,42 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
||||
}
|
||||
return this.compileIndex(charStringsIndex);
|
||||
},
|
||||
compileCharset: function CFFCompiler_compileCharset(charset) {
|
||||
let length = 1 + (this.cff.charStrings.count - 1) * 2;
|
||||
// The contents of the charset doesn't matter, it's just there to make
|
||||
// freetype happy.
|
||||
let out = new Uint8Array(length);
|
||||
compileCharset: function CFFCompiler_compileCharset(charset, numGlyphs,
|
||||
strings, isCIDFont) {
|
||||
// Freetype requires the number of charset strings be correct and MacOS
|
||||
// requires a valid mapping for printing.
|
||||
let out;
|
||||
let numGlyphsLessNotDef = numGlyphs - 1;
|
||||
if (isCIDFont) {
|
||||
// In a CID font, the charset is a mapping of CIDs not SIDs so just
|
||||
// create an identity mapping.
|
||||
out = new Uint8Array([
|
||||
2, // format
|
||||
0, // first CID upper byte
|
||||
0, // first CID lower byte
|
||||
(numGlyphsLessNotDef >> 8) & 0xFF,
|
||||
numGlyphsLessNotDef & 0xFF,
|
||||
]);
|
||||
} else {
|
||||
let length = 1 + numGlyphsLessNotDef * 2;
|
||||
out = new Uint8Array(length);
|
||||
out[0] = 0; // format 0
|
||||
let charsetIndex = 0;
|
||||
let numCharsets = charset.charset.length;
|
||||
for (let i = 1; i < out.length; i += 2) {
|
||||
let sid = 0;
|
||||
if (charsetIndex < numCharsets) {
|
||||
let name = charset.charset[charsetIndex++];
|
||||
sid = strings.getSID(name);
|
||||
if (sid === -1) {
|
||||
sid = 0;
|
||||
warn(`Couldn't find ${name} in CFF strings`);
|
||||
}
|
||||
}
|
||||
out[i] = (sid >> 8) & 0xFF;
|
||||
out[i + 1] = sid & 0xFF;
|
||||
}
|
||||
}
|
||||
return this.compileTypedArray(out);
|
||||
},
|
||||
compileEncoding: function CFFCompiler_compileEncoding(encoding) {
|
||||
|
@ -3339,16 +3339,12 @@ var Type1Font = (function Type1FontClosure() {
|
||||
var i, ii;
|
||||
for (i = 0; i < count; i++) {
|
||||
var index = CFFStandardStrings.indexOf(charstrings[i].glyphName);
|
||||
// TODO: Insert the string and correctly map it. Previously it was
|
||||
// thought mapping names that aren't in the standard strings to .notdef
|
||||
// was fine, however in issue818 when mapping them all to .notdef the
|
||||
// adieresis glyph no longer worked.
|
||||
if (index === -1) {
|
||||
index = 0;
|
||||
index = strings.add(charstrings[i].glyphName);
|
||||
}
|
||||
charsetArray.push((index >> 8) & 0xff, index & 0xff);
|
||||
charsetArray.push(index);
|
||||
}
|
||||
cff.charset = new CFFCharset(false, 0, [], charsetArray);
|
||||
cff.charset = new CFFCharset(false, 0, charsetArray);
|
||||
|
||||
var charStringsIndex = new CFFIndex();
|
||||
charStringsIndex.add([0x8B, 0x0E]); // .notdef
|
||||
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
CFFCompiler, CFFFDSelect, CFFParser, CFFStrings
|
||||
CFFCharset, CFFCompiler, CFFFDSelect, CFFParser, CFFStrings
|
||||
} from '../../src/core/cff_parser';
|
||||
import { SEAC_ANALYSIS_ENABLED } from '../../src/core/fonts';
|
||||
import { Stream } from '../../src/core/stream';
|
||||
@ -446,5 +446,35 @@ describe('CFFCompiler', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('compiles charset of CID font', function() {
|
||||
var charset = new CFFCharset();
|
||||
var c = new CFFCompiler();
|
||||
var numGlyphs = 7;
|
||||
var out = c.compileCharset(charset, numGlyphs, new CFFStrings(), true);
|
||||
// All CID charsets get turned into a simple format 2.
|
||||
expect(out).toEqual([
|
||||
2, // format
|
||||
0, // cid (high)
|
||||
0, // cid (low)
|
||||
0, // nLeft (high)
|
||||
numGlyphs - 1, // nLeft (low)
|
||||
]);
|
||||
});
|
||||
|
||||
it('compiles charset of non CID font', function() {
|
||||
var charset = new CFFCharset(false, 0, ['space', 'exclam']);
|
||||
var c = new CFFCompiler();
|
||||
var numGlyphs = 3;
|
||||
var out = c.compileCharset(charset, numGlyphs, new CFFStrings(), false);
|
||||
// All non-CID fonts use a format 0 charset.
|
||||
expect(out).toEqual([
|
||||
0, // format
|
||||
0, // sid of 'space' (high)
|
||||
1, // sid of 'space' (low)
|
||||
0, // sid of 'exclam' (high)
|
||||
2, // sid of 'exclam' (low)
|
||||
]);
|
||||
});
|
||||
|
||||
// TODO a lot more compiler tests
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user