[rkward-cvs] SF.net SVN: rkward-code:[4629] branches/development_branches/ rkward_graphpics_device/rkward/rbackend/rkwarddevice

tfry at users.sf.net tfry at users.sf.net
Tue Mar 26 11:02:02 UTC 2013


Revision: 4629
          http://sourceforge.net/p/rkward/code/4629
Author:   tfry
Date:     2013-03-26 11:02:01 +0000 (Tue, 26 Mar 2013)
Log Message:
-----------
Use direct rendering to QPixmap, instead.

Modified Paths:
--------------
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp	2013-03-25 18:18:17 UTC (rev 4628)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp	2013-03-26 11:02:01 UTC (rev 4629)
@@ -15,19 +15,12 @@
  *                                                                         *
  ***************************************************************************/
 
-/******************************* ACKNOWLEDGEMENT ***************************
- * 
- * The drawing functions in this file are heavily inspired, in some parts even copied from package qtutils, version 0.1-3
- * by Deepayan Sarkar. Package qtutils is available from http://qtinterfaces.r-forge.r-project.org
- * under GNU LPGL 2 or later.
- * 
- ***************************************************************************/
-
 #include "rkgraphicsdevice.h"
 
 #include <QGraphicsScene>
 #include <QGraphicsView>
 #include <QGraphicsRectItem>
+#include <qmath.h>
 
 #include "../../debug.h"
 
@@ -35,38 +28,31 @@
 
 QHash<int, RKGraphicsDevice*> RKGraphicsDevice::devices;
 
