[Libreoffice-commits] core.git: vcl/inc vcl/quartz vcl/source vcl/unx vcl/win
Khaled Hosny
khaledhosny at eglug.org
Sat Dec 10 00:58:58 UTC 2016
vcl/inc/sallayout.hxx | 16 +--
vcl/quartz/salgdi.cxx | 8 -
vcl/source/gdi/pdfwriter_impl.cxx | 58 ++++++-------
vcl/source/gdi/pdfwriter_impl.hxx | 2
vcl/source/gdi/sallayout.cxx | 129 ++++++++++++-------------------
vcl/source/outdev/font.cxx | 12 +-
vcl/source/outdev/text.cxx | 24 ++---
vcl/source/outdev/textline.cxx | 11 --
vcl/unx/generic/gdi/cairotextrender.cxx | 9 +-
vcl/unx/generic/print/genpspgraphics.cxx | 30 +------
vcl/win/gdi/winlayout.cxx | 81 +++++++------------
11 files changed, 151 insertions(+), 229 deletions(-)
New commits:
commit b894104a0b02a9b074c76feb925389d7bee6a493
Author: Khaled Hosny <khaledhosny at eglug.org>
Date: Thu Dec 8 00:43:09 2016 +0200
Pass GlyphItem around
We have this nice structure that contains (almost) all the information
we need, so pass it around instead of passing separate fragments of said
information.
The ultimate is to kill the horrible sal_GlyphId hack if encoding
various bits of information in the higher bits of a 32-bit integer.
Change-Id: Ie496bb4c2932157527a388e2a94e46bf0a325a70
Reviewed-on: https://gerrit.libreoffice.org/31781
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Khaled Hosny <khaledhosny at eglug.org>
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index 3df4921..21a1e0b 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -39,6 +39,7 @@ typedef unsigned short LanguageType;
class SalGraphics;
class PhysicalFontFace;
+struct GlyphItem;
enum class SalLayoutFlags;
namespace vcl {
class TextLayoutCache;
@@ -176,9 +177,8 @@ public:
virtual bool IsKashidaPosValid ( int /*nCharPos*/ ) const { return true; } // i60594
// methods using glyph indexing
- virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdAry, Point& rPos, int&,
- DeviceCoordinate* pGlyphAdvAry = nullptr, int* pCharPosAry = nullptr,
- const PhysicalFontFace** pFallbackFonts = nullptr ) const = 0;
+ virtual int GetNextGlyphs(int nLen, const GlyphItem** pGlyphs, Point& rPos, int&,
+ const PhysicalFontFace** pFallbackFonts = nullptr) const = 0;
virtual bool GetOutline( SalGraphics&, basegfx::B2DPolyPolygonVector& ) const;
virtual bool GetBoundRect( SalGraphics&, Rectangle& ) const;
@@ -234,9 +234,8 @@ public:
virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const override;
virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const override;
virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const override;
- virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos,
- int&, DeviceCoordinate* pGlyphAdvAry = nullptr, int* pCharPosAry = nullptr,
- const PhysicalFontFace** pFallbackFonts = nullptr ) const override;
+ virtual int GetNextGlyphs(int nLen, const GlyphItem** pGlyphs, Point& rPos, int&,
+ const PhysicalFontFace** pFallbackFonts = nullptr) const override;
virtual bool GetOutline( SalGraphics&, basegfx::B2DPolyPolygonVector& ) const override;
virtual bool IsKashidaPosValid(int nCharPos) const override;
@@ -338,9 +337,8 @@ public:
virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const override;
// used by display layers
- virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos, int&,
- DeviceCoordinate* pGlyphAdvAry = nullptr, int* pCharPosAry = nullptr,
- const PhysicalFontFace** pFallbackFonts = nullptr ) const override;
+ virtual int GetNextGlyphs(int nLen, const GlyphItem** pGlyphs, Point& rPos, int&,
+ const PhysicalFontFace** pFallbackFonts = nullptr) const override;
protected:
GenericSalLayout();
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index c2dba02..4b3a63a 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -415,12 +415,12 @@ void AquaSalGraphics::DrawTextLayout(const CommonSalLayout& rLayout)
CGAffineTransform aRotMatrix = CGAffineTransformMakeRotation(-rStyle.mfFontRotation);
Point aPos;
- sal_GlyphId aGlyphId;
+ const GlyphItem* pGlyph;
std::vector<CGGlyph> aGlyphIds;
std::vector<CGPoint> aGlyphPos;
std::vector<bool> aGlyphOrientation;
int nStart = 0;
- while (rLayout.GetNextGlyphs(1, &aGlyphId, aPos, nStart))
+ while (rLayout.GetNextGlyphs(1, &pGlyph, aPos, nStart))
{
CGPoint aGCPos = CGPointMake(aPos.X(), -aPos.Y());
@@ -429,7 +429,7 @@ void AquaSalGraphics::DrawTextLayout(const CommonSalLayout& rLayout)
if (rStyle.mfFontRotation)
{
- if ((aGlyphId & GF_ROTMASK) == GF_ROTL)
+ if ((pGlyph->maGlyphId & GF_ROTMASK) == GF_ROTL)
{
bUprightGlyph = true;
// Adjust the position of upright (vertical) glyphs.
@@ -442,7 +442,7 @@ void AquaSalGraphics::DrawTextLayout(const CommonSalLayout& rLayout)
}
}
- aGlyphIds.push_back(aGlyphId & GF_IDXMASK);
+ aGlyphIds.push_back(pGlyph->maGlyphId & GF_IDXMASK);
aGlyphPos.push_back(aGCPos);
aGlyphOrientation.push_back(bUprightGlyph);
}
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index d754428..b67cb4f 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -8127,7 +8127,7 @@ sal_Int32 PDFWriterImpl::getSystemFont( const vcl::Font& i_rFont )
}
void PDFWriterImpl::registerGlyphs( int nGlyphs,
- sal_GlyphId* pGlyphs,
+ const GlyphItem** pGlyphs,
sal_Int32* pGlyphWidths,
sal_Ucs* pUnicodes,
sal_Int32* pUnicodesPerGlyph,
@@ -8144,7 +8144,7 @@ void PDFWriterImpl::registerGlyphs( int nGlyphs,
sal_Ucs* pCurUnicode = pUnicodes;
for( int i = 0; i < nGlyphs; pCurUnicode += pUnicodesPerGlyph[i] , i++ )
{
- const int nFontGlyphId = pGlyphs[i] & GF_IDXMASK;
+ const int nFontGlyphId = pGlyphs[i]->maGlyphId & GF_IDXMASK;
const PhysicalFontFace* pCurrentFont = pFallbackFonts[i] ? pFallbackFonts[i] : pDevFont;
FontSubset& rSubset = m_aSubsets[ pCurrentFont ];
@@ -8183,7 +8183,7 @@ void PDFWriterImpl::registerGlyphs( int nGlyphs,
}
if (!getReferenceDevice()->AcquireGraphics())
return;
- const bool bVertical = ((pGlyphs[i] & GF_ROTMASK) != 0);
+ const bool bVertical = ((pGlyphs[i]->maGlyphId & GF_ROTMASK) != 0);
pGlyphWidths[i] = m_aFontCache.getGlyphWidth( pCurrentFont,
nFontGlyphId,
bVertical,
@@ -8466,16 +8466,14 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
const int nMaxGlyphs = 256;
- sal_GlyphId pGlyphs[nMaxGlyphs];
+ const GlyphItem* pGlyphs[nMaxGlyphs] = { nullptr };
+ const PhysicalFontFace* pFallbackFonts[nMaxGlyphs] = { nullptr };
sal_Int32 pGlyphWidths[nMaxGlyphs];
sal_uInt8 pMappedGlyphs[nMaxGlyphs];
sal_Int32 pMappedFontObjects[nMaxGlyphs];
std::vector<sal_Ucs> aUnicodes;
aUnicodes.reserve( nMaxGlyphs );
sal_Int32 pUnicodesPerGlyph[nMaxGlyphs];
- int pCharPosAry[nMaxGlyphs];
- DeviceCoordinate nAdvanceWidths[nMaxGlyphs];
- const PhysicalFontFace* pFallbackFonts[nMaxGlyphs] = { nullptr };
bool bVertical = m_aCurrentPDFState.m_aFont.IsVertical();
int nGlyphs;
int nIndex = 0;
@@ -8603,28 +8601,28 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
aGlyphs.reserve( nTmpMaxGlyphs );
// first get all the glyphs and register them; coordinates still in Pixel
Point aGNGlyphPos;
- while( (nGlyphs = rLayout.GetNextGlyphs( nTmpMaxGlyphs, pGlyphs, aGNGlyphPos, nIndex, nAdvanceWidths, pCharPosAry, pFallbackFonts )) != 0 )
+ while ((nGlyphs = rLayout.GetNextGlyphs(nTmpMaxGlyphs, pGlyphs, aGNGlyphPos, nIndex, pFallbackFonts)) != 0)
{
aUnicodes.clear();
for( int i = 0; i < nGlyphs; i++ )
{
// default case: 1 glyph is one unicode
pUnicodesPerGlyph[i] = 1;
- if( pCharPosAry[i] >= nMinCharPos && pCharPosAry[i] <= nMaxCharPos )
+ if (pGlyphs[i]->mnCharPos >= nMinCharPos && pGlyphs[i]->mnCharPos <= nMaxCharPos)
{
int nChars = 1;
pUnicodesPerGlyph[i] = 1;
// try to handle ligatures and such
if( i < nGlyphs-1 )
{
- nChars = pCharPosAry[i+1] - pCharPosAry[i];
- int start = pCharPosAry[i];
+ nChars = pGlyphs[i+1]->mnCharPos - pGlyphs[i]->mnCharPos;
+ int start = pGlyphs[i]->mnCharPos;
// #i115618# fix for simple RTL+CTL cases
// supports RTL ligatures. TODO: more complex CTL, etc.
if( nChars < 0 )
{
nChars = -nChars;
- start = pCharPosAry[i+1] + 1;
+ start = pGlyphs[i+1]->mnCharPos + 1;
}
else if (nChars == 0)
nChars = 1;
@@ -8633,7 +8631,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
aUnicodes.push_back( rText[ start + n ] );
}
else
- aUnicodes.push_back( rText[ pCharPosAry[i] ] );
+ aUnicodes.push_back(rText[pGlyphs[i]->mnCharPos]);
// #i36691# hack that is needed because currently the pGlyphs[]
// argument is ignored for embeddable fonts and so the layout
// engine's glyph work is ignored (i.e. char mirroring)
@@ -8661,13 +8659,13 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
{
aGlyphs.push_back( PDFGlyph( aGNGlyphPos,
pGlyphWidths[i],
- pGlyphs[i],
+ pGlyphs[i]->maGlyphId,
pMappedFontObjects[i],
pMappedGlyphs[i] ) );
if( bVertical )
- aGNGlyphPos.Y() += nAdvanceWidths[i]/rLayout.GetUnitsPerPixel();
+ aGNGlyphPos.Y() += pGlyphs[i]->mnNewWidth/rLayout.GetUnitsPerPixel();
else
- aGNGlyphPos.X() += nAdvanceWidths[i]/rLayout.GetUnitsPerPixel();
+ aGNGlyphPos.X() += pGlyphs[i]->mnNewWidth/rLayout.GetUnitsPerPixel();
}
}
@@ -8714,19 +8712,16 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
{
Point aPos, aStartPt;
sal_Int32 nWidth = 0;
- DeviceCoordinate nAdvance = 0;
- for( int nStart = 0;;)
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ while (rLayout.GetNextGlyphs(1, &pGlyph, aPos, nStart))
{
- sal_GlyphId aGlyphId;
- if( !rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart, &nAdvance ) )
- break;
-
- if( !SalLayout::IsSpacingGlyph( aGlyphId ) )
+ if (!SalLayout::IsSpacingGlyph(pGlyph->maGlyphId))
{
if( !nWidth )
aStartPt = aPos;
- nWidth += nAdvance;
+ nWidth += pGlyph->mnNewWidth;
}
else if( nWidth > 0 )
{
@@ -8813,18 +8808,15 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
else if ( eAlign == ALIGN_TOP )
aOffset.Y() += m_pReferenceDevice->mpFontInstance->mxFontMetric->GetAscent();
- for( int nStart = 0;;)
+ Point aPos;
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ while (rLayout.GetNextGlyphs(1, &pGlyph, aPos, nStart))
{
- Point aPos;
- sal_GlyphId aGlyphId;
- DeviceCoordinate nAdvance;
- if( !rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart, &nAdvance ) )
- break;
-
- if( !SalLayout::IsSpacingGlyph( aGlyphId ) )
+ if (!SalLayout::IsSpacingGlyph(pGlyph->maGlyphId))
{
Point aAdjOffset = aOffset;
- aAdjOffset.X() += (nAdvance - nEmphWidth) / 2;
+ aAdjOffset.X() += (pGlyph->mnNewWidth - nEmphWidth) / 2;
aAdjOffset = aRotScale.transform( aAdjOffset );
aAdjOffset -= Point( nEmphWidth2, nEmphHeight2 );
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 5a30cf2..378801b 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -768,7 +768,7 @@ i12626
void appendLiteralStringEncrypt( OStringBuffer& rInString, const sal_Int32 nInObjectNumber, OStringBuffer& rOutBuffer );
/* creates fonts and subsets that will be emitted later */
- void registerGlyphs( int nGlyphs, sal_GlyphId* pGlyphs, sal_Int32* pGlpyhWidths, sal_Ucs* pUnicodes, sal_Int32* pUnicodesPerGlyph, sal_uInt8* pMappedGlyphs, sal_Int32* pMappedFontObjects, const PhysicalFontFace* pFallbackFonts[] );
+ void registerGlyphs(int nGlyphs, const GlyphItem** pGlyphs, sal_Int32* pGlpyhWidths, sal_Ucs* pUnicodes, sal_Int32* pUnicodesPerGlyph, sal_uInt8* pMappedGlyphs, sal_Int32* pMappedFontObjects, const PhysicalFontFace* pFallbackFonts[]);
/* emits a text object according to the passed layout */
/* TODO: remove rText as soon as SalLayout will change so that rText is not necessary anymore */
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index 2a50f67..25c1600 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -667,16 +667,15 @@ bool SalLayout::GetOutline( SalGraphics& rSalGraphics,
bool bAllOk = true;
bool bOneOk = false;
- Point aPos;
basegfx::B2DPolyPolygon aGlyphOutline;
- for( int nStart = 0;;)
- {
- sal_GlyphId nLGlyph;
- if( !GetNextGlyphs( 1, &nLGlyph, aPos, nStart ) )
- break;
+ Point aPos;
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ while (GetNextGlyphs(1, &pGlyph, aPos, nStart))
+ {
// get outline of individual glyph, ignoring "empty" glyphs
- bool bSuccess = rSalGraphics.GetGlyphOutline( nLGlyph, aGlyphOutline );
+ bool bSuccess = rSalGraphics.GetGlyphOutline(pGlyph->maGlyphId, aGlyphOutline);
bAllOk &= bSuccess;
bOneOk |= bSuccess;
// only add non-empty outlines
@@ -700,16 +699,15 @@ bool SalLayout::GetBoundRect( SalGraphics& rSalGraphics, Rectangle& rRect ) cons
bool bRet = false;
rRect.SetEmpty();
- Point aPos;
Rectangle aRectangle;
- for( int nStart = 0;;)
- {
- sal_GlyphId nLGlyph;
- if( !GetNextGlyphs( 1, &nLGlyph, aPos, nStart ) )
- break;
+ Point aPos;
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ while (GetNextGlyphs(1, &pGlyph, aPos, nStart))
+ {
// get bounding rectangle of individual glyph
- if( rSalGraphics.GetGlyphBoundRect( nLGlyph, aRectangle ) )
+ if (rSalGraphics.GetGlyphBoundRect(pGlyph->maGlyphId, aRectangle))
{
// merge rectangle
aRectangle += aPos;
@@ -951,9 +949,9 @@ sal_Int32 GenericSalLayout::GetTextBreak( DeviceCoordinate nMaxWidth, DeviceCoor
return -1;
}
-int GenericSalLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos,
- int& nStart, DeviceCoordinate* pGlyphAdvAry, int* pCharPosAry,
- const PhysicalFontFace** /*pFallbackFonts*/ ) const
+int GenericSalLayout::GetNextGlyphs(int nLen, const GlyphItem** pGlyphs,
+ Point& rPos, int& nStart,
+ const PhysicalFontFace** /*pFallbackFonts*/) const
{
std::vector<GlyphItem>::const_iterator pGlyphIter = m_GlyphItems.begin();
std::vector<GlyphItem>::const_iterator pGlyphIterEnd = m_GlyphItems.end();
@@ -985,11 +983,7 @@ int GenericSalLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos
{
// update return data with glyph info
++nCount;
- *(pGlyphs++) = pGlyphIter->maGlyphId;
- if( pCharPosAry )
- *(pCharPosAry++) = pGlyphIter->mnCharPos;
- if( pGlyphAdvAry )
- *pGlyphAdvAry = pGlyphIter->mnNewWidth;
+ *(pGlyphs++) = &(*pGlyphIter);
// break at end of glyph list
if( ++nStart >= (int)m_GlyphItems.size() )
@@ -999,17 +993,9 @@ int GenericSalLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos
break;
long nGlyphAdvance = pGlyphIter[1].maLinearPos.X() - pGlyphIter->maLinearPos.X();
- if( pGlyphAdvAry )
- {
- // override default advance width with correct value
- *(pGlyphAdvAry++) = nGlyphAdvance;
- }
- else
- {
- // stop when next x-position is unexpected
- if( pGlyphIter->mnOrigWidth != nGlyphAdvance )
- break;
- }
+ // stop when next x-position is unexpected
+ if( pGlyphIter->mnOrigWidth != nGlyphAdvance )
+ break;
// advance to next glyph
++pGlyphIter;
@@ -1225,11 +1211,9 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
// prepare "merge sort"
int nStartOld[ MAX_FALLBACK ];
int nStartNew[ MAX_FALLBACK ];
- int nCharPos[ MAX_FALLBACK ];
- DeviceCoordinate nGlyphAdv[ MAX_FALLBACK ];
+ const GlyphItem* pGlyphs[MAX_FALLBACK];
int nValid[ MAX_FALLBACK ] = {0};
- sal_GlyphId nDummy;
Point aPos;
int nLevel = 0, n;
for( n = 0; n < mnLevel; ++n )
@@ -1256,8 +1240,7 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
// prepare merging components
nStartNew[ nLevel ] = nStartOld[ nLevel ] = 0;
- nValid[ nLevel ] = mpLayouts[n]->GetNextGlyphs( 1, &nDummy, aPos,
- nStartNew[ nLevel ], &nGlyphAdv[ nLevel ], &nCharPos[ nLevel ] );
+ nValid[nLevel] = mpLayouts[n]->GetNextGlyphs(1, &pGlyphs[nLevel], aPos, nStartNew[nLevel]);
if( (n > 0) && !nValid[ nLevel ] )
{
@@ -1284,12 +1267,12 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
for( n = 0; n < nLevel; ++n )
maFallbackRuns[n].ResetPos();
// get the next codepoint index that needs fallback
- int nActiveCharPos = nCharPos[0];
+ int nActiveCharPos = pGlyphs[0]->mnCharPos;
int nActiveCharIndex = nActiveCharPos - mnMinCharPos;
// get the end index of the active run
int nLastRunEndChar = (nActiveCharIndex >= 0 && vRtl[nActiveCharIndex]) ?
rArgs.mnEndCharPos : rArgs.mnMinCharPos - 1;
- int nRunVisibleEndChar = nCharPos[0];
+ int nRunVisibleEndChar = pGlyphs[0]->mnCharPos;
// merge the fallback levels
while( nValid[0] && (nLevel > 0))
{
@@ -1318,14 +1301,13 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
{
// drop the NotDef glyphs in the base layout run if a fallback run exists
while (
- (maFallbackRuns[ n-1 ].PosIsInRun( nCharPos[0] ) ) &&
- (!maFallbackRuns[ n ].PosIsInAnyRun( nCharPos[0] ) )
+ (maFallbackRuns[n-1].PosIsInRun(pGlyphs[0]->mnCharPos)) &&
+ (!maFallbackRuns[n].PosIsInAnyRun(pGlyphs[0]->mnCharPos))
)
{
mpLayouts[0]->DropGlyph( nStartOld[0] );
nStartOld[0] = nStartNew[0];
- nValid[0] = mpLayouts[0]->GetNextGlyphs( 1, &nDummy, aPos,
- nStartNew[0], &nGlyphAdv[0], &nCharPos[0] );
+ nValid[0] = mpLayouts[0]->GetNextGlyphs(1, &pGlyphs[0], aPos, nStartNew[0]);
if( !nValid[0] )
break;
@@ -1337,13 +1319,12 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
bool bKeepNotDef = (nFBLevel >= nLevel);
for(;;)
{
- nRunAdvance += nGlyphAdv[n];
+ nRunAdvance += pGlyphs[n]->mnNewWidth;
// proceed to next glyph
nStartOld[n] = nStartNew[n];
- int nOrigCharPos = nCharPos[n];
- nValid[n] = mpLayouts[n]->GetNextGlyphs( 1, &nDummy, aPos,
- nStartNew[n], &nGlyphAdv[n], &nCharPos[n] );
+ int nOrigCharPos = pGlyphs[n]->mnCharPos;
+ nValid[n] = mpLayouts[n]->GetNextGlyphs(1, &pGlyphs[n], aPos, nStartNew[n]);
// break after last glyph of active layout
if( !nValid[n] )
{
@@ -1356,16 +1337,16 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
//If the next character is one which belongs to the next level, then we
//are finished here for now, and we'll pick up after the next level has
//been processed
- if ((n+1 < nLevel) && (nCharPos[n] != nOrigCharPos))
+ if ((n+1 < nLevel) && (pGlyphs[n]->mnCharPos != nOrigCharPos))
{
- if (nOrigCharPos < nCharPos[n])
+ if (nOrigCharPos < pGlyphs[n]->mnCharPos)
{
- if (nCharPos[n+1] > nOrigCharPos && (nCharPos[n+1] < nCharPos[n]))
+ if (pGlyphs[n+1]->mnCharPos > nOrigCharPos && (pGlyphs[n+1]->mnCharPos < pGlyphs[n]->mnCharPos))
break;
}
- else if (nOrigCharPos > nCharPos[n])
+ else if (nOrigCharPos > pGlyphs[n]->mnCharPos)
{
- if (nCharPos[n+1] > nCharPos[n] && (nCharPos[n+1] < nOrigCharPos))
+ if (pGlyphs[n+1]->mnCharPos > pGlyphs[n]->mnCharPos && (pGlyphs[n+1]->mnCharPos < nOrigCharPos))
break;
}
}
@@ -1374,15 +1355,15 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
if( n > 0 )
{
// skip until end of fallback run
- if( !maFallbackRuns[n-1].PosIsInRun( nCharPos[n] ) )
+ if (!maFallbackRuns[n-1].PosIsInRun(pGlyphs[n]->mnCharPos))
break;
}
else
{
// break when a fallback is needed and available
- bool bNeedFallback = maFallbackRuns[0].PosIsInRun( nCharPos[0] );
+ bool bNeedFallback = maFallbackRuns[0].PosIsInRun(pGlyphs[0]->mnCharPos);
if( bNeedFallback )
- if( !maFallbackRuns[ nLevel-1 ].PosIsInRun( nCharPos[0] ) )
+ if (!maFallbackRuns[nLevel-1].PosIsInRun(pGlyphs[0]->mnCharPos))
break;
// break when change from resolved to unresolved base layout run
if( bKeepNotDef && !bNeedFallback )
@@ -1393,21 +1374,21 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
if (aMultiArgs.mpDXArray &&
nRunVisibleEndChar < mnEndCharPos &&
nRunVisibleEndChar >= mnMinCharPos &&
- nCharPos[n] < mnEndCharPos &&
- nCharPos[n] >= mnMinCharPos)
+ pGlyphs[n]->mnCharPos < mnEndCharPos &&
+ pGlyphs[n]->mnCharPos >= mnMinCharPos)
{
if (vRtl[nActiveCharPos - mnMinCharPos])
{
if (aMultiArgs.mpDXArray[nRunVisibleEndChar-mnMinCharPos]
- >= aMultiArgs.mpDXArray[nCharPos[n] - mnMinCharPos])
+ >= aMultiArgs.mpDXArray[pGlyphs[n]->mnCharPos - mnMinCharPos])
{
- nRunVisibleEndChar = nCharPos[n];
+ nRunVisibleEndChar = pGlyphs[n]->mnCharPos;
}
}
else if (aMultiArgs.mpDXArray[nRunVisibleEndChar-mnMinCharPos]
- <= aMultiArgs.mpDXArray[nCharPos[n] - mnMinCharPos])
+ <= aMultiArgs.mpDXArray[pGlyphs[n]->mnCharPos - mnMinCharPos])
{
- nRunVisibleEndChar = nCharPos[n];
+ nRunVisibleEndChar = pGlyphs[n]->mnCharPos;
}
}
}
@@ -1435,7 +1416,7 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
nRunAdvance -= aMultiArgs.mpDXArray[nLastRunEndChar - mnMinCharPos];
}
nLastRunEndChar = nRunVisibleEndChar;
- nRunVisibleEndChar = nCharPos[0];
+ nRunVisibleEndChar = pGlyphs[0]->mnCharPos;
// the requested width is still in pixel units
// => convert it to base level font units
nRunAdvance *= mnUnitsPerPixel;
@@ -1452,7 +1433,7 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs )
nXPos += nRunAdvance;
// prepare for next fallback run
- nActiveCharPos = nCharPos[0];
+ nActiveCharPos = pGlyphs[0]->mnCharPos;
// it essential that the runs don't get ahead of themselves and in the
// if( bKeepNotDef && !bNeedFallback ) statement above, the next run may
// have already been reached on the base level
@@ -1612,9 +1593,9 @@ void MultiSalLayout::GetCaretPositions( int nMaxIndex, long* pCaretXArray ) cons
}
}
-int MultiSalLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos,
- int& nStart, DeviceCoordinate* pGlyphAdvAry, int* pCharPosAry,
- const PhysicalFontFace** pFallbackFonts ) const
+int MultiSalLayout::GetNextGlyphs(int nLen, const GlyphItem** pGlyphs,
+ Point& rPos, int& nStart,
+ const PhysicalFontFace** pFallbackFonts) const
{
// for multi-level fallback only single glyphs should be used
if( mnLevel > 1 && nLen > 1 )
@@ -1627,23 +1608,15 @@ int MultiSalLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& r
{
SalLayout& rLayout = *mpLayouts[ nLevel ];
rLayout.InitFont();
- int nRetVal = rLayout.GetNextGlyphs( nLen, pGlyphIdxAry, rPos,
- nStart, pGlyphAdvAry, pCharPosAry );
+ int nRetVal = rLayout.GetNextGlyphs(nLen, pGlyphs, rPos, nStart);
if( nRetVal )
{
int nFontTag = nLevel << GF_FONTSHIFT;
nStart |= nFontTag;
- double fUnitMul = mnUnitsPerPixel;
- fUnitMul /= mpLayouts[nLevel]->GetUnitsPerPixel();
for( int i = 0; i < nRetVal; ++i )
{
- if( pGlyphAdvAry )
- {
- DeviceCoordinate w = pGlyphAdvAry[i];
- w = static_cast<DeviceCoordinate>(w * fUnitMul + 0.5);
- pGlyphAdvAry[i] = w;
- }
- pGlyphIdxAry[ i ] |= nFontTag;
+ // FIXME: This is ugly!
+ const_cast<GlyphItem*>(pGlyphs[i])->maGlyphId |= nFontTag;
if( pFallbackFonts )
{
pFallbackFonts[ i ] = mpFallbackFonts[ nLevel ];
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 9b0a5dd..71d3f21 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -1296,16 +1296,14 @@ void OutputDevice::ImplDrawEmphasisMarks( SalLayout& rSalLayout )
Point aOutPoint;
Rectangle aRectangle;
- for( int nStart = 0;;)
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ while (rSalLayout.GetNextGlyphs(1, &pGlyph, aOutPoint, nStart))
{
- sal_GlyphId aGlyphId;
- if( !rSalLayout.GetNextGlyphs( 1, &aGlyphId, aOutPoint, nStart ) )
- break;
-
- if( !mpGraphics->GetGlyphBoundRect( aGlyphId, aRectangle ) )
+ if (!mpGraphics->GetGlyphBoundRect(pGlyph->maGlyphId, aRectangle ) )
continue;
- if( !SalLayout::IsSpacingGlyph( aGlyphId ) )
+ if (!SalLayout::IsSpacingGlyph(pGlyph->maGlyphId))
{
Point aAdjPoint = aOffset;
aAdjPoint.X() += aRectangle.Left() + (aRectangle.GetWidth() - nEmphasisWidth) / 2;
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 6e034a1..93deefe 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -2389,19 +2389,17 @@ SystemTextLayoutData OutputDevice::GetSysTextLayoutData(const Point& rStartPt, c
// setup glyphs
Point aPos;
- sal_GlyphId aGlyphId;
- for( int nStart = 0; pLayout->GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
- {
- // NOTE: Windows backend is producing unicode chars (ucs4), so on windows,
- // ETO_GLYPH_INDEX is unusable, unless extra glyph conversion is made.
-
- SystemGlyphData aGlyph;
- aGlyph.index = static_cast<unsigned long> (aGlyphId & GF_IDXMASK);
- aGlyph.x = aPos.X();
- aGlyph.y = aPos.Y();
- int nLevel = (aGlyphId & GF_FONTMASK) >> GF_FONTSHIFT;
- aGlyph.fallbacklevel = nLevel < MAX_FALLBACK ? nLevel : 0;
- aSysLayoutData.rGlyphData.push_back(aGlyph);
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ while (pLayout->GetNextGlyphs(1, &pGlyph, aPos, nStart))
+ {
+ SystemGlyphData aSystemGlyph;
+ aSystemGlyph.index = static_cast<unsigned long> (pGlyph->maGlyphId & GF_IDXMASK);
+ aSystemGlyph.x = aPos.X();
+ aSystemGlyph.y = aPos.Y();
+ int nLevel = (pGlyph->maGlyphId & GF_FONTMASK) >> GF_FONTSHIFT;
+ aSystemGlyph.fallbacklevel = nLevel < MAX_FALLBACK ? nLevel : 0;
+ aSysLayoutData.rGlyphData.push_back(aSystemGlyph);
}
// Get font data
diff --git a/vcl/source/outdev/textline.cxx b/vcl/source/outdev/textline.cxx
index d742e8f..c16fd4a 100644
--- a/vcl/source/outdev/textline.cxx
+++ b/vcl/source/outdev/textline.cxx
@@ -752,15 +752,12 @@ void OutputDevice::ImplDrawTextLines( SalLayout& rSalLayout, FontStrikeout eStri
DeviceCoordinate nDist = 0;
DeviceCoordinate nWidth = 0;
DeviceCoordinate nAdvance = 0;
- for( int nStart = 0;;)
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ while (rSalLayout.GetNextGlyphs(1, &pGlyph, aPos, nStart))
{
- // iterate through the layouted glyphs
- sal_GlyphId aGlyphId;
- if( !rSalLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart, &nAdvance ) )
- break;
-
// calculate the boundaries of each word
- if( !SalLayout::IsSpacingGlyph( aGlyphId ) )
+ if (!SalLayout::IsSpacingGlyph(pGlyph->maGlyphId))
{
if( !nWidth )
{
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index de3dc4b..501d399 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -173,16 +173,17 @@ void CairoTextRender::DrawTextLayout(const CommonSalLayout& rLayout)
cairo_glyphs.reserve( 256 );
Point aPos;
- sal_GlyphId aGlyphId;
- for( int nStart = 0; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ while (rLayout.GetNextGlyphs(1, &pGlyph, aPos, nStart))
{
cairo_glyph_t aGlyph;
- aGlyph.index = aGlyphId & GF_IDXMASK;
+ aGlyph.index = pGlyph->maGlyphId & GF_IDXMASK;
aGlyph.x = aPos.X();
aGlyph.y = aPos.Y();
cairo_glyphs.push_back(aGlyph);
- switch (aGlyphId & GF_ROTMASK)
+ switch (pGlyph->maGlyphId & GF_ROTMASK)
{
case GF_ROTL: // left
glyph_extrarotation.push_back(1);
diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx
index b1e4435..213874d 100644
--- a/vcl/unx/generic/print/genpspgraphics.cxx
+++ b/vcl/unx/generic/print/genpspgraphics.cxx
@@ -591,31 +591,15 @@ void PspCommonSalLayout::InitFont() const
void GenPspGraphics::DrawTextLayout(const CommonSalLayout& rLayout)
{
- const int nMaxGlyphs = 1;
- sal_GlyphId aGlyphAry[ nMaxGlyphs ];
- DeviceCoordinate aWidthAry[ nMaxGlyphs ];
- sal_Int32 aIdxAry [ nMaxGlyphs ];
- sal_Unicode aUnicodes[ nMaxGlyphs ];
-
+ const GlyphItem* pGlyph;
Point aPos;
- long nUnitsPerPixel = rLayout.GetUnitsPerPixel();
- for( int nStart = 0;; )
+ int nStart = 0;
+ while (rLayout.GetNextGlyphs(1, &pGlyph, aPos, nStart))
{
- int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, nullptr );
- if( !nGlyphCount )
- break;
-
- DeviceCoordinate nXOffset = 0;
- for( int i = 0; i < nGlyphCount; ++i )
- {
- nXOffset += aWidthAry[ i ];
- aIdxAry[ i ] = nXOffset / nUnitsPerPixel;
- sal_GlyphId aGlyphId = aGlyphAry[i] & (GF_IDXMASK | GF_ROTMASK);
- aUnicodes[i] = 0;
- aGlyphAry[i] = aGlyphId;
- }
-
- m_pPrinterGfx->DrawGlyphs( aPos, aGlyphAry, aUnicodes, nGlyphCount, aIdxAry );
+ sal_GlyphId aGlyphId = pGlyph->maGlyphId & (GF_IDXMASK | GF_ROTMASK);
+ sal_Int32 nAdvance = pGlyph->mnNewWidth / rLayout.GetUnitsPerPixel();
+ sal_Unicode nUnicode = 0;
+ m_pPrinterGfx->DrawGlyphs(aPos, &aGlyphId, &nUnicode, 1, &nAdvance);
}
}
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 621c241..f78e71f 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -289,30 +289,18 @@ bool ExTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
const Rectangle* pRectToErase,
Point* pPos, int* pGetNextGlypInfo)
{
- const int MAX_GLYPHS = 2;
- sal_GlyphId glyphIntStr[MAX_GLYPHS];
- int nGlyphs = 0;
- WORD glyphWStr[MAX_GLYPHS];
- do
+ bool bGlyphs = false;
+ const GlyphItem* pGlyph;
+ while (rLayout.GetNextGlyphs(1, &pGlyph, *pPos, *pGetNextGlypInfo))
{
- nGlyphs = rLayout.GetNextGlyphs(1, glyphIntStr, *pPos, *pGetNextGlypInfo);
- if (nGlyphs < 1)
- break;
-
- if (SalLayout::UseCommonLayout())
- {
- for (int i = 0; i < nGlyphs; i++)
- {
- if ((glyphIntStr[i] & GF_ROTMASK) == GF_ROTL)
- glyphIntStr[i] |= GF_VERT;
- }
- }
-
- std::copy_n(glyphIntStr, nGlyphs, glyphWStr);
- ExtTextOutW(hDC, pPos->X(), pPos->Y(), ETO_GLYPH_INDEX, nullptr, LPCWSTR(&glyphWStr), nGlyphs, nullptr);
- } while (!pRectToErase);
+ bGlyphs = true;
+ WORD glyphWStr[] = { pGlyph->maGlyphId & GF_IDXMASK };
+ if ((pGlyph->maGlyphId & GF_ROTMASK) == GF_ROTL)
+ glyphWStr[0] |= GF_VERT;
+ ExtTextOutW(hDC, pPos->X(), pPos->Y(), ETO_GLYPH_INDEX, nullptr, LPCWSTR(&glyphWStr), 1, nullptr);
+ }
- return (pRectToErase && nGlyphs >= 1);
+ return (pRectToErase && bGlyphs);
}
D2DWriteTextOutRenderer::D2DWriteTextOutRenderer()
@@ -373,16 +361,9 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
succeeded &= SUCCEEDED(mpRT->CreateSolidColorBrush(D2D1::ColorF(GetRValue(bgrTextColor) / 255.0f, GetGValue(bgrTextColor) / 255.0f, GetBValue(bgrTextColor) / 255.0f), &pBrush));
HRESULT hr = S_OK;
- int nGlyphs = 0;
+ bool bGlyphs = false;
if (succeeded)
{
- const int MAX_GLYPHS = 2;
- sal_GlyphId glyphIntStr[MAX_GLYPHS];
- UINT16 glyphIndices[MAX_GLYPHS];
- long glyphIntAdv[MAX_GLYPHS];
- FLOAT glyphAdvances[MAX_GLYPHS];
- DWRITE_GLYPH_OFFSET glyphOffsets[MAX_GLYPHS] = { { 0.0f, 0.0f }, };
-
bool bVertical = false;
float nYDiff = 0.0f;
const CommonSalLayout* pCSL = dynamic_cast<const CommonSalLayout*>(&rLayout);
@@ -401,20 +382,18 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
D2D1_MATRIX_3X2_F aOrigTrans, aRotTrans;
mpRT->GetTransform(&aOrigTrans);
- do
+ const GlyphItem* pGlyph;
+ while (rLayout.GetNextGlyphs(1, &pGlyph, *pPos, *pGetNextGlypInfo))
{
- nGlyphs = rLayout.GetNextGlyphs(1, glyphIntStr, *pPos, *pGetNextGlypInfo, glyphIntAdv);
- if (nGlyphs < 1)
- break;
-
- std::copy_n(glyphIntStr, nGlyphs, glyphIndices);
- std::copy_n(glyphIntAdv, nGlyphs, glyphAdvances);
-
+ bGlyphs = true;
+ UINT16 glyphIndices[] = { pGlyph->maGlyphId & GF_IDXMASK };
+ FLOAT glyphAdvances[] = { pGlyph->mnNewWidth };
+ DWRITE_GLYPH_OFFSET glyphOffsets[] = { { 0.0f, 0.0f }, };
D2D1_POINT_2F baseline = { pPos->X() - bounds.Left(), pPos->Y() - bounds.Top() };
DWRITE_GLYPH_RUN glyphs = {
mpFontFace,
mlfEmHeight,
- nGlyphs,
+ 1,
glyphIndices,
glyphAdvances,
glyphOffsets,
@@ -422,7 +401,7 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
0
};
- if (bVertical && (glyphIntStr[0] & GF_ROTMASK) != GF_ROTL)
+ if (bVertical && (pGlyph->maGlyphId & GF_ROTMASK) != GF_ROTL)
{
D2D1MakeRotateMatrix(90.0f, baseline, &aRotTrans);
mpRT->SetTransform(aOrigTrans * aRotTrans);
@@ -433,7 +412,7 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
{
mpRT->DrawGlyphRun({ baseline.x, baseline.y + nYDiff }, &glyphs, pBrush);
}
- } while (!pRectToErase);
+ }
hr = mpRT->EndDraw();
}
@@ -446,7 +425,7 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
if (hr == D2DERR_RECREATE_TARGET)
CreateRenderTarget();
- return (succeeded && nGlyphs >= 1 && pRectToErase);
+ return (succeeded && bGlyphs && pRectToErase);
}
bool D2DWriteTextOutRenderer::BindFont(HDC hDC)
@@ -558,16 +537,16 @@ bool D2DWriteTextOutRenderer::GetDWriteInkBox(SalLayout const &rLayout, Rectangl
mpFontFace->GetMetrics(&aFontMetrics);
Point aPos;
- sal_GlyphId nLGlyph;
+ const GlyphItem* pGlyph;
std::vector<uint16_t> indices;
- std::vector<sal_GlyphId> gids;
+ std::vector<bool> vertical;
std::vector<Point> positions;
int nStart = 0;
- while (rLayout.GetNextGlyphs(1, &nLGlyph, aPos, nStart) == 1)
+ while (rLayout.GetNextGlyphs(1, &pGlyph, aPos, nStart))
{
positions.push_back(aPos);
- indices.push_back(nLGlyph);
- gids.push_back(nLGlyph);
+ indices.push_back(pGlyph->maGlyphId & GF_IDXMASK);
+ vertical.push_back((pGlyph->maGlyphId & GF_ROTMASK) == GF_ROTL);
}
auto aBoxes = GetGlyphInkBoxes(indices.data(), indices.data() + indices.size());
@@ -588,18 +567,20 @@ bool D2DWriteTextOutRenderer::GetDWriteInkBox(SalLayout const &rLayout, Rectangl
}
auto p = positions.begin();
- auto gid = gids.begin();
+ auto v = vertical.begin();
for (auto &b:aBoxes)
{
if (bVertical)
{
- if ((*gid++ & GF_ROTMASK) != GF_ROTL)
+ if (!*v)
// FIXME: Hack, should rotate the box here instead.
b.expand(std::max(b.getHeight(), b.getWidth()));
else
b += Point(0, nYDiff);
}
- b += *p++;
+ b += *p;
+ p++;
+ v++;
rOut.Union(b);
}
More information about the Libreoffice-commits
mailing list