synthetic font styles (oblique, fake-bold) do not work consistently in HTML5 canvas element for all styles and font backends

RESOLVED FIXED

Status

()

RESOLVED FIXED
3 years ago
2 years ago

People

(Reporter: brian, Unassigned)

Tracking

({testcase})

Trunk
testcase
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(platform-rel +)

Details

(Whiteboard: [platform-rel-Google][platform-rel-GoogleDocs])

(Reporter)

Description

3 years ago
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36

Steps to reproduce:

Attempted to draw italic text on an HTML5 canvas using a @font-face rule to define the font.  An example can be seen here:

https://jsfiddle.net/mwqpx3fs/


Actual results:

When using the @font-face rule, the text is not italic.  When referencing a font family directly, it works as expected.

I experience the behavior in FireFox 38.0 on both Windows and Mac.


Expected results:

The text should have been rendered as italic as it does in other browsers, and as it does in FireFox when not drawing on the canvas.

Updated

3 years ago
Component: Untriaged → Layout: Text

Updated

3 years ago
Keywords: testcase
Flags: needinfo?(jfkthame)
It appears that we don't apply synthetic font styles in canvas, so you'll only get an italic face if the font family you're using has one. The "_Arial" family defined in the testcase contains only a regular face, so that's the only style we render in canvas.

If you provide an italic face in the _Arial family, then italic style will work as expected:

  @font-face {
    font-family: _Arial;
    src: local('Arial');
  }
  @font-face {
    font-family: _Arial;
    font-style: italic;
    src: local('Arial Italic');
  }

The same will apply to bold, by the way: for font-style:bold to work in canvas, you need a bold face to be defined in the family you're using.

Perhaps we should apply synthetic style effects in canvas, similarly to HTML text. But currently, at least, we don't. One possible justification for that could be that canvas is a graphics environment where the programmer expects to control everything exactly -- so when you draw text, you get exactly the font (face) you've specified, not some synthetically-modified version of it; while HTML text is more about content, and less about precise graphical control.

Remember that css font-style and font-weight properties (together with font-family) are primarily a means *selecting* a specific font face (resource) from the collection of fonts available to match, not about modifying a font. The fact that in HTML text, we attempt to simulate certain faces -- bold and italic (or rather, oblique) variants of a regular face -- if they're not available is a secondary feature.

Compare https://jsfiddle.net/5ypxjd5q/ in Chrome, for example, to see the difference between 'italic' selecting an italic face, and applying a synthetic-oblique effect to a family that is specified as having only a regular face. Gecko doesn't currently do the latter in canvas text.

Anyway, that's what's going on. Whether we should change this behavior is perhaps debatable, but it's at least worth considering.
Flags: needinfo?(jfkthame)
(Reporter)

Comment 2

3 years ago
Jonathan,

Thanks for the quick response and detailed explanation as to what is occurring.  Your reasoning as to why the canvas does not apply synthetic styles makes sense.  In my particular case, I'm creating an HTML5 design app where the user can choose from fonts installed on their machine, and then I rasterize the design via the canvas.  In this instance, it would be helpful to have the synthetic styles in the event that a font doesn't include the true style.

You mentioned that synthetic bold is not applied in the canvas either.  Interestingly, I am seeing what appears to be a synthetic bold applied.  You can see it in this test case which includes real bold, synthetic bold, and normal text: http://jsfiddle.net/xuuuwxnh/2/.
(In reply to brian from comment #2)
> You mentioned that synthetic bold is not applied in the canvas either. 
> Interestingly, I am seeing what appears to be a synthetic bold applied.  You
> can see it in this test case which includes real bold, synthetic bold, and
> normal text: http://jsfiddle.net/xuuuwxnh/2/.

Hmm, that's interesting. On looking closely, I see that the synthetic-bold (middle) line in your example renders with the same glyphs as the regular line, but with slightly increased letter spacing. This is on Mac OS X; the result is similar on Windows XP. But on Win8, I do see synthetic bold. (Disabling hardware acceleration in Preferences / Advanced, and restarting, reverts to the WinXP-like rendering because it switches from DirectWrite to GDI font usage.)

This is happening because Gecko implements synthetic-bold in different ways depending on the underlying font system being used. With DirectWrite, it turns out it does work in canvas; but with the other platforms I've tested, we get the increased glyph spacing that would be associated with synthetic bold, but we don't get the actual double-striking of the glyphs.

That's undeniably a bug: we should either not support these effects at all, or we should support them fully; but the current situation where synthetic bold is "semi-supported" is clearly bad.

Updating the bug title to more clearly reflect our new understanding of what is going on.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Italic font style does not work with @font-face in HTML5 canvas element → synthetic font styles (oblique, fake-bold) do not work consistently in HTML5 canvas element for all styles and font backends
Version: 38 Branch → Trunk
I believe the patch recently landed in bug 1274936 has fixed this for simple cases, and bug 1275693 should extend that to cover more kinds of canvas painting. Once that's also landed, let's re-evaluate the behavior here and see if anything more is needed.
Depends on: 1274936, 1275693
Depends on: 1287144
AFAICT, this is now working, thanks to fixes in the several dependent bugs. Synthetic bold & italic (slanting) should be applied to <canvas> text in the same way as normal HTML text.

Brian, if you'd like to check the behavior in current Nightly releases[1] and confirm whether you're still seeing any problems in this area, that would be great - thanks.
Flags: needinfo?(brian)
Oops, I meant to provide a link:

[1] https://nightly.mozilla.org/
(Reporter)

Comment 7

2 years ago
Jonathan, thanks for the update.  It appears that the fix has resolved my issue.  I had resorted to applying my own transform to slant the letters by 15 degrees, so it's nice to know that I'll be able to phase that out.  Thanks again.
Flags: needinfo?(brian)
OK, thanks; resolving this as Fixed. For the record, this was fixed primarily by the combination of bug 1274936 and bug 1275693, with bug 1287552 as a followup to fix synthetic-bold on Linux.
Status: NEW → RESOLVED
Last Resolved: 2 years ago
Resolution: --- → FIXED
platform-rel: --- → +
Whiteboard: [platform-rel-Google][platform-rel-GoogleDocs]
You need to log in before you can comment on or make changes to this bug.