ArthurOutputDev: Rudimentary support for transparency groups
This patch adds minimal support for transparency groups. With it,
the Arthur backend can render highlight annotations.
diff --git a/qt5/src/ArthurOutputDev.cc b/qt5/src/ArthurOutputDev.cc
index c5afc14..96774e5 100644
--- a/qt5/src/ArthurOutputDev.cc
+++ b/qt5/src/ArthurOutputDev.cc
@@ -55,6 +55,8 @@
#include <QRawFont>
#include <QGlyphRun>
#include <QtGui/QPainterPath>
+#include <QPicture>
+
//------------------------------------------------------------------------
#ifdef HAVE_SPLASH
@@ -89,6 +91,7 @@
//------------------------------------------------------------------------
ArthurOutputDev::ArthurOutputDev(QPainter *painter):
+ m_lastTransparencyGroupPicture(nullptr),
m_fontHinting(NoHinting)
{
m_painter.push(painter);
@@ -990,3 +993,46 @@
m_painter.top()->drawImage( QRect(0,0,1,1), image );
}
+void ArthurOutputDev::beginTransparencyGroup(GfxState * /*state*/, double * /*bbox*/,
+ GfxColorSpace * /*blendingColorSpace*/,
+ GBool /*isolated*/, GBool /*knockout*/,
+ GBool /*forSoftMask*/)
+{
+ // The entire transparency group will be painted into a
+ // freshly created QPicture object. Since an existing painter
+ // cannot change its paint device, we need to construct a
+ // new QPainter object as well.
+ m_qpictures.push(new QPicture);
+ m_painter.push(new QPainter(m_qpictures.top()));
+}
+
+void ArthurOutputDev::endTransparencyGroup(GfxState * /*state*/)
+{
+ // Stop painting into the group
+ m_painter.top()->end();
+
+ // Kill the painter that has been used for the transparency group
+ delete(m_painter.top());
+ m_painter.pop();
+
+ // Store the QPicture object that holds the result of the transparency group
+ // painting. It will be painted and deleted in the method paintTransparencyGroup.
+ if (m_lastTransparencyGroupPicture)
+ {
+ qDebug() << "Found a transparency group that has not been painted";
+ delete(m_lastTransparencyGroupPicture);
+ }
+ m_lastTransparencyGroupPicture = m_qpictures.top();
+ m_qpictures.pop();
+}
+
+void ArthurOutputDev::paintTransparencyGroup(GfxState * /*state*/, double * /*bbox*/)
+{
+ // Actually draw the transparency group
+ m_painter.top()->drawPicture(0,0,*m_lastTransparencyGroupPicture);
+
+ // And delete it
+ delete(m_lastTransparencyGroupPicture);
+ m_lastTransparencyGroupPicture = nullptr;
+}
+
diff --git a/qt5/src/ArthurOutputDev.h b/qt5/src/ArthurOutputDev.h
index 4fae0a5..b4ab3d7 100644
--- a/qt5/src/ArthurOutputDev.h
+++ b/qt5/src/ArthurOutputDev.h
@@ -164,6 +164,14 @@
void type3D1(GfxState *state, double wx, double wy,
double llx, double lly, double urx, double ury) override;
+ //----- transparency groups and soft masks
+ virtual void beginTransparencyGroup(GfxState *state, double *bbox,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ GBool forSoftMask) override;
+ virtual void endTransparencyGroup(GfxState *state) override;
+ virtual void paintTransparencyGroup(GfxState *state, double *bbox) override;
+
//----- special access
// Called to indicate that a new PDF document has been loaded.
@@ -178,6 +186,13 @@
// It is popped again when the transparency group ends.
std::stack<QPainter*> m_painter;
+ // This is the corresponding stack of QPicture objects
+ std::stack<QPicture*> m_qpictures;
+
+ // endTransparencyGroup removes a QPicture from the stack, but stores
+ // it here for later use in paintTransparencyGroup.
+ QPicture* m_lastTransparencyGroupPicture;
+
FontHinting m_fontHinting;
QPen m_currentPen;