• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Canvas2D extensions for Shaped Text
2=============
3[Shaped Text](text_shaper.md) is a proposal for exposing the Browser's text shaping engine. It takes in
4a block of (annoated) text, and returns the low-level information needed to correctly measure, hit-test,
5and draw the text as positioned glyphs. This processing step is needed whenever text is measured or
6drawn in the browser, and this processing can be complex and time consuming. The output of this processing
7is, however, simple and can be rendered quite efficiently. It is runs (tied to a specific Typeface and size)
8of glyph IDs and x,y postions.
9
10This proposal extends Canvas2D to allow it to draw those glyphs directly, and also includes utilities for
11querying attributes of the glyphs (not needed for drawing, but useful for other operations).
12
13### Principles
14* Drawing postioned glyphs should be at least as flexible as the existing fillText() method.
15* It is expected that drawing glyphs can be faster than fillText() -- no shaping/processing is needed.
16* With the additional utilities, new effects should be easy and efficient.
17
18## Drawing glyphs
19
20At the heart of the proposal is a parallel to fillText/strokeText...
21
22```js
23context.fillGlyphs(glyphs, positions, Font);
24
25context.strokeGlyphs(glyphs, positions, Font);
26```
27
28These respect all of the same settings as their 'Text' equivalents (e.g. current transform, clip, style)
29with the exception of the actual text attributes:
30- font
31- textAlign
32- textBaseline
33- direction
34
35These are ignored, because they have already been 'computed' by the Shape Text processing, and their
36results are represented in the glyphs, positions, and [Font](text_shaper.md) parameters.
37
38[Font](text_shaper.md) is far more specific in this extension that the existing context.font attribute. In
39today's canvas2d, "font" holds a high-level description of the typeface(s): It is a string with the
40font's name, which has to be resolved to find the actual (set of) resources. For Shaped Text, this
41resolution has already occured. The glyph IDs are specific to exactly 1 resource (i.e. file/blob) and
42so the Font interface contains not the name, but a handle to the actual resource.
43
44The upside to this specificity is performance: with all "fallback" and shaping having already
45occured, the draw calls can execute faster.
46
47## Font utilities
48
49[Shaped Text](text_shaper.md) introduced the Font interface, but for shaping, it only needed to specify
50the resource (Typeface object) sizing information, and (on input) optional font-features. After shaping,
51clients may want to query information about specific glyphs within that Font. Those extended methods are
52presented here.
53
54```WebIDL
55interface Font {
56    ...     // see [Shaped Text](text_shaper.md) for descriptive attributes
57
58    // return array of advance widths for the specified glyphs.
59    //
60    sequence<float> getGlyphAdvances(sequene<unsigned short> glyphs);
61
62    // return array of [left, top, right, bottom] coordinates for the specified glyphs,
63    //
64    // If positions are provided, then the rectangles are relative to each glyph's postion.
65    // If no positions are provided, then the rectangles are all relateive to (0,0).
66    // Note: positions are stored as (x,y) pairs
67    //
68    sequence<float> getGlyphBounds(sequene<unsigned short> glyphs, sequence<float> positions?);
69
70    // return array of Path2D objects for the specified glyphs,
71    //
72    // If positions are provided, then the paths are relative to each glyph's postion.
73    // If no positions are provided, then the paths are all relateive to (0,0).
74    // Note: positions are stored as (x,y) pairs
75    //
76    // If a glyph has no visual representation (e.g. a SPACE) then its path will be null.
77    // If a glyph has an image for its representation, then its path will be undefined.
78    //
79    sequence<Path2D> getGlyphPaths(sequene<unsigned short> glyphs, sequence<float> positions?);
80
81    // A glyph may be represented with an image (e.g. emoji). getGlyphImage() for these glyphs
82    // will return a GlyphImage object. If the glyph does not have an Image, null is returned.
83    //
84    GlyphImage getGlyphImage(unsigned short glyphID);
85};
86
87interface GlyphImage {
88    readonly attribute ImageBitmap image;
89    readonly attribute DOMMatrix transform;
90};
91```
92
93[Overview document](text_overview.md)
94
95## Contributors:
96 [mikerreed](https://github.com/mikerreed),
97