[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