diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2018-09-06 13:46:28 +0200 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2018-09-21 15:47:04 +0200 |
commit | 974ad88c876cfabe0fb334b29cc04bb8a06fd5e9 (patch) | |
tree | efe02fa35ebb4f21de9665e6bb4ec95f32288f3c | |
parent | 4a242e736be63f4ca40963f6690d9f0619bad29a (diff) |
tdf#119302 WIN better font scale handling
Moves the scale factor into the LogicalFontInstance and uses the
Glyphs font fallback level to use the correct font and scale.
Probably the glyphs should be using a rtl::Reference to the
LogcalFontInstance instead of the fallback level. I don't know if
glyphs are evicted from the cache, if the fallback changes. There
is now an assert and all places will use 1.0 as the default
scaling factor, so LO should at least not crash.
Reviewed-on: https://gerrit.libreoffice.org/60091
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
(cherry picked from commit c177c305fc839e7a64d228ec56209d133588572b)
Conflicts:
vcl/inc/win/salgdi.h
vcl/win/gdi/salfont.cxx
Change-Id: I9dd4fc3a5b5924fc379b48a7f71c9eed26b4779d
Reviewed-on: https://gerrit.libreoffice.org/60722
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
Tested-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rw-r--r-- | vcl/inc/win/salgdi.h | 1 | ||||
-rw-r--r-- | vcl/inc/win/winlayout.hxx | 3 | ||||
-rw-r--r-- | vcl/win/gdi/salfont.cxx | 66 | ||||
-rw-r--r-- | vcl/win/gdi/salgdi.cxx | 1 |
4 files changed, 46 insertions, 25 deletions
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index fe4f4b8dc8eb..d43a1b28bef7 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -172,7 +172,6 @@ private: HFONT mhFonts[ MAX_FALLBACK ]; // Font + Fallbacks 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 diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx index 2e22834c891e..0c447153c800 100644 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -156,6 +156,8 @@ public: void SetHFONT(const HFONT); HFONT GetHFONT() const { return m_hFont; } + void SetScale(float fScale) { m_fScale = fScale; } + float GetScale() const { return m_fScale; } // Prevend deletion of the HFONT in the WinFontInstance destructor // Used for the ScopedFont handling @@ -167,6 +169,7 @@ private: virtual hb_font_t* ImplInitHbFont() override; HFONT m_hFont; + float m_fScale; GlyphCache maGlyphCache; }; diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 81c8d3a92628..8056b46522a6 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -925,7 +925,6 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel ::SelectFont(getHDC(), mhDefFont); mhDefFont = nullptr; } - mfCurrentFontScale = mfFontScale[nFallbackLevel]; // release no longer referenced font handles for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) { @@ -939,6 +938,7 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel GetWinFontEntry(i)->Release(); mpWinFontEntry[i] = nullptr; } + mfFontScale[i] = 1.0; } return; } @@ -953,52 +953,61 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel { pFont->mpFontInstance->Acquire(); } - mpWinFontEntry[ nFallbackLevel ] = reinterpret_cast<WinFontInstance*>( pFont->mpFontInstance ); + + WinFontInstance *pFontInstance = static_cast<WinFontInstance*>(pFont->mpFontInstance); + mpWinFontEntry[ nFallbackLevel ] = pFontInstance; HFONT hOldFont = nullptr; - HFONT hNewFont = mpWinFontEntry[ nFallbackLevel ] ? mpWinFontEntry[ nFallbackLevel ]->GetHFONT() : nullptr; + HFONT hNewFont = pFontInstance ? pFontInstance->GetHFONT() : nullptr; if (!hNewFont) { - hNewFont = ImplDoSetFont(pFont->GetFontSelectPattern(), pFont->GetFontFace(), mfFontScale[ nFallbackLevel ], hOldFont); - mpWinFontEntry[ nFallbackLevel ]->SetHFONT(hNewFont); + float fFontScale = 1.0; + hNewFont = ImplDoSetFont(pFont, nullptr, fFontScale, hOldFont); + if (pFontInstance) + { + pFontInstance->SetHFONT(hNewFont); + pFontInstance->SetScale(fFontScale); + } + else + { + if (mhFonts[nFallbackLevel]) + ::DeleteFont(mhFonts[nFallbackLevel]); + mhFonts[nFallbackLevel] = hNewFont; + mfFontScale[nFallbackLevel] = fFontScale; + } } else hOldFont = ::SelectFont( getHDC(), hNewFont ); - mfCurrentFontScale = mfFontScale[nFallbackLevel]; - + // keep default font if( !mhDefFont ) - { - // keep default font mhDefFont = hOldFont; - } else { // release no longer referenced font handles - for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) + for (int i = nFallbackLevel + 1; i < MAX_FALLBACK; ++i) { - if( mhFonts[i] ) + if (mhFonts[i]) { ::DeleteFont( mhFonts[i] ); mhFonts[i] = nullptr; } - if (i > nFallbackLevel && mpWinFontEntry[i]) + if (mpWinFontEntry[i]) { GetWinFontEntry(i)->Release(); mpWinFontEntry[i] = nullptr; } + mfFontScale[i] = 1.0; } } // store new font in correct layer - if (mpWinFontEntry[nFallbackLevel]) + if (pFontInstance) { // now the font is live => update font face - const WinFontFace* pFontFace = static_cast<const WinFontFace*>(mpWinFontEntry[nFallbackLevel]->GetFontFace()); + const WinFontFace* pFontFace = static_cast<const WinFontFace*>(pFontInstance->GetFontFace()); pFontFace->UpdateFromHDC(getHDC()); } - else - mhFonts[ nFallbackLevel ] = hNewFont; } void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFallbackLevel ) @@ -1037,7 +1046,7 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFa rxFontMetric->SetSlant( 0 ); // transformation dependent font metrics - rxFontMetric->SetWidth(static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmAveCharWidth )); + rxFontMetric->SetWidth(static_cast<int>(mpWinFontEntry[nFallbackLevel]->GetScale() * 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()); @@ -1385,7 +1394,14 @@ bool WinSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle return true; } + WinFontInstance* pFont = mpWinFontEntry[rGlyph.mnFallbackLevel]; + HFONT hNewFont = pFont ? pFont->GetHFONT() : mhFonts[rGlyph.mnFallbackLevel]; + float fFontScale = pFont ? pFont->GetScale() : mfFontScale[rGlyph.mnFallbackLevel]; + HDC hDC = getHDC(); + HFONT hFont = static_cast<HFONT>(GetCurrentObject(hDC, OBJ_FONT)); + if (hNewFont && (hFont != hNewFont)) + SelectObject(hDC, hNewFont); // use unity matrix MAT2 aMat; @@ -1399,15 +1415,17 @@ bool WinSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle aGM.gmptGlyphOrigin.x = aGM.gmptGlyphOrigin.y = 0; aGM.gmBlackBoxX = aGM.gmBlackBoxY = 0; DWORD nSize = ::GetGlyphOutlineW(hDC, rGlyph.maGlyphId, nGGOFlags, &aGM, 0, nullptr, &aMat); + if (hNewFont && (hFont != hNewFont)) + SelectObject(hDC, hFont); if( nSize == GDI_ERROR ) return false; rRect = tools::Rectangle( Point( +aGM.gmptGlyphOrigin.x, -aGM.gmptGlyphOrigin.y ), Size( aGM.gmBlackBoxX, aGM.gmBlackBoxY ) ); - 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); + rRect.SetLeft(static_cast<int>( fFontScale * rRect.Left() )); + rRect.SetRight(static_cast<int>( fFontScale * rRect.Right() ) + 1); + rRect.SetTop(static_cast<int>( fFontScale * rRect.Top() )); + rRect.SetBottom(static_cast<int>( fFontScale * rRect.Bottom() ) + 1); g_BoundRectCache.insert({rGlyph.maGlyphId, rRect}); @@ -1587,7 +1605,9 @@ bool WinSalGraphics::GetGlyphOutline(const GlyphItem& rGlyph, // rescaling needed for the tools::PolyPolygon conversion if( rB2DPolyPoly.count() ) { - const double fFactor(mfCurrentFontScale/256); + WinFontInstance *pFont = mpWinFontEntry[rGlyph.mnFallbackLevel]; + float fFontScale = pFont ? pFont->GetScale() : mfFontScale[rGlyph.mnFallbackLevel]; + const double fFactor(fFontScale/256); rB2DPolyPoly.transform(basegfx::utils::createScaleB2DHomMatrix(fFactor, fFactor)); } diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx index d38337b6d546..aba0d6e6589e 100644 --- a/vcl/win/gdi/salgdi.cxx +++ b/vcl/win/gdi/salgdi.cxx @@ -607,7 +607,6 @@ 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), |