summaryrefslogtreecommitdiff
path: root/vcl/source/gdi
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-03-16 15:04:08 +0100
committerLuboš Luňák <l.lunak@collabora.com>2021-03-17 22:49:33 +0100
commit7439cabc643de2f07c18adc35056f802997f484a (patch)
tree1fb8f6bd207a81936617263091dca32d3536f1d6 /vcl/source/gdi
parent9d02d86e8a9111b7a689062eb9a856146a9e80b1 (diff)
make SalLayoutGlyphs work with MultiSalLayout
Code that needs to lay out texts repeatedly can cache the result of SalLayout::GetGlyphs() can reuse it. But GetGlyphs() returns nullptr for MultiSalLayout, so caching for it doesn't work. Worse still, it actually increases the number of layout calls, because there's the initial layout for caching and then each call will need to do the layout again because of the nullptr that's not cached. This commit changes SalLayoutGlyphs to possibly include multiple SalLayoutGlyphsImpl objects, one for each SalLayout handled by MultiSalLayout. Changes include making GenericSalLayout work directly with the Impl class, which avoids an indirection and simplifies code. Change-Id: Ic4b19934a8a06d4955b51527fe3777c5e91107b2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112590 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl/source/gdi')
-rw-r--r--vcl/source/gdi/CommonSalLayout.cxx68
-rw-r--r--vcl/source/gdi/impglyphitem.cxx42
-rw-r--r--vcl/source/gdi/sallayout.cxx64
3 files changed, 91 insertions, 83 deletions
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: */