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);

    // restore alignment
    SetTextAlign( getHDC(), ta );
        bOk = ImplDrawNativeControl(getHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr);

    //GdiFlush();
        // 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));

        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;
            }

            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;
            }
        }
    }
}