summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-10-15 13:02:37 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-10-15 13:02:37 -0500
commit623f11f6000cb2f05f51c81e7a1c6fc02ce21907 (patch)
treeebff174e76c82e87e00f0f167073c2d435fef91a
parent467876d56afdf133bdce18b7a1ed13a303e82703 (diff)
downloadgtk3-tqt-engine-623f11f6000cb2f05f51c81e7a1c6fc02ce21907.tar.gz
gtk3-tqt-engine-623f11f6000cb2f05f51c81e7a1c6fc02ce21907.zip
Fix pixel imperfection, image drawing, and clipping problems
Update test suite
-rw-r--r--tdegtk/tqtcairopainter.cpp267
-rw-r--r--tdegtk/tqtcairopainter.h22
-rw-r--r--tests/test-painter.cpp28
3 files changed, 223 insertions, 94 deletions
diff --git a/tdegtk/tqtcairopainter.cpp b/tdegtk/tqtcairopainter.cpp
index 44b1895..c19a736 100644
--- a/tdegtk/tqtcairopainter.cpp
+++ b/tdegtk/tqtcairopainter.cpp
@@ -4,7 +4,7 @@
**
** Copyright (C) 2012 Timothy Pearson. All rights reserved.
**
-** This file is part of the TDE Qt4 style interface
+** This file is part of the TDE GTK3 style interface
**
** This file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free
@@ -30,7 +30,8 @@
#undef Qt
-#define CAIRO_PIXEL_OFFSET (0.5)
+#define CAIRO_PEN_PIXEL_OFFSET (0.5)
+#define CAIRO_BRUSH_PIXEL_OFFSET (0.0)
#define CAIRO_FONT_SIZE_FUDGE_FACTOR (1.4)
#define SET_BIT(x, y) (x |= 1 << y)
@@ -42,6 +43,30 @@
#define ARGB_G_BYTE_NUMBER 1
#define ARGB_B_BYTE_NUMBER 0
+inline int cairoPainterRectSubtraction(TQPen* pen) {
+ return ((pen->style() != TQt::NoPen) && ((pen->width() == 0) || (pen->width() == 1))) ? 1 : 0;
+}
+
+inline void standardAlphaToPremultipliedAlpha(unsigned char *a, unsigned char *r, unsigned char *g, unsigned char *b) {
+ register double alpha_adjust;
+
+ alpha_adjust = (*a / 255.0);
+ *r = char( *r * alpha_adjust );
+ *g = char( *g * alpha_adjust );
+ *b = char( *b * alpha_adjust );
+ *a = char( *a * 1.0 );
+}
+
+inline void premultipliedAlphaToStandardAlpha(unsigned char *a, unsigned char *r, unsigned char *g, unsigned char *b) {
+ register double alpha_adjust;
+
+ alpha_adjust = (*a / 255.0);
+ *r = char( *r / alpha_adjust );
+ *g = char( *g / alpha_adjust );
+ *b = char( *b / alpha_adjust );
+ *a = char( *a / 1.0 );
+}
+
cairo_surface_t* TQImageToCairoSurface(TQImage origimg) {
cairo_surface_t* ret;
@@ -53,9 +78,28 @@ cairo_surface_t* TQImageToCairoSurface(TQImage origimg) {
img = origimg;
}
- cairo_format_t cairo_format;
int depth = img.depth();
if (depth == 32) {
+ // Convert ARGB to premultiplied ARGB
+ // SLOW
+ int x;
+ int y;
+ for (x=0; x<img.width(); x++) {
+ for (y=0; y<img.height(); y++) {
+ unsigned int pixel = img.pixel(x, y);
+ unsigned char a = (pixel & 0xff000000) >> 24;
+ unsigned char r = (pixel & 0x00ff0000) >> 16;
+ unsigned char g = (pixel & 0x0000ff00) >> 8;
+ unsigned char b = (pixel & 0x000000ff) >> 0;
+ standardAlphaToPremultipliedAlpha(&a, &r, &g, &b);
+ pixel = (a << 24) | (r << 16) | (g << 8) | (b << 0);
+ img.setPixel(x, y, pixel);
+ }
+ }
+ }
+
+ cairo_format_t cairo_format;
+ if (depth == 32) {
cairo_format = CAIRO_FORMAT_ARGB32;
}
else if (depth == 24) {
@@ -99,31 +143,12 @@ void TQt3CairoPaintDevice::resetIntermediateSurface() {
cairo_surface_destroy(m_intermediateSurface);
}
- int height = cairo_image_surface_get_height(m_surface);
- int width = cairo_image_surface_get_width(m_surface);
+ updateSurfaceDimensions();
+ int height = m_height;
+ int width = m_width;
m_intermediateSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
}
-inline void standardAlphaToPremultipliedAlpha(unsigned char *a, unsigned char *r, unsigned char *g, unsigned char *b) {
- register double alpha_adjust;
-
- alpha_adjust = (*a / 255.0);
- *r = char( *r * alpha_adjust );
- *g = char( *g * alpha_adjust );
- *b = char( *b * alpha_adjust );
- *a = char( *a * 1.0 );
-}
-
-inline void premultipliedAlphaToStandardAlpha(unsigned char *a, unsigned char *r, unsigned char *g, unsigned char *b) {
- register double alpha_adjust;
-
- alpha_adjust = (*a / 255.0);
- *r = char( *r / alpha_adjust );
- *g = char( *g / alpha_adjust );
- *b = char( *b / alpha_adjust );
- *a = char( *a / 1.0 );
-}
-
void TQt3CairoPaintDevice::transferIntermediateSurface() {
bool overlayMerge = true;
cairo_surface_flush(m_intermediateSurface);
@@ -132,8 +157,9 @@ void TQt3CairoPaintDevice::transferIntermediateSurface() {
overlayMerge = false;
cairo_surface_flush(m_surface);
cairo_surface_flush(m_intermediateSurface);
- register int height = cairo_image_surface_get_height(m_surface);
- register int width = cairo_image_surface_get_width(m_surface);
+ updateSurfaceDimensions();
+ register int height = m_height;
+ register int width = m_width;
register int stride = cairo_format_stride_for_width(cairo_image_surface_get_format(m_surface), width);
cairo_surface_t *usableDeviceSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo_t *copyPainter = cairo_create(usableDeviceSurface);
@@ -182,19 +208,19 @@ void TQt3CairoPaintDevice::transferIntermediateSurface() {
// Perform requested bitwise operation
if (m_rop == TQPainter::OrROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = devicePixel_r | intermediatePixel_r;
combinedPixel_g = devicePixel_g | intermediatePixel_g;
combinedPixel_b = devicePixel_b | intermediatePixel_b;
}
else if (m_rop == TQPainter::XorROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = devicePixel_r ^ intermediatePixel_r;
combinedPixel_g = devicePixel_g ^ intermediatePixel_g;
combinedPixel_b = devicePixel_b ^ intermediatePixel_b;
}
else if (m_rop == TQPainter::NotAndROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = devicePixel_r & (~intermediatePixel_r);
combinedPixel_g = devicePixel_g & (~intermediatePixel_g);
combinedPixel_b = devicePixel_b & (~intermediatePixel_b);
@@ -206,25 +232,25 @@ void TQt3CairoPaintDevice::transferIntermediateSurface() {
combinedPixel_b = ~intermediatePixel_b;
}
else if (m_rop == TQPainter::NotOrROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = devicePixel_r | (~intermediatePixel_r);
combinedPixel_g = devicePixel_g | (~intermediatePixel_g);
combinedPixel_b = devicePixel_b | (~intermediatePixel_b);
}
else if (m_rop == TQPainter::NotXorROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = devicePixel_r ^ (~intermediatePixel_r);
combinedPixel_g = devicePixel_g ^ (~intermediatePixel_g);
combinedPixel_b = devicePixel_b ^ (~intermediatePixel_b);
}
else if (m_rop == TQPainter::AndROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = devicePixel_r & intermediatePixel_r;
combinedPixel_g = devicePixel_g & intermediatePixel_g;
combinedPixel_b = devicePixel_b & intermediatePixel_b;
}
else if (m_rop == TQPainter::NotROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = ~devicePixel_r;
combinedPixel_g = ~devicePixel_g;
combinedPixel_b = ~devicePixel_b;
@@ -242,31 +268,31 @@ void TQt3CairoPaintDevice::transferIntermediateSurface() {
combinedPixel_b = 0xff;
}
else if (m_rop == TQPainter::NopROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = devicePixel_r;
combinedPixel_g = devicePixel_g;
combinedPixel_b = devicePixel_b;
}
else if (m_rop == TQPainter::AndNotROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = (~devicePixel_r) & intermediatePixel_r;
combinedPixel_g = (~devicePixel_g) & intermediatePixel_g;
combinedPixel_b = (~devicePixel_b) & intermediatePixel_b;
}
else if (m_rop == TQPainter::OrNotROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = (~devicePixel_r) | intermediatePixel_r;
combinedPixel_g = (~devicePixel_g) | intermediatePixel_g;
combinedPixel_b = (~devicePixel_b) | intermediatePixel_b;
}
else if (m_rop == TQPainter::NandROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = ~(devicePixel_r & intermediatePixel_r);
combinedPixel_g = ~(devicePixel_g & intermediatePixel_g);
combinedPixel_b = ~(devicePixel_b & intermediatePixel_b);
}
else if (m_rop == TQPainter::NorROP) {
- combinedPixel_a = devicePixel_a;
+ combinedPixel_a = ((devicePixel_a != 0) || (intermediatePixel_a != 0))?0xff:0x00;
combinedPixel_r = ~(devicePixel_r | intermediatePixel_r);
combinedPixel_g = ~(devicePixel_g | intermediatePixel_g);
combinedPixel_b = ~(devicePixel_b | intermediatePixel_b);
@@ -308,9 +334,9 @@ void TQt3CairoPaintDevice::transferIntermediateSurface() {
else {
// Clipping enabled
cairo_surface_t* maskSurface = TQImageToCairoSurface(m_clipRegion);
- cairo_mask_surface(m_devicePainter, maskSurface, 0, 0);
+ cairo_set_source_surface(m_devicePainter, m_intermediateSurface, 0, 0);
cairo_set_operator(m_devicePainter, overlayMerge?CAIRO_OPERATOR_OVER:CAIRO_OPERATOR_SOURCE);
- cairo_fill(m_devicePainter);
+ cairo_mask_surface(m_devicePainter, maskSurface, 0, 0);
cairo_surface_destroy(maskSurface);
}
@@ -564,7 +590,7 @@ void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke, cairo_fill_rule_t
cairo_surface_t* brushSurface = TQImageToCairoSurface(brushImage);
cairo_pattern_t* pattern = cairo_pattern_create_for_surface(brushSurface);
cairo_matrix_t brush_translation_matrix;
- cairo_matrix_init_translate(&brush_translation_matrix, m_brushOrigin.x(), m_brushOrigin.y());
+ cairo_matrix_init_translate(&brush_translation_matrix, m_brushOrigin.x()+1, m_brushOrigin.y());
cairo_pattern_set_matrix(pattern, &brush_translation_matrix);
cairo_set_source(m_painter, pattern);
cairo_pattern_set_extend(cairo_get_source(m_painter), CAIRO_EXTEND_REPEAT);
@@ -607,11 +633,11 @@ void TQt3CairoPaintDevice::drawPolygon(const TQPointArray* pointarray, bool wind
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);
+ cairo_move_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
first = false;
}
else {
- cairo_line_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ cairo_line_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
}
}
if (close) {
@@ -624,11 +650,11 @@ void TQt3CairoPaintDevice::drawPolygon(const TQPointArray* pointarray, bool wind
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);
+ cairo_move_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
first = false;
}
else {
- cairo_line_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ cairo_line_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
}
}
if (close) {
@@ -646,6 +672,9 @@ void TQt3CairoPaintDevice::drawRoundRect(int x, int y, int w, int h, int xRnd, i
return;
}
+ w=w+2;
+ h=h+2;
+
if ( xRnd <= 0 || yRnd <= 0 ) {
// Draw normal rectangle
TQPDevCmdParam param[2];
@@ -664,7 +693,7 @@ void TQt3CairoPaintDevice::drawRoundRect(int x, int y, int w, int h, int xRnd, i
}
if ( w <= 0 || h <= 0 ) {
- fix_neg_rect( &x, &y, &w, &h );
+ fix_neg_rect( &x, &y, &w, &h );
}
w--;
h--;
@@ -707,7 +736,7 @@ void TQt3CairoPaintDevice::drawEllipse(int x, int y, int w, int h) {
}
TQPointArray a;
- a.makeArc(x, y, w, h, 0, 360*16);
+ a.makeArc(x, y, w+1, h+1, 0, 360*16);
// Draw polygon
drawPolygon(&a, false, true, true);
@@ -749,8 +778,8 @@ void TQt3CairoPaintDevice::drawPie(int x, int y, int w, int h, int a, int alen)
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;
+ cx = (x+w/2)+1;
+ cy = (y+h/2)+1;
pa.resize(n+2);
pa.setPoint(n, cx, cy); // add legs
pa.setPoint(n+1, pa.at(0));
@@ -767,7 +796,7 @@ void TQt3CairoPaintDevice::drawChord(int x, int y, int w, int h, int a, int alen
}
TQPointArray pa;
- pa.makeArc(x, y, w-1, h-1, a, alen); // arc polygon
+ pa.makeArc(x, y, w, h, a, alen); // arc polygon
int n = pa.size();
pa.resize(n+1);
pa.setPoint(n, pa.at(0)); // connect endpoints
@@ -787,6 +816,7 @@ void TQt3CairoPaintDevice::pangoSetupTextPath(PangoLayout *layout, const char* t
// FIXME
// overline and a handful of other flags are not supported by Pango!
+ // https://bugzilla.gnome.org/show_bug.cgi?id=577190
TQString family = m_font.family();
// bool bold = m_font.bold();
bool italic = m_font.italic();
@@ -948,7 +978,7 @@ void TQt3CairoPaintDevice::drawTextInRect(TQPainter *p, TQRect rect, int textFla
pango_layout_set_height(layout, 0);
}
if (!(textFlags & TQt::DontClip)) {
- cairo_rectangle(m_painter, rect.x()+CAIRO_PIXEL_OFFSET, rect.y()+CAIRO_PIXEL_OFFSET, rect.width(), rect.height());
+ cairo_rectangle(m_painter, rect.x()+CAIRO_PEN_PIXEL_OFFSET, rect.y()+CAIRO_PEN_PIXEL_OFFSET, rect.width(), rect.height());
cairo_clip(m_painter);
}
if (textFlags & TQt::ExpandTabs) {
@@ -1053,10 +1083,24 @@ void TQt3CairoPaintDevice::setCairoTransformations() {
Constructs TQt3CairoPaintDevice on an existing QPainter
*/
-TQt3CairoPaintDevice::TQt3CairoPaintDevice( cairo_surface_t *cairosurface )
- : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice ), m_intermediateSurface(NULL), m_painter(NULL), m_devicePainter(NULL), m_tabStops(NULL), m_tabStopArray(NULL)
+TQt3CairoPaintDevice::TQt3CairoPaintDevice( cairo_surface_t *cairosurface, int width, int height, cairo_t *overridepainter )
+ : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice )
{
- m_surface = cairosurface;
+ init();
+
+ if (width >= 0) {
+ m_width = width;
+ }
+ if (height >= 0) {
+ m_height = width;
+ }
+ if (overridepainter) {
+ m_overridePainter = overridepainter;
+ m_surface = cairo_get_group_target(overridepainter);
+ }
+ else {
+ m_surface = cairosurface;
+ }
m_worldMatrixStack.setAutoDelete(TRUE);
m_tabStops = pango_tab_array_new(0, false);
@@ -1089,6 +1133,31 @@ TQt3CairoPaintDevice::~TQt3CairoPaintDevice()
}
/*!
+ Initializes all data structures
+*/
+void TQt3CairoPaintDevice::init() {
+ m_width = -1;
+ m_height = -1;
+
+ m_intermediateSurface = NULL;
+ m_painter = NULL;
+ m_devicePainter = NULL;
+ m_overridePainter = NULL;
+ m_tabStops = NULL;
+ m_tabStopArray = NULL;
+}
+
+void TQt3CairoPaintDevice::updateSurfaceDimensions() const {
+ if ((m_width < 0) || (m_height < 0)) {
+ m_width = cairo_image_surface_get_width(m_surface);
+ m_height = cairo_image_surface_get_height(m_surface);
+ }
+ if ((m_width < 1) || (m_height < 1)) {
+ printf("[WARNING] Cairo surface height or width less than 0; drawing will not be possible!\n\r"); fflush(stdout);
+ }
+}
+
+/*!
\internal
Implementation of the function forwarded above to the internal data struct.
*/
@@ -1136,8 +1205,8 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
if (m_painter) {
cairo_save(m_painter);
if (m_pen.style() != TQPen::NoPen) {
- cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
- cairo_line_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ cairo_move_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
+ cairo_line_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
updatePen(FALSE);
cairo_set_line_cap(m_painter, CAIRO_LINE_CAP_ROUND);
cairo_stroke(m_painter);
@@ -1150,7 +1219,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
if (m_painter) {
cairo_save(m_painter);
if (m_pen.style() != TQPen::NoPen) {
- cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
+ cairo_move_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
}
cairo_restore(m_painter);
}
@@ -1159,7 +1228,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
if (m_painter) {
cairo_save(m_painter);
if (m_pen.style() != TQPen::NoPen) {
- cairo_line_to(m_painter, x2+CAIRO_PIXEL_OFFSET, y2+CAIRO_PIXEL_OFFSET);
+ cairo_line_to(m_painter, x2+CAIRO_PEN_PIXEL_OFFSET, y2+CAIRO_PEN_PIXEL_OFFSET);
dualStrokePen();
}
cairo_restore(m_painter);
@@ -1169,8 +1238,8 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
if (m_painter) {
cairo_save(m_painter);
if (m_pen.style() != TQPen::NoPen) {
- cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
- cairo_line_to(m_painter, x2+CAIRO_PIXEL_OFFSET, y2+CAIRO_PIXEL_OFFSET);
+ cairo_move_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
+ cairo_line_to(m_painter, x2+CAIRO_PEN_PIXEL_OFFSET, y2+CAIRO_PEN_PIXEL_OFFSET);
dualStrokePen();
}
cairo_restore(m_painter);
@@ -1179,15 +1248,16 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
case PdcDrawRect:
if (m_painter) {
cairo_save(m_painter);
- if (m_pen.style() != TQPen::NoPen) {
- cairo_rectangle(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height);
- dualStrokePen();
- }
+ int adjustment = cairoPainterRectSubtraction(&m_pen);
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));
+ cairo_rectangle(m_painter, x+line_width+CAIRO_BRUSH_PIXEL_OFFSET, y+line_width+CAIRO_BRUSH_PIXEL_OFFSET, width-(line_width*2)-adjustment, height-(line_width*2)-adjustment);
dualStrokeBrush(CAIRO_FILL_RULE_EVEN_ODD);
}
+ if (m_pen.style() != TQPen::NoPen) {
+ cairo_rectangle(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET, width-adjustment, height-adjustment);
+ dualStrokePen();
+ }
cairo_restore(m_painter);
}
else {
@@ -1199,8 +1269,9 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
case PdcDrawRoundRect:
if (m_painter) {
cairo_save(m_painter);
+ int adjustment = cairoPainterRectSubtraction(&m_pen);
if (p) {
- drawRoundRect(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height, p[1].ival, p[2].ival);
+ drawRoundRect(x, y, width-adjustment, height-adjustment, p[1].ival, p[2].ival);
}
cairo_restore(m_painter);
}
@@ -1208,8 +1279,9 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
case PdcDrawEllipse:
if (m_painter) {
cairo_save(m_painter);
+ int adjustment = cairoPainterRectSubtraction(&m_pen);
if (p) {
- drawEllipse(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height);
+ drawEllipse(x, y, width-adjustment, height-adjustment);
}
cairo_restore(m_painter);
}
@@ -1217,8 +1289,9 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
case PdcDrawArc:
if (m_painter) {
cairo_save(m_painter);
+ int adjustment = cairoPainterRectSubtraction(&m_pen);
if (p) {
- drawArc(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height, p[1].ival, p[2].ival);
+ drawArc(x, y, width-adjustment, height-adjustment, p[1].ival, p[2].ival);
}
cairo_restore(m_painter);
}
@@ -1226,8 +1299,9 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
case PdcDrawPie:
if (m_painter) {
cairo_save(m_painter);
+ int adjustment = cairoPainterRectSubtraction(&m_pen);
if (p) {
- drawPie(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height, p[1].ival, p[2].ival);
+ drawPie(x, y, width-adjustment, height-adjustment, p[1].ival, p[2].ival);
}
cairo_restore(m_painter);
}
@@ -1235,8 +1309,9 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
case PdcDrawChord:
if (m_painter) {
cairo_save(m_painter);
+ int adjustment = cairoPainterRectSubtraction(&m_pen);
if (p) {
- drawChord(x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET, width, height, p[1].ival, p[2].ival);
+ drawChord(x, y, width-adjustment, height-adjustment, p[1].ival, p[2].ival);
}
cairo_restore(m_painter);
}
@@ -1255,8 +1330,8 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
for (i=0;i<pointarray->count();i=i+2) {
pointarray->point(i+0, &x, &y);
pointarray->point(i+1, &x2, &y2);
- cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
- cairo_line_to(m_painter, x2+CAIRO_PIXEL_OFFSET, y2+CAIRO_PIXEL_OFFSET);
+ cairo_move_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
+ cairo_line_to(m_painter, x2+CAIRO_PEN_PIXEL_OFFSET, y2+CAIRO_PEN_PIXEL_OFFSET);
dualStrokePen();
}
}
@@ -1267,7 +1342,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
break;
case PdcDrawPolyline:
if (p) {
- drawPolygon(p[0].ptarr, false, false, true);
+ drawPolygon(p[0].ptarr, false, false, false);
}
break;
case PdcDrawPolygon:
@@ -1295,8 +1370,8 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
pointarray->point(i+1, &x2, &y2);
pointarray->point(i+2, &x3, &y3);
pointarray->point(i+3, &x4, &y4);
- cairo_move_to(m_painter, x+CAIRO_PIXEL_OFFSET, y+CAIRO_PIXEL_OFFSET);
- cairo_curve_to(m_painter, x2+CAIRO_PIXEL_OFFSET, y2+CAIRO_PIXEL_OFFSET, x3+CAIRO_PIXEL_OFFSET, y3+CAIRO_PIXEL_OFFSET, x4+CAIRO_PIXEL_OFFSET, y4+CAIRO_PIXEL_OFFSET);
+ cairo_move_to(m_painter, x+CAIRO_PEN_PIXEL_OFFSET, y+CAIRO_PEN_PIXEL_OFFSET);
+ cairo_curve_to(m_painter, x2+CAIRO_PEN_PIXEL_OFFSET, y2+CAIRO_PEN_PIXEL_OFFSET, x3+CAIRO_PEN_PIXEL_OFFSET, y3+CAIRO_PEN_PIXEL_OFFSET, x4+CAIRO_PEN_PIXEL_OFFSET, y4+CAIRO_PEN_PIXEL_OFFSET);
dualStrokePen();
}
}
@@ -1310,7 +1385,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
cairo_save(m_painter);
if (p) {
TQString string = *p[1].str;
- drawText(pt, p[0].rect->x()+CAIRO_PIXEL_OFFSET, p[0].rect->y()+CAIRO_PIXEL_OFFSET, string);
+ drawText(pt, p[0].rect->x()+CAIRO_PEN_PIXEL_OFFSET, p[0].rect->y()+CAIRO_PEN_PIXEL_OFFSET, string);
}
cairo_restore(m_painter);
}
@@ -1331,7 +1406,7 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
cairo_save(m_painter);
if (p) {
TQString string = *p[1].str;
- drawText(pt, p[0].rect->x()+CAIRO_PIXEL_OFFSET, p[0].rect->y()+CAIRO_PIXEL_OFFSET, string);
+ drawText(pt, p[0].rect->x()+CAIRO_PEN_PIXEL_OFFSET, p[0].rect->y()+CAIRO_PEN_PIXEL_OFFSET, string);
}
cairo_restore(m_painter);
}
@@ -1351,7 +1426,17 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
if (m_painter) {
cairo_save(m_painter);
if (p) {
- TQImage sourceImage = p[1].pixmap->convertToImage();
+ TQImage sourceImage;
+ const TQBitmap* bitmap = dynamic_cast<const TQBitmap*>(p[1].pixmap);
+ if (bitmap) {
+ TQPixmap mergedPixmap = TQPixmap(bitmap->width(), bitmap->height());
+ mergedPixmap.fill(m_pen.color());
+ mergedPixmap.setMask(*bitmap);
+ sourceImage = mergedPixmap.convertToImage();
+ }
+ else {
+ sourceImage = p[1].pixmap->convertToImage();
+ }
cairo_surface_t* sourceSurface = TQImageToCairoSurface(sourceImage);
cairo_rectangle(m_painter, p[0].rect->x(), p[0].rect->y(), p[0].rect->width(), p[0].rect->height());
cairo_set_source_surface(m_painter, sourceSurface, p[0].rect->x(), p[0].rect->y());
@@ -1385,7 +1470,13 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
resetIntermediateSurface();
m_painter = cairo_create(m_intermediateSurface);
cairo_set_operator(m_painter, CAIRO_OPERATOR_OVER);
- m_devicePainter = cairo_create(m_surface);
+ if (m_overridePainter) {
+ m_devicePainter = m_overridePainter;
+ }
+ else {
+ m_devicePainter = cairo_create(m_surface);
+ }
+ cairo_set_antialias(m_devicePainter, CAIRO_ANTIALIAS_NONE);
m_pen = TQPen();
m_brush = TQBrush();
m_brushOrigin = TQPoint(0,0);
@@ -1408,7 +1499,9 @@ bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
m_painter = NULL;
}
if (m_devicePainter) {
- cairo_destroy(m_devicePainter);
+ if (!m_overridePainter) {
+ cairo_destroy(m_devicePainter);
+ }
m_devicePainter = NULL;
}
break;
@@ -1650,18 +1743,22 @@ int TQt3CairoPaintDevice::metric( int m ) const
switch ( m ) {
// ### hard coded dpi and color depth values !
case TQPaintDeviceMetrics::PdmWidth:
- val = cairo_image_surface_get_width(m_surface);
+ updateSurfaceDimensions();
+ val = m_width;
break;
case TQPaintDeviceMetrics::PdmHeight:
- val = cairo_image_surface_get_height(m_surface);
+ updateSurfaceDimensions();
+ val = m_height;
break;
case TQPaintDeviceMetrics::PdmWidthMM:
+ updateSurfaceDimensions();
cairo_surface_get_fallback_resolution(m_surface, &x_pixels_per_inch, &y_pixels_per_inch);
- val = ((cairo_image_surface_get_width(m_surface)/x_pixels_per_inch)*25.4);
+ val = ((m_width/x_pixels_per_inch)*25.4);
break;
case TQPaintDeviceMetrics::PdmHeightMM:
+ updateSurfaceDimensions();
cairo_surface_get_fallback_resolution(m_surface, &x_pixels_per_inch, &y_pixels_per_inch);
- val = ((cairo_image_surface_get_height(m_surface)/y_pixels_per_inch)*25.4);
+ val = ((m_height/y_pixels_per_inch)*25.4);
break;
case TQPaintDeviceMetrics::PdmDpiX:
cairo_surface_get_fallback_resolution(m_surface, &x_pixels_per_inch, &y_pixels_per_inch);
diff --git a/tdegtk/tqtcairopainter.h b/tdegtk/tqtcairopainter.h
index 404c526..20a03d3 100644
--- a/tdegtk/tqtcairopainter.h
+++ b/tdegtk/tqtcairopainter.h
@@ -4,7 +4,7 @@
**
** Copyright (C) 2012 Timothy Pearson. All rights reserved.
**
-** This file is part of the TDE Qt4 style interface
+** This file is part of the TDE GTK3 style interface
**
** This file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free
@@ -18,8 +18,8 @@
**
**********************************************************************/
-#ifndef TDEQT4PAINTER_H
-#define TDEQT4PAINTER_H
+#ifndef TQTCAIROPAINTER_H
+#define TQTCAIROPAINTER_H
#define TQT_NO_COMPAT_NAMES
#include "ntqpaintdevice.h"
@@ -40,14 +40,16 @@ typedef TQPtrStack<TQWMatrix> TQWMatrixStack;
class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice // picture class
{
public:
- TQt3CairoPaintDevice( cairo_surface_t * );
+ TQt3CairoPaintDevice( cairo_surface_t *, int width = -1, int height = -1, cairo_t *overridepainter = NULL );
~TQt3CairoPaintDevice();
-
+
protected:
bool cmd( int, TQPainter *, TQPDevCmdParam * );
int metric( int ) const;
-
+
private:
+ void init();
+ void updateSurfaceDimensions() const;
void resetIntermediateSurface();
void transferIntermediateSurface();
@@ -69,12 +71,16 @@ class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice // picture class
void drawTextInRect(TQPainter *p, TQRect rect, int textFlags, const TQString &str);
void setCairoTransformations();
-
+
private:
+ mutable int m_width;
+ mutable int m_height;
+
cairo_surface_t *m_surface;
cairo_surface_t *m_intermediateSurface;
cairo_t *m_painter;
cairo_t *m_devicePainter;
+ cairo_t *m_overridePainter;
cairo_matrix_t m_worldMatrix;
cairo_matrix_t m_viewportMatrix;
bool m_worldMatrixEnabled;
@@ -97,4 +103,4 @@ class Q_EXPORT TQt3CairoPaintDevice : public TQPaintDevice // picture class
bool m_tabStopArrayValid;
};
-#endif // TDEQT4PAINTER_H
+#endif // TQTCAIROPAINTER_H
diff --git a/tests/test-painter.cpp b/tests/test-painter.cpp
index 45e064c..3c21432 100644
--- a/tests/test-painter.cpp
+++ b/tests/test-painter.cpp
@@ -2,6 +2,7 @@
#include <tqpainter.h>
#include <tqapplication.h>
+#include <tqstyle.h>
#include "tqtcairopainter.h"
@@ -36,6 +37,14 @@ void drawColorWheel(TQPainter *p, double scale)
void runTests(TQPaintDevice* pd) {
TQPainter p(pd);
+ // Background
+ {
+ p.setPen( TQt::NoPen );
+ TQBrush brush(TQColor(0,0,0), TQBrush::SolidPattern);
+ p.setBrush(brush);
+ p.drawRect(0,0,1000,1000);
+ }
+
// Rectangle tests
{
p.setPen(TQPen(TQt::red, 1));
@@ -44,8 +53,9 @@ void runTests(TQPaintDevice* pd) {
p.setBrush( brush ); // set the yellow brush
p.setPen( TQt::NoPen ); // do not draw outline
p.drawRect( 0,0, 25,25 ); // draw filled rectangle
+ p.drawRect( 452,400, 25,25 ); // draw filled rectangle
TQBrush brush2( TQt::green, TQBrush::SolidPattern ); // green pattern
- p.setBrush( brush2 ); // set the yellow brush
+ p.setBrush( brush2 ); // set the green brush
p.setPen( TQt::NoPen ); // do not draw outline
p.drawRect( 40,30, 200,100 ); // draw filled rectangle
p.setBrush( TQt::NoBrush ); // do not fill
@@ -100,6 +110,9 @@ void runTests(TQPaintDevice* pd) {
p.setBrush(TQBrush());
p.setPen(TQPen(TQt::blue, 1));
p.drawRoundRect(80, 150, 50, 50);
+ p.setBrush(TQt::green);
+ p.setPen(TQPen());
+ p.drawRoundRect(150, 150, 50, 50);
}
// Ellipse tests
@@ -110,6 +123,9 @@ void runTests(TQPaintDevice* pd) {
p.setBrush(TQBrush());
p.setPen(TQPen(TQt::blue, 1));
p.drawEllipse(80, 220, 50, 50);
+ p.setBrush(TQt::green);
+ p.setPen(TQPen());
+ p.drawEllipse(150, 220, 50, 50);
}
// Arc tests
@@ -161,6 +177,7 @@ void runTests(TQPaintDevice* pd) {
p.drawCubicBezier(a);
}
+#if 1
// Pixmap tests
{
TQPixmap pixmap("open.png");
@@ -172,7 +189,9 @@ void runTests(TQPaintDevice* pd) {
TQImage image("open.png");
p.drawImage(350, 10, image, 0, 0, -1, -1);
}
+#endif
+#if 0
// Font tests
{
p.setPen(TQColor(0,128,255));
@@ -208,6 +227,7 @@ void runTests(TQPaintDevice* pd) {
//p.drawText( TQRect(0, 250, 250, 150), TQt::BreakAnywhere | TQt::AlignCenter, TQString("TQt3 renders via Cairo!") );
//p.drawText( TQRect(0, 250, 250, 150), TQt::BreakAnywhere | TQt::AlignHCenter | TQt::AlignBottom, TQString("TQt3 renders via Cairo!") );
}
+#endif
// Clipping tests
{
@@ -226,11 +246,17 @@ void runTests(TQPaintDevice* pd) {
p.setBrush(TQBrush(TQt::white));
p.setPen(TQPen());
p.drawRect(325, 275, 50, 50);
+ p.setRasterOp(TQPainter::CopyROP);
}
//drawColorWheel(&p, 0.5);
//drawColorWheel(&p, 1.0);
+ TQColorGroup cg;
+ cg.setColor(TQColorGroup::Background, TQColor(128,128,128));
+ cg.setColor(TQColorGroup::Foreground, TQColor(0,0,0));
+ tqApp->style().drawPrimitive(TQStyle::PE_ExclusiveIndicator, &p, TQRect(400, 400, 16, 16), cg, TQStyle::Style_Down);
+
p.end();
}