[education/rkward] rkward/rbackend/rkwarddevice: Use a different stack for keeping track of path recordings. They are mostly orthogonal to pattern recordings, after all.

Thomas Friedrichsmeier null at kde.org
Thu Mar 24 21:02:51 GMT 2022


Git commit 43a269d79c39e1bac741721030bb8a074edebea4 by Thomas Friedrichsmeier.
Committed on 24/03/2022 at 21:01.
Pushed by tfry into branch 'master'.

Use a different stack for keeping track of path recordings. They are mostly orthogonal to pattern recordings, after all.

M  +11   -11   rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
M  +2    -4    rkward/rbackend/rkwarddevice/rkgraphicsdevice.h

https://invent.kde.org/education/rkward/commit/43a269d79c39e1bac741721030bb8a074edebea4

diff --git a/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp b/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
index fb269003..a0bf9815 100644
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
@@ -78,17 +78,14 @@ void RKGraphicsDevice::beginPainter() {
 			auto &c = contexts.last();
 			painter.begin(&(c.surface));
 			painter.setTransform(c.transform);
-			recording_path = c.record_path;
 		}
 	}
 }
 
-void RKGraphicsDevice::pushContext(double width, double height, double x, double y, bool record_path) {
+void RKGraphicsDevice::pushContext(double width, double height, double x, double y) {
 	RK_TRACE (GRAPHICS_DEVICE);
 	painter.end();
 	PaintContext c;
-	c.record_path = record_path;
-	c.path_below = recorded_path;
 // NOTE: R cairo device uses an all different method for pattern capture:
 // drawing is scaled up to full device coordinates, then shrunk and offset back to pattern size.
 // probably due to cairo internals, somehow. Here, instead we paint on a separate surface with the same coords,
@@ -117,16 +114,14 @@ RKGraphicsDevice::PaintContext RKGraphicsDevice::popContext() {
 	}
 
 	painter.end();
-
 	auto ret = contexts.takeLast();
-	recorded_path = ret.path_below;
 	beginPainter();
 	return ret;
 }
 
 void RKGraphicsDevice::initMaskedDraw(){
 	RK_ASSERT(current_mask);
-	pushContext(area.width(), area.height(), 0, 0, false);
+	pushContext(area.width(), area.height(), 0, 0);
 }
 
 void RKGraphicsDevice::commitMaskedDraw() {
@@ -139,7 +134,7 @@ void RKGraphicsDevice::commitMaskedDraw() {
 
 void RKGraphicsDevice::startRecordTilingPattern(double width, double height, double x, double y) {
 	RK_TRACE (GRAPHICS_DEVICE);
-	pushContext(width, height, x, y, false);
+	pushContext(width, height, x, y);
 }
 
 int RKGraphicsDevice::finalizeTilingPattern(int extend) {
@@ -277,7 +272,10 @@ void RKGraphicsDevice::destroyPattern(int id) {
 
 void RKGraphicsDevice::startRecordPath() {
 	RK_TRACE(GRAPHICS_DEVICE);
-	pushContext(0, 0, 0, 0, true);
+
+	stashed_paths.append(recorded_path);
+	recorded_path = QPainterPath();
+	recording_path = true;
 }
 
 QPainterPath RKGraphicsDevice::endRecordPath(int fillrule) {
@@ -287,7 +285,9 @@ QPainterPath RKGraphicsDevice::endRecordPath(int fillrule) {
 	if (fillrule == NonZeroWindingRule) ret.setFillRule(Qt::WindingFill);
 	else ret.setFillRule(Qt::OddEvenFill);
 
-	popContext();
+	RK_ASSERT(!stashed_paths.isEmpty());
+	recorded_path = stashed_paths.takeLast();
+	recording_path = !stashed_paths.isEmpty();
 	return ret;
 }
 
@@ -315,7 +315,7 @@ bool RKGraphicsDevice::setClipToCachedPath(int index){
 
 void RKGraphicsDevice::startRecordMask() {
 	RK_TRACE (GRAPHICS_DEVICE);
-	pushContext(area.width(), area.height(), 0, 0, false);
+	pushContext(area.width(), area.height(), 0, 0);
 }
 
 QImage RKGraphicsDevice::endRecordMask(bool luminance) {
diff --git a/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h b/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
index eaa3f52c..9a69437c 100644
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice.h
@@ -143,6 +143,7 @@ private:
 	// NOTE on path recording: In principle, we could really do _all_ painting on QPainterPath, but in regular operation stroke and fill right away.
 	// However, that is noticably slower.
 	QPainterPath recorded_path;
+	QList<QPainterPath> stashed_paths;
 	bool recording_path;
 	int current_mask;
 
@@ -152,17 +153,14 @@ private:
 	QList<StoredEvent> stored_events;
 
 	struct PaintContext {
-		// TODO: this probably also needs info like clipping paths, transforms, add mode, etc. Just an initial attempt.
 		QImage surface;
 		QTransform transform;
 		QRect capture_coords;
-		QPainterPath path_below;
-		bool record_path;
 	};
 	QList<PaintContext> contexts;
 	// make sure the painter is active on the current context
 	void beginPainter();
-	void pushContext(double width, double height, double x, double y, bool record_path);
+	void pushContext(double width, double height, double x, double y);
 	PaintContext popContext();
 	void initMaskedDraw();
 	void commitMaskedDraw();


More information about the rkward-tracker mailing list