Closed Bug 1126391 Opened 10 years ago Closed 6 years ago

Canvas' measureText does not measure the same way than DOM

Categories

(Core :: Graphics: Canvas2D, defect)

ARM
Gonk (Firefox OS)
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX
Tracking Status
b2g-master --- affected

People

(Reporter: julienw, Unassigned)

References

()

Details

(Whiteboard: [gfx-noted])

Attachments

(3 files)

Context: in Gaia's gaia-header [1] we use "measureText" to know if we have enough space to display a specific text, and possibly decrease the font to make the text display completely. But it looks like that with some fonts we get a smaller value with measureText than what is really used in the DOM, resulting in an ellipsis. [1] https://github.com/gaia-components/gaia-header/ (testcase is coming)
Ok, seems to be B2G only, I can't repro on Desktop.
OS: Linux → Gonk (Firefox OS)
Hardware: x86_64 → ARM
Attached file test-canvas.html
http://everlong.org/mozilla/test-overflow.html is the issue we're facing in gaia-header. There is a ~1.5px difference here! (and in gaia-header I even measured a 3px difference in the exact same case, I'm not entirely sure why we don't find the same result). I have about the same difference both in italic and normal. However I don't always find such a difference depending on the font size.
See Also: → 1112131
Attached file test-overflow.html
If QA could help loading http://everlong.org/mozilla/test-overflow.html on various branches and tell us if we see the ellipsis and/or we see different values for intrinsic and measured width, it would help.
Keywords: qawanted
Attached image BranchCheck.png
I checked on Flame 2.2, 2.1, and 2.0. I see the ellipses and different values. The attached is the screenshots from those 3 branches. Environmental Variables: Device: Flame 2.2 BuildID: 20150128230035 Gaia: 6e494f1d2676d231abba7dcc2e2822d1170d2d02 Gecko: 5e6fac01a72f Version: 37.0a2 (2.2) Firmware Version: v18D-1 User Agent: Mozilla/5.0 (Mobile; rv:37.0) Gecko/37.0 Firefox/37.0 Environmental Variables: Device: Flame 2.1 BuildID: 20150129103533 Gaia: 0ef345ec8b5a2cbde4bf46304eb59ab1c32ee251 Gecko: 5803dc422e39 Version: 34.0 (2.1) Firmware Version: v18D-1 User Agent: Mozilla/5.0 (Mobile; rv:34.0) Gecko/34.0 Firefox/34.0 Environmental Variables: Device: Flame 2.0 BuildID: 20150129074534 Gaia: 2989f2b2bd12fcc0e9c017d2db766e76a55873b8 Gecko: 6150867fc6a8 Version: 32.0 (2.0) Firmware Version: v18D-1 User Agent: Mozilla/5.0 (Mobile; rv:32.0) Gecko/32.0 Firefox/32.0
Flags: needinfo?(ktucker)
QA Whiteboard: [QAnalyst-Triage?]
Keywords: qawanted
QA Whiteboard: [QAnalyst-Triage?] → [QAnalyst-Triage+]
Flags: needinfo?(ktucker)
Note that we don't use exactly the same font in the different versions (the first character is different for example) so that's likely why we have different values accross versions.
hey Jeff, Nical told me you could be the right person to look at this?
Flags: needinfo?(jmuizelaar)
I'm not sure why there would be different results here. Maybe someone who knows more about text will have an answer.
Flags: needinfo?(jmuizelaar) → needinfo?(jfkthame)
I think the issue is that on a device where CSS pixels do not correspond to device pixels (i.e. we have a devicePixelRatio other than 1.0), the canvas measureText operation here is not using the same font size as the HTML text. Remember that canvas is a CSS-pixel-based API, so when you ask it for "24px sans-serif" we'll render text using the sans-serif font scaled to 24 pixels per em, and paint the resulting pixels to the canvas bitmap. (Or return the resulting textWidth, if you're just measuring.) But if devicePixelRatio is 1.5, for example (typical of some mobile devices), 24 CSS px will correspond to 36 device pixels, and so HTML text will be rendered using the sans-serif font scaled to 36 pixels per em. The resulting device-pixel width will then be scaled back to CSS pixels for APIs such as offsetWidth. Depending on the platform and font rendering settings, it's entirely possible (especially in the presence of hinting, but even without hints, pixel-rounding is enough...) that text metrics do not scale linearly with font size. You can reproduce similar discrepancies on desktop platforms by setting layout.css.devPixelsPerPx to various values -- try things like 0.8, 0.9, 1.2, 1.3, etc. -- if it doesn't occur with the default value. To get a more accurate measurement via canvas measureText, it would probably work to scale the font size used in canvas by devicePixelRatio, and then unscale the resulting width; but it might be better/safer/simpler to measure an HTML element directly.
Flags: needinfo?(jfkthame)
To explain a little more the context, we use a canvas instead of an HTML element because this does not involve reflows. Maybe using an iframe with an HTML element inside would work fine though.
I noticed this on imagecompare tests too - very occasionally header texts show an ellipsis one day all of a sudden. Also in some instances one character is slightly out of size compared to the rest of the ones. Any updates on this bug?

Closing bugs with b2g-master=affected as it is likely to be out dated.

Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: