[Libreoffice-commits] core.git: vcl/inc vcl/source

Khaled Hosny khaledhosny at eglug.org
Sat Nov 19 22:54:47 UTC 2016


 vcl/inc/CommonSalLayout.hxx        |    3 +
 vcl/source/gdi/CommonSalLayout.cxx |   60 ++++++++++++++++++++++++++++++++-----
 2 files changed, 56 insertions(+), 7 deletions(-)

New commits:
commit 0f3861e65d8e652dcc31cf9a2f2b5c1a0a73b86d
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Sat Nov 19 21:32:19 2016 +0200

    tdf#103969: Do fallback glyph rotation
    
    Charters with vertical orientation Tr (transformed rotated) should be
    rotated does not provide a vertical alternate. We check this by seeing
    if the glyph we got from HarfBuzz is possibly a vertical alternate.
    
    Change-Id: I40a0956847bedef1d67ab02ccb27a97d049ba471
    Reviewed-on: https://gerrit.libreoffice.org/30984
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Khaled Hosny <khaledhosny at eglug.org>

diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 5d54cb8..31b9dca 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -58,6 +58,9 @@ class CommonSalLayout : public GenericSalLayout
 
     void                    getScale(double* nXScale, double* nYScale);
 
+    hb_set_t*               mpVertGlyphs;
+    bool                    IsVerticalAlternate(hb_codepoint_t nGlyphIndex);
+
 public:
 #if defined(_WIN32)
     explicit                CommonSalLayout(HDC, WinFontInstance&, const WinFontFace&);
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index b9240e7..cf6a53a 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -182,6 +182,7 @@ CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance, con
 ,   mhDC(hDC)
 ,   mhFont(static_cast<HFONT>(GetCurrentObject(hDC, OBJ_FONT)))
 ,   mnAveWidthFactor(1.0f)
+,   mpVertGlyphs(nullptr)
 {
     mpHbFont = rWinFontFace.GetHbFont();
     if (!mpHbFont)
@@ -219,8 +220,9 @@ CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance, con
 
 #elif defined(MACOSX) || defined(IOS)
 CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
-:   mrFontSelData(rCoreTextStyle.maFontSelData),
-    mrCoreTextStyle(rCoreTextStyle)
+:   mrFontSelData(rCoreTextStyle.maFontSelData)
+,   mrCoreTextStyle(rCoreTextStyle)
+,   mpVertGlyphs(nullptr)
 {
     mpHbFont = rCoreTextStyle.GetHbFont();
     if (!mpHbFont)
@@ -244,8 +246,9 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
 
 #else
 CommonSalLayout::CommonSalLayout(FreetypeFont& rFreetypeFont)
-:   mrFontSelData(rFreetypeFont.GetFontSelData()),
-    mrFreetypeFont(rFreetypeFont)
+:   mrFontSelData(rFreetypeFont.GetFontSelData())
+,   mrFreetypeFont(rFreetypeFont)
+,   mpVertGlyphs(nullptr)
 {
     mpHbFont = rFreetypeFont.GetHbFont();
     if (!mpHbFont)
@@ -377,6 +380,41 @@ void CommonSalLayout::DrawText(SalGraphics& rSalGraphics) const
     rSalGraphics.DrawSalLayout( *this );
 }
 
+// Find if the given glyph index can result from applying “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)
+{
+    if (!mpVertGlyphs)
+    {
+        hb_face_t* pHbFace = hb_font_get_face(mpHbFont);
+        mpVertGlyphs = hb_set_create();
+
+        // Find all GSUB lookups for “vert” feature.
+        hb_set_t* pLookups = hb_set_create();
+        hb_tag_t  pFeatures[] = { HB_TAG('v','e','r','t'), HB_TAG_NONE };
+        hb_ot_layout_collect_lookups(pHbFace, HB_OT_TAG_GSUB, nullptr, nullptr, pFeatures, pLookups);
+        if (!hb_set_is_empty(pLookups))
+        {
+            // Find the output glyphs in each lookup (i.e. the glyphs that
+            // would result from applying this lookup).
+            hb_codepoint_t nIdx = HB_SET_VALUE_INVALID;
+            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_set_union(mpVertGlyphs, pGlyphs);
+            }
+        }
+    }
+
+    if (hb_set_has(mpVertGlyphs, nGlyphIndex))
+        return true;
+
+    return false;
+}
+
 bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
 {
     hb_face_t* pHbFace = hb_font_get_face(mpHbFont);
@@ -550,6 +588,9 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
                 if (bInCluster)
                     nGlyphFlags |= GlyphItem::IS_IN_CLUSTER;
 
+                sal_Int32 indexUtf16 = nCharPos;
+                sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0);
+
                 bool bDiacritic = false;
                 if (hb_ot_layout_has_glyph_classes(pHbFace))
                 {
@@ -560,8 +601,6 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
                 else
                 {
 #if HB_VERSION_ATLEAST(0, 9, 42)
-                    sal_Int32 indexUtf16 = nCharPos;
-                    sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0);
                     if (u_getIntPropertyValue(aChar, UCHAR_GENERAL_CATEGORY) == U_NON_SPACING_MARK)
                         bDiacritic = true;
 #else
@@ -583,7 +622,14 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
                 DeviceCoordinate nAdvance, nXOffset, nYOffset;
                 if (aSubRun.maDirection == HB_DIRECTION_TTB)
                 {
-                    nGlyphIndex |= GF_ROTL;
+                    // 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;
+
                     nAdvance = -pHbPositions[i].y_advance;
                     nXOffset =  pHbPositions[i].y_offset;
                     nYOffset =  pHbPositions[i].x_offset;


More information about the Libreoffice-commits mailing list