Closed Bug 517642 Opened 15 years ago Closed 11 months ago

Investigate DirectWrite glyph rendering modes

Categories

(Core :: Graphics: Text, defect)

x86
Windows 7
defect

Tracking

()

RESOLVED WONTFIX

People

(Reporter: karlt, Assigned: bas.schouten)

References

(Blocks 1 open bug)

Details

Attachments

(12 files, 5 obsolete files)

326.68 KB, image/png
Details
415.43 KB, image/x-png
Details
447.37 KB, image/png
Details
446.85 KB, image/png
Details
216.85 KB, image/x-png
Details
140.48 KB, image/x-png
Details
38.35 KB, image/png
Details
129.42 KB, image/png
Details
21.13 KB, image/png
Details
13.43 KB, image/png
Details
51.33 KB, image/png
Details
361.86 KB, patch
Details | Diff | Splinter Review
The DirectWrite enum DWRITE_RENDERING_MODE includes some new glyph
rasterizing modes.
http://msdn.microsoft.com/en-us/library/dd368118%28VS.85%29.aspx

Included in these, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC enables
anti-aliasing in the vertical direction even with ClearType subpixel
anti-aliasing in the horizontal direction.

Is it necessary to use DirectWrite (on systems where it is available) to
make text look similar to how it looks in other apps?

It would also be interesting to see whether any of these modes enable subpixel
anti-aliasing of fonts with PostScript outlines (including CFF).
The default setting (which appears to use CLEARTYPE_NATURAL_SYMMETRIC at sizes below 100 and OUTLINE above) does perform sub-pixel anti-aliasing on CFF fonts.
I've done some investigating on this. I currently have an implementation working using Uniscribe as shaper and a cairo font on directwrite. So it is rasterizing using directwrite. I've attached an image of this, and the same screenshot using Uniscribe with GDI.

Glyph positioning seems to be suboptimal, but I think this is partially because uniscribe was made for GDI, with no sub-pixel accuracy. I will attempt to do further investigation using DirectWrite shaping.
I've added full DirectWrite support now, using the DirectWrite shaper. Attached are new screenshots. Significant difference can be seen, lines are also less wide, this is likely due to sub-pixel placement. Kerning looks quite a bit better in my opinion, especially when looking for example around the 'V' in DEVELOPER at the top, including new reference image.
Is the DirectWrite rendering using ClearType?
(In reply to comment #6)
> Is the DirectWrite rendering using ClearType?

Looks to me like it is.
Attached patch DWrite-only DWrite patch (obsolete) — Splinter Review
Attaching my patch for others to play with and remote backup.

De-allocations aren't well managed yet so expect it to leak if you try this. It also only implements the part of the cairo backend we use. It cannot do user fonts (it will fallback) and there's no support in our tree yet on windows for switching gfxFont implementation at runtime. So it only works on windows 7.
Looks like you forgot to include gfxWindowsDWFonts.h in your patch. :)
(In reply to comment #9)
> Looks like you forgot to include gfxWindowsDWFonts.h in your patch. :)

