opentype.js
Advanced tools
Comparing version 0.6.2 to 0.6.3
{ | ||
"name": "opentype.js", | ||
"version": "0.6.2", | ||
"version": "0.6.3", | ||
"main": "dist/opentype.js", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
{ | ||
"name": "opentype.js", | ||
"description": "OpenType font parser", | ||
"version": "0.6.2", | ||
"version": "0.6.3", | ||
"author": { | ||
@@ -35,11 +35,11 @@ "name": "Frederik De Bleser", | ||
"devDependencies": { | ||
"browserify": "^9.0.3", | ||
"jscs": "^1.12.0", | ||
"jshint": "^2.8.0", | ||
"browserify": "^13.0.1", | ||
"jscs": "^3.0.3", | ||
"jshint": "^2.9.2", | ||
"mkdirp": "^0.5.1", | ||
"mocha": "^2.2.5", | ||
"parallelshell": "^1.1.1", | ||
"rimraf": "^2.4.0", | ||
"mocha": "^2.4.5", | ||
"parallelshell": "^2.0.0", | ||
"rimraf": "^2.5.2", | ||
"uglifyify": "^3.0.1", | ||
"watchify": "^2.6.0" | ||
"watchify": "^3.7.0" | ||
}, | ||
@@ -50,4 +50,4 @@ "browser": { | ||
"dependencies": { | ||
"tiny-inflate": "^1.0.1" | ||
"tiny-inflate": "^1.0.2" | ||
} | ||
} |
@@ -99,3 +99,3 @@ opentype.js | ||
advanceWidth: 650, | ||
path: new opentype.Path(); | ||
path: new opentype.Path() | ||
}); | ||
@@ -102,0 +102,0 @@ |
@@ -0,1 +1,6 @@ | ||
0.6.3 (May 10, 2016) | ||
========================= | ||
* Wrapped parseBuffer in a try/catch so it doesn't throw exceptions. Thanks @rBurgett! | ||
* Fix a leaking global variable. Thanks @cuixiping! | ||
0.6.2 (March 11, 2016) | ||
@@ -2,0 +7,0 @@ ========================= |
@@ -170,26 +170,26 @@ // Glyph encoding | ||
switch (post.version) { | ||
case 1: | ||
this.names = exports.standardNames.slice(); | ||
break; | ||
case 2: | ||
this.names = new Array(post.numberOfGlyphs); | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
if (post.glyphNameIndex[i] < exports.standardNames.length) { | ||
this.names[i] = exports.standardNames[post.glyphNameIndex[i]]; | ||
} else { | ||
this.names[i] = post.names[post.glyphNameIndex[i] - exports.standardNames.length]; | ||
case 1: | ||
this.names = exports.standardNames.slice(); | ||
break; | ||
case 2: | ||
this.names = new Array(post.numberOfGlyphs); | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
if (post.glyphNameIndex[i] < exports.standardNames.length) { | ||
this.names[i] = exports.standardNames[post.glyphNameIndex[i]]; | ||
} else { | ||
this.names[i] = post.names[post.glyphNameIndex[i] - exports.standardNames.length]; | ||
} | ||
} | ||
} | ||
break; | ||
case 2.5: | ||
this.names = new Array(post.numberOfGlyphs); | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
this.names[i] = exports.standardNames[i + post.glyphNameIndex[i]]; | ||
} | ||
break; | ||
case 2.5: | ||
this.names = new Array(post.numberOfGlyphs); | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
this.names[i] = exports.standardNames[i + post.glyphNameIndex[i]]; | ||
} | ||
break; | ||
case 3: | ||
this.names = []; | ||
break; | ||
break; | ||
case 3: | ||
this.names = []; | ||
break; | ||
} | ||
@@ -196,0 +196,0 @@ } |
@@ -175,62 +175,62 @@ // opentype.js | ||
switch (tableEntry.tag) { | ||
case 'cmap': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.cmap = cmap.parse(table.data, table.offset); | ||
font.encoding = new encoding.CmapEncoding(font.tables.cmap); | ||
break; | ||
case 'fvar': | ||
fvarTableEntry = tableEntry; | ||
break; | ||
case 'head': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.head = head.parse(table.data, table.offset); | ||
font.unitsPerEm = font.tables.head.unitsPerEm; | ||
indexToLocFormat = font.tables.head.indexToLocFormat; | ||
break; | ||
case 'hhea': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.hhea = hhea.parse(table.data, table.offset); | ||
font.ascender = font.tables.hhea.ascender; | ||
font.descender = font.tables.hhea.descender; | ||
font.numberOfHMetrics = font.tables.hhea.numberOfHMetrics; | ||
break; | ||
case 'hmtx': | ||
hmtxTableEntry = tableEntry; | ||
break; | ||
case 'ltag': | ||
table = uncompressTable(data, tableEntry); | ||
ltagTable = ltag.parse(table.data, table.offset); | ||
break; | ||
case 'maxp': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.maxp = maxp.parse(table.data, table.offset); | ||
font.numGlyphs = font.tables.maxp.numGlyphs; | ||
break; | ||
case 'name': | ||
nameTableEntry = tableEntry; | ||
break; | ||
case 'OS/2': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.os2 = os2.parse(table.data, table.offset); | ||
break; | ||
case 'post': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.post = post.parse(table.data, table.offset); | ||
font.glyphNames = new encoding.GlyphNames(font.tables.post); | ||
break; | ||
case 'glyf': | ||
glyfTableEntry = tableEntry; | ||
break; | ||
case 'loca': | ||
locaTableEntry = tableEntry; | ||
break; | ||
case 'CFF ': | ||
cffTableEntry = tableEntry; | ||
break; | ||
case 'kern': | ||
kernTableEntry = tableEntry; | ||
break; | ||
case 'GPOS': | ||
gposTableEntry = tableEntry; | ||
break; | ||
case 'cmap': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.cmap = cmap.parse(table.data, table.offset); | ||
font.encoding = new encoding.CmapEncoding(font.tables.cmap); | ||
break; | ||
case 'fvar': | ||
fvarTableEntry = tableEntry; | ||
break; | ||
case 'head': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.head = head.parse(table.data, table.offset); | ||
font.unitsPerEm = font.tables.head.unitsPerEm; | ||
indexToLocFormat = font.tables.head.indexToLocFormat; | ||
break; | ||
case 'hhea': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.hhea = hhea.parse(table.data, table.offset); | ||
font.ascender = font.tables.hhea.ascender; | ||
font.descender = font.tables.hhea.descender; | ||
font.numberOfHMetrics = font.tables.hhea.numberOfHMetrics; | ||
break; | ||
case 'hmtx': | ||
hmtxTableEntry = tableEntry; | ||
break; | ||
case 'ltag': | ||
table = uncompressTable(data, tableEntry); | ||
ltagTable = ltag.parse(table.data, table.offset); | ||
break; | ||
case 'maxp': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.maxp = maxp.parse(table.data, table.offset); | ||
font.numGlyphs = font.tables.maxp.numGlyphs; | ||
break; | ||
case 'name': | ||
nameTableEntry = tableEntry; | ||
break; | ||
case 'OS/2': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.os2 = os2.parse(table.data, table.offset); | ||
break; | ||
case 'post': | ||
table = uncompressTable(data, tableEntry); | ||
font.tables.post = post.parse(table.data, table.offset); | ||
font.glyphNames = new encoding.GlyphNames(font.tables.post); | ||
break; | ||
case 'glyf': | ||
glyfTableEntry = tableEntry; | ||
break; | ||
case 'loca': | ||
locaTableEntry = tableEntry; | ||
break; | ||
case 'CFF ': | ||
cffTableEntry = tableEntry; | ||
break; | ||
case 'kern': | ||
kernTableEntry = tableEntry; | ||
break; | ||
case 'GPOS': | ||
gposTableEntry = tableEntry; | ||
break; | ||
} | ||
@@ -293,4 +293,8 @@ } | ||
} | ||
var font = parseBuffer(arrayBuffer); | ||
var font; | ||
try { | ||
font = parseBuffer(arrayBuffer); | ||
} catch (e) { | ||
return callback(e, null); | ||
} | ||
return callback(null, font); | ||
@@ -300,3 +304,3 @@ }); | ||
// Syncronously load the font from a URL or file. | ||
// Synchronously load the font from a URL or file. | ||
// When done, return the font object or throw an error. | ||
@@ -303,0 +307,0 @@ function loadSync(url) { |
@@ -422,197 +422,217 @@ // The `CFF` table contains the glyph outlines in PostScript format. | ||
switch (v) { | ||
case 1: // hstem | ||
parseStems(); | ||
break; | ||
case 3: // vstem | ||
parseStems(); | ||
break; | ||
case 4: // vmoveto | ||
if (stack.length > 1 && !haveWidth) { | ||
width = stack.shift() + font.nominalWidthX; | ||
haveWidth = true; | ||
} | ||
case 1: // hstem | ||
parseStems(); | ||
break; | ||
case 3: // vstem | ||
parseStems(); | ||
break; | ||
case 4: // vmoveto | ||
if (stack.length > 1 && !haveWidth) { | ||
width = stack.shift() + font.nominalWidthX; | ||
haveWidth = true; | ||
} | ||
y += stack.pop(); | ||
newContour(x, y); | ||
break; | ||
case 5: // rlineto | ||
while (stack.length > 0) { | ||
x += stack.shift(); | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
} | ||
y += stack.pop(); | ||
newContour(x, y); | ||
break; | ||
case 5: // rlineto | ||
while (stack.length > 0) { | ||
x += stack.shift(); | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
} | ||
break; | ||
case 6: // hlineto | ||
while (stack.length > 0) { | ||
x += stack.shift(); | ||
p.lineTo(x, y); | ||
if (stack.length === 0) { | ||
break; | ||
break; | ||
case 6: // hlineto | ||
while (stack.length > 0) { | ||
x += stack.shift(); | ||
p.lineTo(x, y); | ||
if (stack.length === 0) { | ||
break; | ||
} | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
} | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
} | ||
break; | ||
case 7: // vlineto | ||
while (stack.length > 0) { | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
if (stack.length === 0) { | ||
break; | ||
} | ||
break; | ||
case 7: // vlineto | ||
while (stack.length > 0) { | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
if (stack.length === 0) { | ||
break; | ||
x += stack.shift(); | ||
p.lineTo(x, y); | ||
} | ||
x += stack.shift(); | ||
p.lineTo(x, y); | ||
} | ||
break; | ||
case 8: // rrcurveto | ||
while (stack.length > 0) { | ||
c1x = x + stack.shift(); | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y + stack.shift(); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
break; | ||
case 8: // rrcurveto | ||
while (stack.length > 0) { | ||
c1x = x + stack.shift(); | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y + stack.shift(); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
break; | ||
case 10: // callsubr | ||
codeIndex = stack.pop() + font.subrsBias; | ||
subrCode = font.subrs[codeIndex]; | ||
if (subrCode) { | ||
parse(subrCode); | ||
} | ||
break; | ||
case 10: // callsubr | ||
codeIndex = stack.pop() + font.subrsBias; | ||
subrCode = font.subrs[codeIndex]; | ||
if (subrCode) { | ||
parse(subrCode); | ||
} | ||
break; | ||
case 11: // return | ||
return; | ||
case 12: // flex operators | ||
v = code[i]; | ||
i += 1; | ||
switch (v) { | ||
case 35: // flex | ||
// |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd flex (12 35) |- | ||
c1x = x + stack.shift(); // dx1 | ||
c1y = y + stack.shift(); // dy1 | ||
c2x = c1x + stack.shift(); // dx2 | ||
c2y = c1y + stack.shift(); // dy2 | ||
jpx = c2x + stack.shift(); // dx3 | ||
jpy = c2y + stack.shift(); // dy3 | ||
c3x = jpx + stack.shift(); // dx4 | ||
c3y = jpy + stack.shift(); // dy4 | ||
c4x = c3x + stack.shift(); // dx5 | ||
c4y = c3y + stack.shift(); // dy5 | ||
x = c4x + stack.shift(); // dx6 | ||
y = c4y + stack.shift(); // dy6 | ||
stack.shift(); // flex depth | ||
p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy); | ||
p.curveTo(c3x, c3y, c4x, c4y, x, y); | ||
break; | ||
case 34: // hflex | ||
// |- dx1 dx2 dy2 dx3 dx4 dx5 dx6 hflex (12 34) |- | ||
c1x = x + stack.shift(); // dx1 | ||
c1y = y; // dy1 | ||
c2x = c1x + stack.shift(); // dx2 | ||
c2y = c1y + stack.shift(); // dy2 | ||
jpx = c2x + stack.shift(); // dx3 | ||
jpy = c2y; // dy3 | ||
c3x = jpx + stack.shift(); // dx4 | ||
c3y = c2y; // dy4 | ||
c4x = c3x + stack.shift(); // dx5 | ||
c4y = y; // dy5 | ||
x = c4x + stack.shift(); // dx6 | ||
p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy); | ||
p.curveTo(c3x, c3y, c4x, c4y, x, y); | ||
break; | ||
case 36: // hflex1 | ||
// |- dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6 hflex1 (12 36) |- | ||
c1x = x + stack.shift(); // dx1 | ||
c1y = y + stack.shift(); // dy1 | ||
c2x = c1x + stack.shift(); // dx2 | ||
c2y = c1y + stack.shift(); // dy2 | ||
jpx = c2x + stack.shift(); // dx3 | ||
jpy = c2y; // dy3 | ||
c3x = jpx + stack.shift(); // dx4 | ||
c3y = c2y; // dy4 | ||
c4x = c3x + stack.shift(); // dx5 | ||
c4y = c3y + stack.shift(); // dy5 | ||
x = c4x + stack.shift(); // dx6 | ||
p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy); | ||
p.curveTo(c3x, c3y, c4x, c4y, x, y); | ||
break; | ||
case 37: // flex1 | ||
// |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6 flex1 (12 37) |- | ||
c1x = x + stack.shift(); // dx1 | ||
c1y = y + stack.shift(); // dy1 | ||
c2x = c1x + stack.shift(); // dx2 | ||
c2y = c1y + stack.shift(); // dy2 | ||
jpx = c2x + stack.shift(); // dx3 | ||
jpy = c2y + stack.shift(); // dy3 | ||
c3x = jpx + stack.shift(); // dx4 | ||
c3y = jpy + stack.shift(); // dy4 | ||
c4x = c3x + stack.shift(); // dx5 | ||
c4y = c3y + stack.shift(); // dy5 | ||
if (Math.abs(c4x - x) > Math.abs(c4y - y)) { | ||
x = c4x + stack.shift(); | ||
} else { | ||
y = c4y + stack.shift(); | ||
} | ||
break; | ||
case 11: // return | ||
return; | ||
case 12: // flex operators | ||
v = code[i]; | ||
i += 1; | ||
switch (v) { | ||
case 35: // flex | ||
// |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd flex (12 35) |- | ||
c1x = x + stack.shift(); // dx1 | ||
c1y = y + stack.shift(); // dy1 | ||
c2x = c1x + stack.shift(); // dx2 | ||
c2y = c1y + stack.shift(); // dy2 | ||
jpx = c2x + stack.shift(); // dx3 | ||
jpy = c2y + stack.shift(); // dy3 | ||
c3x = jpx + stack.shift(); // dx4 | ||
c3y = jpy + stack.shift(); // dy4 | ||
c4x = c3x + stack.shift(); // dx5 | ||
c4y = c3y + stack.shift(); // dy5 | ||
x = c4x + stack.shift(); // dx6 | ||
y = c4y + stack.shift(); // dy6 | ||
stack.shift(); // flex depth | ||
p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy); | ||
p.curveTo(c3x, c3y, c4x, c4y, x, y); | ||
p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy); | ||
p.curveTo(c3x, c3y, c4x, c4y, x, y); | ||
break; | ||
default: | ||
console.log('Glyph ' + glyph.index + ': unknown operator ' + 1200 + v); | ||
stack.length = 0; | ||
} | ||
break; | ||
case 34: // hflex | ||
// |- dx1 dx2 dy2 dx3 dx4 dx5 dx6 hflex (12 34) |- | ||
c1x = x + stack.shift(); // dx1 | ||
c1y = y; // dy1 | ||
c2x = c1x + stack.shift(); // dx2 | ||
c2y = c1y + stack.shift(); // dy2 | ||
jpx = c2x + stack.shift(); // dx3 | ||
jpy = c2y; // dy3 | ||
c3x = jpx + stack.shift(); // dx4 | ||
c3y = c2y; // dy4 | ||
c4x = c3x + stack.shift(); // dx5 | ||
c4y = y; // dy5 | ||
x = c4x + stack.shift(); // dx6 | ||
p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy); | ||
p.curveTo(c3x, c3y, c4x, c4y, x, y); | ||
case 14: // endchar | ||
if (stack.length > 0 && !haveWidth) { | ||
width = stack.shift() + font.nominalWidthX; | ||
haveWidth = true; | ||
} | ||
if (open) { | ||
p.closePath(); | ||
open = false; | ||
} | ||
break; | ||
case 36: // hflex1 | ||
// |- dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6 hflex1 (12 36) |- | ||
c1x = x + stack.shift(); // dx1 | ||
c1y = y + stack.shift(); // dy1 | ||
c2x = c1x + stack.shift(); // dx2 | ||
c2y = c1y + stack.shift(); // dy2 | ||
jpx = c2x + stack.shift(); // dx3 | ||
jpy = c2y; // dy3 | ||
c3x = jpx + stack.shift(); // dx4 | ||
c3y = c2y; // dy4 | ||
c4x = c3x + stack.shift(); // dx5 | ||
c4y = c3y + stack.shift(); // dy5 | ||
x = c4x + stack.shift(); // dx6 | ||
p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy); | ||
p.curveTo(c3x, c3y, c4x, c4y, x, y); | ||
case 18: // hstemhm | ||
parseStems(); | ||
break; | ||
case 37: // flex1 | ||
// |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6 flex1 (12 37) |- | ||
c1x = x + stack.shift(); // dx1 | ||
c1y = y + stack.shift(); // dy1 | ||
c2x = c1x + stack.shift(); // dx2 | ||
c2y = c1y + stack.shift(); // dy2 | ||
jpx = c2x + stack.shift(); // dx3 | ||
jpy = c2y + stack.shift(); // dy3 | ||
c3x = jpx + stack.shift(); // dx4 | ||
c3y = jpy + stack.shift(); // dy4 | ||
c4x = c3x + stack.shift(); // dx5 | ||
c4y = c3y + stack.shift(); // dy5 | ||
if (Math.abs(c4x - x) > Math.abs(c4y - y)) { | ||
x = c4x + stack.shift(); | ||
} else { | ||
y = c4y + stack.shift(); | ||
case 19: // hintmask | ||
case 20: // cntrmask | ||
parseStems(); | ||
i += (nStems + 7) >> 3; | ||
break; | ||
case 21: // rmoveto | ||
if (stack.length > 2 && !haveWidth) { | ||
width = stack.shift() + font.nominalWidthX; | ||
haveWidth = true; | ||
} | ||
p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy); | ||
p.curveTo(c3x, c3y, c4x, c4y, x, y); | ||
y += stack.pop(); | ||
x += stack.pop(); | ||
newContour(x, y); | ||
break; | ||
default: | ||
console.log('Glyph ' + glyph.index + ': unknown operator ' + 1200 + v); | ||
stack.length = 0; | ||
} | ||
break; | ||
case 14: // endchar | ||
if (stack.length > 0 && !haveWidth) { | ||
width = stack.shift() + font.nominalWidthX; | ||
haveWidth = true; | ||
} | ||
case 22: // hmoveto | ||
if (stack.length > 1 && !haveWidth) { | ||
width = stack.shift() + font.nominalWidthX; | ||
haveWidth = true; | ||
} | ||
if (open) { | ||
p.closePath(); | ||
open = false; | ||
} | ||
x += stack.pop(); | ||
newContour(x, y); | ||
break; | ||
case 23: // vstemhm | ||
parseStems(); | ||
break; | ||
case 24: // rcurveline | ||
while (stack.length > 2) { | ||
c1x = x + stack.shift(); | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y + stack.shift(); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
break; | ||
case 18: // hstemhm | ||
parseStems(); | ||
break; | ||
case 19: // hintmask | ||
case 20: // cntrmask | ||
parseStems(); | ||
i += (nStems + 7) >> 3; | ||
break; | ||
case 21: // rmoveto | ||
if (stack.length > 2 && !haveWidth) { | ||
width = stack.shift() + font.nominalWidthX; | ||
haveWidth = true; | ||
} | ||
x += stack.shift(); | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
break; | ||
case 25: // rlinecurve | ||
while (stack.length > 6) { | ||
x += stack.shift(); | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
} | ||
y += stack.pop(); | ||
x += stack.pop(); | ||
newContour(x, y); | ||
break; | ||
case 22: // hmoveto | ||
if (stack.length > 1 && !haveWidth) { | ||
width = stack.shift() + font.nominalWidthX; | ||
haveWidth = true; | ||
} | ||
x += stack.pop(); | ||
newContour(x, y); | ||
break; | ||
case 23: // vstemhm | ||
parseStems(); | ||
break; | ||
case 24: // rcurveline | ||
while (stack.length > 2) { | ||
c1x = x + stack.shift(); | ||
@@ -625,136 +645,116 @@ c1y = y + stack.shift(); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
break; | ||
case 26: // vvcurveto | ||
if (stack.length % 2) { | ||
x += stack.shift(); | ||
} | ||
x += stack.shift(); | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
break; | ||
case 25: // rlinecurve | ||
while (stack.length > 6) { | ||
x += stack.shift(); | ||
y += stack.shift(); | ||
p.lineTo(x, y); | ||
} | ||
while (stack.length > 0) { | ||
c1x = x; | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x; | ||
y = c2y + stack.shift(); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
c1x = x + stack.shift(); | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y + stack.shift(); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
break; | ||
case 26: // vvcurveto | ||
if (stack.length % 2) { | ||
x += stack.shift(); | ||
} | ||
break; | ||
case 27: // hhcurveto | ||
if (stack.length % 2) { | ||
y += stack.shift(); | ||
} | ||
while (stack.length > 0) { | ||
c1x = x; | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x; | ||
y = c2y + stack.shift(); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
while (stack.length > 0) { | ||
c1x = x + stack.shift(); | ||
c1y = y; | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y; | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
break; | ||
case 27: // hhcurveto | ||
if (stack.length % 2) { | ||
y += stack.shift(); | ||
} | ||
break; | ||
case 28: // shortint | ||
b1 = code[i]; | ||
b2 = code[i + 1]; | ||
stack.push(((b1 << 24) | (b2 << 16)) >> 16); | ||
i += 2; | ||
break; | ||
case 29: // callgsubr | ||
codeIndex = stack.pop() + font.gsubrsBias; | ||
subrCode = font.gsubrs[codeIndex]; | ||
if (subrCode) { | ||
parse(subrCode); | ||
} | ||
while (stack.length > 0) { | ||
c1x = x + stack.shift(); | ||
c1y = y; | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y; | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
break; | ||
case 30: // vhcurveto | ||
while (stack.length > 0) { | ||
c1x = x; | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y + (stack.length === 1 ? stack.shift() : 0); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
if (stack.length === 0) { | ||
break; | ||
} | ||
break; | ||
case 28: // shortint | ||
b1 = code[i]; | ||
b2 = code[i + 1]; | ||
stack.push(((b1 << 24) | (b2 << 16)) >> 16); | ||
i += 2; | ||
break; | ||
case 29: // callgsubr | ||
codeIndex = stack.pop() + font.gsubrsBias; | ||
subrCode = font.gsubrs[codeIndex]; | ||
if (subrCode) { | ||
parse(subrCode); | ||
} | ||
break; | ||
case 30: // vhcurveto | ||
while (stack.length > 0) { | ||
c1x = x; | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y + (stack.length === 1 ? stack.shift() : 0); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
if (stack.length === 0) { | ||
break; | ||
c1x = x + stack.shift(); | ||
c1y = y; | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
y = c2y + stack.shift(); | ||
x = c2x + (stack.length === 1 ? stack.shift() : 0); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
c1x = x + stack.shift(); | ||
c1y = y; | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
y = c2y + stack.shift(); | ||
x = c2x + (stack.length === 1 ? stack.shift() : 0); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
break; | ||
case 31: // hvcurveto | ||
while (stack.length > 0) { | ||
c1x = x + stack.shift(); | ||
c1y = y; | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
y = c2y + stack.shift(); | ||
x = c2x + (stack.length === 1 ? stack.shift() : 0); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
if (stack.length === 0) { | ||
break; | ||
} | ||
break; | ||
case 31: // hvcurveto | ||
while (stack.length > 0) { | ||
c1x = x + stack.shift(); | ||
c1y = y; | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
y = c2y + stack.shift(); | ||
x = c2x + (stack.length === 1 ? stack.shift() : 0); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
if (stack.length === 0) { | ||
break; | ||
c1x = x; | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y + (stack.length === 1 ? stack.shift() : 0); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
c1x = x; | ||
c1y = y + stack.shift(); | ||
c2x = c1x + stack.shift(); | ||
c2y = c1y + stack.shift(); | ||
x = c2x + stack.shift(); | ||
y = c2y + (stack.length === 1 ? stack.shift() : 0); | ||
p.curveTo(c1x, c1y, c2x, c2y, x, y); | ||
} | ||
break; | ||
default: | ||
if (v < 32) { | ||
console.log('Glyph ' + glyph.index + ': unknown operator ' + v); | ||
} else if (v < 247) { | ||
stack.push(v - 139); | ||
} else if (v < 251) { | ||
b1 = code[i]; | ||
i += 1; | ||
stack.push((v - 247) * 256 + b1 + 108); | ||
} else if (v < 255) { | ||
b1 = code[i]; | ||
i += 1; | ||
stack.push(-(v - 251) * 256 - b1 - 108); | ||
} else { | ||
b1 = code[i]; | ||
b2 = code[i + 1]; | ||
b3 = code[i + 2]; | ||
b4 = code[i + 3]; | ||
i += 4; | ||
stack.push(((b1 << 24) | (b2 << 16) | (b3 << 8) | b4) / 65536); | ||
} | ||
break; | ||
default: | ||
if (v < 32) { | ||
console.log('Glyph ' + glyph.index + ': unknown operator ' + v); | ||
} else if (v < 247) { | ||
stack.push(v - 139); | ||
} else if (v < 251) { | ||
b1 = code[i]; | ||
i += 1; | ||
stack.push((v - 247) * 256 + b1 + 108); | ||
} else if (v < 255) { | ||
b1 = code[i]; | ||
i += 1; | ||
stack.push(-(v - 251) * 256 - b1 - 108); | ||
} else { | ||
b1 = code[i]; | ||
b2 = code[i + 1]; | ||
b3 = code[i + 2]; | ||
b4 = code[i + 3]; | ||
i += 4; | ||
stack.push(((b1 << 24) | (b2 << 16) | (b3 << 8) | b4) / 65536); | ||
} | ||
} | ||
@@ -761,0 +761,0 @@ } |
@@ -135,3 +135,3 @@ // The `fvar` table stores font variation axes and instances. | ||
return {axes:axes, instances:instances}; | ||
return {axes: axes, instances: instances}; | ||
} | ||
@@ -138,0 +138,0 @@ |
@@ -31,4 +31,3 @@ // The `GPOS` table contains kerning pairs, among other things. | ||
return p.parseUShortList(count); | ||
} | ||
else if (format === 2) { | ||
} else if (format === 2) { | ||
var coverage = []; | ||
@@ -61,4 +60,3 @@ for (; count--;) { | ||
}; | ||
} | ||
else if (format === 2) { | ||
} else if (format === 2) { | ||
// Format 2 defines multiple groups of glyph indices that belong to the same class. | ||
@@ -143,4 +141,3 @@ var rangeCount = p.parseUShort(); | ||
}; | ||
} | ||
else if (format === 2) { | ||
} else if (format === 2) { | ||
// Pair Positioning Adjustment: Format 2 | ||
@@ -147,0 +144,0 @@ var classDef1Offset = p.parseUShort(); |
@@ -532,16 +532,16 @@ // The `name` naming table. | ||
switch (platformID) { | ||
case 0: // Unicode | ||
if (languageID === 0xFFFF) { | ||
return 'und'; | ||
} else if (ltag) { | ||
return ltag[languageID]; | ||
} | ||
case 0: // Unicode | ||
if (languageID === 0xFFFF) { | ||
return 'und'; | ||
} else if (ltag) { | ||
return ltag[languageID]; | ||
} | ||
break; | ||
break; | ||
case 1: // Macintosh | ||
return macLanguages[languageID]; | ||
case 1: // Macintosh | ||
return macLanguages[languageID]; | ||
case 3: // Windows | ||
return windowsLanguages[languageID]; | ||
case 3: // Windows | ||
return windowsLanguages[languageID]; | ||
} | ||
@@ -614,14 +614,14 @@ | ||
switch (platformID) { | ||
case 0: // Unicode | ||
return utf16; | ||
case 0: // Unicode | ||
return utf16; | ||
case 1: // Apple Macintosh | ||
return macLanguageEncodings[languageID] || macScriptEncodings[encodingID]; | ||
case 1: // Apple Macintosh | ||
return macLanguageEncodings[languageID] || macScriptEncodings[encodingID]; | ||
case 3: // Microsoft Windows | ||
if (encodingID === 1 || encodingID === 10) { | ||
return utf16; | ||
} | ||
case 3: // Microsoft Windows | ||
if (encodingID === 1 || encodingID === 10) { | ||
return utf16; | ||
} | ||
break; | ||
break; | ||
} | ||
@@ -628,0 +628,0 @@ |
@@ -25,29 +25,29 @@ // The `post` table stores additional PostScript information, such as glyph names. | ||
switch (post.version) { | ||
case 1: | ||
post.names = encoding.standardNames.slice(); | ||
break; | ||
case 2: | ||
post.numberOfGlyphs = p.parseUShort(); | ||
post.glyphNameIndex = new Array(post.numberOfGlyphs); | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
post.glyphNameIndex[i] = p.parseUShort(); | ||
} | ||
case 1: | ||
post.names = encoding.standardNames.slice(); | ||
break; | ||
case 2: | ||
post.numberOfGlyphs = p.parseUShort(); | ||
post.glyphNameIndex = new Array(post.numberOfGlyphs); | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
post.glyphNameIndex[i] = p.parseUShort(); | ||
} | ||
post.names = []; | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
if (post.glyphNameIndex[i] >= encoding.standardNames.length) { | ||
var nameLength = p.parseChar(); | ||
post.names.push(p.parseString(nameLength)); | ||
post.names = []; | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
if (post.glyphNameIndex[i] >= encoding.standardNames.length) { | ||
var nameLength = p.parseChar(); | ||
post.names.push(p.parseString(nameLength)); | ||
} | ||
} | ||
} | ||
break; | ||
case 2.5: | ||
post.numberOfGlyphs = p.parseUShort(); | ||
post.offset = new Array(post.numberOfGlyphs); | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
post.offset[i] = p.parseChar(); | ||
} | ||
break; | ||
case 2.5: | ||
post.numberOfGlyphs = p.parseUShort(); | ||
post.offset = new Array(post.numberOfGlyphs); | ||
for (i = 0; i < post.numberOfGlyphs; i++) { | ||
post.offset[i] = p.parseChar(); | ||
} | ||
break; | ||
break; | ||
} | ||
@@ -54,0 +54,0 @@ return post; |
@@ -150,2 +150,7 @@ // The `sfnt` wrapper provides organization for the tables in the font. | ||
var unicode = glyph.unicode | 0; | ||
if (typeof glyph.advanceWidth === 'undefined') { | ||
throw new Error('Glyph ' + glyph.name + ' (' + i + '): advanceWidth is required.'); | ||
} | ||
if (firstCharIndex > unicode || firstCharIndex === null) { | ||
@@ -152,0 +157,0 @@ firstCharIndex = unicode; |
@@ -43,2 +43,27 @@ 'use strict'; | ||
it('handles a parseBuffer error', function(done) { | ||
opentype.load('./fonts/badfont.ttf', function(err) { | ||
if (err) { | ||
done(); | ||
} | ||
}); | ||
}); | ||
it('throws an error when advanceWidth is not set', function() { | ||
var notdefGlyph = new opentype.Glyph({ | ||
name: '.notdef', | ||
unicode: 0, | ||
path: new opentype.Path() | ||
}); | ||
var font = new opentype.Font({ | ||
familyName: 'MyFont', | ||
styleName: 'Medium', | ||
unitsPerEm: 1000, | ||
ascender: 800, | ||
descender: -200, | ||
glyphs: [notdefGlyph] | ||
}); | ||
assert.throws(function() { font.toArrayBuffer(); }, /advanceWidth is required/); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
709713
64
12849
Updatedtiny-inflate@^1.0.2