You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gtk3-tqt-engine/tdegtk/tqtcairopainter.cpp

814 lines
22 KiB

/****************************************************************************
**
** Implementation of TQt3CairoPaintDevice class
**
** Copyright (C) 2012 Timothy Pearson. All rights reserved.
**
** This file is part of the TDE Qt4 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
** Software Foundation and appearing in the files LICENSE.GPL2
** and LICENSE.GPL3 included in the packaging of this file.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
** herein.
**
**********************************************************************/
#include "tqtcairopainter.h"
#define TQT_NO_COMPAT_NAMES
#include "tqpainter.h"
#include "tqpixmap.h"
#include "tqbitmap.h"
#include "tqimage.h"
#include "tqfile.h"
#include "tqpaintdevicemetrics.h"
#undef Qt
#define CAIRO_PIXEL_OFFSET (0.5)
#define SET_BIT(x, y) (x |= 1 << y)
#define TEST_BIT(x, y) ((x & (1 << y)) >> y)
cairo_surface_t* TQImageToCairoSurface(TQImage origimg) {
cairo_surface_t* ret;
TQImage img;
if (origimg.depth() < 24) {
img = origimg.convertDepth(32);
}
else {
img = origimg;
}
cairo_format_t cairo_format;
int depth = img.depth();
if (depth == 32) {
cairo_format = CAIRO_FORMAT_ARGB32;
}
else if (depth == 24) {
cairo_format = CAIRO_FORMAT_RGB24;
}
else {
cairo_format = CAIRO_FORMAT_RGB24;
}
int stride = cairo_format_stride_for_width(cairo_format, img.width());
ret = cairo_image_surface_create_for_data(img.bits(), cairo_format, img.width(), img.height(), stride);
return ret;
}
TQImage CairoSurfaceToTQImage(cairo_surface_t* surface) {
cairo_surface_flush(surface);
cairo_format_t cairo_format = cairo_image_surface_get_format(surface);
int height = cairo_image_surface_get_height(surface);
int width = cairo_image_surface_get_width(surface);
int depth;
if (cairo_format == CAIRO_FORMAT_ARGB32) {
depth = 32;
}
else if (cairo_format == CAIRO_FORMAT_RGB24) {
depth = 24;
}
else {
// FIXME
// Force Cairo to convert the surface to a format that TQImage can read!
printf("[WARNING] Tried to convert a Cairo surface of format %d to a TQImage (NULL image returned!)\n\r", cairo_format); fflush(stdout);
return TQImage();
}
return TQImage(cairo_image_surface_get_data(surface), width, height, depth, (TQRgb*)NULL, 0, TQImage::BigEndian);
}
void TQt3CairoPaintDevice::dualStrokePen() {
if (m_bgColorMode == TQt::OpaqueMode) {
// Draw background
cairo_save(m_painter);
updatePen(TRUE);
cairo_stroke(m_painter);
cairo_restore(m_painter);
}
// Draw foreground
updatePen(FALSE);
cairo_stroke(m_painter);
}
void TQt3CairoPaintDevice::dualStrokeBrush() {
if (m_bgColorMode == TQt::OpaqueMode) {
// Draw background
cairo_save(m_painter);
updateBrush(TRUE);
cairo_fill(m_painter);
cairo_restore(m_painter);
}
// Draw foreground
updateBrush(FALSE);
cairo_fill(m_painter);
}
void TQt3CairoPaintDevice::updatePen(bool backgroundStroke) {
if (!m_painter) {
return;
}
int ps = m_pen.style();
double dashes[10]; // custom pen dashes
int dash_len = 0; // length of dash list
int dash_offset = 0;
cairo_line_cap_t cp = CAIRO_LINE_CAP_BUTT;
cairo_line_join_t jn = CAIRO_LINE_JOIN_MITER;
/*
We are emulating Windows here. Windows treats m_pen.width() == 1
(or 0) as a very special case. The fudge variable unifies this
case with the general case.
*/
int dot = m_pen.width(); // width of a dot
int fudge = 1;
//bool allow_zero_lw = TRUE;
bool allow_zero_lw = FALSE;
if ( dot <= 1 ) {
dot = 3;
fudge = 2;
}
switch( ps ) {
case TQPainter::NoPen:
case TQPainter::SolidLine:
break;
case TQPainter::DashLine:
dashes[0] = fudge * 3 * dot;
dashes[1] = fudge * dot;
dash_len = 2;
allow_zero_lw = FALSE;
break;
case TQPainter::DotLine:
dashes[0] = dot;
dashes[1] = dot;
dash_len = 2;
allow_zero_lw = FALSE;
break;
case TQPainter::DashDotLine:
dashes[0] = 3 * dot;
dashes[1] = fudge * dot;
dashes[2] = dot;
dashes[3] = fudge * dot;
dash_len = 4;
allow_zero_lw = FALSE;
break;
case TQPainter::DashDotDotLine:
dashes[0] = 3 * dot;
dashes[1] = dot;
dashes[2] = dot;
dashes[3] = dot;
dashes[4] = dot;
dashes[5] = dot;
dash_len = 6;
allow_zero_lw = FALSE;
break;
case TQPainter::FineDotLine:
dot = 1;
dashes[0] = dot;
dashes[1] = dot;
dash_len = 2;
allow_zero_lw = FALSE;
}
Q_ASSERT( dash_len <= (int) sizeof(dashes) );
switch ( m_pen.capStyle() ) {
case TQPainter::SquareCap:
cp = CAIRO_LINE_CAP_SQUARE;
break;
case TQPainter::RoundCap:
cp = CAIRO_LINE_CAP_ROUND;
break;
case TQPainter::FlatCap:
default:
cp = CAIRO_LINE_CAP_BUTT;
break;
}
switch ( m_pen.joinStyle() ) {
case TQPainter::BevelJoin:
jn = CAIRO_LINE_JOIN_BEVEL;
break;
case TQPainter::RoundJoin:
jn = CAIRO_LINE_JOIN_ROUND;
break;
case TQPainter::MiterJoin:
default:
jn = CAIRO_LINE_JOIN_MITER;
break;
}
if (backgroundStroke) {
dash_len = 0;
}
cairo_set_dash(m_painter, dashes, dash_len, dash_offset);
cairo_set_line_cap(m_painter, cp);
cairo_set_line_join(m_painter, jn);
cairo_set_line_width(m_painter, ((!allow_zero_lw) && (m_pen.width() == 0)) ? 1 : m_pen.width());
TQRgb color = (backgroundStroke)?m_bgColor.rgb():m_pen.color().rgb();
cairo_set_source_rgba(m_painter, tqRed(color), tqGreen(color), tqBlue(color), tqAlpha(color));
}
void TQt3CairoPaintDevice::updateBrush(bool backgroundStroke) {
if (!m_painter) {
return;
}
if (backgroundStroke) {
TQRgb color = m_bgColor.rgb();
cairo_pattern_t* pattern = cairo_pattern_create_rgba(tqRed(color), tqGreen(color), tqBlue(color), tqAlpha(color));
cairo_set_source(m_painter, pattern);
cairo_pattern_set_extend(cairo_get_source(m_painter), CAIRO_EXTEND_REPEAT);
cairo_pattern_destroy(pattern);
}
else {
static const uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
static const uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
static const uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
static const uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
static const uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
static const uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
static const uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
static const uchar hor_pat[] = { // horizontal pattern
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const uchar ver_pat[] = { // vertical pattern
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20 };
static const uchar cross_pat[] = { // cross pattern
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0xff, 0xff, 0xff,
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
0x08, 0x82, 0x20, 0xff, 0xff, 0xff, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0xff, 0xff, 0xff,
0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
0x08, 0x82, 0x20, 0xff, 0xff, 0xff, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20 };
static const uchar bdiag_pat[] = { // backward diagonal pattern
0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01,
0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04,
0x02, 0x02, 0x01, 0x01, 0x80, 0x80, 0x40, 0x40 };
static const uchar fdiag_pat[] = { // forward diagonal pattern
0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
0x80, 0x80, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10,
0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x01, 0x01 };
static const uchar dcross_pat[] = { // diagonal cross pattern
0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x41, 0x41,
0x80, 0x80, 0x41, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x14, 0x14,
0x22, 0x22, 0x41, 0x41, 0x80, 0x80, 0x41, 0x41 };
static const uchar * const pat_tbl[] = {
dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
dense6_pat, dense7_pat,
hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
int bs = m_brush.style();
const uchar *pat = 0; // pattern
int d = 0; // defalt pattern size: d*d
if ( bs >= TQBrush::Dense1Pattern && bs <= TQBrush::DiagCrossPattern ) {
pat = pat_tbl[ bs-TQBrush::Dense1Pattern ];
if ( bs <= TQBrush::Dense7Pattern ) {
d = 8;
}
else if ( bs <= TQBrush::CrossPattern ) {
d = 24;
}
else {
d = 16;
}
}
if ( (bs == TQBrush::CustomPattern) || pat ) {
TQImage brushImage;
if ( pat ) {
TQRgb color = m_brush.color().rgb();
brushImage = TQImage(d, d, 32);
int x;
int y;
int byte = 0;
int bit = 7;
for (x=0; x<d; x++) {
for (y=0; y<d; y++) {
brushImage.setPixel(x, y, (TEST_BIT(pat[byte], bit))?color:0x00000000);
bit--;
if (bit < 0) {
bit = 7;
byte++;
}
}
}
}
else {
TQPixmap *pm;
pm = m_brush.pixmap();
brushImage = pm->convertToImage();
}
cairo_surface_t* brushSurface = TQImageToCairoSurface(brushImage);
cairo_pattern_t* pattern = cairo_pattern_create_for_surface(brushSurface);
cairo_set_source(m_painter, pattern);
cairo_pattern_set_extend(cairo_get_source(m_painter), CAIRO_EXTEND_REPEAT);
cairo_pattern_destroy(pattern);
cairo_surface_destroy(brushSurface);
}
else {
TQRgb color = m_brush.color().rgb();
cairo_pattern_t* pattern = cairo_pattern_create_rgba(tqRed(color), tqGreen(color), tqBlue(color), tqAlpha(color));
cairo_set_source(m_painter, pattern);
cairo_pattern_set_extend(cairo_get_source(m_painter), CAIRO_EXTEND_REPEAT);
cairo_pattern_destroy(pattern);
}
}
}
/*!
\class TQt3CairoPaintDevice tdeqt4painter.h
\brief The TQt3CairoPaintDevice class is a paint device that translates
Qt paint events to a TQt painter.
\ingroup graphics
\ingroup shared
*/
/*!
Constructs TQt3CairoPaintDevice on an existing QPainter
*/
TQt3CairoPaintDevice::TQt3CairoPaintDevice( cairo_surface_t *cairosurface )
: TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice ), m_painter(NULL)
{
m_surface = cairosurface;
}
/*!
Destroys the TQt3CairoPaintDevice.
*/
TQt3CairoPaintDevice::~TQt3CairoPaintDevice()
{
if (m_painter) {
cairo_destroy(m_painter);
m_painter = NULL;
}
}
/*!
\internal
Implementation of the function forwarded above to the internal data struct.
*/
bool TQt3CairoPaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
{
Q_UNUSED(pt);
unsigned int i;
double x;
double y;
double x2;
double y2;
double width;
double height;
int index;
int count;
int lineCount;
// Convert data types
if (p) {
if ((c == PdcDrawPoint) || (c == PdcMoveTo) || (c == PdcLineTo) || (c == PdcSetBrushOrigin)) {
x = p[0].point->x();
y = p[0].point->y();
}
if (c == PdcDrawLine) {
x = p[0].point->x();
y = p[0].point->y();
x2 = p[1].point->x();
y2 = p[1].point->y();
}
// if ((c == PdcDrawPolyline) || (c == PdcDrawPolygon) || (c == PdcDrawLineSegments) || (c == PdcDrawCubicBezier)) {
// TQPointArray qt3parray = *p[0].ptarr;
// qt4polygon.resize(qt3parray.count());
// for (i=0;i<qt3parray.count();i++) {
// qt3parray.point(i, &x, &y );
// qt4polygon.setPoint(i, x, y);
// }
// }
if ((c == PdcDrawRect) || (c == PdcDrawRoundRect) || (c == PdcDrawEllipse) || (c == PdcDrawArc) || (c == PdcDrawPie) || (c == PdcDrawChord)) {
x = p[0].rect->x();
y = p[0].rect->y();
width = p[0].rect->width();
height = p[0].rect->height();
}
}
// Perform drawing operation
switch ( c ) { // exec cmd
case PdcNOP:
break;
case PdcDrawPoint:
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);
updatePen(FALSE);
cairo_set_line_cap(m_painter, CAIRO_LINE_CAP_ROUND);
cairo_stroke(m_painter);
}
cairo_restore(m_painter);
}
break;
case PdcMoveTo:
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_restore(m_painter);
}
break;
case PdcLineTo:
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);
dualStrokePen();
}
cairo_restore(m_painter);
}
break;
case PdcDrawLine:
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);
dualStrokePen();
}
cairo_restore(m_painter);
}
break;
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();
}
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();
}
cairo_restore(m_painter);
}
else {
#if defined(QT_CHECK_RANGE)
tqWarning( "TQt3CairoPaintDevice::cmd: TQPainter::begin must be called before PdcDrawRect" );
#endif
}
break;
#if 0
case PdcDrawRoundRect:
m_qt4painter->drawRoundedRect( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter), p[1].ival, p[2].ival );
break;
case PdcDrawEllipse:
m_qt4painter->drawEllipse( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter) );
break;
case PdcDrawArc:
m_qt4painter->drawArc( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter), p[1].ival, p[2].ival );
break;
case PdcDrawPie:
m_qt4painter->drawPie( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter), p[1].ival, p[2].ival );
break;
case PdcDrawChord:
m_qt4painter->drawChord( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter), p[1].ival, p[2].ival );
break;
case PdcDrawLineSegments:
index = 0;
count = -1;
lineCount = (count == -1) ? (qt4polygon.size() - index) / 2 : count;
m_qt4painter->drawLines(qt4polygon.constData() + index * 2, lineCount);
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);
}
break;
#if 0
case PdcDrawPolygon:
m_qt4painter->drawPolygon( qt4polygon, (p[1].ival == 0)?Qt::OddEvenFill:Qt::WindingFill );
break;
case PdcDrawCubicBezier:
index = 0;
path.moveTo(qt4polygon.at(index));
path.cubicTo(qt4polygon.at(index+1), qt4polygon.at(index+2), qt4polygon.at(index+3));
m_qt4painter->strokePath(path, m_qt4painter->pen());
break;
case PdcDrawText:
m_qt4painter->drawText( qt4point1, qt4string );
break;
case PdcDrawTextFormatted:
m_qt4painter->drawText( qt4rect, qt4formattedtextflags, qt4string );
break;
case PdcDrawText2:
m_qt4painter->drawText( qt4point1, qt4string );
break;
case PdcDrawText2Formatted:
m_qt4painter->drawText( qt4rect, qt4formattedtextflags, qt4string );
break;
case PdcDrawPixmap:
m_qt4painter->drawPixmap( qt4rect, qt4pixmap );
break;
#if 0
case PdcDrawImage: {
TQImage image;
if ( d->formatMajor < 4 ) {
s >> p >> image;
painter->drawImage( p, image );
} else {
s >> r >> image;
painter->drawImage( r, image );
}
}
break;
#endif
#endif
case PdcBegin:
if (!m_painter) {
m_bgColor = TQColor(0,0,0);
m_bgColorMode = TQt::TransparentMode;
m_painter = cairo_create(m_surface);
m_pen = TQPen();
m_brush = TQBrush();
}
break;
case PdcEnd:
if (m_painter) {
cairo_destroy(m_painter);
m_painter = NULL;
}
break;
#if 0
case PdcSave:
m_qt4painter->save();
break;
case PdcRestore:
m_qt4painter->restore();
break;
#endif
case PdcSetBkColor:
if (p) {
const TQColor* color = p[0].color;
if (color) {
m_bgColor = *color;
}
}
break;
case PdcSetBkMode:
if (p) {
m_bgColorMode = (TQt::BGMode)p[0].ival;
}
break;
#if 0
case PdcSetROP:
m_qt4painter->setCompositionMode(qt4compositionmode);
break;
case PdcSetBrushOrigin:
m_qt4painter->setBrushOrigin( qt4point1 );
break;
case PdcSetFont:
m_qt4painter->setFont( qt4font );
break;
#endif
case PdcSetPen:
if (p) {
const TQPen* pen = p[0].pen;
if (pen) {
m_pen = *pen;
}
}
break;
case PdcSetBrush:
if (p) {
const TQBrush* brush = p[0].brush;
if (brush) {
m_brush = *brush;
}
}
break;
#if 0
#if 0
case PdcSetTabStops:
s >> i_16;
painter->setTabStops( i_16 );
break;
case PdcSetTabArray:
s >> i_16;
if ( i_16 == 0 ) {
painter->setTabArray( 0 );
} else {
int *ta = new int[i_16];
TQ_CHECK_PTR( ta );
for ( int i=0; i<i_16; i++ ) {
s >> i1_16;
ta[i] = i1_16;
}
painter->setTabArray( ta );
delete [] ta;
}
break;
case PdcSetVXform:
s >> i_8;
#ifndef QT_NO_TRANSFORMATIONS
painter->setViewXForm( i_8 );
#endif
break;
case PdcSetWindow:
s >> r;
#ifndef QT_NO_TRANSFORMATIONS
painter->setWindow( r );
#endif
break;
case PdcSetViewport:
s >> r;
#ifndef QT_NO_TRANSFORMATIONS
painter->setViewport( r );
#endif
break;
#endif
case PdcSetWXform:
m_qt4painter->setWorldMatrixEnabled( p[0].ival );
break;
case PdcSetWMatrix:
m_qt4painter->setWorldMatrix( qt4matrix, p[1].ival );
break;
#if 0
#ifndef QT_NO_TRANSFORMATIONS
case PdcSaveWMatrix:
painter->saveWorldMatrix();
break;
case PdcRestoreWMatrix:
painter->restoreWorldMatrix();
break;
#endif
#endif
case PdcSetClip:
m_qt4painter->setClipping( p[0].ival );
break;
case PdcSetClipRegion:
m_qt4painter->setClipRegion( qt4region, Qt::ReplaceClip );
break;
#endif
default:
#if defined(QT_CHECK_RANGE)
tqWarning( "TQt3CairoPaintDevice::cmd: Invalid command %d", c );
#endif
}
return TRUE;
}
/*!
Internal implementation of the virtual TQPaintDevice::metric()
function.
Use the TQPaintDeviceMetrics class instead.
A picture has the following hard-coded values: dpi=72,
numcolors=16777216 and depth=24.
\a m is the metric to get.
*/
int TQt3CairoPaintDevice::metric( int m ) const
{
int val;
if (m_surface) {
double x_pixels_per_inch;
double y_pixels_per_inch;
cairo_format_t format;
switch ( m ) {
// ### hard coded dpi and color depth values !
case TQPaintDeviceMetrics::PdmWidth:
val = cairo_image_surface_get_width(m_surface);
break;
case TQPaintDeviceMetrics::PdmHeight:
val = cairo_image_surface_get_height(m_surface);
break;
case TQPaintDeviceMetrics::PdmWidthMM:
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);
break;
case TQPaintDeviceMetrics::PdmHeightMM:
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);
break;
case TQPaintDeviceMetrics::PdmDpiX:
cairo_surface_get_fallback_resolution(m_surface, &x_pixels_per_inch, &y_pixels_per_inch);
val = x_pixels_per_inch;
break;
case TQPaintDeviceMetrics::PdmPhysicalDpiX:
cairo_surface_get_fallback_resolution(m_surface, &x_pixels_per_inch, &y_pixels_per_inch);
val = x_pixels_per_inch;
break;
case TQPaintDeviceMetrics::PdmDpiY:
cairo_surface_get_fallback_resolution(m_surface, &x_pixels_per_inch, &y_pixels_per_inch);
val = y_pixels_per_inch;
break;
case TQPaintDeviceMetrics::PdmPhysicalDpiY:
cairo_surface_get_fallback_resolution(m_surface, &x_pixels_per_inch, &y_pixels_per_inch);
val = y_pixels_per_inch;
break;
case TQPaintDeviceMetrics::PdmNumColors:
format = cairo_image_surface_get_format(m_surface);
if (format == CAIRO_FORMAT_ARGB32) {
val = INT_MAX;
}
else if (format == CAIRO_FORMAT_RGB24) {
val = 16777216;
}
else if (format == CAIRO_FORMAT_RGB16_565) {
val = 65536;
}
else {
val = 65536;
}
break;
case TQPaintDeviceMetrics::PdmDepth:
format = cairo_image_surface_get_format(m_surface);
if (format == CAIRO_FORMAT_ARGB32) {
val = 32;
}
else if (format == CAIRO_FORMAT_RGB24) {
val = 24;
}
else if (format == CAIRO_FORMAT_RGB16_565) {
val = 16;
}
else {
val = 16;
}
break;
default:
val = 0;
#if defined(QT_CHECK_RANGE)
tqWarning( "TQt3CairoPaintDevice::metric: Invalid metric command" );
#endif
}
}
else {
val = 0;
#if defined(QT_CHECK_RANGE)
tqWarning( "TQt3CairoPaintDevice::metric: No Cairo surface available" );
#endif
}
return val;
}