Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/harfbuzz/harfbuzzjs
Providing HarfBuzz shaping library for client/server side JavaScript projects
https://github.com/harfbuzz/harfbuzzjs
harfbuzz javascript nodejs opentype wasm
Last synced: about 1 month ago
JSON representation
Providing HarfBuzz shaping library for client/server side JavaScript projects
- Host: GitHub
- URL: https://github.com/harfbuzz/harfbuzzjs
- Owner: harfbuzz
- License: other
- Created: 2019-04-19T14:42:50.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2024-03-24T15:41:46.000Z (6 months ago)
- Last Synced: 2024-04-22T14:23:45.356Z (5 months ago)
- Topics: harfbuzz, javascript, nodejs, opentype, wasm
- Language: JavaScript
- Homepage: https://harfbuzz.github.io/harfbuzzjs/
- Size: 3.39 MB
- Stars: 175
- Watchers: 17
- Forks: 31
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# harfbuzzjs
Providing [HarfBuzz](https://github.com/harfbuzz/harfbuzz) shaping
library for client/server side JavaScript projects.See the demo [here](https://harfbuzz.github.io/harfbuzzjs/).
## Building
1. Install emscripten
2. `./build.sh`## Download
Download the pack from [releases tab](https://github.com/harfbuzz/harfbuzzjs/releases)
of the project, or just download the [demo page](https://harfbuzz.github.io/harfbuzzjs/) (the
demo source is in [gh-pages](https://github.com/harfbuzz/harfbuzzjs/tree/gh-pages) branch).## Usage and testing
### TL;DR
```javascript
hb = require("hbjs.js")
WebAssembly.instantiateStreaming(fetch("hb.wasm")).then(function (result) {
fetch('myfont.ttf').then(function (data) {
return data.arrayBuffer();
}).then(function (fontdata) {
var blob = hb.createBlob(fontdata); // Load the font data into something Harfbuzz can use
var face = hb.createFace(blob, 0); // Select the first font in the file (there's normally only one!)
var font = hb.createFont(face); // Create a Harfbuzz font object from the face
var buffer = hb.createBuffer(); // 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, determining glyph IDs and positions
var output = buffer.json();// Enumerate the glyphs
var xCursor = 0;
var yCursor = 0;
for (glyph of output) {
var glyphId = glyph.g;
var xAdvance = glyph.ax;
var xDisplacement = glyph.dx;
var yDisplacement = glyph.dy;var svgPath = font.glyphToPath(glyphId);
// You need to supply this bit
drawAGlyph(svgPath, xCursor + xDisplacement, yDisplacement);xCursor += xAdvance;
}// Release memory
buffer.destroy();
font.destroy();
face.destroy();
blob.destroy();
})
})
```More examples:
### Browser
1. `npx pad.js`
2. Open `http://127.0.0.1/examples/hbjs.example.html` or `http://127.0.0.1/examples/nohbjs.html`### Node.js
1. `(cd examples && node hbjs.example.node.js)`
We provide a tiny wrapper (`hbjs.js`) around the main functionality of harfbuzz, but it's also easy to use other parts. (See `example/nohbjs.js` as an example. However, you may need a custom build to expose additional functionality.)
## [npm](https://www.npmjs.com/package/harfbuzzjs)
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 `hbjs.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 Javascript to bridge to it - in this case, handling the memory allocation of the `char *` parameter `name` and marshalling it to a JavaScript string with `heapu8.subarray`. The best way to do this is to look at `hbjs.js` 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](https://github.com/emscripten-core/emscripten/blob/master/tools/ports/harfbuzz.py)
and [emscripten-ports/HarfBuzz](https://github.com/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.