diff options
author | Jan Holesovsky <kendy@collabora.com> | 2014-11-13 23:53:34 +0100 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2014-11-14 00:07:49 +0100 |
commit | 19ad91f7bc7ca96c55e0ca3450608f616f87c4ed (patch) | |
tree | 834b12da4c292940f7148e80d679647ed4959e9c | |
parent | 966fc1f2ab7c8c59ceac8b77c6feaa33f6e8ee02 (diff) |
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
-rw-r--r-- | vcl/inc/opengl/win/gdiimpl.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/win/salgdi.h | 1 | ||||
-rw-r--r-- | vcl/inc/win/salvd.h | 3 | ||||
-rw-r--r-- | vcl/win/source/gdi/salvd.cxx | 15 | ||||
-rw-r--r-- | vcl/win/source/gdi/winlayout.cxx | 64 |
5 files changed, 69 insertions, 15 deletions
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx index aa29dd9bb75c..085be79bcef2 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 69ea4cfde2cb..5e4d32fbb360 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 546a1f0dda53..2c59f47ab7e9 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 2269debcd1a8..2b00c0377be3 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 4351883cd965..a5945daeb11b 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); } } |