diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.com> | 2015-12-10 13:41:36 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-12-14 11:10:43 +0000 |
commit | f625f1e1ff3b557fbe16c281baaf35fdb48eb048 (patch) | |
tree | fc63fcda7e7ba6d4e9cc4a90354b43f04e375f2f | |
parent | fabfd88b11bb6253e9631664d9adb47c119f9e7d (diff) |
tdf#94851 can't use OpenGLSalBitmap with WinSalGraphics
Printing is done with the WinSalGraphics and not with
WinOpenGLSalGraphics on Windows even when OpenGL is enabled, but
the SalBitmap is still using the OpenGLSalBitmap which can't be
used with WinSalGraphics. So detect when the implementation of
SalGraphic is "wrong" and convert.
(cherry picked from commit 1cc30679765ce996a009865e6bad3e5b74b96b41)
also includes commit:
tdf#94851 use BGR color order in Windows
(cherry picked from commit 8a498fad249b3a92f275f33b683f242cb8d68b7b)
and commit:
tdf#94851 check SalBitmap & convert in all drawBitmap methods
(cherry picked from commit 917d59a84124d1022bd1912874e7a53c674784f1)
Change-Id: I67c730514a8a016c828b5cafdf6e70ddeca450ec
Reviewed-on: https://gerrit.libreoffice.org/20659
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | vcl/opengl/salbmp.cxx | 109 | ||||
-rw-r--r-- | vcl/win/source/gdi/salgdi2.cxx | 72 |
2 files changed, 140 insertions, 41 deletions
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index cbf60c244ba4..ce03ccfe98f2 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -37,6 +37,44 @@ namespace { +inline bool determineTextureFormat(sal_uInt16 nBits, GLenum& nFormat, GLenum& nType) +{ + switch(nBits) + { + case 8: + nFormat = GL_LUMINANCE; + nType = GL_UNSIGNED_BYTE; + return true; + case 16: +#ifdef WNT + nFormat = GL_BGR; +#else + nFormat = GL_RGB; +#endif + nType = GL_UNSIGNED_SHORT_5_6_5; + return true; + case 24: +#ifdef WNT + nFormat = GL_BGR; +#else + nFormat = GL_RGB; +#endif + nType = GL_UNSIGNED_BYTE; + return true; + case 32: +#ifdef WNT + nFormat = GL_BGRA; +#else + nFormat = GL_RGBA; +#endif + nType = GL_UNSIGNED_BYTE; + return true; + default: + break; + } + return false; +} + static bool isValidBitCount( sal_uInt16 nBitCount ) { return (nBitCount == 1) || (nBitCount == 4) || (nBitCount == 8) || (nBitCount == 16) || (nBitCount == 24) || (nBitCount == 32); @@ -396,18 +434,7 @@ GLuint OpenGLSalBitmap::CreateTexture() // no conversion needed for truecolor pData = maUserBuffer.get(); - switch( mnBits ) - { - case 16: nFormat = GL_RGB; - nType = GL_UNSIGNED_SHORT_5_6_5; - break; - case 24: nFormat = GL_RGB; - nType = GL_UNSIGNED_BYTE; - break; - case 32: nFormat = GL_RGBA; - nType = GL_UNSIGNED_BYTE; - break; - } + determineTextureFormat(mnBits, nFormat, nType); } else if( mnBits == 8 && maPalette.IsGreyPalette() ) { @@ -421,8 +448,8 @@ GLuint OpenGLSalBitmap::CreateTexture() // convert to 32 bits RGBA using palette pData = new sal_uInt8[mnBufHeight * mnBufWidth * 4]; bAllocated = true; - nFormat = GL_RGBA; - nType = GL_UNSIGNED_BYTE; + + determineTextureFormat(32, nFormat, nType); ImplPixelFormat* pSrcFormat = ImplPixelFormat::GetFormat( mnBits, maPalette ); sal_uInt8* pSrcData = maUserBuffer.get(); @@ -469,31 +496,18 @@ bool OpenGLSalBitmap::ReadTexture() { sal_uInt8* pData = maUserBuffer.get(); + SAL_INFO( "vcl.opengl", "::ReadTexture " << mnWidth << "x" << mnHeight ); + GLenum nFormat = GL_RGBA; + GLenum nType = GL_UNSIGNED_BYTE; + if( pData == NULL ) return false; if (mnBits == 8 || mnBits == 16 || mnBits == 24 || mnBits == 32) { - GLenum nFormat = GL_RGBA; - GLenum nType = GL_UNSIGNED_BYTE; - - switch( mnBits ) - { - case 8: nFormat = GL_LUMINANCE; - nType = GL_UNSIGNED_BYTE; - break; - case 16: nFormat = GL_RGB; - nType = GL_UNSIGNED_SHORT_5_6_5; - break; - case 24: nFormat = GL_RGB; - nType = GL_UNSIGNED_BYTE; - break; - case 32: nFormat = GL_RGBA; - nType = GL_UNSIGNED_BYTE; - break; - } + determineTextureFormat(mnBits, nFormat, nType); makeCurrent(); maTexture.Read(nFormat, nType, pData); @@ -506,7 +520,8 @@ bool OpenGLSalBitmap::ReadTexture() std::vector<sal_uInt8> aBuffer(mnWidth * mnHeight * 3); makeCurrent(); sal_uInt8* pBuffer = aBuffer.data(); - maTexture.Read(GL_RGB, GL_UNSIGNED_BYTE, pBuffer); + determineTextureFormat(24, nFormat, nType); + maTexture.Read(nFormat, nType, pBuffer); int nShift = 7; size_t nIndex = 0; @@ -719,12 +734,30 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( BitmapAccessMode nMode ) case 1: pBuffer->mnFormat = BMP_FORMAT_1BIT_MSB_PAL; break; case 4: pBuffer->mnFormat = BMP_FORMAT_4BIT_MSN_PAL; break; case 8: pBuffer->mnFormat = BMP_FORMAT_8BIT_PAL; break; - case 16: pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK; - pBuffer->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f ); + case 16: +#ifdef WNT + pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK; + pBuffer->maColorMask = ColorMask(0x7c00, 0x03e0, 0x001f); +#else + pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK; + pBuffer->maColorMask = ColorMask(0xf800, 0x07e0, 0x001f); +#endif + break; + case 24: +#ifdef WNT + pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_BGR; +#else + pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_RGB; +#endif break; - case 24: pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_RGB; break; - case 32: pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_RGBA; - pBuffer->maColorMask = ColorMask( 0xff000000, 0x00ff0000, 0x0000ff00 ); + case 32: +#ifdef WNT + pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_BGRA; + pBuffer->maColorMask = ColorMask(0x00ff0000, 0x0000ff00, 0x000000ff); +#else + pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_RGBA; + pBuffer->maColorMask = ColorMask(0xff000000, 0x00ff0000, 0x0000ff00); +#endif break; } diff --git a/vcl/win/source/gdi/salgdi2.cxx b/vcl/win/source/gdi/salgdi2.cxx index f00945164f3e..dae658dc406d 100644 --- a/vcl/win/source/gdi/salgdi2.cxx +++ b/vcl/win/source/gdi/salgdi2.cxx @@ -34,6 +34,8 @@ #include "vcl/bmpacc.hxx" #include "outdata.hxx" #include "salgdiimpl.hxx" +#include "opengl/win/gdiimpl.hxx" + bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const { @@ -69,23 +71,87 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, nSrcWidth, nSrcHeight, nFlags ); } +namespace +{ + +void convertToWinSalBitmap(SalBitmap& rSalBitmap, WinSalBitmap& rWinSalBitmap) +{ + BitmapBuffer* pRead = rSalBitmap.AcquireBuffer(BITMAP_READ_ACCESS); + + rWinSalBitmap.Create(rSalBitmap.GetSize(), rSalBitmap.GetBitCount(), BitmapPalette()); + BitmapBuffer* pWrite = rWinSalBitmap.AcquireBuffer(BITMAP_WRITE_ACCESS); + + sal_uInt8* pSource(pRead->mpBits); + sal_uInt8* pDestination(pWrite->mpBits); + + for (long y = 0; y < pRead->mnHeight; y++) + { + memcpy(pDestination, pSource, pRead->mnScanlineSize); + pSource += pRead->mnScanlineSize; + pDestination += pWrite->mnScanlineSize; + } + rWinSalBitmap.ReleaseBuffer(pWrite, BITMAP_WRITE_ACCESS); + + rSalBitmap.ReleaseBuffer(pRead, BITMAP_READ_ACCESS); +} + +} // end anonymous namespace + void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap) { - mpImpl->drawBitmap( rPosAry, rSalBitmap ); + if (dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()) == nullptr && + dynamic_cast<const WinSalBitmap*>(&rSalBitmap) == nullptr) + { + std::unique_ptr<WinSalBitmap> pWinSalBitmap(new WinSalBitmap()); + SalBitmap& rConstBitmap = const_cast<SalBitmap&>(rSalBitmap); + convertToWinSalBitmap(rConstBitmap, *pWinSalBitmap.get()); + mpImpl->drawBitmap(rPosAry, *pWinSalBitmap.get()); + } + else + { + mpImpl->drawBitmap(rPosAry, rSalBitmap); + } } void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, SalColor nTransparentColor ) { - mpImpl->drawBitmap( rPosAry, rSSalBitmap, nTransparentColor ); + if (dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()) == nullptr && + dynamic_cast<const WinSalBitmap*>(&rSSalBitmap) == nullptr) + { + std::unique_ptr<WinSalBitmap> pWinSalBitmap(new WinSalBitmap()); + SalBitmap& rConstBitmap = const_cast<SalBitmap&>(rSSalBitmap); + convertToWinSalBitmap(rConstBitmap, *pWinSalBitmap.get()); + mpImpl->drawBitmap(rPosAry, *pWinSalBitmap.get(), nTransparentColor); + } + else + { + mpImpl->drawBitmap(rPosAry, rSSalBitmap, nTransparentColor); + } } void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, const SalBitmap& rSTransparentBitmap ) { - mpImpl->drawBitmap( rPosAry, rSSalBitmap, rSTransparentBitmap ); + if (dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()) == nullptr && + dynamic_cast<const WinSalBitmap*>(&rSSalBitmap) == nullptr) + { + std::unique_ptr<WinSalBitmap> pWinSalBitmap(new WinSalBitmap()); + SalBitmap& rConstBitmap = const_cast<SalBitmap&>(rSSalBitmap); + convertToWinSalBitmap(rConstBitmap, *pWinSalBitmap.get()); + + std::unique_ptr<WinSalBitmap> pWinTransparentSalBitmap(new WinSalBitmap()); + SalBitmap& rConstTransparentBitmap = const_cast<SalBitmap&>(rSTransparentBitmap); + convertToWinSalBitmap(rConstTransparentBitmap, *pWinTransparentSalBitmap.get()); + + mpImpl->drawBitmap(rPosAry, *pWinSalBitmap.get(), *pWinTransparentSalBitmap.get()); + } + else + { + mpImpl->drawBitmap(rPosAry, rSSalBitmap, rSTransparentBitmap); + } } bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, |