summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/glyphitem.hxx19
-rw-r--r--include/vcl/outdev.hxx6
-rw-r--r--include/vcl/vcllayout.hxx6
-rw-r--r--sc/source/ui/view/output2.cxx4
-rw-r--r--svtools/source/control/ruler.cxx6
-rw-r--r--sw/source/core/txtnode/fntcache.cxx6
-rw-r--r--vcl/inc/impglyphitem.hxx7
-rw-r--r--vcl/inc/sallayout.hxx13
-rw-r--r--vcl/qa/cppunit/complextext.cxx10
-rw-r--r--vcl/source/control/imp_listbox.cxx6
-rw-r--r--vcl/source/gdi/CommonSalLayout.cxx68
-rw-r--r--vcl/source/gdi/impglyphitem.cxx42
-rw-r--r--vcl/source/gdi/sallayout.cxx64
-rw-r--r--vcl/source/outdev/font.cxx9
-rw-r--r--vcl/source/outdev/text.cxx4
-rw-r--r--vcl/source/window/menuitemlist.cxx6
-rw-r--r--vcl/source/window/status.cxx16
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);
}