diff options
-rw-r--r-- | include/vcl/glyphitem.hxx | 19 | ||||
-rw-r--r-- | include/vcl/outdev.hxx | 6 | ||||
-rw-r--r-- | include/vcl/vcllayout.hxx | 6 | ||||
-rw-r--r-- | sc/source/ui/view/output2.cxx | 4 | ||||
-rw-r--r-- | svtools/source/control/ruler.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/txtnode/fntcache.cxx | 6 | ||||
-rw-r--r-- | vcl/inc/impglyphitem.hxx | 7 | ||||
-rw-r--r-- | vcl/inc/sallayout.hxx | 13 | ||||
-rw-r--r-- | vcl/qa/cppunit/complextext.cxx | 10 | ||||
-rw-r--r-- | vcl/source/control/imp_listbox.cxx | 6 | ||||
-rw-r--r-- | vcl/source/gdi/CommonSalLayout.cxx | 68 | ||||
-rw-r--r-- | vcl/source/gdi/impglyphitem.cxx | 42 | ||||
-rw-r--r-- | vcl/source/gdi/sallayout.cxx | 64 | ||||
-rw-r--r-- | vcl/source/outdev/font.cxx | 9 | ||||
-rw-r--r-- | vcl/source/outdev/text.cxx | 4 | ||||
-rw-r--r-- | vcl/source/window/menuitemlist.cxx | 6 | ||||
-rw-r--r-- | vcl/source/window/status.cxx | 16 |
17 files changed, 147 insertions, 145 deletions
diff --git a/include/vcl/glyphitem.hxx b/include/vcl/glyphitem.hxx index 7634bd3a4413..02d783a3e166 100644 --- a/include/vcl/glyphitem.hxx +++ b/include/vcl/glyphitem.hxx @@ -23,23 +23,30 @@ #include <sal/types.h> #include <vcl/dllapi.h> +#include <vector> + typedef sal_uInt16 sal_GlyphId; class SalLayoutGlyphsImpl; class VCL_DLLPUBLIC SalLayoutGlyphs final { - friend class SalLayoutGlyphsImpl; - SalLayoutGlyphsImpl* m_pImpl; + std::vector<SalLayoutGlyphsImpl*> m_pImpls; public: - SalLayoutGlyphs(); - SalLayoutGlyphs(const SalLayoutGlyphs&); + SalLayoutGlyphs() = default; + SalLayoutGlyphs(const SalLayoutGlyphs&) = delete; + SalLayoutGlyphs(SalLayoutGlyphs&&); ~SalLayoutGlyphs(); - SalLayoutGlyphs& operator=(const SalLayoutGlyphs&); + SalLayoutGlyphs& operator=(const SalLayoutGlyphs&) = delete; + SalLayoutGlyphs& operator=(SalLayoutGlyphs&&); - SalLayoutGlyphsImpl* Impl() const { return m_pImpl; } + SalLayoutGlyphsImpl* Impl(unsigned int nLevel) const + { + return nLevel < m_pImpls.size() ? m_pImpls[nLevel] : nullptr; + } + void AppendImpl(SalLayoutGlyphsImpl* pImpl) { m_pImpls.push_back(pImpl); } bool IsValid() const; void Invalidate(); diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index a8d77c77b30e..ce7d54e75689 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -1352,11 +1352,13 @@ public: SalLayoutFlags flags = SalLayoutFlags::NONE, vcl::TextLayoutCache const* = nullptr) const; SAL_DLLPRIVATE std::unique_ptr<SalLayout> - ImplGlyphFallbackLayout( std::unique_ptr<SalLayout>, ImplLayoutArgs& ) const; + ImplGlyphFallbackLayout( std::unique_ptr<SalLayout>, + ImplLayoutArgs&, + const SalLayoutGlyphs* ) const; SAL_DLLPRIVATE std::unique_ptr<SalLayout> getFallbackLayout( LogicalFontInstance* pLogicalFont, int nFallbackLevel, - ImplLayoutArgs& rLayoutArgs) const; + ImplLayoutArgs& rLayoutArgs, const SalLayoutGlyphs* ) const; // Enabling/disabling RTL only makes sense for OutputDevices that use a mirroring SalGraphicsLayout diff --git a/include/vcl/vcllayout.hxx b/include/vcl/vcllayout.hxx index 7d53d12bd40b..e09e54f59d65 100644 --- a/include/vcl/vcllayout.hxx +++ b/include/vcl/vcllayout.hxx @@ -24,13 +24,13 @@ #include <tools/gen.hxx> #include <tools/degree.hxx> #include <vcl/devicecoordinate.hxx> +#include <vcl/glyphitem.hxx> #include <vcl/dllapi.h> class ImplLayoutArgs; class PhysicalFontFace; class SalGraphics; class GlyphItem; -class SalLayoutGlyphs; // all positions/widths are in font units // one exception: drawposition is in pixel units @@ -73,7 +73,7 @@ public: const Point& DrawOffset() const { return maDrawOffset; } Point GetDrawPosition( const Point& rRelative = Point(0,0) ) const; - virtual bool LayoutText( ImplLayoutArgs&, const SalLayoutGlyphs* ) = 0; // first step of layouting + virtual bool LayoutText( ImplLayoutArgs&, const SalLayoutGlyphsImpl* ) = 0; // first step of layouting virtual void AdjustLayout( ImplLayoutArgs& ); // adjusting after fallback etc. virtual void InitFont() const {} virtual void DrawText( SalGraphics& ) const = 0; @@ -94,7 +94,7 @@ public: virtual bool GetOutline(basegfx::B2DPolyPolygonVector&) const; bool GetBoundRect(tools::Rectangle&) const; - virtual const SalLayoutGlyphs* GetGlyphs() const; + virtual SalLayoutGlyphs GetGlyphs() const; protected: // used by layout engines diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 46f4bc0b3e0e..4d5003bdc02e 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -779,9 +779,9 @@ const SalLayoutGlyphs* ScDrawStringsVars::GetLayoutGlyphs(const OUString& rStrin return &it->second; std::unique_ptr<SalLayout> layout = pOutput->pFmtDevice->ImplLayout( rString, 0, rString.getLength(), Point( 0, 0 ), 0, nullptr, SalLayoutFlags::GlyphItemsOnly ); - if( layout && layout->GetGlyphs()) + if( layout ) { - mCachedGlyphs.insert( std::make_pair( rString, *layout->GetGlyphs())); + mCachedGlyphs.insert( std::make_pair( rString, layout->GetGlyphs())); assert(mCachedGlyphs.find( rString ) == mCachedGlyphs.begin()); // newly inserted item is first return &mCachedGlyphs.begin()->second; } diff --git a/svtools/source/control/ruler.cxx b/svtools/source/control/ruler.cxx index 1f4a5d4eafac..2551dc39581d 100644 --- a/svtools/source/control/ruler.cxx +++ b/svtools/source/control/ruler.cxx @@ -84,12 +84,8 @@ SalLayoutGlyphs* lcl_GetRulerTextGlyphs(const vcl::RenderContext& rRenderContext if (!pLayout) return nullptr; - const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs(); - if (!pGlyphs) - return nullptr; - // Remember the calculation result. - rTextGlyphs = *pGlyphs; + rTextGlyphs = pLayout->GetGlyphs(); return &rTextGlyphs; } diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx index 2327ce0de4ce..eeeb3f833193 100644 --- a/sw/source/core/txtnode/fntcache.cxx +++ b/sw/source/core/txtnode/fntcache.cxx @@ -234,12 +234,8 @@ static SalLayoutGlyphs* lcl_CreateLayout(const SwTextGlyphsKey& rKey, std::map<S if (!pLayout) return nullptr; - const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs(); - if (!pGlyphs) - return nullptr; - // Remember the calculation result. - it->second.m_aTextGlyphs = *pGlyphs; + it->second.m_aTextGlyphs = pLayout->GetGlyphs(); return &it->second.m_aTextGlyphs; } diff --git a/vcl/inc/impglyphitem.hxx b/vcl/inc/impglyphitem.hxx index da56b660d7b6..c3bd423d7e5a 100644 --- a/vcl/inc/impglyphitem.hxx +++ b/vcl/inc/impglyphitem.hxx @@ -119,19 +119,18 @@ class SalLayoutGlyphsImpl : public std::vector<GlyphItem> friend class GenericSalLayout; public: - SalLayoutGlyphsImpl* clone(SalLayoutGlyphs& rGlyphs) const; + SalLayoutGlyphsImpl* clone() const; LogicalFontInstance& GetFont() const { return *m_rFontInstance; } bool IsValid() const; void Invalidate(); private: - mutable rtl::Reference<LogicalFontInstance> m_rFontInstance; + rtl::Reference<LogicalFontInstance> m_rFontInstance; SalLayoutFlags mnFlags = SalLayoutFlags::NONE; - SalLayoutGlyphsImpl(SalLayoutGlyphs& rGlyphs, LogicalFontInstance& rFontInstance) + SalLayoutGlyphsImpl(LogicalFontInstance& rFontInstance) : m_rFontInstance(&rFontInstance) { - rGlyphs.m_pImpl = this; } }; diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx index 30fd5580b4c5..d480089c0b38 100644 --- a/vcl/inc/sallayout.hxx +++ b/vcl/inc/sallayout.hxx @@ -134,13 +134,14 @@ public: const PhysicalFontFace** pFallbackFont = nullptr) const override; bool GetOutline(basegfx::B2DPolyPolygonVector&) const override; bool IsKashidaPosValid(int nCharPos) const override; + SalLayoutGlyphs GetGlyphs() const final override; // used only by OutputDevice::ImplLayout, TODO: make friend explicit MultiSalLayout( std::unique_ptr<SalLayout> pBaseLayout ); void AddFallback(std::unique_ptr<SalLayout> pFallbackLayout, ImplLayoutRuns const &); // give up ownership of the initial pBaseLayout taken by the ctor std::unique_ptr<SalLayout> ReleaseBaseLayout(); - bool LayoutText(ImplLayoutArgs&, const SalLayoutGlyphs*) override; + bool LayoutText(ImplLayoutArgs&, const SalLayoutGlyphsImpl*) override; void AdjustLayout(ImplLayoutArgs&) override; void InitFont() const override; @@ -168,10 +169,10 @@ public: ~GenericSalLayout() override; void AdjustLayout(ImplLayoutArgs&) final override; - bool LayoutText(ImplLayoutArgs&, const SalLayoutGlyphs*) final override; + bool LayoutText(ImplLayoutArgs&, const SalLayoutGlyphsImpl*) final override; void DrawText(SalGraphics&) const final override; static std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&); - const SalLayoutGlyphs* GetGlyphs() const final override; + SalLayoutGlyphs GetGlyphs() const final override; bool IsKashidaPosValid(int nCharPos) const final override; @@ -183,11 +184,13 @@ public: // used by display layers LogicalFontInstance& GetFont() const - { return m_GlyphItems.Impl()->GetFont(); } + { return m_GlyphItems.GetFont(); } bool GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart, const PhysicalFontFace** pFallbackFont = nullptr) const override; + const SalLayoutGlyphsImpl& GlyphsImpl() const { return m_GlyphItems; } + private: // for glyph+font+script fallback void MoveGlyph(int nStart, tools::Long nNewXPos); @@ -211,7 +214,7 @@ private: css::uno::Reference<css::i18n::XBreakIterator> mxBreak; - SalLayoutGlyphs m_GlyphItems; + SalLayoutGlyphsImpl m_GlyphItems; OString msLanguage; std::vector<hb_feature_t> maFeatures; diff --git a/vcl/qa/cppunit/complextext.cxx b/vcl/qa/cppunit/complextext.cxx index f769fe4688b4..f953c3060eb4 100644 --- a/vcl/qa/cppunit/complextext.cxx +++ b/vcl/qa/cppunit/complextext.cxx @@ -121,17 +121,15 @@ void VclComplexTextTest::testKashida() = OUString(u"ﻊﻨﺻﺭ ﺎﻠﻓﻮﺴﻓﻭﺭ ﻊﻨﺻﺭ ﻒﻟﺰﻳ ﺺﻠﺑ. ﺖﺘﻛﻮﻧ ﺎﻟﺩﻭﺭﺓ ﺎﻟﺭﺎﺒﻋﺓ ﻢﻧ ١٥ ﻊﻨﺻﺭﺍ."); std::unique_ptr<SalLayout> pLayout = pOutputDevice->ImplLayout( aText, 0, aText.getLength(), Point(0, 0), 0, nullptr, SalLayoutFlags::GlyphItemsOnly); - const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs(); - if (!pGlyphs) - // Failed in some non-interesting ways. - return; - SalLayoutGlyphs aGlyphs = *pGlyphs; + SalLayoutGlyphs aGlyphs = pLayout->GetGlyphs(); + CPPUNIT_ASSERT(aGlyphs.IsValid()); + CPPUNIT_ASSERT(aGlyphs.Impl(0) != nullptr); // Now lay it out using the cached glyph list. ImplLayoutArgs aLayoutArgs(aText, 0, aText.getLength(), SalLayoutFlags::NONE, pOutputDevice->GetFont().GetLanguageTag(), nullptr); pLayout = pOutputDevice->GetGraphics()->GetTextLayout(0); - CPPUNIT_ASSERT(pLayout->LayoutText(aLayoutArgs, &aGlyphs)); + CPPUNIT_ASSERT(pLayout->LayoutText(aLayoutArgs, aGlyphs.Impl(0))); // Without the accompanying fix in place, this test would have failed with 'assertion failed'. // The kashida justification flag was lost when going via the glyph cache. diff --git a/vcl/source/control/imp_listbox.cxx b/vcl/source/control/imp_listbox.cxx index 0c5e8f1237f6..8f2269941986 100644 --- a/vcl/source/control/imp_listbox.cxx +++ b/vcl/source/control/imp_listbox.cxx @@ -592,12 +592,8 @@ SalLayoutGlyphs* ImplEntryType::GetTextGlyphs(const OutputDevice* pOutputDevice) if (!pLayout) return nullptr; - const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs(); - if (!pGlyphs) - return nullptr; - // Remember the calculation result. - maStrGlyphs = *pGlyphs; + maStrGlyphs = pLayout->GetGlyphs(); return &maStrGlyphs; } diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 7f557c73b314..2ef3c98d2f9d 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -57,10 +57,10 @@ static hb_unicode_funcs_t* getUnicodeFuncs() #endif GenericSalLayout::GenericSalLayout(LogicalFontInstance &rFont) - : mpVertGlyphs(nullptr) + : m_GlyphItems(rFont) + , mpVertGlyphs(nullptr) , mbFuzzing(utl::ConfigManager::IsFuzzing()) { - new SalLayoutGlyphsImpl(m_GlyphItems, rFont); } GenericSalLayout::~GenericSalLayout() @@ -190,9 +190,11 @@ std::shared_ptr<vcl::TextLayoutCache> GenericSalLayout::CreateTextLayoutCache(OU return std::make_shared<vcl::TextLayoutCache>(rString.getStr(), rString.getLength()); } -const SalLayoutGlyphs* GenericSalLayout::GetGlyphs() const +SalLayoutGlyphs GenericSalLayout::GetGlyphs() const { - return &m_GlyphItems; + SalLayoutGlyphs glyphs; + glyphs.AppendImpl(m_GlyphItems.clone()); + return glyphs; } void GenericSalLayout::SetNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nCharPos, bool bRightToLeft) @@ -284,7 +286,7 @@ bool GenericSalLayout::HasVerticalAlternate(sal_UCS4 aChar, sal_UCS4 aVariationS return hb_set_has(mpVertGlyphs, nGlyphIndex) != 0; } -bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs* pGlyphs) +bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphsImpl* pGlyphs) { // No need to touch m_GlyphItems at all for an empty string. if (rArgs.mnEndCharPos - rArgs.mnMinCharPos <= 0) @@ -295,7 +297,7 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs* // Work with pre-computed glyph items. m_GlyphItems = *pGlyphs; // Some flags are set as a side effect of text layout, restore them here. - rArgs.mnFlags |= pGlyphs->Impl()->mnFlags; + rArgs.mnFlags |= pGlyphs->mnFlags; return true; } @@ -303,7 +305,7 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs* bool isGraphite = GetFont().IsGraphiteFont(); int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos); - m_GlyphItems.Impl()->reserve(nGlyphCapacity); + m_GlyphItems.reserve(nGlyphCapacity); const int nLength = rArgs.mrStr.getLength(); const sal_Unicode *pStr = rArgs.mrStr.getStr(); @@ -603,7 +605,7 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs* Point aNewPos(aCurrPos.X() + nXOffset, aCurrPos.Y() + nYOffset); const GlyphItem aGI(nCharPos, nCharCount, nGlyphIndex, aNewPos, nGlyphFlags, nAdvance, nXOffset, &GetFont()); - m_GlyphItems.Impl()->push_back(aGI); + m_GlyphItems.push_back(aGI); aCurrPos.AdjustX(nAdvance ); } @@ -614,7 +616,7 @@ bool GenericSalLayout::LayoutText(ImplLayoutArgs& rArgs, const SalLayoutGlyphs* // Some flags are set as a side effect of text layout, save them here. if (rArgs.mnFlags & SalLayoutFlags::GlyphItemsOnly) - m_GlyphItems.Impl()->mnFlags = rArgs.mnFlags; + m_GlyphItems.mnFlags = rArgs.mnFlags; return true; } @@ -626,7 +628,7 @@ void GenericSalLayout::GetCharWidths(DeviceCoordinate* pCharWidths) const for (int i = 0; i < nCharCount; ++i) pCharWidths[i] = 0; - for (auto const& aGlyphItem : *m_GlyphItems.Impl()) + for (auto const& aGlyphItem : m_GlyphItems) { const int nIndex = aGlyphItem.charPos() - mnMinCharPos; if (nIndex >= nCharCount) @@ -694,31 +696,31 @@ void GenericSalLayout::ApplyDXArray(const ImplLayoutArgs& rArgs) // Apply the DX adjustments to glyph positions and widths. size_t i = 0; - while (i < m_GlyphItems.Impl()->size()) + while (i < m_GlyphItems.size()) { // Accumulate the width difference for all characters corresponding to // this glyph. - int nCharPos = (*m_GlyphItems.Impl())[i].charPos() - mnMinCharPos; + int nCharPos = m_GlyphItems[i].charPos() - mnMinCharPos; DeviceCoordinate nDiff = 0; - for (int j = 0; j < (*m_GlyphItems.Impl())[i].charCount(); j++) + for (int j = 0; j < m_GlyphItems[i].charCount(); j++) nDiff += pNewCharWidths[nCharPos + j] - pOldCharWidths[nCharPos + j]; - if (!(*m_GlyphItems.Impl())[i].IsRTLGlyph()) + if (!m_GlyphItems[i].IsRTLGlyph()) { // Adjust the width and position of the first (leftmost) glyph in // the cluster. - (*m_GlyphItems.Impl())[i].m_nNewWidth += nDiff; - (*m_GlyphItems.Impl())[i].m_aLinearPos.AdjustX(nDelta); + m_GlyphItems[i].m_nNewWidth += nDiff; + m_GlyphItems[i].m_aLinearPos.AdjustX(nDelta); // Adjust the position of the rest of the glyphs in the cluster. - while (++i < m_GlyphItems.Impl()->size()) + while (++i < m_GlyphItems.size()) { - if (!(*m_GlyphItems.Impl())[i].IsInCluster()) + if (!m_GlyphItems[i].IsInCluster()) break; - (*m_GlyphItems.Impl())[i].m_aLinearPos.AdjustX(nDelta); + m_GlyphItems[i].m_aLinearPos.AdjustX(nDelta); } } - else if ((*m_GlyphItems.Impl())[i].IsInCluster()) + else if (m_GlyphItems[i].IsInCluster()) { // RTL glyph in the middle of the cluster, will be handled in the // loop below. @@ -729,34 +731,34 @@ void GenericSalLayout::ApplyDXArray(const ImplLayoutArgs& rArgs) // Adjust the width and position of the first (rightmost) glyph in // the cluster. // For RTL, we put all the adjustment to the left of the glyph. - (*m_GlyphItems.Impl())[i].m_nNewWidth += nDiff; - (*m_GlyphItems.Impl())[i].m_aLinearPos.AdjustX(nDelta + nDiff); + m_GlyphItems[i].m_nNewWidth += nDiff; + m_GlyphItems[i].m_aLinearPos.AdjustX(nDelta + nDiff); // Adjust the X position of all glyphs in the cluster. size_t j = i; while (j > 0) { --j; - if (!(*m_GlyphItems.Impl())[j].IsInCluster()) + if (!m_GlyphItems[j].IsInCluster()) break; - (*m_GlyphItems.Impl())[j].m_aLinearPos.AdjustX(nDelta + nDiff); + m_GlyphItems[j].m_aLinearPos.AdjustX(nDelta + nDiff); } // If 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 first as this would be the // base glyph. - if (bKashidaJustify && (*m_GlyphItems.Impl())[i].AllowKashida() && - nDiff > (*m_GlyphItems.Impl())[i].charCount()) // Rounding errors, 1 pixel per character! + if (bKashidaJustify && m_GlyphItems[i].AllowKashida() && + nDiff > m_GlyphItems[i].charCount()) // Rounding errors, 1 pixel per character! { pKashidas[i] = nDiff; // Move any non-spacing marks attached to this cluster as well. // Looping backward because this is RTL glyph. while (j > 0) { - if (!(*m_GlyphItems.Impl())[j].IsDiacritic()) + if (!m_GlyphItems[j].IsDiacritic()) break; - (*m_GlyphItems.Impl())[j--].m_aLinearPos.AdjustX(nDiff); + m_GlyphItems[j--].m_aLinearPos.AdjustX(nDiff); } } i++; @@ -776,7 +778,7 @@ void GenericSalLayout::ApplyDXArray(const ImplLayoutArgs& rArgs) size_t nInserted = 0; for (auto const& pKashida : pKashidas) { - auto pGlyphIter = m_GlyphItems.Impl()->begin() + nInserted + pKashida.first; + auto pGlyphIter = m_GlyphItems.begin() + nInserted + pKashida.first; // The total Kashida width. DeviceCoordinate nTotalWidth = pKashida.second; @@ -804,7 +806,7 @@ void GenericSalLayout::ApplyDXArray(const ImplLayoutArgs& rArgs) while (nCopies--) { GlyphItem aKashida(nCharPos, 0, nKashidaIndex, aPos, nFlags, nKashidaWidth, 0, &GetFont()); - pGlyphIter = m_GlyphItems.Impl()->insert(pGlyphIter, aKashida); + pGlyphIter = m_GlyphItems.insert(pGlyphIter, aKashida); aPos.AdjustX(nKashidaWidth ); aPos.AdjustX( -nOverlap ); ++pGlyphIter; @@ -815,7 +817,7 @@ void GenericSalLayout::ApplyDXArray(const ImplLayoutArgs& rArgs) bool GenericSalLayout::IsKashidaPosValid(int nCharPos) const { - for (auto pIter = m_GlyphItems.Impl()->begin(); pIter != m_GlyphItems.Impl()->end(); ++pIter) + for (auto pIter = m_GlyphItems.begin(); pIter != m_GlyphItems.end(); ++pIter) { if (pIter->charPos() == nCharPos) { @@ -823,7 +825,7 @@ bool GenericSalLayout::IsKashidaPosValid(int nCharPos) const // changed the text styling in the middle of a word. Since we don’t // do ligatures across layout engine instances, this can’t be a // ligature so it should be fine. - if (pIter == m_GlyphItems.Impl()->begin()) + if (pIter == m_GlyphItems.begin()) return true; // If the character is not supported by this layout, return false @@ -834,7 +836,7 @@ bool GenericSalLayout::IsKashidaPosValid(int nCharPos) const // 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.Impl()->begin(); --pPrev) + for (auto pPrev = pIter - 1; pPrev != m_GlyphItems.begin(); --pPrev) { if (pPrev->charPos() != nCharPos) { diff --git a/vcl/source/gdi/impglyphitem.cxx b/vcl/source/gdi/impglyphitem.cxx index 4bb53d4a4596..d271032e2ad6 100644 --- a/vcl/source/gdi/impglyphitem.cxx +++ b/vcl/source/gdi/impglyphitem.cxx @@ -23,43 +23,41 @@ #include <unx/freetype_glyphcache.hxx> #endif -SalLayoutGlyphs::SalLayoutGlyphs() - : m_pImpl(nullptr) +SalLayoutGlyphs::~SalLayoutGlyphs() { + for (SalLayoutGlyphsImpl* impl : m_pImpls) + delete impl; } -SalLayoutGlyphs::~SalLayoutGlyphs() { delete m_pImpl; } +SalLayoutGlyphs::SalLayoutGlyphs(SalLayoutGlyphs&& rOther) { std::swap(m_pImpls, rOther.m_pImpls); } -SalLayoutGlyphs::SalLayoutGlyphs(const SalLayoutGlyphs& rOther) -{ - m_pImpl = rOther.m_pImpl ? rOther.m_pImpl->clone(*this) : nullptr; -} - -SalLayoutGlyphs& SalLayoutGlyphs::operator=(const SalLayoutGlyphs& rOther) +SalLayoutGlyphs& SalLayoutGlyphs::operator=(SalLayoutGlyphs&& rOther) { if (this != &rOther) - { - delete m_pImpl; - m_pImpl = rOther.m_pImpl ? rOther.m_pImpl->clone(*this) : nullptr; - } + std::swap(m_pImpls, rOther.m_pImpls); return *this; } -bool SalLayoutGlyphs::IsValid() const { return m_pImpl && m_pImpl->IsValid(); } - -void SalLayoutGlyphs::Invalidate() +bool SalLayoutGlyphs::IsValid() const { - if (m_pImpl) - m_pImpl->Invalidate(); + if (m_pImpls.empty()) + return false; + for (SalLayoutGlyphsImpl* impl : m_pImpls) + if (!impl->IsValid()) + return false; + return true; } -SalLayoutGlyphsImpl* SalLayoutGlyphsImpl::clone(SalLayoutGlyphs& rGlyphs) const +void SalLayoutGlyphs::Invalidate() { - SalLayoutGlyphsImpl* pNew = new SalLayoutGlyphsImpl(rGlyphs, *m_rFontInstance); - *pNew = *this; - return pNew; + // Invalidating is in fact simply clearing. + for (SalLayoutGlyphsImpl* impl : m_pImpls) + delete impl; + m_pImpls.clear(); } +SalLayoutGlyphsImpl* SalLayoutGlyphsImpl::clone() const { return new SalLayoutGlyphsImpl(*this); } + bool SalLayoutGlyphsImpl::IsValid() const { if (!m_rFontInstance.is()) diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index 067672dc5366..cde5cac31730 100644 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -647,6 +647,11 @@ bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const return bRet; } +SalLayoutGlyphs SalLayout::GetGlyphs() const +{ + return SalLayoutGlyphs(); // invalid +} + DeviceCoordinate GenericSalLayout::FillDXArray( DeviceCoordinate* pCharWidths ) const { if (pCharWidths) @@ -665,7 +670,7 @@ DeviceCoordinate GenericSalLayout::GetTextWidth() const DeviceCoordinate nMinPos = 0; DeviceCoordinate nMaxPos = 0; - for (auto const& aGlyphItem : *m_GlyphItems.Impl()) + for (auto const& aGlyphItem : m_GlyphItems) { // update the text extent with the glyph extent DeviceCoordinate nXPos = aGlyphItem.m_aLinearPos.getX(); @@ -692,13 +697,13 @@ void GenericSalLayout::Justify( DeviceCoordinate nNewWidth ) return; } // find rightmost glyph, it won't get stretched - std::vector<GlyphItem>::iterator pGlyphIterRight = m_GlyphItems.Impl()->begin(); - pGlyphIterRight += m_GlyphItems.Impl()->size() - 1; + std::vector<GlyphItem>::iterator pGlyphIterRight = m_GlyphItems.begin(); + pGlyphIterRight += m_GlyphItems.size() - 1; std::vector<GlyphItem>::iterator pGlyphIter; // count stretchable glyphs int nStretchable = 0; int nMaxGlyphWidth = 0; - for(pGlyphIter = m_GlyphItems.Impl()->begin(); pGlyphIter != pGlyphIterRight; ++pGlyphIter) + for(pGlyphIter = m_GlyphItems.begin(); pGlyphIter != pGlyphIterRight; ++pGlyphIter) { if( !pGlyphIter->IsDiacritic() ) ++nStretchable; @@ -721,7 +726,7 @@ void GenericSalLayout::Justify( DeviceCoordinate nNewWidth ) { // expand width by distributing space between glyphs evenly int nDeltaSum = 0; - for( pGlyphIter = m_GlyphItems.Impl()->begin(); pGlyphIter != pGlyphIterRight; ++pGlyphIter ) + for( pGlyphIter = m_GlyphItems.begin(); pGlyphIter != pGlyphIterRight; ++pGlyphIter ) { // move glyph to justified position pGlyphIter->m_aLinearPos.AdjustX(nDeltaSum ); @@ -741,9 +746,9 @@ void GenericSalLayout::Justify( DeviceCoordinate nNewWidth ) { // squeeze width by moving glyphs proportionally double fSqueeze = static_cast<double>(nNewWidth) / nOldWidth; - if(m_GlyphItems.Impl()->size() > 1) + if(m_GlyphItems.size() > 1) { - for( pGlyphIter = m_GlyphItems.Impl()->begin(); ++pGlyphIter != pGlyphIterRight;) + for( pGlyphIter = m_GlyphItems.begin(); ++pGlyphIter != pGlyphIterRight;) { int nX = pGlyphIter->m_aLinearPos.getX(); nX = static_cast<int>(nX * fSqueeze); @@ -751,7 +756,7 @@ void GenericSalLayout::Justify( DeviceCoordinate nNewWidth ) } } // adjust glyph widths to new positions - for( pGlyphIter = m_GlyphItems.Impl()->begin(); pGlyphIter != pGlyphIterRight; ++pGlyphIter ) + for( pGlyphIter = m_GlyphItems.begin(); pGlyphIter != pGlyphIterRight; ++pGlyphIter ) pGlyphIter->m_nNewWidth = pGlyphIter[1].m_aLinearPos.getX() - pGlyphIter[0].m_aLinearPos.getX(); } } @@ -804,8 +809,8 @@ void GenericSalLayout::ApplyAsianKerning(const OUString& rStr) const int nLength = rStr.getLength(); tools::Long nOffset = 0; - for (std::vector<GlyphItem>::iterator pGlyphIter = m_GlyphItems.Impl()->begin(), - pGlyphIterEnd = m_GlyphItems.Impl()->end(); + for (std::vector<GlyphItem>::iterator pGlyphIter = m_GlyphItems.begin(), + pGlyphIterEnd = m_GlyphItems.end(); pGlyphIter != pGlyphIterEnd; ++pGlyphIter) { const int n = pGlyphIter->charPos(); @@ -851,7 +856,7 @@ void GenericSalLayout::GetCaretPositions( int nMaxIndex, tools::Long* pCaretXArr pCaretXArray[i] = -1; // calculate caret positions using glyph array - for (auto const& aGlyphItem : *m_GlyphItems.Impl()) + for (auto const& aGlyphItem : m_GlyphItems) { tools::Long nXPos = aGlyphItem.m_aLinearPos.getX(); tools::Long nXRight = nXPos + aGlyphItem.origWidth(); @@ -897,8 +902,8 @@ bool GenericSalLayout::GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart, const PhysicalFontFace**) const { - std::vector<GlyphItem>::const_iterator pGlyphIter = m_GlyphItems.Impl()->begin(); - std::vector<GlyphItem>::const_iterator pGlyphIterEnd = m_GlyphItems.Impl()->end(); + std::vector<GlyphItem>::const_iterator pGlyphIter = m_GlyphItems.begin(); + std::vector<GlyphItem>::const_iterator pGlyphIterEnd = m_GlyphItems.end(); pGlyphIter += nStart; // find next glyph in substring @@ -910,7 +915,7 @@ bool GenericSalLayout::GetNextGlyph(const GlyphItem** pGlyph, } // return zero if no more glyph found - if( nStart >= static_cast<int>(m_GlyphItems.Impl()->size()) ) + if( nStart >= static_cast<int>(m_GlyphItems.size()) ) return false; if( pGlyphIter == pGlyphIterEnd ) @@ -932,10 +937,10 @@ bool GenericSalLayout::GetNextGlyph(const GlyphItem** pGlyph, void GenericSalLayout::MoveGlyph( int nStart, tools::Long nNewXPos ) { - if( nStart >= static_cast<int>(m_GlyphItems.Impl()->size()) ) + if( nStart >= static_cast<int>(m_GlyphItems.size()) ) return; - std::vector<GlyphItem>::iterator pGlyphIter = m_GlyphItems.Impl()->begin(); + std::vector<GlyphItem>::iterator pGlyphIter = m_GlyphItems.begin(); pGlyphIter += nStart; // the nNewXPos argument determines the new cell position @@ -948,7 +953,7 @@ void GenericSalLayout::MoveGlyph( int nStart, tools::Long nNewXPos ) // adjust all following glyph positions if needed if( nXDelta != 0 ) { - for( std::vector<GlyphItem>::iterator pGlyphIterEnd = m_GlyphItems.Impl()->end(); pGlyphIter != pGlyphIterEnd; ++pGlyphIter ) + for( std::vector<GlyphItem>::iterator pGlyphIterEnd = m_GlyphItems.end(); pGlyphIter != pGlyphIterEnd; ++pGlyphIter ) { pGlyphIter->m_aLinearPos.AdjustX(nXDelta ); } @@ -957,10 +962,10 @@ void GenericSalLayout::MoveGlyph( int nStart, tools::Long nNewXPos ) void GenericSalLayout::DropGlyph( int nStart ) { - if( nStart >= static_cast<int>(m_GlyphItems.Impl()->size())) + if( nStart >= static_cast<int>(m_GlyphItems.size())) return; - std::vector<GlyphItem>::iterator pGlyphIter = m_GlyphItems.Impl()->begin(); + std::vector<GlyphItem>::iterator pGlyphIter = m_GlyphItems.begin(); pGlyphIter += nStart; pGlyphIter->dropGlyph(); } @@ -969,20 +974,20 @@ void GenericSalLayout::Simplify( bool bIsBase ) { // remove dropped glyphs inplace size_t j = 0; - for(size_t i = 0; i < m_GlyphItems.Impl()->size(); i++ ) + for(size_t i = 0; i < m_GlyphItems.size(); i++ ) { - if (bIsBase && (*m_GlyphItems.Impl())[i].IsDropped()) + if (bIsBase && m_GlyphItems[i].IsDropped()) continue; - if (!bIsBase && (*m_GlyphItems.Impl())[i].glyphId() == 0) + if (!bIsBase && m_GlyphItems[i].glyphId() == 0) continue; if( i != j ) { - (*m_GlyphItems.Impl())[j] = (*m_GlyphItems.Impl())[i]; + m_GlyphItems[j] = m_GlyphItems[i]; } j += 1; } - m_GlyphItems.Impl()->erase(m_GlyphItems.Impl()->begin() + j, m_GlyphItems.Impl()->end()); + m_GlyphItems.erase(m_GlyphItems.begin() + j, m_GlyphItems.end()); } MultiSalLayout::MultiSalLayout( std::unique_ptr<SalLayout> pBaseLayout ) @@ -1023,7 +1028,7 @@ void MultiSalLayout::AddFallback( std::unique_ptr<SalLayout> pFallback, ++mnLevel; } -bool MultiSalLayout::LayoutText( ImplLayoutArgs& rArgs, const SalLayoutGlyphs* ) +bool MultiSalLayout::LayoutText( ImplLayoutArgs& rArgs, const SalLayoutGlyphsImpl* ) { if( mnLevel <= 1 ) return false; @@ -1576,10 +1581,13 @@ bool MultiSalLayout::IsKashidaPosValid(int nCharPos) const return bValid; } -const SalLayoutGlyphs* SalLayout::GetGlyphs() const +SalLayoutGlyphs MultiSalLayout::GetGlyphs() const { - // No access to the glyphs by default. - return nullptr; + SalLayoutGlyphs glyphs; + for( int n = 0; n < mnLevel; ++n ) + glyphs.AppendImpl(mpLayouts[n]->GlyphsImpl().clone()); + return glyphs; } + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index 2cd38a58ba11..0c6c29674527 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -1210,7 +1210,7 @@ void OutputDevice::ImplDrawEmphasisMarks( SalLayout& rSalLayout ) std::unique_ptr<SalLayout> OutputDevice::getFallbackLayout( LogicalFontInstance* pLogicalFont, int nFallbackLevel, - ImplLayoutArgs& rLayoutArgs) const + ImplLayoutArgs& rLayoutArgs, const SalLayoutGlyphs* pGlyphs) const { // we need a graphics if (!mpGraphics && !AcquireGraphics()) @@ -1225,7 +1225,7 @@ std::unique_ptr<SalLayout> OutputDevice::getFallbackLayout( if (!pFallback) return nullptr; - if (!pFallback->LayoutText(rLayoutArgs, nullptr)) + if (!pFallback->LayoutText(rLayoutArgs, pGlyphs ? pGlyphs->Impl(nFallbackLevel) : nullptr)) { // there is no need for a font that couldn't resolve anything return nullptr; @@ -1234,7 +1234,8 @@ std::unique_ptr<SalLayout> OutputDevice::getFallbackLayout( return pFallback; } -std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_ptr<SalLayout> pSalLayout, ImplLayoutArgs& rLayoutArgs ) const +std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_ptr<SalLayout> pSalLayout, + ImplLayoutArgs& rLayoutArgs, const SalLayoutGlyphs* pGlyphs ) const { // This function relies on a valid mpFontInstance, if it doesn't exist bail out // - we'd have crashed later on anyway. At least here we can catch the error in debug @@ -1288,7 +1289,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt // create and add glyph fallback layout to multilayout std::unique_ptr<SalLayout> pFallback = getFallbackLayout(pFallbackFont.get(), - nFallbackLevel, rLayoutArgs); + nFallbackLevel, rLayoutArgs, pGlyphs); if (pFallback) { if( !pMultiSalLayout ) diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx index 8b8c5363a2cc..1b8d021d0fe1 100644 --- a/vcl/source/outdev/text.cxx +++ b/vcl/source/outdev/text.cxx @@ -1317,7 +1317,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplLayout(const OUString& rOrigStr, std::unique_ptr<SalLayout> pSalLayout = mpGraphics->GetTextLayout(0); // layout text - if( pSalLayout && !pSalLayout->LayoutText( aLayoutArgs, pGlyphs ) ) + if( pSalLayout && !pSalLayout->LayoutText( aLayoutArgs, pGlyphs ? pGlyphs->Impl(0) : nullptr ) ) { pSalLayout.reset(); } @@ -1328,7 +1328,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplLayout(const OUString& rOrigStr, // do glyph fallback if needed // #105768# avoid fallback for very small font sizes if (aLayoutArgs.NeedFallback() && mpFontInstance->GetFontSelectPattern().mnHeight >= 3) - pSalLayout = ImplGlyphFallbackLayout(std::move(pSalLayout), aLayoutArgs); + pSalLayout = ImplGlyphFallbackLayout(std::move(pSalLayout), aLayoutArgs, pGlyphs); if (flags & SalLayoutFlags::GlyphItemsOnly) // Return glyph items only after fallback handling. Otherwise they may diff --git a/vcl/source/window/menuitemlist.cxx b/vcl/source/window/menuitemlist.cxx index 6921e6208118..a9903447c748 100644 --- a/vcl/source/window/menuitemlist.cxx +++ b/vcl/source/window/menuitemlist.cxx @@ -52,12 +52,8 @@ SalLayoutGlyphs* MenuItemData::GetTextGlyphs(const OutputDevice* pOutputDevice) if (!pLayout) return nullptr; - const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs(); - if (!pGlyphs) - return nullptr; - // Remember the calculation result. - aTextGlyphs = *pGlyphs; + aTextGlyphs = pLayout->GetGlyphs(); return &aTextGlyphs; } diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx index e24a76da30c1..e3c193609bd3 100644 --- a/vcl/source/window/status.cxx +++ b/vcl/source/window/status.cxx @@ -398,8 +398,8 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen pLayoutCache = pItem->mxLayoutCache.get(); } - const SalLayoutGlyphs* pGlyphs = pLayoutCache ? pLayoutCache->GetGlyphs() : nullptr; - Size aTextSize(rRenderContext.GetTextWidth(pItem->maText,0,-1,nullptr,pGlyphs), rRenderContext.GetTextHeight()); + const SalLayoutGlyphs glyphs = pLayoutCache ? pLayoutCache->GetGlyphs() : SalLayoutGlyphs(); + Size aTextSize(rRenderContext.GetTextWidth(pItem->maText,0,-1,nullptr,&glyphs), rRenderContext.GetTextHeight()); Point aTextPos = ImplGetItemTextPos(aTextRectSize, aTextSize, pItem->mnBits); if (bOffScreen) @@ -408,7 +408,7 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen aTextPos, pItem->maText, 0, -1, nullptr, nullptr, - pGlyphs ); + &glyphs ); } else { @@ -418,7 +418,7 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen aTextPos, pItem->maText, 0, -1, nullptr, nullptr, - pGlyphs ); + &glyphs ); } } @@ -1139,15 +1139,15 @@ void StatusBar::SetItemText( sal_uInt16 nItemId, const OUString& rText, int nCha if (nCharsWidth != -1) { std::unique_ptr<SalLayout> pSalLayout = ImplLayout("0",0,-1); - const SalLayoutGlyphs* pGlyphs = pSalLayout ? pSalLayout->GetGlyphs() : nullptr; - nWidth = GetTextWidth("0",0,-1,nullptr,pGlyphs ); + const SalLayoutGlyphs glyphs = pSalLayout ? pSalLayout->GetGlyphs() : SalLayoutGlyphs(); + nWidth = GetTextWidth("0",0,-1,nullptr,&glyphs); nWidth = nWidth * nCharsWidth + nFudge; } else { std::unique_ptr<SalLayout> pSalLayout = ImplLayout(pItem->maText,0,-1); - const SalLayoutGlyphs* pGlyphs = pSalLayout ? pSalLayout->GetGlyphs() : nullptr; - nWidth = GetTextWidth( pItem->maText,0,-1,nullptr,pGlyphs ) + nFudge; + const SalLayoutGlyphs glyphs = pSalLayout ? pSalLayout->GetGlyphs() : SalLayoutGlyphs(); + nWidth = GetTextWidth( pItem->maText,0,-1,nullptr,&glyphs) + nFudge; // Store the calculated layout. pItem->mxLayoutCache = std::move(pSalLayout); } |