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

tfry at users.sf.net tfry at users.sf.net
Tue Apr 2 12:02:58 UTC 2013


Revision: 4655
          http://sourceforge.net/p/rkward/code/4655
Author:   tfry
Date:     2013-04-02 12:02:57 +0000 (Tue, 02 Apr 2013)
Log Message:
-----------
Implement capture

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_protocol_shared.h
    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-04-01 15:40:28 UTC (rev 4654)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp	2013-04-02 12:02:57 UTC (rev 4655)
@@ -195,6 +195,12 @@
 	triggerUpdate ();
 }
 
+QImage RKGraphicsDevice::capture () const {
+	RK_TRACE (GRAPHICS_DEVICE);
+
+	return area.toImage ();
+}
+
 void RKGraphicsDevice::setActive (bool active) {
 	RK_TRACE (GRAPHICS_DEVICE);
 

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h	2013-04-01 15:40:28 UTC (rev 4654)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h	2013-04-02 12:02:57 UTC (rev 4655)
@@ -49,6 +49,7 @@
 	void polyline (const QPolygonF& pol, const QPen& pen);
 	void clear (const QColor& col=QColor());
 	void image (const QImage &image, const QRectF &target_rect, double rot, bool interpolate);
+	QImage capture () const;
 	void setActive (bool active);
 	void triggerUpdate ();
 	void locator ();

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-04-01 15:40:28 UTC (rev 4654)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp	2013-04-02 12:02:57 UTC (rev 4655)
@@ -267,6 +267,18 @@
 			bool interpolate;
 			streamer.instream >> target >> rotation >> interpolate;
 			device->image (image, target.normalized (), rotation, interpolate);
+		} else if (opcode == RKDCapture) {
+			QImage image = device->capture ();
+			quint32 w = image.width ();
+			quint32 h = image.height ();
+			streamer.outstream << w << h;
+			for (quint32 col = 0; col < h; ++col) {
+				for (quint32 row = 0; row < w; ++row) {
+					QRgb pixel = image.pixel (row, col);
+					streamer.outstream << (quint8) qRed (pixel) << (quint8) qGreen (pixel) << (quint8) qBlue (pixel) << (quint8) qAlpha (pixel);
+				}
+			}
+			streamer.writeOutBuffer ();
 		} else if (opcode == RKDLocator) {
 			device->locator ();
 #warning TODO keep track of status

Modified: branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
===================================================================
--- branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h	2013-04-01 15:40:28 UTC (rev 4654)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h	2013-04-02 12:02:57 UTC (rev 4655)
@@ -82,6 +82,7 @@
 	RKDMetricInfo, // 15
 	RKDLocator,
 	RKDNewPageConfirm,
+	RKDCapture,
 
 	// Protocol operations
 	RKDCancel

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-04-01 15:40:28 UTC (rev 4654)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_setup.cpp	2013-04-02 12:02:57 UTC (rev 4655)
@@ -147,7 +147,7 @@
 	dev->haveTransparency = 2;
 	dev->haveTransparentBg = 2; // FIXME. Do we really? Check.
 	dev->haveRaster = 2;
-	dev->haveCapture = 1;
+	dev->haveCapture = 2;
 	dev->haveLocator = 2;
 
 	/*
@@ -177,10 +177,11 @@
 	dev->polygon = RKD_Polygon;
 	dev->polyline = RKD_Polyline;
 	dev->rect = RKD_Rect;
-	dev->size = NULL; // RKD_Size;
+	dev->size = RKD_Size;
 	// dev->onexit = RKD_OnExit; NULL is OK
 	// dev->getEvent = SEXP (*getEvent)(SEXP, const char *);
 	dev->raster = RKD_Raster;
+	dev->cap = RKD_Capture;
 	dev->newFrameConfirm = RKD_NewFrameConfirm;
 
 	return true;

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-04-01 15:40:28 UTC (rev 4654)
+++ branches/development_branches/rkward_graphpics_device/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp	2013-04-02 12:02:57 UTC (rev 4655)
@@ -140,6 +140,14 @@
 	RKD_OUT_STREAM << width << height << QString::fromUtf8 (title) << antialias;
 }
 
+// TODO: Handle resizes
+static void RKD_Size (double *left, double *right, double *top, double *bottom, pDevDesc dev) {
+	*left = dev->left;
+	*top = dev->top;
+	*right = dev->right;
+	*bottom = dev->bottom;
+}
+
 static void RKD_Circle (double x, double y, double r, R_GE_gcontext *gc, pDevDesc dev) {
 	RKGraphicsDataStreamWriteGuard guard;
 	WRITE_HEADER (RKDCircle, dev);
@@ -294,6 +302,47 @@
 	RKD_OUT_STREAM << QRectF (x, y, width, height) << rot << (bool) interpolate;
 }
 
+static SEXP RKD_Capture (pDevDesc dev) {
+	{
+		RKGraphicsDataStreamWriteGuard wguard;
+		WRITE_HEADER (RKDCapture, dev);
+	}
+
+	quint32 w, h;
+	quint32 size;
+	int *buffer;
+	{
+		RKGraphicsDataStreamReadGuard rguard;
+		quint8 r, g, b, a;
+		RKD_IN_STREAM >> w >> h;
+		size = w*h;
+ 		buffer = new int[size];// Although unlikely, allocVector below could fail. We don't want to be left with a locked mutex (from the rguard) in this case. (Being left with a dead pointer looks bening in comparison)
+		quint32 i = 0;
+		for (quint32 col = 0; col < h; ++col) {
+			for (quint32 row = 0; row < w; ++row) {
+				RKD_IN_STREAM >> r >> g >> b >> a;
+				buffer[i++] = R_RGBA (r, g, b, a);
+			}
+		}
+	}
+	SEXP ret, dim;
+	PROTECT (ret = Rf_allocVector (INTSXP, size));
+	int* ret_vals = INTEGER (ret);
+	for (quint32 i = 0; i < size; ++i) {
+		ret_vals[i] = buffer[i];
+	}
+	delete (buffer);
+
+	// Documentation does not mention it, but cap expects dim information to be returned
+	PROTECT(dim = Rf_allocVector (INTSXP, 2));
+	INTEGER (dim)[0] = w;
+	INTEGER (dim)[1] = h;
+	Rf_setAttrib (ret, R_DimSymbol, dim);
+
+	UNPROTECT (2);
+	return ret;
+}
+
 static Rboolean RKD_Locator (double *x, double *y, pDevDesc dev) {
 	{
 		RKGraphicsDataStreamWriteGuard wguard;





More information about the rkward-tracker mailing list