[Libreoffice-commits] core.git: Branch 'feature/opengl-vcl2' - 2 commits - include/vcl vcl/inc vcl/source vcl/win

Jan Holesovsky kendy at collabora.com
Thu Nov 20 09:51:11 PST 2014


 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 cab741ef1ed6171ae10f7a51f0ed8d50983ad3dd
Author: Jan Holesovsky <kendy at 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 c87af5f..1af7807 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 83b31b4d05f8c2090e899217fbdda2397473090f
Author: Jan Holesovsky <kendy at 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 2c39b8b..c87af5f 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 e912086..cb7d594 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);
     }
 }
 


More information about the Libreoffice-commits mailing list