It seems I did, my appologies, I'll reupload a patch tomorrow, featuring semi-working user font support too :-).
Attached patch DWrite-only DWrite patch v2 (obsolete) — Splinter Review
Added the missing file, also added user font support. This is still limited and doesn't work completely right yet. Also added some first ranges support but that's not complete either.
Attachment #406606 - Attachment is obsolete: true
Attached patch DWrite-only DWrite patch v3 (obsolete) — Splinter Review
User font support appears now to be completely working. This also fixes some bugs in my range support. And adds the needed defines to allow a clean build from scratch.
Attachment #406941 - Attachment is obsolete: true
(In reply to comment #12)
> Created an attachment (id=407030) [details]
> DWrite-only DWrite patch v3
> 
> User font support appears now to be completely working. This also fixes some
> bugs in my range support. And adds the needed defines to allow a clean build
> from scratch.

A couple of comment from a quick lookover. I think we should use a 'dwrite' or 'directwrite' prefix instead of 'dw'. 'dwrite' is more consistent with microsoft's usage so might be the best choice.

cairo_dw_show_glyphs_on_surface shouldn't be a public function. _cairo_win32_surface_show_glyphs should support using both win32 fonts and directwrite fonts. (i.e. cairo_scaled_font_get_type (scaled_font))
(In reply to comment #13)
> (In reply to comment #12)

> A couple of comment from a quick lookover. I think we should use a 'dwrite' or
> 'directwrite' prefix instead of 'dw'. 'dwrite' is more consistent with
DWrite makes sense.
> microsoft's usage so might be the best choice.
> cairo_dw_show_glyphs_on_surface shouldn't be a public function.
Gotya.
> _cairo_win32_surface_show_glyphs should support using both win32 fonts and
> directwrite fonts. (i.e. cairo_scaled_font_get_type (scaled_font))
Yeah, I was planning on going that when dual support would go in in general. A good deal of work to do for that, need to create an abstraction class for gfxWindowsPlatform to use that is implemented by both gfxWindowsFonts and gfxWindowsDWriteFonts.
Bas, it would be really interesting to see samples with better fonts, sample pages using some of the C* fonts would be a good start (Cambria, Constantia, Calibri, etc.) along with a Japanese font like Meiryo.  All are recent Microsoft fonts intended for use with Cleartype so they're a good comparison point, especially when considering rendering quality and spacing.

I'm also *really* curious about how well Postscript CFF fonts render under DirectWrite, since Cleartype in the past has not covered these, the rendering defaults to simple anti-aliasing under GDI.  Are these nicely subpixel anti-aliased with your patch applied?

Here's an example page using Calluna, a really nice .otf font:

http://people.mozilla.org/~jdaggett/tests/otfkerning.html

Great stuff!
Attached image Calluna DWrite rendering (obsolete) —
Attachment #407190 - Attachment is obsolete: true
Depends on: 510440
I'm curious to know how this looks with rotated text. Currently, slightly rotated text looks kind of ugly (characters don't seem to line up):

data:text/html,<div style="-moz-transform: rotate(2deg); -webkit-transform: rotate(2deg); width: 20em;">Lorem ipsum dolor sit amet</div>

I heard that's because we don't do subpixel positioning (which DirectWrite should do). I think there's a bug opened about it, or there's bug 495802 for instance.

(By the way, that rotated text looks better on WebKit/Chrome (not on WebKit/Safari). I'm not sure if they do subpixel positioning, but they seem to disable ClearType when you rotate the text).
Thanks for the screenshots, the rotated text is looking pretty nice! :-)
There's a try server build with DirectWrite support now at: https://build.mozilla.org/tryserver-builds/bschouten@mozilla.com-dwrite/dwrite-win32.zip

It should also work on Vista & XP and automatically fallback to using GDI.
Attached patch DWrite Patch v4 (obsolete) — Splinter Review
Added the patch used to generate the try server build.
Assignee: nobody → bas.schouten
Attachment #407030 - Attachment is obsolete: true
Status: NEW → ASSIGNED
Attachment #407535 - Attachment is patch: true
Attachment #407535 - Attachment mime type: application/octet-stream → text/plain
(In reply to comment #27)
> This build breaks the following site:
> 
> http://people.mozilla.com/~jmuizelaar/direct-write/test.html

There's a new try-server build which fixes this. Note it might not pick the same font for the symbol as GDI did. Since a slightly different matching system is used.
(In reply to comment #28)
> (In reply to comment #27)
> > This build breaks the following site:
> > 
> > http://people.mozilla.com/~jmuizelaar/direct-write/test.html
> 
> There's a new try-server build which fixes this. Note it might not pick the
> same font for the symbol as GDI did. Since a slightly different matching system
> is used.

The try server build is quite crashy with downloadable fonts.  This page *always* crashes:

http://people.mozilla.org/~jdaggett/tests/waterfall.html
Rendering of Calluna at small sizes with Bas' latest tryserver builds.  Text is readable(!) and uses subpixel anti-aliasing.

The line heights are ever-so-slightly different.  Bas, is our metrics calculation different GDI vs. DirectWrite or is the OS providing us with slightly different metrics?  Notice how the last line is slightly higher in the DirectWrite case.
The rendering with the try-server build can have issues with some transformation effects, tab previews and such show the text all bunched up and the isocube demo featured on hacks.mozilla.org renders wrongly.

http://www.zachstronaut.com/lab/isocube.html

It's good to see this level of support this quickly though, nice work.
(In reply to comment #31)
> The rendering with the try-server build can have issues with some
> transformation effects, tab previews and such show the text all bunched up and
> the isocube demo featured on hacks.mozilla.org renders wrongly.
> 
> http://www.zachstronaut.com/lab/isocube.html
> 
> It's good to see this level of support this quickly though, nice work.

Very nice test case! Thanks. I think this has to do something with the trick I pulled to do transforms. I need to figure out how to generate the correct transformation matrix and it should be fixed, I'll look into it.
(In reply to comment #31)
> The rendering with the try-server build can have issues with some
> transformation effects, tab previews and such show the text all bunched up and
> the isocube demo featured on hacks.mozilla.org renders wrongly.
> 
> http://www.zachstronaut.com/lab/isocube.html
> 
> It's good to see this level of support this quickly though, nice work.
The issue is fixed and the cube renders properly now, except it seems text metrics are ever so slightly different causing the 'cube' next to the HTML button to word wrap. Need to look into if this is a bug somewhere or just difference in behavior. Must say it looks quite a bit better than in GDI, new build should be coming out of the try servers soon.
New directwrite patch, also added kicked a new try server build for this one. This now supports all SVG font tricks I could find so far, if anyone finds something not working or buggy, please let me know!
Attachment #407535 - Attachment is obsolete: true
A few things I've noticed from using the latest try server build...

 * Text doesn't use sub-pixel anti-aliasing, all text uses grey scale AA (last build didn't do this)
 * text-shadow doesn't work (only the underline or such will get a shadow)
 * Speed is much slower than the last build, scrolling a page and animations are laggy
 * Drag images mostly don't work, but they do under certain circumstances (Like the attachment in bug 471457, the text on the left produces no drag image but the text on the right does)
 * Transformations in certain circumstances can still produce a bad rendering, such as the ctrl-tab/all tabs panel
 * Metrics are "off", underlines are inconsistently spaced, line-height's vary, etc. A google search shows this off

I'm sure all this is already known, but it's what I ran into with it.
(In reply to comment #35)
> A few things I've noticed from using the latest try server build...
> 
>  * Text doesn't use sub-pixel anti-aliasing, all text uses grey scale AA (last
> build didn't do this)
>  * text-shadow doesn't work (only the underline or such will get a shadow)
>  * Speed is much slower than the last build, scrolling a page and animations
> are laggy
>  * Drag images mostly don't work, but they do under certain circumstances (Like
> the attachment in bug 471457, the text on the left produces no drag image but
> the text on the right does)
>  * Transformations in certain circumstances can still produce a bad rendering,
> such as the ctrl-tab/all tabs panel
>  * Metrics are "off", underlines are inconsistently spaced, line-height's vary,
> etc. A google search shows this off
> 
> I'm sure all this is already known, but it's what I ran into with it.
Actually, no, this wasn't known. Thanks for letting me know though, regression's really surprise me though! I'll look into it.
(In reply to comment #36)
> (In reply to comment #35)
> > A few things I've noticed from using the latest try server build...
> > 
> >  * Text doesn't use sub-pixel anti-aliasing, all text uses grey scale AA (last
> > build didn't do this)
> >  * text-shadow doesn't work (only the underline or such will get a shadow)
> >  * Speed is much slower than the last build, scrolling a page and animations
> > are laggy
> >  * Drag images mostly don't work, but they do under certain circumstances (Like
> > the attachment in bug 471457, the text on the left produces no drag image but
> > the text on the right does)
> >  * Transformations in certain circumstances can still produce a bad rendering,
> > such as the ctrl-tab/all tabs panel
> >  * Metrics are "off", underlines are inconsistently spaced, line-height's vary,
> > etc. A google search shows this off
> > 
> > I'm sure all this is already known, but it's what I ran into with it.

I've pushed an update to the try server builds. Since D2D performance seems to not perform much better than DWrite directly no GDI I'm using the latter everywhere now. Text shadow seems to work where I tested it. Draw images seem to work now as well. Transformations appear to work right (please do see if I missed something!).

Underline spacing is still off! I'll upload a new patch once I fix that as well. I suspect we're rounding the underline spacing somewhere, thereby causing rounding errors on where the underline is placed.
Transformations work fine with everything I tested, so does text-shadow and drag images, performance is also much better (although a bit slower for some things, the "What's Going On?" section on http://www.facepunch.com/ renders slowly when scrolling)

One thing I have noticed, is random pixels appearing when rendering text-shadow, drag images and elements using opacity (0.5, etc.). This also seems to effect sub-pixel positioning, applying a rotation to an element with opacity set causes the stair-step effect that GDI currently shows (although without the jumping, the characters stay where they are)
(In reply to comment #38)
> Transformations work fine with everything I tested, so does text-shadow and
> drag images, performance is also much better (although a bit slower for some
> things, the "What's Going On?" section on http://www.facepunch.com/ renders
> slowly when scrolling)

Fundamentally, What's Going On on that page contains a -lot- of text, particularly small text. DirectWrite does a lot more here than GDI did, to make it look good, this will probably cause the slower performance. This is a trade-off we'll have to think about.
 
> One thing I have noticed, is random pixels appearing when rendering
> text-shadow, drag images and elements using opacity (0.5, etc.). This also
> seems to effect sub-pixel positioning, applying a rotation to an element with
> opacity set causes the stair-step effect that GDI currently shows (although
> without the jumping, the characters stay where they are)

Yes, sadly I forgot to mention this in my earlier comments, these 'rogue' pixels seems to appear on every 'space' when Cairo is using glyph surfaces (any ARGB surfaces, which can't be drawn directly, like SVG masks). I'm looking into that. But I couldn't figure it out just yet, and thought it more worthwhile to see if all the major performance and transformation issues were fixed now. 

Good to hear your other problems are fixed now, I'll post an update here when I have something better to test.
OT: Would a pref for the rendering mode be possible? Besides an int that would take 7 values, the prospect of morphing gfx.font_rendering.directwrite.enabled into something that would switch to CLEARTYPE_GDI_CLASSIC when D2D is enabled rather than disabling D2D seems quite interesting. (Inspired by the confusion in bug 556193.)
(In reply to comment #40)
Ah, nvm, just noticed an extension that tunes it*, so a pref must be possible. Guess I'll experiment with the extension a bit and then file a bug or two tomorrow if a pref still seems useful.

* https://addons.mozilla.org/en-US/firefox/addon/150952/
Severity: normal → S3

The severity field for this bug is relatively low, S3. However, the bug has 23 votes.
:bas.schouten, could you consider increasing the bug severity?

For more information, please visit auto_nag documentation.

Flags: needinfo?(bas)

The last needinfo from me was triggered in error by recent activity on the bug. I'm clearing the needinfo since this is a very old bug and I don't know if it's still relevant.

Flags: needinfo?(bas)
Component: Graphics → Graphics: Text
Status: ASSIGNED → RESOLVED
Closed: 11 months ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: