summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2016-01-14 20:49:06 +0000
committerCaolán McNamara <caolanm@redhat.com>2016-01-18 11:34:09 +0000
commit4bf6f5581c9938504b841eb94f6121068b2eb752 (patch)
tree572ef155cd3307fcca30e6388bd3f685f781a3cf
parent7d8e94aaaddff0708dd8a5a6fde4d9922cd4e1ea (diff)
svp: replace basebmp surfaces with native cairo surfaces
so we can then a) drop all of our own clipping code in favour of cairos clipping code b) just pass cairo surfaces around the place instead of constantly creating and tearing down surfaces based on basebmp data c) we can additionally drop various flushing of the surfaces as it doesn't matter anymore d) use a lot less of our own code and far more of some one elses hopefully more drawing optimized code e) seeing as the graphics context are always cairo now, then they are always cairo compatible, so those checks can go also still need to figure out drawMask Change-Id: I320cd14cdc714ea59d00e90233f1171f821cf953
-rw-r--r--vcl/headless/svpframe.cxx57
-rw-r--r--vcl/headless/svpgdi.cxx361
-rw-r--r--vcl/headless/svpinst.cxx4
-rw-r--r--vcl/headless/svpvd.cxx50
-rw-r--r--vcl/inc/headless/svpframe.hxx14
-rw-r--r--vcl/inc/headless/svpgdi.hxx33
-rw-r--r--vcl/inc/headless/svpvd.hxx13
-rw-r--r--vcl/inc/unx/gtk/gtkframe.hxx11
-rw-r--r--vcl/unx/gtk3/gtk3gtkframe.cxx107
-rw-r--r--vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx3
10 files changed, 210 insertions, 443 deletions
diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx
index 609db130fcaf..952f0ab7d143 100644
--- a/vcl/headless/svpframe.cxx
+++ b/vcl/headless/svpframe.cxx
@@ -28,6 +28,8 @@
#include <basebmp/scanlineformats.hxx>
#include <basegfx/vector/b2ivector.hxx>
+#include <cairo.h>
+
using namespace basebmp;
using namespace basegfx;
@@ -37,48 +39,15 @@ SvpSalFrame* SvpSalFrame::s_pFocusFrame = nullptr;
#define SvpSalGraphics AquaSalGraphics
#endif
-#ifndef IOS
-namespace {
- /// Decouple SalFrame lifetime from damagetracker lifetime
- struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker
- {
- virtual ~DamageTracker() {}
- virtual void damaged( const basegfx::B2IBox& ) const override {}
- };
-}
-#endif
-
-#ifdef ANDROID
-void SvpSalFrame::enableDamageTracker( bool bOn )
-{
- if( m_bDamageTracking == bOn )
- return;
- if( m_aFrame.get() )
- {
- if( m_bDamageTracking )
- m_aFrame->setDamageTracker( basebmp::IBitmapDeviceDamageTrackerSharedPtr() );
- else
- m_aFrame->setDamageTracker(
- basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker ) );
- }
- m_bDamageTracking = bOn;
-}
-#endif
-
-
SvpSalFrame::SvpSalFrame( SvpSalInstance* pInstance,
SalFrame* pParent,
SalFrameStyleFlags nSalFrameStyle,
- basebmp::Format nScanlineFormat,
SystemParentData* ) :
m_pInstance( pInstance ),
m_pParent( static_cast<SvpSalFrame*>(pParent) ),
m_nStyle( nSalFrameStyle ),
m_bVisible( false ),
-#ifndef IOS
- m_bDamageTracking( false ),
- m_nScanlineFormat( nScanlineFormat ),
-#endif
+ m_pSurface( nullptr ),
m_nMinWidth( 0 ),
m_nMinHeight( 0 ),
m_nMaxWidth( 0 ),
@@ -145,6 +114,8 @@ SvpSalFrame::~SvpSalFrame()
}
}
}
+ if (m_pSurface)
+ cairo_surface_destroy(m_pSurface);
}
void SvpSalFrame::GetFocus()
@@ -176,7 +147,7 @@ SalGraphics* SvpSalFrame::AcquireGraphics()
{
SvpSalGraphics* pGraphics = new SvpSalGraphics();
#ifndef IOS
- pGraphics->setDevice( m_aFrame );
+ pGraphics->setSurface( m_pSurface );
#endif
m_aGraphics.push_back( pGraphics );
return pGraphics;
@@ -284,21 +255,25 @@ void SvpSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_u
}
#ifndef IOS
B2IVector aFrameSize( maGeometry.nWidth, maGeometry.nHeight );
- if( ! m_aFrame.get() || m_aFrame->getSize() != aFrameSize )
+ if (!m_pSurface || cairo_image_surface_get_width(m_pSurface) != aFrameSize.getX() ||
+ cairo_image_surface_get_height(m_pSurface) != aFrameSize.getY() )
{
if( aFrameSize.getX() == 0 )
aFrameSize.setX( 1 );
if( aFrameSize.getY() == 0 )
aFrameSize.setY( 1 );
- m_aFrame = createBitmapDevice( aFrameSize, true, m_nScanlineFormat );
- if (m_bDamageTracking)
- m_aFrame->setDamageTracker(
- basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker ) );
+
+ if (m_pSurface)
+ cairo_surface_destroy(m_pSurface);
+ m_pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ aFrameSize.getX(),
+ aFrameSize.getY());
+
// update device in existing graphics
for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin();
it != m_aGraphics.end(); ++it )
{
- (*it)->setDevice( m_aFrame );
+ (*it)->setSurface(m_pSurface);
}
}
if( m_bVisible )
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 30b319440069..2b0a7f2660ad 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -19,6 +19,7 @@
#include "headless/svpgdi.hxx"
#include "headless/svpbmp.hxx"
+#include "headless/svpframe.hxx"
#ifndef IOS
#include "headless/svpcairotextrender.hxx"
#endif
@@ -276,7 +277,6 @@ bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rS
}
cairo_t* cr = getCairoContext(false);
- assert(cr && m_aDevice->isTopDown());
clipRegion(cr);
cairo_rectangle(cr, rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight);
@@ -332,7 +332,6 @@ bool SvpSalGraphics::drawTransformedBitmap(
const Size aSize = rSourceBitmap.GetSize();
cairo_t* cr = getCairoContext(false);
- assert(cr && m_aDevice->isTopDown());
clipRegion(cr);
// setup the image transformation
@@ -362,34 +361,6 @@ bool SvpSalGraphics::drawTransformedBitmap(
return true;
}
-namespace
-{
- cairo_format_t getCairoFormat(const basebmp::BitmapDeviceSharedPtr &rBuffer)
- {
- cairo_format_t nFormat;
- if (rBuffer->getScanlineFormat() == SVP_CAIRO_FORMAT)
- nFormat = CAIRO_FORMAT_ARGB32;
- else
- nFormat = CAIRO_FORMAT_A1;
- return nFormat;
- }
-
- bool isCairoCompatible(const basebmp::BitmapDeviceSharedPtr &rBuffer)
- {
- if (!rBuffer)
- return false;
-
- if (rBuffer->getScanlineFormat() != SVP_CAIRO_FORMAT &&
- rBuffer->getScanlineFormat() != basebmp::Format::OneBitMsbPal)
- return false;
-
- basegfx::B2IVector size = rBuffer->getSize();
- sal_Int32 nStride = rBuffer->getScanlineStride();
- cairo_format_t nFormat = getCairoFormat(rBuffer);
- return (cairo_format_stride_for_width(nFormat, size.getX()) == nStride);
- }
-}
-
#endif
void SvpSalGraphics::clipRegion(cairo_t* cr)
@@ -412,7 +383,6 @@ void SvpSalGraphics::clipRegion(cairo_t* cr)
bool SvpSalGraphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency)
{
cairo_t* cr = getCairoContext(false);
- assert(cr && m_aDevice->isTopDown());
clipRegion(cr);
const double fTransparency = (100 - nTransparency) * (1.0/100);
@@ -452,12 +422,12 @@ bool SvpSalGraphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight,
}
SvpSalGraphics::SvpSalGraphics() :
+ m_pSurface( nullptr ),
m_bUseLineColor( true ),
m_aLineColor( COL_BLACK ),
m_bUseFillColor( false ),
m_aFillColor( COL_WHITE ),
m_ePaintMode( OVERPAINT ),
- m_bClipSetup( false ),
m_aTextRenderImpl(*this)
{
}
@@ -466,9 +436,9 @@ SvpSalGraphics::~SvpSalGraphics()
{
}
-void SvpSalGraphics::setDevice( basebmp::BitmapDeviceSharedPtr& rDevice )
+void SvpSalGraphics::setSurface(cairo_surface_t* pSurface)
{
- m_aOrigDevice = rDevice;
+ m_pSurface = pSurface;
ResetClipRegion();
}
@@ -481,183 +451,24 @@ void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
sal_uInt16 SvpSalGraphics::GetBitCount() const
{
- return SvpSalBitmap::getBitCountFromScanlineFormat( m_aDevice->getScanlineFormat() );
+ if (CAIRO_FORMAT_A1 == cairo_image_surface_get_format(m_pSurface))
+ return 1;
+ return 32;
}
long SvpSalGraphics::GetGraphicsWidth() const
{
- if( m_aDevice.get() )
- {
- basegfx::B2IVector aSize = m_aOrigDevice->getSize();
- return aSize.getX();
- }
- return 0;
+ return m_pSurface ? cairo_image_surface_get_width(m_pSurface) : 0;
}
void SvpSalGraphics::ResetClipRegion()
{
- m_aDevice = m_aOrigDevice;
- m_aClipMap.reset();
- m_bClipSetup = true;
m_aClipRegion.SetNull();
}
-// verify clip for the whole area is setup
-void SvpSalGraphics::ensureClip()
-{
- if (m_bClipSetup)
- return;
-
- m_aDevice = m_aOrigDevice;
- basegfx::B2IVector aSize = m_aDevice->getSize();
- m_aClipMap = basebmp::createClipDevice( aSize );
-
- RectangleVector aRectangles;
- m_aClipRegion.GetRegionRectangles(aRectangles);
-
- for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
- {
- const long nW(aRectIter->GetWidth());
- if(nW)
- {
- const long nH(aRectIter->GetHeight());
-
- if(nH)
- {
- basegfx::B2DPolyPolygon aFull;
-
- aFull.append(
- basegfx::tools::createPolygonFromRect(
- basegfx::B2DRectangle(
- aRectIter->Left(),
- aRectIter->Top(),
- aRectIter->Left() + nW,
- aRectIter->Top() + nH)));
- m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), basebmp::DrawMode::Paint);
- }
- }
- }
- m_bClipSetup = true;
-}
-
-SvpSalGraphics::ClipUndoHandle::~ClipUndoHandle()
-{
- if( m_aDevice.get() )
- m_rGfx.m_aDevice = m_aDevice;
-}
-
-// setup a clip rectangle -only- iff we have to; if aRange
-// is entirely contained inside an existing clip frame, we
-// will avoid setting up the clip bitmap. Similarly if the
-// range doesn't appear at all we return true to avoid
-// rendering
-bool SvpSalGraphics::isClippedSetup( const basegfx::B2IBox &aRange, SvpSalGraphics::ClipUndoHandle &rUndo )
-{
- if( m_bClipSetup )
- return false;
-
- if( m_aClipRegion.IsEmpty() ) // no clipping
- return false;
-
- // fprintf( stderr, "ensureClipFor: %d, %d %dx%d\n",
- // aRange.getMinX(), aRange.getMinY(),
- // (int)aRange.getWidth(), (int)aRange.getHeight() );
-
- // first see if aRange is purely internal to one of the clip regions
- Rectangle aRect( Point( aRange.getMinX(), aRange.getMinY() ),
- Size( aRange.getWidth(), aRange.getHeight() ) );
-
- // then see if we are overlapping with just one
- int nHit = 0;
- Rectangle aHitRect;
- RectangleVector aRectangles;
- m_aClipRegion.GetRegionRectangles(aRectangles);
- for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
- {
- if( aRectIter->IsOver( aRect ) )
- {
- aHitRect = *aRectIter;
- nHit++;
- }
- }
-
- if( nHit == 0 ) // rendering outside any clipping region
- {
- SAL_INFO("vcl.headless", "SvpSalGraphics::isClippedSetup: degenerate case detected ...");
- return true;
- }
- else if( nHit == 1 ) // common path: rendering against just one clipping region
- {
- if( aHitRect.IsInside( aRect ) )
- {
- //The region to be painted (aRect) is equal to or inside the
- //current clipping region
- SAL_INFO("vcl.headless", "SvpSalGraphics::isClippedSetup: is inside ! avoid deeper clip ...");
- return false;
- }
- SAL_INFO("vcl.headless", "SvpSalGraphics::isClippedSetup: operation only overlaps with a single clip zone");
- rUndo.m_aDevice = m_aDevice;
- m_aDevice = basebmp::subsetBitmapDevice( m_aOrigDevice,
- basegfx::B2IBox (aHitRect.Left(),
- aHitRect.Top(),
- aHitRect.Right() + 1,
- aHitRect.Bottom() + 1) );
- return false;
- }
- SAL_INFO("vcl.headless", "SvpSalGraphics::isClippedSetup: URK: complex & slow clipping case\n");
- // horribly slow & complicated case ...
-
- ensureClip();
- return false;
-}
-
-// Clipping by creating unconditional mask bitmaps is horribly
-// slow so defer it, as much as possible. It is common to get
-// 3 rectangles pushed, and have to create a vast off-screen
-// mask only to destroy it shortly afterwards. That is
-// particularly galling if we render only to a small,
-// well defined rectangular area inside one of these clip
-// rectangles.
-
-// ensureClipFor() or ensureClip() need to be called before
-// real rendering. FIXME: we should prolly push this down to
-// bitmapdevice instead.
bool SvpSalGraphics::setClipRegion( const vcl::Region& i_rClip )
{
m_aClipRegion = i_rClip;
- m_aClipMap.reset();
- if( i_rClip.IsEmpty() )
- {
- m_aDevice = m_aOrigDevice;
- m_bClipSetup = true;
- return true;
- }
-
- RectangleVector aRectangles;
- i_rClip.GetRegionRectangles(aRectangles);
-
- if (1 == aRectangles.size())
- {
- //simplest case, subset the device to clip bounds
- m_aClipMap.reset();
-
- const Rectangle& aBoundRect = aRectangles[0];
- m_aDevice = basebmp::subsetBitmapDevice(
- m_aOrigDevice,
- basegfx::B2IBox(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right() + 1,aBoundRect.Bottom() + 1) );
-
- m_bClipSetup = true;
- }
- else
- {
- //more complex, either setup and tear down temporary
- //subsets of the original device around render calls
- //or generate m_aClipMap and pass that to basebmp
- //calls
- m_aDevice = m_aOrigDevice;
- m_bClipSetup = false;
- }
-
return true;
}
@@ -910,7 +721,6 @@ void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
aPoly.setClosed(false);
cairo_t* cr = getCairoContext(false);
- assert(cr && m_aDevice->isTopDown());
clipRegion(cr);
AddPolygonToPath(cr, aPoly, aPoly.isClosed(), !getAntiAliasB2DDraw(), true);
@@ -955,7 +765,6 @@ bool SvpSalGraphics::drawPolyLine(
}
cairo_t* cr = getCairoContext(false);
- assert(cr && m_aDevice->isTopDown());
clipRegion(cr);
// setup line attributes
@@ -1057,7 +866,6 @@ void SvpSalGraphics::setupPolyPolygon(cairo_t* cr, const basegfx::B2DPolyPolygon
bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency)
{
cairo_t* cr = getCairoContext(true);
- assert(cr && m_aDevice->isTopDown());
setupPolyPolygon(cr, rPolyPoly);
@@ -1095,7 +903,7 @@ bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, d
void SvpSalGraphics::applyColor(cairo_t *cr, const basebmp::Color &rColor)
{
- if (CAIRO_FORMAT_ARGB32 == getCairoFormat(m_aOrigDevice))
+ if (CAIRO_FORMAT_ARGB32 == cairo_image_surface_get_format(m_pSurface))
{
cairo_set_source_rgba(cr, rColor.getRed()/255.0,
rColor.getGreen()/255.0,
@@ -1113,7 +921,6 @@ void SvpSalGraphics::applyColor(cairo_t *cr, const basebmp::Color &rColor)
void SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly)
{
cairo_t* cr = getCairoContext(true);
- assert(cr && m_aDevice->isTopDown());
setupPolyPolygon(cr, rPolyPoly);
@@ -1170,7 +977,6 @@ void SvpSalGraphics::copySource( const SalTwoRect& rTR,
cairo_surface_t* source )
{
cairo_t* cr = getCairoContext(false);
- assert(cr && m_aDevice->isTopDown());
clipRegion(cr);
cairo_rectangle_int_t extents = renderSource(cr, rTR, source);
@@ -1186,18 +992,14 @@ void SvpSalGraphics::copyBits( const SalTwoRect& rTR,
SvpSalGraphics* pSrc = pSrcGraphics ?
static_cast<SvpSalGraphics*>(pSrcGraphics) : this;
- cairo_surface_t* source = SvpSalGraphics::createCairoSurface(pSrc->m_aOrigDevice);
- if (!source)
- {
- SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::copyBits case");
- return;
- }
+ cairo_surface_t* source = pSrc->m_pSurface;
+ cairo_surface_t *pCopy = nullptr;
if (pSrc == this)
{
//self copy is a problem, so dup source in that case
- cairo_surface_t *pCopy = cairo_surface_create_similar_image(source,
- getCairoFormat(m_aOrigDevice),
+ pCopy = cairo_surface_create_similar_image(source,
+ cairo_image_surface_get_format(m_pSurface),
aTR.mnSrcWidth,
aTR.mnSrcHeight);
@@ -1207,7 +1009,6 @@ void SvpSalGraphics::copyBits( const SalTwoRect& rTR,
cairo_fill(cr);
cairo_destroy(cr);
- cairo_surface_destroy(source);
source = pCopy;
aTR.mnSrcX = 0;
@@ -1216,7 +1017,8 @@ void SvpSalGraphics::copyBits( const SalTwoRect& rTR,
copySource(aTR, source);
- cairo_surface_destroy(source);
+ if (pCopy)
+ cairo_surface_destroy(pCopy);
}
void SvpSalGraphics::drawBitmap(const SalTwoRect& rTR, const SalBitmap& rSourceBitmap)
@@ -1227,7 +1029,6 @@ void SvpSalGraphics::drawBitmap(const SalTwoRect& rTR, const SalBitmap& rSourceB
{
SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawBitmap case");
}
-
copySource(rTR, source);
}
@@ -1238,10 +1039,11 @@ void SvpSalGraphics::drawBitmap( const SalTwoRect& rTR,
drawAlphaBitmap(rTR, rSourceBitmap, rTransparentBitmap);
}
-void SvpSalGraphics::drawMask( const SalTwoRect& rPosAry,
- const SalBitmap& rSalBitmap,
- SalColor nMaskColor )
+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,
@@ -1267,6 +1069,7 @@ void SvpSalGraphics::drawMask( const SalTwoRect& rPosAry,
if( !isClippedSetup( aClipRect, aUndo ) )
m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap );
dbgOut( m_aDevice );
+#endif
}
SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
@@ -1274,14 +1077,14 @@ SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeigh
basegfx::B2IVector aSize(nWidth, nHeight);
basebmp::BitmapDeviceSharedPtr aCopy = createBitmapDevice(aSize, true, SVP_CAIRO_FORMAT);
- cairo_t* cr = SvpSalGraphics::createCairoContext(aCopy);
+ cairo_surface_t* target = SvpSalGraphics::createCairoSurface(aCopy);
+ cairo_t* cr = cairo_create(target);
- cairo_surface_t *source = createCairoSurface(m_aOrigDevice);
SalTwoRect aTR(nX, nY, nWidth, nHeight, 0, 0, nWidth, nHeight);
- renderSource(cr, aTR, source);
- cairo_surface_destroy(source);
+ renderSource(cr, aTR, m_pSurface);
cairo_destroy(cr);
+ cairo_surface_destroy(target);
SvpSalBitmap* pBitmap = new SvpSalBitmap();
pBitmap->setBitmap(aCopy);
@@ -1301,12 +1104,12 @@ static sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a)
SalColor SvpSalGraphics::getPixel( long nX, long nY )
{
- cairo_surface_t* surface = createCairoSurface(m_aOrigDevice);
- unsigned char *surface_data = cairo_image_surface_get_data(surface);
- cairo_format_t nFormat = getCairoFormat(m_aOrigDevice);
+ cairo_surface_flush(m_pSurface);
+ cairo_format_t nFormat = cairo_image_surface_get_format(m_pSurface);
assert(nFormat == CAIRO_FORMAT_ARGB32 && "need to implement CAIRO_FORMAT_A1 after all here");
- basegfx::B2IVector size = m_aOrigDevice->getSize();
- sal_Int32 nStride = cairo_format_stride_for_width(nFormat, size.getX());
+ sal_Int32 nStride = cairo_format_stride_for_width(nFormat,
+ cairo_image_surface_get_width(m_pSurface));
+ unsigned char *surface_data = cairo_image_surface_get_data(m_pSurface);
unsigned char *row = surface_data + (nStride*nY);
unsigned char *data = row + (nX * 4);
sal_uInt8 b = unpremultiply(data[0], data[3]);
@@ -1335,7 +1138,6 @@ namespace
void SvpSalGraphics::invert(const basegfx::B2DPolygon &rPoly, SalInvert nFlags)
{
cairo_t* cr = getCairoContext(false);
- assert(cr && m_aDevice->isTopDown());
clipRegion(cr);
cairo_rectangle_int_t extents = {0, 0, 0, 0};
@@ -1409,6 +1211,34 @@ bool SvpSalGraphics::drawEPS( long, long, long, long, void*, sal_uLong )
return false;
}
+namespace
+{
+ cairo_format_t getCairoFormat(const basebmp::BitmapDeviceSharedPtr &rBuffer)
+ {
+ cairo_format_t nFormat;
+ if (rBuffer->getScanlineFormat() == SVP_CAIRO_FORMAT)
+ nFormat = CAIRO_FORMAT_ARGB32;
+ else
+ nFormat = CAIRO_FORMAT_A1;
+ return nFormat;
+ }
+
+ bool isCairoCompatible(const basebmp::BitmapDeviceSharedPtr &rBuffer)
+ {
+ if (!rBuffer)
+ return false;
+
+ if (rBuffer->getScanlineFormat() != SVP_CAIRO_FORMAT &&
+ rBuffer->getScanlineFormat() != basebmp::Format::OneBitMsbPal)
+ return false;
+
+ basegfx::B2IVector size = rBuffer->getSize();
+ sal_Int32 nStride = rBuffer->getScanlineStride();
+ cairo_format_t nFormat = getCairoFormat(rBuffer);
+ return (cairo_format_stride_for_width(nFormat, size.getX()) == nStride);
+ }
+}
+
cairo_surface_t* SvpSalGraphics::createCairoSurface(const basebmp::BitmapDeviceSharedPtr &rBuffer)
{
if (!isCairoCompatible(rBuffer))
@@ -1427,51 +1257,22 @@ cairo_surface_t* SvpSalGraphics::createCairoSurface(const basebmp::BitmapDeviceS
return target;
}
-cairo_surface_t* SvpSalGraphics::createTmpCompatibleCairoSurface(const basebmp::BitmapDeviceSharedPtr &rBuffer)
-{
- if (!isCairoCompatible(rBuffer))
- return nullptr;
-
- basegfx::B2IVector size = rBuffer->getSize();
-
- cairo_format_t nFormat;
- if (rBuffer->getScanlineFormat() == SVP_CAIRO_FORMAT)
- nFormat = CAIRO_FORMAT_ARGB32;
- else
- nFormat = CAIRO_FORMAT_A1;
- cairo_surface_t *target =
- cairo_image_surface_create(nFormat,
- size.getX(), size.getY());
- return target;
-}
-
-cairo_t* SvpSalGraphics::createCairoContext(const basebmp::BitmapDeviceSharedPtr &rBuffer)
+static cairo_t* createTmpCompatibleCairoContext(cairo_surface_t* pSurface)
{
- cairo_surface_t *target = createCairoSurface(rBuffer);
- if (!target)
- return nullptr;
- cairo_t* cr = cairo_create(target);
- cairo_surface_destroy(target);
- return cr;
-}
-
-cairo_t* SvpSalGraphics::createTmpCompatibleCairoContext(const basebmp::BitmapDeviceSharedPtr &rBuffer)
-{
- cairo_surface_t *target = createTmpCompatibleCairoSurface(rBuffer);
- if (!target)
- return nullptr;
- cairo_t* cr = cairo_create(target);
- cairo_surface_destroy(target);
- return cr;
+ cairo_surface_t *target = cairo_image_surface_create(
+ cairo_image_surface_get_format(pSurface),
+ cairo_image_surface_get_width(pSurface),
+ cairo_image_surface_get_height(pSurface));
+ return cairo_create(target);
}
cairo_t* SvpSalGraphics::getCairoContext(bool bXorModeAllowed) const
{
cairo_t* cr;
if (m_ePaintMode == XOR && bXorModeAllowed)
- cr = SvpSalGraphics::createTmpCompatibleCairoContext(m_aOrigDevice);
+ cr = createTmpCompatibleCairoContext(m_pSurface);
else
- cr = SvpSalGraphics::createCairoContext(m_aOrigDevice);
+ cr = cairo_create(m_pSurface);
cairo_set_line_width(cr, 1);
if (m_ePaintMode == INVERT)
cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE);
@@ -1480,15 +1281,22 @@ cairo_t* SvpSalGraphics::getCairoContext(bool bXorModeAllowed) const
return cr;
}
+cairo_user_data_key_t* SvpSalGraphics::getDamageKey()
+{
+ static cairo_user_data_key_t aDamageKey;
+ return &aDamageKey;
+}
+
void SvpSalGraphics::releaseCairoContext(cairo_t* cr, bool bXorModeAllowed, const cairo_rectangle_int_t& extents) const
{
sal_Int32 nExtentsLeft(extents.x), nExtentsTop(extents.y);
sal_Int32 nExtentsRight(extents.x + extents.width), nExtentsBottom(extents.y + extents.height);
- basegfx::B2IVector size = m_aOrigDevice->getSize();
+ sal_Int32 nWidth = cairo_image_surface_get_width(m_pSurface);
+ sal_Int32 nHeight = cairo_image_surface_get_height(m_pSurface);
nExtentsLeft = std::max(nExtentsLeft, 0);
nExtentsTop = std::max(nExtentsTop, 0);
- nExtentsRight = std::min(nExtentsRight, size.getX());
- nExtentsBottom = std::min(nExtentsBottom, size.getY());
+ nExtentsRight = std::min(nExtentsRight, nWidth);
+ nExtentsBottom = std::min(nExtentsBottom, nHeight);
cairo_surface_t* surface = cairo_get_target(cr);
cairo_surface_flush(surface);
@@ -1498,14 +1306,14 @@ void SvpSalGraphics::releaseCairoContext(cairo_t* cr, bool bXorModeAllowed, cons
//emulate it (slowly) here.
if (m_ePaintMode == XOR && bXorModeAllowed)
{
- cairo_surface_t* true_surface = createCairoSurface(m_aOrigDevice);
+ cairo_surface_t* true_surface = m_pSurface;
cairo_surface_flush(true_surface);
unsigned char *true_surface_data = cairo_image_surface_get_data(true_surface);
unsigned char *xor_surface_data = cairo_image_surface_get_data(surface);
- cairo_format_t nFormat = getCairoFormat(m_aOrigDevice);
+ cairo_format_t nFormat = cairo_image_surface_get_format(m_pSurface);
assert(nFormat == CAIRO_FORMAT_ARGB32 && "need to implement CAIRO_FORMAT_A1 after all here");
- sal_Int32 nStride = cairo_format_stride_for_width(nFormat, size.getX());
+ sal_Int32 nStride = cairo_format_stride_for_width(nFormat, nWidth);
for (sal_Int32 y = nExtentsTop; y < nExtentsBottom; ++y)
{
unsigned char *true_row = true_surface_data + (nStride*y);
@@ -1528,17 +1336,16 @@ void SvpSalGraphics::releaseCairoContext(cairo_t* cr, bool bXorModeAllowed, cons
}
}
cairo_surface_mark_dirty(true_surface);
-
- cairo_surface_destroy(true_surface);
+ cairo_surface_destroy(surface);
}
cairo_destroy(cr); // unref
- basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aDevice->getDamageTracker());
- if (xDamageTracker)
+ DamageHandler* pDamage = static_cast<DamageHandler*>(cairo_surface_get_user_data(m_pSurface, getDamageKey()));
+
+ if (pDamage)
{
- xDamageTracker->damaged(basegfx::B2IBox(nExtentsLeft, nExtentsTop, nExtentsRight,
- nExtentsBottom));
+ pDamage->damaged(pDamage->handle, nExtentsLeft, nExtentsTop, nExtentsRight, nExtentsBottom);
}
}
@@ -1579,8 +1386,6 @@ SystemGraphicsData SvpSalGraphics::GetGraphicsData() const
bool SvpSalGraphics::supportsOperation(OutDevSupportType eType) const
{
- if (!isCairoCompatible(m_aOrigDevice))
- return false;
switch (eType)
{
case OutDevSupport_TransparentRect:
diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx
index 8d5096487c42..f45b813f7dd8 100644
--- a/vcl/headless/svpinst.cxx
+++ b/vcl/headless/svpinst.cxx
@@ -200,12 +200,12 @@ bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, SalFrameStyleFlags nStyle )
{
- return new SvpSalFrame( this, nullptr, nStyle, SVP_CAIRO_FORMAT, pParent );
+ return new SvpSalFrame( this, nullptr, nStyle, pParent );
}
SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
{
- return new SvpSalFrame( this, pParent, nStyle, SVP_CAIRO_FORMAT );
+ return new SvpSalFrame( this, pParent, nStyle );
}
void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx
index 0273f3f7311c..01cb18fa28b2 100644
--- a/vcl/headless/svpvd.cxx
+++ b/vcl/headless/svpvd.cxx
@@ -27,6 +27,8 @@
#include <basegfx/vector/b2ivector.hxx>
#include <basebmp/scanlineformats.hxx>
+#include <cairo.h>
+
using namespace basegfx;
using namespace basebmp;
@@ -37,7 +39,7 @@ SvpSalVirtualDevice::~SvpSalVirtualDevice()
SalGraphics* SvpSalVirtualDevice::AcquireGraphics()
{
SvpSalGraphics* pGraphics = new SvpSalGraphics();
- pGraphics->setDevice( m_aDevice );
+ pGraphics->setSurface(m_pSurface);
m_aGraphics.push_back( pGraphics );
return pGraphics;
}
@@ -61,30 +63,48 @@ bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY,
aDevSize.setX( 1 );
if( aDevSize.getY() == 0 )
aDevSize.setY( 1 );
- if( ! m_aDevice.get() || m_aDevice->getSize() != aDevSize ) {
- basebmp::Format nFormat = SvpSalInstance::getBaseBmpFormatForDeviceFormat(m_eFormat);
-
- if (m_eFormat == DeviceFormat::BITMASK) {
- std::vector< basebmp::Color > aDevPal(2);
- aDevPal[0] = basebmp::Color( 0, 0, 0 );
- aDevPal[1] = basebmp::Color( 0xff, 0xff, 0xff );
- m_aDevice = createBitmapDevice( aDevSize, true, nFormat,
- PaletteMemorySharedVector( new std::vector< basebmp::Color >(aDevPal) ) );
- } else {
- m_aDevice = pBuffer ?
- createBitmapDevice( aDevSize, true, nFormat, pBuffer, PaletteMemorySharedVector() )
- : createBitmapDevice( aDevSize, true, nFormat );
+
+ if (!m_pSurface || cairo_image_surface_get_width(m_pSurface) != aDevSize.getX() ||
+ cairo_image_surface_get_height(m_pSurface) != aDevSize.getY() )
+ {
+ if (m_eFormat == DeviceFormat::BITMASK)
+ {
+ m_pSurface = cairo_image_surface_create(CAIRO_FORMAT_A1,
+ aDevSize.getX(),
+ aDevSize.getY());
+ }
+ else
+ {
+ m_pSurface = pBuffer ?
+ cairo_image_surface_create_for_data(pBuffer.get(), CAIRO_FORMAT_ARGB32,
+ aDevSize.getX(),
+ aDevSize.getY(),
+ cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, aDevSize.getX()))
+ :
+ cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ aDevSize.getX(),
+ aDevSize.getY());
}
// update device in existing graphics
for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin();
it != m_aGraphics.end(); ++it )
- (*it)->setDevice( m_aDevice );
+ (*it)->setSurface(m_pSurface);
}
return true;
}
+long SvpSalVirtualDevice::GetWidth() const
+{
+ return m_pSurface ? cairo_image_surface_get_width(m_pSurface) : 0;
+}
+
+long SvpSalVirtualDevice::GetHeight() const
+{
+ return m_pSurface ? cairo_image_surface_get_height(m_pSurface) : 0;
+}
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/headless/svpframe.hxx b/vcl/inc/headless/svpframe.hxx
index 507af74777d6..19d36214691d 100644
--- a/vcl/inc/headless/svpframe.hxx
+++ b/vcl/inc/headless/svpframe.hxx
@@ -44,9 +44,7 @@ class VCL_DLLPUBLIC SvpSalFrame : public SalFrame
SalFrameStyleFlags m_nStyle;
bool m_bVisible;
#ifndef IOS
- basebmp::BitmapDeviceSharedPtr m_aFrame;
- bool m_bDamageTracking;
- basebmp::Format m_nScanlineFormat;
+ cairo_surface_t* m_pSurface;
#endif
long m_nMinWidth;
long m_nMinHeight;
@@ -62,7 +60,6 @@ public:
SvpSalFrame( SvpSalInstance* pInstance,
SalFrame* pParent,
SalFrameStyleFlags nSalFrameStyle,
- basebmp::Format nScanlineFormat,
SystemParentData* pSystemParent = nullptr );
virtual ~SvpSalFrame();
@@ -70,10 +67,6 @@ public:
void LoseFocus();
void PostPaint(bool bImmediate) const;
-#if defined ANDROID
- const basebmp::BitmapDeviceSharedPtr& getDevice() const { return m_aFrame; }
-#endif
-
// SalFrame
virtual SalGraphics* AcquireGraphics() override;
virtual void ReleaseGraphics( SalGraphics* pGraphics ) override;
@@ -122,11 +115,6 @@ public:
virtual void UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) override;
virtual void EndSetClipRegion() override;
-#ifdef ANDROID
- // If enabled we can get damage notifications for regions immediately rendered to ...
- void enableDamageTracker( bool bOn = true );
-#endif
-
/*TODO: functional implementation */
virtual void SetScreenNumber( unsigned int nScreen ) override { (void)nScreen; }
virtual void SetApplicationID(const OUString &rApplicationID) override { (void) rApplicationID; }
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index c2107b78aa39..e2acbd936f98 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -50,15 +50,23 @@ class ServerFont;
typedef struct _cairo cairo_t;
typedef struct _cairo_surface cairo_surface_t;
typedef struct _cairo_rectangle_int cairo_rectangle_int_t;
+typedef struct _cairo_user_data_key cairo_user_data_key_t;
enum PaintMode { OVERPAINT, XOR, INVERT };
-class VCL_DLLPUBLIC SvpSalGraphics : public SalGraphics
+typedef void (*damageHandler)(void* handle,
+ sal_Int32 nExtentsLeft, sal_Int32 nExtentsTop,
+ sal_Int32 nExtentsRight, sal_Int32 nExtentsBottom);
+
+struct VCL_DLLPUBLIC DamageHandler
{
- basebmp::BitmapDeviceSharedPtr m_aDevice;
- basebmp::BitmapDeviceSharedPtr m_aOrigDevice;
+ void *handle;
+ damageHandler damaged;
+};
- basebmp::BitmapDeviceSharedPtr m_aClipMap;
+class VCL_DLLPUBLIC SvpSalGraphics : public SalGraphics
+{
+ cairo_surface_t* m_pSurface;
bool m_bUseLineColor;
basebmp::Color m_aLineColor;
@@ -69,18 +77,10 @@ class VCL_DLLPUBLIC SvpSalGraphics : public SalGraphics
public:
static GlyphCache& getPlatformGlyphCache();
- void setDevice(basebmp::BitmapDeviceSharedPtr& rDevice);
+ void setSurface(cairo_surface_t* pSurface);
+ static cairo_user_data_key_t* getDamageKey();
private:
- bool m_bClipSetup;
- struct ClipUndoHandle {
- SvpSalGraphics &m_rGfx;
- basebmp::BitmapDeviceSharedPtr m_aDevice;
- ClipUndoHandle( SvpSalGraphics *pGfx ) : m_rGfx( *pGfx ) {}
- ~ClipUndoHandle();
- };
- bool isClippedSetup( const basegfx::B2IBox &aRange, ClipUndoHandle &rUndo );
- void ensureClip();
void invert(const basegfx::B2DPolygon &rPoly, SalInvert nFlags);
void copySource(const SalTwoRect& rTR, cairo_surface_t* source);
void setupPolyPolygon(cairo_t* cr, const basegfx::B2DPolyPolygon& rPolyPoly);
@@ -224,10 +224,7 @@ public:
cairo_t* getCairoContext(bool bXorModeAllowed) const;
void releaseCairoContext(cairo_t* cr, bool bXorModeAllowed, const cairo_rectangle_int_t& extents) const;
- static cairo_surface_t* createCairoSurface(const basebmp::BitmapDeviceSharedPtr& rBuffer);
- static cairo_t* createCairoContext(const basebmp::BitmapDeviceSharedPtr& rBuffer);
- static cairo_surface_t* createTmpCompatibleCairoSurface(const basebmp::BitmapDeviceSharedPtr& rBuffer);
- static cairo_t* createTmpCompatibleCairoContext(const basebmp::BitmapDeviceSharedPtr &rBuffer);
+ static cairo_surface_t* createCairoSurface(const basebmp::BitmapDeviceSharedPtr &rBuffer);
void clipRegion(cairo_t* cr);
};
diff --git a/vcl/inc/headless/svpvd.hxx b/vcl/inc/headless/svpvd.hxx
index 4241d383a989..8d6357e09e4b 100644
--- a/vcl/inc/headless/svpvd.hxx
+++ b/vcl/inc/headless/svpvd.hxx
@@ -25,15 +25,20 @@
#include <list>
class SvpSalGraphics;
+typedef struct _cairo_surface cairo_surface_t;
class VCL_DLLPUBLIC SvpSalVirtualDevice : public SalVirtualDevice
{
DeviceFormat m_eFormat;
- basebmp::BitmapDeviceSharedPtr m_aDevice;
+ cairo_surface_t* m_pSurface;
std::list< SvpSalGraphics* > m_aGraphics;
public:
- SvpSalVirtualDevice(DeviceFormat eFormat) : m_eFormat(eFormat) {}
+ SvpSalVirtualDevice(DeviceFormat eFormat)
+ : m_eFormat(eFormat)
+ , m_pSurface(nullptr)
+ {
+ }
virtual ~SvpSalVirtualDevice();
// SalVirtualDevice
@@ -46,8 +51,8 @@ public:
) override;
// SalGeometryProvider
- virtual long GetWidth() const override { return m_aDevice.get() ? m_aDevice->getSize().getX() : 0; }
- virtual long GetHeight() const override { return m_aDevice.get() ? m_aDevice->getSize().getY() : 0; }
+ virtual long GetWidth() const override;
+ virtual long GetHeight() const override;
};
#endif // INCLUDED_VCL_INC_HEADLESS_SVPVD_HXX
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 972b241752d8..c5f14f88949b 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -46,6 +46,8 @@
#include <list>
#include <vector>
+#include "headless/svpgdi.hxx"
+
class GtkSalGraphics;
class GtkSalDisplay;
@@ -60,7 +62,8 @@ typedef ::Window GdkNativeWindow;
typedef void GDBusConnection;
#endif
-class GtkSalFrame : public SalFrame, public X11WindowProvider
+class GtkSalFrame : public SalFrame
+ , public X11WindowProvider
{
struct IMHandler
{
@@ -320,7 +323,8 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider
public:
#if GTK_CHECK_VERSION(3,0,0)
- basebmp::BitmapDeviceSharedPtr m_aFrame;
+ cairo_surface_t* m_pSurface;
+ DamageHandler m_aDamageHandler;
#endif
GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle );
GtkSalFrame( SystemParentData* pSysData );
@@ -356,7 +360,8 @@ public:
#if GTK_CHECK_VERSION(3,0,0)
// only for gtk3 ...
cairo_t* getCairoContext() const;
- void damaged (const basegfx::B2IBox& rDamageRect);
+ void damaged(sal_Int32 nExtentsLeft, sal_Int32 nExtentsTop,
+ sal_Int32 nExtentsRight, sal_Int32 nExtentsBottom) const;
#endif
virtual ~GtkSalFrame();
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index c2551314ba28..6012f58f2650 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -335,24 +335,6 @@ GetAlternateKeyCode( const sal_uInt16 nKeyCode )
return aAlternate;
}
-namespace {
-/// Decouple SalFrame lifetime from damagetracker lifetime
-struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker
-{
- explicit DamageTracker(GtkSalFrame& rFrame) : m_rFrame(rFrame)
- {}
-
- virtual ~DamageTracker() {}
-
- virtual void damaged(const basegfx::B2IBox& rDamageRect) const override
- {
- m_rFrame.damaged(rDamageRect);
- }
-
- GtkSalFrame& m_rFrame;
-};
-}
-
static bool dumpframes = false;
void GtkSalFrame::doKeyCallback( guint state,
@@ -857,6 +839,9 @@ GtkSalFrame::~GtkSalFrame()
delete m_pGraphics;
m_pGraphics = nullptr;
+
+ if (m_pSurface)
+ cairo_surface_destroy(m_pSurface);
}
void GtkSalFrame::moveWindow( long nX, long nY )
@@ -956,8 +941,22 @@ GtkWidget *GtkSalFrame::getMouseEventWidget() const
return GTK_WIDGET(m_pEventBox);
}
+static void damaged(void *handle,
+ sal_Int32 nExtentsLeft, sal_Int32 nExtentsTop,
+ sal_Int32 nExtentsRight, sal_Int32 nExtentsBottom)
+{
+ GtkSalFrame* pThis = static_cast<GtkSalFrame*>(handle);
+ pThis->damaged(nExtentsLeft, nExtentsTop,
+ nExtentsRight, nExtentsBottom);
+}
+
void GtkSalFrame::InitCommon()
{
+ m_pSurface = nullptr;
+
+ m_aDamageHandler.handle = this;
+ m_aDamageHandler.damaged = ::damaged;
+
m_pEventBox = GTK_EVENT_BOX(gtk_event_box_new());
gtk_widget_add_events( GTK_WIDGET(m_pEventBox),
GDK_ALL_EVENTS_MASK );
@@ -1271,12 +1270,12 @@ SalGraphics* GtkSalFrame::AcquireGraphics()
if( !m_pGraphics )
{
m_pGraphics = new GtkSalGraphics( this, m_pWindow );
- if( !m_aFrame.get() )
+ if (!m_pSurface)
{
AllocateFrame();
TriggerPaintEvent();
}
- m_pGraphics->setDevice( m_aFrame );
+ m_pGraphics->setSurface(m_pSurface);
}
m_bGraphics = true;
return m_pGraphics;
@@ -1525,25 +1524,24 @@ void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight )
void GtkSalFrame::AllocateFrame()
{
basegfx::B2IVector aFrameSize( maGeometry.nWidth, maGeometry.nHeight );
- if( ! m_aFrame.get() || m_aFrame->getSize() != aFrameSize )
+ if (!m_pSurface || cairo_image_surface_get_width(m_pSurface) != aFrameSize.getX() ||
+ cairo_image_surface_get_height(m_pSurface) != aFrameSize.getY() )
{
if( aFrameSize.getX() == 0 )
aFrameSize.setX( 1 );
if( aFrameSize.getY() == 0 )
aFrameSize.setY( 1 );
- m_aFrame = basebmp::createBitmapDevice(aFrameSize, true, SVP_CAIRO_FORMAT);
- assert(cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, aFrameSize.getX()) ==
- m_aFrame->getScanlineStride());
- m_aFrame->setDamageTracker(
- basebmp::IBitmapDeviceDamageTrackerSharedPtr(new DamageTracker(*this)) );
- SAL_INFO("vcl.gtk3", "allocated m_aFrame size of " << maGeometry.nWidth << " x " << maGeometry.nHeight);
-
-#if OSL_DEBUG_LEVEL > 0 // set background to orange
- m_aFrame->clear( basebmp::Color( 255, 127, 0 ) );
-#endif
- if( m_pGraphics )
- m_pGraphics->setDevice( m_aFrame );
+ if (m_pSurface)
+ cairo_surface_destroy(m_pSurface);
+ m_pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ aFrameSize.getX(),
+ aFrameSize.getY());
+ cairo_surface_set_user_data(m_pSurface, SvpSalGraphics::getDamageKey(), &m_aDamageHandler, nullptr);
+ SAL_INFO("vcl.gtk3", "allocated Frame size of " << maGeometry.nWidth << " x " << maGeometry.nHeight);
+
+ if (m_pGraphics)
+ m_pGraphics->setSurface(m_pSurface);
}
}
@@ -2654,26 +2652,14 @@ gboolean GtkSalFrame::signalCrossing( GtkWidget*, GdkEventCrossing* pEvent, gpoi
cairo_t* GtkSalFrame::getCairoContext() const
{
- cairo_t* cr = SvpSalGraphics::createCairoContext(m_aFrame);
+ cairo_t* cr = cairo_create(m_pSurface);
assert(cr);
return cr;
}
-void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
+void GtkSalFrame::damaged(sal_Int32 nExtentsLeft, sal_Int32 nExtentsTop,
+ sal_Int32 nExtentsRight, sal_Int32 nExtentsBottom) const
{
-#if OSL_DEBUG_LEVEL > 1
- long long area = rDamageRect.getWidth() * rDamageRect.getHeight();
- if( area > 32 * 1024 )
- {
- fprintf( stderr, "bitmap damaged %d %d (%dx%d) area %lld widget\n",
- (int) rDamageRect.getMinX(),
- (int) rDamageRect.getMinY(),
- (int) rDamageRect.getWidth(),
- (int) rDamageRect.getHeight(),
- area );
- }
-#endif
-
if (dumpframes)
{
static int frame;
@@ -2684,32 +2670,19 @@ void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
}
gtk_widget_queue_draw_area(GTK_WIDGET(m_pFixedContainer),
- rDamageRect.getMinX(),
- rDamageRect.getMinY(),
- rDamageRect.getWidth(),
- rDamageRect.getHeight());
+ nExtentsLeft, nExtentsTop,
+ nExtentsRight - nExtentsLeft,
+ nExtentsBottom - nExtentsTop);
}
-// blit our backing basebmp buffer to the target cairo context cr
-gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame )
+// blit our backing cairo surface to the target cairo context
+gboolean GtkSalFrame::signalDraw(GtkWidget*, cairo_t *cr, gpointer frame)
{
GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
- cairo_save(cr);
-
- cairo_t* source = pThis->getCairoContext();
- cairo_surface_t *pSurface = cairo_get_target(source);
-
- cairo_set_operator( cr, CAIRO_OPERATOR_OVER );
- cairo_set_source_surface(cr, pSurface, 0, 0);
+ cairo_set_source_surface(cr, pThis->m_pSurface, 0, 0);
cairo_paint(cr);
- cairo_destroy(source);
-
- cairo_restore(cr);
-
- cairo_surface_flush(cairo_get_target(cr));
-
return false;
}
diff --git a/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
index ead9d7fb3474..65f3d7c6ad1a 100644
--- a/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
@@ -1214,9 +1214,8 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
}
gtk_style_context_restore(context);
- cairo_surface_flush(cairo_get_target(cr));
cairo_destroy(cr); // unref
- mpFrame->damaged(basegfx::B2IBox(rControlRegion.Left(), rControlRegion.Top(), rControlRegion.Right(), rControlRegion.Bottom()));
+ mpFrame->damaged(rControlRegion.Left(), rControlRegion.Top(), rControlRegion.Right(), rControlRegion.Bottom());
return true;
}