vcl/source/gdi/CommonSalLayout.cxx | 92 ++++++++++++++++++++++++++++---- vcl/unx/generic/gdi/cairotextrender.cxx | 5 + 2 files changed, 86 insertions(+), 11 deletions(-)
New commits: commit b2fef34ef91b155d21b07cd6c0a0233810b80db9 Author: Khaled Hosny <khaledho...@eglug.org> Date: Mon Sep 26 19:09:52 2016 +0200 Support vertical text in CommonSalLayout Change-Id: I52a71c9c21ad75c7cb9c8574e5e7e3b7c1c0c0c3 diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index feb37eb..7ee034a 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -212,12 +212,12 @@ struct HbScriptRun { int32_t mnMin; int32_t mnEnd; - hb_script_t maScript; + UScriptCode maScript; HbScriptRun(int32_t nMin, int32_t nEnd, UScriptCode aScript) : mnMin(nMin) , mnEnd(nEnd) - , maScript(hb_icu_script_to_script(aScript)) + , maScript(aScript) {} }; @@ -307,6 +307,47 @@ void CommonSalLayout::DrawText(SalGraphics& rSalGraphics) const rSalGraphics.DrawSalLayout( *this ); } +/* https://drafts.csswg.org/css-writing-modes-3/#script-orientations */ +static int GetVerticalFlagsForScript(UScriptCode aScript) +{ + int nFlag = GF_NONE; + + switch (aScript) + { + /* ttb 0° */ + case USCRIPT_BOPOMOFO: + case USCRIPT_EGYPTIAN_HIEROGLYPHS: + case USCRIPT_HAN: + case USCRIPT_HANGUL: + case USCRIPT_HIRAGANA: + case USCRIPT_KATAKANA: + case USCRIPT_MEROITIC_CURSIVE: + case USCRIPT_MEROITIC_HIEROGLYPHS: + case USCRIPT_YI: + nFlag = GF_ROTL; + break; +#if 0 + /* ttb 90° */ + case USCRIPT_MONGOLIAN: + case USCRIPT_PHAGS_PA: + nFlag = ??; + break; + /* ttb -90° */ + case USCRIPT_ORKHON: + nFlag = ??; + break; + /* btt -90° */ + case USCRIPT_MONGOLIAN: + nFlag = ??; + break; +#endif + default: + break; + } + + return nFlag; +} + bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) { hb_script_t aHbScript = HB_SCRIPT_INVALID; @@ -371,11 +412,19 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) int nMinRunPos = aScriptRun.mnMin; int nEndRunPos = aScriptRun.mnEnd; int nRunLen = nEndRunPos - nMinRunPos; - aHbScript = aScriptRun.maScript; + aHbScript = hb_icu_script_to_script(aScriptRun.maScript); + // hb_language_from_string() accept ISO639-3 language tag except for Chinese. LanguageTag &rTag = rArgs.maLanguageTag; OString sLanguage = OUStringToOString(rTag.getBcp47(), RTL_TEXTENCODING_ASCII_US); + bool bVertical = false; + if ((rArgs.mnFlags & SalLayoutFlags::Vertical) && + GetVerticalFlagsForScript(aScriptRun.maScript) == GF_ROTL) + { + bVertical = true; + } + int nHbFlags = HB_BUFFER_FLAGS_DEFAULT; if (nMinRunPos == 0) nHbFlags |= HB_BUFFER_FLAG_BOT; /* Beginning-of-text */ @@ -387,7 +436,10 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) static hb_unicode_funcs_t* pHbUnicodeFuncs = getUnicodeFuncs(); hb_buffer_set_unicode_funcs(pHbBuffer, pHbUnicodeFuncs); #endif - hb_buffer_set_direction(pHbBuffer, bRightToLeft ? HB_DIRECTION_RTL: HB_DIRECTION_LTR); + if (bVertical) + hb_buffer_set_direction(pHbBuffer, HB_DIRECTION_TTB); + else + hb_buffer_set_direction(pHbBuffer, bRightToLeft ? HB_DIRECTION_RTL: HB_DIRECTION_LTR); hb_buffer_set_script(pHbBuffer, aHbScript); hb_buffer_set_language(pHbBuffer, hb_language_from_string(sLanguage.getStr(), -1)); hb_buffer_set_flags(pHbBuffer, (hb_buffer_flags_t) nHbFlags); @@ -452,17 +504,35 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) if (bDiacritic) nGlyphFlags |= GlyphItem::IS_DIACRITIC; - int32_t nXOffset = pHbPositions[i].x_offset >> 6; - int32_t nYOffset = pHbPositions[i].y_offset >> 6; - int32_t nXAdvance = pHbPositions[i].x_advance >> 6; - int32_t nYAdvance = pHbPositions[i].y_advance >> 6; + int32_t nAdvance, nXOffset, nYOffset; + if (bVertical) + { + int nVertFlag; +#if 0 /* XXX: does not work as expected for Common script */ + UErrorCode error = U_ZERO_ERROR; + nVertFlag = GetVerticalFlagsForScript(uscript_getScript(aChar, &error)); +#else + nVertFlag = GetVerticalFlags(aChar); + if (nVertFlag == GF_ROTR) + nVertFlag = GF_ROTL; +#endif + nGlyphIndex |= nVertFlag; + nAdvance = -pHbPositions[i].y_advance >> 6; + nXOffset = pHbPositions[i].y_offset >> 6; + nYOffset = -pHbPositions[i].x_offset >> 6; + } + else + { + nAdvance = pHbPositions[i].x_advance >> 6; + nXOffset = pHbPositions[i].x_offset >> 6; + nYOffset = pHbPositions[i].y_offset >> 6; + } Point aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset)); - const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nXAdvance, nXOffset); + const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nAdvance, nXOffset); AppendGlyph(aGI); - aCurrPos.X() += nXAdvance; - aCurrPos.Y() += nYAdvance; + aCurrPos.X() += nAdvance; } hb_buffer_destroy(pHbBuffer); diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index 35d086d..9fe2ea5 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -323,6 +323,11 @@ void CairoTextRender::DrawServerFontLayout( const GenericSalLayout& rLayout, con { ydiff = font_extents.ascent/nHeight; xdiff = -font_extents.descent/nHeight; + if (SalLayout::UseCommonLayout()) + { + ydiff -= font_extents.descent/nHeight; + xdiff = 0; + } } else if (nGlyphRotation == -1) {
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits