diff options
author | Khaled Hosny <khaledhosny@eglug.org> | 2017-03-05 00:04:35 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2017-03-24 12:39:30 +0100 |
commit | 92093e4589da859990d384c13818a038c3b16c4b (patch) | |
tree | 099f625011eeacbf6bfc537e449782e392a47e9b /vcl | |
parent | f20bb20f8e1147d8ea1b93ee6dc216722461d456 (diff) |
Handle Tr vertical orientation before shaping
See https://github.com/behdad/harfbuzz/issues/355
(cherry picked from commit 5c617a811724a45dd8688869eeafac4c44f6a8aa)
Change-Id: Ic82d74046980fae3e7a973fee90fe5bb4f2b8588
Reviewed-on: https://gerrit.libreoffice.org/35387
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Mark Hung <marklh9@gmail.com>
(cherry picked from commit 49eadd40b5f0de6fa97498d89f20118b996385d2)
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/CommonSalLayout.hxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/CommonSalLayout.cxx | 57 |
2 files changed, 41 insertions, 18 deletions
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx index 58cba16e63d4..496d17125835 100644 --- a/vcl/inc/CommonSalLayout.hxx +++ b/vcl/inc/CommonSalLayout.hxx @@ -60,7 +60,7 @@ class CommonSalLayout : public GenericSalLayout void getScale(double* nXScale, double* nYScale); hb_set_t* mpVertGlyphs; - bool IsVerticalAlternate(hb_codepoint_t nGlyphIndex); + bool HasVerticalAlternate(sal_UCS4 aChar, sal_UCS4 aNextChar); public: #if defined(_WIN32) diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index a6ca683c15f5..df2849828df7 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -409,12 +409,16 @@ void CommonSalLayout::DrawText(SalGraphics& rSalGraphics) const rSalGraphics.DrawSalLayout( *this ); } -// Find if the given glyph index can result from applying “vert” feature. +// Find if the nominal glyph of the character is an input to “vert” feature. // We don’t check for a specific script or language as it shouldn’t matter // here; if the glyph would be the result from applying “vert” for any // script/language then we want to always treat it as upright glyph. -bool CommonSalLayout::IsVerticalAlternate(hb_codepoint_t nGlyphIndex) +bool CommonSalLayout::HasVerticalAlternate(sal_UCS4 aChar, sal_UCS4 aVariationSelector) { + hb_codepoint_t nGlyphIndex = 0; + if (!hb_font_get_glyph(mpHbFont, aChar, aVariationSelector, &nGlyphIndex)) + return false; + if (!mpVertGlyphs) { hb_face_t* pHbFace = hb_font_get_face(mpHbFont); @@ -432,7 +436,11 @@ bool CommonSalLayout::IsVerticalAlternate(hb_codepoint_t nGlyphIndex) while (hb_set_next(pLookups, &nIdx)) { hb_set_t* pGlyphs = hb_set_create(); - hb_ot_layout_lookup_collect_glyphs(pHbFace, HB_OT_TAG_GSUB, nIdx, nullptr, nullptr, nullptr, pGlyphs); + hb_ot_layout_lookup_collect_glyphs(pHbFace, HB_OT_TAG_GSUB, nIdx, + nullptr, // glyphs before + pGlyphs, // glyphs input + nullptr, // glyphs after + nullptr); // glyphs out hb_set_union(mpVertGlyphs, pGlyphs); } } @@ -516,16 +524,37 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) { sal_Int32 nPrevIdx = nIdx; sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&nIdx); - switch (vcl::GetVerticalOrientation(aChar)) + VerticalOrientation aVo = vcl::GetVerticalOrientation(aChar); + + sal_UCS4 aVariationSelector = 0; + if (nIdx < nEndRunPos) + { + sal_Int32 nNextIdx = nIdx; + sal_UCS4 aNextChar = rArgs.mrStr.iterateCodePoints(&nNextIdx); + if (u_hasBinaryProperty(aNextChar, UCHAR_VARIATION_SELECTOR)) + { + nIdx = nNextIdx; + aVariationSelector = aNextChar; + } + } + + // Charters with U and Tu vertical orientation should + // be shaped in vertical direction. But characters + // with Tr should be shaped in vertical direction + // only if they have vertical alternates, otherwise + // they should be shaped in horizontal direction + // and then rotated. + // See http://unicode.org/reports/tr50/#vo + if (aVo == VerticalOrientation::Upright || + aVo == VerticalOrientation::TransformedUpright || + (aVo == VerticalOrientation::TransformedRotated && + HasVerticalAlternate(aChar, aVariationSelector))) { - case VerticalOrientation::Upright: - case VerticalOrientation::TransformedUpright: - case VerticalOrientation::TransformedRotated: aDirection = HB_DIRECTION_TTB; - break; - default: + } + else + { aDirection = bRightToLeft ? HB_DIRECTION_RTL : HB_DIRECTION_LTR; - break; } if (aSubRuns.empty() || aSubRuns.back().maDirection != aDirection) @@ -635,13 +664,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) DeviceCoordinate nAdvance, nXOffset, nYOffset; if (aSubRun.maDirection == HB_DIRECTION_TTB) { - // If the vertical orientation is Tr, then we need to - // consider the glyph upright only if it was a vertical - // alternate (i.e. transformed). - // See http://unicode.org/reports/tr50/#vo - if (vcl::GetVerticalOrientation(aChar) != VerticalOrientation::TransformedRotated - || IsVerticalAlternate(pHbGlyphInfos[i].codepoint)) - nGlyphIndex |= GF_ROTL; + nGlyphIndex |= GF_ROTL; nAdvance = -pHbPositions[i].y_advance; nXOffset = pHbPositions[i].y_offset; |