diff options
author | Khaled Hosny <khaledhosny@eglug.org> | 2016-12-08 00:43:09 +0200 |
---|---|---|
committer | Khaled Hosny <khaledhosny@eglug.org> | 2016-12-10 00:58:26 +0000 |
commit | b894104a0b02a9b074c76feb925389d7bee6a493 (patch) | |
tree | 93e8a9362281f2c992f503a4e38ec17d04a9132b /vcl | |
parent | b52167df08511239c3d08904a3d12a3c92141f38 (diff) |
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@libreoffice.org>
Reviewed-by: Khaled Hosny <khaledhosny@eglug.org>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/sallayout.hxx | 16 | ||||
-rw-r--r-- | vcl/quartz/salgdi.cxx | 8 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 58 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/sallayout.cxx | 129 | ||||
-rw-r--r-- | vcl/source/outdev/font.cxx | 12 | ||||
-rw-r--r-- | vcl/source/outdev/text.cxx | 24 | ||||
-rw-r--r-- | vcl/source/outdev/textline.cxx | 11 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/cairotextrender.cxx | 9 | ||||
-rw-r--r-- | vcl/unx/generic/print/genpspgraphics.cxx | 30 | ||||
-rw-r--r-- | vcl/win/gdi/winlayout.cxx | 81 |
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); } |