summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-03-16 15:08:11 +0100
committerLuboš Luňák <l.lunak@collabora.com>2020-03-18 10:48:19 +0100
commit271e8c99a2a1e28b7eb9fdc5fe16f8be1e8ee763 (patch)
tree9235764f08b015ec92716c1f6f1cf777e55ca3cc /vcl
parent2ff6fce634ff173b9eb8a703b7f2f265f6e3ecb1 (diff)
implement text rendering using directly Skia (Windows)
The Windows code needed for Skia text rendering. Like with the X11 code, the font is slightly lighter than with Skia disabled, but otherwise it seems to work. And like the X11 code this also requires patching Skia to use the font we want. Change-Id: Ib5ba52e4ba51b6523617072b77ed5446e7343f46 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90582 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/skia/win/gdiimpl.hxx3
-rw-r--r--vcl/inc/win/wingdiimpl.hxx3
-rw-r--r--vcl/skia/win/gdiimpl.cxx55
-rw-r--r--vcl/win/gdi/winlayout.cxx6
4 files changed, 65 insertions, 2 deletions
diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx
index 676e743151e7..3d6c680f2af4 100644
--- a/vcl/inc/skia/win/gdiimpl.hxx
+++ b/vcl/inc/skia/win/gdiimpl.hxx
@@ -73,6 +73,9 @@ public:
virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, int nX,
int nY, ControlCacheKey& aControlCacheKey) override;
+ virtual bool DrawTextLayout(const GenericSalLayout& layout) override;
+ // TODO This method of text drawing can probably be removed once DrawTextLayout()
+ // is fully usable.
virtual bool UseTextDraw() const override { return true; }
virtual void PreDrawText() override;
virtual void PostDrawText() override;
diff --git a/vcl/inc/win/wingdiimpl.hxx b/vcl/inc/win/wingdiimpl.hxx
index 84884220318f..e81e35201413 100644
--- a/vcl/inc/win/wingdiimpl.hxx
+++ b/vcl/inc/win/wingdiimpl.hxx
@@ -35,6 +35,9 @@ public:
abort();
};
+ // Implementation for WinSalGraphics::DrawTextLayout().
+ // Returns true if handled, if false, then WinSalGraphics will handle it itself.
+ virtual bool DrawTextLayout(const GenericSalLayout&) { return false; }
// If true is returned, the following functions are used for text rendering.
virtual bool UseTextDraw() const { return false; }
virtual void PreDrawText() {}
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index 84aed4f05b92..b7014ed33b48 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -13,12 +13,17 @@
#include <vcl/skia/SkiaHelper.hxx>
#include <skia/utils.hxx>
#include <skia/zone.hxx>
+#include <win/winlayout.hxx>
#include <SkColorFilter.h>
#include <SkPixelRef.h>
+#include <SkTypeface_win.h>
+#include <SkFont.h>
#include <tools/sk_app/win/WindowContextFactory_win.h>
#include <tools/sk_app/WindowContext.h>
+#include <windows.h>
+
WinSkiaSalGraphicsImpl::WinSkiaSalGraphicsImpl(WinSalGraphics& rGraphics,
SalGeometryProvider* mpProvider)
: SkiaSalGraphicsImpl(rGraphics, mpProvider)
@@ -104,6 +109,56 @@ bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, C
return true;
}
+bool WinSkiaSalGraphicsImpl::DrawTextLayout(const GenericSalLayout& rLayout)
+{
+ const WinFontInstance& rWinFont = static_cast<const WinFontInstance&>(rLayout.GetFont());
+ float fHScale = rWinFont.getHScale();
+
+ assert(dynamic_cast<const WinFontInstance*>(&rLayout.GetFont()));
+ const WinFontInstance* pWinFont = static_cast<const WinFontInstance*>(&rLayout.GetFont());
+ const HFONT hLayoutFont = pWinFont->GetHFONT();
+ LOGFONT logFont;
+ if (::GetObjectW(hLayoutFont, sizeof(logFont), &logFont) == 0)
+ {
+ assert(false);
+ return false;
+ }
+ // Wrap the font in Skia's SkTypeFace subclass that's been patched
+ // to use it.
+ sk_sp<SkTypeface> typeface(SkCreateTypefaceFromLOGFONT(logFont, hLayoutFont));
+ // lfHeight actually depends on DPI, so it's not really font height as such,
+ // but for LOGFONT-based typefaces Skia simply sets lfHeight back to this value
+ // directly.
+ // This is probably not necessary since we pass also the HFONT itself, but better
+ // forward that information too, in case SkFont uses it somehow.
+ double fontHeight = logFont.lfHeight;
+ if (fontHeight < 0)
+ fontHeight = -fontHeight;
+ SkFont font(typeface, fontHeight, fHScale, 0);
+ // Skia needs to be explicitly told what kind of antialiasing should be used,
+ // get it from system settings. This does not actually matter for the text
+ // rendering itself, since it will use the font passed to Skia in the code above
+ // (and that one uses DEFAULT_QUALITY, so Windows will select the appropriate AA setting),
+ // but Skia internally chooses the format to which the glyphs will be rendered
+ // based on this setting (subpixel AA requires colors, others do not).
+ BOOL set;
+ if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &set, 0) && set)
+ {
+ UINT set2;
+ if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &set2, 0)
+ && set2 == FE_FONTSMOOTHINGCLEARTYPE)
+ font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
+ else
+ font.setEdging(SkFont::Edging::kAntiAlias);
+ }
+ assert(dynamic_cast<SkiaSalGraphicsImpl*>(mWinParent.GetImpl()));
+ SkiaSalGraphicsImpl* impl = static_cast<SkiaSalGraphicsImpl*>(mWinParent.GetImpl());
+ COLORREF color = ::GetTextColor(mWinParent.getHDC());
+ Color salColor(GetRValue(color), GetGValue(color), GetBValue(color));
+ impl->drawGenericLayout(rLayout, salColor, font);
+ return true;
+}
+
void WinSkiaSalGraphicsImpl::PreDrawText() { preDraw(); }
void WinSkiaSalGraphicsImpl::PostDrawText() { postDraw(); }
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index e13d6930df64..636cac595bf1 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -543,11 +543,13 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout, HDC hDC, bo
void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
{
- HDC hDC = getHDC();
+ WinSalGraphicsImplBase* pImpl = dynamic_cast<WinSalGraphicsImplBase*>(mpImpl.get());
+ if( !mbPrinter && pImpl->DrawTextLayout(rLayout))
+ return; // handled by pImpl
+ HDC hDC = getHDC();
const WinFontInstance* pWinFont = static_cast<const WinFontInstance*>(&rLayout.GetFont());
const HFONT hLayoutFont = pWinFont->GetHFONT();
- WinSalGraphicsImplBase* pImpl = dynamic_cast<WinSalGraphicsImplBase*>(mpImpl.get());
bool bUseClassic = !pImpl->UseTextDraw() || mbPrinter;
// Our DirectWrite renderer is incomplete, skip it for vertical text where glyphs are not