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

tfry at users.sf.net tfry at users.sf.net
Wed Mar 20 19:54:31 UTC 2013


Revision: 4612
          http://sourceforge.net/p/rkward/code/4612
Author:   tfry
Date:     2013-03-20 19:54:28 +0000 (Wed, 20 Mar 2013)
Log Message:
-----------
Add first chunk of code for the experimental new graphics device. This is nowhere near compilable.

Added Paths:
-----------
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp
    branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.h

Added: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp	                        (rev 0)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp	2013-03-20 19:54:28 UTC (rev 4612)
@@ -0,0 +1,160 @@
+/***************************************************************************
+                          rkgraphicsdevice  -  description
+                             -------------------
+    begin                : Mon Mar 18 20:06:08 CET 2013
+    copyright            : (C) 2013 by Thomas Friedrichsmeier 
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+/******************************* ACKNOWLEDGEMENT ***************************
+ * 
+ * Much of the code in this file is based on, or 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 <QRect>
+#include "../rkrsupport.h"
+#include "rkgraphicsdevice_stubs.h"
+
+struct RKGraphicsDeviceDesc {
+	bool initRDevDesc (pDevDesc dev, double pointsize);
+	int devnum;
+	double width, height;
+	QString default_family;
+	pDevDesc rdevdesc;
+};
+
+#define RKGD_DPI 72
+
+void RKStartGraphicsDevice (double width, double height, double pointsize, const QString &family) {
+	if (width <= 0 || height <= 0) {
+		Rf_error ("Invalid width or height: (%g, %g)", width, height);
+	}
+	RKGraphicsDeviceDesc *desc = new RKGraphicsDeviceDesc;
+	desc->width = width * RKGD_DPI;
+	desc->height = height * RKGD_DPI;
+	desc->default_family = family;
+//	_scene->setSceneRect(0.0, 0.0, width, height);
+
+	R_GE_checkVersionOrDie (R_GE_version);
+	R_CheckDeviceAvailable ();
+	BEGIN_SUSPEND_INTERRUPTS {
+		pDevDesc dev;
+		/* Allocate and initialize the device driver data */
+		if (!(dev = (pDevDesc) calloc (1, sizeof(DevDesc))))
+			return 0; /* or error() */
+		/* set up device driver or free 'dev' and error() */
+		if (!desc->initRDevDesc (dev, pointsize, desc)) {
+			free (dev);
+			delete (desc);
+			Rf_error("unable to start device");
+		}
+		pGEDevDesc gdd = GEcreateDevDesc (dev);
+		gdd->displayList = R_NilValue;
+		GEaddDevice2 (gdd, "QTScene");
+	} END_SUSPEND_INTERRUPTS;
+
+	desc->devnum = curDevice ();
+}
+
+SEXP RKStartGraphicsDevice (SEXP width, SEXP height, SEXP pointsize, SEXP family
+#warning TODO: add more params for compatibility with X11
+) {
+	RKStartGraphicsDevice (Rf_asReal (width), Rf_asReal (height), Rf_asReal (pointsize), RKRSupport::SEXPToString (family));
+	return R_NilValue;
+}
+
+bool RKGraphicsDeviceDesc::initRDevDesc (pDevDesc dev, double pointsize) {
+	dev->deviceSpecific = (void *) this;
+
+	// pointsize?
+
+	/*
+	* Initial graphical settings
+	*/
+	dev->startfont = 1;
+	dev->startps = pointsize;
+	dev->startcol = R_RGB(0, 0, 0);
+	dev->startfill = R_TRANWHITE;
+	dev->startlty = LTY_SOLID;
+	dev->startgamma = 1;
+	/*
+	* Device physical characteristics
+	*/
+	dev->left   = dev->clipLeft   = 0;
+	dev->right  = dev->clipRight  = width;
+	dev->bottom = dev->clipBottom = height;
+	dev->top    = dev->clipTop    = 0;
+	dev->cra[0] = 0.9 * pointsize;
+	dev->cra[1] = 1.2 * pointsize;
+	dev->xCharOffset = 0.4900;
+	dev->yCharOffset = 0.3333;
+	dev->yLineBias = 0.1;
+	dev->ipr[0] = 1.0 / RKGD_DPI;
+	dev->ipr[1] = 1.0 / RKGD_DPI;
+	/*
+	* Device capabilities
+	*/
+	dev->canClip = FALSE; // FIXME. can clip, but then selection becomes weird
+	dev->canHAdj = 2;
+	dev->canChangeGamma = FALSE;
+	dev->displayListOn = TRUE;
+
+	dev->hasTextUTF8 = TRUE;
+	dev->textUTF8 = (void (*)()) RKD_TextUTF8;
+	dev->strWidthUTF8 = (double (*)()) RKD_StrWidthUTF8;
+	dev->wantSymbolUTF8 = TRUE;
+	dev->useRotatedTextInContour = TRUE;
+
+	dev->haveTransparency = 2;
+	dev->haveTransparentBg = 2; // FIXME. Do we really? Check.
+	dev->haveRaster = 1;
+	dev->haveCapture = 1;
+	dev->haveLocator = 2;
+
+	/*
+	* Mouse events
+	*/
+//     dev->canGenMouseDown = TRUE;
+//     dev->canGenMouseMove = TRUE;
+//     dev->canGenMouseUp = TRUE; 
+//     dev->canGenKeybd = TRUE;
+
+	// gettingEvent; This is set while getGraphicsEvent is actively
+	// looking for events
+
+	/*
+	* Device functions
+	*/
+	dev->activate =    (void (*)()) RKD_Activate;
+	dev->circle =      (void (*)()) RKD_Circle;
+	dev->clip =        (void (*)()) RKD_Clip;
+	dev->close =       (void (*)()) RKD_Close;
+	dev->deactivate =  (void (*)()) RKD_Deactivate;
+	dev->locator = (Rboolean (*)()) RKD_Locator;
+	dev->line =        (void (*)()) RKD_Line;
+	dev->metricInfo =  (void (*)()) RKD_MetricInfo;
+	dev->mode =        (void (*)()) RKD_Mode;
+	dev->newPage =     (void (*)()) RKD_NewPage;
+	dev->polygon =     (void (*)()) RKD_Polygon;
+	dev->polyline =    (void (*)()) RKD_Polyline;
+	dev->rect =        (void (*)()) RKD_Rect;
+	dev->size =        NULL; // (void (*)()) RKD_Size;
+	// dev->onexit =      (void (*)()) RKD_OnExit; NULL is OK
+	// dev->getEvent = SEXP (*getEvent)(SEXP, const char *);
+	dev->newFrameConfirm = (Rboolean (*)()) RKD_NewFrameConfirm;
+
+	return true;
+}
+ 

