Closed Bug 1108179 Opened 5 years ago Closed 5 years ago

Canvas text rendering is very broken with zero width joiner

Categories

(Core :: Canvas: 2D, defect)

x86_64
Linux
defect
Not set

Tracking

()

RESOLVED FIXED
mozilla37

People

(Reporter: mozilla, Assigned: jfkthame)

References

()

Details

Attachments

(3 files, 1 obsolete file)

ZWNJ shows as a tofu box, among other problems.  See:

  http://jsfiddle.net/ikopylov/dctjn6sz/
Behdad, any chance you can help us find when this broke by using mozregression (http://mozilla.github.io/mozregression/) tool?
Removing the "zero width joiner" \u200D from the example produces matching results on Safari and Firefox.
Summary: Canvas text rendering is very broken → Canvas text rendering is very broken with zero width joiner
I see two problems in this example:
(a) the ZWJ is getting rendered as a missing-glyph box;
(b) the strings that use a trailing \u200D to generate a left-joining form don't shape as intended.

I'm not sure offhand why (a) is happening. It looks like the ZWJ is getting replaced by a .notdef glyph for some reason.

(b) seems to be a result of bidi processing splitting the trailing \u200D from the preceding text. If I add \u200F (right-to-left mark) after the trailing ZWJ on those strings, we get the intended shaping as the entire string now forms a single RTL run. (But the tofu boxes still appear, too.)
Milan: I don't have a Mozilla build.  Jonathan is in the right position to figure this out.
The shaping code filters out stray default-ignorable characters by marking them as 'missing' in the textrun, with their advance set to zero (to distinguish them from true missing glyphs, which we want to render visibly). The source of the tofu here is that the canvas drawing code fails to ignore these zero-width missing-glyph records. This patch fixes that; it does not address the bidi-run issue that's preventing the example actually shaping as intended.
Attachment #8534118 - Flags: review?(jdaggett)
Assignee: nobody → jfkthame
Status: NEW → ASSIGNED
This fixes the bidi-run analysis and shaping. The source of the problem is that ZWJ has bidi category BN, so when we do bidi processing with a base direction of LTR, a trailing ZWJ won't end up in the same bidi run as the preceding Arabic letter, and they won't be seen at the same time by the shaper. By borrowing the first-strong algorithm used for dir=auto, we can make this work better for most cases. There will still be the possibility of mixed-script or all-neutral/weak strings that don't necessarily get analysed into direction runs in the way the author hoped, but this should address any reasonably likely use-case (such as the example here).
Attachment #8534133 - Flags: review?(smontagu)
Comment on attachment 8534133 [details] [diff] [review]
part 2 - Use the first-strong algorithm to determine base direction for bidi analysis of text string being drawn to canvas

Hmm. Unfortunately, this appears to conflict with the text preparation algorithm[1] in the canvas2d spec, where step 5 requires the text to be laid out (hypothetically, at least) in an inline box with 'direction' taken from the target element (step 4).

As a result, this breaks an existing reftest (canvas/text-bidi-rtl-test.html).

[1] http://www.w3.org/TR/2dcontext/#text-preparation-algorithm
Attachment #8534133 - Flags: review?(smontagu)
Comment on attachment 8534133 [details] [diff] [review]
part 2 - Use the first-strong algorithm to determine base direction for bidi analysis of text string being drawn to canvas

Obsoleting this patch, as we can't actually use a fix like this. I think we should just take the fix for the "tofu" boxes in this bug, and file a separate bug on the shaping issue with ZWJ at bidi boundaries. Note that this aspect affects HTML text as well as canvas:

data:text/html,<div style="font:40px times new roman">a&%23x200d;&%23x64a;&%23x200d;b

(Compare rendering in Safari/Chrome with Firefox.)

Fixing this will involve passing context down to the shaping process, I think.
Attachment #8534133 - Attachment is obsolete: true
Attachment #8534118 - Flags: review?(jdaggett) → review+
https://hg.mozilla.org/mozilla-central/rev/d1510bd56577
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Blocks: 1113755
(In reply to Jonathan Kew (:jfkthame) from comment #10)
> Comment on attachment 8534133 [details] [diff] [review]
> part 2 - Use the first-strong algorithm to determine base direction for bidi
> analysis of text string being drawn to canvas
> 
> Obsoleting this patch, as we can't actually use a fix like this. I think we
> should just take the fix for the "tofu" boxes in this bug, and file a
> separate bug on the shaping issue with ZWJ at bidi boundaries. Note that
> this aspect affects HTML text as well as canvas:
> 
> data:text/html,<div style="font:40px times new
> roman">a&%23x200d;&%23x64a;&%23x200d;b
> 
> (Compare rendering in Safari/Chrome with Firefox.)
> 
> Fixing this will involve passing context down to the shaping process, I
> think.

Thanks.  I filed this:

  https://bugzilla.mozilla.org/show_bug.cgi?id=1113755

That said, does the canvas spec specify the bidi behavior of canvas text APIs?
No longer blocks: 1113755
I did a quick check for this using Firefox 37 Beta 3 and the attached URL, but I still get the colored boxes on Windows 7 x64 (same as in the original screenshot) and some other weird glyph instead of the boxes on Ubuntu 14.04 x64.

Can someone else double check and confirm whether this works now (the "tofu" boxes should not show)?
You need to log in before you can comment on or make changes to this bug.