Hi guys,
I've had the (mixed) pleasure of digging through the windows font
rendering in recent days; and I must say - I'm not thoroughly thrilled
with it =)
Let me highlight a few of the problems. First we are using GDI for text
rendering, and this is ~obsolete. Several interesting problems are
pointed out here:
http://blogs.msdn.com/b/text/archive/2009/04/15/introducing-the-directwrite-font-system.aspx
Let me excerpt the rather charitable summary of what I've been falling
over:
"For applications that need to work with fonts at a lower level,
GDI does have some functions that can really be thought of as
physical font APIs. Examples are GetFontData, GetGlyphIndices,
and even ExtTextOut when used with the ETO_GLYPH_INDEX flag.
Yet these “physical” font functions still use an HFONT to
specify the font. This means font mapping still occurs under
the hood, though since no text is specified there is no font
fallback and the same HFONT always maps to the same physical
font internally. While this model works, the lack of a true
physical font object in GDI can make it harder for application
developers that use these low-level functions to be sure of
what is going on."
Something of an under-statement there =) As far as I can see the
SimpleWinLayout - which we use sometimes (in place of the UniScribe layout)
and which has a number of fun comments in it like:
// TODO: support surrogates in rewritten strings
Essentially re-uses the non-obvious, not-really-physical-font
logic with built-in windows font fallback. In contrast the UniScribe
layout engine does not.
The particular issue I'm looking at is that it appears really hard to
get genuine ABC widths (ie. underhang, black-width, and overhang
information) for those fall-back glyphs that are actually not in the
physical font - but that Windows (un)helpfully includes from elsewhere.
Asking for metrics via 'GetCharABCWidths' yields the 'default character's
metrics:
"The ABC widths of the default character are used for characters
outside the range of the currently selected font."
Where by font, they mean physical font ignoring fallbacks it seems.
After lots of nice drawings - thanks to Tor for his nice font rendering
foo, of this kind; notice the '$' character appears from another font,
with inaccurate ABC width - hence the overlap.
info:vcl.gdi.opengl:4212:3344:vcl/win/gdi/winlayout.cxx:540: DX:offset : 17:1 10:2 11:1 9:2 11:0 0:1
info:vcl.gdi.opengl:4212:3344:vcl/win/gdi/winlayout.cxx:266: this=0CC6A0E8 32 old:
{[43..48],[182..187],[286..291],[9832..9837],[9858..9863],[55356..55361]}
info:vcl.gdi.opengl:4212:3344:vcl/win/gdi/winlayout.cxx:357: ABC widths: 0:1:14 3:3:3 1:8:1 0:16:0
1:8:2 0:22:2
info:vcl.gdi.opengl:4212:3344:vcl/win/gdi/winlayout.cxx:431: OpenSymbol: Escapement=0 Orientation=0
Ascent=23 InternalLeading=0 Size=(87,29) totWidth=82
info:vcl.gdi.opengl:4212:3344:vcl/win/gdi/winlayout.cxx:533: this=0CC6A0E8 now:
{[32..37],[43..48],[182..187],[286..291],[9832..9837],[9858..9863],[55356..55361]}
info:vcl.gdi.opengl:4212:3344:vcl/win/gdi/winlayout.cxx:176: Bitmap 7705322A: 82x33:
info:vcl.gdi.opengl:4212:3344:vcl/win/gdi/winlayout.cxx:205: | | |
| |
| | | | |
| | | | |
| | | | |
| | | 7X29 92X7 | |
| 719 | 3X0880X3 | 3X5 9108 | | 3XX19 925
| 80X3 | 3X0880X3 | 92X7 8029 | 818 | 92199219 53
| 7XX29 | 3X0880X3 | 9108 5X3 | 818 | 7X5 7X3 829
| 7XX29 | 3X0880X3 | 8029 3X5 | 80XXXX7 | 3X7 8019 927
| 7XX29 | 3X1991X5 | 5X3 9208 | 5XXXXXXX3| 91X7 8008 53
| 80X3 | 7X2992X7 | 92XXXXXXXXXXXXXX5 | 80X58187XX|791X7 9108 829
| 80X3 | 803 508 | 92XXXXXXXXXXXXXX5 | 5X3 818 3X|391X7 8008 927
| 91X5 | | 9108 5X3 | 3X5 818 | 3X7 8019 53
| 92X7 | | 8029 3X7 | 3X3 818 | 7X5 7X3 829
| 3X7 | | 5X3 9208 | 7XX5818 | 92199219 927
| 308 | | 3X5 8019 | 5XXXX29 | 3XX19 53
| 519 | | 9208 7X29 | 92XXXXX5| 829 92XX19
| 729 | | 3XXXXXXXXXXXXXX3 | 8160XX|5 927 92199208
| 84 | | 3XXXXXXXXXXXXXX3 | 818 3X|29 53 5X5 7X3
| 95 | | 5X3 9208 | 818 80|19 829 92X7 8019
| | | 3X5 8019 | 91X7 818 80|19 927 91X7 9108
| | | 92X7 7X29 | 92X3 818 5X|29 53 91X7 9108
| 92X7 | | 9119 5X5 | 7XX58187XX|5 829 92X7 8019
| 7XX29 | | 7X29 3X7 | 3XXXXXXX3| 927 5X5 7X3
| 92X7 | | 5X3 9108 | 80XXX08 | 53 92199208
| | | | 818 | 719 92XX19
| | | | 818 |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
01234 0123456 012345678901 01234567890123456789 012345678901 01234567890123456789012345
Anyhow - that's my problem #1. I'll carry on working away at it,
but it highlights the mess.
The next issue I looked at is font anti-aliasing; and I notice we
previously use either DEFAULT_QUALITY or NONANTIALIASED_QUALITY fonts
cf. vcl/win/gdi/salfont.cxx
The documentation:
https://msdn.microsoft.com/en-us/library/ms901140.aspx
suggests that DEFAULT_QUALITY can do odd and exciting things to font
metrics =) ie. "Appearance of the font does not matter." vs.
CLEARTYPE_COMPAT_QUALITY which "Enables ClearType® text for the font
using compatible widths. A compatible width produces text that has the
same spacing as non-ClearType text."
Which is also somewhat concerning. I fear that we have perhaps encoded
more platform specific font rendering information into our text than expected.
Anyhow - what to do ?
Having looked at this heap; and worse - the two different heaps for
Windows text rendering, and also the big pile of strange cross-platform
issues with stacking diacritics, emojis etc. I'm pretty convinced that
we cannot do a good job of consistent text shaping and/or rendering
cross-platform while using the Windows font rendering infrastructure.
While we could switch to DirectWrite on windows, which may solve some
of our problems; this will be in itself disruptive.
So - I believe that we should switch to using harfbuzz and freetype
consistently everywhere. This would have the huge benefit of precise
cross-platform font rendering and metric fidelity, give us a font and
shaping stack that is fully introspectable, drop some legacy Windows API
usage, and allow all development work and fixing on all platforms to
share the same underlying code.
There will of course also be some corner-cases where we may simply not
be able to replicate the tangled old layout behaviour - which is
(anyway) inconsistent across platforms - but - I think this is a one-off
risk that is well worth taking to get us to a fully consistent, Free
Software rendering stack. It is interesting that Microsoft also used freetype
for their Office / Mac rendering in the recent past =)
Thoughts appreciated,
ATB,
Michael.
--
michael.meeks@collabora.com <><, Pseudo Engineer, itinerant idiot
Context
- Windows / font / text futures ... · Michael Meeks
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.