Skip to content

Commit

Permalink
Merge pull request #30 from QWOO-SAS/otfFix
Browse files Browse the repository at this point in the history
Otf fix
  • Loading branch information
kekee000 authored Mar 2, 2020
2 parents a052130 + f2bf46c commit d676f12
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 78 deletions.
16 changes: 15 additions & 1 deletion src/ttf/table/CFF.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import table from './table';
import string from '../util/string';
import encoding from './cff/encoding';
import cffStandardStrings from './cff/cffStandardStrings';
import parseCFFDict from './cff/parseCFFDict';
import parseCFFGlyph from './cff/parseCFFGlyph';
import parseCFFCharset from './cff/parseCFFCharset';
Expand Down Expand Up @@ -115,6 +116,7 @@ export default table.create(
[],
{
read(reader, font) {

let offset = this.offset;
reader.seek(offset);

Expand Down Expand Up @@ -178,7 +180,19 @@ export default table.create(
// 解析glyf数据和名字
let charStringsIndex = parseCFFIndex(reader, offset + topDict.charStrings);
let nGlyphs = charStringsIndex.objects.length;
cff.charset = parseCFFCharset(reader, offset + topDict.charset, nGlyphs, stringIndex.objects);

if (topDict.charset < 3) {
/*@author: fr33z00
See end of chapter 13 (p22) of #5176.CFF.pdf :
Still more optimization is possible by
observing that many fonts adopt one of 3 common charsets. In
these cases the operand to the charset operator in the Top DICT
specifies a predefined charset id, in place of an offset, as shown in table 22*/
cff.charset = cffStandardStrings;
}
else {
cff.charset = parseCFFCharset(reader, offset + topDict.charset, nGlyphs, stringIndex.objects);
}

// Standard encoding
if (topDict.encoding === 0) {
Expand Down
63 changes: 63 additions & 0 deletions src/ttf/table/cff/cffStandardStrings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const cffStandardStrings = [
'.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'quoteright',
'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two',
'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater',
'question', 'at', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore',
'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright',
'asciitilde', 'exclamdown', 'cent', 'sterling',
'fraction', 'yen', 'florin', 'section', 'currency', 'quotesingle', 'quotedblleft', 'guillemotleft',
'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'endash', 'dagger',
'daggerdbl', 'periodcentered', 'paragraph',
'bullet', 'quotesinglbase', 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', 'perthousand',
'questiondown', 'grave', 'acute', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent', 'dieresis', 'ring',
'cedilla', 'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine', 'Lslash', 'Oslash', 'OE',
'ordmasculine', 'ae', 'dotlessi', 'lslash', 'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu',
'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter', 'divide', 'brokenbar', 'degree', 'thorn',
'threequarters', 'twosuperior', 'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright',
'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde', 'Ccedilla', 'Eacute', 'Ecircumflex',
'Edieresis', 'Egrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex',
'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex', 'Udieresis', 'Ugrave', 'Yacute',
'Ydieresis', 'Zcaron', 'aacute', 'acircumflex', 'adieresis',
'agrave', 'aring', 'atilde', 'ccedilla', 'eacute',
'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex', 'idieresis', 'igrave', 'ntilde', 'oacute',
'ocircumflex', 'odieresis', 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', 'ugrave',
'yacute', 'ydieresis', 'zcaron', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', 'dollarsuperior',
'ampersandsmall', 'Acutesmall', 'parenleftsuperior', 'parenrightsuperior', '266 ff', 'onedotenleader',
'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle',
'fouroldstyle', 'fiveoldstyle', 'sixoldstyle',
'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'commasuperior', 'threequartersemdash', 'periodsuperior',
'questionsmall', 'asuperior', 'bsuperior', 'centsuperior',
'dsuperior', 'esuperior', 'isuperior', 'lsuperior',
'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', 'tsuperior', 'ff', 'ffi', 'ffl',
'parenleftinferior', 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', 'Asmall',
'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall',
'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall',
'Msmall', 'Nsmall', 'Osmall', 'Psmall', 'Qsmall', 'Rsmall',
'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall',
'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall',
'centoldstyle', 'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', 'Brevesmall', 'Caronsmall',
'Dotaccentsmall', 'Macronsmall', 'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall', 'Cedillasmall',
'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', 'seveneighths', 'onethird', 'twothirds',
'zerosuperior', 'foursuperior', 'fivesuperior', 'sixsuperior',
'sevensuperior', 'eightsuperior', 'ninesuperior',
'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior',
'fourinferior', 'fiveinferior', 'sixinferior',
'seveninferior', 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', 'periodinferior',
'commainferior', 'Agravesmall', 'Aacutesmall', 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall',
'Aringsmall', 'AEsmall', 'Ccedillasmall', 'Egravesmall',
'Eacutesmall', 'Ecircumflexsmall', 'Edieresissmall',
'Igravesmall', 'Iacutesmall', 'Icircumflexsmall',
'Idieresissmall', 'Ethsmall', 'Ntildesmall', 'Ogravesmall',
'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall',
'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall',
'Uacutesmall', 'Ucircumflexsmall', 'Udieresissmall',
'Yacutesmall', 'Thornsmall', 'Ydieresissmall', '001.000',
'001.001', '001.002', '001.003', 'Black', 'Bold',
'Book', 'Light', 'Medium', 'Regular', 'Roman', 'Semibold'
];

export default cffStandardStrings;
62 changes: 1 addition & 61 deletions src/ttf/table/cff/getCFFString.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,7 @@
* @author mengke01([email protected])
*/

const cffStandardStrings = [
'.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'quoteright',
'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two',
'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater',
'question', 'at', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore',
'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright',
'asciitilde', 'exclamdown', 'cent', 'sterling',
'fraction', 'yen', 'florin', 'section', 'currency', 'quotesingle', 'quotedblleft', 'guillemotleft',
'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'endash', 'dagger',
'daggerdbl', 'periodcentered', 'paragraph',
'bullet', 'quotesinglbase', 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', 'perthousand',
'questiondown', 'grave', 'acute', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent', 'dieresis', 'ring',
'cedilla', 'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine', 'Lslash', 'Oslash', 'OE',
'ordmasculine', 'ae', 'dotlessi', 'lslash', 'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu',
'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter', 'divide', 'brokenbar', 'degree', 'thorn',
'threequarters', 'twosuperior', 'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright',
'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde', 'Ccedilla', 'Eacute', 'Ecircumflex',
'Edieresis', 'Egrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex',
'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex', 'Udieresis', 'Ugrave', 'Yacute',
'Ydieresis', 'Zcaron', 'aacute', 'acircumflex', 'adieresis',
'agrave', 'aring', 'atilde', 'ccedilla', 'eacute',
'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex', 'idieresis', 'igrave', 'ntilde', 'oacute',
'ocircumflex', 'odieresis', 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', 'ugrave',
'yacute', 'ydieresis', 'zcaron', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', 'dollarsuperior',
'ampersandsmall', 'Acutesmall', 'parenleftsuperior', 'parenrightsuperior', '266 ff', 'onedotenleader',
'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle',
'fouroldstyle', 'fiveoldstyle', 'sixoldstyle',
'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'commasuperior', 'threequartersemdash', 'periodsuperior',
'questionsmall', 'asuperior', 'bsuperior', 'centsuperior',
'dsuperior', 'esuperior', 'isuperior', 'lsuperior',
'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', 'tsuperior', 'ff', 'ffi', 'ffl',
'parenleftinferior', 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', 'Asmall',
'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall',
'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall',
'Msmall', 'Nsmall', 'Osmall', 'Psmall', 'Qsmall', 'Rsmall',
'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall',
'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall',
'centoldstyle', 'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', 'Brevesmall', 'Caronsmall',
'Dotaccentsmall', 'Macronsmall', 'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall', 'Cedillasmall',
'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', 'seveneighths', 'onethird', 'twothirds',
'zerosuperior', 'foursuperior', 'fivesuperior', 'sixsuperior',
'sevensuperior', 'eightsuperior', 'ninesuperior',
'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior',
'fourinferior', 'fiveinferior', 'sixinferior',
'seveninferior', 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', 'periodinferior',
'commainferior', 'Agravesmall', 'Aacutesmall', 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall',
'Aringsmall', 'AEsmall', 'Ccedillasmall', 'Egravesmall',
'Eacutesmall', 'Ecircumflexsmall', 'Edieresissmall',
'Igravesmall', 'Iacutesmall', 'Icircumflexsmall',
'Idieresissmall', 'Ethsmall', 'Ntildesmall', 'Ogravesmall',
'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall',
'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall',
'Uacutesmall', 'Ucircumflexsmall', 'Udieresissmall',
'Yacutesmall', 'Thornsmall', 'Ydieresissmall', '001.000',
'001.001', '001.002', '001.003', 'Black', 'Bold',
'Book', 'Light', 'Medium', 'Regular', 'Roman', 'Semibold'
];
import cffStandardStrings from './cffStandardStrings';

/**
* 根据索引获取cff字符串
Expand Down
19 changes: 9 additions & 10 deletions src/ttf/table/cff/parseCFFGlyph.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,22 +252,20 @@ export default function parseCFFCharstring(code, font, index) {
haveWidth = true;
}
else if (stack.length === 4) {
glyfs[0] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()])};
glyfs[1] = {
glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]),
transform: {a: 1, b: 0, c: 0, d: 1, f: stack.pop(), e: stack.pop()}
};
glyfs[1] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}};
glyfs[0] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}};
glyfs[1].transform.f = stack.pop();
glyfs[1].transform.e = stack.pop();
}
else if (stack.length === 5) {
if (!haveWidth) {
width = stack.shift() + font.nominalWidthX;
}
haveWidth = true;
glyfs[0] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()])};
glyfs[1] = {
glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]),
transform: {a: 1, b: 0, c: 0, d: 1, f: stack.pop(), e: stack.pop()}
};
glyfs[1] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}};
glyfs[0] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}};
glyfs[1].transform.f = stack.pop();
glyfs[1].transform.e = stack.pop();
}

if (open) {
Expand Down Expand Up @@ -472,6 +470,7 @@ export default function parseCFFCharstring(code, font, index) {
advanceWidth: width
};
if (glyfs.length) {
glyf.compound = true;
glyf.glyfs = glyfs;
}
return glyf;
Expand Down
10 changes: 9 additions & 1 deletion src/ttf/table/glyf/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,15 @@ function parseCompoundGlyf(reader, glyf) {
};
}
else {
error.raise(10202);
g.points = [arg1, arg2];
g.transform = {
a: Math.round(10000 * scaleX / 16384) / 10000,
b: Math.round(10000 * scale01 / 16384) / 10000,
c: Math.round(10000 * scale10 / 16384) / 10000,
d: Math.round(10000 * scaleY / 16384) / 10000,
e: 0,
f: 0
};
}

glyf.glyfs.push(g);
Expand Down
11 changes: 6 additions & 5 deletions src/ttf/table/glyf/write.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,17 @@ export default function write(writer, ttf) {
if (glyf.compound) {

for (i = 0, l = glyf.glyfs.length; i < l; i++) {
let g = glyf.glyfs[i];

flags = componentFlag.ARGS_ARE_XY_VALUES
+ componentFlag.ROUND_XY_TO_GRID; // xy values
flags = g.points ? 0 :
(componentFlag.ARGS_ARE_XY_VALUES
+ componentFlag.ROUND_XY_TO_GRID); // xy values

// more components
if (i < l - 1) {
flags += componentFlag.MORE_COMPONENTS;
}

let g = glyf.glyfs[i];

// use my metrics
flags += g.useMyMetrics ? componentFlag.USE_MY_METRICS : 0;
Expand All @@ -58,8 +59,8 @@ export default function write(writer, ttf) {
let b = transform.b;
let c = transform.c;
let d = transform.d;
let e = transform.e;
let f = transform.f;
let e = g.points ? g.points[0] : transform.e;
let f = g.points ? g.points[1] : transform.f;

// xy values or points
// int 8 放不下,则用int16放
Expand Down

0 comments on commit d676f12

Please sign in to comment.