From 83b31b4d05f8c2090e899217fbdda2397473090f Mon Sep 17 00:00:00 2001 From: Jan Holesovsky Date: Thu, 20 Nov 2014 14:14:30 +0100 Subject: windows opengl: Introduce OpenGLCompatibleDC. This is to abstract the compatible DC creation and usage, to be reused in the native theme rendering. Change-Id: Id34bba4aeea7f46fc2aa42f292f0a525d753b8d7 --- include/vcl/salgtype.hxx | 7 +++++ vcl/inc/win/salgdi.h | 35 +++++++++++++++++++++++- vcl/source/outdev/bitmap.cxx | 6 ++-- vcl/win/source/gdi/salgdi.cxx | 50 ++++++++++++++++++++++++++++++++++ vcl/win/source/gdi/winlayout.cxx | 59 ++++++++-------------------------------- 5 files changed, 105 insertions(+), 52 deletions(-) diff --git a/include/vcl/salgtype.hxx b/include/vcl/salgtype.hxx index dc219047f48f..23b8977f141c 100644 --- a/include/vcl/salgtype.hxx +++ b/include/vcl/salgtype.hxx @@ -46,6 +46,13 @@ struct SalTwoRect long mnDestY; long mnDestWidth; long mnDestHeight; + + SalTwoRect() {} + + SalTwoRect(long nSrcX, long nSrcY, long nSrcWidth, long nSrcHeight, long nDestX, long nDestY, long nDestWidth, long nDestHeight) + : mnSrcX(nSrcX), mnSrcY(nSrcY), mnSrcWidth(nSrcWidth), mnSrcHeight(nSrcHeight), mnDestX(nDestX), mnDestY(nDestY), mnDestWidth(nDestWidth), mnDestHeight(nDestHeight) + { + } }; typedef sal_uInt16 SalROPColor; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 2c39b8bf96bc..c87af5f96b87 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -41,6 +41,7 @@ class ImplWinFontEntry; class ImplFontAttrCache; class PhysicalFontCollection; class SalGraphicsImpl; +class WinOpenGLSalGraphicsImpl; #define RGB_TO_PALRGB(nRGB) ((nRGB)|0x02000000) #define PALRGB_TO_RGB(nPalRGB) ((nPalRGB)&0x00ffffff) @@ -139,11 +140,43 @@ public: bool IsGSUBstituted( sal_UCS4 ) const; }; +/** 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. +*/ +class OpenGLCompatibleDC +{ +private: + /// The compatible DC that we create for our purposes. + HDC mhCompatibleDC; + + /// DIBSection that we use for the GDI drawing, and later obtain. + HBITMAP mhBitmap; + + /// DIBSection data. + sal_uInt8 *mpData; + + /// 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 ignora the drawing, it means it happened directly to the DC.. + WinOpenGLSalGraphicsImpl *mpImpl; + +public: + OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height); + ~OpenGLCompatibleDC(); + + HDC getCompatibleHDC() { return mhCompatibleDC; } + + /// Call the WinOpenGLSalGraphicsImpl's DrawMask(). + void DrawMask(SalColor color); +}; + class WinSalGraphics : public SalGraphics { friend class WinSalGraphicsImpl; friend class ScopedFont; - friend class WinLayout; + friend class OpenGLCompatibleDC; private: boost::scoped_ptr mpImpl; diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index e9120869abfa..cb7d594aea89 100644 --- a/vcl/source/outdev/bitmap.cxx +++ b/vcl/source/outdev/bitmap.cxx @@ -653,12 +653,12 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r if(bTryDirectPaint) { Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY ); - SalTwoRect aTR = { + SalTwoRect aTR( rSrcPtPixel.X(), rSrcPtPixel.Y(), rSrcSizePixel.Width(), rSrcSizePixel.Height(), aRelPt.X(), aRelPt.Y(), - aOutSz.Width(), aOutSz.Height() - }; + aOutSz.Width(), aOutSz.Height()); + SalBitmap* pSalSrcBmp = rBmp.ImplGetImpBitmap()->ImplGetSalBitmap(); SalBitmap* pSalAlphaBmp = rAlpha.ImplGetImpBitmap()->ImplGetSalBitmap(); diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index 1004fbb31c37..d011f3168282 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "salgdiimpl.hxx" @@ -565,6 +566,55 @@ void ImplClearHDCCache( SalData* pData ) } } +OpenGLCompatibleDC::OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height) + : mhBitmap(0) + , mpData(NULL) + , maRects(0, 0, width, height, x, y, width, height) +{ + WinSalGraphics& rWinGraphics = static_cast(rGraphics); + mpImpl = dynamic_cast(rWinGraphics.mpImpl.get()); + + if (!mpImpl) + { + // we avoid the OpenGL drawing, instead we draw directly to the DC + mhCompatibleDC = rWinGraphics.getHDC(); + return; + } + + mhCompatibleDC = CreateCompatibleDC(rWinGraphics.getHDC()); + + // move the origin so that we always paint at 0,0 - to keep the bitmap + // small + OffsetViewportOrgEx(mhCompatibleDC, -x, -y, NULL); + + mhBitmap = WinSalVirtualDevice::ImplCreateVirDevBitmap(mhCompatibleDC, width, height, 32, reinterpret_cast(&mpData)); + + SelectObject(mhCompatibleDC, mhBitmap); +} + +OpenGLCompatibleDC::~OpenGLCompatibleDC() +{ + if (mpImpl) + { + DeleteObject(mhBitmap); + DeleteDC(mhCompatibleDC); + } +} + +void OpenGLCompatibleDC::DrawMask(SalColor color) +{ + if (!mpImpl) + return; + + // turn what's in the mpData into a texture + OpenGLTexture aTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_RGBA, GL_UNSIGNED_BYTE, mpData); + CHECK_GL_ERROR(); + + mpImpl->PreDraw(); + mpImpl->DrawMask(aTexture, color, maRects); + mpImpl->PostDraw(); +} + WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd): mhLocalDC(0), mbPrinter(eType == WinSalGraphics::PRINTER), diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 1d461e6049bf..8457c559da4a 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -27,7 +27,6 @@ #include #include #include -#include #include "sft.hxx" #include "sallayout.hxx" @@ -195,64 +194,28 @@ void WinLayout::DrawText(SalGraphics& rGraphics) const Rectangle aRect; GetBoundRect(rGraphics, aRect); - const int origin_x = aRect.Left(); - const int origin_y = aRect.Top(); - const int width = aRect.GetWidth(); - const int height = aRect.GetHeight(); - const int bpp = 32; + OpenGLCompatibleDC aDC(rGraphics, aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight()); - HDC compatibleDC = CreateCompatibleDC(hDC); - - // move the origin so that we always paint at 0,0 - to keep the bitmap - // small - OffsetViewportOrgEx(compatibleDC, -origin_x, -origin_y, NULL); - - sal_uInt8 *data; - HBITMAP hBitmap = WinSalVirtualDevice::ImplCreateVirDevBitmap(compatibleDC, width, height, bpp, reinterpret_cast(&data)); + // we are making changes to the DC, make sure we got a new one + assert(aDC.getCompatibleHDC() != hDC); // setup the hidden DC with black color and white background, we will // use the result of the text drawing later as a mask only - HGDIOBJ hBitmapOld = SelectObject(compatibleDC, hBitmap); - SelectFont(compatibleDC, mhFont); + SelectFont(aDC.getCompatibleHDC(), mhFont); - SetTextColor(compatibleDC, RGB(0, 0, 0)); - SetBkColor(compatibleDC, RGB(255, 255, 255)); + SetTextColor(aDC.getCompatibleHDC(), RGB(0, 0, 0)); + SetBkColor(aDC.getCompatibleHDC(), RGB(255, 255, 255)); UINT nTextAlign = GetTextAlign(hDC); - SetTextAlign(compatibleDC, nTextAlign); + SetTextAlign(aDC.getCompatibleHDC(), nTextAlign); // the actual drawing - DrawTextImpl(compatibleDC); + DrawTextImpl(aDC.getCompatibleHDC()); - SelectObject(compatibleDC, hBitmapOld); + COLORREF color = GetTextColor(hDC); + SalColor salColor = MAKE_SALCOLOR(GetRValue(color), GetGValue(color), GetBValue(color)); - // and turn it into a texture - OpenGLTexture aTexture(width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); - CHECK_GL_ERROR(); - - WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast(rWinGraphics.mpImpl.get()); - if (pImpl) - { - SalTwoRect aRects; - aRects.mnSrcX = 0; - aRects.mnSrcY = 0; - aRects.mnSrcWidth = width; - aRects.mnSrcHeight = height; - aRects.mnDestX = origin_x; - aRects.mnDestY = origin_y; - aRects.mnDestWidth = width; - aRects.mnDestHeight = height; - - COLORREF color = GetTextColor(hDC); - SalColor salColor = MAKE_SALCOLOR(GetRValue(color), GetGValue(color), GetBValue(color)); - - pImpl->PreDraw(); - pImpl->DrawMask(aTexture, salColor, aRects); - pImpl->PostDraw(); - } - - DeleteObject(hBitmap); - DeleteDC(compatibleDC); + aDC.DrawMask(salColor); } } -- cgit v1.2.3