windows opengl: Proof-of-concept text rendering.

We don't have a method that would paint a texture with transparency yet.  We
also need to limit the size of the DIBSection exactly to what we are going to
paint, no point in creating a huge bitmap that is mostly empty (but the part
where is the text being drawn).

Change-Id: Ice0bf325743d08e19e636be73cef6aff3cde5704
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
index aa29dd9..085be79 100644
--- a/vcl/inc/opengl/win/gdiimpl.hxx
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -17,6 +17,7 @@

class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl
{
    friend class WinLayout;
private:
    WinSalGraphics& mrParent;

diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 69ea4cf..5e4d32f 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -146,6 +146,7 @@ class WinSalGraphics : public SalGraphics
{
    friend class WinSalGraphicsImpl;
    friend class ScopedFont;
    friend class WinLayout;
private:
    boost::scoped_ptr<SalGraphicsImpl> mpImpl;

diff --git a/vcl/inc/win/salvd.h b/vcl/inc/win/salvd.h
index 546a1f0..2c59f47 100644
--- a/vcl/inc/win/salvd.h
+++ b/vcl/inc/win/salvd.h
@@ -51,8 +51,11 @@ public:
    virtual void                    ReleaseGraphics( SalGraphics* pGraphics );
    virtual bool                    SetSize( long nNewDX, long nNewDY );
    virtual void                    GetSize( long& rWidth, long& rHeight );

    static HBITMAP ImplCreateVirDevBitmap(HDC hDC, long nDX, long nDY, sal_uInt16 nBitCount, void **ppDummy);
};


#endif // INCLUDED_VCL_INC_WIN_SALVD_H

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx
index 2269deb..2b00c03 100644
--- a/vcl/win/source/gdi/salvd.cxx
+++ b/vcl/win/source/gdi/salvd.cxx
@@ -27,14 +27,14 @@
#include <win/salgdi.h>
#include <win/salvd.h>

static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
                                       sal_uInt16 nBitCount )
HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, long nDX, long nDY, sal_uInt16 nBitCount, void **ppData)
{
    HBITMAP hBitmap;

     if ( nBitCount == 1 )
     {
         hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, NULL );
         ppData = NULL;
     }
     else
     {
@@ -55,9 +55,8 @@ static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
         aBitmapInfo.bmiHeader.biClrUsed = 0;
         aBitmapInfo.bmiHeader.biClrImportant = 0;

         void* pDummy;
         hBitmap = CreateDIBSection( hDC, &aBitmapInfo,
                                     DIB_RGB_COLORS, &pDummy, NULL,
                                     DIB_RGB_COLORS, ppData, NULL,
                                     0 );
     }

@@ -87,8 +86,8 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics,
        if( !hDC )
            ImplWriteLastError( GetLastError(), "CreateCompatibleDC in CreateVirtualDevice" );

        hBmp    = ImplCreateVirDevBitmap( pGraphics->getHDC(),
                                        nDX, nDY, nBitCount );
        void *pDummy;
        hBmp = WinSalVirtualDevice::ImplCreateVirDevBitmap(pGraphics->getHDC(), nDX, nDY, nBitCount, &pDummy);
        if( !hBmp )
            ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in CreateVirtualDevice" );
        // #124826# continue even if hBmp could not be created
@@ -198,8 +197,8 @@ bool WinSalVirtualDevice::SetSize( long nDX, long nDY )
        return TRUE;    // ???
    else
    {
        HBITMAP hNewBmp = ImplCreateVirDevBitmap( getHDC(), nDX, nDY,
                                              mnBitCount );
        void *pDummy;
        HBITMAP hNewBmp = ImplCreateVirDevBitmap(getHDC(), nDX, nDY, mnBitCount, &pDummy);
        if ( hNewBmp )
        {
            SelectBitmap( getHDC(), hNewBmp );
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 4351883c..a5945da 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -22,10 +22,12 @@
#include "osl/module.h"
#include "osl/file.h"

#include <opengl/texture.hxx>
#include <opengl/win/gdiimpl.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>

#include "win/salgdi.h"
#include "win/saldata.hxx"
#include <win/salgdi.h>
#include <win/saldata.hxx>
#include <win/salvd.h>

#include "sft.hxx"
#include "sallayout.hxx"
@@ -151,14 +153,62 @@ SCRIPT_CACHE& WinLayout::GetScriptCache() const

void WinLayout::DrawText(SalGraphics& rGraphics) const
{
    if (mbUseOpenGL)
    WinSalGraphics& rWinGraphics = static_cast<WinSalGraphics&>(rGraphics);
    HDC hDC = rWinGraphics.getHDC();

    if (!mbUseOpenGL)
    {
        // TODO draw to a texture instead
        DrawTextImpl(static_cast<WinSalGraphics&>(rGraphics).getHDC());
        // no OpenGL, just classic rendering
        DrawTextImpl(hDC);
    }
    else
    {
        DrawTextImpl(static_cast<WinSalGraphics&>(rGraphics).getHDC());
        // we have to render the text to a hidden texture, and draw it

        // FIXME so that we don't have to use enormous bitmap, move the text
        // to 0,0, size the width / height accordingly, and move it back via
        // SalTwoRects later
        const int width = 1024;
        const int height = 1024;
        const int bpp = 32;

        HDC compatibleDC = CreateCompatibleDC(hDC);

        sal_uInt8 *data;
        HBITMAP hBitmap = WinSalVirtualDevice::ImplCreateVirDevBitmap(compatibleDC, width, height, bpp, reinterpret_cast<void **>(&data));
        // FIXME fill transparent instead of 128
        memset(data, 128, width*height*4);

        // draw the text to the hidden DC
        HGDIOBJ hBitmapOld = SelectObject(compatibleDC, hBitmap);
        SelectFont(compatibleDC, mhFont);
        DrawTextImpl(compatibleDC);
        SelectObject(compatibleDC, hBitmapOld);

        // 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 = 0;
            aRects.mnDestY = 0;
            aRects.mnDestWidth = width;
            aRects.mnDestHeight = height;

            // FIXME We don't have a method that could paint a texture with
            // transparency yet, use it when we have it
            pImpl->DrawTexture(aTexture.Id(), Size(width, height), aRects);
        }

        DeleteObject(hBitmap);
        DeleteDC(compatibleDC);
    }
}