summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/sallayout.hxx16
-rw-r--r--vcl/quartz/salgdi.cxx8
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx58
-rw-r--r--vcl/source/gdi/pdfwriter_impl.hxx2
-rw-r--r--vcl/source/gdi/sallayout.cxx129
-rw-r--r--vcl/source/outdev/font.cxx12
-rw-r--r--vcl/source/outdev/text.cxx24
-rw-r--r--vcl/source/outdev/textline.cxx11
-rw-r--r--vcl/unx/generic/gdi/cairotextrender.cxx9
-rw-r--r--vcl/unx/generic/print/genpspgraphics.cxx30
-rw-r--r--vcl/win/gdi/winlayout.cxx81
11 files changed, 151 insertions, 229 deletions
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index 3df492110bf9..21a1e0b81789 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 c2dba0242839..4b3a63ac140d 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 d7544287cd80..b67cb4fa3f07 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 5a30cf23afd8..378801bb0a38 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 2a50f679c71d..25c1600251da 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 9b0a5ddc4823..71d3f21574b2 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 6e034a122ca6..93deefebd5cc 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 d742e8fcf098..c16fd4aa6511 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 de3dc4b9d28b..501d3998a9da 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 b1e4435ba6f7..213874d84e3e 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 621c24118728..f78e71f13cdf 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);
}