diff options
author | Tor Lillqvist <tml@collabora.com> | 2015-10-21 00:10:07 +0300 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2015-10-21 00:17:58 +0300 |
commit | 7323190456c2ed4ec9f092f8e69ba12ce41587cd (patch) | |
tree | 9ef3344051ab6bebf0cd914a28ccca100a19e0fc /vcl/win | |
parent | 5b6e4a225cf39355f4b345cfe033c07d5c165c7e (diff) |
tdf#94897: Don't mess up spacing of combining diacritic glyphs
At least for the Cambria font, instead of a precombined glyph,
Uniscribe ends up using a separate diacritic glyph for some (all?)
accented Latin characters. That caused weird layout errors in
justified lines when an accented character was followed by space: The
diacritic got separated from the base character.
Fix that specific case. Be careful not to mess with any other cases.
While debugging this I added lots of temporary debugging
printouts. Leave some helper functions for that behind, inside #if
0. Maybe we should start collecting such functions, including ones for
most common Win32 structs, in some include file in some common
location?
Change-Id: Ib0198411f820cb8ba8456786869185a43628628c
Diffstat (limited to 'vcl/win')
-rw-r--r-- | vcl/win/source/gdi/winlayout.cxx | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 0a6d806f418d..34bde4fc5ba6 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -701,6 +701,82 @@ UniscribeLayout::~UniscribeLayout() delete[] mpGlyphs2Chars; } +#if 0 // Don't remove -- useful for temporary SAL_ DEBUG when hacking on this + +namespace { + +template<typename IntegerType> +OUString IntegerArrayToString(IntegerType *pWords, int n) +{ + OUString result = "{"; + for (int i = 0; i < n; ++i) + { + if (i > 0) + result += ","; + if (i > 0 && i % 10 == 0) + result += OUString::number(i) + ":"; + result += OUString::number(pWords[i]); + } + result += "}"; + + return result; +} + +OUString GoffsetArrayToString(GOFFSET *pGoffsets, int n) +{ + OUString result = "{"; + for (int i = 0; i < n; ++i) + { + if (i > 0) + result += ","; + if (i > 0 && i % 10 == 0) + result += OUString::number(i) + ":"; + result += "(" + OUString::number(pGoffsets[i].du) + "," + OUString::number(pGoffsets[i].dv) + ")"; + } + result += "}"; + + return result; +} + +OUString VisAttrArrayToString(SCRIPT_VISATTR *pVisAttrs, int n) +{ + static const OUString JUSTIFICATION_NAME[] = { + "NONE", + "ARABIC_BLANK", + "CHARACTER", + "RESERVED1", + "BLANK", + "RESERVED2", + "RESERVED3", + "ARABIC_NORMAL", + "ARABIC_KASHIDA", + "ARABIC_ALEF", + "ARABIC_HA", + "ARABIC_RA", + "ARABIC_BA", + "ARABIC_BARA", + "ARABIC_SEEN", + "ARABIC_SEEN_M" + }; + + OUString result = "{"; + for (int i = 0; i < n; ++i) + { + if (i > 0) + result += ","; + if (i > 0 && i % 10 == 0) + result += OUString::number(i) + ":"; + result += OUString("{") + JUSTIFICATION_NAME[pVisAttrs[i].uJustification] + (pVisAttrs[i].fClusterStart ? OUString(",ClusterStart") : OUString()) + (pVisAttrs[i].fDiacritic ? OUString(",Diacritic") : OUString()) + OUString(pVisAttrs[i].fZeroWidth ? OUString(",ZeroWidth") : OUString()) + OUString("}"); + } + result += "}"; + + return result; +} + +} // anonymous namespace + +#endif // 0 + bool UniscribeLayout::LayoutText( ImplLayoutArgs& rArgs ) { // for a base layout only the context glyphs have to be dropped @@ -2085,6 +2161,27 @@ void UniscribeLayout::ApplyDXArray( const ImplLayoutArgs& rArgs ) mpJustifications[i] -= nXOffsetAdjust; } } + + // tdf#94897: Don't add extra justification to chars with diacritics when the diacritic is a + // separate glyph, followed by blank, in LTR + if( !rVisualItem.IsRTL() ) + { + for( i = nMinGlyphPos; i < nEndGlyphPos; ++i ) + { + const int nXOffsetAdjust = mpJustifications[i] - mpGlyphAdvances[i]; + if( nXOffsetAdjust == 0 ) + continue; + int nIdxAdd = i + 1; + while( (nIdxAdd < nEndGlyphPos) && mpVisualAttrs[nIdxAdd].fDiacritic ) + ++nIdxAdd; + if( nIdxAdd == i + 1 ) + continue; + if( nIdxAdd >= nEndGlyphPos || mpVisualAttrs[nIdxAdd].uJustification != SCRIPT_JUSTIFY_BLANK ) + continue; + mpJustifications[nIdxAdd] += nXOffsetAdjust; + mpJustifications[i] -= nXOffsetAdjust; + } + } } } |