Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 15c86a05..8cbeb6a5 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -1565,40 +1565,54 @@ void Annot::incRefCnt() {
annotLocker();
refCnt++;
}
void Annot::decRefCnt() {
#ifdef MULTITHREADED
gLockMutex(&mutex);
#endif
if (--refCnt == 0) {
#ifdef MULTITHREADED
gUnlockMutex(&mutex);
#endif
delete this;
return;
}
#ifdef MULTITHREADED
gUnlockMutex(&mutex);
#endif
}
+Gfx* Annot::createGfx(OutputDev* output, double hDPI, double vDPI, double width, double height) {
+ int pageNum = getPageNum();
+ Dict *resDict = getDoc()->getPage(pageNum)->getResourceDict();
+ PDFRectangle box(0, 0, width, height);
+ int rotate = 0;
+ GBool (*abortCheckCbkA)(void *data) = NULL;
+ void *abortCheckCbkDataA = NULL;
+ XRef *xrefA = getXRef();
+ Gfx *gfx = new Gfx(doc, output, pageNum, resDict,
+ hDPI, vDPI, &box, (PDFRectangle *)NULL,
+ rotate, abortCheckCbkA, abortCheckCbkDataA, xrefA);
+ return gfx;
+}
+
Annot::~Annot() {
delete rect;
delete contents;
if (name)
delete name;
if (modified)
delete modified;
delete appearStreams;
delete appearBBox;
if (appearState)
delete appearState;
if (border)
delete border;
if (color)
@@ -1803,49 +1817,95 @@ GBool Annot::isVisible(GBool printing) {
if (optContentConfig) {
if (! optContentConfig->optContentIsVisible(&oc))
return gFalse;
}
return gTrue;
}
int Annot::getRotation() const
{
Page *pageobj = doc->getPage(page);
assert(pageobj != nullptr);
if (flags & flagNoRotate) {
return (360 - pageobj->getRotate()) % 360;
} else {
return 0;
}
}
-void Annot::draw(Gfx *gfx, GBool printing) {
+void Annot::draw(Gfx *gfx, GBool printing, GBool drawAtOrigin) {
+ Object obj;
+ PDFRectangle drawRect;
+
+ if (!isVisible (printing))
+ return;
+
annotLocker();
+
+ makeAppearance(obj, drawRect, gfx->getXRef());
+
+ if (drawAtOrigin) {
+ drawRect.translate(-drawRect.x1, -drawRect.y1);
+ }
+
+ drawAppearance(gfx, obj, drawRect);
+}
+
+/* Only this Annot::draw overload can create a Gfx with correct size, because:
+ * -Size of Gfx must be given in Ctor Gfx::Gfx(...box...). Size can't be changed afterwards.
+ * -We don't know the actual size before makeAppearance (NB: Because drawRect may be != Annot::rect.)
+ * Which version of Annot::draw to use? */
+void Annot::draw(OutputDev *outputDev, GBool printing, double hDPI, double vDPI, GBool drawAtOrigin) {
+ Gfx *gfx;
+ Object obj;
+ PDFRectangle drawRect;
+
if (!isVisible (printing))
return;
+ annotLocker();
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
+ /* 1st part of templated algorithm: recreate appearance to resulting form object and size rectangle */
+ makeAppearance(obj, drawRect, getXRef());
+
+ /* Hook in here to respect size of new drawRect, which may be != Annot::rect. */
+ gfx = createGfx(outputDev, hDPI, vDPI, drawRect.x2 - drawRect.x1, drawRect.y2 - drawRect.y1);
+ if (drawAtOrigin) {
+ /* Shift to origin. */
+ drawRect.translate(-drawRect.x1, -drawRect.y1);
+ }
+
+ /* 2nd part of templated algorithm: Draw appearance */
+ drawAppearance(gfx, obj, drawRect);
+
+ delete gfx;
+}
+
+void Annot::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
+ obj = appearance.fetch(xref);
+ drawRect = *Annot::rect;
+}
+
+void Annot::drawAppearance(Gfx *gfx, Object& obj, const PDFRectangle& drawRect) {
gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ drawRect.x1, drawRect.y1, drawRect.x2, drawRect.y2, getRotation());
}
//------------------------------------------------------------------------
// AnnotPopup
//------------------------------------------------------------------------
AnnotPopup::AnnotPopup(PDFDoc *docA, PDFRectangle *rect) :
Annot(docA, rect) {
type = typePopup;
annotObj.dictSet ("Subtype", Object(objName, "Popup"));
initialize (docA, annotObj.getDict());
}
AnnotPopup::AnnotPopup(PDFDoc *docA, Object *dictObject, Object *obj) :
Annot(docA, dictObject, obj) {
type = typePopup;
initialize(docA, dictObject->getDict());
}
@@ -2408,52 +2468,49 @@ void AnnotText::setIcon(GooString *new_icon) {
"0.729412 0.741176 0.713725 RG 18 6 m 6 18 l S\n" \
"6 6 m 18 18 l S\n"
#define ANNOT_TEXT_AP_CIRCLE \
"4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n" \
"2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
"l 1 21.523 2.477 23 4.301 23 c h\n" \
"4.301 23 m f\n" \
"0.533333 0.541176 0.521569 RG 2.5 w\n" \
"1 J\n" \
"1 j\n" \
"[] 0.0 d\n" \
"4 M 19.5 11.5 m 19.5 7.359 16.141 4 12 4 c 7.859 4 4.5 7.359 4.5 11.5 c 4.5\n" \
"15.641 7.859 19 12 19 c 16.141 19 19.5 15.641 19.5 11.5 c h\n" \
"19.5 11.5 m S\n" \
"0.729412 0.741176 0.713725 RG 19.5 12.5 m 19.5 8.359 16.141 5 12 5 c\n" \
"7.859 5 4.5 8.359 4.5 12.5 c 4.5\n" \
"16.641 7.859 20 12 20 c 16.141 20 19.5 16.641 19.5 12.5 c h\n" \
"19.5 12.5 m S\n"
-void AnnotText::draw(Gfx *gfx, GBool printing) {
+void AnnotText::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
double ca = 1;
- if (!isVisible (printing))
- return;
-
- annotLocker();
+ /* If there was no embedded appearance stream in document,
+ * generate a in-memory default appearance stream.
+ * Else use the appearance stream from PDF. */
if (appearance.isNull()) {
ca = opacity;
-
appearBuf = new GooString ();
-
appearBuf->append ("q\n");
if (color)
setColor(color, gTrue);
else
appearBuf->append ("1 1 1 rg\n");
if (!icon->cmp("Note"))
appearBuf->append (ANNOT_TEXT_AP_NOTE);
else if (!icon->cmp("Comment"))
appearBuf->append (ANNOT_TEXT_AP_COMMENT);
else if (!icon->cmp("Key"))
appearBuf->append (ANNOT_TEXT_AP_KEY);
else if (!icon->cmp("Help"))
appearBuf->append (ANNOT_TEXT_AP_HELP);
else if (!icon->cmp("NewParagraph"))
appearBuf->append (ANNOT_TEXT_AP_NEW_PARAGRAPH);
else if (!icon->cmp("Paragraph"))
appearBuf->append (ANNOT_TEXT_AP_PARAGRAPH);
else if (!icon->cmp("Insert"))
appearBuf->append (ANNOT_TEXT_AP_INSERT);
else if (!icon->cmp("Cross"))
@@ -2463,50 +2520,46 @@ void AnnotText::draw(Gfx *gfx, GBool printing) {
appearBuf->append ("Q\n");
// Force 24x24 rectangle
PDFRectangle fixedRect(rect->x1, rect->y2 - 24, rect->x1 + 24, rect->y2);
appearBBox = new AnnotAppearanceBBox(&fixedRect);
double bbox[4];
appearBBox->getBBoxRect(bbox);
if (ca == 1) {
appearance = createForm(bbox, gFalse, nullptr);
} else {
Object aStream = createForm(bbox, gTrue, nullptr);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict);
}
delete appearBuf;
}
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
+ obj = appearance.fetch(xref);
if (appearBBox) {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- appearBBox->getPageXMin(), appearBBox->getPageYMin(),
- appearBBox->getPageXMax(), appearBBox->getPageYMax(),
- getRotation());
+ drawRect = PDFRectangle(appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+ appearBBox->getPageXMax(), appearBBox->getPageYMax());
} else {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ drawRect = *rect;
}
}
//------------------------------------------------------------------------
// AnnotLink
//------------------------------------------------------------------------
AnnotLink::AnnotLink(PDFDoc *docA, PDFRectangle *rect) :
Annot(docA, rect) {
type = typeLink;
annotObj.dictSet ("Subtype", Object(objName, "Link"));
initialize (docA, annotObj.getDict());
}
AnnotLink::AnnotLink(PDFDoc *docA, Object *dictObject, Object *obj) :
Annot(docA, dictObject, obj) {
type = typeLink;
initialize (docA, dictObject->getDict());
}
@@ -2563,49 +2616,43 @@ void AnnotLink::initialize(PDFDoc *docA, Dict *dict) {
uriAction = NULL;
}
obj1.free();
*/
obj1 = dict->lookup("QuadPoints");
if (obj1.isArray()) {
quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
} else {
quadrilaterals = nullptr;
}
obj1 = dict->lookup("BS");
if (obj1.isDict()) {
delete border;
border = new AnnotBorderBS(obj1.getDict());
} else if (!border) {
border = new AnnotBorderBS();
}
}
-void AnnotLink::draw(Gfx *gfx, GBool printing) {
- if (!isVisible (printing))
- return;
-
- annotLocker();
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
- gfx->drawAnnot(&obj, border, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+void AnnotLink::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
+ obj = appearance.fetch(xref);
+ drawRect = *rect;
}
//------------------------------------------------------------------------
// AnnotFreeText
//------------------------------------------------------------------------
AnnotFreeText::AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, GooString *da) :
AnnotMarkup(docA, rect) {
type = typeFreeText;
annotObj.dictSet ("Subtype", Object(objName, "FreeText"));
annotObj.dictSet("DA", Object(da->copy()));
initialize (docA, annotObj.getDict());
}
AnnotFreeText::AnnotFreeText(PDFDoc *docA, Object *dictObject, Object *obj) :
AnnotMarkup(docA, dictObject, obj) {
type = typeFreeText;
initialize(docA, dictObject->getDict());
}
@@ -2940,53 +2987,47 @@ void AnnotFreeText::generateFreeTextAppearance()
appearBuf->append ("ET Q\n");
double bbox[4];
bbox[0] = bbox[1] = 0;
bbox[2] = rect->x2 - rect->x1;
bbox[3] = rect->y2 - rect->y1;
if (ca == 1) {
appearance = createForm(bbox, gFalse, fontResDict);
} else {
Object aStream = createForm(bbox, gTrue, fontResDict);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict);
}
delete appearBuf;
}
-void AnnotFreeText::draw(Gfx *gfx, GBool printing) {
- if (!isVisible (printing))
- return;
-
- annotLocker();
+void AnnotFreeText::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
if (appearance.isNull()) {
generateFreeTextAppearance();
}
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ obj = appearance.fetch(xref);
+ drawRect = *rect;
}
// Before retrieving the res dict, regenerate the appearance stream if needed,
// because AnnotFreeText::draw needs to store font info in the res dict
Object AnnotFreeText::getAppearanceResDict() {
if (appearance.isNull()) {
generateFreeTextAppearance();
}
return Annot::getAppearanceResDict();
}
//------------------------------------------------------------------------
// AnnotLine
//------------------------------------------------------------------------
AnnotLine::AnnotLine(PDFDoc *docA, PDFRectangle *rect) :
AnnotMarkup(docA, rect) {
type = typeLine;
annotObj.dictSet ("Subtype", Object(objName, "Line"));
@@ -3378,59 +3419,52 @@ void AnnotLine::generateLineAppearance()
appearBBox->extendTo (tx, ty);
}
appearBuf->append ("Q\n");
double bbox[4];
appearBBox->getBBoxRect(bbox);
if (ca == 1) {
appearance = createForm(bbox, gFalse, fontResDict);
} else {
Object aStream = createForm(bbox, gTrue, fontResDict);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict);
}
delete appearBuf;
}
-void AnnotLine::draw(Gfx *gfx, GBool printing) {
- if (!isVisible (printing))
- return;
-
- annotLocker();
+void AnnotLine::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
if (appearance.isNull()) {
generateLineAppearance();
}
// draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
+ obj = appearance.fetch(xref);
if (appearBBox) {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- appearBBox->getPageXMin(), appearBBox->getPageYMin(),
- appearBBox->getPageXMax(), appearBBox->getPageYMax(),
- getRotation());
+ drawRect = PDFRectangle(appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+ appearBBox->getPageXMax(), appearBBox->getPageYMax());
} else {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ drawRect = *rect;
}
}
// Before retrieving the res dict, regenerate the appearance stream if needed,
// because AnnotLine::draw may need to store font info in the res dict
Object AnnotLine::getAppearanceResDict() {
if (appearance.isNull()) {
generateLineAppearance();
}
return Annot::getAppearanceResDict();
}
//------------------------------------------------------------------------
// AnnotTextMarkup
//------------------------------------------------------------------------
AnnotTextMarkup::AnnotTextMarkup(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType) :
AnnotMarkup(docA, rect) {
switch (subType) {
case typeHighlight:
annotObj.dictSet ("Subtype", Object(objName, "Highlight"));
@@ -3525,48 +3559,44 @@ void AnnotTextMarkup::setQuadrilaterals(AnnotQuadrilaterals *quadPoints) {
Array *a = new Array(xref);
for (int i = 0; i < quadPoints->getQuadrilateralsLength(); ++i) {
a->add(Object(quadPoints->getX1(i)));
a->add(Object(quadPoints->getY1(i)));
a->add(Object(quadPoints->getX2(i)));
a->add(Object(quadPoints->getY2(i)));
a->add(Object(quadPoints->getX3(i)));
a->add(Object(quadPoints->getY3(i)));
a->add(Object(quadPoints->getX4(i)));
a->add(Object(quadPoints->getY4(i)));
}
delete quadrilaterals;
quadrilaterals = new AnnotQuadrilaterals(a, rect);
annotObj.dictSet ("QuadPoints", Object(a));
invalidateAppearance();
}
-void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
+void AnnotTextMarkup::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
double ca = 1;
int i;
- if (!isVisible (printing))
- return;
-
- annotLocker();
if (appearance.isNull() || type == typeHighlight) {
GBool blendMultiply = gTrue;
ca = opacity;
appearBuf = new GooString ();
appearBuf->append ("q\n");
/* Adjust BBox */
delete appearBBox;
appearBBox = new AnnotAppearanceBBox(rect);
for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
appearBBox->extendTo (quadrilaterals->getX1(i) - rect->x1, quadrilaterals->getY1(i) - rect->y1);
appearBBox->extendTo (quadrilaterals->getX2(i) - rect->x1, quadrilaterals->getY2(i) - rect->y1);
appearBBox->extendTo (quadrilaterals->getX3(i) - rect->x1, quadrilaterals->getY3(i) - rect->y1);
appearBBox->extendTo (quadrilaterals->getX4(i) - rect->x1, quadrilaterals->getY4(i) - rect->y1);
}
switch (type) {
case typeUnderline:
if (color) {
@@ -3683,50 +3713,46 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
bbox[2] = appearBBox->getPageXMax();
bbox[3] = appearBBox->getPageYMax();
aStream = createForm(bbox, gTrue, nullptr);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", 1, blendMultiply ? "Multiply" : nullptr);
if (ca == 1) {
appearance = createForm(bbox, gFalse, resDict);
} else {
aStream = createForm(bbox, gTrue, resDict);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict2 = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict2);
}
delete appearBuf;
}
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
+ obj = appearance.fetch(xref);
if (appearBBox) {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- appearBBox->getPageXMin(), appearBBox->getPageYMin(),
- appearBBox->getPageXMax(), appearBBox->getPageYMax(),
- getRotation());
+ drawRect = PDFRectangle(appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+ appearBBox->getPageXMax(), appearBBox->getPageYMax());
} else {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ drawRect = *rect;
}
}
//------------------------------------------------------------------------
// AnnotWidget
//------------------------------------------------------------------------
AnnotWidget::AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj) :
Annot(docA, dictObject, obj) {
type = typeWidget;
field = nullptr;
initialize(docA, dictObject->getDict());
}
AnnotWidget::AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj, FormField *fieldA) :
Annot(docA, dictObject, obj) {
type = typeWidget;
field = fieldA;
initialize(docA, dictObject->getDict());
}
@@ -4916,80 +4942,84 @@ void AnnotWidget::updateAppearanceStream()
// create a new AP dictionary containing the new appearance stream.
// Otherwise, just update the stream we had created previously.
if (updatedAppearanceStream.num == -1) {
// Write the appearance stream
updatedAppearanceStream = xref->addIndirectObject(&obj1);
// Write the AP dictionary
obj1 = Object(new Dict(xref));
obj1.dictAdd(copyString("N"), Object(updatedAppearanceStream.num, updatedAppearanceStream.gen));
// Update our internal pointers to the appearance dictionary
appearStreams = new AnnotAppearance(doc, &obj1);
update("AP", std::move(obj1));
} else {
// Replace the existing appearance stream
xref->setModifiedObject(&obj1, updatedAppearanceStream);
}
}
-void AnnotWidget::draw(Gfx *gfx, GBool printing) {
- if (!isVisible (printing))
- return;
-
- annotLocker();
+void AnnotWidget::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
addDingbatsResource = gFalse;
// Only construct the appearance stream when
// - annot doesn't have an AP or
// - NeedAppearances is true
if (field) {
if (appearance.isNull() || (form && form->getNeedAppearances()))
generateFieldAppearance();
}
// draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
+ obj = appearance.fetch(xref);
+ drawRect = *rect;
if (addDingbatsResource) {
// We are forcing ZaDb but the font does not exist
// so create a fake one
- Dict *fontDict = new Dict(gfx->getXRef());
+ Dict *fontDict = new Dict(xref);
fontDict->add(copyString("BaseFont"), Object(objName, "ZapfDingbats"));
fontDict->add(copyString("Subtype"), Object(objName, "Type1"));
- Dict *fontsDict = new Dict(gfx->getXRef());
+ Dict *fontsDict = new Dict(xref);
fontsDict->add(copyString("ZaDb"), Object(fontDict));
- Dict *dict = new Dict(gfx->getXRef());
- dict->add(copyString("Font"), Object(fontsDict));
- gfx->pushResources(dict);
- delete dict;
+ fontResourceDict = new Dict(xref);
+ fontResourceDict->add(copyString("Font"), Object(fontsDict));
+ }
+}
+
+void AnnotWidget::drawAppearance(Gfx *gfx, Object& obj, const PDFRectangle& drawRect) {
+ if (fontResourceDict != nullptr) {
+ gfx->pushResources(fontResourceDict);
}
+
gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
- if (addDingbatsResource) {
+ drawRect.x1, drawRect.y1, drawRect.x2, drawRect.y2, getRotation());
+
+ if (fontResourceDict != nullptr) {
gfx->popResources();
+ delete fontResourceDict;
+ fontResourceDict = nullptr;
}
}
-
//------------------------------------------------------------------------
// AnnotMovie
//------------------------------------------------------------------------
AnnotMovie::AnnotMovie(PDFDoc *docA, PDFRectangle *rect, Movie *movieA) :
Annot(docA, rect) {
type = typeMovie;
annotObj.dictSet ("Subtype", Object(objName, "Movie"));
movie = movieA->copy();
// TODO: create movie dict from movieA
initialize(docA, annotObj.getDict());
}
AnnotMovie::AnnotMovie(PDFDoc *docA, Object *dictObject, Object *obj) :
Annot(docA, dictObject, obj) {
type = typeMovie;
initialize(docA, dictObject->getDict());
}
@@ -5011,117 +5041,111 @@ void AnnotMovie::initialize(PDFDoc *docA, Dict* dict) {
Object movieDict = dict->lookup("Movie");
if (movieDict.isDict()) {
Object obj2 = dict->lookup("A");
if (obj2.isDict())
movie = new Movie (&movieDict, &obj2);
else
movie = new Movie (&movieDict);
if (!movie->isOk()) {
delete movie;
movie = nullptr;
ok = gFalse;
}
} else {
error(errSyntaxError, -1, "Bad Annot Movie");
movie = nullptr;
ok = gFalse;
}
}
-void AnnotMovie::draw(Gfx *gfx, GBool printing) {
- if (!isVisible (printing))
- return;
-
- annotLocker();
+void AnnotMovie::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
if (appearance.isNull() && movie->getShowPoster()) {
int width, height;
Object poster = movie->getPoster();
movie->getAspect(&width, &height);
if (width != -1 && height != -1 && !poster.isNone()) {
appearBuf = new GooString ();
appearBuf->append ("q\n");
appearBuf->appendf ("{0:d} 0 0 {1:d} 0 0 cm\n", width, height);
appearBuf->append ("/MImg Do\n");
appearBuf->append ("Q\n");
- Dict *imgDict = new Dict(gfx->getXRef());
+ Dict *imgDict = new Dict(xref);
imgDict->set("MImg", std::move(poster));
- Dict *resDict = new Dict(gfx->getXRef());
+ Dict *resDict = new Dict(xref);
resDict->set("XObject", Object(imgDict));
- Dict *formDict = new Dict(gfx->getXRef());
+ Dict *formDict = new Dict(xref);
formDict->set("Length", Object(appearBuf->getLength()));
formDict->set("Subtype", Object(objName, "Form"));
formDict->set("Name", Object(objName, "FRM"));
- Array *bboxArray = new Array(gfx->getXRef());
+ Array *bboxArray = new Array(xref);
bboxArray->add(Object(0));
bboxArray->add(Object(0));
bboxArray->add(Object(width));
bboxArray->add(Object(height));
formDict->set("BBox", Object(bboxArray));
- Array *matrix = new Array(gfx->getXRef());
+ Array *matrix = new Array(xref);
matrix->add(Object(1));
matrix->add(Object(0));
matrix->add(Object(0));
matrix->add(Object(1));
matrix->add(Object(-width / 2));
matrix->add(Object(-height / 2));
formDict->set("Matrix", Object(matrix));
formDict->set("Resources", Object(resDict));
MemStream *mStream = new MemStream(copyString(appearBuf->getCString()), 0,
appearBuf->getLength(), Object(formDict));
mStream->setNeedFree(gTrue);
delete appearBuf;
- Dict *dict = new Dict(gfx->getXRef());
+ Dict *dict = new Dict(xref);
dict->set("FRM", Object(static_cast<Stream*>(mStream)));
- Dict *resDict2 = new Dict(gfx->getXRef());
+ Dict *resDict2 = new Dict(xref);
resDict2->set("XObject", Object(dict));
appearBuf = new GooString ();
appearBuf->append ("q\n");
appearBuf->appendf ("0 0 {0:d} {1:d} re W n\n", width, height);
appearBuf->append ("q\n");
appearBuf->appendf ("0 0 {0:d} {1:d} re W n\n", width, height);
appearBuf->appendf ("1 0 0 1 {0:d} {1:d} cm\n", width / 2, height / 2);
appearBuf->append ("/FRM Do\n");
appearBuf->append ("Q\n");
appearBuf->append ("Q\n");
double bbox[4];
bbox[0] = bbox[1] = 0;
bbox[2] = width;
bbox[3] = height;
appearance = createForm(bbox, gFalse, resDict2);
delete appearBuf;
}
}
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ obj = appearance.fetch(xref);
+ drawRect = *rect;
}
//------------------------------------------------------------------------
// AnnotScreen
//------------------------------------------------------------------------
AnnotScreen::AnnotScreen(PDFDoc *docA, PDFRectangle *rect) :
Annot(docA, rect) {
type = typeScreen;
annotObj.dictSet ("Subtype", Object(objName, "Screen"));
initialize(docA, annotObj.getDict());
}
AnnotScreen::AnnotScreen(PDFDoc *docA, Object *dictObject, Object *obj) :
Annot(docA, dictObject, obj) {
type = typeScreen;
initialize(docA, dictObject->getDict());
}
AnnotScreen::~AnnotScreen() {
@@ -5300,47 +5324,43 @@ void AnnotGeometry::setType(AnnotSubtype new_type) {
}
type = new_type;
update("Subtype", Object(objName, typeName));
invalidateAppearance();
}
void AnnotGeometry::setInteriorColor(AnnotColor *new_color) {
delete interiorColor;
if (new_color) {
Object obj1 = new_color->writeToObject(xref);
update ("IC", std::move(obj1));
interiorColor = new_color;
} else {
interiorColor = nullptr;
}
invalidateAppearance();
}
-void AnnotGeometry::draw(Gfx *gfx, GBool printing) {
+void AnnotGeometry::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
double ca = 1;
- if (!isVisible (printing))
- return;
-
- annotLocker();
if (appearance.isNull()) {
ca = opacity;
appearBuf = new GooString ();
appearBuf->append ("q\n");
if (color)
setColor(color, gFalse);
double borderWidth = border->getWidth();
setLineStyleForBorder(border);
if (interiorColor)
setColor(interiorColor, gTrue);
if (type == typeSquare) {
appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re\n",
borderWidth / 2.0, borderWidth / 2.0,
(rect->x2 - rect->x1) - borderWidth,
(rect->y2 - rect->y1) - borderWidth);
} else {
@@ -5398,44 +5418,42 @@ void AnnotGeometry::draw(Gfx *gfx, GBool printing) {
appearBuf->append ("Q\n");
double bbox[4];
bbox[0] = bbox[1] = 0;
bbox[2] = rect->x2 - rect->x1;
bbox[3] = rect->y2 - rect->y1;
if (ca == 1) {
appearance = createForm(bbox, gFalse, nullptr);
} else {
Object aStream = createForm(bbox, gTrue, nullptr);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict);
}
delete appearBuf;
}
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ obj = appearance.fetch(xref);
+ drawRect = *rect;
}
//------------------------------------------------------------------------
// AnnotPolygon
//------------------------------------------------------------------------
AnnotPolygon::AnnotPolygon(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType) :
AnnotMarkup(docA, rect) {
switch (subType) {
case typePolygon:
annotObj.dictSet ("Subtype", Object(objName, "Polygon"));
break;
case typePolyLine:
annotObj.dictSet ("Subtype", Object(objName, "PolyLine"));
break;
default:
assert (0 && "Invalid subtype for AnnotGeometry\n");
}
// Store dummy path with one null vertex only
Array *a = new Array(doc->getXRef());
@@ -5596,47 +5614,43 @@ void AnnotPolygon::setInteriorColor(AnnotColor *new_color) {
interiorColor = new_color;
} else {
interiorColor = nullptr;
}
invalidateAppearance();
}
void AnnotPolygon::setIntent(AnnotPolygonIntent new_intent) {
const char *intentName;
intent = new_intent;
if (new_intent == polygonCloud)
intentName = "PolygonCloud";
else if (new_intent == polylineDimension)
intentName = "PolyLineDimension";
else // polygonDimension
intentName = "PolygonDimension";
update ("IT", Object(objName, intentName));
}
-void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
+void AnnotPolygon::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
double ca = 1;
- if (!isVisible (printing))
- return;
-
- annotLocker();
if (appearance.isNull()) {
appearBBox = new AnnotAppearanceBBox(rect);
ca = opacity;
appearBuf = new GooString ();
appearBuf->append ("q\n");
if (color) {
setColor(color, gFalse);
}
setLineStyleForBorder(border);
appearBBox->setBorderWidth(std::max(1., border->getWidth()));
if (interiorColor) {
setColor(interiorColor, gTrue);
}
if (vertices->getCoordsLength() != 0) {
appearBuf->appendf ("{0:.2f} {1:.2f} m\n", vertices->getX(0) - rect->x1, vertices->getY(0) - rect->y1);
@@ -5659,49 +5673,46 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
}
appearBuf->append ("Q\n");
double bbox[4];
appearBBox->getBBoxRect(bbox);
if (ca == 1) {
appearance = createForm(bbox, gFalse, nullptr);
} else {
Object aStream = createForm(bbox, gTrue, nullptr);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict);
}
delete appearBuf;
}
// draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
+ obj = appearance.fetch(xref);
if (appearBBox) {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- appearBBox->getPageXMin(), appearBBox->getPageYMin(),
- appearBBox->getPageXMax(), appearBBox->getPageYMax(),
- getRotation());
+ drawRect = PDFRectangle(appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+ appearBBox->getPageXMax(), appearBBox->getPageYMax());
} else {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ drawRect = *rect;
}
}
//------------------------------------------------------------------------
// AnnotCaret
//------------------------------------------------------------------------
AnnotCaret::AnnotCaret(PDFDoc *docA, PDFRectangle *rect) :
AnnotMarkup(docA, rect) {
type = typeCaret;
annotObj.dictSet ("Subtype", Object(objName, "Caret"));
initialize(docA, annotObj.getDict());
}
AnnotCaret::AnnotCaret(PDFDoc *docA, Object *dictObject, Object *obj) :
AnnotMarkup(docA, dictObject, obj) {
type = typeCaret;
initialize(docA, dictObject->getDict());
}
@@ -5814,47 +5825,43 @@ void AnnotInk::parseInkList(Array *array) {
void AnnotInk::freeInkList() {
if (inkList) {
for (int i = 0; i < inkListLength; ++i)
delete inkList[i];
gfree(inkList);
}
}
void AnnotInk::setInkList(AnnotPath **paths, int n_paths) {
freeInkList();
Array *a = new Array(xref);
writeInkList(paths, n_paths, a);
parseInkList(a);
annotObj.dictSet ("InkList", Object(a));
invalidateAppearance();
}
-void AnnotInk::draw(Gfx *gfx, GBool printing) {
+void AnnotInk::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
double ca = 1;
- if (!isVisible (printing))
- return;
-
- annotLocker();
if (appearance.isNull()) {
appearBBox = new AnnotAppearanceBBox(rect);
ca = opacity;
appearBuf = new GooString ();
appearBuf->append ("q\n");
if (color) {
setColor(color, gFalse);
}
setLineStyleForBorder(border);
appearBBox->setBorderWidth(std::max(1., border->getWidth()));
for (int i = 0; i < inkListLength; ++i) {
const AnnotPath * path = inkList[i];
if (path && path->getCoordsLength() != 0) {
appearBuf->appendf ("{0:.2f} {1:.2f} m\n", path->getX(0) - rect->x1, path->getY(0) - rect->y1);
appearBBox->extendTo (path->getX(0) - rect->x1, path->getY(0) - rect->y1);
@@ -5867,50 +5874,46 @@ void AnnotInk::draw(Gfx *gfx, GBool printing) {
}
}
appearBuf->append ("Q\n");
double bbox[4];
appearBBox->getBBoxRect(bbox);
if (ca == 1) {
appearance = createForm(bbox, gFalse, nullptr);
} else {
Object aStream = createForm(bbox, gTrue, nullptr);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict);
}
delete appearBuf;
}
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
+ obj = appearance.fetch(xref);
if (appearBBox) {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- appearBBox->getPageXMin(), appearBBox->getPageYMin(),
- appearBBox->getPageXMax(), appearBBox->getPageYMax(),
- getRotation());
+ drawRect = PDFRectangle(appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+ appearBBox->getPageXMax(), appearBBox->getPageYMax());
} else {
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ drawRect = *rect;
}
}
//------------------------------------------------------------------------
// AnnotFileAttachment
//------------------------------------------------------------------------
AnnotFileAttachment::AnnotFileAttachment(PDFDoc *docA, PDFRectangle *rect, GooString *filename) :
AnnotMarkup(docA, rect) {
type = typeFileAttachment;
annotObj.dictSet("Subtype", Object(objName, "FileAttachment"));
annotObj.dictSet("FS", Object(filename->copy()));
initialize(docA, annotObj.getDict());
}
AnnotFileAttachment::AnnotFileAttachment(PDFDoc *docA, Object *dictObject, Object *obj) :
AnnotMarkup(docA, dictObject, obj) {
type = typeFileAttachment;
initialize(docA, dictObject->getDict());
@@ -6034,87 +6037,81 @@ void AnnotFileAttachment::initialize(PDFDoc *docA, Dict* dict) {
"0.533333 0.541176 0.521569 RG 1 w\n" \
"0 j\n" \
"11.949 13.184 m 16.191 8.941 l S\n" \
"0.729412 0.741176 0.713725 RG 11.949 14.184 m 16.191 9.941 l S\n" \
"0.533333 0.541176 0.521569 RG 14.07 6.82 m 9.828 11.062 l S\n" \
"0.729412 0.741176 0.713725 RG 14.07 7.82 m 9.828 12.062 l S\n" \
"0.533333 0.541176 0.521569 RG 6.93 15.141 m 8 20 14.27 20.5 16 20.5 c\n" \
"18.094 20.504 19.5 20 19.5 18 c 19.5 16.699 20.91 16.418 22.5 16.5 c S\n" \
"0.729412 0.741176 0.713725 RG 0.999781 w\n" \
"1 j\n" \
"q 1 0 0 -1 0 24 cm\n" \
"8.492 7.707 m 8.492 8.535 7.82 9.207 6.992 9.207 c 6.164 9.207 5.492\n" \
"8.535 5.492 7.707 c 5.492 6.879 6.164 6.207 6.992 6.207 c 7.82 6.207\n" \
"8.492 6.879 8.492 7.707 c h\n" \
"8.492 7.707 m S Q\n" \
"1 w\n" \
"0 j\n" \
"6.93 16.141 m 8 21 14.27 21.5 16 21.5 c 18.094 21.504 19.5 21 19.5 19 c\n" \
"19.5 17.699 20.91 17.418 22.5 17.5 c S\n"
-void AnnotFileAttachment::draw(Gfx *gfx, GBool printing) {
+void AnnotFileAttachment::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
double ca = 1;
- if (!isVisible (printing))
- return;
-
- annotLocker();
if (appearance.isNull()) {
ca = opacity;
appearBuf = new GooString ();
appearBuf->append ("q\n");
if (color)
setColor(color, gTrue);
else
appearBuf->append ("1 1 1 rg\n");
if (!name->cmp("PushPin"))
appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_PUSHPIN);
else if (!name->cmp("Paperclip"))
appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_PAPERCLIP);
else if (!name->cmp("Graph"))
appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_GRAPH);
else if (!name->cmp("Tag"))
appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_TAG);
appearBuf->append ("Q\n");
double bbox[4];
bbox[0] = bbox[1] = 0;
bbox[2] = bbox[3] = 24;
if (ca == 1) {
appearance = createForm (bbox, gFalse, nullptr);
} else {
Object aStream = createForm (bbox, gTrue, nullptr);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict);
}
delete appearBuf;
}
- // draw the appearance stream
- Object obj = appearance.fetch(gfx->getXRef());
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ obj = appearance.fetch(xref);
+ drawRect = *rect;
}
//------------------------------------------------------------------------
// AnnotSound
//------------------------------------------------------------------------
AnnotSound::AnnotSound(PDFDoc *docA, PDFRectangle *rect, Sound *soundA) :
AnnotMarkup(docA, rect) {
type = typeSound;
annotObj.dictSet ("Subtype", Object(objName, "Sound"));
annotObj.dictSet ("Sound", soundA->getObject()->copy());
initialize(docA, annotObj.getDict());
}
AnnotSound::AnnotSound(PDFDoc *docA, Object *dictObject, Object *obj) :
AnnotMarkup(docA, dictObject, obj) {
type = typeSound;
initialize(docA, dictObject->getDict());
}
@@ -6188,84 +6185,77 @@ void AnnotSound::initialize(PDFDoc *docA, Dict* dict) {
"17.5 14.5 m 17.5 11.973 l 17.5 8.941 15.047 6.5 12 6.5 c 8.953 6.5 6.5\n" \
"8.941 6.5 11.973 c 6.5 14.5 l S\n" \
"2 w\n" \
"0 J\n" \
"12 6.52 m 12 3 l S\n" \
"1 J\n" \
"8 3 m 16 3 l S\n" \
"0.729412 0.741176 0.713725 RG 12 21 m 12 21 l 13.656 21 15 19.656 15 18 c\n" \
"15 14 l 15 12.344 13.656 11 12 11 c 12 11 l 10.344 11 9 12.344 9 14 c\n" \
"9 18 l 9 19.656 10.344 21 12 21 c h\n" \
"12 21 m S\n" \
"1 w\n" \
"17.5 15.5 m 17.5 12.973 l 17.5 9.941 15.047 7.5 12 7.5 c 8.953 7.5 6.5\n" \
"9.941 6.5 12.973 c 6.5 15.5 l S\n" \
"2 w\n" \
"0 J\n" \
"12 7.52 m 12 4 l S\n" \
"1 J\n" \
"8 4 m 16 4 l S\n"
-void AnnotSound::draw(Gfx *gfx, GBool printing) {
- Object obj;
+void AnnotSound::makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) {
double ca = 1;
- if (!isVisible (printing))
- return;
-
- annotLocker();
if (appearance.isNull()) {
ca = opacity;
appearBuf = new GooString ();
appearBuf->append ("q\n");
if (color)
setColor(color, gTrue);
else
appearBuf->append ("1 1 1 rg\n");
if (!name->cmp("Speaker"))
appearBuf->append (ANNOT_SOUND_AP_SPEAKER);
else if (!name->cmp("Mic"))
appearBuf->append (ANNOT_SOUND_AP_MIC);
appearBuf->append ("Q\n");
double bbox[4];
bbox[0] = bbox[1] = 0;
bbox[2] = bbox[3] = 24;
if (ca == 1) {
appearance = createForm(bbox, gFalse, nullptr);
} else {
Object aStream = createForm(bbox, gTrue, nullptr);
delete appearBuf;
appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
appearance = createForm(bbox, gFalse, resDict);
}
delete appearBuf;
}
- // draw the appearance stream
- obj = appearance.fetch(gfx->getXRef());
- gfx->drawAnnot(&obj, (AnnotBorder *)nullptr, color,
- rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
+ obj = appearance.fetch(xref);
+ drawRect = *rect;
}
//------------------------------------------------------------------------
// Annot3D
//------------------------------------------------------------------------
Annot3D::Annot3D(PDFDoc *docA, PDFRectangle *rect) :
Annot(docA, rect) {
type = type3D;
annotObj.dictSet ("Subtype", Object(objName, "3D"));
initialize(docA, annotObj.getDict());
}
Annot3D::Annot3D(PDFDoc *docA, Object *dictObject, Object *obj) :
Annot(docA, dictObject, obj) {
type = type3D;
initialize(docA, dictObject->getDict());
}
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 860d95e9..8cce6f75 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -40,40 +40,41 @@
#endif
#include "Object.h"
class XRef;
class Gfx;
class CharCodeToUnicode;
class GfxFont;
class GfxResources;
class Page;
class PDFDoc;
class Form;
class FormWidget;
class FormField;
class FormFieldChoice;
class PDFRectangle;
class Movie;
class LinkAction;
class Sound;
class FileSpec;
+class OutputDev;
enum AnnotLineEndingStyle {
annotLineEndingSquare, // Square
annotLineEndingCircle, // Circle
annotLineEndingDiamond, // Diamond
annotLineEndingOpenArrow, // OpenArrow
annotLineEndingClosedArrow, // ClosedArrow
annotLineEndingNone, // None
annotLineEndingButt, // Butt
annotLineEndingROpenArrow, // ROpenArrow
annotLineEndingRClosedArrow, // RClosedArrow
annotLineEndingSlash // Slash
};
enum AnnotExternalDataType {
annotExternalDataMarkupUnknown,
annotExternalDataMarkup3D // Markup3D
};
//------------------------------------------------------------------------
@@ -560,41 +561,50 @@ public:
actionPageClosing, ///< Performed when the page containing the annotation is closed
actionPageVisible, ///< Performed when the page containing the annotation becomes visible
actionPageInvisible ///< Performed when the page containing the annotation becomes invisible
};
enum FormAdditionalActionsType {
actionFieldModified, ///< Performed when the when the user modifies the field
actionFormatField, ///< Performed before the field is formatted to display its value
actionValidateField, ///< Performed when the field value changes
actionCalculateField, ///< Performed when the field needs to be recalculated
};
Annot(PDFDoc *docA, PDFRectangle *rectA);
Annot(PDFDoc *docA, Object *dictObject);
Annot(PDFDoc *docA, Object *dictObject, Object *obj);
GBool isOk() { return ok; }
void incRefCnt();
void decRefCnt();
- virtual void draw(Gfx *gfx, GBool printing);
+ Gfx* createGfx(OutputDev* splash_output, double hDPI, double vDPI, double width, double height);
+
+ void draw(Gfx *gfx, GBool printing, GBool drawAtOrigin = gFalse);
+
+ void draw(OutputDev *outputDev, GBool printing, double hDPI, double vDPI, GBool drawAtOrigin);
+
+ virtual void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref);
+
+ virtual void drawAppearance(Gfx *gfx, Object& obj, const PDFRectangle& drawRect);
+
// Get the resource dict of the appearance stream
virtual Object getAppearanceResDict();
GBool match(Ref *refA)
{ return ref.num == refA->num && ref.gen == refA->gen; }
double getXMin();
double getYMin();
double getXMax();
double getYMax();
double getFontSize() { return fontSize; }
void setRect(PDFRectangle *rect);
void setRect(double x1, double y1, double x2, double y2);
// Sets the annot contents to new_content
// new_content should never be NULL
virtual void setContents(GooString *new_content);
void setName(GooString *new_name);
@@ -784,74 +794,74 @@ private:
class AnnotText: public AnnotMarkup {
public:
enum AnnotTextState {
stateUnknown,
// Marked state model
stateMarked, // Marked
stateUnmarked, // Unmarked
// Review state model
stateAccepted, // Accepted
stateRejected, // Rejected
stateCancelled, // Cancelled
stateCompleted, // Completed
stateNone // None
};
AnnotText(PDFDoc *docA, PDFRectangle *rect);
AnnotText(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotText();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
// getters
GBool getOpen() const { return open; }
GooString *getIcon() const { return icon; }
AnnotTextState getState() const { return state; }
void setOpen(GBool openA);
void setIcon(GooString *new_icon);
private:
void initialize(PDFDoc *docA, Dict *dict);
GBool open; // Open (Default false)
GooString *icon; // Name (Default Note)
AnnotTextState state; // State (Default Umarked if
// StateModel Marked
// None if StareModel Review)
};
//------------------------------------------------------------------------
// AnnotMovie
//------------------------------------------------------------------------
class AnnotMovie: public Annot {
public:
AnnotMovie(PDFDoc *docA, PDFRectangle *rect, Movie *movieA);
AnnotMovie(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotMovie();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
GooString* getTitle() { return title; }
Movie* getMovie() { return movie; }
private:
void initialize(PDFDoc *docA, Dict *dict);
GooString* title; // T
Movie* movie; // Movie + A
};
//------------------------------------------------------------------------
// AnnotScreen
//------------------------------------------------------------------------
class AnnotScreen: public Annot {
public:
AnnotScreen(PDFDoc *docA, PDFRectangle *rect);
@@ -877,41 +887,41 @@ class AnnotScreen: public Annot {
};
//------------------------------------------------------------------------
// AnnotLink
//------------------------------------------------------------------------
class AnnotLink: public Annot {
public:
enum AnnotLinkEffect {
effectNone, // N
effectInvert, // I
effectOutline, // O
effectPush // P
};
AnnotLink(PDFDoc *docA, PDFRectangle *rect);
AnnotLink(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotLink();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
// getters
LinkAction *getAction() const { return action; }
AnnotLinkEffect getLinkEffect() const { return linkEffect; }
Dict *getUriAction() const { return uriAction; }
AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals; }
protected:
void initialize(PDFDoc *docA, Dict *dict);
LinkAction *action; // A, Dest
AnnotLinkEffect linkEffect; // H (Default I)
Dict *uriAction; // PA
AnnotQuadrilaterals *quadrilaterals; // QuadPoints
};
//------------------------------------------------------------------------
// AnnotFreeText
@@ -919,41 +929,41 @@ protected:
class AnnotFreeText: public AnnotMarkup {
public:
enum AnnotFreeTextQuadding {
quaddingLeftJustified, // 0
quaddingCentered, // 1
quaddingRightJustified // 2
};
enum AnnotFreeTextIntent {
intentFreeText, // FreeText
intentFreeTextCallout, // FreeTextCallout
intentFreeTextTypeWriter // FreeTextTypeWriter
};
AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, GooString *da);
AnnotFreeText(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotFreeText();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
Object getAppearanceResDict() override;
void setContents(GooString *new_content) override;
void setAppearanceString(GooString *new_string);
void setQuadding(AnnotFreeTextQuadding new_quadding);
void setStyleString(GooString *new_string);
void setCalloutLine(AnnotCalloutLine *line);
void setIntent(AnnotFreeTextIntent new_intent);
// getters
GooString *getAppearanceString() const { return appearanceString; }
AnnotFreeTextQuadding getQuadding() const { return quadding; }
// return rc
GooString *getStyleString() const { return styleString; }
AnnotCalloutLine *getCalloutLine() const { return calloutLine; }
AnnotFreeTextIntent getIntent() const { return intent; }
AnnotBorderEffect *getBorderEffect() const { return borderEffect; }
PDFRectangle *getRectangle() const { return rectangle; }
AnnotLineEndingStyle getEndStyle() const { return endStyle; }
@@ -983,41 +993,41 @@ protected:
// AnnotLine
//------------------------------------------------------------------------
class AnnotLine: public AnnotMarkup {
public:
enum AnnotLineIntent {
intentLineArrow, // LineArrow
intentLineDimension // LineDimension
};
enum AnnotLineCaptionPos {
captionPosInline, // Inline
captionPosTop // Top
};
AnnotLine(PDFDoc *docA, PDFRectangle *rect);
AnnotLine(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotLine();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
Object getAppearanceResDict() override;
void setContents(GooString *new_content) override;
void setVertices(double x1, double y1, double x2, double y2);
void setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end);
void setInteriorColor(AnnotColor *new_color);
void setLeaderLineLength(double len);
void setLeaderLineExtension(double len);
void setCaption(bool new_cap);
void setIntent(AnnotLineIntent new_intent);
// getters
AnnotLineEndingStyle getStartStyle() const { return startStyle; }
AnnotLineEndingStyle getEndStyle() const { return endStyle; }
AnnotColor *getInteriorColor() const { return interiorColor; }
double getLeaderLineLength() const { return leaderLineLength; }
double getLeaderLineExtension() const { return leaderLineExtension; }
bool getCaption() const { return caption; }
AnnotLineIntent getIntent() const { return intent; }
double getLeaderLineOffset() const { return leaderLineOffset; }
@@ -1049,41 +1059,41 @@ protected:
bool caption; // Cap (Default false)
AnnotLineIntent intent; // IT
double leaderLineOffset; // LLO
AnnotLineCaptionPos captionPos; // CP (Default Inline)
Dict *measure; // Measure
double captionTextHorizontal; // CO (Default [0, 0])
double captionTextVertical; //
};
//------------------------------------------------------------------------
// AnnotTextMarkup
//------------------------------------------------------------------------
class AnnotTextMarkup: public AnnotMarkup {
public:
AnnotTextMarkup(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType);
AnnotTextMarkup(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotTextMarkup();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
// typeHighlight, typeUnderline, typeSquiggly or typeStrikeOut
void setType(AnnotSubtype new_type);
void setQuadrilaterals(AnnotQuadrilaterals *quadPoints);
AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals; }
protected:
void initialize(PDFDoc *docA, Dict *dict);
AnnotQuadrilaterals *quadrilaterals; // QuadPoints
};
//------------------------------------------------------------------------
// AnnotStamp
//------------------------------------------------------------------------
class AnnotStamp: public AnnotMarkup {
@@ -1099,77 +1109,77 @@ public:
GooString *getIcon() const { return icon; }
private:
void initialize(PDFDoc *docA, Dict *dict);
GooString *icon; // Name (Default Draft)
};
//------------------------------------------------------------------------
// AnnotGeometry
//------------------------------------------------------------------------
class AnnotGeometry: public AnnotMarkup {
public:
AnnotGeometry(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType);
AnnotGeometry(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotGeometry();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
void setType(AnnotSubtype new_type); // typeSquare or typeCircle
void setInteriorColor(AnnotColor *new_color);
// getters
AnnotColor *getInteriorColor() const { return interiorColor; }
AnnotBorderEffect *getBorderEffect() const { return borderEffect; }
PDFRectangle *getGeometryRect() const { return geometryRect; }
private:
void initialize(PDFDoc *docA, Dict *dict);
AnnotColor *interiorColor; // IC
AnnotBorderEffect *borderEffect; // BE
PDFRectangle *geometryRect; // RD (combined with Rect)
};
//------------------------------------------------------------------------
// AnnotPolygon
//------------------------------------------------------------------------
class AnnotPolygon: public AnnotMarkup {
public:
enum AnnotPolygonIntent {
polygonCloud, // PolygonCloud
polylineDimension, // PolyLineDimension
polygonDimension // PolygonDimension
};
AnnotPolygon(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType);
AnnotPolygon(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotPolygon();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
void setType(AnnotSubtype new_type); // typePolygon or typePolyLine
void setVertices(AnnotPath *path);
void setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end);
void setInteriorColor(AnnotColor *new_color);
void setIntent(AnnotPolygonIntent new_intent);
// getters
AnnotPath *getVertices() const { return vertices; }
AnnotLineEndingStyle getStartStyle() const { return startStyle; }
AnnotLineEndingStyle getEndStyle() const { return endStyle; }
AnnotColor *getInteriorColor() const { return interiorColor; }
AnnotBorderEffect *getBorderEffect() const { return borderEffect; }
AnnotPolygonIntent getIntent() const { return intent; }
private:
void initialize(PDFDoc *docA, Dict *dict);
// required
@@ -1210,176 +1220,178 @@ public:
private:
void initialize(PDFDoc *docA, Dict *dict);
AnnotCaretSymbol symbol; // Sy (Default None)
PDFRectangle *caretRect; // RD (combined with Rect)
};
//------------------------------------------------------------------------
// AnnotInk
//------------------------------------------------------------------------
class AnnotInk: public AnnotMarkup {
public:
AnnotInk(PDFDoc *docA, PDFRectangle *rect);
AnnotInk(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotInk();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
void setInkList(AnnotPath **paths, int n_paths);
// getters
AnnotPath **getInkList() const { return inkList; }
int getInkListLength() const { return inkListLength; }
private:
void initialize(PDFDoc *docA, Dict *dict);
void writeInkList(AnnotPath **paths, int n_paths, Array *dest_array);
void parseInkList(Array *src_array);
void freeInkList();
// required
AnnotPath **inkList; // InkList
int inkListLength;
// optional
// inherited from Annot
// AnnotBorderBS border; // BS
};
//------------------------------------------------------------------------
// AnnotFileAttachment
//------------------------------------------------------------------------
class AnnotFileAttachment: public AnnotMarkup {
public:
AnnotFileAttachment(PDFDoc *docA, PDFRectangle *rect, GooString *filename);
AnnotFileAttachment(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotFileAttachment();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
// getters
Object *getFile() { return &file; }
GooString *getName() const { return name; }
private:
void initialize(PDFDoc *docA, Dict *dict);
// required
Object file; // FS
// optional
GooString *name; // Name
};
//------------------------------------------------------------------------
// AnnotSound
//------------------------------------------------------------------------
class AnnotSound: public AnnotMarkup {
public:
AnnotSound(PDFDoc *docA, PDFRectangle *rect, Sound *soundA);
AnnotSound(PDFDoc *docA, Object *dictObject, Object *obj);
~AnnotSound();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
// getters
Sound *getSound() { return sound; }
GooString *getName() const { return name; }
private:
void initialize(PDFDoc *docA, Dict *dict);
// required
Sound *sound; // Sound
// optional
GooString *name; // Name
};
//------------------------------------------------------------------------
// AnnotWidget
//------------------------------------------------------------------------
class AnnotWidget: public Annot {
public:
enum AnnotWidgetHighlightMode {
highlightModeNone, // N
highlightModeInvert, // I
highlightModeOutline, // O
highlightModePush // P,T
};
AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj);
AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj, FormField *fieldA);
~AnnotWidget();
- void draw(Gfx *gfx, GBool printing) override;
+ void makeAppearance(Object& obj, PDFRectangle& drawRect, XRef* xref) override;
+ void drawAppearance(Gfx *gfx, Object& obj, const PDFRectangle& drawRect) override;
void drawBorder();
void drawFormFieldButton(GfxResources *resources, GooString *da);
void drawFormFieldText(GfxResources *resources, GooString *da);
void drawFormFieldChoice(GfxResources *resources, GooString *da);
void generateFieldAppearance ();
void updateAppearanceStream ();
AnnotWidgetHighlightMode getMode() { return mode; }
AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs; }
LinkAction *getAction() { return action; } // The caller should not delete the result
LinkAction *getAdditionalAction(AdditionalActionsType type); // The caller should delete the result
LinkAction *getFormAdditionalAction(FormAdditionalActionsType type); // The caller should delete the result
Dict *getParent() { return parent; }
private:
void initialize(PDFDoc *docA, Dict *dict);
void drawText(GooString *text, GooString *da, GfxResources *resources,
GBool multiline, int comb, int quadding,
GBool txField, GBool forceZapfDingbats,
GBool password=false);
void drawListBox(FormFieldChoice *fieldChoice,
GooString *da, GfxResources *resources, int quadding);
Form *form;
FormField *field; // FormField object for this annotation
AnnotWidgetHighlightMode mode; // H (Default I)
AnnotAppearanceCharacs *appearCharacs; // MK
LinkAction *action; // A
Object additionalActions; // AA
// inherited from Annot
// AnnotBorderBS border; // BS
Dict *parent; // Parent
GBool addDingbatsResource;
Ref updatedAppearanceStream; // {-1,-1} if updateAppearanceStream has never been called
+ Dict *fontResourceDict; // a fake resource, required if drawText is called with forceZapfDingbats = true
};
//------------------------------------------------------------------------
// Annot3D
//------------------------------------------------------------------------
class Annot3D: public Annot {
class Activation {
public:
enum ActivationATrigger {
aTriggerUnknown,
aTriggerPageOpened, // PO
aTriggerPageVisible, // PV
aTriggerUserAction // XA
};
enum ActivationAState {
aStateUnknown,
aStateEnabled, // I
aStateDisabled // L
diff --git a/poppler/Page.cc b/poppler/Page.cc
index d4799dd1..cbd6d2f7 100644
--- a/poppler/Page.cc
+++ b/poppler/Page.cc
@@ -76,40 +76,47 @@ void PDFRectangle::clipTo(PDFRectangle *rect) {
} else if (x1 > rect->x2) {
x1 = rect->x2;
}
if (x2 < rect->x1) {
x2 = rect->x1;
} else if (x2 > rect->x2) {
x2 = rect->x2;
}
if (y1 < rect->y1) {
y1 = rect->y1;
} else if (y1 > rect->y2) {
y1 = rect->y2;
}
if (y2 < rect->y1) {
y2 = rect->y1;
} else if (y2 > rect->y2) {
y2 = rect->y2;
}
}
+void PDFRectangle::translate(double dx, double dy) {
+ x1 += dx;
+ y1 += dy;
+ y2 += dy;
+ x2 += dx;
+}
+
//------------------------------------------------------------------------
// PageAttrs
//------------------------------------------------------------------------
PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
Object obj1;
PDFRectangle mBox;
const GBool isPage = dict->is("Page");
// get old/default values
if (attrs) {
mediaBox = attrs->mediaBox;
cropBox = attrs->cropBox;
haveCropBox = attrs->haveCropBox;
rotate = attrs->rotate;
resources = attrs->resources.copy();
} else {
// set default MediaBox to 8.5" x 11" -- this shouldn't be necessary
// but some (non-compliant) PDF files don't specify a MediaBox
mediaBox.x1 = 0;
diff --git a/poppler/Page.h b/poppler/Page.h
index 61570791..47ac5bf4 100644
--- a/poppler/Page.h
+++ b/poppler/Page.h
@@ -47,40 +47,41 @@ class OutputDev;
class Links;
class LinkAction;
class Annots;
class Annot;
class Gfx;
class FormPageWidgets;
class Form;
//------------------------------------------------------------------------
class PDFRectangle {
public:
double x1, y1, x2, y2;
PDFRectangle() { x1 = y1 = x2 = y2 = 0; }
PDFRectangle(double x1A, double y1A, double x2A, double y2A)
{ x1 = x1A; y1 = y1A; x2 = x2A; y2 = y2A; }
GBool isValid() { return x1 != 0 || y1 != 0 || x2 != 0 || y2 != 0; }
GBool contains(double x, double y) { return x1 <= x && x <= x2 && y1 <= y && y <= y2; }
void clipTo(PDFRectangle *rect);
+ void translate(double dx, double dy);
bool operator==(const PDFRectangle &rect) const { return x1 == rect.x1 && y1 == rect.y1 && x2 == rect.x2 && y2 == rect.y2; }
};
//------------------------------------------------------------------------
// PageAttrs
//------------------------------------------------------------------------
class PageAttrs {
public:
// Construct a new PageAttrs object by merging a dictionary
// (of type Pages or Page) into another PageAttrs object. If
// <attrs> is NULL, uses defaults.
PageAttrs(PageAttrs *attrs, Dict *dict);
// Destructor.
~PageAttrs();
// Accessors.
diff --git a/qt5/src/ArthurOutputDev.cc b/qt5/src/ArthurOutputDev.cc
index 34fde569..2cd69b7d 100644
--- a/qt5/src/ArthurOutputDev.cc
+++ b/qt5/src/ArthurOutputDev.cc
@@ -39,40 +39,41 @@
#include <string.h>
#include <math.h>
#include "goo/gfile.h"
#include "GlobalParams.h"
#include "Error.h"
#include "Object.h"
#include "GfxState.h"
#include "GfxFont.h"
#include "Link.h"
#include "FontEncodingTables.h"
#include <fofi/FoFiTrueType.h>
#include "ArthurOutputDev.h"
#include <QtCore/QtDebug>
#include <QRawFont>
#include <QGlyphRun>
#include <QtGui/QPainterPath>
#include <QPicture>
+#include <QImage>
//------------------------------------------------------------------------
#ifdef HAVE_SPLASH
#include "splash/SplashFontFileID.h"
#include "splash/SplashFTFontFile.h"
#include "splash/SplashFontEngine.h"
//------------------------------------------------------------------------
// SplashOutFontFileID
//------------------------------------------------------------------------
class SplashOutFontFileID: public SplashFontFileID {
public:
SplashOutFontFileID(Ref *rA) { r = *rA; }
~SplashOutFontFileID() {}
GBool matches(SplashFontFileID *id) override {
return ((SplashOutFontFileID *)id)->r.num == r.num &&
@@ -1018,20 +1019,76 @@ void ArthurOutputDev::endTransparencyGroup(GfxState * /*state*/)
// 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;
}
+ScopedPageQPainter::ScopedPageQPainter(QImage& image, int docHints, const QColor& docPaperColor, int pageFlags, int x, int y)
+: m_painter(new QPainter(&image)), m_deletePainter(true) {
+ image.fill(docPaperColor);
+ setup(docHints, pageFlags, x, y);
+}
+
+ScopedPageQPainter::ScopedPageQPainter(QPainter* painter, int docHints, int pageFlags, int x, int y)
+: m_painter(painter), m_deletePainter(false) {
+ setup(docHints, pageFlags, x, y);
+}
+
+ScopedPageQPainter::operator QPainter*() {
+ return m_painter;
+}
+
+void ScopedPageQPainter::setup(int docHints, int pageFlags, int x, int y) {
+ m_savePainter = !(pageFlags & Poppler::Page:: DontSaveAndRestore);
+ if (m_savePainter)
+ m_painter->save();
+ if (docHints & Poppler::Document::Antialiasing)
+ m_painter->setRenderHint(QPainter::Antialiasing);
+ if (docHints & Poppler::Document::TextAntialiasing)
+ m_painter->setRenderHint(QPainter::TextAntialiasing);
+ m_painter->translate(x == -1 ? 0 : -x, y == -1 ? 0 : -y);
+}
+
+ScopedPageQPainter::~ScopedPageQPainter() {
+ if (m_savePainter)
+ m_painter->restore();
+ m_painter->end();
+ if (m_deletePainter)
+ delete m_painter;
+}
+
+QImageDumpingArthurOutputDev::QImageDumpingArthurOutputDev(QPainter *painter, QImage *i)
+ : ArthurOutputDev(painter)
+ , partialUpdateCallback(nullptr)
+ , shouldDoPartialUpdateCallback(nullptr)
+ , image(i)
+{
+}
+
+void QImageDumpingArthurOutputDev::setPartialUpdateCallbackData(Poppler::Page::RenderToImagePartialUpdateFunc callback,
+ Poppler::Page::ShouldRenderToImagePartialQueryFunc shouldDoCallback, const QVariant &payloadA)
+{
+ partialUpdateCallback = callback;
+ shouldDoPartialUpdateCallback = shouldDoCallback;
+ payload = payloadA;
+}
+
+void QImageDumpingArthurOutputDev::dump()
+{
+ if (partialUpdateCallback && shouldDoPartialUpdateCallback && shouldDoPartialUpdateCallback(payload)) {
+ partialUpdateCallback(*image, payload);
+ }
+}
diff --git a/qt5/src/ArthurOutputDev.h b/qt5/src/ArthurOutputDev.h
index b4ab3d7e..0d954449 100644
--- a/qt5/src/ArthurOutputDev.h
+++ b/qt5/src/ArthurOutputDev.h
@@ -24,40 +24,42 @@
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================
#ifndef ARTHUROUTPUTDEV_H
#define ARTHUROUTPUTDEV_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <memory>
#include <map>
#include <stack>
#include "goo/gtypes.h"
#include "OutputDev.h"
#include "GfxState.h"
+#include "poppler-qt5.h"
+#include "OutputDevCallbackHelper.h"
#include <QtGui/QPainter>
class GfxState;
class SplashFontEngine;
class QRawFont;
//------------------------------------------------------------------------
// ArthurOutputDev - Qt 5 QPainter renderer
//------------------------------------------------------------------------
class ArthurOutputDev: public OutputDev {
public:
/**
* Describes how fonts are distorted (aka hinted) to fit the pixel grid.
* More hinting means sharper edges and less adherence to the true letter shapes.
*/
enum FontHinting {
@@ -214,21 +216,48 @@ private:
struct ArthurFontID
{
Ref ref;
double fontSize;
bool operator<(const ArthurFontID& other) const
{
return (ref.num < other.ref.num)
|| ((ref.num == other.ref.num) && (fontSize < other.fontSize));
}
};
// Cache all fonts
std::map<ArthurFontID,std::unique_ptr<QRawFont> > m_rawFontCache;
// The table that maps character codes to glyph indexes
int* m_codeToGID;
std::stack<int*> m_codeToGIDStack;
};
+class ScopedPageQPainter {
+public:
+ ScopedPageQPainter(QImage& image, int docHints, const QColor& docPaperColor, int pageFlags, int x, int y);
+ ScopedPageQPainter(QPainter* painter, int docHints, int pageFlags, int x, int y);
+ operator QPainter*();
+ ~ScopedPageQPainter();
+private:
+ void setup(int docHints, int pageFlags, int x, int y);
+ QPainter* m_painter;
+ bool m_savePainter;
+ bool m_deletePainter;
+};
+
+class QImageDumpingArthurOutputDev : public ArthurOutputDev, public OutputDevCallbackHelper
+{
+public:
+ QImageDumpingArthurOutputDev(QPainter *painter, QImage *i);
+ void setPartialUpdateCallbackData(Poppler::Page::RenderToImagePartialUpdateFunc callback, Poppler::Page::ShouldRenderToImagePartialQueryFunc shouldDoCallback, const QVariant &payloadA);
+ void dump() override;
+
+private:
+ Poppler::Page::RenderToImagePartialUpdateFunc partialUpdateCallback;
+ Poppler::Page::ShouldRenderToImagePartialQueryFunc shouldDoPartialUpdateCallback;
+ QVariant payload;
+ QImage *image;
+};
+
#endif
diff --git a/qt5/src/CMakeLists.txt b/qt5/src/CMakeLists.txt
index 63757c6b..fa656b5a 100644
--- a/qt5/src/CMakeLists.txt
+++ b/qt5/src/CMakeLists.txt
@@ -10,41 +10,43 @@ include_directories(
set(poppler_qt5_SRCS
poppler-annotation.cc
poppler-document.cc
poppler-embeddedfile.cc
poppler-fontinfo.cc
poppler-form.cc
poppler-link.cc
poppler-link-extractor.cc
poppler-movie.cc
poppler-optcontent.cc
poppler-page.cc
poppler-base-converter.cc
poppler-pdf-converter.cc
poppler-private.cc
poppler-ps-converter.cc
poppler-qiodeviceoutstream.cc
poppler-sound.cc
poppler-textbox.cc
poppler-page-transition.cc
poppler-media.cc
+ OutputDevCallbackHelper.cpp
ArthurOutputDev.cc
+ Qt5OutputDev.cc
)
add_library(poppler-qt5 ${poppler_qt5_SRCS})
set_target_properties(poppler-qt5 PROPERTIES VERSION 1.12.0 SOVERSION 1)
if(MINGW)
get_target_property(POPPLER_QT5_SOVERSION poppler-qt5 SOVERSION)
set_target_properties(poppler-qt5 PROPERTIES SUFFIX "-${POPPLER_QT5_SOVERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}")
endif()
target_link_libraries(poppler-qt5 poppler ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Xml_LIBRARIES})
if(MSVC)
target_link_libraries(poppler-qt5 poppler ${poppler_LIBS})
endif()
install(TARGETS poppler-qt5 RUNTIME DESTINATION bin LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES
poppler-qt5.h
poppler-link.h
poppler-annotation.h
poppler-form.h
poppler-optcontent.h
poppler-export.h
diff --git a/qt5/src/OutputDevCallbackHelper.cpp b/qt5/src/OutputDevCallbackHelper.cpp
new file mode 100644
index 00000000..0af70fbf
--- /dev/null
+++ b/qt5/src/OutputDevCallbackHelper.cpp
@@ -0,0 +1,10 @@
+#include "OutputDevCallbackHelper.h"
+
+void OutputDevCallbackHelper::setCallbacks(Poppler::Page::RenderToImagePartialUpdateFunc callback, Poppler::Page::ShouldRenderToImagePartialQueryFunc shouldDoCallback,
+ Poppler::Page::ShouldAbortQueryFunc shouldAbortCallback, const QVariant &payloadA)
+{
+ partialUpdateCallback = callback;
+ shouldDoPartialUpdateCallback = shouldDoCallback;
+ shouldAbortRenderCallback = shouldAbortCallback;
+ payload = payloadA;
+}
diff --git a/qt5/src/OutputDevCallbackHelper.h b/qt5/src/OutputDevCallbackHelper.h
new file mode 100644
index 00000000..3ec27f3e
--- /dev/null
+++ b/qt5/src/OutputDevCallbackHelper.h
@@ -0,0 +1,18 @@
+#ifndef __QT5_OUTCALLBACKHELPER__
+#define __QT5_OUTCALLBACKHELPER__
+
+#include "poppler-qt5.h"
+
+class OutputDevCallbackHelper
+{
+public:
+ void setCallbacks(Poppler::Page::RenderToImagePartialUpdateFunc callback, Poppler::Page::ShouldRenderToImagePartialQueryFunc shouldDoCallback,
+ Poppler::Page::ShouldAbortQueryFunc shouldAbortCallback, const QVariant &payloadA);
+
+ Poppler::Page::RenderToImagePartialUpdateFunc partialUpdateCallback = nullptr;
+ Poppler::Page::ShouldRenderToImagePartialQueryFunc shouldDoPartialUpdateCallback = nullptr;
+ Poppler::Page::ShouldAbortQueryFunc shouldAbortRenderCallback = nullptr;
+ QVariant payload;
+};
+
+#endif
diff --git a/qt5/src/Qt5OutputDev.cc b/qt5/src/Qt5OutputDev.cc
new file mode 100644
index 00000000..8bf54f2f
--- /dev/null
+++ b/qt5/src/Qt5OutputDev.cc
@@ -0,0 +1,137 @@
+#include "Qt5OutputDev.h"
+#include <QImage>
+#include <SplashOutputDev.h>
+#include <splash/SplashBitmap.h>
+#include <ArthurOutputDev.h>
+#include "poppler-qt5.h"
+#include "poppler-private.h"
+
+Qt5SplashSettings::Qt5SplashSettings(const int docHints, QColor docPaperColor)
+: bitmapRowPad(4),
+ reverseVideo(gFalse),
+ ignorePaperColorA(docHints & Poppler::Document::IgnorePaperColor),
+ bitmapTopDown(gTrue),
+ overprintPreview(gFalse) {
+#ifdef SPLASH_CMYK
+ overprintPreview = docHints & Document::OverprintPreview ? gTrue : gFalse;
+ if (overprintPreview)
+ {
+ Guchar c, m, y, k;
+
+ c = 255 - docPaperColor.blue();
+ m = 255 - docPaperColor.red();
+ y = 255 - docPaperColor.green();
+ k = c;
+ if (m < k) {
+ k = m;
+ }
+ if (y < k) {
+ k = y;
+ }
+ bgColor[0] = c - k;
+ bgColor[1] = m - k;
+ bgColor[2] = y - k;
+ bgColor[3] = k;
+ for (int i = 4; i < SPOT_NCOMPS + 4; i++) {
+ bgColor[i] = 0;
+ }
+ }
+ else
+#endif
+ {
+ bgColor[0] = docPaperColor.blue();
+ bgColor[1] = docPaperColor.green();
+ bgColor[2] = docPaperColor.red();
+ }
+
+ colorMode = splashModeXBGR8;
+#ifdef SPLASH_CMYK
+ if (overprintPreview) colorMode = splashModeDeviceN8;
+#endif
+
+ thinLineMode = splashThinLineDefault;
+ if (docHints & Poppler::Document::ThinLineShape)
+ thinLineMode = splashThinLineShape;
+ if (docHints & Poppler::Document::ThinLineSolid)
+ thinLineMode = splashThinLineSolid;
+
+ paperColor = ignorePaperColorA ? nullptr : bgColor;
+
+ textAntialiasing = docHints & Poppler::Document::TextAntialiasing ? gTrue : gFalse;
+ vectorAntialias = docHints & Poppler::Document::Antialiasing ? gTrue : gFalse;
+ freeTypeHintingEnable = docHints & Poppler::Document::TextHinting ? gTrue : gFalse;
+ freeTypeHintingEnableSlightHintingA = docHints & Poppler::Document::TextSlightHinting ? gTrue : gFalse;
+}
+
+Qt5SplashOutputDev::Qt5SplashOutputDev(const Qt5SplashSettings& settings)
+ : SplashOutputDev(settings.colorMode, settings.bitmapRowPad, settings.reverseVideo, settings.paperColor, settings.bitmapTopDown, settings.thinLineMode, settings.overprintPreview)
+ , partialUpdateCallback(nullptr)
+ , shouldDoPartialUpdateCallback(nullptr)
+ , ignorePaperColor(settings.ignorePaperColorA)
+{
+ setFontAntialias(settings.textAntialiasing);
+ setVectorAntialias(settings.vectorAntialias);
+ setFreeTypeHinting(settings.freeTypeHintingEnable, settings.freeTypeHintingEnableSlightHintingA);
+}
+
+Qt5SplashOutputDev::Qt5SplashOutputDev(SplashColorMode colorMode, int bitmapRowPad,
+ GBool reverseVideo, bool ignorePaperColorA, SplashColorPtr paperColor,
+ GBool bitmapTopDown, SplashThinLineMode thinLineMode,
+ GBool overprintPreview)
+ : SplashOutputDev(colorMode, bitmapRowPad, reverseVideo, paperColor, bitmapTopDown, thinLineMode, overprintPreview)
+ , partialUpdateCallback(nullptr)
+ , shouldDoPartialUpdateCallback(nullptr)
+ , ignorePaperColor(ignorePaperColorA)
+{
+}
+
+void Qt5SplashOutputDev::dump()
+{
+ if (partialUpdateCallback && shouldDoPartialUpdateCallback && shouldDoPartialUpdateCallback(payload)) {
+ partialUpdateCallback(getXBGRImage( false /* takeImageData */), payload);
+ }
+}
+
+QImage Qt5SplashOutputDev::getXBGRImage(bool takeImageData)
+{
+ SplashBitmap *b = getBitmap();
+
+ const int bw = b->getWidth();
+ const int bh = b->getHeight();
+ const int brs = b->getRowSize();
+
+ // If we use DeviceN8, convert to XBGR8.
+ // If requested, also transfer Splash's internal alpha channel.
+ const SplashBitmap::ConversionMode mode = ignorePaperColor
+ ? SplashBitmap::conversionAlphaPremultiplied
+ : SplashBitmap::conversionOpaque;
+
+ const QImage::Format format = ignorePaperColor
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32;
+
+ if (b->convertToXBGR(mode)) {
+ SplashColorPtr data = takeImageData ? b->takeData() : b->getDataPtr();
+
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ // Convert byte order from RGBX to XBGR.
+ for (int i = 0; i < bh; ++i) {
+ for (int j = 0; j < bw; ++j) {
+ SplashColorPtr pixel = &data[i * brs + j];
+
+ qSwap(pixel[0], pixel[3]);
+ qSwap(pixel[1], pixel[2]);
+ }
+ }
+ }
+
+ if (takeImageData) {
+ // Construct a Qt image holding (and also owning) the raw bitmap data.
+ return QImage(data, bw, bh, brs, format, gfree, data);
+ } else {
+ return QImage(data, bw, bh, brs, format).copy();
+ }
+ }
+
+ return QImage();
+}
diff --git a/qt5/src/Qt5OutputDev.h b/qt5/src/Qt5OutputDev.h
new file mode 100644
index 00000000..7c73b413
--- /dev/null
+++ b/qt5/src/Qt5OutputDev.h
@@ -0,0 +1,51 @@
+#ifndef __QT5_OUTPUTDEV__
+#define __QT5_OUTPUTDEV__
+
+#include <QImage>
+#include <SplashOutputDev.h>
+#include <splash/SplashBitmap.h>
+#include <ArthurOutputDev.h>
+#include "poppler-qt5.h"
+#include "OutputDevCallbackHelper.h"
+
+class Qt5SplashOutputDev;
+
+struct Qt5SplashSettings {
+ Qt5SplashSettings(const int docHints, QColor docPaperColor);
+
+ SplashColorMode colorMode;
+ int bitmapRowPad;
+ GBool reverseVideo;
+ const bool ignorePaperColorA;
+ SplashColorPtr paperColor;
+ GBool bitmapTopDown;
+ SplashThinLineMode thinLineMode;
+ GBool overprintPreview;
+ SplashColor bgColor;
+ GBool textAntialiasing;
+ GBool vectorAntialias;
+ GBool freeTypeHintingEnable;
+ GBool freeTypeHintingEnableSlightHintingA;
+};
+
+class Qt5SplashOutputDev : public SplashOutputDev, public OutputDevCallbackHelper
+{
+public:
+ Qt5SplashOutputDev(const Qt5SplashSettings& settings);
+ Qt5SplashOutputDev(SplashColorMode colorMode, int bitmapRowPad,
+ GBool reverseVideo, bool ignorePaperColorA, SplashColorPtr paperColor,
+ GBool bitmapTopDown, SplashThinLineMode thinLineMode,
+ GBool overprintPreview);
+
+ void setPartialUpdateCallbackData(Poppler::Page::RenderToImagePartialUpdateFunc callback, Poppler::Page::ShouldRenderToImagePartialQueryFunc shouldDoCallback, const QVariant &payloadA);
+ void dump() override;
+ QImage getXBGRImage(bool takeImageData);
+
+private:
+ Poppler::Page::RenderToImagePartialUpdateFunc partialUpdateCallback;
+ Poppler::Page::ShouldRenderToImagePartialQueryFunc shouldDoPartialUpdateCallback;
+ QVariant payload;
+ bool ignorePaperColor;
+};
+
+#endif
diff --git a/qt5/src/poppler-annotation.cc b/qt5/src/poppler-annotation.cc
index 42f2e9fe..0f86bb7f 100644
--- a/qt5/src/poppler-annotation.cc
+++ b/qt5/src/poppler-annotation.cc
@@ -21,49 +21,49 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
// qt/kde includes
#include <QtCore/QRegExp>
#include <QtCore/QtAlgorithms>
#include <QtXml/QDomElement>
#include <QtGui/QColor>
#include <QtGui/QTransform>
// local includes
#include "poppler-annotation.h"
#include "poppler-link.h"
#include "poppler-qt5.h"
#include "poppler-annotation-helper.h"
#include "poppler-annotation-private.h"
#include "poppler-page-private.h"
#include "poppler-private.h"
-
-// poppler includes
+#include "Qt5OutputDev.h"
#include <Page.h>
#include <Annot.h>
#include <Gfx.h>
#include <Error.h>
#include <FileSpec.h>
#include <Link.h>
+
/* Almost all getters directly query the underlying poppler annotation, with
* the exceptions of link, file attachment, sound, movie and screen annotations,
* Whose data retrieval logic has not been moved yet. Their getters return
* static data set at creation time by findAnnotations
*/
namespace Poppler {
//BEGIN AnnotationUtils implementation
Annotation * AnnotationUtils::createAnnotation( const QDomElement & annElement )
{
// safety check on annotation element
if ( !annElement.hasAttribute( QStringLiteral("type") ) )
return nullptr;
// build annotation of given type
Annotation * annotation = nullptr;
int typeNumber = annElement.attribute( QStringLiteral("type") ).toInt();
switch ( typeNumber )
{
@@ -1562,40 +1562,80 @@ QRectF Annotation::boundary() const
return d->boundary;
const PDFRectangle * rect = d->pdfAnnot->getRect();
return d->fromPdfRectangle( *rect );
}
void Annotation::setBoundary( const QRectF &boundary )
{
Q_D( Annotation );
if (!d->pdfAnnot)
{
d->boundary = boundary;
return;
}
PDFRectangle rect = d->boundaryToPdfRectangle( boundary, flags() );
d->pdfAnnot->setRect(&rect);
}
+//QImage Annotation::renderToPainter(QPainter* painter, double xres, double yres, int x, int y, int w, int h, Rotation rotate, PainterFlags flags) const {
+//
+//}
+
+QImage Annotation::renderToImage(double hDPI, double vDPI) const
+{
+ Q_D( const Annotation );
+ QImage img;
+ switch(d->parentDoc->m_backend)
+ {
+ case Poppler::Document::SplashBackend:
+ {
+#if defined(HAVE_SPLASH)
+ int hints = d->parentDoc->m_hints | Poppler::Document::IgnorePaperColor;
+ Qt5SplashSettings splashSettings(hints, d->parentDoc->paperColor);
+ Qt5SplashOutputDev splash_output(splashSettings);
+ splash_output.startDoc( d->parentDoc->doc);
+ splash_output.dump();
+ d->pdfAnnot->draw(&splash_output, gFalse, hDPI, vDPI, gTrue);
+ splash_output.dump();
+ img = splash_output.getXBGRImage(true); // must happen after delete gfx
+#endif
+ break;
+ }
+ case Poppler::Document::ArthurBackend:
+ {
+ /* Warning: pdfAnnot->getRect() may not be the real size. Annot::draw choses to ignore that sometimes.*/
+ int x = qRound((d->pdfAnnot->getRect()->x2 - d->pdfAnnot->getRect()->x1) * hDPI / 72.0);
+ int y = qRound((d->pdfAnnot->getRect()->y2 - d->pdfAnnot->getRect()->y1) * vDPI / 72.0);
+ QImage tmpimg(x, y, QImage::Format_ARGB32);
+ ScopedPageQPainter painter(tmpimg, d->parentDoc->m_hints, d->parentDoc->paperColor, Page::DontSaveAndRestore, -1, -1);
+ QImageDumpingArthurOutputDev arthur_output(painter, &tmpimg);
+ arthur_output.startDoc(d->parentDoc->doc->getXRef());
+ d->pdfAnnot->draw(&arthur_output, gFalse, hDPI, vDPI, gTrue);
+ img = tmpimg;
+ }
+ }
+ return img;
+}
+
Annotation::Style Annotation::style() const
{
Q_D( const Annotation );
if (!d->pdfAnnot)
return d->style;
Style s;
s.setColor(convertAnnotColor( d->pdfAnnot->getColor() ));
const AnnotMarkup *markupann = dynamic_cast<const AnnotMarkup*>(d->pdfAnnot);
if (markupann)
s.setOpacity( markupann->getOpacity() );
const AnnotBorder *border = d->pdfAnnot->getBorder();
if (border)
{
if ( border->getType() == AnnotBorder::typeArray )
{
const AnnotBorderArray *border_array = static_cast<const AnnotBorderArray*>(border);
diff --git a/qt5/src/poppler-annotation.h b/qt5/src/poppler-annotation.h
index a70cbe4f..5c578f6e 100644
--- a/qt5/src/poppler-annotation.h
+++ b/qt5/src/poppler-annotation.h
@@ -271,40 +271,49 @@ class POPPLER_QT5_EXPORT Annotation
void setFlags( int flags );
/**
* Returns this annotation's boundary rectangle in normalized coordinates
*
* \sa setBoundary(const QRectF&)
*/
QRectF boundary() const;
/**
* Sets this annotation's boundary rectangle
*
* The boundary rectangle is the smallest rectangle that contains the
* annotation.
*
* \warning This property is mandatory: you must always set this.
*
* \sa boundary(), \ref annotFixedRotation
*/
void setBoundary( const QRectF &boundary );
+ /**
+ * Renders the annotations normal appearance, closed state, into a QImage.
+ * It renders the single object onto transparent background.
+ * Resulting QImage is in Format_ARGB32_Premultiplied format.
+ *
+ * \since 0.63
+ */
+ QImage renderToImage(double hDPI, double vDPI) const;
+
/**
* \short Container class for Annotation style information
*
* \since 0.20
*/
class POPPLER_QT5_EXPORT Style
{
public:
Style();
Style( const Style &other );
Style& operator=( const Style &other );
~Style();
// appearance properties
QColor color() const; // black
void setColor(const QColor &color);
double opacity() const; // 1.0
void setOpacity(double opacity);
// pen properties
diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index 381a608b..0fd28e8d 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -50,163 +50,57 @@
#include <Form.h>
#include <ErrorCodes.h>
#include <TextOutputDev.h>
#include <Annot.h>
#include <Link.h>
#include <ArthurOutputDev.h>
#include <Rendition.h>
#if defined(HAVE_SPLASH)
#include <SplashOutputDev.h>
#include <splash/SplashBitmap.h>
#endif
#include "poppler-private.h"
#include "poppler-page-transition-private.h"
#include "poppler-page-private.h"
#include "poppler-link-extractor-private.h"
#include "poppler-link-private.h"
#include "poppler-annotation-private.h"
#include "poppler-form.h"
#include "poppler-media.h"
+#include "Qt5OutputDev.h"
namespace Poppler {
class TextExtractionAbortHelper
{
public:
TextExtractionAbortHelper(Page::ShouldAbortQueryFunc shouldAbortCallback, const QVariant &payloadA)
{
shouldAbortExtractionCallback = shouldAbortCallback;
payload = payloadA;
}
Page::ShouldAbortQueryFunc shouldAbortExtractionCallback = nullptr;
QVariant payload;
};
-class OutputDevCallbackHelper
-{
-public:
- void setCallbacks(Page::RenderToImagePartialUpdateFunc callback, Page::ShouldRenderToImagePartialQueryFunc shouldDoCallback, Page::ShouldAbortQueryFunc shouldAbortCallback, const QVariant &payloadA)
- {
- partialUpdateCallback = callback;
- shouldDoPartialUpdateCallback = shouldDoCallback;
- shouldAbortRenderCallback = shouldAbortCallback;
- payload = payloadA;
- }
-
- Page::RenderToImagePartialUpdateFunc partialUpdateCallback = nullptr;
- Page::ShouldRenderToImagePartialQueryFunc shouldDoPartialUpdateCallback = nullptr;
- Page::ShouldAbortQueryFunc shouldAbortRenderCallback = nullptr;
- QVariant payload;
-};
-
-class Qt5SplashOutputDev : public SplashOutputDev, public OutputDevCallbackHelper
-{
-public:
- Qt5SplashOutputDev(SplashColorMode colorModeA, int bitmapRowPadA,
- GBool reverseVideoA, bool ignorePaperColorA, SplashColorPtr paperColorA,
- GBool bitmapTopDownA, SplashThinLineMode thinLineMode,
- GBool overprintPreviewA)
- : SplashOutputDev(colorModeA, bitmapRowPadA, reverseVideoA, paperColorA, bitmapTopDownA, thinLineMode, overprintPreviewA)
- , ignorePaperColor(ignorePaperColorA)
- {
- }
-
- void dump() override
- {
- if (partialUpdateCallback && shouldDoPartialUpdateCallback && shouldDoPartialUpdateCallback(payload)) {
- partialUpdateCallback(getXBGRImage( false /* takeImageData */), payload);
- }
- }
-
- QImage getXBGRImage(bool takeImageData)
- {
- SplashBitmap *b = getBitmap();
-
- const int bw = b->getWidth();
- const int bh = b->getHeight();
- const int brs = b->getRowSize();
-
- // If we use DeviceN8, convert to XBGR8.
- // If requested, also transfer Splash's internal alpha channel.
- const SplashBitmap::ConversionMode mode = ignorePaperColor
- ? SplashBitmap::conversionAlphaPremultiplied
- : SplashBitmap::conversionOpaque;
-
- const QImage::Format format = ignorePaperColor
- ? QImage::Format_ARGB32_Premultiplied
- : QImage::Format_RGB32;
-
- if (b->convertToXBGR(mode)) {
- SplashColorPtr data = takeImageData ? b->takeData() : b->getDataPtr();
-
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {