summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tdegtk/tqtcairopainter.cpp287
-rw-r--r--tdegtk/tqtcairopainter.h11
-rw-r--r--tests/test-painter.cpp61
3 files changed, 315 insertions, 44 deletions
diff --git a/tdegtk/tqtcairopainter.cpp b/tdegtk/tqtcairopainter.cpp
index ae440b7..8f917e1 100644
--- a/tdegtk/tqtcairopainter.cpp
+++ b/tdegtk/tqtcairopainter.cpp
@@ -99,16 +99,16 @@ void TQt3CairoPaintDevice::dualStrokePen() {
cairo_stroke(m_painter);
}
-void TQt3CairoPaintDevice::dualStrokeBrush() {
+void TQt3CairoPaintDevice::dualStrokeBrush(cairo_fill_rule_t fillMethod) {
if (m_bgColorMode == TQt::OpaqueMode) {
// Draw background
cairo_save(m_painter);
- updateBrush(TRUE);
+ updateBrush(TRUE, fillMethod);
cairo_fill(m_painter);
cairo_restore(m_painter);
}
// Draw foreground
- updateBrush(FALSE);
+ updateBrush(FALSE, fillMethod);
cairo_fill(m_painter);
}
@@ -222,7 +222,7 @@ void TQt3CairoPaintDevice::updatePen(bool backgroundStroke) {
cairo_set_source_rgba(m_painter, tqRed(color), tqGreen(color), tqBlue(color), tqAlpha(color));
}
-void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke) {
+void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke, cairo_fill_rule_t fillMethod) {
if (!m_painter) {
return;
}
@@ -338,6 +338,203 @@ void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke) {
cairo_pattern_destroy(pattern);
}
}
+ cairo_set_fill_rule(m_painter, fillMethod);
+}
+
+static inline void fix_neg_rect( int *x, int *y, int *w, int *h ) {
+ if ( *w < 0 ) {
+ *w = -*w + 2;
+ *x -= *w - 1;
+ }
+ if ( *h < 0 ) {
+ *h = -*h + 2;
+ *y -= *h - 1;
+ }
+}
+
+void TQt3CairoPaintDevice::drawPolygon(const TQPointArray* pointarray, bool winding, bool fill, bool close) {
+ int i;
+
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (pointarray) {
+ int x;
+ int y;
+ bool first;
+ if ((m_brush.style() != TQBrush::NoBrush) && fill) {
+ first = true;
+ for (i=0;i<pointarray->count();i++) {
+ pointarray->point(i, &x, &y );
+ if (first) {
+ cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ first = false;
+ }
+ else {
+ cairo_line_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ }
+ }
+ if (close) {
+ cairo_close_path(m_painter);
+ }
+ dualStrokeBrush((winding)?CAIRO_FILL_RULE_EVEN_ODD:CAIRO_FILL_RULE_WINDING);
+ }
+ if (m_pen.style() != TQPen::NoPen) {
+ first = true;
+ for (i=0;i<pointarray->count();i++) {
+ pointarray->point(i, &x, &y );
+ if (first) {
+ cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ first = false;
+ }
+ else {
+ cairo_line_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ }
+ }
+ if (close) {
+ cairo_close_path(m_painter);
+ }
+ dualStrokePen();
+ }
+ }
+ cairo_restore(m_painter);
+ }
+}
+
+void TQt3CairoPaintDevice::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd) {
+ if (!m_painter) {
+ return;
+ }
+
+ if ( xRnd <= 0 || yRnd <= 0 ) {
+ // Draw normal rectangle
+ TQPDevCmdParam param[2];
+ int command = PdcDrawRect;
+ TQRect rectangle(x, y, w, h);
+ param[0].rect = &rectangle;
+ cmd(command, NULL, param);
+ return;
+ }
+
+ if ( xRnd >= 100 ) { // fix ranges
+ xRnd = 99;
+ }
+ if ( yRnd >= 100 ) {
+ yRnd = 99;
+ }
+
+ if ( w <= 0 || h <= 0 ) {
+ fix_neg_rect( &x, &y, &w, &h );
+ }
+ w--;
+ h--;
+ int rxx = w*xRnd/200;
+ int ryy = h*yRnd/200;
+ // were there overflows?
+ if ( rxx < 0 ) {
+ rxx = w/200*xRnd;
+ }
+ if ( ryy < 0 ) {
+ ryy = h/200*yRnd;
+ }
+ int rxx2 = 2*rxx;
+ int ryy2 = 2*ryy;
+ TQPointArray a[4];
+ a[0].makeArc( x, y, rxx2, ryy2, 1*16*90, 16*90 );
+ a[1].makeArc( x, y+h-ryy2, rxx2, ryy2, 2*16*90, 16*90 );
+ a[2].makeArc( x+w-rxx2, y+h-ryy2, rxx2, ryy2, 3*16*90, 16*90 );
+ a[3].makeArc( x+w-rxx2, y, rxx2, ryy2, 0*16*90, 16*90 );
+ // ### is there a better way to join TQPointArrays?
+ TQPointArray aa;
+ aa.resize( a[0].size() + a[1].size() + a[2].size() + a[3].size() );
+ uint j = 0;
+ for ( int k=0; k<4; k++ ) {
+ for ( uint i=0; i<a[k].size(); i++ ) {
+ aa.setPoint( j, a[k].point(i) );
+ j++;
+ }
+ }
+
+ // Draw polygon
+ drawPolygon(&aa, false, true, true);
+
+ return;
+}
+
+void TQt3CairoPaintDevice::drawEllipse(int x, int y, int w, int h) {
+ if (!m_painter) {
+ return;
+ }
+
+ TQPointArray a;
+ a.makeArc(x, y, w, h, 0, 360*16);
+
+ // Draw polygon
+ drawPolygon(&a, false, true, true);
+
+ return;
+}
+
+void TQt3CairoPaintDevice::drawArc(int x, int y, int w, int h, int a, int alen) {
+ if (!m_painter) {
+ return;
+ }
+
+ TQPointArray pa;
+ pa.makeArc(x, y, w, h, a, alen); // arc polyline
+
+ // Draw polygon
+ drawPolygon(&pa, false, false, false);
+
+ return;
+}
+
+void TQt3CairoPaintDevice::drawPie(int x, int y, int w, int h, int a, int alen) {
+ if (!m_painter) {
+ return;
+ }
+
+ // Make sure "a" is 0..360*16, as otherwise a*4 may overflow 16 bits.
+ if ( a > (360*16) ) {
+ a = a % (360*16);
+ }
+ else if ( a < 0 ) {
+ a = a % (360*16);
+ if ( a < 0 ) {
+ a += (360*16);
+ }
+ }
+
+ TQPointArray pa;
+ pa.makeArc(x, y, w, h, a, alen); // arc polyline
+ int n = pa.size();
+ int cx, cy;
+ cx = x+w/2;
+ cy = y+h/2;
+ pa.resize(n+2);
+ pa.setPoint(n, cx, cy); // add legs
+ pa.setPoint(n+1, pa.at(0));
+
+ // Draw polygon
+ drawPolygon(&pa, false, true, true);
+
+ return;
+}
+
+void TQt3CairoPaintDevice::drawChord(int x, int y, int w, int h, int a, int alen) {
+ if (!m_painter) {
+ return;
+ }
+
+ TQPointArray pa;
+ pa.makeArc(x, y, w-1, h-1, a, alen); // arc polygon
+ int n = pa.size();
+ pa.resize(n+1);
+ pa.setPoint(n, pa.at(0)); // connect endpoints
+
+ // Draw polygon
+ drawPolygon(&pa, false, true, true);
+
+ return;
}
/*!
@@ -478,7 +675,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
if (m_brush.style() != TQBrush::NoBrush) {
int line_width = m_pen.width();
cairo_rectangle(m_painter, x+line_width+CAIRO_PIXEL_OFFSET, y+line_width+CAIRO_PIXEL_OFFSET, width-(line_width*2), height-(line_width*2));
- dualStrokeBrush();
+ dualStrokeBrush(CAIRO_FILL_RULE_EVEN_ODD);
}
cairo_restore(m_painter);
}
@@ -488,22 +685,52 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
#endif
}
break;
-#if 0
case PdcDrawRoundRect:
- m_qt4painter->drawRoundedRect( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter), p[1].ival, p[2].ival );
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (p) {
+ drawRoundRect(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height, p[1].ival, p[2].ival);
+ }
+ cairo_restore(m_painter);
+ }
break;
case PdcDrawEllipse:
- m_qt4painter->drawEllipse( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter) );
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (p) {
+ drawEllipse(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height);
+ }
+ cairo_restore(m_painter);
+ }
break;
case PdcDrawArc:
- m_qt4painter->drawArc( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter), p[1].ival, p[2].ival );
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (p) {
+ drawArc(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height, p[1].ival, p[2].ival);
+ }
+ cairo_restore(m_painter);
+ }
break;
case PdcDrawPie:
- m_qt4painter->drawPie( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter), p[1].ival, p[2].ival );
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (p) {
+ drawPie(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height, p[1].ival, p[2].ival);
+ }
+ cairo_restore(m_painter);
+ }
break;
case PdcDrawChord:
- m_qt4painter->drawChord( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter), p[1].ival, p[2].ival );
+ if (m_painter) {
+ cairo_save(m_painter);
+ if (p) {
+ drawChord(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height, p[1].ival, p[2].ival);
+ }
+ cairo_restore(m_painter);
+ }
break;
+#if 0
case PdcDrawLineSegments:
index = 0;
count = -1;
@@ -512,36 +739,16 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
break;
#endif
case PdcDrawPolyline:
- if (m_painter) {
- cairo_save(m_painter);
- if (p) {
- const TQPointArray* pointarray = p[0].ptarr;
- if (pointarray) {
- int x;
- int y;
- bool first=true;
- for (i=0;i<pointarray->count();i++) {
- pointarray->point(i, &x, &y );
- if (first) {
- cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
- first = false;
- }
- else {
- cairo_line_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
- }
- }
- if (m_pen.style() != TQPen::NoPen) {
- dualStrokePen();
- }
- }
- }
- cairo_restore(m_painter);
+ if (p) {
+ drawPolygon(p[0].ptarr, false, false, true);
}
break;
-#if 0
case PdcDrawPolygon:
- m_qt4painter->drawPolygon( qt4polygon, (p[1].ival == 0)?Qt::OddEvenFill:Qt::WindingFill );
+ if (p) {
+ drawPolygon(p[0].ptarr, p[1].ival, true, true);
+ }
break;
+#if 0
case PdcDrawCubicBezier:
index = 0;
path.moveTo(qt4polygon.at(index));
@@ -592,14 +799,12 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
m_painter = NULL;
}
break;
-#if 0
case PdcSave:
- m_qt4painter->save();
+ cairo_save(m_painter);
break;
case PdcRestore:
- m_qt4painter->restore();
+ cairo_restore(m_painter);
break;
-#endif
case PdcSetBkColor:
if (p) {
const TQColor* color = p[0].color;
diff --git a/tdegtk/tqtcairopainter.h b/tdegtk/tqtcairopainter.h
index fa051c2..7e43468 100644
--- a/tdegtk/tqtcairopainter.h
+++ b/tdegtk/tqtcairopainter.h
@@ -44,8 +44,15 @@ class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice // picture class
void updatePen(bool backgroundStroke=FALSE);
void dualStrokePen();
- void updateBrush(bool backgroundStroke=FALSE);
- void dualStrokeBrush();
+ void updateBrush(bool backgroundStroke=FALSE, cairo_fill_rule_t fillMethod=CAIRO_FILL_RULE_WINDING);
+ void dualStrokeBrush(cairo_fill_rule_t fillMethod=CAIRO_FILL_RULE_WINDING);
+
+ void drawPolygon(const TQPointArray* pointarray, bool winding, bool fill, bool close);
+ void drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd);
+ void drawEllipse(int x, int y, int w, int h);
+ void drawArc(int x, int y, int w, int h, int a, int alen);
+ void drawPie(int x, int y, int w, int h, int a, int alen);
+ void drawChord(int x, int y, int w, int h, int a, int alen);
private:
cairo_surface_t *m_surface;
diff --git a/tests/test-painter.cpp b/tests/test-painter.cpp
index 8a2b02e..f932c83 100644
--- a/tests/test-painter.cpp
+++ b/tests/test-painter.cpp
@@ -65,7 +65,7 @@ main (int argc, char *argv[])
// Polyline tests
{
TQPointArray a;
- int x1 = 200;
+ int x1 = 250;
int y1 = 10;
a.setPoints( 11, x1+0, y1+85, x1+75, y1+75, x1+100, y1+10, x1+125, y1+75, x1+200, y1+85, x1+150, y1+125, x1+160, y1+190, x1+100, y1+150, x1+40, y1+190, x1+50, y1+125, x1+0, y1+85 );
@@ -73,6 +73,65 @@ main (int argc, char *argv[])
p.drawPolyline(a);
}
+ // Polyfill tests
+ {
+ TQPointArray a;
+ int x1 = 250;
+ int y1 = 200;
+
+ a.setPoints( 11, x1+0, y1+85, x1+75, y1+75, x1+100, y1+10, x1+125, y1+75, x1+200, y1+85, x1+150, y1+125, x1+160, y1+190, x1+100, y1+150, x1+40, y1+190, x1+50, y1+125, x1+0, y1+85 );
+ p.setPen(TQt::blue);
+ p.setBrush(TQt::green);
+ p.drawPolygon(a);
+ }
+
+ // Rounded rectangle tests
+ {
+ p.setBrush(TQt::green);
+ p.setPen(TQPen(TQt::red, 1));
+ p.drawRoundRect(10, 150, 50, 50);
+ p.setBrush(TQBrush());
+ p.setPen(TQPen(TQt::blue, 1));
+ p.drawRoundRect(80, 150, 50, 50);
+ }
+
+ // Ellipse tests
+ {
+ p.setBrush(TQt::green);
+ p.setPen(TQPen(TQt::red, 1));
+ p.drawEllipse(10, 220, 50, 50);
+ p.setBrush(TQBrush());
+ p.setPen(TQPen(TQt::blue, 1));
+ p.drawEllipse(80, 220, 50, 50);
+ }
+
+ // Arc tests
+ {
+ p.setBrush(TQBrush());
+ p.setPen(TQPen(TQt::yellow, 1));
+ p.drawArc(10,10, 70,100, 100*16, 160*16); // draws a "(" arc
+ }
+
+ // Pie tests
+ {
+ p.setBrush(TQBrush());
+ p.setPen(TQPen(TQt::red, 1));
+ p.drawPie(250, 400, 200, 100, 45*16, 90*16);
+ p.setBrush(TQt::green);
+ p.setPen(TQPen(TQt::blue, 1));
+ p.drawPie(250, 450, 200, 100, 45*16, 90*16);
+ }
+
+ // Chord tests
+ {
+ p.setBrush(TQBrush());
+ p.setPen(TQPen(TQt::red, 1));
+ p.drawChord(100, 400, 200, 100, 45*16, 90*16);
+ p.setBrush(TQt::green);
+ p.setPen(TQPen(TQt::blue, 1));
+ p.drawChord(100, 450, 200, 100, 45*16, 90*16);
+ }
+
p.end();
/* Write output and clean up */