Issue 12954 in skia: CanvasKit: strokeText & drawParagraph have different letter spacing

172 views
Skip to first unread message

kaise… via monorail

unread,
Feb 15, 2022, 11:34:28 PM2/15/22
to bu...@skia.org
Status: Untriaged
Owner: ----
Priority: Medium
Type: Defect

New issue 12954 by kaise...@gmail.com: CanvasKit: strokeText & drawParagraph have different letter spacing
https://bugs.chromium.org/p/skia/issues/detail?id=12954

What steps will reproduce the problem?
Load a custom font using CanvasKit, use the normal paragrpah apis to draw text to the canvas, then try using `ctx.strokeText` to add a stroke on top of the canvas. There will be a noticeable difference in the letter spacing the more text that is on the page.


What is the expected output? What do you see instead?
I would expect `ctx.drawParagraph` and `ctx.strokeText` to render text using the same letter spacing. This is not the case. You can see the result in the attached `out.png` file.


What version of the product are you using? On what operating system?


Please submit a code sample via fiddle.skia.org showing the issue.
this is a deno code example. I am not well versed in C/C++, so unfortunately I am just going to give you the deno repro. This is largely a bug about inconsistencies with the web api, so I probably am stuck giving a javascript repro regardless. It is attached under the file `repro.ts`.
The file can be ran using the following command:
```bash
deno run --allow-run --allow-read --allow-write --watch repro.ts
```
You must also download the font and place it in the same folder as repro.ts (or just download any old font)


Provide any additional information below.

If there is another way to render text strokes using the Paragraph API, or some other canvaskit api, I am just as happy to use that, I just could not find any searching through the type defs (`modules/canvaskit/canvaskit/types/index.d.ts`).

The library I am using to access CanvasKit is https://github.com/DjDeveloperr/deno-canvas

Attachments:
repro.ts 1.4 KB
out.png 54.9 KB
Qdbettercomicsans-jEEeG.ttf 29.7 KB

--
You received this message because:
1. The project was configured to send all issue notifications to this address

You may adjust your notification preferences at:
https://bugs.chromium.org/hosting/settings

micha… via monorail

unread,
Feb 21, 2022, 12:28:08 PM2/21/22
to bu...@skia.org
Updates:
Cc: bung...@google.com kjlu...@google.com
Labels: Area-TextLayout Area-CanvasKit
Owner: jlav...@google.com
Status: Accepted

Comment #1 on issue 12954 by michae...@google.com: CanvasKit: strokeText & drawParagraph have different letter spacing
https://bugs.chromium.org/p/skia/issues/detail?id=12954#c1

Do we incorporate stroke width into each glyph's advance? Or is it WAI that glyph layout from SkParagraph can be different than glyph layout handled by the simple functions in drawTextBlob? Or is it in canvaskit's emulation of the canvas2d strokeText function (a brief look didn't suggest there was anything special it was doing). Alternatively, could it be the custom font, providing paths that we turn into stroked shapes that don't line up with the glyph masks that true type produces when doing a conventional fill style?

bunge… via monorail

unread,
Feb 21, 2022, 5:28:56 PM2/21/22
to bu...@skia.org

Comment #2 on issue 12954 by bung...@google.com: CanvasKit: strokeText & drawParagraph have different letter spacing
https://bugs.chromium.org/p/skia/issues/detail?id=12954#c2

This is more of a CanvasKit API decision. In Skia anything other than SkText, SkShaper, and SkParagraph that takes code points should be labeled as "toy". SkText, SkShaper, and SkParagraph all do actual text shaping, doing fallback and applying the shaping rules from the font as requested. The other "text" drawing APIs currently just convert code points to glyphs one to one through the font's default character mapping, apply the default advance width for each, and do no font fallback (do no shaping). These methods will never agree with each other.

The "toy" versions are mostly for code size reduction (shaping can be large and require a significant amount of data and take time) for those with a fixed set of strings and a fixed set of fonts and know that everything will just work out well enough. If that's all you need then it's possible to create a minimal CanvasKit without text shaping but still with minimal font support. However, if you're going to do anything internationalized, or allow for user input strings or anything like that, it's generally necessary to go through shaping to get good results.

kjlub… via monorail

unread,
Feb 22, 2022, 2:05:30 PM2/22/22
to bu...@skia.org
Updates:
Cc: -kjlu...@google.com jlav...@google.com
Owner: kjlu...@google.com
Status: WontFix

Comment #3 on issue 12954 by kjlu...@google.com: CanvasKit: strokeText & drawParagraph have different letter spacing
https://bugs.chromium.org/p/skia/issues/detail?id=12954#c3

If you want properly shaped text, the Paragraph API is what you should use. The Canvas2D emulation layer only uses the toy implementation and will likely continue to do so for the medium term.

When you say "text strokes", what exactly do you mean? For examples of the Paragraph API, see the unit tests: https://github.com/google/skia/blob/main/modules/canvaskit/tests/paragraph.spec.js
Reply all
Reply to author
Forward
0 new messages