vcl/inc/win/salgdi.h | 11 vcl/win/source/gdi/salgdi.cxx | 5 vcl/win/source/gdi/salgdi3.cxx | 40 - vcl/win/source/gdi/winlayout.cxx | 828 --------------------------------------- vcl/win/source/gdi/winlayout.hxx | 45 -- 5 files changed, 10 insertions(+), 919 deletions(-)
New commits: commit b8e719b73ce6c27c5cf5376c2669bfe530b36014 Author: Tor Lillqvist <[email protected]> Date: Mon Jan 11 13:11:25 2016 +0200 Revert "tdf#96420: Re-introduce SimpleWinLayout" This reverts commit 9123edb25359e5e1c781139ac8b02bd361f7a60f. diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index dd2452f..4ff01fa 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -214,9 +214,6 @@ private: RGNDATA* mpClipRgnData; // ClipRegion-Data RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data ImplFontAttrCache* mpFontAttrCache; // Cache font attributes from files in so/share/fonts - bool mbFontKernInit; // FALSE: FontKerns must be queried - KERNINGPAIR* mpFontKernPairs; // Kerning Pairs of the current Font - sal_uIntPtr mnFontKernPairCount;// Number of Kerning Pairs of the current Font int mnPenWidth; // Linienbreite public: @@ -333,12 +330,6 @@ protected: const SalBitmap* pAlphaBitmap) override; virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) override; -private: - // local helpers - - // get kernign pairs of the current font - sal_uLong GetKernPairs(); - public: // public SalGraphics methods, the interface to the independent vcl part @@ -460,7 +451,7 @@ void ImplGetLogFontFromFontSelect( HDC, const FontSelectPattern*, #define MAX_64KSALPOINTS ((((sal_uInt16)0xFFFF)-8)/sizeof(POINTS)) // #102411# Win's GCP mishandles kerning => we need to do it ourselves -// SalGraphicsData::mpFontKernPairs is sorted by +// kerning pairs is sorted by inline bool ImplCmpKernData( const KERNINGPAIR& a, const KERNINGPAIR& b ) { if( a.wFirst < b.wFirst ) diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index 42ab90e..5f29820 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -631,9 +631,6 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hW mhDefPal(0), mpStdClipRgnData(NULL), mpFontAttrCache(NULL), - mpFontKernPairs(NULL), - mnFontKernPairCount(0), - mbFontKernInit(false), mnPenWidth(GSL_PEN_WIDTH) { if (OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter) @@ -663,8 +660,6 @@ WinSalGraphics::~WinSalGraphics() // delete cache data delete [] (BYTE*)mpStdClipRgnData; - - delete [] mpFontKernPairs; } SalGraphicsImpl* WinSalGraphics::GetImpl() const diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index 4de6530..9412799 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -1559,17 +1559,6 @@ sal_uInt16 WinSalGraphics::SetFont( FontSelectPattern* pFont, int nFallbackLevel if( mpWinFontData[ nFallbackLevel ] ) mpWinFontData[ nFallbackLevel ]->UpdateFromHDC( getHDC() ); - if( !nFallbackLevel ) - { - mbFontKernInit = TRUE; - if ( mpFontKernPairs ) - { - delete[] mpFontKernPairs; - mpFontKernPairs = NULL; - } - mnFontKernPairCount = 0; - } - // some printers have higher internal resolution, so their // text output would be different from what we calculated // => suggest DrawTextArray to workaround this problem @@ -1656,35 +1645,6 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLe pMetric->mnMinKashida = GetMinKashidaWidth(); } -sal_uLong WinSalGraphics::GetKernPairs() -{ - if ( mbFontKernInit ) - { - if( mpFontKernPairs ) - { - delete[] mpFontKernPairs; - mpFontKernPairs = NULL; - } - mnFontKernPairCount = 0; - - KERNINGPAIR* pPairs = NULL; - int nCount = ::GetKerningPairsW( getHDC(), 0, NULL ); - if( nCount ) - { - pPairs = new KERNINGPAIR[ nCount+1 ]; - mpFontKernPairs = pPairs; - mnFontKernPairCount = nCount; - ::GetKerningPairsW( getHDC(), nCount, pPairs ); - } - - mbFontKernInit = FALSE; - - std::sort( mpFontKernPairs, mpFontKernPairs + mnFontKernPairCount, ImplCmpKernData ); - } - - return mnFontKernPairCount; -} - const FontCharMapPtr WinSalGraphics::GetFontCharMap() const { if( !mpWinFontData[0] ) diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index f334fda..cef4f8a 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -47,8 +47,6 @@ #include <unordered_map> -typedef std::unordered_map<int,int> IntMap; - // Graphite headers #include <config_graphite.h> #if ENABLE_GRAPHITE @@ -99,15 +97,6 @@ private: // TODO: also add HFONT??? Watch out for issues with too many active fonts... public: - bool HasKernData() const; - void SetKernData( int, const KERNINGPAIR* ); - int GetKerning( sal_Unicode, sal_Unicode ) const; - -private: - KERNINGPAIR* mpKerningPairs; - int mnKerningPairs; - -public: SCRIPT_CACHE& GetScriptCache() const { return maScriptCache; } private: @@ -115,9 +104,6 @@ private: std::vector<OpenGLGlyphCacheChunk> maOpenGLGlyphCache; public: - int GetCachedGlyphWidth( int nCharCode ) const; - void CacheGlyphWidth( int nCharCode, int nCharWidth ); - bool InitKashidaHandling( HDC ); int GetMinKashidaWidth() const { return mnMinKashidaWidth; } int GetMinKashidaGlyph() const { return mnMinKashidaGlyph; } @@ -131,7 +117,6 @@ public: const OpenGLGlyphCacheChunk& GetCachedGlyphChunkFor(int nGlyphIndex) const; private: - IntMap maWidthMap; mutable int mnMinKashidaWidth; mutable int mnMinKashidaGlyph; bool mbGLyphySetupCalled; @@ -207,19 +192,6 @@ inline std::basic_ostream<charT, traits> & operator <<( return stream << "}"; } -inline void ImplWinFontEntry::CacheGlyphWidth( int nCharCode, int nCharWidth ) -{ - maWidthMap[ nCharCode ] = nCharWidth; -} - -inline int ImplWinFontEntry::GetCachedGlyphWidth( int nCharCode ) const -{ - IntMap::const_iterator it = maWidthMap.find( nCharCode ); - if( it == maWidthMap.end() ) - return -1; - return it->second; -} - bool ImplWinFontEntry::GlyphIsCached(int nGlyphIndex) const { if (nGlyphIndex == DROPPED_OUTGLYPH) @@ -471,705 +443,6 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou return true; } -SimpleWinLayout::SimpleWinLayout(HDC hDC, BYTE nCharSet, const ImplWinFontData& rWinFontData, - ImplWinFontEntry& rWinFontEntry, bool bUseOpenGL) -: WinLayout(hDC, rWinFontData, rWinFontEntry, bUseOpenGL), - mnGlyphCount( 0 ), - mnCharCount( 0 ), - mpOutGlyphs( NULL ), - mpGlyphAdvances( NULL ), - mpGlyphOrigAdvs( NULL ), - mpCharWidths( NULL ), - mpChars2Glyphs( NULL ), - mpGlyphs2Chars( NULL ), - mpGlyphRTLFlags( NULL ), - mnWidth( 0 ), - mnNotdefWidth( -1 ), - mnCharSet( nCharSet ) -{ -} - -SimpleWinLayout::~SimpleWinLayout() -{ - delete[] mpGlyphRTLFlags; - delete[] mpGlyphs2Chars; - delete[] mpChars2Glyphs; - if( mpCharWidths != mpGlyphAdvances ) - delete[] mpCharWidths; - delete[] mpGlyphOrigAdvs; - delete[] mpGlyphAdvances; - delete[] mpOutGlyphs; -} - -bool SimpleWinLayout::LayoutText( ImplLayoutArgs& rArgs ) -{ - // prepare layout - // TODO: fix case when recyclying old SimpleWinLayout object - mnCharCount = rArgs.mnEndCharPos - rArgs.mnMinCharPos; - - // TODO: use a cached value for bDisableAsianKern from upper layers - if( rArgs.mnFlags & SalLayoutFlags::KerningAsian ) - { - TEXTMETRICA aTextMetricA; - if( GetTextMetricsA( mhDC, &aTextMetricA ) - && !(aTextMetricA.tmPitchAndFamily & TMPF_FIXED_PITCH) && !(aTextMetricA.tmCharSet == 0x86) ) - rArgs.mnFlags &= ~SalLayoutFlags::KerningAsian; - } - - // layout text - int i, j; - - mnGlyphCount = 0; - bool bVertical(rArgs.mnFlags & SalLayoutFlags::Vertical); - - // count the number of chars to process if no RTL run - rArgs.ResetPos(); - bool bHasRTL = false; - while( rArgs.GetNextRun( &i, &j, &bHasRTL ) && !bHasRTL ) - mnGlyphCount += j - i; - - // if there are RTL runs we need room to remember individual BiDi flags - if( bHasRTL ) - { - mpGlyphRTLFlags = new bool[ mnCharCount ]; - for( i = 0; i < mnCharCount; ++i ) - mpGlyphRTLFlags[i] = false; - } - - // rewrite the logical string if needed to prepare for the API calls - const sal_Unicode* pBidiStr = rArgs.mrStr.pData->buffer + rArgs.mnMinCharPos; - if( (mnGlyphCount != mnCharCount) || bVertical ) - { - // we need to rewrite the pBidiStr when any of - // - BiDirectional layout - // - vertical layout - // - partial runs (e.g. with control chars or for glyph fallback) - // are involved - sal_Unicode* pRewrittenStr = (sal_Unicode*)alloca( mnCharCount * sizeof(sal_Unicode) ); - pBidiStr = pRewrittenStr; - - // note: glyph to char mapping is relative to first character - mpChars2Glyphs = new int[ mnCharCount ]; - mpGlyphs2Chars = new int[ mnCharCount ]; - for( i = 0; i < mnCharCount; ++i ) - mpChars2Glyphs[i] = mpGlyphs2Chars[i] = -1; - - mnGlyphCount = 0; - rArgs.ResetPos(); - bool bIsRTL = false; - while( rArgs.GetNextRun( &i, &j, &bIsRTL ) ) - { - do - { - // get the next leftmost character in this run - int nCharPos = bIsRTL ? --j : i++; - sal_UCS4 cChar = rArgs.mrStr[ nCharPos ]; - - // in the RTL case mirror the character and remember its RTL status - if( bIsRTL ) - { - cChar = GetMirroredChar( cChar ); - mpGlyphRTLFlags[ mnGlyphCount ] = true; - } - - // rewrite the original string - // update the mappings between original and rewritten string - // TODO: support surrogates in rewritten strings - pRewrittenStr[ mnGlyphCount ] = static_cast<sal_Unicode>(cChar); - mpGlyphs2Chars[ mnGlyphCount ] = nCharPos; - mpChars2Glyphs[ nCharPos - rArgs.mnMinCharPos ] = mnGlyphCount; - ++mnGlyphCount; - } while( i < j ); - } - } - - mpOutGlyphs = new WCHAR[ mnGlyphCount ]; - mpGlyphAdvances = new int[ mnGlyphCount ]; - - if( rArgs.mnFlags & (SalLayoutFlags::KerningPairs | SalLayoutFlags::KerningAsian) ) - mpGlyphOrigAdvs = new int[ mnGlyphCount ]; - - for( i = 0; i < mnGlyphCount; ++i ) - mpOutGlyphs[i] = pBidiStr[ i ]; - mnWidth = 0; - for( i = 0; i < mnGlyphCount; ++i ) - { - // get the current UCS-4 code point, check for surrogate pairs - const WCHAR* pCodes = reinterpret_cast<LPCWSTR>(&pBidiStr[i]); - unsigned nCharCode = pCodes[0]; - bool bSurrogate = ((nCharCode >= 0xD800) && (nCharCode <= 0xDFFF)); - if( bSurrogate ) - { - // ignore high surrogates, they were already processed with their low surrogates - if( nCharCode >= 0xDC00 ) - continue; - // check the second half of the surrogate pair - bSurrogate &= (0xDC00 <= pCodes[1]) && (pCodes[1] <= 0xDFFF); - // calculate the UTF-32 code of valid surrogate pairs - if( bSurrogate ) - nCharCode = 0x10000 + ((pCodes[0] - 0xD800) << 10) + (pCodes[1] - 0xDC00); - else // or fall back to a replacement character - nCharCode = '?'; - } - - // get the advance width for the current UTF-32 code point - int nGlyphWidth = mrWinFontEntry.GetCachedGlyphWidth( nCharCode ); - if( nGlyphWidth == -1 ) - { - ABC aABC; - SIZE aExtent; - if( GetTextExtentPoint32W( mhDC, &pCodes[0], bSurrogate ? 2 : 1, &aExtent) ) - nGlyphWidth = aExtent.cx; - else if( GetCharABCWidthsW( mhDC, nCharCode, nCharCode, &aABC ) ) - nGlyphWidth = aABC.abcA + aABC.abcB + aABC.abcC; - else if( !GetCharWidth32W( mhDC, nCharCode, nCharCode, &nGlyphWidth ) - && !GetCharWidthW( mhDC, nCharCode, nCharCode, &nGlyphWidth ) ) - nGlyphWidth = 0; - mrWinFontEntry.CacheGlyphWidth( nCharCode, nGlyphWidth ); - } - mpGlyphAdvances[ i ] = nGlyphWidth; - mnWidth += nGlyphWidth; - - // the second half of surrogate pair gets a zero width - if( bSurrogate && ((i+1) < mnGlyphCount) ) - mpGlyphAdvances[ i+1 ] = 0; - - // check with the font face if glyph fallback is needed - if( mrWinFontData.HasChar( nCharCode ) ) - continue; - - // request glyph fallback at this position in the string - bool bRTL = mpGlyphRTLFlags ? mpGlyphRTLFlags[i] : false; - int nCharPos = mpGlyphs2Chars ? mpGlyphs2Chars[i]: i + rArgs.mnMinCharPos; - rArgs.NeedFallback( nCharPos, bRTL ); - if( bSurrogate && ((nCharPos+1) < rArgs.mrStr.getLength()) ) - rArgs.NeedFallback( nCharPos+1, bRTL ); - - // replace the current glyph shape with the NotDef glyph shape - if( rArgs.mnFlags & SalLayoutFlags::ForFallback ) - { - // when we already are layouting for glyph fallback - // then a new unresolved glyph is not interesting - mnNotdefWidth = 0; - mpOutGlyphs[i] = DROPPED_OUTGLYPH; - } - else - { - if( mnNotdefWidth < 0 ) - { - // get the width of the NotDef glyph - SIZE aExtent; - WCHAR cNotDef = rArgs.mrStr[ nCharPos ]; - mnNotdefWidth = 0; - if( GetTextExtentPoint32W( mhDC, &cNotDef, 1, &aExtent) ) - mnNotdefWidth = aExtent.cx; - } - } - if( bSurrogate && ((i+1) < mnGlyphCount) ) - mpOutGlyphs[i+1] = DROPPED_OUTGLYPH; - - // adjust the current glyph width to the NotDef glyph width - mnWidth += mnNotdefWidth - mpGlyphAdvances[i]; - mpGlyphAdvances[i] = mnNotdefWidth; - if( mpGlyphOrigAdvs ) - mpGlyphOrigAdvs[i] = mnNotdefWidth; - } - - // apply kerning if the layout engine has not yet done it - if( rArgs.mnFlags & (SalLayoutFlags::KerningAsian|SalLayoutFlags::KerningPairs) ) - { - for( i = 0; i < mnGlyphCount; ++i ) - mpGlyphOrigAdvs[i] = mpGlyphAdvances[i]; - - // #99658# also apply asian kerning on the substring border - int nLen = mnGlyphCount; - if( rArgs.mnMinCharPos + nLen < rArgs.mrStr.getLength() ) - ++nLen; - for( i = 1; i < nLen; ++i ) - { - if( rArgs.mnFlags & SalLayoutFlags::KerningPairs ) - { - int nKernAmount = mrWinFontEntry.GetKerning( pBidiStr[i-1], pBidiStr[i] ); - mpGlyphAdvances[ i-1 ] += nKernAmount; - mnWidth += nKernAmount; - } - else if( rArgs.mnFlags & SalLayoutFlags::KerningAsian ) - - if( ( (0x3000 == (0xFF00 & pBidiStr[i-1])) || (0x2010 == (0xFFF0 & pBidiStr[i-1])) || (0xFF00 == (0xFF00 & pBidiStr[i-1]))) - && ( (0x3000 == (0xFF00 & pBidiStr[i])) || (0x2010 == (0xFFF0 & pBidiStr[i])) || (0xFF00 == (0xFF00 & pBidiStr[i])) ) ) - { - long nKernFirst = +CalcAsianKerning( pBidiStr[i-1], true, bVertical ); - long nKernNext = -CalcAsianKerning( pBidiStr[i], false, bVertical ); - - long nDelta = (nKernFirst < nKernNext) ? nKernFirst : nKernNext; - if( nDelta<0 && nKernFirst!=0 && nKernNext!=0 ) - { - nDelta = (nDelta * mpGlyphAdvances[i-1] + 2) / 4; - mpGlyphAdvances[i-1] += nDelta; - mnWidth += nDelta; - } - } - } - } - - // calculate virtual char widths - if( !mpGlyphs2Chars ) - mpCharWidths = mpGlyphAdvances; - else - { - mpCharWidths = new int[ mnCharCount ]; - for( i = 0; i < mnCharCount; ++i ) - mpCharWidths[ i ] = 0; - for( i = 0; i < mnGlyphCount; ++i ) - { - int k = mpGlyphs2Chars[ i ] - rArgs.mnMinCharPos; - if( k >= 0 ) - mpCharWidths[ k ] += mpGlyphAdvances[ i ]; - } - } - - // scale layout metrics if needed - // TODO: does it make the code more simple if the metric scaling - // is moved to the methods that need metric scaling (e.g. FillDXArray())? - if( mfFontScale != 1.0 ) - { - mnWidth = (long)(mnWidth * mfFontScale); - mnBaseAdv = (int)(mnBaseAdv * mfFontScale); - for( i = 0; i < mnCharCount; ++i ) - mpCharWidths[i] = (int)(mpCharWidths[i] * mfFontScale); - if( mpGlyphAdvances != mpCharWidths ) - for( i = 0; i < mnGlyphCount; ++i ) - mpGlyphAdvances[i] = (int)(mpGlyphAdvances[i] * mfFontScale); - if( mpGlyphOrigAdvs && (mpGlyphOrigAdvs != mpGlyphAdvances) ) - for( i = 0; i < mnGlyphCount; ++i ) - mpGlyphOrigAdvs[i] = (int)(mpGlyphOrigAdvs[i] * mfFontScale); - } - - return true; -} - -int SimpleWinLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIds, Point& rPos, int& nStart, - DeviceCoordinate* pGlyphAdvances, int* pCharIndexes, - const PhysicalFontFace** /*pFallbackFonts*/ ) const -{ - // return zero if no more glyph found - if( nStart >= mnGlyphCount ) - return 0; - - // calculate glyph position relative to layout base - // TODO: avoid for nStart!=0 case by reusing rPos - long nXOffset = mnBaseAdv; - for( int i = 0; i < nStart; ++i ) - nXOffset += mpGlyphAdvances[ i ]; - - // calculate absolute position in pixel units - Point aRelativePos( nXOffset, 0 ); - rPos = GetDrawPosition( aRelativePos ); - - int nCount = 0; - while( nCount < nLen ) - { - // update return values {aGlyphId,nCharPos,nGlyphAdvance} - sal_GlyphId aGlyphId = mpOutGlyphs[ nStart ]; - if( mnLayoutFlags & SalLayoutFlags::Vertical ) - { - const sal_UCS4 cChar = static_cast<sal_UCS4>(aGlyphId & GF_IDXMASK); - if( mrWinFontData.HasGSUBstitutions( mhDC ) - && mrWinFontData.IsGSUBstituted( cChar ) ) - aGlyphId |= GF_GSUB | GF_ROTL; - else - { - aGlyphId |= GetVerticalFlags( cChar ); - if( (aGlyphId & GF_ROTMASK) == 0 ) - aGlyphId |= GF_VERT; - } - } - aGlyphId |= GF_ISCHAR; - - ++nCount; - *(pGlyphIds++) = aGlyphId; - if( pGlyphAdvances ) - *(pGlyphAdvances++) = mpGlyphAdvances[ nStart ]; - if( pCharIndexes ) - { - int nCharPos; - if( !mpGlyphs2Chars ) - nCharPos = nStart + mnMinCharPos; - else - nCharPos = mpGlyphs2Chars[nStart]; - *(pCharIndexes++) = nCharPos; - } - - // stop at last glyph - if( ++nStart >= mnGlyphCount ) - break; - - // stop when next x-position is unexpected - if( !pGlyphAdvances && mpGlyphOrigAdvs ) - if( mpGlyphAdvances[nStart-1] != mpGlyphOrigAdvs[nStart-1] ) - break; - } - - return nCount; -} - -bool SimpleWinLayout::DrawTextImpl(HDC hDC, - const Rectangle* pRectToErase, - Point* /* pPos */, - int* /* pGetNextGlypInfo */) const -{ - if (pRectToErase) - { - RECT aRect = { pRectToErase->Left(), pRectToErase->Top(), pRectToErase->Left()+pRectToErase->GetWidth(), pRectToErase->Top()+pRectToErase->GetHeight() }; - FillRect(hDC, &aRect, static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH))); - } - - if( mnGlyphCount <= 0 ) - return false; - - HFONT hOrigFont = DisableFontScaling(); - Point aPos = GetDrawPosition( Point( mnBaseAdv, 0 ) ); - - // #108267#, break up into glyph portions of a limited size required by Win32 API - const unsigned int maxGlyphCount = 8192; - UINT numGlyphPortions = mnGlyphCount / maxGlyphCount; - UINT remainingGlyphs = mnGlyphCount % maxGlyphCount; - - if( numGlyphPortions ) - { - // #108267#,#109387# break up string into smaller chunks - // the output positions will be updated by windows (SetTextAlign) - POINT oldPos; - UINT oldTa = GetTextAlign(hDC); - SetTextAlign(hDC, (oldTa & ~TA_NOUPDATECP) | TA_UPDATECP); - MoveToEx(hDC, aPos.X(), aPos.Y(), &oldPos); - unsigned int i = 0; - for( unsigned int n = 0; n < numGlyphPortions; ++n, i+=maxGlyphCount ) - { - ExtTextOutW(hDC, 0, 0, 0, NULL, mpOutGlyphs+i, maxGlyphCount, mpGlyphAdvances+i); - } - ExtTextOutW(hDC, 0, 0, 0, NULL, mpOutGlyphs+i, remainingGlyphs, mpGlyphAdvances+i); - MoveToEx(hDC, oldPos.x, oldPos.y, (LPPOINT) NULL); - SetTextAlign(hDC, oldTa); - } - else - ExtTextOutW(hDC, aPos.X(), aPos.Y(), 0, NULL, mpOutGlyphs, mnGlyphCount, mpGlyphAdvances); - - if( hOrigFont ) - DeleteFont(SelectFont(hDC, hOrigFont)); - - return false; -} - -DeviceCoordinate SimpleWinLayout::FillDXArray( DeviceCoordinate* pDXArray ) const -{ - if( !mnWidth ) - { - mnWidth = mnBaseAdv; - for( int i = 0; i < mnGlyphCount; ++i ) - mnWidth += mpGlyphAdvances[ i ]; - } - - if( pDXArray != NULL ) - { - for( int i = 0; i < mnCharCount; ++i ) - pDXArray[ i ] = mpCharWidths[ i ]; - } - - return mnWidth; -} - -sal_Int32 SimpleWinLayout::GetTextBreak( DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor ) const -// NOTE: the nFactor is used to prevent rounding errors for small nCharExtra values -{ - if( mnWidth ) - if( (mnWidth * nFactor + mnCharCount * nCharExtra) <= nMaxWidth ) - return -1; - - long nExtraWidth = mnBaseAdv * nFactor; - for( int n = 0; n < mnCharCount; ++n ) - { - // skip unused characters - if( mpChars2Glyphs && (mpChars2Glyphs[n] < 0) ) - continue; - // add char widths until max - nExtraWidth += mpCharWidths[ n ] * nFactor; - if( nExtraWidth > nMaxWidth ) - return (mnMinCharPos + n); - nExtraWidth += nCharExtra; - } - - return -1; -} - -void SimpleWinLayout::GetCaretPositions( int nMaxIdx, long* pCaretXArray ) const -{ - long nXPos = mnBaseAdv; - - if( !mpGlyphs2Chars ) - { - for( int i = 0; i < nMaxIdx; i += 2 ) - { - pCaretXArray[ i ] = nXPos; - nXPos += mpGlyphAdvances[ i>>1 ]; - pCaretXArray[ i+1 ] = nXPos; - } - } - else - { - int i; - for( i = 0; i < nMaxIdx; ++i ) - pCaretXArray[ i ] = -1; - - // assign glyph positions to character positions - for( i = 0; i < mnGlyphCount; ++i ) - { - int nCurrIdx = mpGlyphs2Chars[ i ] - mnMinCharPos; - long nXRight = nXPos + mpCharWidths[ nCurrIdx ]; - nCurrIdx *= 2; - if( !(mpGlyphRTLFlags && mpGlyphRTLFlags[i]) ) - { - // normal positions for LTR case - pCaretXArray[ nCurrIdx ] = nXPos; - pCaretXArray[ nCurrIdx+1 ] = nXRight; - } - else - { - // reverse positions for RTL case - pCaretXArray[ nCurrIdx ] = nXRight; - pCaretXArray[ nCurrIdx+1 ] = nXPos; - } - nXPos += mpGlyphAdvances[ i ]; - } - } -} - -void SimpleWinLayout::Justify( DeviceCoordinate nNewWidth ) -{ - DeviceCoordinate nOldWidth = mnWidth; - mnWidth = nNewWidth; - - if( mnGlyphCount <= 0 ) - return; - - if( nNewWidth == nOldWidth ) - return; - - // the rightmost glyph cannot be stretched - const int nRight = mnGlyphCount - 1; - nOldWidth -= mpGlyphAdvances[ nRight ]; - nNewWidth -= mpGlyphAdvances[ nRight ]; - - // count stretchable glyphs - int nStretchable = 0, i; - for( i = 0; i < nRight; ++i ) - if( mpGlyphAdvances[i] >= 0 ) - ++nStretchable; - - // stretch these glyphs - DeviceCoordinate nDiffWidth = nNewWidth - nOldWidth; - for( i = 0; (i < nRight) && (nStretchable > 0); ++i ) - { - if( mpGlyphAdvances[i] <= 0 ) - continue; - DeviceCoordinate nDeltaWidth = nDiffWidth / nStretchable; - mpGlyphAdvances[i] += nDeltaWidth; - --nStretchable; - nDiffWidth -= nDeltaWidth; - } -} - -void SimpleWinLayout::AdjustLayout( ImplLayoutArgs& rArgs ) -{ - SalLayout::AdjustLayout( rArgs ); - - // adjust positions if requested - if( rArgs.mpDXArray ) - ApplyDXArray( rArgs ); - else if( rArgs.mnLayoutWidth ) - Justify( rArgs.mnLayoutWidth ); - else - return; - - // recalculate virtual char widths if they were changed - if( mpCharWidths != mpGlyphAdvances ) - { - int i; - if( !mpGlyphs2Chars ) - { - // standard LTR case - for( i = 0; i < mnGlyphCount; ++i ) - mpCharWidths[ i ] = mpGlyphAdvances[ i ]; - } - else - { - // BiDi or complex case - for( i = 0; i < mnCharCount; ++i ) - mpCharWidths[ i ] = 0; - for( i = 0; i < mnGlyphCount; ++i ) - { - int j = mpGlyphs2Chars[ i ] - rArgs.mnMinCharPos; - if( j >= 0 ) - mpCharWidths[ j ] += mpGlyphAdvances[ i ]; - } - } - } -} - -void SimpleWinLayout::ApplyDXArray( const ImplLayoutArgs& rArgs ) -{ - // try to avoid disturbance of text flow for LSB rounding case; - const long* pDXArray = rArgs.mpDXArray; - - int i = 0; - long nOldWidth = mnBaseAdv; - for(; i < mnCharCount; ++i ) - { - int j = !mpChars2Glyphs ? i : mpChars2Glyphs[i]; - if( j >= 0 ) - { - nOldWidth += mpGlyphAdvances[ j ]; - long nDiff = nOldWidth - pDXArray[ i ]; - - // disabled because of #104768# - // works great for static text, but problems when typing - // if( nDiff>+1 || nDiff<-1 ) - // only bother with changing anything when something moved - if( nDiff != 0 ) - break; - } - } - if( i >= mnCharCount ) - return; - - if( !mpGlyphOrigAdvs ) - { - mpGlyphOrigAdvs = new int[ mnGlyphCount ]; - for( i = 0; i < mnGlyphCount; ++i ) - mpGlyphOrigAdvs[ i ] = mpGlyphAdvances[ i ]; - } - - mnWidth = mnBaseAdv; - for( i = 0; i < mnCharCount; ++i ) - { - int j = !mpChars2Glyphs ? i : mpChars2Glyphs[i]; - if( j >= 0 ) - mpGlyphAdvances[j] = pDXArray[i] - mnWidth; - mnWidth = pDXArray[i]; - } -} - -void SimpleWinLayout::MoveGlyph( int nStart, long nNewXPos ) -{ - if( nStart > mnGlyphCount ) - return; - - // calculate the current x-position of the requested glyph - // TODO: cache absolute positions - int nXPos = mnBaseAdv; - for( int i = 0; i < nStart; ++i ) - nXPos += mpGlyphAdvances[i]; - - // calculate the difference to the current glyph position - int nDelta = nNewXPos - nXPos; - - // adjust the width of the layout if it was already cached - if( mnWidth ) - mnWidth += nDelta; - - // depending on whether the requested glyph is leftmost in the layout - // adjust either the layout's or the requested glyph's relative position - if( nStart > 0 ) - mpGlyphAdvances[ nStart-1 ] += nDelta; - else - mnBaseAdv += nDelta; -} - -void SimpleWinLayout::DropGlyph( int nStart ) -{ - mpOutGlyphs[ nStart ] = DROPPED_OUTGLYPH; -} - -void SimpleWinLayout::Simplify( bool /*bIsBase*/ ) -{ - // return early if no glyph has been dropped - int i = mnGlyphCount; - while( (--i >= 0) && (mpOutGlyphs[ i ] != DROPPED_OUTGLYPH) ); - if( i < 0 ) - return; - - // convert the layout to a sparse layout if it is not already - if( !mpGlyphs2Chars ) - { - mpGlyphs2Chars = new int[ mnGlyphCount ]; - mpCharWidths = new int[ mnCharCount ]; - // assertion: mnGlyphCount == mnCharCount - for( int k = 0; k < mnGlyphCount; ++k ) - { - mpGlyphs2Chars[ k ] = mnMinCharPos + k; - mpCharWidths[ k ] = mpGlyphAdvances[ k ]; - } - } - - // remove dropped glyphs that are rightmost in the layout - for( i = mnGlyphCount; --i >= 0; ) - { - if( mpOutGlyphs[ i ] != DROPPED_OUTGLYPH ) - break; - if( mnWidth ) - mnWidth -= mpGlyphAdvances[ i ]; - int nRelCharPos = mpGlyphs2Chars[ i ] - mnMinCharPos; - if( nRelCharPos >= 0 ) - mpCharWidths[ nRelCharPos ] = 0; - } - mnGlyphCount = i + 1; - - // keep original glyph widths around - if( !mpGlyphOrigAdvs ) - { - mpGlyphOrigAdvs = new int[ mnGlyphCount ]; - for( int k = 0; k < mnGlyphCount; ++k ) - mpGlyphOrigAdvs[ k ] = mpGlyphAdvances[ k ]; - } - - // remove dropped glyphs inside the layout - int nNewGC = 0; - for( i = 0; i < mnGlyphCount; ++i ) - { - if( mpOutGlyphs[ i ] == DROPPED_OUTGLYPH ) - { - // adjust relative position to last valid glyph - int nDroppedWidth = mpGlyphAdvances[ i ]; - mpGlyphAdvances[ i ] = 0; - if( nNewGC > 0 ) - mpGlyphAdvances[ nNewGC-1 ] += nDroppedWidth; - else - mnBaseAdv += nDroppedWidth; - - // zero the virtual char width for the char that has a fallback - int nRelCharPos = mpGlyphs2Chars[ i ] - mnMinCharPos; - if( nRelCharPos >= 0 ) - mpCharWidths[ nRelCharPos ] = 0; - } - else - { - if( nNewGC != i ) - { - // rearrange the glyph array to get rid of the dropped glyph - mpOutGlyphs[ nNewGC ] = mpOutGlyphs[ i ]; - mpGlyphAdvances[ nNewGC ] = mpGlyphAdvances[ i ]; - mpGlyphOrigAdvs[ nNewGC ] = mpGlyphOrigAdvs[ i ]; - mpGlyphs2Chars[ nNewGC ] = mpGlyphs2Chars[ i ]; - } - ++nNewGC; - } - } - - mnGlyphCount = nNewGC; - if( mnGlyphCount <= 0 ) - mnWidth = mnBaseAdv = 0; -} - const OpenGLGlyphCacheChunk& ImplWinFontEntry::GetCachedGlyphChunkFor(int nGlyphIndex) const { auto i = maOpenGLGlyphCache.cbegin(); @@ -1383,16 +656,6 @@ void WinLayout::DrawText(SalGraphics& rGraphics) const } } -bool SimpleWinLayout::CacheGlyphs(SalGraphics& /*rGraphics*/) const -{ - return false; -} - -bool SimpleWinLayout::DrawCachedGlyphs(SalGraphics& /*rGraphics*/) const -{ - return false; -} - struct VisualItem { public: @@ -3606,7 +2869,7 @@ void GraphiteWinLayout::Simplify( bool is_base ) } #endif // ENABLE_GRAPHITE -SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel ) +SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& /*rArgs*/, int nFallbackLevel ) { if (!mpWinFontEntry[nFallbackLevel]) return nullptr; @@ -3621,56 +2884,18 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe if (!bUspInited) InitUSP(); - - if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) ) - { #if ENABLE_GRAPHITE - if (rFontFace.SupportsGraphite()) - { - pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - } - else -#endif // ENABLE_GRAPHITE - { - // script complexity is determined in upper layers - pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - // NOTE: it must be guaranteed that the WinSalGraphics lives longer than - // the created UniscribeLayout, otherwise the data passed into the - // constructor might become invalid too early - } + if (rFontFace.SupportsGraphite()) + { + pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); } else - { -#if ENABLE_GRAPHITE - if (rFontFace.SupportsGraphite()) - { - pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - } - else #endif // ENABLE_GRAPHITE - { - static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL); - - if (!bAvoidSimpleWinLayout) - { - if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() ) - { - // TODO: directly cache kerning info in the rFontInstance - // TODO: get rid of kerning methods+data in WinSalGraphics object - GetKernPairs(); - rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs ); - } - - pWinLayout = new SimpleWinLayout(getHDC(), ANSI_CHARSET, rFontFace, rFontInstance, bUseOpenGL); - } - else - { - pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - // NOTE: it must be guaranteed that the WinSalGraphics lives longer than - // the created UniscribeLayout, otherwise the data passed into the - // constructor might become invalid too early - } - } + { + pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); + // NOTE: it must be guaranteed that the WinSalGraphics lives longer than + // the created UniscribeLayout, otherwise the data passed into the + // constructor might become invalid too early } if( mfFontScale[nFallbackLevel] != 1.0 ) @@ -3692,9 +2917,6 @@ ImplWinFontEntry::ImplWinFontEntry( FontSelectPattern& rFSD ) : ImplFontEntry( rFSD ) , mpGLyphyAtlas( nullptr ) , mpGLyphyFont( nullptr ) -, mpKerningPairs( NULL ) -, mnKerningPairs( -1 ) -, maWidthMap( 512 ) , mnMinKashidaWidth( -1 ) , mnMinKashidaGlyph( -1 ) { @@ -3707,38 +2929,6 @@ ImplWinFontEntry::~ImplWinFontEntry() { if( maScriptCache != NULL ) ScriptFreeCache( &maScriptCache ); - delete[] mpKerningPairs; -} - -bool ImplWinFontEntry::HasKernData() const -{ - return (mnKerningPairs >= 0); -} - -void ImplWinFontEntry::SetKernData( int nPairCount, const KERNINGPAIR* pPairData ) -{ - mnKerningPairs = nPairCount; - mpKerningPairs = new KERNINGPAIR[ mnKerningPairs ]; - memcpy( mpKerningPairs, (const void*)pPairData, nPairCount*sizeof(KERNINGPAIR) ); -} - -int ImplWinFontEntry::GetKerning( sal_Unicode cLeft, sal_Unicode cRight ) const -{ - int nKernAmount = 0; - if( mpKerningPairs ) - { - const KERNINGPAIR aRefPair = { cLeft, cRight, 0 }; - const KERNINGPAIR* pFirstPair = mpKerningPairs; - const KERNINGPAIR* pEndPair = mpKerningPairs + mnKerningPairs; - const KERNINGPAIR* pPair = std::lower_bound( pFirstPair, - pEndPair, aRefPair, ImplCmpKernData ); - if( (pPair != pEndPair) - && (pPair->wFirst == aRefPair.wFirst) - && (pPair->wSecond == aRefPair.wSecond) ) - nKernAmount = pPair->iKernAmount; - } - - return nKernAmount; } bool ImplWinFontEntry::InitKashidaHandling( HDC hDC ) diff --git a/vcl/win/source/gdi/winlayout.hxx b/vcl/win/source/gdi/winlayout.hxx index 1d2a776..ff4e5cc 100644 --- a/vcl/win/source/gdi/winlayout.hxx +++ b/vcl/win/source/gdi/winlayout.hxx @@ -68,51 +68,6 @@ public: ImplWinFontEntry& mrWinFontEntry; }; -class SimpleWinLayout : public WinLayout -{ -public: - SimpleWinLayout(HDC, BYTE nCharSet, const ImplWinFontData&, ImplWinFontEntry&, bool bUseOpenGL); - virtual ~SimpleWinLayout(); - - virtual bool LayoutText( ImplLayoutArgs& ) override; - virtual void AdjustLayout( ImplLayoutArgs& ) override; - virtual bool DrawTextImpl(HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) const override; - - virtual bool CacheGlyphs(SalGraphics& rGraphics) const override; - virtual bool DrawCachedGlyphs(SalGraphics& rGraphics) const override; - virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int&, - DeviceCoordinate* pGlyphAdvances, int* pCharIndexes, - const PhysicalFontFace** pFallbackFonts = NULL ) const override; - - virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const override; - virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const override; - virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const override; - - // for glyph+font+script fallback - virtual void MoveGlyph( int nStart, long nNewXPos ) override; - virtual void DropGlyph( int nStart ) override; - virtual void Simplify( bool bIsBase ) override; - -protected: - void Justify( DeviceCoordinate nNewWidth ); - void ApplyDXArray( const ImplLayoutArgs& ); - -private: - int mnGlyphCount; - int mnCharCount; - WCHAR* mpOutGlyphs; - int* mpGlyphAdvances; // if possible this is shared with mpGlyphAdvances[] - int* mpGlyphOrigAdvs; - int* mpCharWidths; // map rel char pos to char width - int* mpChars2Glyphs; // map rel char pos to abs glyph pos - int* mpGlyphs2Chars; // map abs glyph pos to abs char pos - bool* mpGlyphRTLFlags; // BiDi status for glyphs: true=>RTL - mutable long mnWidth; - - int mnNotdefWidth; - BYTE mnCharSet; -}; - class UniscribeLayout : public WinLayout { public: _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