-RKGraphicsDevice::RKGraphicsDevice (double width, double height) : QObject () {
+RKGraphicsDevice::RKGraphicsDevice (double width, double height) : QObject (), area (qAbs (width) + 1, qAbs (height) + 1) {
 	RK_TRACE (GRAPHICS_DEVICE);
-	scene = new QGraphicsScene (0, 0, width, height, this);
-	view = new QGraphicsView (scene);
-//	view->setOptimizationFlags (QGraphicsView::DontSavePainterState);
-//	view->setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
-//	scene->setItemIndexMethod (QGraphicsScene::NoIndex);
-//	scene->setBspTreeDepth (16);
-//	view->setViewportUpdateMode (QGraphicsView::NoViewportUpdate);
+	painter.setRenderHints (QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+	view = new QLabel ();
+	view->setFixedSize (area.size ());
 	connect (&updatetimer, SIGNAL (timeout ()), this, SLOT (updateNow ()));
-	view->show ();
-	item_z = clip_z = 0;
-	clip = 0;
-	setClip (scene->sceneRect ());
+	updatetimer.setSingleShot (true);
+	clear ();
 }
 
 RKGraphicsDevice::~RKGraphicsDevice () {
 	RK_TRACE (GRAPHICS_DEVICE);
+	painter.end ();
 	delete view;
 }
 
 void RKGraphicsDevice::triggerUpdate () {
-	view->setUpdatesEnabled (false);
 	updatetimer.start (UPDATE_INTERVAL);
 }
 
 void RKGraphicsDevice::updateNow () {
-//	QList<QRectF> dummy;
-//	dummy.append (scene->sceneRect ());
-//	view->updateScene (dummy);
-	view->setUpdatesEnabled (true);
-	view->update ();
+	if (painter.isActive ()) painter.end ();
+	view->setPixmap (area);
+	view->show ();
+	painter.begin (&area);
 }
 
 RKGraphicsDevice* RKGraphicsDevice::newDevice (int devnum, double width, double height) {
@@ -88,137 +74,96 @@
 	devices.take (devnum)->deleteLater ();
 }
 
-void RKGraphicsDevice::clear (const QBrush& bg) {
+void RKGraphicsDevice::clear (const QColor& col) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
-	scene->clear ();
-	clip = 0;
-	setClip (scene->sceneRect ());
-	rect (scene->sceneRect (), QPen (Qt::NoPen), bg);
-	view->show ();
-	updatetimer.start (UPDATE_INTERVAL);
+	if (painter.isActive ()) painter.end ();
+ 	if (col.isValid ()) area.fill (col);
+	else area.fill (QColor (255, 255, 255, 255));
+	updateNow ();
 }
 
 void RKGraphicsDevice::setClip (const QRectF& new_clip) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
-//	QGraphicsItem* old_clip = clip;
-	clip = scene->addRect (new_clip, QPen (Qt::NoPen));
-	clip->setZValue (clip_z += .1);
-	clip->setFlags (QGraphicsItem::ItemClipsChildrenToShape);
-	item_z = 0;
-//	if (old_clip) old_clip->setCacheMode (QGraphicsItem::DeviceCoordinateCache);
+	if (!painter.isActive ()) painter.begin (&area);
+	painter.setClipRect (new_clip);
 }
 
-void RKGraphicsDevice::addItem (QGraphicsItem* item) {
-	if (item_z > 1000) {
-		updatetimer.stop ();
-		QGraphicsItem *old_clip = clip;
-		QRectF brect = clip->rect ().normalized ();
-		QPixmap cache (brect.width () + 1, brect.height () + 1);
-		cache.fill (QColor (0, 0, 0, 0));
-		QPainter painter;
-		painter.begin (&cache);
-		scene->render (&painter, cache.rect (), brect);
-		painter.end ();
-		setClip (brect);
-		QGraphicsPixmapItem *cached = new QGraphicsPixmapItem (cache);
-		cached->setPos (brect.x (), brect.y ());
-		addItem (cached);
-		delete old_clip;
-	}
-	item->setZValue (item_z += .1);
-	item->setParentItem (clip);
-	triggerUpdate ();
-}
-
 void RKGraphicsDevice::circle (double x, double y, double r, const QPen& pen, const QBrush& brush) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
-	QGraphicsEllipseItem* circle = new QGraphicsEllipseItem (x - r, y - r, r+r, r+r);
-	circle->setPen (pen);
-	circle->setBrush (brush);
-	addItem (circle);
+	painter.setPen (pen);
+	painter.setBrush (brush);
+	painter.drawEllipse (x - r, y - r, r+r, r+r);
+	triggerUpdate ();
 }
 
 void RKGraphicsDevice::line (double x1, double y1, double x2, double y2, const QPen& pen) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
-	QGraphicsLineItem* line = new QGraphicsLineItem (x1, y1, x2, y2);
-	line->setPen (pen);
-	addItem (line);
+	painter.setPen (pen);
+	painter.drawLine (x1, y1, x2, y2);
+	triggerUpdate ();
 }
 
 void RKGraphicsDevice::rect (const QRectF& rec, const QPen& pen, const QBrush& brush) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
-	QGraphicsRectItem* rect = new QGraphicsRectItem (rec);
-	rect->setPen (pen);
-	rect->setBrush (brush);
-	addItem (rect);
+	painter.setPen (pen);
+	painter.setBrush (brush);
+	painter.drawRect (rec);
+	triggerUpdate ();
 }
 
-double RKGraphicsDevice::strWidth (const QString& text, const QFont& font) {
+QSizeF RKGraphicsDevice::strSize (const QString& text, const QFont& font) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
-	QGraphicsTextItem t (text);
-	t.setFont (font);
-	return t.boundingRect ().width ();
+	painter.setFont (font);
+	QSizeF size = painter.boundingRect (QRectF (area.rect ()), text).size ();
+	return size;
 }
 
