Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7934384
Start load function
Mar 18, 2015
d4700c2
.load compiling and crashing
Mar 19, 2015
2101bef
upgrade node-pre-gyp
Mar 19, 2015
9971b02
convert test to async + check font exits
Mar 19, 2015
f598331
pass file_name string to baton
Mar 19, 2015
b5205b1
req is not heap allocated so no need to delete
Mar 19, 2015
5cf9c94
simplify + use more of Nan API in AfterLoad
Mar 19, 2015
b564fba
prep for handling multiface fonts + call FT_Done_Freetype
Mar 19, 2015
b6f8ab1
Start passing back FaceMetadata
Mar 19, 2015
0bfaf03
use emplace_back to construct objects in place
Mar 19, 2015
6b62495
node v0.12.x support
Mar 19, 2015
f177796
test on node v0.12.x + tweak travis script for simplicity
Mar 19, 2015
ac6f71f
code coverage
Mar 20, 2015
c173e1d
coverage: ignore node_modules and tests
Mar 20, 2015
76d1e0e
add coveralls badge [skip ci]
Mar 20, 2015
d93d777
Merge pull request #79 from mapbox/coverage
Mar 20, 2015
937d148
delete delete delete
Mar 20, 2015
41e3aa8
Merge branch 'overhaul' of github.com:mapbox/node-fontnik into overhaul
Mar 20, 2015
b1a1329
Make travis like my tests
Mar 20, 2015
1456f23
coverage: ignore protoc generated code
Mar 20, 2015
3efecf0
Use preexisting test fixture
Mar 20, 2015
f36a1b5
Merge branch 'overhaul' of github.com:mapbox/node-fontnik into overhaul
Mar 20, 2015
d87eb89
Docs
Mar 20, 2015
7bf1fce
travis plz test faster
Mar 20, 2015
0ca7fc8
Add a bit more coverage
Mar 20, 2015
b4ad2cf
gonna way semver this
Mar 20, 2015
90224b0
ignore missing coverage for failed FT_Init_FreeType
Mar 20, 2015
4b754af
test coverage of invalid font files
Mar 20, 2015
c687172
Change fontnik.range to wrap args into an options object
Mar 20, 2015
8a32e55
Split expected fontnik.load JSON into separate file
Mar 20, 2015
b773cff
Use set for codepoints, closes #67
Mar 20, 2015
09d4ba1
[wip] add benchmark scripts
Mar 20, 2015
43b3037
Add empty filepath test
Mar 20, 2015
8c3b3b1
Merge branch 'overhaul' of github.com:mapbox/node-fontnik into overhaul
Mar 20, 2015
8f742e1
use uname -s instead of undercased platform (for simplicity)
Mar 20, 2015
d67e56b
fix range usage in benchmark scripts
Mar 20, 2015
87fbd84
Loading faces from memory: super slow?
Mar 20, 2015
60593bd
fix bench scripts
Mar 21, 2015
7d39a04
minor optimizations and refactoring
Mar 23, 2015
d6035c4
Merge pull request #81 from mapbox/overhaul-memory
Mar 23, 2015
1b408bd
Memory leak fixes (wip)
Mar 23, 2015
c493204
Fix leaks
Mar 24, 2015
7cda0dd
Merge pull request #83 from mapbox/overhaul-memleaks
Mar 24, 2015
d66850d
goodbye boost libs
Mar 24, 2015
064085f
keep things simple: no need for glyphs.hpp to be in nested dir
Mar 24, 2015
a92a35b
silence boost warnings + fix header
Mar 24, 2015
feb4a46
shuffle includes: unordered_map is unused, cmath is
Mar 24, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 61 additions & 21 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,69 @@
language: cpp
os:
- linux
- osx
compiler:
- clang
- gcc

matrix:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a lot of value in gcc. So, I intentionally left it out to keep the matrix tight. If you feel differently, then sure, add an entry to run gcc on linux.

wrt to iojs, feel free to add, but node v0.12 is already covered.

include:
# Coverage
- os: osx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason this has to be osx? Would be quicker to run this as linux on slowtravis I would think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the clang++ on OS X works but @flippmoke found that the clang on travis linux boxes did not play well with coverage (likely some missing libraries). So, running on OS X is my recommendation for now (even though its a bit slow).

