diff options
author | Armin Le Grand <Armin.Le.Grand@cib.de> | 2018-09-06 18:15:02 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@cib.de> | 2018-09-13 08:49:35 +0200 |
commit | 7034311dce663c895577267110baadbec312d491 (patch) | |
tree | 8c1d712cbfb1b15dc492e6e724b6b22892914249 /vcl/headless | |
parent | d92b0efe58b77247e1e5292c1a989baa934df797 (diff) |
Support buffering SystemDependent GraphicData (II)
In this step I have changed all calls that use a
B2DPolyPolygon and do filled graphics, added support for
providing needed transformation which will -if supported-
be used. Added buffering of SystemDependentData at
B2DPolyPolygon for that purpose, see comments describing
the current possibilities in the Gdiplus implementation.
Moved lifetime creation/cleanup of SystemDependentDataManager
to ImplSVData due to cleanup problems in the clang build
Tried to use a std::unique_ptr to hold the instance
of a SystemDependentDataBuffer at ImplSVData and cleanup
inside DeInitVCL() right before ::ImplDeInitScheduler. This
works in principle, but scheduler shutdown triggers
ProcessEventsToIdle which leads to repaints and re-creates
the buffer. Will now do exactly as was done with GdiPlusBuffer
before, a simple local static incarnation and a call to
SetStatic() in constructor
Splitted SystemDependentDataBuffer and Timer due to
different LifeTimes. Timer needs to be destructed
earlier than SystemDependentDataBuffer, before
Scheduler::ImplDeInitScheduler() is called from
DeInitVCL()
Change-Id: I2134e4346a183a4cee1be3428c51541cc8867c11
Reviewed-on: https://gerrit.libreoffice.org/60102
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Diffstat (limited to 'vcl/headless')
-rw-r--r-- | vcl/headless/svpgdi.cxx | 152 |
1 files changed, 79 insertions, 73 deletions
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 5acd288e8787..56bd740dbe40 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -714,7 +714,10 @@ void SvpSalGraphics::drawPixel( long nX, long nY, Color nColor ) m_aLineColor = SALCOLOR_NONE; m_aFillColor = nColor; - drawPolyPolygon(basegfx::B2DPolyPolygon(aRect)); + drawPolyPolygon( + basegfx::B2DHomMatrix(), + basegfx::B2DPolyPolygon(aRect), + 0.0); m_aFillColor = aOrigFillColor; m_aLineColor = aOrigLineColor; @@ -732,7 +735,12 @@ void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) { basegfx::B2DPolygon aRect = basegfx::utils::createPolygonFromRect(basegfx::B2DRectangle(nX, nY, nX+nWidth, nY+nHeight)); m_aFillColor = aOrigFillColor; - drawPolyPolygon(basegfx::B2DPolyPolygon(aRect)); + + drawPolyPolygon( + basegfx::B2DHomMatrix(), + basegfx::B2DPolyPolygon(aRect), + 0.0); + m_aFillColor = SALCOLOR_NONE; } @@ -741,7 +749,12 @@ void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) // need same -1 hack as X11SalGraphicsImpl::drawRect basegfx::B2DPolygon aRect = basegfx::utils::createPolygonFromRect(basegfx::B2DRectangle( nX, nY, nX+nWidth-1, nY+nHeight-1)); m_aLineColor = aOrigLineColor; - drawPolyPolygon(basegfx::B2DPolyPolygon(aRect)); + + drawPolyPolygon( + basegfx::B2DHomMatrix(), + basegfx::B2DPolyPolygon(aRect), + 0.0); + m_aLineColor = SALCOLOR_NONE; } @@ -775,7 +788,10 @@ 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)); + drawPolyPolygon( + basegfx::B2DHomMatrix(), + basegfx::B2DPolyPolygon(aPoly), + 0.0); } void SvpSalGraphics::drawPolyPolygon(sal_uInt32 nPoly, @@ -798,7 +814,10 @@ void SvpSalGraphics::drawPolyPolygon(sal_uInt32 nPoly, } } - drawPolyPolygon(aPolyPoly); + drawPolyPolygon( + basegfx::B2DHomMatrix(), + aPolyPoly, + 0.0); } basegfx::B2DPoint impPixelSnap( @@ -1061,7 +1080,7 @@ bool SvpSalGraphics::drawPolyLine( bool bPixelSnapHairline) { // short circuit if there is nothing to do - if(0 == rPolyLine.count()) + if(0 == rPolyLine.count() || fTransparency < 0.0 || fTransparency >= 1.0) { return true; } @@ -1111,7 +1130,7 @@ bool SvpSalGraphics::drawPolyLine( bool bPixelSnapHairline) { // short circuit if there is nothing to do - if(0 == rPolyLine.count()) + if(0 == rPolyLine.count() || fTransparency < 0.0 || fTransparency >= 1.0) { return true; } @@ -1283,7 +1302,7 @@ bool SvpSalGraphics::drawPolyLine( // copy and add to buffering mechanism pSystemDependentData_CairoPath = rPolyLine.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>( - SalGraphics::getSystemDependentDataManager(), + ImplGetSystemDependentDataManager(), cairo_copy_path(cr)); // fill data of buffered data @@ -1337,36 +1356,68 @@ bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32, return false; } -void SvpSalGraphics::setupPolyPolygon(cairo_t* cr, const basegfx::B2DPolyPolygon& rPolyPoly) -{ - clipRegion(cr); - - for (const auto & rPoly : rPolyPoly) - { - // PixelOffset used: Was dependent of 'm_aLineColor != SALCOLOR_NONE' - // Adapt setupPolyPolygon-users to set a linear transformation to achieve PixelOffset - AddPolygonToPath( - cr, - rPoly, - basegfx::B2DHomMatrix(), - !getAntiAliasB2DDraw(), - false); - } -} - -bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency) +bool SvpSalGraphics::drawPolyPolygon( + const basegfx::B2DHomMatrix& rObjectToDevice, + const basegfx::B2DPolyPolygon& rPolyPolygon, + double fTransparency) { const bool bHasFill(m_aFillColor != SALCOLOR_NONE); const bool bHasLine(m_aLineColor != SALCOLOR_NONE); - if(0 == rPolyPoly.count() || !(bHasFill || bHasLine)) + if(0 == rPolyPolygon.count() || !(bHasFill || bHasLine) || fTransparency < 0.0 || fTransparency >= 1.0) { return true; } cairo_t* cr = getCairoContext(true); + clipRegion(cr); + + // Set full (Object-to-Device) transformation - if used + if(!rObjectToDevice.isIdentity()) + { + cairo_matrix_t aMatrix; + + cairo_matrix_init( + &aMatrix, + rObjectToDevice.get( 0, 0 ), + rObjectToDevice.get( 1, 0 ), + rObjectToDevice.get( 0, 1 ), + rObjectToDevice.get( 1, 1 ), + rObjectToDevice.get( 0, 2 ), + rObjectToDevice.get( 1, 2 )); + cairo_set_matrix(cr, &aMatrix); + } - setupPolyPolygon(cr, rPolyPoly); + // try to access buffered data + std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath( + rPolyPolygon.getSystemDependentData<SystemDependentData_CairoPath>()); + + if(pSystemDependentData_CairoPath) + { + // re-use data + cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath()); + } + else + { + // create data + for (const auto & rPoly : rPolyPolygon) + { + // PixelOffset used: Was dependent of 'm_aLineColor != SALCOLOR_NONE' + // Adapt setupPolyPolygon-users to set a linear transformation to achieve PixelOffset + AddPolygonToPath( + cr, + rPoly, + rObjectToDevice, + !getAntiAliasB2DDraw(), + false); + } + + // copy and add to buffering mechanism + // for decisions how/what to buffer, see Note in WinSalGraphicsImpl::drawPolyPolygon + pSystemDependentData_CairoPath = rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>( + ImplGetSystemDependentDataManager(), + cairo_copy_path(cr)); + } // To make releaseCairoContext work, use empty extents basegfx::B2DRange extents; @@ -1426,51 +1477,6 @@ void SvpSalGraphics::applyColor(cairo_t *cr, Color aColor) } } -void SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly) -{ - const bool bHasFill(m_aFillColor != SALCOLOR_NONE); - const bool bHasLine(m_aLineColor != SALCOLOR_NONE); - - if(0 == rPolyPoly.count() || !(bHasFill || bHasLine)) - { - return; - } - - cairo_t* cr = getCairoContext(true); - - setupPolyPolygon(cr, rPolyPoly); - - // To make releaseCairoContext work, use empty extents - basegfx::B2DRange extents; - - if (bHasFill) - { - applyColor(cr, m_aFillColor); - - // Get FillDamage (will be extended for LineDamage below) - extents = getClippedFillDamage(cr); - - cairo_fill_preserve(cr); - } - - if (bHasLine) - { - // PixelOffset used: Set PixelOffset as linear transformation - cairo_matrix_t aMatrix; - cairo_matrix_init_translate(&aMatrix, 0.5, 0.5); - cairo_set_matrix(cr, &aMatrix); - - applyColor(cr, m_aLineColor); - - // expand with possible StrokeDamage - extents.expand(getClippedStrokeDamage(cr)); - - cairo_stroke_preserve(cr); - } - - releaseCairoContext(cr, true, extents); -} - void SvpSalGraphics::copyArea( long nDestX, long nDestY, long nSrcX, |