-void RKGraphicsDevice::text (double x, double y, const QString& _text, double rot, double hadj, const QColor& col, const QFont& font) {
+void RKGraphicsDevice::text (double x, double y, const QString& text, double rot, double hadj, const QColor& col, const QFont& font) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
-	QGraphicsTextItem *text = new QGraphicsTextItem ();
-	text->setPlainText (_text);
-	text->setFont (font);
-	text->setDefaultTextColor (col);
-	QRectF brect = text->boundingRect ();
-	text->rotate (-rot);
-	text->translate (-hadj * brect.width (), - QFontMetricsF (font).height ());
-	text->setPos (x, y);
-	text->setTextInteractionFlags (Qt::TextSelectableByMouse);
-	addItem (text);
+	painter.save ();
+	QSizeF size = strSize (text, font);	// NOTE: side-effect of setting font!
+//	painter.setFont (font);
+	painter.setPen (QPen (col));
+	painter.translate (x, y);
+	painter.rotate (-rot);
+	painter.drawText (-(hadj * size.width ()), 0, text);
+	painter.restore ();	// undo rotation / translation
+	triggerUpdate ();
 }
 
 void RKGraphicsDevice::metricInfo (const QChar& c, const QFont& font, double* ascent, double* descent, double* width) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
+	// Don't touch! This is the result of a lot of trial and error, and replicates the behavior of X11() on the ?plotmath examples
 	QFontMetricsF fm (font);
-	*ascent = fm.ascent ();	// TODO: or should we return the metrics of this particular char (similar to strWidth)
-	*descent = fm.descent ();
+	QRectF rect = fm.boundingRect (c);
+	*ascent = -rect.top ();
+	*descent = rect.bottom ();
 	*width = fm.width (c);
-/*	QGraphicsTextItem t;
-	t.setPlainText (QString (c));
-	t.setFont (font);
-	*ascent = t.boundingRect().height();
-	*descent = 0;
-	*width = t.boundingRect().width(); */
 }
 
 void RKGraphicsDevice::polygon (const QPolygonF& pol, const QPen& pen, const QBrush& brush) {
 	RK_TRACE (GRAPHICS_DEVICE);
 
-	QGraphicsPolygonItem *poli = new QGraphicsPolygonItem (pol);
-	poli->setPen (pen);
-	poli->setBrush (brush);
-	addItem (poli);
+	painter.setPen (pen);
+	painter.setBrush (brush);
+	painter.drawPolygon (pol);
+	triggerUpdate ();
 }
 
 void RKGraphicsDevice::polyline (const QPolygonF& pol, const QPen& pen) {
 	RK_TRACE (GRAPHICS_DEVICE);
-// Qt insistes that all QGraphicsPolygonItems must be closed. So the this does not work:
-// QGraphicsPolygonItem *poli = new QGraphicsPolygonItem (pol, clip);
-	if (pol.isEmpty ()) return;
 
-	QPainterPath path;
-	path.moveTo (pol[0]);
-	for (int i = 1; i < pol.size (); ++i) {
-		path.lineTo (pol[i]);
-	}
-	QGraphicsPathItem *poli = new QGraphicsPathItem (path);
-	poli->setPen (pen);
-	addItem (poli);
+	painter.setPen (pen);
+	painter.drawPolyline (pol);
+	triggerUpdate ();
 }
 
 void RKGraphicsDevice::setActive (bool active) {

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h	2013-03-25 18:18:17 UTC (rev 4628)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h	2013-03-26 11:02:01 UTC (rev 4629)
@@ -21,12 +21,10 @@
 #include <QHash>
 #include <QPen>
 #include <QTimer>
+#include <QPixmap>
+#include <QPainter>
+#include <QLabel>
 
-class QGraphicsRectItem;
-class QGraphicsView;
-class QGraphicsScene;
-class QGraphicsItem;
-
 /** This is the class that actually does all the drawing for the RKGraphicsDevice */
 class RKGraphicsDevice : public QObject {
 	Q_OBJECT
@@ -41,13 +39,13 @@
 	void circle (double x, double y, double r, const QPen& pen, const QBrush& brush);
 	void line (double x1, double y1, double x2, double y2, const QPen& pen);
 	void rect (const QRectF& rec, const QPen& pen, const QBrush& brush);
-	double strWidth (const QString &text, const QFont& font);
+	QSizeF strSize (const QString &text, const QFont& font);
 	void text (double x, double y, const QString &text, double rot, double hadj, const QColor& col, const QFont& font);
 	void metricInfo (const QChar& c, const QFont& font, double *ascent, double *descent, double *width);
 	void setClip (const QRectF& new_clip);
 	void polygon (const QPolygonF& pol, const QPen& pen, const QBrush &brush);
 	void polyline (const QPolygonF& pol, const QPen& pen);
-	void clear (const QBrush& bg);
+	void clear (const QColor& col=QColor());
 	void setActive (bool active);
 	void triggerUpdate ();
 signals:
@@ -55,13 +53,10 @@
 private slots:
 	void updateNow ();
 private:
-	void addItem (QGraphicsItem *item);
 	QTimer updatetimer;
-	QGraphicsScene* scene;
-	QGraphicsView* view;
-	QGraphicsRectItem* clip;
-	double clip_z;
-	double item_z;
+	QPixmap area;
+	QPainter painter;
+	QLabel *view;
 };
 
 #endif

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp	2013-03-25 18:18:17 UTC (rev 4628)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp	2013-03-26 11:02:01 UTC (rev 4629)
@@ -143,17 +143,16 @@
 	return ret;
 }
 
