Bug 172165 - Canvas measureText brings wrong results in the first time for custom font face
Summary: Canvas measureText brings wrong results in the first time for custom font face
Status: RESOLVED CONFIGURATION CHANGED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Canvas (show other bugs)
Version: Safari Technology Preview
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2017-05-16 05:04 PDT by erezg
Modified: 2022-07-18 14:43 PDT (History)
6 users (show)

See Also:


Attachments
HTML + WOFF for a repro (25.87 KB, application/x-zip-compressed)
2017-05-16 05:04 PDT, erezg
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description erezg 2017-05-16 05:04:24 PDT
Created attachment 310255 [details]
HTML + WOFF for a repro

I have a custom font in a WOFF file that is dynamically loaded when needed.
In the first use (before the font is loaded), I call the canvas's measureText and I get a wrong result.
The returned result is much bigger than the final result, causing dynamic elements to render wrong.

I attached a demo using HTML and WOFF.
Call the measureTest() function several times. It uses the font-face declared in the style.
In the first time, the result is 103.271484375
In the next times, the result is 49.6240234375.
This function doesn't do any random calculation and should return the correct result (49.6240234375) every time.

In iOS 9, the first result is 51.123046875, and I think this was the case until iOS 10.3 (not including).
The small diff on older OSs didn't matter much but does matter now in the latest iOS.

The problem happens on all latest Safari + Safari Mobile + Safari Technology Preview versions.
Comment 1 Alexey Proskuryakov 2017-05-16 20:11:53 PDT
Thank you for the report! What behavior do you expect in this case? It seems unsurprising that the size is different while the font is not loaded yet.
Comment 2 erezg 2017-05-16 23:38:28 PDT
I agree it seems unsurprising, but I have no way of knowing that the result that I got is true in the first time.
I would expect it to be a synchronous command that waits for the custom font-face to get loaded.
Is there any workaround available that doesn't involve requesting a new animation frame or such?
Comment 3 Roland Soos 2017-05-17 07:56:30 PDT
Your issue might be the same as mine. You can check my ticket here and do the tests: https://bugs.webkit.org/show_bug.cgi?id=172210
Comment 4 Myles C. Maxfield 2017-05-17 15:22:10 PDT
I'm pretty sure I just fixed this in https://trac.webkit.org/changeset/216944/webkit. Can you try tomorrow's nightly build to see if it still happens?
Comment 5 erezg 2017-05-21 00:51:59 PDT
I just verified with the nightly of Version 10.1 (12603.1.30.0.34, r217192).
The results are now different, but the first value is still wrong.

I get 48.18359375 in the first time, and the correct value of 49.6240234375 in the other times.
Comment 6 Myles C. Maxfield 2017-05-21 09:50:07 PDT
There’s no way you can get exactly the correct width because the font required to perform the calculation hasn’t arrived yet.

What are your expectations around what the browser should do in your situation?
Comment 7 erezg 2017-05-22 00:14:27 PDT
Is there an event I can subscribe to in order to make sure the font is rendered and the calculation will be done right after it?
Comment 8 Myles C. Maxfield 2017-05-22 17:08:21 PDT
(In reply to erezg from comment #7)
> Is there an event I can subscribe to in order to make sure the font is
> rendered and the calculation will be done right after it?

Yes, you can use the CSS Font Loading API. https://www.w3.org/TR/css-font-loading/
Comment 9 Radar WebKit Bug Importer 2022-07-18 14:43:16 PDT
<rdar://problem/97221073>