diff --git a/README.md b/README.md index 6c1bda0..aa9b90c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ # harfbuzzjs
-

harfbuzzjs Logo

- -[![Build](https://github.com/harfbuzz/harfbuzzjs/actions/workflows/build.yml/badge.svg)](https://github.com/harfbuzz/harfbuzzjs/actions/workflows/build.yml) -[![NPM Version](https://img.shields.io/npm/v/harfbuzzjs)](https://www.npmjs.com/package/harfbuzzjs) +

harfbuzzjs Logo

+ [![Build](https://github.com/harfbuzz/harfbuzzjs/actions/workflows/build.yml/badge.svg)](https://github.com/harfbuzz/harfbuzzjs/actions/workflows/build.yml) + [![NPM Version](https://img.shields.io/npm/v/harfbuzzjs)](https://www.npmjs.com/package/harfbuzzjs)
Providing [HarfBuzz](https://github.com/harfbuzz/harfbuzz) shaping @@ -13,69 +12,77 @@ library for client/server side JavaScript projects. See the demo [here](https://harfbuzz.github.io/harfbuzzjs/demo/). -## Building -1. Install emscripten -2. `make` +## Download -## Testing -1. `make test` +From the repo's [releases](https://github.com/harfbuzz/harfbuzzjs/releases), or npm: -## Download -Download from the [releases tab](https://github.com/harfbuzz/harfbuzzjs/releases). +``` +npm install harfbuzzjs +``` ## Migrating from v0.x -The v1 release introduced several API-breaking changes. See [MIGRATING](MIGRATING.md) for migrating from v0.x. -## Usage +The v1 release introduced several API-breaking changes. See [MIGRATING](MIGRATING.md) for migrating from v0.x. -### TL;DR +## Usage examples -```javascript +```js import * as hb from "harfbuzzjs"; -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.xAdvance; - var yAdvance = glyph.yAdvance; - var xDisplacement = glyph.xOffset; - var yDisplacement = glyph.yOffset; - - var svgPath = font.glyphToPath(glyphId); - // You need to supply this bit - drawAGlyph(svgPath, xCursor + xDisplacement, yCursor + yDisplacement); - - xCursor += xAdvance; - yCursor += yAdvance; +// Load data from a font file: +const response = await fetch("font.ttf"); +const arrayBuffer = await response.arrayBuffer(); + +// Create a HarfBuzz font object from the data: +const blob = new hb.Blob(arrayBuffer); +const face = new hb.Face(blob); +const font = new hb.Font(face); + +// Shape text in a HarfBuzz buffer with the font: +const buffer = new hb.Buffer(); +buffer.addText("abc"); +buffer.guessSegmentProperties(); +hb.shape(font, buffer); + +// Enumerate the resulted glyphs in the buffer: +const infos = buffer.getGlyphInfos(); +const positions = buffer.getGlyphPositions(); +for (const [index, glyph] of infos.entries()) { + const gid = glyph.codepoint; // Glyph ID despite the property name + console.log( + font.glyphToPath(gid), // SVG path + positions[index], // xAdvance, yAdvance, xOffset, yOffset + ); } ``` -More examples: +### Alternative browser example + +See [examples/harfbuzz.example.html](examples/harfbuzz.example.html). To quickly run it in a browser: + +``` +npx http-server -o /examples/harfbuzz.example.html +``` + +### Node.js example -### Browser +See [examples/harfbuzz.example.node.js](examples/harfbuzz.example.node.js). -1. `npx pad.js` -2. Open `http://127.0.0.1/examples/harfbuzz.example.html` +## Development -### Node.js +### Building -1. `node examples/harfbuzz.example.node.js` +First install [emscripten](https://emscripten.org), then: -## [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. +``` +make +``` + +### Testing + +``` +make test +``` ## Need more of the library? diff --git a/examples/harfbuzz.example.node.js b/examples/harfbuzz.example.node.js index e78d83c..ca06bd8 100644 --- a/examples/harfbuzz.example.node.js +++ b/examples/harfbuzz.example.node.js @@ -1,29 +1,30 @@ import fs from "node:fs"; import path from "node:path"; -import { fileURLToPath } from "node:url"; -import { Blob, Face, Font, Buffer, shape } from "../dist/index.mjs"; +import * as hb from "harfbuzzjs"; -const __dirname = path.dirname(fileURLToPath(import.meta.url)); +// Load data from a font file: +const nodeBuffer = fs.readFileSync( + path.join(import.meta.dirname, "../test/fonts/noto/NotoSans-Regular.ttf"), +); -function example(fontPath, text) { - var blob = new Blob(fs.readFileSync(fontPath)); - var face = new Face(blob, 0); - var font = new Font(face); +// Create a HarfBuzz font object from the data: +const blob = new hb.Blob(nodeBuffer); +const face = new hb.Face(blob); +const font = new hb.Font(face); - var buffer = new Buffer(); - buffer.addText(text || "abc"); - buffer.guessSegmentProperties(); - shape(font, buffer); +// Shape text in a HarfBuzz buffer with the font: +const buffer = new hb.Buffer(); +buffer.addText("abc"); +buffer.guessSegmentProperties(); +hb.shape(font, buffer); - return buffer.getGlyphInfosAndPositions(); +// Enumerate the resulted glyphs in the buffer: +const infos = buffer.getGlyphInfos(); +const positions = buffer.getGlyphPositions(); +for (const [index, glyph] of infos.entries()) { + const gid = glyph.codepoint; // Glyph ID despite the property name + console.log( + font.glyphToPath(gid), // SVG path + positions[index], // xAdvance, yAdvance, xOffset, yOffset + ); } - -console.log( - example(path.resolve(__dirname, "../test/fonts/noto/NotoSans-Regular.ttf")), -); -console.log( - example( - path.resolve(__dirname, "../test/fonts/noto/NotoSansArabic-Variable.ttf"), - "أبجد", - ), -);