Experimental word-wrapping and layout for Opentype.js.
Best used with npm and browserify. This should also work in Node.js and other environments.
npm install opentype-layout-improved --save
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.
See the demo folder for a complete example.
var opentype = ;var computeLayout = ;opentype;
layout = computeLayout(font, text, [opt])
Computes a new layout from the given Opentype.js
Font interface and a
All units should be in raw font units in the EM square, assuming a lower-left origin. For example, a
'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.
widththe width of the box in font units, will cause word-wrapping (default
alignstring alignment of the text within its
letterSpacingthe additional letter spacing in font units (default 0)
lineHeightthe line height in font units as per CSS spec, default
1.175 * font.unitsPerEmto match browsers
startthe starting character index into
textto layout, default 0
endthe ending index into
textto layout (exclusive), default
modecan be 'pre' (maintain spacing), or 'nowrap' (collapse whitespace but only break on newline characters), otherwise defaults to normal word-wrap behaviour
See word-wrapper for details on how word wrapping is computed.
The returned object has the following metrics.
This provides an array of characters after layout, useful for rendering. Each element in the array has the following properties:
position: x ydata: ... Opentypejs Glyph object ...index: charIndexrow: lineIndexcolumn: columnInLineIndex
The position is in raw font units.
This is the value from pen origin to the baseline of the last line of text in the layout.
This is the
L value in the CSS line-height spec. 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.
This is an array of line objects with the following properties:
start: startCharIndex // inclusiveend: endCharIndex // exclusivewidth: lineWidth // in font units
This is the computed
lineHeight in font units. If no
lineHeight is specified in options, it will be equivalent to
1.175 * font.unitsPerEm.
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.
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.
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.
The height of the text box, including the half leadings above the first ascender and below the last descender.
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.
This module is not yet finished — below are some areas that need improvement. PRs welcome.
'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
MIT, see LICENSE.md for details.