Closed Bug 1600470 Opened 3 months ago Closed 2 months ago

synthetic bold on color emoji looks bad

Categories

(Core :: Graphics: Text, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla73
Tracking Status
firefox73 --- fixed

People

(Reporter: heycam, Assigned: jfkthame)

Details

Attachments

(2 files)

We should probably inhibit synthetic bolding when rendering emoji -- maybe for all COLR/CPAL glyphs?

Test case and screenshots: https://twitter.com/FakeUnicode/status/1200923394373406720

Yeah, that does look pretty bad!

(The result will vary quite a bit between platforms, because the various back-ends have different implementations of synthetic bolding. This'll be FreeType's "embolden" feature getting applied, as it's on Ubuntu.)

The decision on whether synthetic-bold should be applied gets made when a given font is instantiated, but there are fonts that are primarily monochrome and yet have a few color glyphs (so we'd detect them as being color fonts). Unless we're willing to accept that synthetic-bold just won't apply to such fonts at all -- even for the monochrome glyphs -- this may be a bit tricky.

I'm not certain it's worth the effort, but would it be possible to instantiate two copies of the font when we need synthetic bold: one where we turn on FreeType's embolden feature but set our idea of character coverage to omit glyphs that have COLR/CPAL definitions, and another where we leave the embolden feature off and set our character coverage to be only the COLR/CPAL glyphs?

Yes, something like that would be feasible, I think. Whether it's worth the extra code/complexity may be questionable, though.

Oh, we'd need to think through how that works with a font that supports both monochrome and color presentations for the same codepoints - controlled by use of variation selectors U+FE0E or U+FE0F. I guess we could just say that emoji characters in such a font don't ever get synthetic-bolding, even if they're being rendered in their monochrome form.

Yeah even monochrome emoji don't make sense to bold or italicize, imo.

We could also regard this as a bug in the font, since this doesn't happen on windows and they're using a similar system for color emoji. iirc they actually provide bold/italic variants (still dubious) but I think ideally twemoji would claim that it supports bold/italic and just implement them as no-ops.

That said, it's in the wild, so we should probably just handle this ourselves. From the WR side of things, it's possible we can just temporarily mask out FontInstanceFlags_SYNTHETIC_BOLD in the WR RenderColorGlyph Path.

(synthetics have changed a bit since I last looked at them, so that's a bit of a guess)

Waking up more and realizing my hacky suggesting doesn't make sense since synthetic bold/italics is factored in much earlier to properly compute glyph advance all the way up in the text layout code. Very nasty indeed...

Priority: -- → P3

(In reply to Alexis Beingessner [:Gankra] from comment #4)

Yeah even monochrome emoji don't make sense to bold or italicize, imo.

Well... the same could also be said for various symbols that aren't considered emoji at all. (Italicized box-drawing characters, anyone?) But I don't think we should be making that sort of call. If authors request these effects, we should just apply them, even if we don't think it makes much sense to stylize certain characters in that way.

We could also regard this as a bug in the font, since this doesn't happen on windows and they're using a similar system for color emoji.

Actually, this does happen on Windows as well, only less so. We use DirectWrite's bold "simulation" there, and it does a somewhat similar thing to FreeType's emboldening, but it's considerably less extreme and generally doesn't look too bad.

I think to mitigate this issue, and generally improve synthetic-bold on Linux/Android, we should reduce the "strength" of emboldening that's used via FreeType. Currently, it's excessive (especially compared to what DirectWrite is doing on Windows), and this leads to the poor emoji rendering we see here.

This screenshot shows the results for a normal Latin text face (with no true bold face available). Top is what we currently get on Linux using FT_GlyphSlot_Embolden, where the fake-bold face is very heavy; middle is what DirectWrite does on Windows 10; and bottom is what we could get using FT_Outline_Embolden with a 50% reduced strength compared to what FT_GlyphSlot_Embolden does.

Assignee: nobody → jfkthame
Status: NEW → ASSIGNED
Pushed by jkew@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/bf28a7e8a8a4
Reduce the emboldening strength used for synthetic-bold faces with FreeType. r=lsalzman

So this breaks the wrench (standalone webrender testing) build, because mozilla_GlyphSlot_Embolden_Less was defined in gfx/2d, which is not available to the webrender font.rs code in that build.

I guess we can fix this by moving the implementation of mozilla_GlyphSlot_Embolden_Less over to the webrender code, and exposing it for SkFontHost_cairo to call, rather than vice versa. (If we ever wanted to be able to use SkFontHost_cairo without linking webrender, we'd run into a similar issue; maybe we'd need to implement versions of mozilla_GlyphSlot_Embolden_Less in both places. But for now I don't think that's a concern.)

Flags: needinfo?(jfkthame)
Pushed by jkew@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/f2d54eefdb44
Reduce the emboldening strength used for synthetic-bold faces with FreeType. r=lsalzman
Status: ASSIGNED → RESOLVED
Closed: 2 months ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla73
You need to log in before you can comment on or make changes to this bug.