diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-10 23:30:02 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2014-11-11 11:08:25 +0100 |
commit | 14a1d4da2f49c92caaccfae9cab6940ac6e672a5 (patch) | |
tree | be4d83e77cfa75e6291dfbbd8c9550bdb341ee63 | |
parent | 0f839d5ba9e2cc1e9958c46b901c831b01a7d93d (diff) |
vcl: Fix text rendering with OpenGL
Change-Id: I7784fa81cb6f9a3d6437b2b628c37e7895c84733
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/salgdiimpl.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/unx/salgdi.h | 4 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 17 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.cxx | 6 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.hxx | 4 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/openglx11cairotextrender.cxx | 53 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi2.cxx | 6 | ||||
-rw-r--r-- | vcl/win/source/gdi/gdiimpl.hxx | 5 |
9 files changed, 96 insertions, 9 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index e9be6653dca0..6f920e515ee0 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -243,6 +243,11 @@ public: const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + /** Render 32-bits bitmap with alpha channel */ + virtual bool drawAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ virtual bool drawTransformedBitmap( const basegfx::B2DPoint& rNull, diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index 5d4995201274..4b4b7353df98 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -181,6 +181,11 @@ public: const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) = 0; + /** Render 32-bits bitmap with alpha channel */ + virtual bool drawAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) = 0; + /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ virtual bool drawTransformedBitmap( const basegfx::B2DPoint& rNull, diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index 8a5cc0c43bae..2546689b3618 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -251,6 +251,10 @@ public: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + + virtual bool drawAlphaBitmap( const SalTwoRect&, + const SalBitmap& rBitmap ); + virtual bool drawTransformedBitmap( const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 80a5414978b5..e9aaa669f270 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -1025,6 +1025,23 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap( return true; } +bool OpenGLSalGraphicsImpl::drawAlphaBitmap( + const SalTwoRect& rPosAry, + const SalBitmap& rSalBitmap ) +{ + const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); + const GLuint nTexture( rBitmap.GetTexture( maContext ) ); + + SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" ); + PreDraw(); + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + DrawTexture( nTexture, rBitmap.GetSize(), rPosAry ); + glDisable( GL_BLEND ); + PostDraw(); + return true; +} + /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ bool OpenGLSalGraphicsImpl::drawTransformedBitmap( const basegfx::B2DPoint& /*rNull*/, diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index efe66d8fe3d3..4adea6259f46 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -955,6 +955,12 @@ bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR, return true; } +bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& /*rTR*/, + const SalBitmap& /*rBitmap*/ ) +{ + return false; +} + bool X11SalGraphicsImpl::drawTransformedBitmap( const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index 91592eb6bfd5..5b0062c93949 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -242,6 +242,10 @@ public: const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + virtual bool drawAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE; + /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ virtual bool drawTransformedBitmap( const basegfx::B2DPoint& rNull, diff --git a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx index 9b7c49ed450f..36a76b06c6ee 100644 --- a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx +++ b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx @@ -24,26 +24,61 @@ cairo_surface_t* OpenGLX11CairoTextRender::getCairoSurface() // static size_t id = 0; // OString aFileName = OString("/tmp/libo_logs/text_rendering") + OString::number(id++) + OString(".svg"); // cairo_surface_t* surface = cairo_svg_surface_create(aFileName.getStr(), GetWidth(), GetHeight()); - cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, GetWidth(), GetHeight()); + cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, GetWidth(), GetHeight()); return surface; } void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr) { - cairo_surface_t* surface = cairo_get_target(cr); - int width = cairo_image_surface_get_width(surface); - int height = cairo_image_surface_get_height(surface); + cairo_surface_t* pSurface = cairo_get_target(cr); + int nWidth = cairo_image_surface_get_width( pSurface ); + int nHeight = cairo_image_surface_get_height( pSurface ); SalBitmap* pBitmap = ImplGetSVData()->mpDefInst->CreateSalBitmap(); - pBitmap->Create(Size(width, height), 24, BitmapPalette()); + pBitmap->Create(Size(nWidth, nHeight), 32, BitmapPalette()); + + cairo_surface_flush( pSurface ); BitmapBuffer* pBuffer = pBitmap->AcquireBuffer(false); - std::memcpy(pBuffer->mpBits, cairo_image_surface_get_data(surface), width*height*3); + unsigned char *pSrc = cairo_image_surface_get_data( pSurface ); + unsigned int nSrcStride = cairo_image_surface_get_stride( pSurface ); + unsigned int nDestStride = pBuffer->mnScanlineSize; + for( unsigned long y = 0; y < (unsigned long) nHeight; y++ ) + { + // Cairo surface is y-inverse + sal_uInt32 *pSrcPix = (sal_uInt32 *)(pSrc + nSrcStride * (nHeight - y - 1)); + sal_uInt32 *pDestPix = (sal_uInt32 *)(pBuffer->mpBits + nDestStride * y); + for( unsigned long x = 0; x < (unsigned long) nWidth; x++ ) + { + sal_uInt8 nAlpha = (*pSrcPix >> 24); + sal_uInt8 nR = (*pSrcPix >> 16) & 0xff; + sal_uInt8 nG = (*pSrcPix >> 8) & 0xff; + sal_uInt8 nB = *pSrcPix & 0xff; + if( nAlpha != 0 && nAlpha != 255 ) + { + // Cairo uses pre-multiplied alpha - we do not => re-multiply + nR = (sal_uInt8) MinMax( ((sal_uInt32)nR * 255) / nAlpha, 0, 255 ); + nG = (sal_uInt8) MinMax( ((sal_uInt32)nG * 255) / nAlpha, 0, 255 ); + nB = (sal_uInt8) MinMax( ((sal_uInt32)nB * 255) / nAlpha, 0, 255 ); + } + + // FIXME: lfrb: depends on endianness (use BitmapWriteAccess) + *pDestPix = (nAlpha << 24) + (nB << 16) + (nG << 8) + nR; + pSrcPix++; + pDestPix++; + } + } pBitmap->ReleaseBuffer(pBuffer, false); + SalTwoRect aRect; aRect.mnSrcX = 0; aRect.mnSrcY = 0; - aRect.mnSrcWidth = width; - aRect.mnSrcHeight = height; - mrParent.drawBitmap(aRect, *pBitmap); + aRect.mnSrcWidth = nWidth; + aRect.mnSrcHeight = nHeight; + aRect.mnDestX = 0; + aRect.mnDestY = 0; + aRect.mnDestWidth = nWidth; + aRect.mnDestHeight = nHeight; + + mrParent.drawAlphaBitmap(aRect, *pBitmap); delete pBitmap; } diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx index 63ab32b8981d..fe7199c16ffb 100644 --- a/vcl/unx/generic/gdi/salgdi2.cxx +++ b/vcl/unx/generic/gdi/salgdi2.cxx @@ -185,6 +185,12 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, return mpImpl->drawAlphaBitmap( rTR, rSrcBitmap, rAlphaBmp ); } +bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, + const SalBitmap& rBitmap ) +{ + return mpImpl->drawAlphaBitmap( rTR, rBitmap ); +} + bool X11SalGraphics::drawTransformedBitmap( const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, diff --git a/vcl/win/source/gdi/gdiimpl.hxx b/vcl/win/source/gdi/gdiimpl.hxx index 2a0780f21738..0159f7c831a1 100644 --- a/vcl/win/source/gdi/gdiimpl.hxx +++ b/vcl/win/source/gdi/gdiimpl.hxx @@ -189,6 +189,11 @@ public: const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE; + /** Render 32-bits bitmap with alpha channel */ + virtual bool drawAlphaBitmap( + const SalTwoRect&, + const SalBitmap& rBitmap ) SAL_OVERRIDE {return false;} + /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ virtual bool drawTransformedBitmap( const basegfx::B2DPoint& rNull, |