summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.com>2015-12-10 13:41:36 +0100
committerCaolán McNamara <caolanm@redhat.com>2015-12-14 11:10:43 +0000
commitf625f1e1ff3b557fbe16c281baaf35fdb48eb048 (patch)
treefc63fcda7e7ba6d4e9cc4a90354b43f04e375f2f
parentfabfd88b11bb6253e9631664d9adb47c119f9e7d (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.cxx109
-rw-r--r--vcl/win/source/gdi/salgdi2.cxx72
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,