Rebased ref, commits from common ancestor: commit c74ddf0d07c34dc5b20853be752508bce7a67578 Author: Khaled Hosny <khaledho...@eglug.org> Date: Mon Oct 10 00:54:00 2016 +0200
Validate Kashida positions in CommonSalLayout Currently checks only for ligatures, but that is a big improvement over al code that didnât do any validation except on Windows. Change-Id: I035248f4ccc23134ea27b40c2dd6197130749f14 diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx index e9116ba..8ee1255 100644 --- a/vcl/inc/CommonSalLayout.hxx +++ b/vcl/inc/CommonSalLayout.hxx @@ -68,4 +68,6 @@ public: virtual bool GetCharWidths(DeviceCoordinate* pCharWidths) const override; virtual void ApplyDXArray(ImplLayoutArgs&) override; + + virtual bool IsKashidaPosValid(int nCharPos) const override; }; diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index e338261..0bbab99 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -612,3 +612,30 @@ void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs) } } } + +bool CommonSalLayout::IsKashidaPosValid(int nCharPos) const +{ + for (auto pIter = m_GlyphItems.begin(); pIter != m_GlyphItems.end(); ++pIter) + { + if (pIter->mnCharPos == nCharPos) + { + // Search backwards for previous glyph belonging to a different + // character. We are looking backwards because we are dealing with + // RTL glyphs, which will be in visual order. + for (auto pPrev = pIter - 1; pPrev != m_GlyphItems.begin(); --pPrev) + { + if (pPrev->mnCharPos != nCharPos) + { + // Check if the found glyph belongs to the next character, + // otherwise the current glyph will be a ligature which is + // invalid kashida position. + if (pPrev->mnCharPos == (nCharPos + 1)) + return true; + break; + } + } + } + } + + return false; +} commit 7b36271ca9095c60c01a3810df2e42334e02a8de Author: Khaled Hosny <khaledho...@eglug.org> Date: Sun Oct 9 23:23:45 2016 +0200 Re-enable Kashida insertion in CommonSalLayout We now do Kashida insertion in ApplyDXArray(), no need for a separate step. This simplifies the code greatly (old code is in GenericSalLayout::KashidaJustify()). Change-Id: Ie31c8969e26f1f293820f1e90f963a5ba1fc9eb1 diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 433fbee..e338261 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -283,27 +283,18 @@ void CommonSalLayout::SetNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nCharPos, void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs) { - GenericSalLayout::AdjustLayout(rArgs); + SalLayout::AdjustLayout(rArgs); + + if (rArgs.mpDXArray) + ApplyDXArray(rArgs); + else if (rArgs.mnLayoutWidth) + Justify(rArgs.mnLayoutWidth); // apply asian kerning if the glyphs are not already formatted if( (rArgs.mnFlags & SalLayoutFlags::KerningAsian) && !(rArgs.mnFlags & SalLayoutFlags::Vertical) ) if( (rArgs.mpDXArray != nullptr) || (rArgs.mnLayoutWidth != 0) ) ApplyAsianKerning(rArgs.mrStr); - - if((rArgs.mnFlags & SalLayoutFlags::KashidaJustification) && rArgs.mpDXArray) - { - hb_codepoint_t nKashidaCodePoint = 0x0640; - hb_codepoint_t nKashidaGlyphIndex; - - if(hb_font_get_glyph(mpHbFont, nKashidaCodePoint, 0, &nKashidaGlyphIndex)) - { - if(nKashidaGlyphIndex) - { - KashidaJustify(nKashidaGlyphIndex, hb_font_get_glyph_h_advance(mpHbFont, nKashidaGlyphIndex) >> 6); - } - } - } } void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const @@ -546,6 +537,16 @@ void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs) pNewCharWidths[i] = rArgs.mpDXArray[i] - rArgs.mpDXArray[i - 1]; } + DeviceCoordinate nKashidaWidth = 0; + hb_codepoint_t nKashidaIndex; + if (rArgs.mnFlags & SalLayoutFlags::KashidaJustification) + { + if (hb_font_get_glyph(mpHbFont, 0x0640, 0, &nKashidaIndex)) + nKashidaWidth = hb_font_get_glyph_h_advance(mpHbFont, nKashidaIndex) / 64; + } + + std::map<size_t, DeviceCoordinate> pKashidas; + DeviceCoordinate nDelta = 0; size_t i = 0; while (i < m_GlyphItems.size()) @@ -553,16 +554,61 @@ void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs) int nCharPos = m_GlyphItems[i].mnCharPos - mnMinCharPos; DeviceCoordinate nDiff = pNewCharWidths[nCharPos] - pOldCharWidths[nCharPos]; - m_GlyphItems[i].maLinearPos.X() += nDelta; + if (nKashidaWidth && nDiff) + pKashidas[i] = nDiff; + size_t j = i; - while (++j < m_GlyphItems.size()) + while (j < m_GlyphItems.size()) { if (m_GlyphItems[j].mnCharPos != m_GlyphItems[i].mnCharPos) break; m_GlyphItems[j].maLinearPos.X() += nDelta; + // For RTL, put all justification space to the left of the glyph. + if (m_GlyphItems[i].IsRTLGlyph()) + m_GlyphItems[j].maLinearPos.X() += nDiff; + ++j; } nDelta += nDiff; i = j; } + + if (!pKashidas.empty()) + { + size_t nInserted = 0; + for (auto const& pKashida : pKashidas) + { + auto pGlyphIter = m_GlyphItems.begin() + nInserted + pKashida.first; + + if (!pGlyphIter->IsRTLGlyph()) + continue; + + sal_Int32 indexUtf16 = pGlyphIter->mnCharPos; + sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0); + static hb_unicode_funcs_t* pHbUnicodeFuncs = getUnicodeFuncs(); + if (hb_unicode_general_category (pHbUnicodeFuncs, aChar) == HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR) + continue; + + DeviceCoordinate nGapWidth = pKashida.second; + int nKashidaCount = ceil(nGapWidth / nKashidaWidth); + DeviceCoordinate nInsertedKashidaWidth; + if (nGapWidth < nKashidaWidth) + nInsertedKashidaWidth = nGapWidth; + else + nInsertedKashidaWidth = nGapWidth / nKashidaCount; + + Point aPos(pGlyphIter->maLinearPos.X() - nGapWidth, 0); + int nCharPos = pGlyphIter->mnCharPos; + int nFlags = GlyphItem::IS_IN_CLUSTER | GlyphItem::IS_RTL_GLYPH; + while (nKashidaCount) + { + GlyphItem aKashida(nCharPos, nKashidaIndex, aPos, nFlags, nInsertedKashidaWidth); + pGlyphIter = m_GlyphItems.insert(pGlyphIter, aKashida); + aPos.X() += nInsertedKashidaWidth; + ++pGlyphIter; + ++nInserted; + --nKashidaCount; + } + } + } } commit 13d388b2468572c67d9d8b96536b07eadc28e70c Author: Khaled Hosny <khaledho...@eglug.org> Date: Sun Oct 9 19:08:18 2016 +0200 Revert "Use HarfBuzz shape plan for a bit more control" This reverts commit 8b32ead0b988b142cd9878f126d985d946fd4ccc. diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index bd1b029..433fbee 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -314,7 +314,6 @@ void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) { - hb_face_t* pHbFace = hb_font_get_face(mpHbFont); hb_script_t aHbScript = HB_SCRIPT_INVALID; int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos); @@ -416,13 +415,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) #if HB_VERSION_ATLEAST(0, 9, 42) hb_buffer_set_cluster_level(pHbBuffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); #endif - const char *pHbShapers[5] = { "coretext_aat", "graphite2", "ot", "fallback", nullptr }; - hb_segment_properties_t aHbProps; - hb_buffer_get_segment_properties(pHbBuffer, &aHbProps); - hb_shape_plan_t *pHbPlan = hb_shape_plan_create_cached(pHbFace, &aHbProps, nullptr, 0, pHbShapers); - assert(hb_shape_plan_execute(pHbPlan, mpHbFont, pHbBuffer, nullptr, 0)); - hb_buffer_set_content_type(pHbBuffer, HB_BUFFER_CONTENT_TYPE_GLYPHS); - SAL_INFO("vcl.harfbuzz", hb_shape_plan_get_shaper(pHbPlan) << " shaper used for " << rArgs); + hb_shape(mpHbFont, pHbBuffer, nullptr, 0); int nRunGlyphCount = hb_buffer_get_length(pHbBuffer); hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr); @@ -455,6 +448,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) nGlyphFlags |= GlyphItem::IS_IN_CLUSTER; bool bDiacritic = false; + hb_face_t* pHbFace = hb_font_get_face(mpHbFont); if (hb_ot_layout_has_glyph_classes(pHbFace)) { // the font has GDEF table commit 793771e9c0bc6fcd34633375f0bd920c0f20ad22 Author: Khaled Hosny <khaledho...@eglug.org> Date: Thu Oct 6 04:15:41 2016 +0200 Use HarfBuzz shape plan for a bit more control This way we control exactly what shapers we use in what order, and as an extra we can now tell which shaper HarfBuzz ends up using. Change-Id: Idd303b2a557e16ac86ada0c2006d3e2a052ac489 diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 433fbee..bd1b029 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -314,6 +314,7 @@ void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) { + hb_face_t* pHbFace = hb_font_get_face(mpHbFont); hb_script_t aHbScript = HB_SCRIPT_INVALID; int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos); @@ -415,7 +416,13 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) #if HB_VERSION_ATLEAST(0, 9, 42) hb_buffer_set_cluster_level(pHbBuffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); #endif - hb_shape(mpHbFont, pHbBuffer, nullptr, 0); + const char *pHbShapers[5] = { "coretext_aat", "graphite2", "ot", "fallback", nullptr }; + hb_segment_properties_t aHbProps; + hb_buffer_get_segment_properties(pHbBuffer, &aHbProps); + hb_shape_plan_t *pHbPlan = hb_shape_plan_create_cached(pHbFace, &aHbProps, nullptr, 0, pHbShapers); + assert(hb_shape_plan_execute(pHbPlan, mpHbFont, pHbBuffer, nullptr, 0)); + hb_buffer_set_content_type(pHbBuffer, HB_BUFFER_CONTENT_TYPE_GLYPHS); + SAL_INFO("vcl.harfbuzz", hb_shape_plan_get_shaper(pHbPlan) << " shaper used for " << rArgs); int nRunGlyphCount = hb_buffer_get_length(pHbBuffer); hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr); @@ -448,7 +455,6 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) nGlyphFlags |= GlyphItem::IS_IN_CLUSTER; bool bDiacritic = false; - hb_face_t* pHbFace = hb_font_get_face(mpHbFont); if (hb_ot_layout_has_glyph_classes(pHbFace)) { // the font has GDEF table commit 3298e627e15a9773829623f524c65e2709edf3b1 Author: Khaled Hosny <khaledho...@eglug.org> Date: Mon Sep 26 19:09:52 2016 +0200 First try on vertical text in CommonSalLayout Does not work quite right yet. Change-Id: I52a71c9c21ad75c7cb9c8574e5e7e3b7c1c0c0c3 diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 20310b6..433fbee 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -381,6 +381,16 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) LanguageTag &rTag = rArgs.maLanguageTag; OString sLanguage = OUStringToOString(rTag.getBcp47(), RTL_TEXTENCODING_ASCII_US); + bool bVertical = false; + if ((rArgs.mnFlags & SalLayoutFlags::Vertical) && + (aHbScript == HB_SCRIPT_HAN || + aHbScript == HB_SCRIPT_HANGUL || + aHbScript == HB_SCRIPT_HIRAGANA || + aHbScript == HB_SCRIPT_KATAKANA)) + { + bVertical = true; + } + int nHbFlags = HB_BUFFER_FLAGS_DEFAULT; if (nMinRunPos == 0) nHbFlags |= HB_BUFFER_FLAG_BOT; /* Beginning-of-text */ @@ -392,7 +402,10 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) #if !HB_VERSION_ATLEAST(1, 1, 0) hb_buffer_set_unicode_funcs(pHbBuffer, pHbUnicodeFuncs); #endif - hb_buffer_set_direction(pHbBuffer, bRightToLeft ? HB_DIRECTION_RTL: HB_DIRECTION_LTR); + if (SAL_UNLIKELY(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); @@ -457,17 +470,31 @@ 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 nXOffset; + int32_t nYOffset; + int32_t nXAdvance; + Point aNewPos; + + if (SAL_UNLIKELY(bVertical)) + { + nXOffset = pHbPositions[i].y_offset >> 6; + nYOffset = pHbPositions[i].x_offset >> 6; + nXAdvance = pHbPositions[i].y_advance >> 6; + nGlyphIndex |= GF_ROTL; + aNewPos = Point(-(aCurrPos.X() + nXOffset), aCurrPos.Y() + nYOffset); + } + else + { + nXOffset = pHbPositions[i].x_offset >> 6; + nYOffset = pHbPositions[i].y_offset >> 6; + nXAdvance = pHbPositions[i].x_advance >> 6; + aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset)); + } - Point aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset)); const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nXAdvance, nXOffset); AppendGlyph(aGI); aCurrPos.X() += nXAdvance; - aCurrPos.Y() += nYAdvance; } hb_buffer_destroy(pHbBuffer); commit 5447455d02b749bd217dac06a9c690fb7b0115bf Author: Khaled Hosny <khaledho...@eglug.org> Date: Sat Sep 24 23:13:47 2016 +0200 Use range loop Change-Id: I5ce49e57ed57378b4b9e16c8bb020048644252a9 diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 05b136d..20310b6 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -371,12 +371,12 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) if (bRightToLeft) std::reverse(aScriptSubRuns.begin(), aScriptSubRuns.end()); - for (HbScriptRuns::iterator it = aScriptSubRuns.begin(); it != aScriptSubRuns.end(); ++it) + for (const auto& aScriptRun : aScriptSubRuns) { - int nMinRunPos = it->mnMin; - int nEndRunPos = it->mnEnd; + int nMinRunPos = aScriptRun.mnMin; + int nEndRunPos = aScriptRun.mnEnd; int nRunLen = nEndRunPos - nMinRunPos; - aHbScript = it->maScript; + aHbScript = 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); commit eec9fb46f330e402a026c71e693823f3a8eb951e Author: Khaled Hosny <khaledho...@eglug.org> Date: Sat Sep 24 23:04:39 2016 +0200 Use const reference Change-Id: I0f632f3a8b480f785608aa081add1b1d2fefd312 diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx index 89214d4..e9116ba 100644 --- a/vcl/inc/CommonSalLayout.hxx +++ b/vcl/inc/CommonSalLayout.hxx @@ -36,7 +36,7 @@ class CommonSalLayout : public GenericSalLayout { hb_font_t* mpHbFont; - FontSelectPattern maFontSelData; + const FontSelectPattern& mrFontSelData; css::uno::Reference<css::i18n::XBreakIterator> mxBreak; #ifdef _WIN32 HDC mhDC; diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 7698bab..05b136d 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -129,7 +129,7 @@ static hb_unicode_funcs_t* getUnicodeFuncs() CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontInstance, const WinFontFace& rWinFontFace) : mhFont((HFONT)GetCurrentObject(WSL->getHDC(), OBJ_FONT)), mhDC(WSL->getHDC()), - maFontSelData(rWinFontInstance.maFontSelData), + mrFontSelData(rWinFontInstance.maFontSelData), mpD2DRenderer(nullptr) { mpHbFont = rWinFontFace.GetHbFont(); @@ -153,7 +153,7 @@ CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontI hb_face_destroy(pHbFace); } - scaleHbFont(mpHbFont, maFontSelData); + scaleHbFont(mpHbFont, mrFontSelData); } void CommonSalLayout::InitFont() const @@ -163,7 +163,7 @@ void CommonSalLayout::InitFont() const #elif defined(MACOSX) || defined(IOS) CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle) -: maFontSelData(rCoreTextStyle.maFontSelData), +: mrFontSelData(rCoreTextStyle.maFontSelData), mrCoreTextStyle(rCoreTextStyle) { mpHbFont = rCoreTextStyle.GetHbFont(); @@ -184,12 +184,12 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle) hb_face_destroy(pHbFace); } - scaleHbFont(mpHbFont, maFontSelData); + scaleHbFont(mpHbFont, mrFontSelData); } #else CommonSalLayout::CommonSalLayout(ServerFont& rServerFont) -: maFontSelData(rServerFont.GetFontSelData()), +: mrFontSelData(rServerFont.GetFontSelData()), mrServerFont(rServerFont) { mpHbFont = rServerFont.GetHbFont(); @@ -203,7 +203,7 @@ CommonSalLayout::CommonSalLayout(ServerFont& rServerFont) hb_face_destroy(pHbFace); } - scaleHbFont(mpHbFont, maFontSelData); + scaleHbFont(mpHbFont, mrFontSelData); } #endif commit 44d8b051018dab82648bb65b4de401b8860aab0d Author: Khaled Hosny <khaledho...@eglug.org> Date: Fri Sep 23 18:34:09 2016 +0200 Make sure HarfBuzz module depends on Graphite Change-Id: I9c1cc9c679ceebeb4e5cd898876aaa7b61c18f17 diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index 64eeacf..c818136 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -1368,6 +1368,8 @@ $(call gb_LinkTarget_add_libs,$(1),$(GRAPHITE_LIBS)) endef +gb_ExternalProject__use_graphite:= + else # !SYSTEM_GRAPHITE define gb_LinkTarget__use_graphite @@ -1382,6 +1384,10 @@ $(call gb_LinkTarget_use_static_libraries,$(1),\ endef +define gb_ExternalProject__use_graphite +$(call gb_ExternalProject_use_external_project,$(1),graphite) + +endef endif # SYSTEM_GRAPHITE ifneq ($(SYSTEM_ICU),) diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk b/external/harfbuzz/ExternalProject_harfbuzz.mk index 1be5c6f..57cfc44 100644 --- a/external/harfbuzz/ExternalProject_harfbuzz.mk +++ b/external/harfbuzz/ExternalProject_harfbuzz.mk @@ -17,6 +17,7 @@ $(eval $(call gb_ExternalProject_register_targets,harfbuzz,\ $(eval $(call gb_ExternalProject_use_externals,harfbuzz,\ icu \ + graphite \ )) $(call gb_ExternalProject_get_state_target,harfbuzz,build) : commit ad594e7c82aa4cc40f95d4308dcb8bb1f01786eb Author: Khaled Hosny <khaledho...@eglug.org> Date: Thu Sep 22 07:57:04 2016 -0700 Build HarfBuzz with Core Text on Mac To enable support for AAT fonts. Change-Id: Ifcc7d1672e98f8c067482400b7e45226bed4dbf1 diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk b/external/harfbuzz/ExternalProject_harfbuzz.mk index 4412815..1be5c6f 100644 --- a/external/harfbuzz/ExternalProject_harfbuzz.mk +++ b/external/harfbuzz/ExternalProject_harfbuzz.mk @@ -36,6 +36,7 @@ $(call gb_ExternalProject_get_state_target,harfbuzz,build) : --with-cairo=no \ --with-glib=no \ --with-graphite2=yes \ + $(if $(filter MACOSX,$(OS)),--with-coretext=yes) \ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \ $(if $(CROSS_COMPILING),--build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM)) \ $(if $(filter LINUX,$(OS)),CXXFLAGS="$(CXXFLAGS) -fvisibility=hidden") \ commit 6d9bf14e3c0f458dc024f08035675e78f51f30e4 Author: Khaled Hosny <khaledho...@eglug.org> Date: Thu Sep 22 19:48:10 2016 +0200 Always pass BCP 47 tags to HarfBuzz This is what it is expecting anyway, no need to special case it for Chinese. Change-Id: I6732412375d19816b599005d78abd796f67599ee diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index a5e3bf6..7698bab 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -379,7 +379,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) aHbScript = it->maScript; // hb_language_from_string() accept ISO639-3 language tag except for Chinese. LanguageTag &rTag = rArgs.maLanguageTag; - OString sLanguage = OUStringToOString( MsLangId::isChinese(rTag.getLanguageType()) ? rTag.getBcp47():rTag.getLanguage() , RTL_TEXTENCODING_UTF8 ); + OString sLanguage = OUStringToOString(rTag.getBcp47(), RTL_TEXTENCODING_ASCII_US); int nHbFlags = HB_BUFFER_FLAGS_DEFAULT; if (nMinRunPos == 0) commit 63c7b0eaf502bd184757917212caab1c424f52ce Author: Khaled Hosny <khaledho...@eglug.org> Date: Thu Sep 22 19:45:23 2016 +0200 Always build Graphite everywhere It is no longer an optional feature on any platform. The --enable-graphite stuff is kept as it controls the old Graphite integration code and it should be removed without. Change-Id: Ib4d76bba782a1439f02f93411b22d237a1987ea5 diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index e0f1337..64eeacf 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -1357,8 +1357,6 @@ endef endif # SYSTEM_FONTCONFIG -ifeq ($(ENABLE_GRAPHITE),TRUE) - ifneq ($(SYSTEM_GRAPHITE),) define gb_LinkTarget__use_graphite @@ -1386,12 +1384,6 @@ endef endif # SYSTEM_GRAPHITE -else # !ENABLE_GRAPHITE - -gb_LinkTarget__use_graphite := - -endif # ENABLE_GRAPHITE - ifneq ($(SYSTEM_ICU),) gb_LinkTarget__use_icu_headers:= diff --git a/configure.ac b/configure.ac index d67054b..1419367 100644 --- a/configure.ac +++ b/configure.ac @@ -9240,19 +9240,20 @@ AC_SUBST(ICU_LIBS) dnl =================================================================== dnl Graphite dnl =================================================================== +libo_CHECK_SYSTEM_MODULE([graphite],[GRAPHITE],[graphite2 >= 0.9.3],["-I${WORKDIR}/UnpackedTarball/graphite/include"],["-L${WORKDIR}/LinkTarget/StaticLibrary -lgraphite"]) +if test "$with_system_graphite" = "yes"; then + libo_MINGW_CHECK_DLL([libgraphite2]) +fi +if test "$COM" = "MSC"; then # override the above + GRAPHITE_LIBS="${WORKDIR}/LinkTarget/StaticLibrary/graphite.lib" +fi +# This is the old Graphite support that will eventually be removed AC_MSG_CHECKING([whether to enable graphite support]) if test $_os != Darwin -a $_os != Android -a $_os != iOS -a \( -z "$enable_graphite" -o "$enable_graphite" != no \); then AC_MSG_RESULT([yes]) ENABLE_GRAPHITE="TRUE" AC_DEFINE(ENABLE_GRAPHITE) - libo_CHECK_SYSTEM_MODULE([graphite],[GRAPHITE],[graphite2 >= 0.9.3],["-I${WORKDIR}/UnpackedTarball/graphite/include"],["-L${WORKDIR}/LinkTarget/StaticLibrary -lgraphite"]) - if test "$with_system_graphite" = "yes"; then - libo_MINGW_CHECK_DLL([libgraphite2]) - fi - if test "$COM" = "MSC"; then # override the above - GRAPHITE_LIBS="${WORKDIR}/LinkTarget/StaticLibrary/graphite.lib" - fi else AC_MSG_RESULT([no]) @@ -9339,6 +9340,9 @@ if test "$COM" = "MSC"; then # override the above HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib" fi if test "$with_system_harfbuzz" = "yes"; then + if test "$with_system_graphite" = "no"; then + AC_MSG_ERROR([--with-system-graphite must be used when --with-system-harfbuzz is used]) + fi AC_MSG_CHECKING([whether system Harfbuzz is built with Graphite support]) _save_libs="$LIBS" _save_cflags="$CFLAGS" @@ -9347,6 +9351,10 @@ if test "$with_system_harfbuzz" = "yes"; then AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])]) LIBS="$_save_libs" CFLAGS="$_save_cflags" +else + if test "$with_system_graphite" = "yes"; then + AC_MSG_ERROR([--without-system-graphite must be used when --without-system-harfbuzz is used]) + fi fi AC_MSG_CHECKING([whether to use X11]) diff --git a/vcl/CppunitTest_vcl_wmf_test.mk b/vcl/CppunitTest_vcl_wmf_test.mk index 51e9126..1de86d8 100644 --- a/vcl/CppunitTest_vcl_wmf_test.mk +++ b/vcl/CppunitTest_vcl_wmf_test.mk @@ -80,6 +80,7 @@ endif $(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ gio \ + graphite \ harfbuzz \ icuuc \ lcms2 \ @@ -90,10 +91,6 @@ $(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ )) endif -ifeq ($(ENABLE_GRAPHITE),TRUE) -$(eval $(call gb_CppunitTest_use_external,vcl_wmf_test,graphite)) -endif - ifeq ($(OS),MACOSX) $(eval $(call gb_CppunitTest_use_system_darwin_frameworks,vcl_wmf_test,\ ApplicationServices \ diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 67bcbe5..2b0874a 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -116,6 +116,7 @@ $(eval $(call gb_Library_use_externals,vcl,\ boost_headers \ gio \ glm_headers \ + graphite \ harfbuzz \ icu_headers \ icuuc \ @@ -434,8 +435,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ )) endif -$(eval $(call gb_Library_use_external,vcl,graphite)) - endif vcl_quartz_code= \ commit 424d47ade5bf3081bb01a4a93aebcf72c590fe2f Author: Khaled Hosny <khaledho...@eglug.org> Date: Thu Sep 22 19:29:04 2016 +0200 Always build HarfBuzz everywhere It is no longer an optional feature on any platform. Change-Id: I70cdcd2c0df69d961ecc5f36b4e8d035d251ef16 diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index 95241ab..e0f1337 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -1490,7 +1490,6 @@ endef endif # SYSTEM_ICU -ifeq ($(ENABLE_HARFBUZZ),TRUE) ifneq ($(SYSTEM_HARFBUZZ),) define gb_LinkTarget__use_harfbuzz @@ -1515,11 +1514,6 @@ $(call gb_LinkTarget_use_external_project,$(1),harfbuzz) endef endif # SYSTEM_HARFBUZZ -else # ENABLE_HARFBUZZ != YES - -gb_LinkTarget__use_harfbuzz := - -endif # ENABLE_HARFBUZZ ifeq ($(DISABLE_OPENSSL),TRUE) diff --git a/config_host.mk.in b/config_host.mk.in index 2e6d007..90c25a6 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -133,7 +133,6 @@ export ENABLE_FIREBIRD_SDBC=@ENABLE_FIREBIRD_SDBC@ export ENABLE_GIO=@ENABLE_GIO@ export ENABLE_GRAPHITE=@ENABLE_GRAPHITE@ export ENABLE_ORCUS=@ENABLE_ORCUS@ -export ENABLE_HARFBUZZ=@ENABLE_HARFBUZZ@ export ENABLE_GLTF=@ENABLE_GLTF@ export SYSTEM_LIBGLTF=@SYSTEM_LIBGLTF@ export LIBGLTF_CFLAGS=@LIBGLTF_CFLAGS@ diff --git a/configure.ac b/configure.ac index 6dd2d10..d67054b 100644 --- a/configure.ac +++ b/configure.ac @@ -2135,12 +2135,6 @@ AC_ARG_WITH(iwyu, Use only if you are hacking on it.]), ,) -AC_ARG_WITH(harfbuzz, - AS_HELP_STRING([--with-harfbuzz], - [Enable HarfBuzz support regardless of the platform. - Experimental only. Use only if working on it.]), -,) - dnl =================================================================== dnl Branding dnl =================================================================== @@ -9340,32 +9334,20 @@ AC_SUBST(ENABLE_ORCUS) dnl =================================================================== dnl HarfBuzz dnl =================================================================== -AC_MSG_CHECKING([whether to enable HarfBuzz support]) -if test "$with_harfbuzz" = "yes" -o \( $_os != WINNT -a $_os != Darwin -a $_os != iOS \); then - AC_MSG_RESULT([yes]) - ENABLE_HARFBUZZ="TRUE" - if $PKG_CONFIG --atleast-version 0.9.18 harfbuzz; then - libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz-icu >= 0.9.18],["-I${WORKDIR}/UnpackedTarball/harfbuzz/src"],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"]) - else - libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz >= 0.9.10],[-I${WORKDIR}/UnpackedTarball/harfbuzz/src],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"]) - fi - if test "$COM" = "MSC"; then # override the above - HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib" - fi - if test "$with_system_harfbuzz" = "yes"; then - AC_MSG_CHECKING([whether system Harfbuzz is built with Graphite support]) - _save_libs="$LIBS" - _save_cflags="$CFLAGS" - LIBS="$LIBS $HARFBUZZ_LIBS" - CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS" - AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])]) - LIBS="$_save_libs" - CFLAGS="$_save_cflags" - fi -else - AC_MSG_RESULT([no]) +libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz-icu >= 0.9.18],["-I${WORKDIR}/UnpackedTarball/harfbuzz/src"],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"]) +if test "$COM" = "MSC"; then # override the above + HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib" +fi +if test "$with_system_harfbuzz" = "yes"; then + AC_MSG_CHECKING([whether system Harfbuzz is built with Graphite support]) + _save_libs="$LIBS" + _save_cflags="$CFLAGS" + LIBS="$LIBS $HARFBUZZ_LIBS" + CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS" + AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])]) + LIBS="$_save_libs" + CFLAGS="$_save_cflags" fi -AC_SUBST(ENABLE_HARFBUZZ) AC_MSG_CHECKING([whether to use X11]) dnl *************************************** commit 63fc67caa13e6dfe7f3f1930751deab78a5c5878 Author: Khaled Hosny <khaledho...@eglug.org> Date: Sun Sep 11 10:25:46 2016 +0200 Override GetCharWidths and ApplyDXArray in CSL A much simpler and saner implementation. This also unbreaks Awami Nastaliq. Break kashida justification, will need to rewrite that one as well. Change-Id: I843679e937f2881e77df61f5cbd9516b6df1b3b6 diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx index 83de5c1..89214d4 100644 --- a/vcl/inc/CommonSalLayout.hxx +++ b/vcl/inc/CommonSalLayout.hxx @@ -65,4 +65,7 @@ public: virtual bool LayoutText(ImplLayoutArgs&) override; virtual void DrawText( SalGraphics& ) const override; std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&) const override; + + virtual bool GetCharWidths(DeviceCoordinate* pCharWidths) const override; + virtual void ApplyDXArray(ImplLayoutArgs&) override; }; diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx index cfb2930..1050943 100644 --- a/vcl/inc/sallayout.hxx +++ b/vcl/inc/sallayout.hxx @@ -326,7 +326,7 @@ public: void AppendGlyph( const GlyphItem& ); void Reserve(int size) { m_GlyphItems.reserve(size + 1); } virtual void AdjustLayout( ImplLayoutArgs& ) override; - void ApplyDXArray( ImplLayoutArgs& ); + virtual void ApplyDXArray( ImplLayoutArgs& ); void Justify( DeviceCoordinate nNewWidth ); void KashidaJustify( long nIndex, int nWidth ); void ApplyAsianKerning(const OUString& rStr); @@ -352,7 +352,7 @@ protected: virtual void DropGlyph( int nStart ) override; virtual void Simplify( bool bIsBase ) override; - bool GetCharWidths( DeviceCoordinate* pCharWidths ) const; + virtual bool GetCharWidths( DeviceCoordinate* pCharWidths ) const; std::vector<GlyphItem> m_GlyphItems; diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 9c68bdb..a5e3bf6 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -486,3 +486,56 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) return true; } + +bool CommonSalLayout::GetCharWidths(DeviceCoordinate* pCharWidths) const +{ + int nCharCount = mnEndCharPos - mnMinCharPos; + + for (int i = 0; i < nCharCount; ++i) + pCharWidths[i] = 0; + + for (auto const& aGlyphItem : m_GlyphItems) + pCharWidths[aGlyphItem.mnCharPos - mnMinCharPos] += aGlyphItem.mnNewWidth; + + return true; +} + +void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs) +{ + if (rArgs.mpDXArray == nullptr) + return; + + int nCharCount = mnEndCharPos - mnMinCharPos; + std::unique_ptr<DeviceCoordinate[]> const pOldCharWidths(new DeviceCoordinate[nCharCount]); + std::unique_ptr<DeviceCoordinate[]> const pNewCharWidths(new DeviceCoordinate[nCharCount]); + + GetCharWidths(pOldCharWidths.get()); + + for (int i = 0; i < nCharCount; ++i) + { + if (i == 0) + pNewCharWidths[i] = rArgs.mpDXArray[i]; + else + pNewCharWidths[i] = rArgs.mpDXArray[i] - rArgs.mpDXArray[i - 1]; + } + + DeviceCoordinate nDelta = 0; + size_t i = 0; + while (i < m_GlyphItems.size()) + { + int nCharPos = m_GlyphItems[i].mnCharPos - mnMinCharPos; + DeviceCoordinate nDiff = pNewCharWidths[nCharPos] - pOldCharWidths[nCharPos]; + + m_GlyphItems[i].maLinearPos.X() += nDelta; + size_t j = i; + while (++j < m_GlyphItems.size()) + { + if (m_GlyphItems[j].mnCharPos != m_GlyphItems[i].mnCharPos) + break; + m_GlyphItems[j].maLinearPos.X() += nDelta; + } + + nDelta += nDiff; + i = j; + } +}
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits