|
|
2135ec |
From 71077148d442b3bbfeefd9a572942946c6a95823 Mon Sep 17 00:00:00 2001
|
|
|
2135ec |
From: Khaled Hosny <khaledhosny@eglug.org>
|
|
|
2135ec |
Date: Wed, 30 Oct 2013 09:34:38 +0200
|
|
|
2135ec |
Subject: [PATCH] fdo#70968: Incorrect rendering of Devanagari short 'i' vowel
|
|
|
2135ec |
|
|
|
2135ec |
It seems that some Indic fonts assign 'mark' glyph class to combining
|
|
|
2135ec |
spacing marks (spacing not non spacing) so my reliance on the glyph
|
|
|
2135ec |
class to set the IS_DIACRITIC flags broke those fonts. This is a bandaid
|
|
|
2135ec |
to get around the issue, plus some long rant! (at this rate, I'll be
|
|
|
2135ec |
writing "The VCL haters handbook" pretty soon).
|
|
|
2135ec |
|
|
|
2135ec |
Change-Id: I3ff892acf746d50182573f94e7e8c3c6f9464ae0
|
|
|
2135ec |
---
|
|
|
2135ec |
vcl/generic/glyphs/gcach_layout.cxx | 26 +++++++++++++++++++++-----
|
|
|
2135ec |
vcl/source/gdi/sallayout.cxx | 21 +++++++++++++++++++++
|
|
|
2135ec |
2 files changed, 42 insertions(+), 5 deletions(-)
|
|
|
2135ec |
|
|
|
2135ec |
diff --git a/vcl/generic/glyphs/gcach_layout.cxx b/vcl/generic/glyphs/gcach_layout.cxx
|
|
|
2135ec |
index 4673931..7a8bfc9 100644
|
|
|
2135ec |
--- a/vcl/generic/glyphs/gcach_layout.cxx
|
|
|
2135ec |
+++ b/vcl/generic/glyphs/gcach_layout.cxx
|
|
|
2135ec |
@@ -456,20 +456,36 @@ bool HbLayoutEngine::layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
|
|
|
2135ec |
if (bInCluster)
|
|
|
2135ec |
nGlyphFlags |= GlyphItem::IS_IN_CLUSTER;
|
|
|
2135ec |
|
|
|
2135ec |
+ // The whole IS_DIACRITIC concept is a stupid hack that was
|
|
|
2135ec |
+ // introduced ages ago to work around the utter brokenness of the
|
|
|
2135ec |
+ // way justification adjustments are applied (the DXArray fiasco).
|
|
|
2135ec |
+ // Since it is such a stupid hack, there is no sane way to directly
|
|
|
2135ec |
+ // map to concepts of the "outside" world, so we do some rather
|
|
|
2135ec |
+ // ugly hacks:
|
|
|
2135ec |
+ // * If the font has a GDEF table, we check for glyphs with mark
|
|
|
2135ec |
+ // glyph class which is sensible, except that some fonts
|
|
|
2135ec |
+ // (fdo#70968) assign mark class to spacing marks (which is wrong
|
|
|
2135ec |
+ // but usually harmless), so we try to sniff what HarfBuzz thinks
|
|
|
2135ec |
+ // about this glyph by checking if it gives it a zero advance
|
|
|
2135ec |
+ // width.
|
|
|
2135ec |
+ // * If the font has no GDEF table, we just check if the glyph has
|
|
|
2135ec |
+ // zero advance width, but this is stupid and can be wrong. A
|
|
|
2135ec |
+ // better way would to check the character's Unicode combining
|
|
|
2135ec |
+ // class, but unfortunately glyph gives combining marks the
|
|
|
2135ec |
+ // cluster value of its base character, so nCharPos will be
|
|
|
2135ec |
+ // pointing to the wrong character (but HarfBuzz might change
|
|
|
2135ec |
+ // this in the future).
|
|
|
2135ec |
bool bDiacritic = false;
|
|
|
2135ec |
if (hb_ot_layout_has_glyph_classes(mpHbFace))
|
|
|
2135ec |
{
|
|
|
2135ec |
// the font has GDEF table
|
|
|
2135ec |
- if (hb_ot_layout_get_glyph_class(mpHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK)
|
|
|
2135ec |
+ bool bMark = hb_ot_layout_get_glyph_class(mpHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
|
|
|
2135ec |
+ if (bMark && pHbPositions[i].x_advance == 0)
|
|
|
2135ec |
bDiacritic = true;
|
|
|
2135ec |
}
|
|
|
2135ec |
else
|
|
|
2135ec |
{
|
|
|
2135ec |
// the font lacks GDEF table
|
|
|
2135ec |
- // HACK: if the resolved glyph advance is zero assume it is a
|
|
|
2135ec |
- // combining mark. The whole IS_DIACRITIC concept is a hack to
|
|
|
2135ec |
- // fix the other hacks we use to second-guess glyph advances in
|
|
|
2135ec |
- // ApplyDXArray and the likes and it needs to die
|
|
|
2135ec |
if (pHbPositions[i].x_advance == 0)
|
|
|
2135ec |
bDiacritic = true;
|
|
|
2135ec |
}
|
|
|
2135ec |
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
|
|
|
2135ec |
index f395936..450ec232 100644
|
|
|
2135ec |
--- a/vcl/source/gdi/sallayout.cxx
|
|
|
2135ec |
+++ b/vcl/source/gdi/sallayout.cxx
|
|
|
2135ec |
@@ -1018,6 +1018,27 @@ void GenericSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
|
|
|
2135ec |
|
|
|
2135ec |
// -----------------------------------------------------------------------
|
|
|
2135ec |
|
|
|
2135ec |
+// This DXArray thing is one of the stupidest ideas I have ever seen (I've been
|
|
|
2135ec |
+// told that it probably a one-to-one mapping of some Windows 3.1 API, which is
|
|
|
2135ec |
+// telling). To justify a text string, Writer calls OutputDevice::GetTextArray()
|
|
|
2135ec |
+// to get an array that maps input characters (not glyphs) to their absolute
|
|
|
2135ec |
+// position, GetTextArray() in turn calls SalLayout::FillDXArray() to get an
|
|
|
2135ec |
+// array of character widths that it converts to absolute positions.
|
|
|
2135ec |
+//
|
|
|
2135ec |
+// Writer would then apply justification adjustments to that array of absolute
|
|
|
2135ec |
+// character positions and return to OutputDevice, which eventually calls
|
|
|
2135ec |
+// ApplyDXArray(), which needs to extract the individual adjustments for each
|
|
|
2135ec |
+// character to apply it to corresponding glyphs, and since that information is
|
|
|
2135ec |
+// already lost it tries to do some heuristics to guess it again. Those
|
|
|
2135ec |
+// heuristics often fail, and have always been a source of all sorts of weird
|
|
|
2135ec |
+// text layout bugs, and instead of fixing the broken design a hack after hack
|
|
|
2135ec |
+// have been applied on top of it, making it a complete mess that nobody
|
|
|
2135ec |
+// understands.
|
|
|
2135ec |
+//
|
|
|
2135ec |
+// As you can see by now, this is utterly stupid, why Writer does not just send
|
|
|
2135ec |
+// us directly the advance width transformations it wants to apply to each
|
|
|
2135ec |
+// character instead of this whole mess?
|
|
|
2135ec |
+
|
|
|
2135ec |
void GenericSalLayout::ApplyDXArray( ImplLayoutArgs& rArgs )
|
|
|
2135ec |
{
|
|
|
2135ec |
if( m_GlyphItems.empty())
|
|
|
2135ec |
--
|
|
|
2135ec |
1.8.3.1
|
|
|
2135ec |
|