vcl/inc/win/salgdi.h | 4 +++- vcl/win/gdi/salfont.cxx | 48 ++++++++++++++++++++++++++++++++++++++---------- vcl/win/gdi/salgdi.cxx | 2 ++ 3 files changed, 43 insertions(+), 11 deletions(-)
New commits: commit 335036f0d05bdfde49cacf245863c686d07a2d5f Author: Khaled Hosny <khaledho...@eglug.org> Date: Mon Apr 16 22:30:50 2018 +0200 tdf#116812: Revert "The mfFontScale[n] is always 1.0" This reverts commit 1b7e788eb3bf9cbe56ed5cc4a3fa7fa5e70ac40a and followup commit 843c6d6eec95b99e867c28ab27860215d5d72b37. Change-Id: I42d1ab76778466db356f0597c90e1afc2dc9997d Reviewed-on: https://gerrit.libreoffice.org/53013 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Khaled Hosny <khaledho...@eglug.org> diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index b1edef997d85..23531842dde3 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -166,6 +166,8 @@ private: HFONT mhFonts[ MAX_FALLBACK ]; // Font + Fallbacks const WinFontFace* mpWinFontData[ MAX_FALLBACK ]; // pointer to the most recent font face WinFontInstance* mpWinFontEntry[ MAX_FALLBACK ]; // pointer to the most recent font instance + float mfFontScale[ MAX_FALLBACK ]; // allows metrics emulation of huge font sizes + float mfCurrentFontScale; HRGN mhRegion; // vcl::Region Handle HPEN mhDefPen; // DefaultPen HBRUSH mhDefBrush; // DefaultBrush @@ -205,7 +207,7 @@ public: HWND gethWnd(); - HFONT ImplDoSetFont( FontSelectPattern const * i_pFont, HFONT& o_rOldFont ); + HFONT ImplDoSetFont( FontSelectPattern const * i_pFont, float& o_rFontScale, HFONT& o_rOldFont ); public: explicit WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd, diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 7c6bb027f245..f9b9418ccb75 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -62,6 +62,8 @@ using namespace vcl; // The cache limit is set by the rough number of characters needed to read your average Asian newspaper. static o3tl::lru_map<sal_GlyphId, tools::Rectangle> g_BoundRectCache(3000); +static const int MAXFONTHEIGHT = 2048; + inline FIXED FixedFromDouble( double d ) { const long l = static_cast<long>( d * 65536. ); @@ -838,11 +840,10 @@ void ImplGetLogFontFromFontSelect( HDC hDC, } } -HFONT WinSalGraphics::ImplDoSetFont(FontSelectPattern const * i_pFont, HFONT& o_rOldFont) +HFONT WinSalGraphics::ImplDoSetFont(FontSelectPattern const * i_pFont, float& o_rFontScale, HFONT& o_rOldFont) { // clear the cache on font change g_BoundRectCache.clear(); - HFONT hNewFont = nullptr; HDC hdcScreen = nullptr; @@ -853,6 +854,26 @@ HFONT WinSalGraphics::ImplDoSetFont(FontSelectPattern const * i_pFont, HFONT& o_ LOGFONTW aLogFont; ImplGetLogFontFromFontSelect( getHDC(), i_pFont, aLogFont, true ); + // #i47675# limit font requests to MAXFONTHEIGHT + // TODO: share MAXFONTHEIGHT font instance + if( (-aLogFont.lfHeight <= MAXFONTHEIGHT) + && (+aLogFont.lfWidth <= MAXFONTHEIGHT) ) + { + o_rFontScale = 1.0; + } + else if( -aLogFont.lfHeight >= +aLogFont.lfWidth ) + { + o_rFontScale = -aLogFont.lfHeight / (float)MAXFONTHEIGHT; + aLogFont.lfHeight = -MAXFONTHEIGHT; + aLogFont.lfWidth = FRound( aLogFont.lfWidth / o_rFontScale ); + } + else // #i95867# also limit font widths + { + o_rFontScale = +aLogFont.lfWidth / (float)MAXFONTHEIGHT; + aLogFont.lfWidth = +MAXFONTHEIGHT; + aLogFont.lfHeight = FRound( aLogFont.lfHeight / o_rFontScale ); + } + hNewFont = ::CreateFontIndirectW( &aLogFont ); if( hdcScreen ) { @@ -890,6 +911,7 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel // deselect still active font if( mhDefFont ) ::SelectFont( getHDC(), mhDefFont ); + mfCurrentFontScale = mfFontScale[nFallbackLevel]; // release no longer referenced font handles for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) { @@ -922,7 +944,8 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel mpWinFontData[ nFallbackLevel ] = static_cast<const WinFontFace*>( pFont->mpFontData ); HFONT hOldFont = nullptr; - HFONT hNewFont = ImplDoSetFont(pFont, hOldFont); + HFONT hNewFont = ImplDoSetFont(pFont, mfFontScale[ nFallbackLevel ], hOldFont); + mfCurrentFontScale = mfFontScale[nFallbackLevel]; if( !mhDefFont ) { @@ -971,7 +994,7 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFa { int nKashidaWidth = 0; if (GetCharWidthI(getHDC(), nKashidaGid, 1, nullptr, &nKashidaWidth)) - rxFontMetric->SetMinKashida(nKashidaWidth); + rxFontMetric->SetMinKashida(static_cast<int>(mfFontScale[nFallbackLevel] * nKashidaWidth)); } // get the font metric @@ -993,7 +1016,7 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFa rxFontMetric->SetSlant( 0 ); // transformation dependent font metrics - rxFontMetric->SetWidth(aWinMetric.tmAveCharWidth); + rxFontMetric->SetWidth(static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmAveCharWidth )); const std::vector<uint8_t> rHhea(aHheaRawData.get(), aHheaRawData.get() + aHheaRawData.size()); const std::vector<uint8_t> rOS2(aOS2RawData.get(), aOS2RawData.get() + aOS2RawData.size()); @@ -1360,10 +1383,13 @@ bool WinSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle rRect = tools::Rectangle( Point( +aGM.gmptGlyphOrigin.x, -aGM.gmptGlyphOrigin.y ), Size( aGM.gmBlackBoxX, aGM.gmBlackBoxY ) ); - rRect.AdjustRight(1); - rRect.AdjustBottom(1); + rRect.SetLeft(static_cast<int>( mfCurrentFontScale * rRect.Left() )); + rRect.SetRight(static_cast<int>( mfCurrentFontScale * rRect.Right() ) + 1); + rRect.SetTop(static_cast<int>( mfCurrentFontScale * rRect.Top() )); + rRect.SetBottom(static_cast<int>( mfCurrentFontScale * rRect.Bottom() ) + 1); g_BoundRectCache.insert({rGlyph.maGlyphId, rRect}); + return true; } @@ -1540,7 +1566,7 @@ bool WinSalGraphics::GetGlyphOutline(const GlyphItem& rGlyph, // rescaling needed for the tools::PolyPolygon conversion if( rB2DPolyPoly.count() ) { - const double fFactor(1.0/256); + const double fFactor(mfCurrentFontScale/256); rB2DPolyPoly.transform(basegfx::utils::createScaleB2DHomMatrix(fFactor, fFactor)); } @@ -1618,8 +1644,9 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile, // TODO: much better solution: move SetFont and restoration of old font to caller ScopedFont aOldFont(*this); + float fScale = 1.0; HFONT hOldFont = nullptr; - ImplDoSetFont(&aIFSD, hOldFont); + ImplDoSetFont(&aIFSD, fScale, hOldFont); WinFontFace const * pWinFontData = static_cast<WinFontFace const *>(aIFSD.mpFontData); @@ -1766,8 +1793,9 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, // TODO: much better solution: move SetFont and restoration of old font to caller ScopedFont aOldFont(*this); + float fScale = 0.0; HFONT hOldFont = nullptr; - ImplDoSetFont(&aIFSD, hOldFont); + ImplDoSetFont(&aIFSD, fScale, hOldFont); // get raw font file data const RawFontData xRawFontData( getHDC() ); diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx index 7933226e362c..8aa601a461b2 100644 --- a/vcl/win/gdi/salgdi.cxx +++ b/vcl/win/gdi/salgdi.cxx @@ -607,6 +607,7 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hW mbWindow(eType == WinSalGraphics::WINDOW), mbScreen(bScreen), mhWnd(hWnd), + mfCurrentFontScale(1.0), mhRegion(nullptr), mhDefPen(nullptr), mhDefBrush(nullptr), @@ -625,6 +626,7 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hW mhFonts[ i ] = nullptr; mpWinFontData[ i ] = nullptr; mpWinFontEntry[ i ] = nullptr; + mfFontScale[ i ] = 1.0; } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits