[education/rkward] rkward/rbackend/rkwarddevice: Forced synchronization is not needed after all, only proper initialization of fresh QImages.

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


Git commit 34948803e56dcb058f5bc29a4cf7800e4af2c5e5 by Thomas Friedrichsmeier.
Committed on 24/03/2022 at 19:34.
Pushed by tfry into branch 'master'.

Forced synchronization is not needed after all, only proper initialization of fresh QImages.

Also simplify mask calculation.

M  +6    -17   rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
M  +1    -4    rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
M  +1    -2    rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
M  +1    -18   rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp

https://invent.kde.org/education/rkward/commit/34948803e56dcb058f5bc29a4cf7800e4af2c5e5

diff --git a/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp b/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
index 6c828c76..fa72f383 100644
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice.cpp
@@ -93,6 +93,7 @@ void RKGraphicsDevice::pushContext(double width, double height, double x, double
 // probably due to cairo internals, somehow. Here, instead we paint on a separate surface with the same coords,
 // then extract the rectangle of interest.
 	c.surface = QImage(area.width(), area.height(), QImage::Format_ARGB32);
+	c.surface.fill(Qt::transparent);
 	if (width < 0) { // may happen, at least in R 4.1.2
 		width = -width;
 		x -= width;
@@ -115,6 +116,7 @@ RKGraphicsDevice::PaintContext RKGraphicsDevice::popContext() {
 	}
 
 	painter.end();
+
 	auto ret = contexts.takeLast();
 	recorded_path = ret.path_below;
 	beginPainter();
@@ -140,6 +142,7 @@ int RKGraphicsDevice::finalizeTilingPattern(int extend) {
 	if (extend == GradientExtendReflect) {
 		QImage single = c.surface.copy(c.capture_coords);
 		QImage reflected(single.width()*2, single.height()*2, single.format());
+		reflected.fill(Qt::transparent);
 		QPainter p(&reflected);
 		p.drawImage(0, 0, single);
 		p.drawImage(single.width(), 0, single.mirrored(true, false));
@@ -321,16 +324,9 @@ QImage RKGraphicsDevice::endRecordMask(bool luminance) {
 	QImage ret = popContext().surface;
 	// KF6 TODO: instead paint on a grayscale surface from the start?
 	if (luminance) {
-		for (int x = ret.width(); x >= 0; --x) {
-			for (int y = ret.height(); y >= 0; --y) {
-				// warning! inefficient!
-				QColor px = ret.pixelColor(x, y);
-				px.setAlpha(px.lightness());
-				ret.setPixelColor(x, y, px);
-			}
-		}
+		return ret.convertToFormat(QImage::Format_Grayscale8);
 	}
-	return ret;
+	return ret.convertToFormat(QImage::Format_Alpha8);
 }
 
 int RKGraphicsDevice::registerMask(const QImage& mask) {
@@ -414,14 +410,7 @@ void RKGraphicsDevice::rect (const QRectF& rec, const QPen& pen, const QBrush& b
 	if (current_mask) {
 		QImage mask = cached_masks.value(current_mask);
 		QImage masked = popContext().surface;
-		for (int x = masked.width(); x >= 0; --x) {
-			for (int y = masked.height(); y >= 0; --y) {
-				// warning! inefficient!
-				QColor px = masked.pixelColor(x, y);
-				px.setAlpha(qMin(px.alpha(), mask.pixelColor(x, y).alpha()));
-				masked.setPixelColor(x, y, px);
-			}
-		}
+		masked.setAlphaChannel(mask); // NOTE: QT docs: "If the image already has an alpha channel, the existing alpha channel is multiplied with the new one."
 		painter.drawImage(0, 0, masked);
 	}
 
diff --git a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
index c9f23f22..50fc0f90 100644
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
@@ -465,9 +465,6 @@ void RKGraphicsDeviceFrontendTransmitter::newData () {
 			streamer.writeOutBuffer ();
 		} else if (opcode == RKDNewPageConfirm) {
 			device->confirmNewPage ();
-		} else if (opcode == RKDForceSync) {
-			device->forceSync();
-			sendDummyReply(opcode);
 		} else {
 			RK_DEBUG (GRAPHICS_DEVICE, DL_ERROR, "Unhandled operation of type %d for device number %d. Skipping.", opcode, devnum+1);
 		}
@@ -508,7 +505,7 @@ void RKGraphicsDeviceFrontendTransmitter::sendDummyReply (quint8 opcode) {
 		streamer.outstream << (qint32) 0;
 	} else if (opcode == RKDFetchNextEvent) {
 		streamer.outstream << (qint8) RKDNothing;
-	} else if (opcode == RKDClose || opcode == RKDForceSync) {
+	} else if (opcode == RKDClose) {
 		streamer.outstream << (qint8) RKDNothing;
 	} else {
 		return;	// nothing to write
diff --git a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
index 07d4e462..80e4dc2e 100644
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_protocol_shared.h
@@ -126,8 +126,7 @@ enum RKDOpcodes {
 	RKDEndRecordClipPath,
 	RKDSetMask,
 	RKDEndRecordMask,
-	RKDForceSync,
-	RKDClose,             // 115
+	RKDClose,
 
 	// Protocol operations
 	RKDCancel              = 200
diff --git a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp
index 5c1fe048..4dc7cdd3 100644
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_stubs.cpp
@@ -671,21 +671,6 @@ SEXP makeInt(int val) {
 	return ret;
 }
 
-void forceSync(pDevDesc dev) {
-	RK_TRACE(GRAPHICS_DEVICE);
-// NOTE: See comment in RKGraphicsDevice::forceSync();
-// KF6 TODO: Still neded with Qt6?
-	{
-		RKGraphicsDataStreamWriteGuard wguard;
-		WRITE_HEADER(RKDForceSync, dev);
-	}
-	{
-		RKGraphicsDataStreamReadGuard rguard;
-		qint8 dummy;
-		RKD_IN_STREAM >> dummy;
-	}
-}
-
 SEXP RKD_SetPattern (SEXP pattern, pDevDesc dev) {
 	RK_TRACE(GRAPHICS_DEVICE);
 	auto ptype = R_GE_patternType(pattern);
@@ -715,7 +700,6 @@ SEXP RKD_SetPattern (SEXP pattern, pDevDesc dev) {
 			RKD_OUT_STREAM << getGradientExtend(R_GE_radialGradientExtend(pattern));
 		}
 	} else if (ptype == R_GE_tilingPattern) {
-		forceSync(dev);
 		{
 			RKGraphicsDataStreamWriteGuard wguard;
 			WRITE_HEADER(RKDStartRecordTilingPattern, dev);
@@ -728,7 +712,6 @@ SEXP RKD_SetPattern (SEXP pattern, pDevDesc dev) {
 		SEXP pattern_func = PROTECT(Rf_lang1(R_GE_tilingPatternFunction(pattern)));
 		R_tryEval(pattern_func, R_GlobalEnv, &error);
 		UNPROTECT(1);
-		forceSync(dev);
 		{
 			RKGraphicsDataStreamWriteGuard wguard;
 			WRITE_HEADER(RKDEndRecordTilingPattern, dev);
@@ -866,7 +849,7 @@ SEXP RKD_SetMask (SEXP mask, SEXP ref, pDevDesc dev) {
 #if R_VERSION >= R_Version(4,2,0)
 		RKD_OUT_STREAM << (qint8) R_GE_maskType(mask) == R_GE_luminanceMask ? 1 : 0;
 #else
-		RKD_OUT_STREAM << 0;
+		RKD_OUT_STREAM << (qint8) 0;
 #endif
 	}
 	{



More information about the rkward-tracker mailing list