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