Skip to content

harfbuzz/harfbuzzjs

Repository files navigation

harfbuzzjs

harfbuzzjs Logo

Build NPM Version

Providing HarfBuzz shaping library for client/server side JavaScript projects.

See the demo here.

Building

  1. Install emscripten
  2. make

Testing

  1. make test

Download

Download from the releases tab.

Usage

TL;DR

import harfbuzz from "harfbuzzjs";
const hb = await harfbuzz;

const fontdata = await fetch('myfont.ttf').then(r => r.arrayBuffer());
const blob = new hb.Blob(fontdata);      // Load the font data into Harfbuzz blob
const face = new hb.Face(blob, 0);       // Select the first font in the file
const font = new hb.Font(face);          // Create a Harfbuzz font object from the face
const buffer = new hb.Buffer();          // Make a buffer to hold some text
buffer.addText('abc');                   // Fill it with some stuff
buffer.guessSegmentProperties();         // Set script, language and direction
hb.shape(font, buffer);                  // Shape the text
const output = buffer.getGlyphInfosAndPositions();

// Enumerate the glyphs
var xCursor = 0;
var yCursor = 0;
for (var glyph of output) {
    var glyphId = glyph.codepoint;
    var xAdvance = glyph.x_advance;
    var yAdvance = glyph.y_advance;
    var xDisplacement = glyph.x_offset;
    var yDisplacement = glyph.y_offset;

    var svgPath = font.glyphToPath(glyphId);
    // You need to supply this bit
    drawAGlyph(svgPath, xCursor + xDisplacement, yCursor + yDisplacement);

    xCursor += xAdvance;
    yCursor += yAdvance;
}

More examples:

Browser

  1. npx pad.js
  2. Open http://127.0.0.1/examples/harfbuzz.example.html

Node.js

  1. node examples/harfbuzz.example.node.js

Can be added with npm i harfbuzzjs or yarn add harfbuzzjs, see the examples for how to use it.

Need more of the library?

harfbuzzjs uses a stripped-down version of Harfbuzz generated by compiling Harfbuzz with -DHB_TINY. This may mean that some functions you need are not available. Look at src/hb-config.hh in the Harfbuzz source directory to see what has been removed. For example, HB_TINY defines HB_LEAN which (amongst other things) defines HB_NO_OT_GLYPH_NAMES. If, for example, you really need to get at the glyph names:

  1. First, undefine the macro in question, by adding e.g. #undef HB_NO_OT_GLYPH_NAMES to config-override.h.
  2. Next, export any function that you need by adding a line to harfbuzz.symbols; in this case _hb_ot_get_glyph_name.
  3. Now the function will be exported through the WASM object, but you need to add TypeScript to bridge to it - in this case, handling the memory allocation of the char * parameter name and marshalling it to a JavaScript string. The best way to do this is to look at the source files in src/ for functions which use similar signatures.

If you have extended harfbuzzjs in ways that you think others will also benefit from, please raise a pull request. If there are parts of Harfbuzz that you need but the instructions above don't work, describe what you are trying to do in an issue.

Using the library in a bigger emscripten project?

See harfbuzz port inside emscripten and emscripten-ports/HarfBuzz, basically all you need is to use -s USE_HARFBUZZ=1 in your build.

binaryen

Optionally you can install binaryen and use wasm-opt like:

wasm-opt -Oz hb.wasm -o hb.wasm

binaryen also provides wasm-dis which can be used for,

wasm-dis hb.wasm | grep export
wasm-dis hb.wasm | grep import

with that you can check if the built wasm file only exports things you need and doesn't need to import anything, as usual with wasm files built here.

About

Providing HarfBuzz shaping library for client/server side JavaScript projects

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors