diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2019-10-15 16:17:26 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2019-11-27 09:55:08 +0100 |
commit | b6cbf5dbd067c63f94872e31f2332e95edc201dd (patch) | |
tree | c169fd52f259038dca208c2bcc6904f38163fb1b | |
parent | 8fa83a3265e25b164cb11d598f1fbb49a7b8fbf1 (diff) |
refactor Windows OpenGLGlyphCache stuff to be reusable for Skia
Basically just remove 'OpenGL' from names of most of the classes,
turn them into base classes that have OpenGL subclasses that
actually implement the functionality.
Change-Id: Idf1f347cebc2a417bda37d6955201c775ecb0890
-rw-r--r-- | vcl/Library_vclplug_win.mk | 1 | ||||
-rw-r--r-- | vcl/inc/opengl/RenderList.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/opengl/gdiimpl.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/opengl/win/gdiimpl.hxx | 37 | ||||
-rw-r--r-- | vcl/inc/opengl/win/winlayout.hxx | 46 | ||||
-rw-r--r-- | vcl/inc/opengl/x11/gdiimpl.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/skia/win/gdiimpl.hxx | 10 | ||||
-rw-r--r-- | vcl/inc/win/saldata.hxx | 4 | ||||
-rw-r--r-- | vcl/inc/win/salgdi.h | 40 | ||||
-rw-r--r-- | vcl/inc/win/wingdiimpl.hxx | 44 | ||||
-rw-r--r-- | vcl/inc/win/winlayout.hxx | 83 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 6 | ||||
-rw-r--r-- | vcl/opengl/win/gdiimpl.cxx | 67 | ||||
-rw-r--r-- | vcl/opengl/win/winlayout.cxx | 56 | ||||
-rw-r--r-- | vcl/skia/win/gdiimpl.cxx | 5 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.hxx | 2 | ||||
-rw-r--r-- | vcl/win/gdi/gdiimpl.cxx | 4 | ||||
-rw-r--r-- | vcl/win/gdi/gdiimpl.hxx | 10 | ||||
-rw-r--r-- | vcl/win/gdi/salgdi.cxx | 36 | ||||
-rw-r--r-- | vcl/win/gdi/winlayout.cxx | 99 |
20 files changed, 371 insertions, 184 deletions
diff --git a/vcl/Library_vclplug_win.mk b/vcl/Library_vclplug_win.mk index 1b73c2458629..f0dc4ac17fc6 100644 --- a/vcl/Library_vclplug_win.mk +++ b/vcl/Library_vclplug_win.mk @@ -62,6 +62,7 @@ $(eval $(call gb_Library_use_externals,vclplug_win,\ $(eval $(call gb_Library_add_exception_objects,vclplug_win,\ vcl/opengl/win/gdiimpl \ + vcl/opengl/win/winlayout \ vcl/win/app/saldata \ vcl/win/app/salinfo \ vcl/win/app/salinst \ diff --git a/vcl/inc/opengl/RenderList.hxx b/vcl/inc/opengl/RenderList.hxx index e4df834755d6..06dd03b4d7d1 100644 --- a/vcl/inc/opengl/RenderList.hxx +++ b/vcl/inc/opengl/RenderList.hxx @@ -150,7 +150,7 @@ public: return maRenderEntries; } - void addDrawTextureWithMaskColor(OpenGLTexture const & rTexture, Color nColor, const SalTwoRect& r2Rect); + VCL_DLLPUBLIC void addDrawTextureWithMaskColor(OpenGLTexture const & rTexture, Color nColor, const SalTwoRect& r2Rect); void addDrawPixel(long nX, long nY, Color nColor); diff --git a/vcl/inc/opengl/gdiimpl.hxx b/vcl/inc/opengl/gdiimpl.hxx index e90e55458d12..b0b1de88b185 100644 --- a/vcl/inc/opengl/gdiimpl.hxx +++ b/vcl/inc/opengl/gdiimpl.hxx @@ -141,7 +141,6 @@ public: void DrawLinearGradient( const Gradient& rGradient, const tools::Rectangle& rRect ); void DrawAxialGradient( const Gradient& rGradient, const tools::Rectangle& rRect ); void DrawRadialGradient( const Gradient& rGradient, const tools::Rectangle& rRect ); - void DeferredTextDraw(OpenGLTexture const & rTexture, const Color nMaskColor, const SalTwoRect& rPosAry); void FlushDeferredDrawing(); void FlushLinesOrTriangles(DrawShaderType eType, RenderParameters const & rParameters); diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx index 3af0ccbcd344..f7d3865ceec7 100644 --- a/vcl/inc/opengl/win/gdiimpl.hxx +++ b/vcl/inc/opengl/win/gdiimpl.hxx @@ -16,11 +16,34 @@ #include <opengl/gdiimpl.hxx> #include <svdata.hxx> #include <win/salgdi.h> +#include <win/wingdiimpl.hxx> #include <o3tl/lru_map.hxx> #include <vcl/opengl/OpenGLContext.hxx> #include <ControlCacheKey.hxx> -class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl +class OpenGLCompatibleDC : public CompatibleDC +{ +public: + OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height); + + virtual std::unique_ptr<Texture> getTexture() override; + // overload, caller must delete + OpenGLTexture* getOpenGLTexture(); + + virtual bool copyToTexture(Texture& aTexture) override; + + struct Texture; +}; + +struct OpenGLCompatibleDC::Texture : public CompatibleDC::Texture +{ + OpenGLTexture texture; + virtual bool isValid() const { return !!texture; } + virtual int GetWidth() const { return texture.GetWidth(); } + virtual int GetHeight() const { return texture.GetHeight(); } +}; + +class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl, public WinSalGraphicsImplBase { friend class WinLayout; private: @@ -42,11 +65,17 @@ public: virtual void Init() override; virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) override; + virtual bool UseTextDraw() const override { return true; } + virtual void PreDrawText() override; + virtual void PostDrawText() override; + virtual void DrawMask( CompatibleDC::Texture* rTexture, Color nMaskColor, const SalTwoRect& rPosAry ) override; + using OpenGLSalGraphicsImpl::DrawMask; + virtual void DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry) override; - bool TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY); + virtual bool TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY) override; - bool RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack, - int nX, int nY , ControlCacheKey& aControlCacheKey); + virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, + int nX, int nY , ControlCacheKey& aControlCacheKey) override; }; diff --git a/vcl/inc/opengl/win/winlayout.hxx b/vcl/inc/opengl/win/winlayout.hxx new file mode 100644 index 000000000000..c6ce77bdad4e --- /dev/null +++ b/vcl/inc/opengl/win/winlayout.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_INC_OPENGL_WIN_WINLAYOUT_HXX +#define INCLUDED_VCL_INC_OPENGL_WIN_WINLAYOUT_HXX + +#include <win/winlayout.hxx> +#include <opengl/PackedTextureAtlas.hxx> + +struct OpenGLGlobalWinGlyphCache : public GlobalWinGlyphCache +{ + OpenGLGlobalWinGlyphCache() + : maPackedTextureAtlas(2048, 2048) + { + } + + PackedTextureAtlasManager maPackedTextureAtlas; + + virtual bool AllocateTexture(WinGlyphDrawElement& rElement, int nWidth, int nHeight) override; +}; + +class OpenGLWinGlyphCache : public WinGlyphCache +{ +public: + void RemoveTextures(std::vector<GLuint>& rTextureIDs); +}; + +#endif // INCLUDED_VCL_INC_OPENGL_WIN_WINLAYOUT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx index d0c0c3caf352..d86af9223c54 100644 --- a/vcl/inc/opengl/x11/gdiimpl.hxx +++ b/vcl/inc/opengl/x11/gdiimpl.hxx @@ -32,8 +32,6 @@ protected: virtual rtl::Reference<OpenGLContext> CreateWinContext() override; public: - // implementation of X11GraphicsImpl - virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) override; virtual void Init() override; diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx index 621d8d4b4a78..4c47f02baa95 100644 --- a/vcl/inc/skia/win/gdiimpl.hxx +++ b/vcl/inc/skia/win/gdiimpl.hxx @@ -15,6 +15,7 @@ #include <skia/gdiimpl.hxx> #include <win/salgdi.h> +#include <win/wingdiimpl.hxx> class ControlCacheKey; namespace sk_app @@ -22,7 +23,7 @@ namespace sk_app class WindowContext; } -class WinSkiaSalGraphicsImpl : public SkiaSalGraphicsImpl +class WinSkiaSalGraphicsImpl : public SkiaSalGraphicsImpl, public WinSalGraphicsImplBase { private: WinSalGraphics& mWinParent; @@ -36,10 +37,11 @@ public: virtual void freeResources() override; - bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX, int nY); + virtual bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX, + int nY) override; - bool RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack, int nX, - int nY, ControlCacheKey& aControlCacheKey); + virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, int nX, + int nY, ControlCacheKey& aControlCacheKey) override; protected: virtual void createSurface() override; diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx index dd08b7553734..e9889e6653d1 100644 --- a/vcl/inc/win/saldata.hxx +++ b/vcl/inc/win/saldata.hxx @@ -38,7 +38,7 @@ class WinSalFrame; class WinSalVirtualDevice; class WinSalPrinter; namespace vcl { class Font; } -struct GlobalOpenGLGlyphCache; +struct GlobalWinGlyphCache; struct HDCCache; struct TempFontItem; class TextOutRenderer; @@ -122,7 +122,7 @@ public: std::unique_ptr<TextOutRenderer> m_pD2DWriteTextOutRenderer; // tdf#107205 need 2 instances because D2DWrite can't rotate text std::unique_ptr<TextOutRenderer> m_pExTextOutRenderer; - std::unique_ptr<GlobalOpenGLGlyphCache> m_pGlobalOpenGLGlyphCache; + std::unique_ptr<GlobalWinGlyphCache> m_pGlobalWinGlyphCache; std::unique_ptr<TheTextureCache> m_pTextureCache; }; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index d6d8dea14c24..f7fb206624b5 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -45,10 +45,9 @@ class FontSelectPattern; class WinFontInstance; class ImplFontAttrCache; -class OpenGLTexture; class PhysicalFontCollection; class SalGraphicsImpl; -class WinOpenGLSalGraphicsImpl; +class WinSalGraphicsImplBase; class ImplFontMetricData; #define RGB_TO_PALRGB(nRGB) ((nRGB)|0x02000000) @@ -95,11 +94,12 @@ private: /** Class that creates (and destroys) a compatible Device Context. -This is to be used for GDI drawing into a DIB that we later use as a texture for OpenGL drawing. +This is to be used for GDI drawing into a DIB that we later use for a different +drawing method, such as a texture for OpenGL drawing or surface for Skia drawing. */ -class OpenGLCompatibleDC +class CompatibleDC { -private: +protected: /// The compatible DC that we create for our purposes. HDC mhCompatibleDC; @@ -115,12 +115,16 @@ private: /// Mapping between the GDI position and OpenGL, to use for OpenGL drawing. SalTwoRect maRects; - /// The OpenGL-based SalGraphicsImpl where we will draw. If null, we ignore the drawing, it means it happened directly to the DC... - WinOpenGLSalGraphicsImpl *mpImpl; + /// The SalGraphicsImpl where we will draw. If null, we ignore the drawing, it means it happened directly to the DC... + WinSalGraphicsImplBase *mpImpl; + + // If 'disable' is true, this class is a simple wrapper for drawing directly. Subclasses should use true. + CompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height, bool disable=true); public: - OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height); - ~OpenGLCompatibleDC(); + static std::unique_ptr< CompatibleDC > create(SalGraphics &rGraphics, int x, int y, int width, int height); + + virtual ~CompatibleDC(); HDC getCompatibleHDC() { return mhCompatibleDC; } @@ -131,11 +135,22 @@ public: /// Reset the DC with the defined color. void fill(sal_uInt32 color); - /// Obtain the texture; the caller must delete it after use. - OpenGLTexture* getTexture(); + /// Base texture class (OpenGL and Skia will provide their implementations). + struct Texture; + + /// Obtain the texture. + virtual std::unique_ptr<Texture> getTexture() { abort(); }; /// Copy bitmap data to the texture. Texture must be initialized and the correct size to hold the bitmap. - bool copyToTexture(OpenGLTexture& aTexture); + virtual bool copyToTexture(Texture& /*aTexture*/) { abort(); }; +}; + +struct CompatibleDC::Texture +{ + virtual ~Texture() = 0 {}; + virtual bool isValid() const = 0; + virtual int GetWidth() const = 0; + virtual int GetHeight() const = 0; }; class WinSalGraphics : public SalGraphics @@ -143,7 +158,6 @@ class WinSalGraphics : public SalGraphics friend class WinSalGraphicsImpl; friend class WinOpenGLSalGraphicsImpl; friend class ScopedFont; - friend class OpenGLCompatibleDC; protected: std::unique_ptr<SalGraphicsImpl> mpImpl; diff --git a/vcl/inc/win/wingdiimpl.hxx b/vcl/inc/win/wingdiimpl.hxx new file mode 100644 index 000000000000..d283f4c2bb5c --- /dev/null +++ b/vcl/inc/win/wingdiimpl.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_WIN_WINGDIIMPL_HXX +#define INCLUDED_VCL_INC_WIN_WINGDIIMPL_HXX + +#include <win/salgdi.h> +#include <ControlCacheKey.hxx> + +class ControlCacheKey; + +// Base class for some functionality that OpenGL/Skia/GDI backends must each implement. +class WinSalGraphicsImplBase +{ +public: + virtual ~WinSalGraphicsImplBase(){}; + + virtual bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX, + int nY) + = 0; + + virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, int nX, + int nY, ControlCacheKey& aControlCacheKey) + = 0; + + // If true is returned, the following functions are used for text rendering. + virtual bool UseTextDraw() const { return false; } + virtual void PreDrawText() {} + virtual void PostDrawText() {} + virtual void DrawMask(CompatibleDC::Texture* /*rTexture*/, Color /*nMaskColor*/, + const SalTwoRect& /*rPosAry*/){}; + virtual void DeferredTextDraw(const CompatibleDC::Texture* /*pTexture*/, Color /*nMaskColor*/, + const SalTwoRect& /*rPosAry*/){}; +}; + +#endif // INCLUDED_VCL_INC_WIN_WINGDIIMPL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx index 035998e2bcd9..aef394fa83e3 100644 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -26,8 +26,6 @@ #include <svsys.h> #include <win/salgdi.h> -#include <opengl/PackedTextureAtlas.hxx> - class WinFontInstance; namespace @@ -38,11 +36,11 @@ const int GLYPH_SPACE_RATIO = 8; const int GLYPH_OFFSET_RATIO = GLYPH_SPACE_RATIO * 2; } -struct OpenGLGlyphDrawElement +struct WinGlyphDrawElement { tools::Rectangle maLocation; int maLeftOverhangs; - OpenGLTexture maTexture; + std::unique_ptr<CompatibleDC::Texture> maTexture; int mnBaselineOffset; int mnHeight; bool mbVertical; @@ -58,87 +56,48 @@ struct OpenGLGlyphDrawElement } }; -class OpenGLGlyphCache; +class WinGlyphCache; -struct GlobalOpenGLGlyphCache +struct GlobalWinGlyphCache { - GlobalOpenGLGlyphCache() - : maPackedTextureAtlas(2048, 2048) - {} + std::unordered_set<WinGlyphCache*> maWinGlyphCaches; - PackedTextureAtlasManager maPackedTextureAtlas; - std::unordered_set<OpenGLGlyphCache*> maOpenGLGlyphCaches; + static GlobalWinGlyphCache * get(); - static GlobalOpenGLGlyphCache * get(); + virtual bool AllocateTexture(WinGlyphDrawElement& rElement, int nWidth, int nHeight) = 0; }; -class OpenGLGlyphCache +class WinGlyphCache { -private: - std::unordered_map<int, OpenGLGlyphDrawElement> maOpenGLTextureCache; +protected: + std::unordered_map<int, WinGlyphDrawElement> maWinTextureCache; public: - OpenGLGlyphCache() - { - GlobalOpenGLGlyphCache::get()->maOpenGLGlyphCaches.insert(this); - } - - ~OpenGLGlyphCache() - { - GlobalOpenGLGlyphCache::get()->maOpenGLGlyphCaches.erase(this); - } - - static bool ReserveTextureSpace(OpenGLGlyphDrawElement& rElement, int nWidth, int nHeight) + WinGlyphCache() { - GlobalOpenGLGlyphCache* pGlobalOpenGLGlyphCache = GlobalOpenGLGlyphCache::get(); - rElement.maTexture = pGlobalOpenGLGlyphCache->maPackedTextureAtlas.Reserve(nWidth, nHeight); - if (!rElement.maTexture) - return false; - std::vector<GLuint> aTextureIDs = pGlobalOpenGLGlyphCache->maPackedTextureAtlas.ReduceTextureNumber(8); - if (!aTextureIDs.empty()) - { - for (auto& pOpenGLGlyphCache: pGlobalOpenGLGlyphCache->maOpenGLGlyphCaches) - { - pOpenGLGlyphCache->RemoveTextures(aTextureIDs); - } - } - return true; + GlobalWinGlyphCache::get()->maWinGlyphCaches.insert(this); } - void RemoveTextures(std::vector<GLuint>& rTextureIDs) + virtual ~WinGlyphCache() { - auto it = maOpenGLTextureCache.begin(); - - while (it != maOpenGLTextureCache.end()) - { - GLuint nTextureID = it->second.maTexture.Id(); - - if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end()) - { - it = maOpenGLTextureCache.erase(it); - } - else - { - ++it; - } - } + GlobalWinGlyphCache::get()->maWinGlyphCaches.erase(this); } - void PutDrawElementInCache(const OpenGLGlyphDrawElement& rElement, int nGlyphIndex) + void PutDrawElementInCache(WinGlyphDrawElement&& rElement, int nGlyphIndex) { assert(!IsGlyphCached(nGlyphIndex)); - maOpenGLTextureCache[nGlyphIndex] = rElement; + maWinTextureCache[nGlyphIndex] = std::move( rElement ); } - OpenGLGlyphDrawElement& GetDrawElement(int nGlyphIndex) + WinGlyphDrawElement& GetDrawElement(int nGlyphIndex) { assert(IsGlyphCached(nGlyphIndex)); - return maOpenGLTextureCache[nGlyphIndex]; + return maWinTextureCache[nGlyphIndex]; } bool IsGlyphCached(int nGlyphIndex) const { - return maOpenGLTextureCache.find(nGlyphIndex) != maOpenGLTextureCache.end(); + return maWinTextureCache.find(nGlyphIndex) != maWinTextureCache.end(); } }; @@ -167,7 +126,7 @@ public: WinFontFace * GetFontFace() { return static_cast<WinFontFace *>(LogicalFontInstance::GetFontFace()); } bool CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics, const GenericSalLayout& rLayout); - OpenGLGlyphCache& GetOpenGLGlyphCache() { return maOpenGLGlyphCache; } + WinGlyphCache& GetWinGlyphCache() { return maWinGlyphCache; } bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const override; @@ -180,7 +139,7 @@ private: WinSalGraphics *m_pGraphics; HFONT m_hFont; float m_fScale; - OpenGLGlyphCache maOpenGLGlyphCache; + WinGlyphCache maWinGlyphCache; }; class TextOutRenderer diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 30d2299978ea..0f0e40dd7eaa 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -1324,12 +1324,6 @@ void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, Color nMaskColor, co mpProgram->Clean(); } -void OpenGLSalGraphicsImpl::DeferredTextDraw(OpenGLTexture const & rTexture, Color aMaskColor, const SalTwoRect& rPosAry) -{ - mpRenderList->addDrawTextureWithMaskColor(rTexture, aMaskColor, rPosAry); - PostBatchDraw(); -} - void OpenGLSalGraphicsImpl::FlushLinesOrTriangles(DrawShaderType eType, RenderParameters const & rParameters) { if (!UseProgram("combinedVertexShader", "combinedFragmentShader", "#define USE_VERTEX_COLORS")) diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx index b0d1188519c2..d71a03714198 100644 --- a/vcl/opengl/win/gdiimpl.cxx +++ b/vcl/opengl/win/gdiimpl.cxx @@ -756,6 +756,37 @@ ControlCacheType & TheTextureCache::get() { return data->m_pTextureCache->cache; } +OpenGLCompatibleDC::OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height) +: CompatibleDC( rGraphics, x, y, width, height, false ) +{ +} + +OpenGLTexture* OpenGLCompatibleDC::getOpenGLTexture() +{ + if (!mpImpl) + return nullptr; + + // turn what's in the mpData into a texture + return new OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData); +} + +std::unique_ptr<CompatibleDC::Texture> OpenGLCompatibleDC::getTexture() +{ + auto ret = std::make_unique<OpenGLCompatibleDC::Texture>(); + ret->texture = OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData); + return ret; +} + +bool OpenGLCompatibleDC::copyToTexture(CompatibleDC::Texture& aTexture) +{ + if (!mpImpl) + return false; + + assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(&aTexture)); + return static_cast<OpenGLCompatibleDC::Texture&>(aTexture).texture.CopyData( + maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, reinterpret_cast<sal_uInt8*>(mpData)); +} + bool WinOpenGLSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY) { static bool gbCacheEnabled = !getenv("SAL_WITHOUT_WIDGET_CACHE"); @@ -801,8 +832,8 @@ bool WinOpenGLSalGraphicsImpl::RenderCompatibleDC(OpenGLCompatibleDC& rWhite, Op PreDraw(); - rCombo.mpTexture.reset(rWhite.getTexture()); - rCombo.mpMask.reset(rBlack.getTexture()); + rCombo.mpTexture.reset(rWhite.getOpenGLTexture()); + rCombo.mpMask.reset(rBlack.getOpenGLTexture()); bRet = RenderTextureCombo(rCombo, nX, nY); @@ -810,12 +841,16 @@ bool WinOpenGLSalGraphicsImpl::RenderCompatibleDC(OpenGLCompatibleDC& rWhite, Op return bRet; } -bool WinOpenGLSalGraphicsImpl::RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack, +bool WinOpenGLSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, int nX, int nY , ControlCacheKey& aControlCacheKey) { + assert(dynamic_cast<OpenGLCompatibleDC*>(&rWhite)); + assert(dynamic_cast<OpenGLCompatibleDC*>(&rBlack)); + std::unique_ptr<TextureCombo> pCombo(new TextureCombo); - bool bResult = RenderCompatibleDC(rWhite, rBlack, nX, nY, *pCombo); + bool bResult = RenderCompatibleDC(static_cast<OpenGLCompatibleDC&>(rWhite), + static_cast<OpenGLCompatibleDC&>(rBlack), nX, nY, *pCombo); if (!bResult) return false; @@ -828,4 +863,28 @@ bool WinOpenGLSalGraphicsImpl::RenderAndCacheNativeControl(OpenGLCompatibleDC& r return bResult; } +void WinOpenGLSalGraphicsImpl::PreDrawText() +{ + PreDraw(); +} + +void WinOpenGLSalGraphicsImpl::PostDrawText() +{ + PostDraw(); +} + +void WinOpenGLSalGraphicsImpl::DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color aMaskColor, const SalTwoRect& rPosAry) +{ + assert(dynamic_cast<const OpenGLCompatibleDC::Texture*>(pTexture)); + mpRenderList->addDrawTextureWithMaskColor( + static_cast<const OpenGLCompatibleDC::Texture*>(pTexture)->texture, aMaskColor, rPosAry); + PostBatchDraw(); +} + +void WinOpenGLSalGraphicsImpl::DrawMask( CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry ) +{ + assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(pTexture)); + DrawMask( static_cast<OpenGLCompatibleDC::Texture*>(pTexture)->texture, nMaskColor, rPosAry ); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/win/winlayout.cxx b/vcl/opengl/win/winlayout.cxx new file mode 100644 index 000000000000..ddc72c8b28cf --- /dev/null +++ b/vcl/opengl/win/winlayout.cxx @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <opengl/win/winlayout.hxx> + +#include <opengl/win/gdiimpl.hxx> + +bool OpenGLGlobalWinGlyphCache::AllocateTexture(WinGlyphDrawElement& rElement, int nWidth, + int nHeight) +{ + assert(rElement.maTexture.get() == nullptr); + OpenGLCompatibleDC::Texture* texture = new OpenGLCompatibleDC::Texture; + rElement.maTexture.reset(texture); + texture->texture = maPackedTextureAtlas.Reserve(nWidth, nHeight); + if (!texture->texture) + return false; + std::vector<GLuint> aTextureIDs = maPackedTextureAtlas.ReduceTextureNumber(8); + if (!aTextureIDs.empty()) + { + for (auto& pWinGlyphCache : maWinGlyphCaches) + { + assert(dynamic_cast<OpenGLWinGlyphCache*>(pWinGlyphCache)); + static_cast<OpenGLWinGlyphCache*>(pWinGlyphCache)->RemoveTextures(aTextureIDs); + } + } + return true; +} + +void OpenGLWinGlyphCache::RemoveTextures(std::vector<GLuint>& rTextureIDs) +{ + auto it = maWinTextureCache.begin(); + + while (it != maWinTextureCache.end()) + { + assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(it->second.maTexture.get())); + GLuint nTextureID + = static_cast<OpenGLCompatibleDC::Texture*>(it->second.maTexture.get())->texture.Id(); + + if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end()) + { + it = maWinTextureCache.erase(it); + } + else + { + ++it; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx index 0763334f0ebf..ccfd59572424 100644 --- a/vcl/skia/win/gdiimpl.cxx +++ b/vcl/skia/win/gdiimpl.cxx @@ -87,9 +87,8 @@ bool WinSkiaSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey const& return false; // TODO } -// TODO OpenGLCompatibleDC? -bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite, - OpenGLCompatibleDC& rBlack, int nX, int nY, +bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, + int nX, int nY, ControlCacheKey& aControlCacheKey) { (void)rWhite; diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index 315ed4094f8b..edacdac787c5 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -283,8 +283,6 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override; public: - // implementation of X11GraphicsImpl - void Init() override; }; diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx index 79621f53bf60..f63258b83dd2 100644 --- a/vcl/win/gdi/gdiimpl.cxx +++ b/vcl/win/gdi/gdiimpl.cxx @@ -2576,12 +2576,12 @@ bool WinSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/, return false; } -bool WinSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey& /*rControlCacheKey*/, int /*nX*/, int /*nY*/) +bool WinSalGraphicsImpl::TryRenderCachedNativeControl(const ControlCacheKey& /*rControlCacheKey*/, int /*nX*/, int /*nY*/) { return false; } -bool WinSalGraphicsImpl::RenderAndCacheNativeControl(OpenGLCompatibleDC& /*rWhite*/, OpenGLCompatibleDC& /*rBlack*/, +bool WinSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& /*rWhite*/, CompatibleDC& /*rBlack*/, int /*nX*/, int /*nY*/ , ControlCacheKey& /*aControlCacheKey*/) { return false; diff --git a/vcl/win/gdi/gdiimpl.hxx b/vcl/win/gdi/gdiimpl.hxx index bc4a6ac27414..d7d37557565c 100644 --- a/vcl/win/gdi/gdiimpl.hxx +++ b/vcl/win/gdi/gdiimpl.hxx @@ -22,6 +22,7 @@ #include <salgdiimpl.hxx> #include <win/salgdi.h> +#include <win/wingdiimpl.hxx> #include <vcl/gradient.hxx> @@ -30,7 +31,7 @@ class WinSalGraphics; -class WinSalGraphicsImpl : public SalGraphicsImpl +class WinSalGraphicsImpl : public SalGraphicsImpl, public WinSalGraphicsImplBase { private: @@ -238,10 +239,11 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override; - virtual bool TryRenderCachedNativeControl(ControlCacheKey& rControlCacheKey, int nX, int nY); + virtual bool TryRenderCachedNativeControl(const ControlCacheKey& rControlCacheKey, + int nX, int nY) override; - virtual bool RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack, - int nX, int nY , ControlCacheKey& aControlCacheKey); + virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, + int nX, int nY , ControlCacheKey& aControlCacheKey) override; }; #endif // INCLUDED_VCL_WIN_GDI_GDIIMPL_HXX diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx index 6da451de36aa..29c6f83e11f6 100644 --- a/vcl/win/gdi/salgdi.cxx +++ b/vcl/win/gdi/salgdi.cxx @@ -547,21 +547,30 @@ void ImplClearHDCCache( SalData* pData ) } } -OpenGLCompatibleDC::OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height) +std::unique_ptr< CompatibleDC > CompatibleDC::create(SalGraphics &rGraphics, int x, int y, int width, int height) +{ + if (OpenGLHelper::isVCLOpenGLEnabled()) + return std::make_unique< OpenGLCompatibleDC >( rGraphics, x, y, width, height ); + return std::unique_ptr< CompatibleDC >( new CompatibleDC( rGraphics, x, y, width, height )); +} + +CompatibleDC::CompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height, bool disable) : mhBitmap(nullptr) , mpData(nullptr) , maRects(0, 0, width, height, x, y, width, height) + , mpImpl(nullptr) { WinSalGraphics& rWinGraphics = static_cast<WinSalGraphics&>(rGraphics); - mpImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(rWinGraphics.mpImpl.get()); - if (!mpImpl) + if( disable ) { // we avoid the OpenGL drawing, instead we draw directly to the DC mhCompatibleDC = rWinGraphics.getHDC(); return; } + mpImpl = dynamic_cast<WinSalGraphicsImplBase*>(rWinGraphics.GetImpl()); + assert(mpImpl != nullptr); mhCompatibleDC = CreateCompatibleDC(rWinGraphics.getHDC()); // move the origin so that we always paint at 0,0 - to keep the bitmap @@ -573,7 +582,7 @@ OpenGLCompatibleDC::OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int mhOrigBitmap = static_cast<HBITMAP>(SelectObject(mhCompatibleDC, mhBitmap)); } -OpenGLCompatibleDC::~OpenGLCompatibleDC() +CompatibleDC::~CompatibleDC() { if (mpImpl) { @@ -583,7 +592,7 @@ OpenGLCompatibleDC::~OpenGLCompatibleDC() } } -void OpenGLCompatibleDC::fill(sal_uInt32 color) +void CompatibleDC::fill(sal_uInt32 color) { if (!mpData) return; @@ -593,23 +602,6 @@ void OpenGLCompatibleDC::fill(sal_uInt32 color) *p++ = color; } -OpenGLTexture* OpenGLCompatibleDC::getTexture() -{ - if (!mpImpl) - return nullptr; - - // turn what's in the mpData into a texture - return new OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData); -} - -bool OpenGLCompatibleDC::copyToTexture(OpenGLTexture& aTexture) -{ - if (!mpImpl) - return false; - - return aTexture.CopyData(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, reinterpret_cast<sal_uInt8*>(mpData)); -} - WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd, SalGeometryProvider *pProvider): mhLocalDC(nullptr), mbPrinter(eType == WinSalGraphics::PRINTER), diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index 7fa273a79c97..9305f38e9dd9 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -26,12 +26,13 @@ #include <comphelper/windowserrorstring.hxx> #include <comphelper/scopeguard.hxx> -#include <opengl/texture.hxx> #include <opengl/win/gdiimpl.hxx> +#include <opengl/win/winlayout.hxx> #include <vcl/opengl/OpenGLHelper.hxx> #include <win/salgdi.h> #include <win/saldata.hxx> +#include <win/wingdiimpl.hxx> #include <outdev.h> #include <win/DWriteTextRenderer.hxx> @@ -51,18 +52,18 @@ #include <shlwapi.h> #include <winver.h> -GlobalOpenGLGlyphCache * GlobalOpenGLGlyphCache::get() +GlobalWinGlyphCache * GlobalWinGlyphCache::get() { SalData *data = GetSalData(); - if (!data->m_pGlobalOpenGLGlyphCache) - data->m_pGlobalOpenGLGlyphCache.reset(new GlobalOpenGLGlyphCache); - return data->m_pGlobalOpenGLGlyphCache.get(); + if (!data->m_pGlobalWinGlyphCache) // TODO SKIA + data->m_pGlobalWinGlyphCache.reset(new OpenGLGlobalWinGlyphCache); + return data->m_pGlobalWinGlyphCache.get(); } bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics, const GenericSalLayout& rLayout) { - OpenGLGlyphDrawElement aElement; + WinGlyphDrawElement aElement; ScopedHDC aHDC(CreateCompatibleDC(hDC)); @@ -144,14 +145,14 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, aElement.maLocation.SetBottom(bounds.getHeight() + aElement.getExtraSpace()); nPos = aEnds[0]; - OpenGLCompatibleDC aDC(rGraphics, 0, 0, nBitmapWidth, nBitmapHeight); + std::unique_ptr<CompatibleDC> aDC(CompatibleDC::create(rGraphics, 0, 0, nBitmapWidth, nBitmapHeight)); - SetTextColor(aDC.getCompatibleHDC(), RGB(0, 0, 0)); - SetBkColor(aDC.getCompatibleHDC(), RGB(255, 255, 255)); + SetTextColor(aDC->getCompatibleHDC(), RGB(0, 0, 0)); + SetBkColor(aDC->getCompatibleHDC(), RGB(255, 255, 255)); - aDC.fill(RGB(0xff, 0xff, 0xff)); + aDC->fill(RGB(0xff, 0xff, 0xff)); - pTxt->BindDC(aDC.getCompatibleHDC(), tools::Rectangle(0, 0, nBitmapWidth, nBitmapHeight)); + pTxt->BindDC(aDC->getCompatibleHDC(), tools::Rectangle(0, 0, nBitmapWidth, nBitmapHeight)); auto pRT = pTxt->GetRenderTarget(); ID2D1SolidColorBrush* pBrush = nullptr; @@ -193,12 +194,12 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, return false; } - if (!OpenGLGlyphCache::ReserveTextureSpace(aElement, nBitmapWidth, nBitmapHeight)) + if (!GlobalWinGlyphCache::get()->AllocateTexture(aElement, nBitmapWidth, nBitmapHeight)) return false; - if (!aDC.copyToTexture(aElement.maTexture)) + if (!aDC->copyToTexture(*aElement.maTexture.get())) return false; - maOpenGLGlyphCache.PutDrawElementInCache(aElement, nGlyphIndex); + maWinGlyphCache.PutDrawElementInCache(std::move(aElement), nGlyphIndex); return true; } @@ -457,7 +458,7 @@ bool WinSalGraphics::CacheGlyphs(const GenericSalLayout& rLayout) const GlyphItem* pGlyph; while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart)) { - if (!rFont.GetOpenGLGlyphCache().IsGlyphCached(pGlyph->glyphId())) + if (!rFont.GetWinGlyphCache().IsGlyphCached(pGlyph->glyphId())) { if (!rFont.CacheGlyphToAtlas(hDC, hFONT, pGlyph->glyphId(), *this, rLayout)) return false; @@ -489,19 +490,19 @@ bool WinSalGraphics::DrawCachedGlyphs(const GenericSalLayout& rLayout) const GlyphItem* pGlyph; while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart)) { - OpenGLGlyphDrawElement& rElement(rFont.GetOpenGLGlyphCache().GetDrawElement(pGlyph->glyphId())); - OpenGLTexture& rTexture = rElement.maTexture; + WinGlyphDrawElement& rElement(rFont.GetWinGlyphCache().GetDrawElement(pGlyph->glyphId())); + const CompatibleDC::Texture* texture = rElement.maTexture.get(); - if (!rTexture) + if (!texture || !texture->isValid()) return false; SalTwoRect a2Rects(0, 0, - rTexture.GetWidth(), rTexture.GetHeight(), + texture->GetWidth(), texture->GetHeight(), aPos.X() - rElement.getExtraOffset() + rElement.maLeftOverhangs, aPos.Y() - rElement.mnBaselineOffset - rElement.getExtraOffset(), - rTexture.GetWidth(), rTexture.GetHeight()); + texture->GetWidth(), texture->GetHeight()); - pImpl->DeferredTextDraw(rTexture, salColor, a2Rects); + pImpl->DeferredTextDraw(texture, salColor, a2Rects); } return true; @@ -519,14 +520,14 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout) const WinFontInstance* pWinFont = static_cast<const WinFontInstance*>(&rLayout.GetFont()); const HFONT hLayoutFont = pWinFont->GetHFONT(); - // TODO SKIA - bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter; + 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 // rotated. bool bForceGDI = rLayout.GetFont().GetFontSelectPattern().mbVertical; - if (!bUseOpenGL) + if (bUseClassic) { // no OpenGL, just classic rendering const HFONT hOrigFont = ::SelectFont(hDC, hLayoutFont); @@ -568,45 +569,39 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout) tools::Rectangle aRect; rLayout.GetBoundRect(aRect); - // TODO SKIA - WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()); - - if (pImpl) - { - pImpl->PreDraw(); + pImpl->PreDrawText(); - OpenGLCompatibleDC aDC(*this, aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight()); + std::unique_ptr<CompatibleDC> aDC(CompatibleDC::create(*this, aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight())); - // we are making changes to the DC, make sure we got a new one - assert(aDC.getCompatibleHDC() != hDC); + // we are making changes to the DC, make sure we got a new one + assert(aDC->getCompatibleHDC() != hDC); - RECT aWinRect = { aRect.Left(), aRect.Top(), aRect.Left() + aRect.GetWidth(), aRect.Top() + aRect.GetHeight() }; - ::FillRect(aDC.getCompatibleHDC(), &aWinRect, static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH))); + RECT aWinRect = { aRect.Left(), aRect.Top(), aRect.Left() + aRect.GetWidth(), aRect.Top() + aRect.GetHeight() }; + ::FillRect(aDC->getCompatibleHDC(), &aWinRect, static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH))); - // setup the hidden DC with black color and white background, we will - // use the result of the text drawing later as a mask only - const HFONT hOrigFont = ::SelectFont(aDC.getCompatibleHDC(), hLayoutFont); + // setup the hidden DC with black color and white background, we will + // use the result of the text drawing later as a mask only + const HFONT hOrigFont = ::SelectFont(aDC->getCompatibleHDC(), hLayoutFont); - ::SetTextColor(aDC.getCompatibleHDC(), RGB(0, 0, 0)); - ::SetBkColor(aDC.getCompatibleHDC(), RGB(255, 255, 255)); + ::SetTextColor(aDC->getCompatibleHDC(), RGB(0, 0, 0)); + ::SetBkColor(aDC->getCompatibleHDC(), RGB(255, 255, 255)); - UINT nTextAlign = ::GetTextAlign(hDC); - ::SetTextAlign(aDC.getCompatibleHDC(), nTextAlign); + UINT nTextAlign = ::GetTextAlign(hDC); + ::SetTextAlign(aDC->getCompatibleHDC(), nTextAlign); - COLORREF color = ::GetTextColor(hDC); - Color salColor(GetRValue(color), GetGValue(color), GetBValue(color)); + COLORREF color = ::GetTextColor(hDC); + Color salColor(GetRValue(color), GetGValue(color), GetBValue(color)); - // the actual drawing - DrawTextLayout(rLayout, aDC.getCompatibleHDC(), !bForceGDI); + // the actual drawing + DrawTextLayout(rLayout, aDC->getCompatibleHDC(), !bForceGDI); - std::unique_ptr<OpenGLTexture> xTexture(aDC.getTexture()); - if (xTexture) - pImpl->DrawMask(*xTexture, salColor, aDC.getTwoRect()); + std::unique_ptr<CompatibleDC::Texture> xTexture(aDC->getTexture()); + if (xTexture) + pImpl->DrawMask(xTexture.get(), salColor, aDC->getTwoRect()); - ::SelectFont(aDC.getCompatibleHDC(), hOrigFont); + ::SelectFont(aDC->getCompatibleHDC(), hOrigFont); - pImpl->PostDraw(); - } + pImpl->PostDrawText(); } } |