include/vcl/salgtype.hxx | 7 +++ vcl/inc/win/salgdi.h | 44 ++++++++++++++++++- vcl/source/outdev/bitmap.cxx | 6 +- vcl/win/source/gdi/salgdi.cxx | 55 +++++++++++++++++++++++ vcl/win/source/gdi/salnativewidgets-luna.cxx | 54 +++++++++++++++++++---- vcl/win/source/gdi/salvd.cxx | 6 +- vcl/win/source/gdi/winlayout.cxx | 62 +++++++-------------------- 7 files changed, 175 insertions(+), 59 deletions(-)
New commits: commit 57d6b92b69a31260dea0d84fcd1fc5866ada7adb Author: Jan Holesovsky <ke...@collabora.com> Date: Thu Nov 20 18:49:03 2014 +0100 windows opengl: Implement the native theming with OpenGL. Change-Id: If8eb5cef228f4eb28e16de3e3135742282403cdc diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 831a703..8d88784 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -39,6 +39,7 @@ class FontSelectPattern; class ImplWinFontEntry; class ImplFontAttrCache; +class OpenGLTexture; class PhysicalFontCollection; class SalGraphicsImpl; class WinOpenGLSalGraphicsImpl; @@ -154,7 +155,7 @@ private: HBITMAP mhBitmap; /// DIBSection data. - sal_uInt8 *mpData; + sal_uInt32 *mpData; /// Mapping between the GDI position and OpenGL, to use for OpenGL drawing. SalTwoRect maRects; @@ -168,8 +169,13 @@ public: HDC getCompatibleHDC() { return mhCompatibleDC; } - /// Call the WinOpenGLSalGraphicsImpl's DrawMask(). - void DrawMask(SalColor color); + SalTwoRect getTwoRect() { return maRects; } + + /// Reset the DC with the defined color. + void fill(sal_uInt32 color); + + /// Obtain the texture; the caller must delete it after use. + OpenGLTexture* getTexture(); }; class WinSalGraphics : public SalGraphics @@ -177,9 +183,12 @@ class WinSalGraphics : public SalGraphics friend class WinSalGraphicsImpl; friend class ScopedFont; friend class OpenGLCompatibleDC; -private: + friend class WinLayout; + +protected: boost::scoped_ptr<SalGraphicsImpl> mpImpl; +private: HDC mhLocalDC; // HDC bool mbPrinter : 1; // is Printer bool mbVirDev : 1; // is VirDev diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index d011f31..678067d 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -601,18 +601,23 @@ OpenGLCompatibleDC::~OpenGLCompatibleDC() } } -void OpenGLCompatibleDC::DrawMask(SalColor color) +void OpenGLCompatibleDC::fill(sal_uInt32 color) { - if (!mpImpl) + if (!mpData) 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(); + sal_uInt32 *p = mpData; + for (int i = maRects.mnSrcWidth * maRects.mnSrcHeight; i > 0; --i) + *p++ = color; +} - mpImpl->PreDraw(); - mpImpl->DrawMask(aTexture, color, maRects); - mpImpl->PostDraw(); +OpenGLTexture* OpenGLCompatibleDC::getTexture() +{ + if (!mpImpl) + return NULL; + + // turn what's in the mpData into a texture + return new OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<sal_uInt8*>(mpData)); } WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd): diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx index 8fcc16e..8c87710 100644 --- a/vcl/win/source/gdi/salnativewidgets-luna.cxx +++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx @@ -35,6 +35,7 @@ #include "osl/module.h" +#include <opengl/win/gdiimpl.hxx> #include "vcl/svapp.hxx" #include <vcl/settings.hxx> @@ -1260,18 +1261,53 @@ bool WinSalGraphics::drawNativeControl( ControlType nType, rc.top = buttonRect.Top(); rc.bottom = buttonRect.Bottom()+1; - // set default text alignment - int ta = SetTextAlign( getHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP ); + OUString aCaptionStr(aCaption.replace('~', '&')); // translate mnemonics - OUString aCaptionStr( aCaption.replace('~', '&') ); // translate mnemonics - bOk = ImplDrawNativeControl(getHDC(), hTheme, rc, - nType, nPart, nState, aValue, - aCaptionStr ); + WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()); + if (pImpl == NULL) + { + // set default text alignment + int ta = SetTextAlign(getHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP); + + bOk = ImplDrawNativeControl(getHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr); + + // restore alignment + SetTextAlign(getHDC(), ta); + } + else + { + // We can do OpenGL + OpenGLCompatibleDC aBlackDC(*this, buttonRect.Left(), buttonRect.Top(), buttonRect.GetWidth(), buttonRect.GetHeight()); + SetTextAlign(aBlackDC.getCompatibleHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP); + aBlackDC.fill(MAKE_SALCOLOR(0, 0, 0)); + + OpenGLCompatibleDC aWhiteDC(*this, buttonRect.Left(), buttonRect.Top(), buttonRect.GetWidth(), buttonRect.GetHeight()); + SetTextAlign(aWhiteDC.getCompatibleHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP); + aWhiteDC.fill(MAKE_SALCOLOR(0xff, 0xff, 0xff)); - // restore alignment - SetTextAlign( getHDC(), ta ); + if (ImplDrawNativeControl(aBlackDC.getCompatibleHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr) && + ImplDrawNativeControl(aWhiteDC.getCompatibleHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr)) + { + OpenGLTexture *pBlackTexture = aBlackDC.getTexture(); + if (!pBlackTexture) + return false; + + OpenGLTexture *pWhiteTexture = aWhiteDC.getTexture(); + if (!pWhiteTexture) + { + delete pBlackTexture; + return false; + } - //GdiFlush(); + pImpl->PreDraw(); + pImpl->DrawTexture(*pBlackTexture, aBlackDC.getTwoRect()); // FIXME combine the textures - DrawTextureSynthesizedAlpha() + pImpl->PostDraw(); + + delete pBlackTexture; + delete pWhiteTexture; + bOk = true; + } + } return bOk; } diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx index 2b00c03..c85133d 100644 --- a/vcl/win/source/gdi/salvd.cxx +++ b/vcl/win/source/gdi/salvd.cxx @@ -38,6 +38,9 @@ HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, long nDX, long nDY, } else { + if (nBitCount == 0) + nBitCount = (WORD)GetDeviceCaps(hDC, BITSPIXEL); + // #146839# Don't use CreateCompatibleBitmap() - there seem to // be build-in limits for those HBITMAPs, at least this fails // rather often on large displays/multi-monitor setups. @@ -46,8 +49,7 @@ HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, long nDX, long nDY, aBitmapInfo.bmiHeader.biWidth = nDX; aBitmapInfo.bmiHeader.biHeight = nDY; aBitmapInfo.bmiHeader.biPlanes = 1; - aBitmapInfo.bmiHeader.biBitCount = (WORD)GetDeviceCaps( hDC, - BITSPIXEL ); + aBitmapInfo.bmiHeader.biBitCount = nBitCount; aBitmapInfo.bmiHeader.biCompression = BI_RGB; aBitmapInfo.bmiHeader.biSizeImage = 0; aBitmapInfo.bmiHeader.biXPelsPerMeter = 0; diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 8457c55..3778db3 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -215,7 +215,18 @@ void WinLayout::DrawText(SalGraphics& rGraphics) const COLORREF color = GetTextColor(hDC); SalColor salColor = MAKE_SALCOLOR(GetRValue(color), GetGValue(color), GetBValue(color)); - aDC.DrawMask(salColor); + WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(rWinGraphics.mpImpl.get()); + if (pImpl) + { + OpenGLTexture *pTexture = aDC.getTexture(); + if (pTexture) + { + pImpl->PreDraw(); + pImpl->DrawMask(*pTexture, salColor, aDC.getTwoRect()); + pImpl->PostDraw(); + delete pTexture; + } + } } } commit 3f94c9e9ddfd807b449f3bb9b232cf2041fa12d2 Author: Jan Holesovsky <ke...@collabora.com> Date: Thu Nov 20 14:14:30 2014 +0100 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 diff --git a/include/vcl/salgtype.hxx b/include/vcl/salgtype.hxx index dc21904..23b8977 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 74e8fe0..831a703 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<SalGraphicsImpl> mpImpl; diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index 93c37c4..93a04b8 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 1004fbb..d011f31 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -30,6 +30,7 @@ #include <win/saldata.hxx> #include <win/salgdi.h> #include <win/salframe.h> +#include <win/salvd.h> #include <basegfx/matrix/b2dhommatrixtools.hxx> #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<WinSalGraphics&>(rGraphics); + mpImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(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<void **>(&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 1d461e6..8457c55 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -27,7 +27,6 @@ #include <vcl/opengl/OpenGLHelper.hxx> #include <win/salgdi.h> #include <win/saldata.hxx> -#include <win/salvd.h> #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<void **>(&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<WinOpenGLSalGraphicsImpl*>(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); } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits