[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