diff options
author | Caolán McNamara <caolanm@redhat.com> | 2016-01-16 20:41:51 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2016-01-18 11:34:09 +0000 |
commit | dc01e9db6fc6126b8f21bcbeb6145daf2c8941bf (patch) | |
tree | 38abebd5b795525b0b0d3fdbbdf5610b4208c730 /vcl/headless | |
parent | 4ce66db6ac8a18c34011fa0bd3198752a0867d24 (diff) |
svp: implement drawMask via cairo
Change-Id: Iafb49b4258ffeab98cdf07a175ee7234e106e04c
Diffstat (limited to 'vcl/headless')
-rw-r--r-- | vcl/headless/svpgdi.cxx | 111 |
1 files changed, 70 insertions, 41 deletions
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 2b0a7f2660ad..43b3853a5cdd 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -1039,37 +1039,76 @@ void SvpSalGraphics::drawBitmap( const SalTwoRect& rTR, drawAlphaBitmap(rTR, rSourceBitmap, rTransparentBitmap); } -void SvpSalGraphics::drawMask( const SalTwoRect& /*rPosAry*/, - const SalBitmap& /*rSalBitmap*/, - SalColor /*nMaskColor*/ ) -{ -#if 0 - const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); - basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, - rPosAry.mnSrcX+rPosAry.mnSrcWidth, - rPosAry.mnSrcY+rPosAry.mnSrcHeight ); - basegfx::B2IPoint aDestPoint( rPosAry.mnDestX, rPosAry.mnDestY ); - - // BitmapDevice::drawMaskedColor works with 0==transparent, - // 255==opaque. drawMask() semantic is the other way - // around. Therefore, invert mask. - basebmp::BitmapDeviceSharedPtr aCopy = - cloneBitmapDevice( basegfx::B2IVector( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ), - rSrc.getBitmap() ); - basebmp::Color aBgColor( COL_WHITE ); - aCopy->clear(aBgColor); - basebmp::Color aFgColor( COL_BLACK ); - aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, basegfx::B2IPoint() ); - - basebmp::Color aColor( nMaskColor ); - basegfx::B2IBox aSrcRect2( 0, 0, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ); - const basegfx::B2IBox aClipRect( aDestPoint, basegfx::B2ITuple( aSrcRect.getWidth(), aSrcRect.getHeight() ) ); - - SvpSalGraphics::ClipUndoHandle aUndo( this ); - if( !isClippedSetup( aClipRect, aUndo ) ) - m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap ); - dbgOut( m_aDevice ); -#endif +static sal_uInt8 unpremultiply(sal_uInt8 c, sal_uInt8 a) +{ + return (a > 0) ? (c * 255 + a / 2) / a : 0; +} + +static sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a) +{ + return (c * a + 127) / 255; +} + +void SvpSalGraphics::drawMask( const SalTwoRect& rTR, + const SalBitmap& rSalBitmap, + SalColor nMaskColor ) +{ + /** creates an image from the given rectangle, replacing all black pixels + * with nMaskColor and make all other full transparent */ + SourceHelper aSurface(rSalBitmap); + cairo_surface_t* mask = aSurface.getSurface(); + + cairo_surface_flush(mask); + + unsigned char *mask_data = cairo_image_surface_get_data(mask); + + cairo_format_t nFormat = cairo_image_surface_get_format(mask); + assert(nFormat == CAIRO_FORMAT_ARGB32 && "need to implement CAIRO_FORMAT_A1 after all here"); + sal_Int32 nStride = cairo_format_stride_for_width(nFormat, + cairo_image_surface_get_width(mask)); + for (sal_Int32 y = rTR.mnSrcY ; y < rTR.mnSrcY + rTR.mnSrcHeight; ++y) + { + unsigned char *row = mask_data + (nStride*y); + unsigned char *data = row + (rTR.mnSrcX * 4); + for (sal_Int32 x = rTR.mnSrcX; x < rTR.mnSrcX + rTR.mnSrcWidth; ++x) + { + sal_uInt8 b = unpremultiply(data[0], data[3]); + sal_uInt8 g = unpremultiply(data[1], data[3]); + sal_uInt8 r = unpremultiply(data[2], data[3]); + if (r == 0 && g == 0 && b == 0) + { + data[0] = SALCOLOR_BLUE(nMaskColor); + data[1] = SALCOLOR_GREEN(nMaskColor); + data[2] = SALCOLOR_RED(nMaskColor); + data[3] = 0xff; + } + else + { + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + } + data+=4; + } + } + cairo_surface_mark_dirty(mask); + + cairo_t* cr = getCairoContext(false); + clipRegion(cr); + + cairo_rectangle(cr, rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight); + + cairo_rectangle_int_t extents = getFillDamage(cr); + + cairo_clip(cr); + + cairo_translate(cr, rTR.mnDestX, rTR.mnDestY); + cairo_scale(cr, (double)(rTR.mnDestWidth)/rTR.mnSrcWidth, ((double)rTR.mnDestHeight)/rTR.mnSrcHeight); + cairo_set_source_surface(cr, mask, -rTR.mnSrcX, -rTR.mnSrcY); + cairo_paint(cr); + + releaseCairoContext(cr, false, extents); } SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeight ) @@ -1092,16 +1131,6 @@ SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeigh return pBitmap; } -static sal_uInt8 unpremultiply(sal_uInt8 c, sal_uInt8 a) -{ - return (a > 0) ? (c * 255 + a / 2) / a : 0; -} - -static sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a) -{ - return (c * a + 127) / 255; -} - SalColor SvpSalGraphics::getPixel( long nX, long nY ) { cairo_surface_flush(m_pSurface); |