[canvaskit] Add rough measureText to Canvas2D emulation layer

I wanted to use SkParagraph myself, but the API is a little
awkward right now in that I cannot just pass in a SkFont object
(which I have) - I would have to make a FontCollection, which
we lack the ability to do so.

Change-Id: I1488fb9c1a42af020a245a792b8e266c809b599a
Bug: skia:12705
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/481238
Reviewed-by: Nathaniel Nifong <nifong@google.com>
This commit is contained in:
Kevin Lubick 2021-12-07 15:15:08 -05:00
parent b4d01cbe41
commit 5d1d92c505
5 changed files with 26 additions and 4 deletions

View File

@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Canvas.drawVertices` and `Canvas.drawPatch` treat the default blend mode differently.
See https://bugs.chromium.org/p/skia/issues/detail?id=12662.
### Added
- Rough implementation of `measureText` to Canvas2D emulation layer. For accurate numbers, clients
should use a real shaping library, like SkParagraph.
## [0.31.0] - 2021-11-16
### Added

View File

@ -781,7 +781,15 @@ function CanvasRenderingContext2D(skcanvas) {
};
this.measureText = function(text) {
throw new Error('Clients wishing to properly measure text should use the Paragraph API');
const ids = this._font.getGlyphIDs(text);
const widths = this._font.getGlyphWidths(ids);
let totalWidth = 0;
for (const w of widths) {
totalWidth += w;
}
return {
"width": totalWidth,
};
};
this.moveTo = function(x, y) {

View File

@ -80,7 +80,7 @@ APIs and some documentation about them.
## Drop-in Canvas2D replacement
For environments where an HTML canvas is not available (e.g. Node, headless servers),
CanvasKit has an optional API (included by default) that mirrors the HTML canvas.
CanvasKit has an optional API (included by default) that mostly mirrors the HTML canvas.
let skcanvas = CanvasKit.MakeCanvas(600, 600);
@ -101,6 +101,11 @@ CanvasKit has an optional API (included by default) that mirrors the HTML canvas
See more examples in `example.html` and `node.example.js`.
### Known issues with Canvas2D Emulation layer
- measureText returns width only and does no shaping. It is only sort of valid with ASCII letters.
- textAlign is not supported.
- textBaseAlign is not supported.
- fillText does not support the width parameter.
# Filing bugs

View File

@ -491,8 +491,9 @@
ctx.fillStyle = 'black';
ctx.font = '26px Bungee';
ctx.rotate(.1);
let text = ctx.measureText('Awesome');
ctx.fillText('Awesome ', 25, 100);
ctx.strokeText('Groovy!', 200, 100);
ctx.strokeText('Groovy!', 35 + text.width, 100);
// Draw line under Awesome
ctx.strokeStyle = 'rgba(125,0,0,0.5)';

View File

@ -727,7 +727,7 @@ describe('Canvas 2D emulation', () => {
describe('loading custom fonts', () => {
const realFontLoaded = new FontFace('BungeeNonSystem', 'url(/assets/Bungee-Regular.ttf)', {
'family': 'BungeeNonSystem', //Make sure the canvas does not use the system font
'family': 'BungeeNonSystem', // Make sure the canvas does not use the system font
'style': 'normal',
'weight': '400',
}).load().then((font) => {
@ -763,6 +763,10 @@ describe('Canvas 2D emulation', () => {
ctx.fillText('2.0em Bungee filled', 10, 80);
ctx.strokeText('2.0em Bungee stroked', 10, 130);
const m = ctx.measureText('A phrase in English');
expect(m).toBeTruthy();
expect(m['width']).toBeTruthy();
ctx.font = '40pt monospace';
ctx.strokeText('40pt monospace', 10, 200);