Added: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.h	                        (rev 0)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.h	2013-03-20 19:54:28 UTC (rev 4612)
@@ -0,0 +1,210 @@
+// NOTE: heavy copying from QGraphicsSceneDevice
+#include <QRect>
+#include <R_ext/GraphicsEngine.h>
+#include <limits.h>
+
+#define WRITE_HEADER(x,dev) (qint8) x << (quint8) static_cast<RKGraphicsDeviceDesc*> (dev->deviceSpecific)->devnum
+#define WRITE_COL() (qint32) gc->col
+#define WRITE_PEN() WRITE_COL() << (double) gc->lwd << (qint32) << gc->lty
+#define WRITE_LINE_ENDS() (quint8) gc->lend << (quint8) gc->ljoin << gc->lmitre
+#define WRITE_FILL() (qint32) gc->fill
+#define WRITE_FONT(dev) gc->cex << gc->ps << gc->lineheight << (quint8) gc->fontface << gc->fontfamily[0] ? QString (gc->fontfamily) : (static_cast<RKGraphicsDeviceDesc*> (dev->deviceSpecific)->default_family)
+
+QByteArray aux_buffer;
+QDataStream aux_stream;
+QByteArray buffer;
+QDataStream connection (&buffer);
+QMutex rkwarddeviceprotocolmutex;
+
+class RKSocketDataStreamWriteGuard {
+	RKSocketDataStreamWriteGuard () {
+		rkwarddeviceprotocolmutex.lock ();
+	}
+	~RKSocketDataStreamWriteGuard () {
+		aux_stream << (quint32) buffer.size ();
+		device.write (aux_stream);
+		aux_stream.resize (0);
+		device.write (buffer);
+		buffer.resize (0);
+		rkwarddeviceprotocolmutex.unlock ();
+	}
+};
+
+enum {
+	// Asynchronous operations
+	RKDCircle,
+	RKDLine,
+	RKDPolygon,
+	RKDPolyline,
+	RKDRect,
+	RKDTextUTF8,
+	RKDNewPage,
+	RKDClose,
+	RKDActivate,
+	RKDDeActivate,
+	RKDClip,
+	RKDMode,
+
+	// Synchronous operations
+	RKD_First_Synchronous_Request,
+	RKDStrWidthUTF8,
+	RKDMetricInfo,
+	RKDLocator,
+	RKDNewPageConfirm
+} OpCodes;
+
+static void RKD_Circle (double x, double y, double r, R_GE_gcontext *gc, pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDCircle, dev);
+	connection << x << y << r;
+	connection << WRITE_PEN ();
+}
+
+static void RKD_Line (double x1, double y1, double x2, double y2, R_GE_gcontext *gc, pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDLine, dev);
+	connection << x1 << y1 << x2 << y2;
+	connection << WRITE_PEN ();
+}
+
+static void RKD_Polygon (int n, double *x, double *y, R_GE_gcontext *gc, pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDPolygon, dev);
+	quint32 _n = qMax (n, std::numeric_limits<quint32>::max());
+	connection << _n;
+	for (quint32 i; i < n; ++i) {
+		connection << x[i] << y[i];
+	}
+	connection << WRITE_PEN ();
+	connection << WRITE_LINE_ENDS ();
+	connection << WRITE_FILL ();
+}
+
+static void RKD_Polyline (int n, double *x, double *y, R_GE_gcontext *gc, pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDPolyline, dev);
+	quint32 _n = qMax (n, std::numeric_limits<quint32>::max());
+	connection << _n;
+	for (quint32 i; i < n; ++i) {
+		connection << x[i] << y[i];
+	}
+	connection << WRITE_PEN ();
+	connection << WRITE_LINE_ENDS ();
+}
+
+static void RKD_Rect (double x0, double y0, double x1, double y1, R_GE_gcontext *gc, pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDPolyline, dev);
+	connection << QRectF (x0, y0, x1-x0, y1-y0);
+	connection << WRITE_PEN ();
+	connection << WRITE_LINE_ENDS ();
+	connection << WRITE_FILL ();
+}
+
+static void RKD_TextUTF8 (double x, double y, char *str, double rot, double hadj, R_GE_gcontext *gc, pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDTextUTF8, dev);
+	connection << x << y << QString::fromUtf8 (str) << rot << hadj;
+	connection << WRITE_COL ();
+	connection << WRITE_FONT (dev);
+}
+
+static double RKD_StrWidthUTF8 (char *str, R_GE_gcontext *gc, pDevDesc dev) {
+	{
+		RKSocketDataStreamWriteGuard guard;
+		connection << WRITE_HEADER (RKDStrWidthUTF8, dev);
+		connection << QString::fromUtf8 (str);
+		connection << WRITE_FONT (dev);
+	}
+	double ret;
+	{
+		RKSocketDataStreamReadGuard guard;
+		ret << connection;
+	}
+	return ret;
+}
+
+static void RKD_NewPage (R_GE_gcontext *gc, pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDNewPage, dev);
+	connection << WRITE_FILL ();
+}
+
+static void RKD_MetricInfo (int c, R_GE_gcontext *gc, double* ascent, double* descent, double* width, pDevDesc dev) {
+	{
+		RKSocketDataStreamWriteGuard guard;
+		connection << WRITE_HEADER (RKDMetricInfo, dev);
+		connection << QChar (c);
+		connection << WRITE_FONT (dev);
+	}
+	{
+		RKSocketDataStreamReadGuard guard;
+		*ascent << connection;
+		*descent << connection;
+		*width << connection;
+	}
+}
+
+static void RKD_Close (pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDClose, dev);
+}
+
+static void RKD_Activate(pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDActivate, dev);
+}
+
+static void RKD_Deactivate(pDevDesc dev) {
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDDeActivate, dev);
+}
+
+static void RKD_Clip(double left, double right, double top, double bottom, pDevDesc dev) {
+	dev->clipLeft = left;
+	dev->clipRight = right;
+	dev->clipTop = top;
+	dev->clipBottom = bottom;
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDClip, dev);
+	connection << QRectF (left, top, right - left, bottom - top);
+}
+
+static void RKD_Mode (int mode, pDevDesc dev) {
+/* Left empty for now. 1 is start signal, 0 is stop signal. Might be useful for flushing, though.
+
+	RKSocketDataStreamWriteGuard guard;
+	connection << WRITE_HEADER (RKDMode, dev);
+	connectoin << (qint8) mode; */
+}
+
+static Rboolean RKD_Locator (double *x, double *y, pDevDesc dev) {
+	{
+		RKSocketDataStreamWriteGuard guard;
+		connection << WRITE_HEADER (RKDLocator, dev);
+	}
+#warning TODO: handle cancellation from backend
+	{
+		RKSocketDataStreamReadGuard guard;
+		bool ok;
+		ok << connection;
+		*x << connection;
+		*y << connection;
+		if (ok) return TRUE;
+		return FALSE;
+	}
+}
+
+static Rboolean RKD_NewFrameConfirm (pDevDesc dev) {
+	{
+		RKSocketDataStreamWriteGuard guard;
+		connection << WRITE_HEADER (RKDNewPageConfirm, dev);
+	}
+#warning TODO: handle cancellation from backend
+	{
+		RKSocketDataStreamReadGuard guard;
+		bool ok << connection;
+		if (ok) return TRUE;
+		return FALSE;
+	}
+}





More information about the rkward-tracker mailing list