diff options
-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); } |