Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Experience-Monks/opentype-layout
word wraps and lays out Opentype.js glyphs
https://github.com/Experience-Monks/opentype-layout
Last synced: 28 days ago
JSON representation
word wraps and lays out Opentype.js glyphs
- Host: GitHub
- URL: https://github.com/Experience-Monks/opentype-layout
- Owner: Experience-Monks
- License: mit
- Created: 2016-06-21T16:09:52.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2016-06-21T19:08:33.000Z (over 8 years ago)
- Last Synced: 2024-11-14T09:19:11.383Z (28 days ago)
- Language: JavaScript
- Homepage: https://jam3.github.io/opentype-layout/
- Size: 406 KB
- Stars: 89
- Watchers: 15
- Forks: 11
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-typography - opentype-layout - Experimental word-wrapping and layout for OpenType.js. (JavaScript)
README
# opentype-layout
[![experimental](http://badges.github.io/stability-badges/dist/experimental.svg)](http://github.com/badges/stability-badges)
Experimental word-wrapping and layout for [Opentype.js](https://github.com/nodebox/opentype.js).
## Install
Best used with npm and browserify. This should also work in Node.js and other environments.
```sh
npm install opentype-layout --save
```## Demo
[Live Demo](https://jam3.github.io/opentype-layout/)
The demo shows Canvas2D vector text (red stroke) rendered on top of DOM/CSS (black fill). The demo reads the computed CSS style and converts units into the proper EM font units. Some lines also visualize some of the available metrics.
[](https://jam3.github.io/opentype-layout/)
## Example
See the [demo](./demo) folder for a complete example.
```js
var opentype = require('opentype.js');
var computeLayout = require('opentype-layout');opentype.load('Font.ttf', function (err, font) {
if (err) throw err;var fontSizePx = 72;
var text = 'Hello\nWorld! This box should start word-wrapping!'
var scale = 1 / font.unitsPerEm * fontSizePx;// Layout some text - notice everything is in em units!
var result = computeLayout(font, text, {
lineHeight: 2.5 * font.unitsPerEm, // '2.5em' in font units
width: 500 / scale // '500px' in font units
});// Array of characters after layout
console.log(result.glyphs);// Computed height after word-wrap
console.log(result.height);
});
```## Usage
#### `layout = computeLayout(font, text, [opt])`
Computes a new layout from the given Opentype.js `Font` interface and a `text` string.
All units should be in raw font units in the EM square, assuming a lower-left origin. For example, a `lineHeight` of `'2em'` should be passed as `2 * font.unitsPerEm`. It is up to the user to scale the results to a pixel/point size after the fact.
Options:
- `width` the width of the box in font units, will cause word-wrapping (default `Infinity`)
- `align` string alignment of the text within its `width` (default `'left'`)
- `letterSpacing` the additional letter spacing in font units (default 0)
- `lineHeight` the line height in font units as per CSS spec, default `1.175 * font.unitsPerEm` to match browsers
- `start` the starting character index into `text` to layout, default 0
- `end` the ending index into `text` to layout (exclusive), default `text.length`
- `mode` can be 'pre' (maintain spacing), or 'nowrap' (collapse whitespace but only break on newline characters), otherwise defaults to normal word-wrap behaviourSee [word-wrapper](https://www.npmjs.com/package/word-wrapper) for details on how word wrapping is computed.
## Metrics
The returned object has the following metrics.
#### `layout.glyphs`
This provides an array of characters after layout, useful for rendering. Each element in the array has the following properties:
```js
{
position: [ x, y ],
data: { ... Opentype.js Glyph object ... },
index: charIndex,
row: lineIndex,
column: columnInLineIndex
}
```The position is in raw font units.
#### `layout.baseline`
This is the value from pen origin to the baseline of the last line of text in the layout.
#### `layout.leading`
This is the `L` value in the [CSS line-height spec](https://www.w3.org/TR/CSS2/visudet.html#line-height). Divide this by two for the "half-leading", which tells you how far above the first ascender and below the last descender the text box extends to.
#### `layout.lines`
This is an array of line objects with the following properties:
```js
{
start: startCharIndex, // inclusive
end: endCharIndex, // exclusive
width: lineWidth // in font units
}
```#### `layout.lineHeight`
This is the computed `lineHeight` in font units. If no `lineHeight` is specified in options, it will be equivalent to `1.175 * font.unitsPerEm`.
#### `layout.left`
This is the distance from the left of the text box to the widest line of text in the box. This is zero when `align` is left, but changes with other alignments.
#### `layout.right`
This is the distance from the right of the box to the widest line of text in the box. This is zero when `align` is right, but changes with other alignments.
#### `layout.width`
The width of the text box. If no `opt.width` is passed, this will equal `layout.maxLineWidth` (i.e. length of a single line of text). If `opt.width` is passed, this value should equal it.
#### `layout.height`
The height of the text box, including the half leadings above the first ascender and below the last descender.
#### `layout.maxLineWidth`
This is the maximum line width in all lines. This can be used to determine the "real" width of the text box after word wrap, instead of the `layout.width` which may be larger.
## TODOs
This module is not yet finished — below are some areas that need improvement. PRs welcome.
- `'center'` and `'right'` alignment do not match exactly with DOM/CSS
- Tab characters are not yet handled
- Undefined characters are not yet handled gracefully
- Word wrap algorithm is naïve and does not always match DOM/CSS
- Mainly suited for Latin left-to-right text, does not handle CTL## License
MIT, see [LICENSE.md](http://github.com/Jam3/opentype-layout/blob/master/LICENSE.md) for details.