compiler: clang
env: NODE_VERSION="0.10" COVERAGE=true
# Linux
- os: linux
compiler: clang
env: NODE_VERSION="0.10"
- os: linux
compiler: clang
env: NODE_VERSION="0.12"
# OS X
- os: osx
compiler: clang
env: NODE_VERSION="0.10"
- os: osx
compiler: clang
env: NODE_VERSION="0.12"

env:
matrix:
- NODE_NVM_VERSION="0.8.26"
- NODE_NVM_VERSION="0.10"
global:
- BUILD: '/tmp/fontnik-build'
- PKG_CONFIG_PATH: '/tmp/fontnik-build/lib/pkgconfig'
- secure: "XV0lekmfgT+D9t0ZTIU+UJF6g+p3cBQMO6T6C9lkoKTC0YbtLtxSFtBahD/4PjL86DMJgTaf1nBmxqOxbrfkcpJUxnLe3r8u4Z2L/+7+QSACLNktlIfWNSO+33WxKNb4mVw6jMFZIo4ZurF016MXYzLzjpxRELW2oO2STUs2m44="
- secure: "CQNHbxw8yHlAdUVbKokHzHmj7C+duXP3mifWOkZm9GKw4myWsRFhhoSYZmOSkgj9EWfYYkedrqEr9+GaMg9rkVJuO/7jzn6S+M7CFXKJju6MoZEDO6WcFva4M8pw6IFb9q22GcQ+OsE8/i0DwchTokyFkNb3fpwWuwROUPQ/nWg="
- JOBS: "8"
- BUILD: '/tmp/fontnik-build'
- PKG_CONFIG_PATH: '/tmp/fontnik-build/lib/pkgconfig'
- secure: "XV0lekmfgT+D9t0ZTIU+UJF6g+p3cBQMO6T6C9lkoKTC0YbtLtxSFtBahD/4PjL86DMJgTaf1nBmxqOxbrfkcpJUxnLe3r8u4Z2L/+7+QSACLNktlIfWNSO+33WxKNb4mVw6jMFZIo4ZurF016MXYzLzjpxRELW2oO2STUs2m44="
- secure: "CQNHbxw8yHlAdUVbKokHzHmj7C+duXP3mifWOkZm9GKw4myWsRFhhoSYZmOSkgj9EWfYYkedrqEr9+GaMg9rkVJuO/7jzn6S+M7CFXKJju6MoZEDO6WcFva4M8pw6IFb9q22GcQ+OsE8/i0DwchTokyFkNb3fpwWuwROUPQ/nWg="

before_install:
- export platform=$(uname -s | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/")
- export PATH="$BUILD/bin:$PATH"
- if [[ "$platform" == "linux" ]]; then export CXX=g++-4.8; export CC=gcc-4.8; fi
- ./deps/nvm_install.sh
- ./deps/travis_build.sh
- export COVERAGE=${COVERAGE:-false}
# here we set up the node version on the fly based on the matrix value.
# This is done manually so that it is easy to flip the 'language' to
# objective-c in another branch (to run the same travis.yml on OS X)
- git clone https://github.com/creationix/nvm.git ../.nvm
- source ../.nvm/nvm.sh
- nvm install $NODE_VERSION
- nvm use $NODE_VERSION
- node --version
- npm --version
- if [[ ${COVERAGE} == true ]]; then
brew update;
brew install pyenv;
eval "$(pyenv init -)";
pyenv install 2.7.6;
pyenv global 2.7.6;
pyenv rehash;
pip install cpp-coveralls;
pyenv rehash;
fi;
- export PATH="$BUILD/bin:$PATH"
- ./deps/travis_build.sh

install:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we document why --clang=1 is needed here? I always forget.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- npm install --build-from-source
- if [[ ${COVERAGE} == true ]]; then
export LDFLAGS="--coverage" && export CXXFLAGS="--coverage" && npm install --build-from-source --debug --clang=1;
else
npm install --build-from-source --clang=1;
fi;

script:
- npm test
- npm test
- if [[ ${COVERAGE} == true ]]; then cpp-coveralls --exclude node_modules --exclude tests --build-root build --gcov-options '\-lp' --exclude doc --exclude build/Debug/obj/gen; fi;

after_success:
- ./deps/travis_publish.sh
- ./deps/travis_publish.sh

43 changes: 11 additions & 32 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,19 @@

### `range(options: object, callback: function)`

`options` is an object with options:

Get a range of glyphs as a protocol buffer. `options` is an object with options:
* `file: string`
* `start: number`
* `end: number`
* `fontstack: ?string`

Get a range of glyphs as a gzipped protocol buffer.

### `conf(options: object)`

`options` is an object with options:

* `fonts: Array<string>`

Configure node-fontnik.

### `getRange(start: number, end: number): Array<number>`

Generate an array of the numbers from `start` to `end`. `start` must be
less than `end` and both numbers must be in the inclusive range 0 to 65535.

### `faces(): Array<string>`

Return an array of supported font faces, as strings.

## `new fontnik.Glyphs()`

Create a new Glyphs object.

### `glyphs.codepoints(face: string): Array<number>`

Get an array of numbers corresponding to unicode points where this font face
has coverage.
`file` is the path to a font file on disk.]

