/****************************************************************************
**
** Implementation of TDEQt4PaintDevice 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 "tdeqt4painter.h"

#include "tqpainter.h"
#include "tqpixmap.h"
#include "tqbitmap.h"
#include "tqimage.h"
#include "tqfile.h"
#include "tqpaintdevicemetrics.h"
#undef Qt

#include "tdeqt4converter.h"

#define SET_BIT(x, y) (x |= 1 << y)
#define TEST_BIT(x, y) ((x & (1 << y)) >> y)

// When the time comes that Qt4/Qt5 are no longer able to use X11 data structures, unset this define...
#define USE_QT4_FROM_X11_PIXMAP_FUNCTIONS

/*!
    \class TDEQt4PaintDevice tdeqt4painter.h
    \brief The TDEQt4PaintDevice class is a paint device that translates
    Qt paint events to a TQt painter.

    \ingroup graphics
    \ingroup shared

*/

inline int qt4PainterRectSubtraction(QPainter* pd) {
	QPen pen = pd->pen();
	return pen.style() != Qt::NoPen && pen.width() == 0 ? 1 : 0;
}

inline QRect qt4PainterAdjustedRectangle(const QRect &r, QPainter* pd)
{
	QRect rect = r.normalized();
	int subtract = qt4PainterRectSubtraction(pd);
	if (subtract != 0) {
		rect.setSize(QSize(rect.width() - subtract, rect.height() - subtract));
	}
	return rect;
}

/*!
    Constructs TDEQt4PaintDevice on an existing QPainter
*/

TDEQt4PaintDevice::TDEQt4PaintDevice( QPainter *qt4painter )
    : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice )
{
	m_qt4painter = qt4painter;
	m_qt4OrigClipping = m_qt4painter->hasClipping();
	m_qt4OrigClipRegion = m_qt4painter->clipRegion();
	m_qt4OrigWorldTransformEnabled = m_qt4painter->worldMatrixEnabled();
	m_qt4OrigWorldTransform = m_qt4painter->worldTransform();
}

/*!
    Destroys the TDEQt4PaintDevice.
*/
TDEQt4PaintDevice::~TDEQt4PaintDevice()
{
}

/*!
  \internal
  Implementation of the function forwarded above to the internal data struct.
*/

