vcl/inc/sallayout.hxx | 1 vcl/source/gdi/CommonSalLayout.cxx | 76 +++++++++++++++---------------------- vcl/source/gdi/sallayout.cxx | 35 ----------------- 3 files changed, 32 insertions(+), 80 deletions(-)
New commits: commit f246542d1f61b5253189676688f59e5f952267a1 Author: Khaled Hosny <[email protected]> Date: Mon Nov 28 06:43:29 2016 +0200 Simplify things a bit * Drop SortGlyphItems() and update the Kashida insertion code not depend on that sorting. * IS_DIACRITIC flag can now be based solely on the General Category property, since it now is used for non-spacing marks not any OpenType mark glyph. Pending complete removal. * Check whether a glyph can take Kashida or not in one place. We need to stop second-guessing here and pass explicit Kashida insertion points from upper layers. Change-Id: I39caa126a07d08c5725505615acc0c8f7a14e169 Reviewed-on: https://gerrit.libreoffice.org/31300 Tested-by: Jenkins <[email protected]> Reviewed-by: Khaled Hosny <[email protected]> diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx index c20a582..effb646 100644 --- a/vcl/inc/sallayout.hxx +++ b/vcl/inc/sallayout.hxx @@ -333,7 +333,6 @@ public: virtual void ApplyDXArray(ImplLayoutArgs&) = 0; void Justify(DeviceCoordinate nNewWidth); void ApplyAsianKerning(const OUString& rStr); - void SortGlyphItems(); // used by upper layers virtual DeviceCoordinate GetTextWidth() const override; diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 59a5d80..c61e540 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -598,29 +598,15 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) sal_Int32 indexUtf16 = nCharPos; sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0); - bool bDiacritic = false; - if (hb_ot_layout_has_glyph_classes(pHbFace)) - { - // the font has GDEF table - if (pHbPositions[i].x_advance == 0) - bDiacritic = hb_ot_layout_get_glyph_class(pHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK; - } - else - { #if HB_VERSION_ATLEAST(0, 9, 42) - if (u_getIntPropertyValue(aChar, UCHAR_GENERAL_CATEGORY) == U_NON_SPACING_MARK) - bDiacritic = true; -#else - // the font lacks GDEF table - if (pHbPositions[i].x_advance == 0) - bDiacritic = true; -#endif - } - - if (bDiacritic) + if (u_getIntPropertyValue(aChar, UCHAR_GENERAL_CATEGORY) == U_NON_SPACING_MARK) nGlyphFlags |= GlyphItem::IS_DIACRITIC; +#endif - if ((aSubRun.maScript == HB_SCRIPT_ARABIC) || (aSubRun.maScript == HB_SCRIPT_SYRIAC)) + if ((aSubRun.maScript == HB_SCRIPT_ARABIC || + aSubRun.maScript == HB_SCRIPT_SYRIAC) && + HB_DIRECTION_IS_BACKWARD(aSubRun.maDirection) && + !u_isUWhiteSpace(aChar)) { nGlyphFlags |= GlyphItem::ALLOW_KASHIDA; rArgs.mnFlags |= SalLayoutFlags::KashidaJustification; @@ -664,11 +650,6 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) hb_buffer_destroy(pHbBuffer); - // sort glyphs in visual order - // and then in logical order (e.g. diacritics after cluster start) - // XXX: why? - SortGlyphItems(); - return true; } @@ -753,14 +734,10 @@ void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs) int nCharPos = m_GlyphItems[i].mnCharPos - mnMinCharPos; DeviceCoordinate nDiff = pNewCharWidths[nCharPos] - pOldCharWidths[nCharPos]; - // nDiff > 1 to ignore rounding errors. - if (bKashidaJustify && m_GlyphItems[i].AllowKashida() && nDiff > 1) - pKashidas[i] = nDiff; - - // Adjust the width of the first glyph belonging to current character. + // Adjust the width of the first glyph in the cluster. m_GlyphItems[i].mnNewWidth += nDiff; - // Apply the X position of all glyphs belonging to current character. + // Apply the X position of all glyphs in the cluster. size_t j = i; while (j < m_GlyphItems.size()) { @@ -773,10 +750,31 @@ void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs) ++j; } + // Id this glyph is Kashida-justifiable, then mark this as a Kashida + // position. Since this must be a RTL glyph, we mark the last glyph in + // the cluster not the fisrt as this would be the base glyph. + // nDiff > 1 to ignore rounding errors. + if (bKashidaJustify && m_GlyphItems[i].AllowKashida() && nDiff > 1) + { + pKashidas[j - 1] = nDiff; + // Move any non-spacing marks attached to this cluster as well. + // Looping backward because this is RTL glyph. + if (i > 0) + { + auto pGlyph = m_GlyphItems.begin() + i - 1; + while (pGlyph != m_GlyphItems.begin() && pGlyph->IsDiacritic()) + { + pGlyph->maLinearPos.X() += nDiff; + --pGlyph; + } + } + } + + // Increment the delta, the loop above makes sure we do so only once - // for every character not for every glyph (otherwise we would apply it - // multiple times for each glyphs belonging to the same character which - // is wrong since DX adjustments are character based). + // for every character (cluster) not for every glyph (otherwise we + // would apply it multiple times for each glyphs belonging to the same + // character which is wrong since DX adjustments are character based). nDelta += nDiff; i = j; } @@ -789,16 +787,6 @@ void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs) { auto pGlyphIter = m_GlyphItems.begin() + nInserted + pKashida.first; - // Donât insert Kashida after LTR glyphs. - if (!pGlyphIter->IsRTLGlyph()) - continue; - - // Donât insert Kashida after space. - sal_Int32 indexUtf16 = pGlyphIter->mnCharPos; - sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0); - if (u_isUWhiteSpace(aChar)) - continue; - // The total Kashida width. DeviceCoordinate nTotalWidth = pKashida.second; diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index ebae19b..9c10cde 100644 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -1129,41 +1129,6 @@ void GenericSalLayout::Simplify( bool bIsBase ) m_GlyphItems.erase(m_GlyphItems.begin() + j, m_GlyphItems.end()); } -// make sure GlyphItems are sorted left to right -void GenericSalLayout::SortGlyphItems() -{ - // move cluster components behind their cluster start (especially for RTL) - // using insertion sort because the glyph items are "almost sorted" - - for( std::vector<GlyphItem>::iterator pGlyphIter = m_GlyphItems.begin(), pGlyphIterEnd = m_GlyphItems.end(); pGlyphIter != pGlyphIterEnd; ++pGlyphIter ) - { - // find a cluster starting with a diacritic - if( !pGlyphIter->IsDiacritic() ) - continue; - if( !pGlyphIter->IsClusterStart() ) - continue; - for( std::vector<GlyphItem>::iterator pBaseGlyph = pGlyphIter; ++pBaseGlyph != pGlyphIterEnd; ) - { - // find the base glyph matching to the misplaced diacritic - if( pBaseGlyph->IsClusterStart() ) - break; - if( pBaseGlyph->IsDiacritic() ) - continue; - - // found the matching base glyph - // => this base glyph becomes the new cluster start - iter_swap(pGlyphIter, pBaseGlyph); - - // update glyph flags of swapped glyphitems - pGlyphIter->mnFlags &= ~GlyphItem::IS_IN_CLUSTER; - pBaseGlyph->mnFlags |= GlyphItem::IS_IN_CLUSTER; - // prepare for checking next cluster - pGlyphIter = pBaseGlyph; - break; - } - } -} - MultiSalLayout::MultiSalLayout( SalLayout& rBaseLayout ) : SalLayout() , mnLevel( 1 )
_______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
