Add more primitives to Cairo drawing backend

pull/1/head
Timothy Pearson 12 years ago
parent 2e57d2cf81
commit 7d1ad9f6f5

@ -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;

@ -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;

@ -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 */

Loading…
Cancel
Save