Fix pixel imperfection, image drawing, and clipping problems

Update test suite
pull/1/head
Timothy Pearson 12 years ago
parent 467876d56a
commit 623f11f600

@ -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,8 +78,27 @@ 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;
}
@ -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);
@ -1088,6 +1132,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);

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

@ -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();
}

Loading…
Cancel
Save