-static QVector<QPointF> readPoints (QDataStream &instream, bool close) {
+static QVector<QPointF> readPoints (QDataStream &instream) {
 	quint32 n;
 	instream >> n;
 	QVector<QPointF> points;
-	points.reserve (n + (close ? 1 : 0));
+	points.reserve (n);
 	for (quint32 i = 0; i < n; ++i) {
 		double x, y;
 		instream >> x >> y;
 		points.append (QPointF (x, y));
 	}
-	if (n && close) points.append (points[0]);
 	return points;
 }
 
@@ -192,11 +191,11 @@
 			streamer.instream >> x1 >> y1 >> x2 >> y2;
 			device->line (x1, y1, x2, y2, readPen (streamer.instream));
 		} else if (opcode == RKDPolygon) {
-			QPolygonF pol (readPoints (streamer.instream, true));
+			QPolygonF pol (readPoints (streamer.instream));
 			QPen pen = readPen (streamer.instream);
 			device->polygon (pol, pen, readBrush (streamer.instream));
 		} else if (opcode == RKDPolyline) {
-			QPolygonF pol (readPoints (streamer.instream, false));
+			QPolygonF pol (readPoints (streamer.instream));
 			device->polyline (pol, readPen (streamer.instream));
 		} else if (opcode == RKDRect) {
 			QRectF rect;
@@ -206,7 +205,7 @@
 		} else if (opcode == RKDStrWidthUTF8) {
 			QString out;
 			streamer.instream >> out;
-			double w = device->strWidth (out, readFont (streamer.instream));
+			double w = device->strSize (out, readFont (streamer.instream)).width ();
 			streamer.outstream << w;
 			streamer.writeOutBuffer ();
 		} else if (opcode == RKDMetricInfo) {
@@ -223,7 +222,7 @@
 			QColor col = readColor (streamer.instream);
 			device->text (x, y, out, rot, hadj, col, readFont (streamer.instream));
 		} else if (opcode == RKDNewPage) {
-			device->clear (readBrush (streamer.instream));
+			device->clear (readColor (streamer.instream));
 		} else if (opcode == RKDClose) {
 			RKGraphicsDevice::closeDevice (devnum);
 		} else if (opcode == RKDActivate) {

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp	2013-03-25 18:18:17 UTC (rev 4628)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp	2013-03-26 11:02:01 UTC (rev 4629)
@@ -41,6 +41,10 @@
 	bool initRDevDesc (pDevDesc dev, double pointsize);
 	int devnum;
 	double width, height;
+	QString getFontFamily (bool symbolfont) const {
+		if (symbolfont) return QString ("symbol");
+		return default_family;
+	}
 	QString default_family;
 	pDevDesc rdevdesc;
 };

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp	2013-03-25 18:18:17 UTC (rev 4628)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp	2013-03-26 11:02:01 UTC (rev 4629)
@@ -103,7 +103,7 @@
 #define WRITE_FILL() \
 	WRITE_COLOR_BYTES (gc->fill)
 #define WRITE_FONT(dev) \
