diff options
author | Timothy Pearson <[email protected]> | 2012-09-17 13:56:41 -0500 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2012-09-17 13:56:41 -0500 |
commit | b646ed4c554e54e5354edc3dfdfc76edbb7656f0 (patch) | |
tree | 6c84014856390daf5a662b516cf91c8c1f00f1cc | |
parent | b6cb4612ca9c615323c0540a3b05edc24feec642 (diff) | |
download | gtk3-tqt-engine-b646ed4c554e54e5354edc3dfdfc76edbb7656f0.tar.gz gtk3-tqt-engine-b646ed4c554e54e5354edc3dfdfc76edbb7656f0.zip |
Add intermediate surface
Enable clip regions
-rw-r--r-- | tdegtk/tqtcairopainter.cpp | 78 | ||||
-rw-r--r-- | tdegtk/tqtcairopainter.h | 9 | ||||
-rw-r--r-- | tests/test-painter.cpp | 15 |
3 files changed, 97 insertions, 5 deletions
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 diff --git a/tests/test-painter.cpp b/tests/test-painter.cpp index 6979af4..f458e26 100644 --- a/tests/test-painter.cpp +++ b/tests/test-painter.cpp @@ -169,6 +169,8 @@ void runTests(TQPaintDevice* pd) { // Font tests { + p.setPen(TQColor(0,128,255)); + static const char *fonts[] = { "Helvetica", "Courier", "Times", 0 }; static int sizes[] = { 10, 12, 18, 24, 36, 0 }; int f = 0; @@ -192,6 +194,19 @@ void runTests(TQPaintDevice* pd) { break; } } + + p.setPen(TQColor(255,128,0)); + p.drawText( TQRect(250, 250, 250, 250), 0, TQString("TQt3 renders via Cairo!") ); + } + + // Clipping tests + { + p.setBrush(TQBrush(TQt::green)); + p.setPen(TQPen(TQt::blue, 1)); + TQRect boundary(400, 10, 100, 100); + TQRegion rectRegion(425,35,50,50); + p.setClipRegion(rectRegion); + p.fillRect(boundary, TQBrush(TQt::green)); } //drawColorWheel(&p, 0.5); |