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'
|
'Black', 'Bold', 'Book', 'Light', 'Medium', 'Regular', 'Roman', 'Semibold'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const NUM_STANDARD_CFF_STRINGS = 391;
|
||||||
|
|
||||||
var CFFParser = (function CFFParserClosure() {
|
var CFFParser = (function CFFParserClosure() {
|
||||||
var CharstringValidationData = [
|
var CharstringValidationData = [
|
||||||
null,
|
null,
|
||||||
@ -931,16 +933,27 @@ var CFFStrings = (function CFFStringsClosure() {
|
|||||||
}
|
}
|
||||||
CFFStrings.prototype = {
|
CFFStrings.prototype = {
|
||||||
get: function CFFStrings_get(index) {
|
get: function CFFStrings_get(index) {
|
||||||
if (index >= 0 && index <= 390) {
|
if (index >= 0 && index <= (NUM_STANDARD_CFF_STRINGS - 1)) {
|
||||||
return CFFStandardStrings[index];
|
return CFFStandardStrings[index];
|
||||||
}
|
}
|
||||||
if (index - 391 <= this.strings.length) {
|
if (index - NUM_STANDARD_CFF_STRINGS <= this.strings.length) {
|
||||||
return this.strings[index - 391];
|
return this.strings[index - NUM_STANDARD_CFF_STRINGS];
|
||||||
}
|
}
|
||||||
return CFFStandardStrings[0];
|
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) {
|
add: function CFFStrings_add(value) {
|
||||||
this.strings.push(value);
|
return this.strings.push(value) + NUM_STANDARD_CFF_STRINGS - 1;
|
||||||
},
|
},
|
||||||
get count() {
|
get count() {
|
||||||
return this.strings.length;
|
return this.strings.length;
|
||||||
@ -1312,7 +1325,8 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|||||||
output.add(encoding);
|
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);
|
topDictTracker.setEntryLocation('charset', [output.length], output);
|
||||||
output.add(charset);
|
output.add(charset);
|
||||||
|
|
||||||
@ -1580,11 +1594,42 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|||||||
}
|
}
|
||||||
return this.compileIndex(charStringsIndex);
|
return this.compileIndex(charStringsIndex);
|
||||||
},
|
},
|
||||||
compileCharset: function CFFCompiler_compileCharset(charset) {
|
compileCharset: function CFFCompiler_compileCharset(charset, numGlyphs,
|
||||||
let length = 1 + (this.cff.charStrings.count - 1) * 2;
|
strings, isCIDFont) {
|
||||||
// The contents of the charset doesn't matter, it's just there to make
|
// Freetype requires the number of charset strings be correct and MacOS
|
||||||
// freetype happy.
|
// requires a valid mapping for printing.
|
||||||
let out = new Uint8Array(length);
|
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);
|
return this.compileTypedArray(out);
|
||||||
},
|
},
|
||||||
compileEncoding: function CFFCompiler_compileEncoding(encoding) {
|
compileEncoding: function CFFCompiler_compileEncoding(encoding) {
|
||||||
|
@ -3339,16 +3339,12 @@ var Type1Font = (function Type1FontClosure() {
|
|||||||
var i, ii;
|
var i, ii;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
var index = CFFStandardStrings.indexOf(charstrings[i].glyphName);
|
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) {
|
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();
|
var charStringsIndex = new CFFIndex();
|
||||||
charStringsIndex.add([0x8B, 0x0E]); // .notdef
|
charStringsIndex.add([0x8B, 0x0E]); // .notdef
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CFFCompiler, CFFFDSelect, CFFParser, CFFStrings
|
CFFCharset, CFFCompiler, CFFFDSelect, CFFParser, CFFStrings
|
||||||
} from '../../src/core/cff_parser';
|
} from '../../src/core/cff_parser';
|
||||||
import { SEAC_ANALYSIS_ENABLED } from '../../src/core/fonts';
|
import { SEAC_ANALYSIS_ENABLED } from '../../src/core/fonts';
|
||||||
import { Stream } from '../../src/core/stream';
|
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
|
// TODO a lot more compiler tests
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user