From b646ed4c554e54e5354edc3dfdfc76edbb7656f0 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <kb9vqf@pearsoncomputing.net>
Date: Mon, 17 Sep 2012 13:56:41 -0500
Subject: Add intermediate surface Enable clip regions

---
 tdegtk/tqtcairopainter.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++---
 tdegtk/tqtcairopainter.h   |  9 +++++-
 2 files changed, 82 insertions(+), 5 deletions(-)

(limited to 'tdegtk')

diff --git a/tdegtk/tqtcairopainter.cpp b/tdegtk/tqtcairopainter.cpp
index 2f16d11..a552ee9 100644
--- a/tdegtk/tqtcairopainter.cpp
+++ b/tdegtk/tqtcairopainter.cpp
@@ -88,6 +88,39 @@ TQImage CairoSurfaceToTQImage(cairo_surface_t* surface) {
 	return TQImage(cairo_image_surface_get_data(surface), width, height, depth, (TQRgb*)NULL, 0, TQImage::BigEndian);
 }
 
+void TQt3CairoPaintDevice::resetIntermediateSurface() {
+	if (m_intermediateSurface) {
+		cairo_surface_destroy(m_intermediateSurface);
+	}
+
+	int height = cairo_image_surface_get_height(m_surface);
+	int width = cairo_image_surface_get_width(m_surface);
+	m_intermediateSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+}
+
+void TQt3CairoPaintDevice::transferIntermediateSurface() {
+	cairo_surface_flush(m_intermediateSurface);
+	if (m_clipRegion.isNull()) {
+		// Clipping disabled
+		cairo_set_source_surface(m_devicePainter, m_intermediateSurface, 0, 0);
+		cairo_set_operator(m_devicePainter, CAIRO_OPERATOR_SOURCE);
+		cairo_paint(m_devicePainter);
+	}
+	else {
+		// Clipping enabled
+		cairo_surface_t* maskSurface = TQImageToCairoSurface(m_clipRegion);
+		cairo_mask_surface(m_devicePainter, maskSurface, 0, 0);
+		cairo_fill(m_devicePainter);
+		cairo_surface_destroy(maskSurface);
+	}
+
+	// Clear intermediate surface
+	cairo_save(m_painter);
+	cairo_set_source_rgba(m_painter, 0.0, 0.0, 0.0, 0.0);
+	cairo_paint(m_painter);
+	cairo_restore(m_painter);
+}
+
 void TQt3CairoPaintDevice::dualStrokePen() {
 	if (m_bgColorMode == TQt::OpaqueMode) {
 		// Draw background
@@ -99,6 +132,7 @@ void TQt3CairoPaintDevice::dualStrokePen() {
 	// Draw foreground
 	updatePen(FALSE);
 	cairo_stroke(m_painter);
+	transferIntermediateSurface();
 }
 
 void TQt3CairoPaintDevice::dualStrokeBrush(cairo_fill_rule_t fillMethod) {
@@ -112,6 +146,7 @@ void TQt3CairoPaintDevice::dualStrokeBrush(cairo_fill_rule_t fillMethod) {
 	// Draw foreground
 	updateBrush(FALSE, fillMethod);
 	cairo_fill(m_painter);
+	transferIntermediateSurface();
 }
 
 void TQt3CairoPaintDevice::updatePen(bool backgroundStroke) {
@@ -678,6 +713,8 @@ void TQt3CairoPaintDevice::drawText(TQPainter *p, int x, int y, const TQString &
 	}
 
 	g_object_unref(layout);
+
+	transferIntermediateSurface();
 }
 
 void TQt3CairoPaintDevice::setCairoTransformations() {
@@ -712,7 +749,7 @@ void TQt3CairoPaintDevice::setCairoTransformations() {
 */
 
 TQt3CairoPaintDevice::TQt3CairoPaintDevice( cairo_surface_t *cairosurface )
-    : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice ), m_painter(NULL)
+    : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice ), m_intermediateSurface(NULL), m_painter(NULL), m_devicePainter(NULL)
 {
 	m_surface = cairosurface;
 }
@@ -726,6 +763,13 @@ TQt3CairoPaintDevice::~TQt3CairoPaintDevice()
 		cairo_destroy(m_painter);
 		m_painter = NULL;
 	}
+	if (m_devicePainter) {
+		cairo_destroy(m_devicePainter);
+		m_devicePainter = NULL;
+	}
+	if (m_intermediateSurface) {
+		cairo_surface_destroy(m_intermediateSurface);
+	}
 }
 
 /*!
@@ -783,6 +827,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
 				cairo_stroke(m_painter);
 			}
 			cairo_restore(m_painter);
+			transferIntermediateSurface();
 		}
 		break;
 	    case PdcMoveTo:
@@ -988,6 +1033,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
 				cairo_surface_destroy(sourceSurface);
 			}
 			cairo_restore(m_painter);
+			transferIntermediateSurface();
 		}
 		break;
 #if 0
@@ -1007,7 +1053,9 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
 		if (!m_painter) {
 			m_bgColor = TQColor(0,0,0);
 			m_bgColorMode = TQt::TransparentMode;
-			m_painter = cairo_create(m_surface);
+			resetIntermediateSurface();
+			m_painter = cairo_create(m_intermediateSurface);
+			m_devicePainter = cairo_create(m_surface);
 			m_pen = TQPen();
 			m_brush = TQBrush();
 			m_brushOrigin = TQPoint(0,0);
@@ -1016,6 +1064,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
 			cairo_matrix_init_identity(&m_worldMatrix);
 			cairo_matrix_init_identity(&m_viewportMatrix);
 			setCairoTransformations();
+			m_clipRegion = TQImage();
 		}
 		break;
 	    case PdcEnd:
@@ -1023,6 +1072,10 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
 			cairo_destroy(m_painter);
 			m_painter = NULL;
 		}
+		if (m_devicePainter) {
+			cairo_destroy(m_devicePainter);
+			m_devicePainter = NULL;
+		}
 		break;
 	    case PdcSave:
 		cairo_save(m_painter);
@@ -1238,10 +1291,27 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
 	    case PdcSetClip:
 		m_qt4painter->setClipping( p[0].ival );
 		break;
+#endif
 	    case PdcSetClipRegion:
-		m_qt4painter->setClipRegion( qt4region, Qt::ReplaceClip );
+		if ((p) && (m_painter)) {
+			// SLOW
+			TQRect tqt3br = p[0].rgn->boundingRect();
+			if (!tqt3br.isNull()) {
+				m_clipRegion = TQImage(tqt3br.x()+tqt3br.width(), tqt3br.y()+tqt3br.height(), 32);
+				int x;
+				int y;
+				for (x=0; x<m_clipRegion.width(); x++) {
+					for (y=0; y<m_clipRegion.height(); y++) {
+						TQPoint point(x,y);
+						m_clipRegion.setPixel(x, y, (p[0].rgn->contains(point))?0xffffffff:0x00000000);
+					}
+				}
+			}
+			else {
+				m_clipRegion = TQImage();
+			}
+		}
 		break;
-#endif
 	    default:
 #if defined(QT_CHECK_RANGE)
 		tqWarning( "TQt3CairoPaintDevice::cmd: Invalid command %d", c );
diff --git a/tdegtk/tqtcairopainter.h b/tdegtk/tqtcairopainter.h
index 9700b63..ef3dbac 100644
--- a/tdegtk/tqtcairopainter.h
+++ b/tdegtk/tqtcairopainter.h
@@ -28,6 +28,7 @@
 #include "ntqpen.h"
 #include "ntqbrush.h"
 #include "ntqfont.h"
+#include "ntqimage.h"
 #include "ntqpainter.h"
 
 #include <cairo.h>
@@ -44,6 +45,9 @@ class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice		// picture class
 		int metric( int ) const;
 	
 	private:
+		void resetIntermediateSurface();
+		void transferIntermediateSurface();
+
 		void updatePen(bool backgroundStroke=FALSE);
 		void dualStrokePen();
 
@@ -64,18 +68,21 @@ class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice		// picture class
 	
 	private:
 		cairo_surface_t *m_surface;
+		cairo_surface_t *m_intermediateSurface;
 		cairo_t *m_painter;
+		cairo_t *m_devicePainter;
 		cairo_matrix_t m_worldMatrix;
 		cairo_matrix_t m_viewportMatrix;
 		bool m_worldMatrixEnabled;
 		bool m_viewportMatrixEnabled;
-	
+
 		TQColor m_bgColor;
 		TQt::BGMode m_bgColorMode;
 		TQPen m_pen;
 		TQBrush m_brush;
 		TQPoint m_brushOrigin;
 		TQFont m_font;
+		TQImage m_clipRegion;
 };
 
 #endif // TDEQT4PAINTER_H
-- 
cgit v1.2.1