### `glyphs.range(face: string, range: string, chars: Array<number>, callback: function)`
### `load(fontpath: string, callback: function)`

### `glyphs.serialize(): Buffer`
Read a font's metadata. Returns an object like
``` json
"family_name": "Open Sans",
"style_name": "Regular",
"points": [32,33,34,35…]
```
where `points` is an array of numbers corresponding to unicode points where this font face has coverage.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# node-fontnik

[![NPM](https://nodei.co/npm/fontnik.png?compact=true)](https://nodei.co/npm/fontnik/) [![Build Status](https://travis-ci.org/mapbox/node-fontnik.svg?branch=master)](https://travis-ci.org/mapbox/node-fontnik)
[![NPM](https://nodei.co/npm/fontnik.png?compact=true)](https://nodei.co/npm/fontnik/)
[![Build Status](https://travis-ci.org/mapbox/node-fontnik.svg?branch=master)](https://travis-ci.org/mapbox/node-fontnik)
[![Coverage Status](https://coveralls.io/repos/mapbox/node-fontnik/badge.svg?branch=coverage)](https://coveralls.io/r/mapbox/node-fontnik?branch=coverage)

A library that delivers a range of glyphs rendered as SDFs (signed distance fields) in a protocol buffer. We use these encoded glyphs as the basic blocks of font rendering in [Mapbox GL](https://github.com/mapbox/mapbox-gl-js). SDF encoding is superior to traditional fonts for our usecase terms of scaling, rotation, and quickly deriving halos - WebGL doesn't have built-in font rendering, so the decision is between vectorization, which tends to be slow, and SDF generation.

Expand Down
49 changes: 49 additions & 0 deletions bench/bench.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';

var path = require('path');
var fontnik = require('../');
var queue = require('queue-async');
var fs = require('fs');

// https://gist.github.com/mourner/96b1335c6a43e68af252
// https://gist.github.com/fengmk2/4345606
function now() {
var hr = process.hrtime();
return hr[0] + hr[1] / 1e9;
}

function bench(opts,cb) {
var q = queue(opts.concurrency);
var start = now();
for (var i = 1; i <= opts.iterations; i++) {
q.defer.apply({},opts.args);
}
q.awaitAll(function(error, results) {
var seconds = now() - start;
console.log(opts.name, Math.round(opts.iterations / (seconds)),'ops/sec',opts.iterations,opts.concurrency);
return cb();
});
}

function main() {
var opensans = fs.readFileSync(path.resolve(__dirname + '/../fonts/open-sans/OpenSans-Regular.ttf'));

var suite = queue(1);
suite.defer(bench, {
name:"fontnik.load",
args:[fontnik.load,opensans],
iterations: 10,
concurrency: 10
});
suite.defer(bench, {
name:"fontnik.range",
args:[fontnik.range,{font:opensans,start:0,end:256}],
iterations: 1000,
concurrency: 100
});
suite.awaitAll(function(err) {
if (err) throw err;
})
}

main();
38 changes: 38 additions & 0 deletions bench/bench2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

var path = require('path');
var fontnik = require('../');
var Benchmark = require('benchmark');
var fs = require('fs');

var opensans = fs.readFileSync(path.resolve(__dirname + '/../fonts/open-sans/OpenSans-Regular.ttf'));

var suite = new Benchmark.Suite();

suite
.add('fontnik.load', {
'defer': true,
'fn': function(deferred) {
// avoid test inlining
suite.name;
fontnik.load(opensans,function(err) {
if (err) throw err;
deferred.resolve();
});
}
})
.add('fontnik.range', {
'defer': true,
'fn': function(deferred) {
// avoid test inlining
suite.name;
fontnik.range({font:opensans,start:0,end:256},function(err) {
if (err) throw err;
deferred.resolve();
});
}
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.run({async:true});
12 changes: 0 additions & 12 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,17 @@
'src/node_fontnik.cpp',
'src/glyphs.cpp',
'vendor/agg/src/agg_curves.cpp',
'vendor/fontnik/src/glyphs.cpp',
'vendor/fontnik/src/face.cpp',
'vendor/mapnik/src/debug.cpp',
'vendor/mapnik/src/font_engine_freetype.cpp',
'vendor/mapnik/src/font_set.cpp',
'vendor/mapnik/src/fs.cpp',
'vendor/mapnik/src/text/face_set.cpp',
'<(SHARED_INTERMEDIATE_DIR)/glyphs.pb.cc'
],
'include_dirs': [
'./include',
'./vendor/agg/include',
'./vendor/fontnik/include',
'./vendor/mapnik/include',
'./vendor/node_mapnik/include',
'<(SHARED_INTERMEDIATE_DIR)/',
'<!@(pkg-config freetype2 --cflags-only-I | sed s/-I//g)',
'<!@(pkg-config protobuf --cflags-only-I | sed s/-I//g)',
"<!(node -e \"require('nan')\")"
],
'libraries': [
'-lboost_system',
'-lboost_filesystem',
'<!@(pkg-config freetype2 --libs --static)',
'<!@(pkg-config protobuf --libs --static)'
],
Expand Down
11 changes: 0 additions & 11 deletions deps/nvm_install.sh

This file was deleted.

4 changes: 2 additions & 2 deletions deps/travis_publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
set -e

# Inspect binary.
if [ $platform == "linux" ]; then
if [[ $(uname -s) == "Linux" ]]; then
ldd ./lib/fontnik.node
else
otool -L ./lib/fontnik.node
fi

COMMIT_MESSAGE=$(git show -s --format=%B $TRAVIS_COMMIT | tr -d '\n')

if test "${COMMIT_MESSAGE#*'[publish binary]'}" != "$COMMIT_MESSAGE"
if test "${COMMIT_MESSAGE#*'[publish binary]'}" != "$COMMIT_MESSAGE" && [[ ${COVERAGE} == false ]];
then

npm install aws-sdk
Expand Down
34 changes: 0 additions & 34 deletions include/node_fontnik/glyphs.hpp

This file was deleted.

37 changes: 1 addition & 36 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,36 +1 @@
var zlib = require('zlib');
var path = require('path');
var util = require('util');
var fontnik = require('./lib/fontnik.node');

module.exports = fontnik;
module.exports.range = range;
module.exports.getRange = getRange;

// Retrieve a range of glyphs as a pbf.
function range(options, callback) {
'use strict';
options = options || {};
options.fontstack = options.fontstack || 'Open Sans Regular';

var glyphs = new fontnik.Glyphs();
glyphs.range(options.fontstack, options.start + '-' + options.end, getRange(options.start, options.end), gzip);

function gzip(err) {
if (err) return callback(err);
var after = glyphs.serialize();
zlib.gzip(after, callback);
}
}

function getRange(start, end) {
if (typeof start !== 'number') throw new Error('start must be a number from 0-65535');
if (start < 0) throw new Error('start must be a number from 0-65535');
if (typeof end !== 'number') throw new Error('end must be a number from 0-65535');
if (end > 65535) throw new Error('end must be a number from 0-65535');
if (start > end) throw new Error('start must be less than or equal to end');
var range = [];
for (var i = start; i <= end; i++) range.push(i);
return range;
}

module.exports = require('./lib/fontnik.node');
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fontnik",
"version": "0.2.6",
"version": "1.0.0",
"description": "A library that delivers a range of glyphs rendered as SDFs (signed distance fields) in a protobuf.",
"keywords": [
"font",
Expand All @@ -23,9 +23,10 @@
}
],
"dependencies": {
"benchmark": "^1.0.0",
"minimist": "^0.2.0",
"nan": "^1.2.0",
"node-pre-gyp": "^0.5.31",
"nan": "^1.7.0",
"node-pre-gyp": "~0.6.4",
"queue-async": "^1.0.7"
},
"bundledDependencies": [
Expand Down
Loading