diff options
author | Caolán McNamara <caolanm@redhat.com> | 2016-01-13 09:52:42 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2016-01-18 11:34:08 +0000 |
commit | dd0a16bb6b2a674b60a2f7e55307c2800ad4c427 (patch) | |
tree | a3eec378e06764ad71c0680c4902186f74e7fdec /vcl/headless | |
parent | 828b117624724647abea4f353343887747043390 (diff) |
svp: vcl and cairo have a difference of opinion on fg/bg of 1bit masks
Change-Id: I3702e5a1ba0e64868f7f537aaa6040449bd82e8b
Diffstat (limited to 'vcl/headless')
-rw-r--r-- | vcl/headless/svpgdi.cxx | 81 |
1 files changed, 62 insertions, 19 deletions
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 7f068f049469..d90024e08982 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -146,14 +146,6 @@ bool SvpSalGraphics::blendAlphaBitmap( const SalTwoRect&, const SalBitmap&, cons namespace { - unsigned char reverseAndInvert(unsigned char b) - { - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - return ~b; - } - class SourceHelper { public: @@ -226,16 +218,17 @@ namespace } else { - // the alpha values need to be inverted *and* reordered for Cairo - // so big stupid copy and reverse + invert here + // the alpha values need to be inverted for Cairo + // so big stupid copy and invert here const int nImageSize = size.getY() * nStride; const unsigned char* pSrcBits = data.get(); pAlphaBits = new unsigned char[nImageSize]; memcpy(pAlphaBits, pSrcBits, nImageSize); + // TODO: make upper layers use standard alpha unsigned char* pDst = pAlphaBits; for (int i = nImageSize; --i >= 0; ++pDst) - *pDst = reverseAndInvert(*pDst); + *pDst = ~*pDst; mask = cairo_image_surface_create_for_data(pAlphaBits, CAIRO_FORMAT_A1, @@ -747,7 +740,7 @@ void SvpSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) m_bUseLineColor = false; m_bUseFillColor = true; m_aFillColor = basebmp::Color(nSalColor); - drawPolyPolygon(basegfx::B2DPolyPolygon(aRect), 0.0); + drawPolyPolygon(basegfx::B2DPolyPolygon(aRect)); m_bUseFillColor = bOrigUseFillColor; m_bUseLineColor = bOrigUseLineColor; @@ -776,7 +769,7 @@ void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) { basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect(basegfx::B2DRectangle(nX, nY, nX+nWidth, nY+nHeight)); m_bUseFillColor = true; - drawPolyPolygon(basegfx::B2DPolyPolygon(aRect), 0.0); + drawPolyPolygon(basegfx::B2DPolyPolygon(aRect)); m_bUseFillColor = false; } @@ -785,7 +778,7 @@ void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) // need same -1 hack as X11SalGraphicsImpl::drawRect basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect(basegfx::B2DRectangle( nX, nY, nX+nWidth-1, nY+nHeight-1)); m_bUseLineColor = true; - drawPolyPolygon(basegfx::B2DPolyPolygon(aRect), 0.0); + drawPolyPolygon(basegfx::B2DPolyPolygon(aRect)); m_bUseLineColor = false; } @@ -812,7 +805,7 @@ void SvpSalGraphics::drawPolygon(sal_uInt32 nPoints, const SalPoint* pPtAry) for (sal_uInt32 i = 1; i < nPoints; ++i) aPoly.setB2DPoint(i, basegfx::B2DPoint(pPtAry[i].mnX, pPtAry[i].mnY)); - drawPolyPolygon(basegfx::B2DPolyPolygon(aPoly), 0.0); + drawPolyPolygon(basegfx::B2DPolyPolygon(aPoly)); } void SvpSalGraphics::drawPolyPolygon(sal_uInt32 nPoly, @@ -835,7 +828,7 @@ void SvpSalGraphics::drawPolyPolygon(sal_uInt32 nPoly, } } - drawPolyPolygon(aPolyPoly, 0.0); + drawPolyPolygon(aPolyPoly); } static const basegfx::B2DPoint aHalfPointOfs(0.5, 0.5); @@ -1041,14 +1034,20 @@ bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32, return false; } -bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency) +void SvpSalGraphics::setupPolyPolygon(cairo_t* cr, const basegfx::B2DPolyPolygon& rPolyPoly) { - cairo_t* cr = getCairoContext(true); - assert(cr && m_aDevice->isTopDown()); clipRegion(cr); for (const basegfx::B2DPolygon* pPoly = rPolyPoly.begin(); pPoly != rPolyPoly.end(); ++pPoly) AddPolygonToPath(cr, *pPoly, true, !getAntiAliasB2DDraw(), m_bUseLineColor); +} + +bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency) +{ + cairo_t* cr = getCairoContext(true); + assert(cr && m_aDevice->isTopDown()); + + setupPolyPolygon(cr, rPolyPoly); cairo_rectangle_int_t extents = {0, 0, 0, 0}; @@ -1082,6 +1081,50 @@ bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, d return true; } +void SvpSalGraphics::applyColor(cairo_t *cr, const basebmp::Color &rColor) +{ + if (CAIRO_FORMAT_ARGB32 == getCairoFormat(m_aOrigDevice)) + { + cairo_set_source_rgba(cr, rColor.getRed()/255.0, + rColor.getGreen()/255.0, + rColor.getBlue()/255.0, + 1.0); + } + else + { + double fSet = rColor.toInt32() == COL_BLACK ? 0.0 : 1.0; + cairo_set_source_rgba(cr, 1, 1, 1, fSet); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + } +} + +void SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly) +{ + cairo_t* cr = getCairoContext(true); + assert(cr && m_aDevice->isTopDown()); + + setupPolyPolygon(cr, rPolyPoly); + + cairo_rectangle_int_t extents = {0, 0, 0, 0}; + + if (m_bUseFillColor) + { + applyColor(cr, m_aFillColor); + if (!m_bUseLineColor) + extents = getFillDamage(cr); + cairo_fill_preserve(cr); + } + + if (m_bUseLineColor) + { + applyColor(cr, m_aLineColor); + extents = getStrokeDamage(cr); + cairo_stroke_preserve(cr); + } + + releaseCairoContext(cr, true, extents); +} + void SvpSalGraphics::copyArea( long nDestX, long nDestY, long nSrcX, |