bool TDEQt4PaintDevice::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
{
	Q_UNUSED(pt);

	unsigned int i;
	int x;
	int y;
	QPen qt4pen;
	QRect qt4rect;
	QBrush qt4brush;
	QPoint qt4point1;
	QPoint qt4point2;
	QPolygon qt4polygon;
	QFont qt4font;
	QPixmap qt4pixmap;
	QString qt4string;
	QMatrix qt4matrix;
	QRegion qt4region;
	Qt::BGMode qt4bkmode = Qt::TransparentMode;
	QPainter::CompositionMode qt4compositionmode = QPainter::CompositionMode_SourceOver;
	int qt4formattedtextflags = 0;

	if (p) {
		if (c == PdcSetClipRegion) {
			// FIXME
			// Ellipses are not being handle correctly AT ALL
			// Look at the Lipstik progress bar for an example of this...
#if 0
			// IMPRECISE
			const TQMemArray<TQRect> rects = p[0].rgn->rects();
			for ( uint i = 0; i < rects.count(); i++ ) {
				TQRect r = rects[(int)i];
				qt4region = qt4region.united(QRegion(QRect(r.x(), r.y(), r.width(), r.height())));
			}
			{
#else
			// SLOW
			TQRect tqt3br = p[0].rgn->boundingRect();
			if (!tqt3br.isNull()) {
#ifdef USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
				TQBitmap regionMask(tqt3br.x()+tqt3br.width(), tqt3br.y()+tqt3br.height());
				regionMask.fill(TQt::color0);
				TQPainter tqt3brpainter(&regionMask);
				tqt3brpainter.setClipRegion(*p[0].rgn);
				tqt3brpainter.fillRect(0,0,regionMask.width(),regionMask.height(),TQt::color1);
				tqt3brpainter.end();
				QBitmap qt4RegionMask = QPixmap::fromX11Pixmap(regionMask.handle(), QPixmap::ImplicitlyShared);
				qt4RegionMask.detach();
#else // USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
				TQBitmap regionMask(tqt3br.x()+tqt3br.width(), tqt3br.y()+tqt3br.height(), 32);
				int width = regionMask.width();
				int height = regionMask.height();
				int size = (((width*height)/8)+1);
				unsigned char* monoData = (unsigned char*)malloc(size);
				memset(monoData, 0, size);
				int x;
				int y;
				int byte = 0;
				int bit = 7;
				for (x=0; x<width; x++) {
					for (y=0; y<height; y++) {
						if (p[0].rgn->contains(TQPoint(x,y))) {
							SET_BIT(monoData[byte], bit);
						}
						bit--;
						if (bit < 0) {
							bit = 7;
							byte++;
						}
					}
				}
				QBitmap qt4RegionMask = QBitmap::fromData(QSize(width, height), monoData, QImage::Format_Mono);
				free(monoData);
#endif // USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
				qt4region = QRegion(qt4RegionMask);
#endif
				TQPainter::CoordinateMode tqt3coordmode = (TQPainter::CoordinateMode)p[1].ival;
				if ( tqt3coordmode == TQPainter::CoordDevice ) {
					qt4region = qt4region;
				}
				else {
					qt4region = m_qt4painter->transform().map(qt4region);
				}
			}
		}
		if (c == PdcSetWMatrix) {
			const TQWMatrix* tqt3matrix = p[0].matrix;
			qt4matrix = QMatrix(tqt3matrix->m11(), tqt3matrix->m12(), tqt3matrix->m21(), tqt3matrix->m22(), tqt3matrix->dx(), tqt3matrix->dy());
		}
		if (c == PdcSetROP) {
			TQt::RasterOp rop = (TQt::RasterOp)p[0].ival;
			switch (rop) {
				case TQPainter::CopyROP:
					qt4compositionmode=QPainter::CompositionMode_SourceOver;
					break;
				case TQPainter::OrROP:
					qt4compositionmode=QPainter::RasterOp_SourceOrDestination;
					break;
				case TQPainter::XorROP:
					qt4compositionmode=QPainter::RasterOp_SourceXorDestination;
					break;
				case TQPainter::NotAndROP:
					qt4compositionmode=QPainter::RasterOp_NotSourceAndDestination;
					break;
// 				case TQPainter::EraseROP:
// 					qt4compositionmode=QPainter::RasterOp_NotSourceAndDestination;
// 					break;
				case TQPainter::NotCopyROP:
					qt4compositionmode=QPainter::RasterOp_NotSource;
					break;
				case TQPainter::NotOrROP:
					tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n", rop);
					break;
				case TQPainter::NotXorROP:
					qt4compositionmode=QPainter::RasterOp_NotSourceXorDestination;
					break;
				case TQPainter::AndROP:
					qt4compositionmode=QPainter::RasterOp_SourceAndDestination;
					break;
// 				case TQPainter::NotEraseROP:
// 					qt4compositionmode=QPainter::RasterOp_SourceAndDestination;
// 					break;
				case TQPainter::NotROP:
					qt4compositionmode=QPainter::RasterOp_SourceAndNotDestination;          // [WARNING] This may not be a correct substitute for NotROP!
					break;
				case TQPainter::ClearROP:
					qt4compositionmode=QPainter::CompositionMode_Clear;
					break;
				case TQPainter::SetROP:
					tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n", rop);
					break;
				case TQPainter::NopROP:
					qt4compositionmode=QPainter::CompositionMode_Destination;
					break;
				case TQPainter::AndNotROP:
					qt4compositionmode=QPainter::RasterOp_SourceAndNotDestination;
					break;
				case TQPainter::OrNotROP:
					tqWarning("TDEQt4PaintDevice::cmd: Unhandled raster operation [Was attempting to use raster operation %d\n", rop);
					break;
				case TQPainter::NandROP:
					qt4compositionmode=QPainter::RasterOp_NotSourceOrNotDestination;
					break;
				case TQPainter::NorROP:
					qt4compositionmode=QPainter::RasterOp_NotSourceAndNotDestination;
					break;
				default:
					qt4compositionmode=QPainter::CompositionMode_SourceOver;
#if defined(QT_CHECK_RANGE)
					tqWarning( "TDEQt4PaintDevice::cmd: Unhandled raster operation %d", rop );
#endif
			}
		}
		if (( c== PdcDrawTextFormatted) || (c == PdcDrawText2Formatted)) {
			qt4rect = QRect(p[0].rect->x(), p[0].rect->y(), p[0].rect->width(), p[0].rect->height());
			qt4formattedtextflags = 0;
// 			if (p[1].ival & TQt::AlignAuto) {
// 				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignAuto;
// 			}
			if ((p[1].ival & TQt::AlignLeft) == TQt::AlignLeft) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignLeft;
			}
			if ((p[1].ival & TQt::AlignRight) == TQt::AlignRight) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignRight;
			}
			if ((p[1].ival & TQt::AlignHCenter) == TQt::AlignHCenter) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignHCenter;
			}
			if ((p[1].ival & TQt::AlignJustify) == TQt::AlignJustify) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignJustify;
			}
			if ((p[1].ival & TQt::AlignTop) == TQt::AlignTop) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignTop;
			}
			if ((p[1].ival & TQt::AlignBottom) == TQt::AlignBottom) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignBottom;
			}
			if ((p[1].ival & TQt::AlignVCenter) == TQt::AlignVCenter) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignVCenter;
			}
			if ((p[1].ival & TQt::AlignCenter) == TQt::AlignCenter) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::AlignCenter;
			}
			if ((p[1].ival & TQt::SingleLine) == TQt::SingleLine) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::TextSingleLine;
			}
			if ((p[1].ival & TQt::DontClip) == TQt::DontClip) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::TextDontClip;
			}
			if ((p[1].ival & TQt::ExpandTabs) == TQt::ExpandTabs) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::TextExpandTabs;
			}
			if ((p[1].ival & TQt::ShowPrefix) == TQt::ShowPrefix) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::TextShowMnemonic;
			}
			if ((p[1].ival & TQt::WordBreak) == TQt::WordBreak) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::TextWordWrap;
			}
			if ((p[1].ival & TQt::BreakAnywhere) == TQt::BreakAnywhere) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::TextWrapAnywhere;
			}
			if ((p[1].ival & TQt::NoAccel) == TQt::NoAccel) {
				qt4formattedtextflags = qt4formattedtextflags | Qt::TextHideMnemonic;
			}
			qt4string = QString::fromUtf8(p[2].str->utf8().data());
		}
		if ((c == PdcDrawPoint) || (c == PdcMoveTo) || (c == PdcLineTo) || (c == PdcSetBrushOrigin)) {
			qt4point1 = QPoint(p[0].point->x(), p[0].point->y());
		}
		if (c == PdcDrawLine) {
			qt4point1 = QPoint(p[0].point->x(), p[0].point->y());
			qt4point2 = QPoint(p[1].point->x(), 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)) {
			qt4rect = QRect(p[0].rect->x(), p[0].rect->y(), p[0].rect->width(), p[0].rect->height());
		}
		if (c == PdcSetBrush) {
			TQt::BrushStyle tqt3brushstyle = p[0].brush->style();
			Qt::BrushStyle qt4brushstyle;
			switch ( tqt3brushstyle ) {
				case TQt::NoBrush:
					qt4brushstyle = Qt::NoBrush;
					break;
				case TQt::SolidPattern:
					qt4brushstyle = Qt::SolidPattern;
					break;
				case TQt::Dense1Pattern:
					qt4brushstyle = Qt::Dense1Pattern;
					break;
				case TQt::Dense2Pattern:
					qt4brushstyle = Qt::Dense2Pattern;
					break;
				case TQt::Dense3Pattern:
					qt4brushstyle = Qt::Dense3Pattern;
					break;
				case TQt::Dense4Pattern:
					qt4brushstyle = Qt::Dense4Pattern;
					break;
				case TQt::Dense5Pattern:
					qt4brushstyle = Qt::Dense5Pattern;
					break;
				case TQt::Dense6Pattern:
					qt4brushstyle = Qt::Dense6Pattern;
					break;
				case TQt::Dense7Pattern:
					qt4brushstyle = Qt::Dense7Pattern;
					break;
				case TQt::HorPattern:
					qt4brushstyle = Qt::HorPattern;
					break;
				case TQt::VerPattern:
					qt4brushstyle = Qt::VerPattern;
					break;
				case TQt::CrossPattern:
					qt4brushstyle = Qt::CrossPattern;
					break;
				case TQt::BDiagPattern:
					qt4brushstyle = Qt::BDiagPattern;
					break;
				case TQt::FDiagPattern:
					qt4brushstyle = Qt::FDiagPattern;
					break;
				case TQt::DiagCrossPattern:
					qt4brushstyle = Qt::DiagCrossPattern;
					break;
				case TQt::CustomPattern:
					qt4brushstyle = Qt::TexturePattern;
					break;
				default:
					qt4brushstyle = Qt::NoBrush;
#if defined(QT_CHECK_RANGE)
					tqWarning( "TDEQt4PaintDevice::cmd: Invalid brush style %d", tqt3brushstyle );
#endif
			}
			qt4brush.setStyle(qt4brushstyle);
			TQColor qt3color = p[0].brush->color();
			qt4brush.setColor(QColor(qt3color.red(), qt3color.green(), qt3color.blue(), 255));
			if (qt4brushstyle == Qt::TexturePattern) {
#ifdef USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
				TQPixmap tqtPM = *p[0].brush->pixmap();
				QPixmap qtPM = QPixmap::fromX11Pixmap(tqtPM.handle(), QPixmap::ImplicitlyShared);
				qtPM.detach();
#else // USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
				TQImage qt3image = (*p[0].brush->pixmap()).convertToImage();
				qt3image = qt3image.convertDepth(32);
				QImage qt4image(qt3image.bits(), qt3image.width(), qt3image.height(), QImage::Format_ARGB32);
				QPixmap qtPM = QPixmap::fromImage(qt4image);
#endif // USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
				qt4brush.setTexture(qtPM);
			}
		}
		if (c == PdcSetPen) {
			bool customPenStyle = false;
			TQt::PenStyle tqt3penstyle = p[0].pen->style();
			Qt::PenStyle qt4penstyle;
			QVector<qreal> dashes;
			qreal mark;
			qreal space;
			switch ( tqt3penstyle ) {
				case TQt::NoPen:
					qt4penstyle = Qt::NoPen;
					break;
				case TQt::SolidLine:
					qt4penstyle = Qt::SolidLine;
					break;
				case TQt::DashLine:
					qt4penstyle = Qt::DashLine;
					break;
				case TQt::DotLine:
					qt4penstyle = Qt::DotLine;
					break;
				case TQt::DashDotLine:
					qt4penstyle = Qt::DashDotLine;
					break;
				case TQt::DashDotDotLine:
					qt4penstyle = Qt::DashDotDotLine;
					break;
				case TQt::FineDotLine:
					customPenStyle = true;
					mark = 1;
					space = 1;
					dashes << mark << space;
					qt4pen.setDashPattern(dashes);
					break;
				case TQt::MPenStyle:
					qt4penstyle = Qt::MPenStyle;
					break;
				default:
					qt4penstyle = Qt::NoPen;
#if defined(QT_CHECK_RANGE)
					tqWarning( "TDEQt4PaintDevice::cmd: Invalid pen style %d", tqt3penstyle );
#endif
			}
			if (customPenStyle == false) {
				qt4pen.setStyle(qt4penstyle);
			}
			TQt::PenCapStyle tqt3pencapstyle = p[0].pen->capStyle();
			Qt::PenCapStyle qt4pencapstyle;
			switch ( tqt3pencapstyle ) {
				case TQt::FlatCap:
					qt4pencapstyle = Qt::FlatCap;
					break;
				case TQt::SquareCap:
					qt4pencapstyle = Qt::SquareCap;
					break;
				case TQt::RoundCap:
					qt4pencapstyle = Qt::RoundCap;
					break;
				case TQt::MPenCapStyle:
					qt4pencapstyle = Qt::MPenCapStyle;
				default:
					qt4pencapstyle = Qt::FlatCap;
#if defined(QT_CHECK_RANGE)
					tqWarning( "TDEQt4PaintDevice::cmd: Invalid pen cap style %d", tqt3pencapstyle );
#endif
			}
			qt4pen.setCapStyle(qt4pencapstyle);
			TQt::PenJoinStyle tqt3penjoinstyle = p[0].pen->joinStyle();
			Qt::PenJoinStyle qt4penjoinstyle;
			switch ( tqt3penjoinstyle ) {
				case TQt::MiterJoin:
					qt4penjoinstyle = Qt::MiterJoin;
					break;
				case TQt::BevelJoin:
					qt4penjoinstyle = Qt::BevelJoin;
					break;
				case TQt::RoundJoin:
					qt4penjoinstyle = Qt::RoundJoin;
					break;
				case TQt::MPenJoinStyle:
					qt4penjoinstyle = Qt::MPenJoinStyle;
				default:
					qt4penjoinstyle = Qt::MiterJoin;
#if defined(QT_CHECK_RANGE)
					tqWarning( "TDEQt4PaintDevice::cmd: Invalid pen join style %d", tqt3penjoinstyle );
#endif
			}
			qt4pen.setJoinStyle(qt4penjoinstyle);
			TQColor qt3color = p[0].pen->color();
			qt4pen.setColor(QColor(qt3color.red(), qt3color.green(), qt3color.blue(), 255));
			qt4pen.setWidth(p[0].pen->width());
		}
		if (c == PdcSetBkMode) {
			TQt::BGMode qt3bkmode = (TQt::BGMode)p[0].ival;
			switch ( qt3bkmode ) {
				case TQt::TransparentMode:
					qt4bkmode = Qt::TransparentMode;
					break;
				case TQt::OpaqueMode:
					qt4bkmode = Qt::OpaqueMode;
					break;
				default:
					qt4bkmode = Qt::TransparentMode;
#if defined(QT_CHECK_RANGE)
					tqWarning( "TDEQt4PaintDevice::cmd: Invalid background mode %d", qt3bkmode );
#endif
			}
		}
		if (c == PdcSetFont) {
			TQFont qt3font = *p[0].font;
			qt4font = convertTQt3ToQt4Font(qt3font);
		}
		if (c == PdcDrawPixmap) {
			qt4rect = QRect(p[0].rect->x(), p[0].rect->y(), p[0].rect->width(), p[0].rect->height());
			TQPixmap qt3pixmap = *p[1].pixmap;
#ifdef USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
			qt4pixmap = QPixmap::fromX11Pixmap(qt3pixmap.handle(), QPixmap::ImplicitlyShared);
			qt4pixmap.detach();
#else // USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
			TQImage qt3image = qt3pixmap.convertToImage();
			qt3image = qt3image.convertDepth(32);
			QImage qt4image(qt3image.bits(), qt3image.width(), qt3image.height(), QImage::Format_ARGB32);
			qt4pixmap = QPixmap::fromImage(qt4image);
#endif // USE_QT4_FROM_X11_PIXMAP_FUNCTIONS
		}
		if (c == PdcDrawText2) {
			qt4point1 = QPoint(p[0].point->x(), p[0].point->y());
			qt4string = QString::fromUtf8(p[1].str->utf8().data());
		}
	}

	int index;
	int count;
	int lineCount;
	QPainterPath path;

	switch ( c ) {				// exec cmd
	    case PdcNOP:
		break;
	    case PdcDrawPoint:
		m_qt4painter->drawPoint( qt4point1 );
		break;
	    case PdcMoveTo:
		curPt = qt4point1;
		break;
	    case PdcLineTo:
		prevPt = curPt;
		curPt = qt4point1;
		m_qt4painter->drawLine( prevPt, curPt );
		break;
	    case PdcDrawLine:
		m_qt4painter->drawLine( qt4point1, qt4point2 );
		break;
	    case PdcDrawRect:
		m_qt4painter->drawRect( qt4PainterAdjustedRectangle(qt4rect, m_qt4painter) );
		break;
	    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;
	    case PdcDrawPolyline:
		m_qt4painter->drawPolyline( qt4polygon );
		break;
	    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
	    case PdcBegin:
		if (m_qt4painter->isActive()) {
			// KEEP THIS DEACTIVATED
// 			QPaintDevice* pd = m_qt4painter->device();
// 			m_qt4painter->end();
// 			m_qt4painter->begin(pd);
		}
#if defined(QT_CHECK_RANGE)
		else {
			tqWarning( "TDEQt4PaintDevice::cmd: Painter has no paint device available" );
		}
#endif
		break;
	    case PdcEnd:
		// KEEP THIS DEACTIVATED
// 		m_qt4painter->end();
		break;
	    case PdcSave:
		m_qt4painter->save();
		break;
	    case PdcRestore:
		m_qt4painter->restore();
		break;
	    case PdcSetBkColor:
		m_qt4painter->setBackground( QBrush(QColor(p[0].color->red(), p[0].color->green(), p[0].color->blue())) );
		break;
	    case PdcSetBkMode:
		m_qt4painter->setBackgroundMode( qt4bkmode );
		break;
	    case PdcSetROP:
		m_qt4painter->setCompositionMode(qt4compositionmode);
		break;
	    case PdcSetBrushOrigin:
		m_qt4painter->setBrushOrigin( qt4point1 );
		break;
	    case PdcSetFont:
		m_qt4painter->setFont( qt4font );
		break;
	    case PdcSetPen:
		m_qt4painter->setPen( qt4pen );
		break;
	    case PdcSetBrush:
		m_qt4painter->setBrush( qt4brush );
		break;
#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 TQT_NO_TRANSFORMATIONS
		painter->setViewXForm( i_8 );
#endif
		break;
	    case PdcSetWindow:
		s >> r;
#ifndef TQT_NO_TRANSFORMATIONS
		painter->setWindow( r );
#endif
		break;
	    case PdcSetViewport:
		s >> r;
#ifndef TQT_NO_TRANSFORMATIONS
		painter->setViewport( r );
#endif
		break;
#endif
	    case PdcSetWXform:
		m_qt4painter->setWorldMatrixEnabled( (m_qt4OrigWorldTransformEnabled)?true:p[0].ival );
		break;
	    case PdcSetWMatrix:
		m_qt4painter->setWorldMatrix( qt4matrix, p[1].ival );
		break;
#if 0
#ifndef TQT_NO_TRANSFORMATIONS
	    case PdcSaveWMatrix:
		painter->saveWorldMatrix();
		break;
	    case PdcRestoreWMatrix:
		painter->restoreWorldMatrix();
		break;
#endif
#endif
	    case PdcSetClip:
		m_qt4painter->setClipping( (m_qt4OrigClipping)?true:p[0].ival );
		break;
	    case PdcSetClipRegion:
		m_qt4painter->setClipRegion( (m_qt4OrigClipping)?qt4region.intersected(m_qt4OrigClipRegion):qt4region, Qt::ReplaceClip );
		break;
	    default:
#if defined(QT_CHECK_RANGE)
		tqWarning( "TDEQt4PaintDevice::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 TDEQt4PaintDevice::metric( int m ) const
{
	int val;
	QPaintDevice* qt4pd = m_qt4painter->device();
	if (qt4pd) {
		switch ( m ) {
			// ### hard coded dpi and color depth values !
			case TQPaintDeviceMetrics::PdmWidth:
				val = qt4pd->width();
				break;
			case TQPaintDeviceMetrics::PdmHeight:
				val = qt4pd->height();
				break;
			case TQPaintDeviceMetrics::PdmWidthMM:
				val = qt4pd->widthMM();
				break;
			case TQPaintDeviceMetrics::PdmHeightMM:
				val = qt4pd->heightMM();
				break;
			case TQPaintDeviceMetrics::PdmDpiX:
				val = qt4pd->logicalDpiX();
				break;
			case TQPaintDeviceMetrics::PdmPhysicalDpiX:
				val = qt4pd->physicalDpiX();
				break;
			case TQPaintDeviceMetrics::PdmDpiY:
				val = qt4pd->logicalDpiY();
				break;
			case TQPaintDeviceMetrics::PdmPhysicalDpiY:
				val = qt4pd->physicalDpiY();
				break;
			case TQPaintDeviceMetrics::PdmNumColors:
				val = qt4pd->colorCount();
				break;
			case TQPaintDeviceMetrics::PdmDepth:
				val = qt4pd->depth();
				break;
			default:
				val = 0;
#if defined(QT_CHECK_RANGE)
				tqWarning( "TDEQt4PaintDevice::metric: Invalid metric command" );
#endif
		}
	}
	else {
		val = 0;
#if defined(QT_CHECK_RANGE)
		tqWarning( "TDEQt4PaintDevice::metric: No Qt4 paint device available" );
#endif
	}
	return val;
}

