[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