-	RKD_OUT_STREAM << gc->cex << gc->ps << gc->lineheight << (quint8) gc->fontface << (gc->fontfamily[0] ? QString (gc->fontfamily) : (static_cast<RKGraphicsDeviceDesc*> (dev->deviceSpecific)->default_family))
+	RKD_OUT_STREAM << gc->cex << gc->ps << gc->lineheight << (quint8) gc->fontface << (gc->fontfamily[0] ? QString (gc->fontfamily) : (static_cast<RKGraphicsDeviceDesc*> (dev->deviceSpecific)->getFontFamily (gc->fontface == 5)))
 
 static void RKD_Create (double width, double height, pDevDesc dev) {
 	RKGraphicsDataStreamWriteGuard guard;
@@ -161,20 +161,10 @@
 	WRITE_FILL ();
 }
 
-static QString RToQString (const char *str, bool is_symbol) {
-	if (is_symbol) {
-		int n = strlen (str);
-		char outbuf[n*4 + 16];
-		Rf_AdobeSymbol2utf8 (outbuf, str, n*4);
-		return QString::fromUtf8 (outbuf);
-	}
-	return QString::fromUtf8 (str);
-}
-
 static void RKD_TextUTF8 (double x, double y, const char *str, double rot, double hadj, R_GE_gcontext *gc, pDevDesc dev) {
 	RKGraphicsDataStreamWriteGuard guard;
 	WRITE_HEADER (RKDTextUTF8, dev);
-	RKD_OUT_STREAM << x << y << RToQString (str, gc->fontface == 5) << rot << hadj;
+	RKD_OUT_STREAM << x << y << QString::fromUtf8 (str) << rot << hadj;	// NOTE: yes, even Symbols are sent as UTF-8, here.
 	WRITE_COL ();
 	WRITE_FONT (dev);
 }
@@ -183,7 +173,7 @@
 	{
 		RKGraphicsDataStreamWriteGuard guard;
 		WRITE_HEADER (RKDStrWidthUTF8, dev);
-		RKD_OUT_STREAM << RToQString (str, gc->fontface == 5);
+		RKD_OUT_STREAM << QString::fromUtf8 (str);	// NOTE: yes, even Symbols are sent as UTF-8, here.
 		WRITE_FONT (dev);
 	}
 	double ret;
@@ -205,16 +195,13 @@
 		RKGraphicsDataStreamWriteGuard wguard;
 		WRITE_HEADER (RKDMetricInfo, dev);
 		QChar unichar;
-		if (c < 0) { unichar = QChar (-c); }
-		else if ((gc->fontface == 5) || (!mbcslocale)) {
-			char inbuf[2];
+		if (c < 0) unichar = QChar (-c);
+		else {		// correct?! Do we get utf8, here?
+			int inbuf[2];
 			inbuf[0] = c;
 			inbuf[1] = 0;
-			QString dummy = RToQString (inbuf, gc->fontface == 5);
+			QString dummy = QString::fromUtf8 ((char*) inbuf);
 			if (!dummy.isEmpty ()) unichar = dummy.at (0);
-		} else {
-#warning TODO: handle non-unicode locale?
-			unichar = QChar (c);
 		}
 		RKD_OUT_STREAM << unichar;
 		WRITE_FONT (dev);





More information about the rkward-tracker mailing list