opentype.js
Advanced tools
Comparing version 0.5.1 to 0.6.0
{ | ||
"name": "opentype.js", | ||
"version": "0.5.1", | ||
"version": "0.6.0", | ||
"main": "dist/opentype.js", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -52,3 +52,3 @@ # Contributing | ||
npm dist | ||
npm run dist | ||
@@ -55,0 +55,0 @@ This compiles the source and places `opentype.js` and `opentype.min.js` in the `dist` folder. |
@@ -8,1 +8,7 @@ OpenType.js Examples | ||
Then navigate to one of the examples, e.g.: http://localhost:8080/examples/reading-writing.html | ||
The `generate-font-node.js` example can be run from node.js: | ||
cd opentype.js/examples | ||
node generate-font-node.js | ||
# This generates a font file, called Pyramid-Regular.otf. |
{ | ||
"name": "opentype.js", | ||
"description": "OpenType font parser", | ||
"version": "0.5.1", | ||
"version": "0.6.0", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "Frederik De Bleser", |
@@ -95,7 +95,2 @@ opentype.js | ||
// Note that the .notdef glyph is required. | ||
var notdefPath = new opentype.Path(); | ||
notdefPath.moveTo(100, 0); | ||
notdefPath.lineTo(100, 700); | ||
// more drawing instructions.... | ||
var notdefGlyph = new opentype.Glyph({ | ||
@@ -105,3 +100,3 @@ name: '.notdef', | ||
advanceWidth: 650, | ||
path: notdefPath | ||
path: new opentype.Path(); | ||
}); | ||
@@ -121,7 +116,13 @@ | ||
var glyphs = [notdefGlyph, aGlyph]; | ||
var font = new opentype.Font({familyName: 'OpenTypeSans', styleName: 'Medium', unitsPerEm: 1000, glyphs: glyphs}); | ||
var font = new opentype.Font({ | ||
familyName: 'OpenTypeSans', | ||
styleName: 'Medium', | ||
unitsPerEm: 1000, | ||
ascender: 800, | ||
descender: -200, | ||
glyphs: glyphs}); | ||
font.download(); | ||
If you want to inspect the font, use `font.toTables()` to generate an object showing the data structures that map | ||
directly to binary values. If you want to get an `ArrayBuffer`, use `font.toBuffer()`. | ||
directly to binary values. If you want to get an `ArrayBuffer`, use `font.toArrayBuffer()`. | ||
@@ -128,0 +129,0 @@ |
@@ -0,1 +1,6 @@ | ||
0.6.0 (December 1, 2015) | ||
======================== | ||
* Improvements to font writing: generated fonts now work properly on OS X. | ||
* When creating a new font, ascender and descender are now required. | ||
0.5.1 (October 26, 2015) | ||
@@ -2,0 +7,0 @@ ======================== |
@@ -9,2 +9,3 @@ // The Font object | ||
var glyphset = require('./glyphset'); | ||
var util = require('./util'); | ||
@@ -17,20 +18,33 @@ // A Font represents a loaded OpenType font file. | ||
// OS X will complain if the names are empty, so we put a single space everywhere by default. | ||
this.names = { | ||
fontFamily: {en: options.familyName || ' '}, | ||
fontSubfamily: {en: options.styleName || ' '}, | ||
designer: {en: options.designer || ' '}, | ||
designerURL: {en: options.designerURL || ' '}, | ||
manufacturer: {en: options.manufacturer || ' '}, | ||
manufacturerURL: {en: options.manufacturerURL || ' '}, | ||
license: {en: options.license || ' '}, | ||
licenseURL: {en: options.licenseURL || ' '}, | ||
version: {en: options.version || 'Version 0.1'}, | ||
description: {en: options.description || ' '}, | ||
copyright: {en: options.copyright || ' '}, | ||
trademark: {en: options.trademark || ' '} | ||
}; | ||
this.unitsPerEm = options.unitsPerEm || 1000; | ||
this.ascender = options.ascender; | ||
this.descender = options.descender; | ||
if (!options.empty) { | ||
// Check that we've provided the minimum set of names. | ||
util.checkArgument(options.familyName, 'When creating a new Font object, familyName is required.'); | ||
util.checkArgument(options.styleName, 'When creating a new Font object, styleName is required.'); | ||
util.checkArgument(options.unitsPerEm, 'When creating a new Font object, unitsPerEm is required.'); | ||
util.checkArgument(options.ascender, 'When creating a new Font object, ascender is required.'); | ||
util.checkArgument(options.descender, 'When creating a new Font object, descender is required.'); | ||
util.checkArgument(options.descender < 0, 'Descender should be negative (e.g. -512).'); | ||
// OS X will complain if the names are empty, so we put a single space everywhere by default. | ||
this.names = { | ||
fontFamily: {en: options.familyName || ' '}, | ||
fontSubfamily: {en: options.styleName || ' '}, | ||
fullName: {en: options.fullName || options.familyName + ' ' + options.styleName}, | ||
postScriptName: {en: options.postScriptName || options.familyName + options.styleName}, | ||
designer: {en: options.designer || ' '}, | ||
designerURL: {en: options.designerURL || ' '}, | ||
manufacturer: {en: options.manufacturer || ' '}, | ||
manufacturerURL: {en: options.manufacturerURL || ' '}, | ||
license: {en: options.license || ' '}, | ||
licenseURL: {en: options.licenseURL || ' '}, | ||
version: {en: options.version || 'Version 0.1'}, | ||
description: {en: options.description || ' '}, | ||
copyright: {en: options.copyright || ' '}, | ||
trademark: {en: options.trademark || ' '} | ||
}; | ||
this.unitsPerEm = options.unitsPerEm || 1000; | ||
this.ascender = options.ascender; | ||
this.descender = options.descender; | ||
} | ||
this.supported = true; // Deprecated: parseBuffer will throw an error if font is not supported. | ||
@@ -270,2 +284,7 @@ this.glyphs = new glyphset.GlyphSet(this, options.glyphs || []); | ||
Font.prototype.toBuffer = function() { | ||
console.warn('Font.toBuffer is deprecated. Use Font.toArrayBuffer instead.'); | ||
return this.toArrayBuffer(); | ||
}; | ||
Font.prototype.toArrayBuffer = function() { | ||
var sfntTable = this.toTables(); | ||
@@ -287,25 +306,30 @@ var bytes = sfntTable.encode(); | ||
var fileName = familyName.replace(/\s/g, '') + '-' + styleName + '.otf'; | ||
var buffer = this.toBuffer(); | ||
var arrayBuffer = this.toArrayBuffer(); | ||
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; | ||
window.requestFileSystem(window.TEMPORARY, buffer.byteLength, function(fs) { | ||
fs.root.getFile(fileName, {create: true}, function(fileEntry) { | ||
fileEntry.createWriter(function(writer) { | ||
var dataView = new DataView(buffer); | ||
var blob = new Blob([dataView], {type: 'font/opentype'}); | ||
writer.write(blob); | ||
if (util.isBrowser()) { | ||
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; | ||
window.requestFileSystem(window.TEMPORARY, arrayBuffer.byteLength, function(fs) { | ||
fs.root.getFile(fileName, {create: true}, function(fileEntry) { | ||
fileEntry.createWriter(function(writer) { | ||
var dataView = new DataView(arrayBuffer); | ||
var blob = new Blob([dataView], {type: 'font/opentype'}); | ||
writer.write(blob); | ||
writer.addEventListener('writeend', function() { | ||
// Navigating to the file will download it. | ||
location.href = fileEntry.toURL(); | ||
}, false); | ||
writer.addEventListener('writeend', function() { | ||
// Navigating to the file will download it. | ||
location.href = fileEntry.toURL(); | ||
}, false); | ||
}); | ||
}); | ||
}, | ||
function(err) { | ||
throw err; | ||
}); | ||
}, | ||
function(err) { | ||
throw err; | ||
}); | ||
} else { | ||
var fs = require('fs'); | ||
var buffer = util.arrayBufferToNodeBuffer(arrayBuffer); | ||
fs.writeFileSync(fileName, buffer); | ||
} | ||
}; | ||
exports.Font = Font; |
@@ -6,3 +6,3 @@ // opentype.js | ||
/* global ArrayBuffer, DataView, Uint8Array, XMLHttpRequest */ | ||
/* global DataView, Uint8Array, XMLHttpRequest */ | ||
@@ -18,2 +18,3 @@ 'use strict'; | ||
var path = require('./path'); | ||
var util = require('./util'); | ||
@@ -38,13 +39,2 @@ var cmap = require('./tables/cmap'); | ||
// Convert a Node.js Buffer to an ArrayBuffer | ||
function toArrayBuffer(buffer) { | ||
var arrayBuffer = new ArrayBuffer(buffer.length); | ||
var data = new Uint8Array(arrayBuffer); | ||
for (var i = 0; i < buffer.length; i += 1) { | ||
data[i] = buffer[i]; | ||
} | ||
return arrayBuffer; | ||
} | ||
function loadFromFile(path, callback) { | ||
@@ -57,3 +47,3 @@ var fs = require('fs'); | ||
callback(null, toArrayBuffer(buffer)); | ||
callback(null, util.nodeBufferToArrayBuffer(buffer)); | ||
}); | ||
@@ -139,7 +129,9 @@ } | ||
// Since the constructor can also be called to create new fonts from scratch, we indicate this | ||
// should be an empty font that we'll fill with our own data. | ||
var font = new _font.Font({empty: true}); | ||
// OpenType fonts use big endian byte ordering. | ||
// We can't rely on typed array view types, because they operate with the endianness of the host computer. | ||
// Instead we use DataViews where we can specify endianness. | ||
var font = new _font.Font(); | ||
var data = new DataView(buffer, 0); | ||
@@ -314,3 +306,3 @@ var numTables; | ||
var buffer = fs.readFileSync(url); | ||
return parseBuffer(toArrayBuffer(buffer)); | ||
return parseBuffer(util.nodeBufferToArrayBuffer(buffer)); | ||
} | ||
@@ -317,0 +309,0 @@ |
@@ -1038,10 +1038,2 @@ // The `CFF` table contains the glyph outlines in PostScript format. | ||
function makePrivateDictIndex(privateDict) { | ||
var t = new table.Table('Private DICT INDEX', [ | ||
{name: 'privateDicts', type: 'INDEX', value: []} | ||
]); | ||
t.privateDicts = [{name: 'privateDict_0', type: 'TABLE', value: privateDict}]; | ||
return t; | ||
} | ||
function makeCFFTable(glyphs, options) { | ||
@@ -1056,3 +1048,3 @@ var t = new table.Table('CFF ', [ | ||
{name: 'charStringsIndex', type: 'TABLE'}, | ||
{name: 'privateDictIndex', type: 'TABLE'} | ||
{name: 'privateDict', type: 'TABLE'} | ||
]); | ||
@@ -1069,2 +1061,3 @@ | ||
weight: options.weightName, | ||
fontBBox: options.fontBBox || [0, 0, 0, 0], | ||
fontMatrix: [fontScale, 0, 0, fontScale, 0, 0], | ||
@@ -1097,4 +1090,3 @@ charset: 999, | ||
t.charStringsIndex = makeCharStringsIndex(glyphs); | ||
var privateDict = makePrivateDict(privateAttrs, strings); | ||
t.privateDictIndex = makePrivateDictIndex(privateDict); | ||
t.privateDict = makePrivateDict(privateAttrs, strings); | ||
@@ -1101,0 +1093,0 @@ // Needs to come at the end, to encode all custom strings used in the font. |
@@ -30,3 +30,3 @@ // The `head` table contains global information about the font. | ||
head.fontDirectionHint = p.parseShort(); | ||
head.indexToLocFormat = p.parseShort(); // 50 | ||
head.indexToLocFormat = p.parseShort(); | ||
head.glyphDataFormat = p.parseShort(); | ||
@@ -33,0 +33,0 @@ return head; |
@@ -27,4 +27,4 @@ // The `name` naming table. | ||
'designerURL', // 12 | ||
'licence', // 13 | ||
'licenceURL', // 14 | ||
'license', // 13 | ||
'licenseURL', // 14 | ||
'reserved', // 15 | ||
@@ -31,0 +31,0 @@ 'preferredFamily', // 16 |
@@ -197,2 +197,3 @@ // The `sfnt` wrapper provides organization for the tables in the font. | ||
var headTable = head.make({ | ||
flags: 3, // 00000011 (baseline for font at y=0; left sidebearing point at x=0) | ||
unitsPerEm: font.unitsPerEm, | ||
@@ -202,3 +203,4 @@ xMin: globals.xMin, | ||
xMax: globals.xMax, | ||
yMax: globals.yMax | ||
yMax: globals.yMax, | ||
lowestRecPPEM: 3 | ||
}); | ||
@@ -228,2 +230,3 @@ | ||
ulUnicodeRange4: ulUnicodeRange4, | ||
fsSelection: 64, // REGULAR | ||
// See http://typophile.com/node/13081 for more info on vertical metrics. | ||
@@ -236,6 +239,8 @@ // We get metrics for typical characters (such as "x" for xHeight). | ||
sTypoLineGap: 0, | ||
usWinAscent: globals.ascender, | ||
usWinDescent: -globals.descender, | ||
sxHeight: metricsForChar(font, 'xyvw', {yMax: 0}).yMax, | ||
usWinAscent: globals.yMax, | ||
usWinDescent: Math.abs(globals.yMin), | ||
ulCodePageRange1: 1, // FIXME: hard-code Latin 1 support for now | ||
sxHeight: metricsForChar(font, 'xyvw', {yMax: Math.round(globals.ascender / 2)}).yMax, | ||
sCapHeight: metricsForChar(font, 'HIKLEFJMNTZBDPRAGOQSUVWXY', globals).yMax, | ||
usDefaultChar: font.hasChar(' ') ? 32 : 0, // Use space as the default character, if available. | ||
usBreakChar: font.hasChar(' ') ? 32 : 0 // Use space as the break character, if available. | ||
@@ -287,3 +292,4 @@ }); | ||
postScriptName: postScriptName, | ||
unitsPerEm: font.unitsPerEm | ||
unitsPerEm: font.unitsPerEm, | ||
fontBBox: [0, globals.yMin, globals.ascender, globals.advanceWidthMax] | ||
}); | ||
@@ -290,0 +296,0 @@ |
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
1359363
63
21473
257
19