--- Begin Message ---
Source: inkscape
Version: 1.4.3-1
Severity: normal
Tags: ftbfs
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Dear Maintainer,
poppler 26.07 is currently in experimental. Once it migrates to unstable,
inkscape 1.4.3-1 will fail to build from source as the PDF import extension
(src/extension/internal/pdfinput/) does not compile against it
poppler 26.02-26.07 reshaped much of the internal C++ API it uses.
GfxColor*/PDFRectangle* parameters became const references,
Object::getString() returns const std::string&, Gfx8BitFont::getEncoding()
returns a std::array, GfxFont::getWMode() returns a scoped enum, and
GfxState::setPath(), Object::streamGetDict()/arrayGetNF()/dictGetKey()/
dictGetValNF() and the Object(Dict*) constructor were removed, while
Catalog::indexToLabel() now takes a std::string*
All of these have already been fixed upstream. You may prefer to package a
newer upstream release (1.4.4+, which contains them natively) rather than
carry a patch. If a backport is more convenient, the attached patch combines
the relevant upstream merge requests -- !7780, !7839, !7919, !7968, !8034 and
!8037 -- rebased onto 1.4.3. Every change is guarded on POPPLER_CHECK_VERSION,
so it is a no-op with the poppler currently in unstable and can be applied now,
ahead of the transition
Thanks,
Nadzeya
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEEuVOE/FJ0HcdfWSw//lAdKwFeZPsFAmprT7gACgkQ/lAdKwFe
ZPskrg/+KPi8GT3siGW/atvAaPQkE8PZyJfDwEZHBGDS4CK9OfMpkwph38c5yOlB
kShnMqVWqOHXPsX+V2c773CyQsu9wZrubYhT03DcGXmjHZrFUMSUhjS2zqUkjNHq
ImK/uMo8KUDVtlRS7DdoZ8gJ8/bDGxvgu2NQwjZ1Jv2CbqNgKQxEAtaanvEJBvUZ
rVLkl+bkkJHeKBNhUaa77E+1nw5SOlBBFFKAb4fPs/UPahyvHRwH0QaiLL/vvnem
2+rpRAp+rvGKtBA0PVHkwAOeP7Zxlkwx4CBHy4GXw5PCpFko8yZh7zIXfLOu3tzc
rPR902qZDT1t5hXaD6i6rklujY8Dw/Sqho5sCCNCNrWY2cAHAVP3pIuWNjHcAb+G
vR9lPcfAZSP4mtXKCVqkIISLm9YwIjNfhsGZ+cwPBQyG9Ji+u2IQ6CtvBcMsbNbq
jX4hOddb3BRNUpsWZ6kPlcDctL1TYTzqt6eP+eVzB3RushozsJ1ejJq9JBgFkAb6
f0+s8GNfsIsFROCKsOVs3ti9dWUSuSgrL67/9U/zCbc81wDG4Cy/ESqhVZ0UxnSD
Qv26Iqq1kkf2wJDd2iUbdh0gzMkSsfs+miyucQ0jIWKV3AZp/2L0rVSntpi5v9hA
8VAlOM35yNsuHaxuSIIpA9nEvogJu+USPj26uPjQGs8WyI1soXs=
=lqz7
-----END PGP SIGNATURE-----
Description: Fix FTBFS with poppler 26.07
poppler 26.02 through 26.07 reshaped large parts of the internal C++ API used
by Inkscape's PDF import extension: many GfxColor*/PDFRectangle* parameters and
getters became const references, Object::getString() now returns a
const std::string&, Gfx8BitFont::getEncoding() returns a std::array,
GfxFont::getWMode() returns a scoped enum, and GfxState::setPath(),
Object::streamGetDict()/arrayGetNF()/dictGetKey()/dictGetValNF() and the
Object(Dict*) constructor were removed, while Catalog::indexToLabel() now
takes a std::string*.
.
This backports Inkscape's own upstream poppler 26.02-26.07 port, rebased onto
1.4.3, combining these upstream merge requests:
* !7780 - Fix building with Poppler 26.02 (47e20c05)
* !7839 - Fix building with Poppler 26.04 (9fcd1ec7)
* !7919 - Support for poppler >= 26.05 font encoding change
* !7968 - Fix building with Poppler 26.06 (1ad89c94)
* !8034 - Fix building with Poppler 26.07 (fc52525f)
* !8037 - Fix incorrect Poppler version check (09cbe3cf)
.
Every change is guarded on POPPLER_CHECK_VERSION, so it is a no-op with the
poppler currently in the archive and can be applied ahead of the transition.
Author: Nadzeya Hutsko <[email protected]>
Bug-Ubuntu: https://bugs.launchpad.net/bugs/2162141
Origin: backport, https://gitlab.com/inkscape/inkscape/-/commit/09cbe3cf
Forwarded: not-needed
Last-Update: 2026-07-30
--- a/src/extension/internal/pdfinput/pdf-input.cpp
+++ b/src/extension/internal/pdfinput/pdf-input.cpp
@@ -59,6 +59,8 @@
#include "document.h"
#include "extension/input.h"
#include "extension/system.h"
+#include <optional>
+
#include "inkscape.h"
#include "object/sp-root.h"
#include "pdf-parser.h"
@@ -808,7 +810,11 @@
}
// Apply crop settings
+#if POPPLER_CHECK_VERSION(26, 6, 0)
+ std::optional<PDFRectangle> clipToBox;
+#else
_POPPLER_CONST PDFRectangle *clipToBox = nullptr;
+#endif
if (crop_to == "media-box") {
clipToBox = page->getMediaBox();
@@ -822,8 +828,16 @@
clipToBox = page->getArtBox();
}
+ std::optional<PDFRectangle> cropBox;
+#if POPPLER_CHECK_VERSION(26, 6, 0)
+ cropBox = clipToBox;
+#else
+ if (clipToBox) {
+ cropBox = *clipToBox;
+ }
+#endif
// Create parser (extension/internal/pdfinput/pdf-parser.h)
- auto pdf_parser = PdfParser(pdf_doc, builder, page, clipToBox);
+ auto pdf_parser = PdfParser(pdf_doc, builder, page, cropBox);
// Set up approximation precision for parser. Used for converting Mesh
Gradients into tiles.
if ( color_delta <= 0.0 ) {
--- a/src/extension/internal/pdfinput/pdf-parser.cpp
+++ b/src/extension/internal/pdfinput/pdf-parser.cpp
@@ -43,6 +43,7 @@
#include <poppler/GlobalParams.h>
#include <poppler/Lexer.h>
#include <poppler/Object.h>
+#include <poppler/OptionalContent.h>
#include <poppler/OutputDev.h>
#include <poppler/PDFDoc.h>
#include <poppler/Page.h>
@@ -266,7 +267,7 @@
//------------------------------------------------------------------------
PdfParser::PdfParser(std::shared_ptr<PDFDoc> pdf_doc,
Inkscape::Extension::Internal::SvgBuilder *builderA, Page *page,
- _POPPLER_CONST PDFRectangle *cropBox)
+ const std::optional<PDFRectangle> &cropBox)
: _pdf_doc(pdf_doc)
, xref(pdf_doc->getXRef())
, builder(builderA)
@@ -292,8 +293,8 @@
if (page) {
// Increment the page building here and set page label
Catalog *catalog = pdf_doc->getCatalog();
- GooString *label = new GooString("");
- catalog->indexToLabel(page->getNum() - 1, label);
+ _POPPLER_STRING_26_7 label;
+ catalog->indexToLabel(page->getNum() - 1, &label);
builder->pushPage(getString(label), state);
}
@@ -307,8 +308,8 @@
builder->setMargins(getRect(page->getTrimBox()) * scale,
getRect(page->getArtBox()) * scale,
getRect(page->getBleedBox()) * scale);
- if (cropBox && getRect(cropBox) != page_box) {
- builder->cropPage(getRect(cropBox) * scale);
+ if (cropBox && getRect(*cropBox) != page_box) {
+ builder->cropPage(getRect(*cropBox) * scale);
}
saveState();
@@ -325,7 +326,7 @@
, printCommands(false)
, res(new GfxResources(xref, resDict, nullptr))
, // start the resource stack
- state(new GfxState(72, 72, box, 0, false))
+ state(new _POPPLER_GFX_STATE(72, 72, *box, 0, false))
, fontChanged(gFalse)
, clip(clipNone)
, ignoreUndef(0)
@@ -653,7 +654,11 @@
void PdfParser::opSetLineJoin(Object args[], int /*numArgs*/)
{
builder->beforeStateChange(state);
+#if POPPLER_CHECK_VERSION(26,2,0)
+ state->setLineJoin((GfxState::LineJoinStyle) args[0].getInt());
+#else
state->setLineJoin(args[0].getInt());
+#endif
builder->updateStyle(state);
}
@@ -661,7 +666,11 @@
void PdfParser::opSetLineCap(Object args[], int /*numArgs*/)
{
builder->beforeStateChange(state);
+#if POPPLER_CHECK_VERSION(26,2,0)
+ state->setLineCap((GfxState::LineCapStyle) args[0].getInt());
+#else
state->setLineCap(args[0].getInt());
+#endif
builder->updateStyle(state);
}
@@ -809,7 +818,7 @@
}
_POPPLER_FREE(obj3);
if (_POPPLER_CALL_ARGS_DEREF(obj3, obj2.dictLookup,
"G").isStream()) {
- if (_POPPLER_CALL_ARGS_DEREF(obj4,
obj3.streamGetDict()->lookup, "Group").isDict()) {
+ if (_POPPLER_CALL_ARGS_DEREF(obj4,
obj3.getStream()->getDict()->lookup, "Group").isDict()) {
std::unique_ptr<GfxColorSpace> blendingColorSpace;
GBool isolated = gFalse;
GBool knockout = gFalse;
@@ -872,7 +881,7 @@
}
// get stream dict
- dict = str->streamGetDict();
+ dict = str->getStream()->getDict();
// check form type
_POPPLER_CALL_ARGS(obj1, dict->lookup, "FormType");
@@ -984,7 +993,7 @@
state->setFillPattern(nullptr);
state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceGrayColorSpace>()));
color.c[0] = dblToCol(args[0].getNum());
- state->setFillColor(&color);
+ state->_POPPLER_SET_FILL_COLOR(color);
builder->updateStyle(state);
}
@@ -996,7 +1005,7 @@
state->setStrokePattern(nullptr);
state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique<GfxDeviceGrayColorSpace>()));
color.c[0] = dblToCol(args[0].getNum());
- state->setStrokeColor(&color);
+ state->_POPPLER_SET_STROKE_COLOR(color);
builder->updateStyle(state);
}
@@ -1011,7 +1020,7 @@
for (i = 0; i < 4; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
- state->setFillColor(&color);
+ state->_POPPLER_SET_FILL_COLOR(color);
builder->updateStyle(state);
}
@@ -1025,7 +1034,7 @@
for (int i = 0; i < 4; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
- state->setStrokeColor(&color);
+ state->_POPPLER_SET_STROKE_COLOR(color);
builder->updateStyle(state);
}
@@ -1039,7 +1048,7 @@
for (int i = 0; i < 3; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
- state->setFillColor(&color);
+ state->_POPPLER_SET_FILL_COLOR(color);
builder->updateStyle(state);
}
@@ -1052,7 +1061,7 @@
for (int i = 0; i < 3; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
- state->setStrokeColor(&color);
+ state->_POPPLER_SET_STROKE_COLOR(color);
builder->updateStyle(state);
}
@@ -1068,7 +1077,7 @@
GfxColor color;
colorSpace->getDefaultColor(&color);
state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace));
- state->setFillColor(&color);
+ state->_POPPLER_SET_FILL_COLOR(color);
builder->updateStyle(state);
} else {
error(errSyntaxError, getPos(), "Bad color space (fill)");
@@ -1089,7 +1098,7 @@
GfxColor color;
colorSpace->getDefaultColor(&color);
state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace));
- state->setStrokeColor(&color);
+ state->_POPPLER_SET_STROKE_COLOR(color);
builder->updateStyle(state);
} else {
error(errSyntaxError, getPos(), "Bad color space (stroke)");
@@ -1109,7 +1118,7 @@
for (i = 0; i < numArgs; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
- state->setFillColor(&color);
+ state->_POPPLER_SET_FILL_COLOR(color);
builder->updateStyle(state);
}
@@ -1126,7 +1135,7 @@
for (i = 0; i < numArgs; ++i) {
color.c[i] = dblToCol(args[i].getNum());
}
- state->setStrokeColor(&color);
+ state->_POPPLER_SET_STROKE_COLOR(color);
builder->updateStyle(state);
}
@@ -1147,7 +1156,7 @@
color.c[i] = dblToCol(args[i].getNum());
}
}
- state->setFillColor(&color);
+ state->_POPPLER_SET_FILL_COLOR(color);
builder->updateStyle(state);
}
if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) {
@@ -1166,7 +1175,7 @@
color.c[i] = dblToCol(args[i].getNum());
}
}
- state->setFillColor(&color);
+ state->_POPPLER_SET_FILL_COLOR(color);
builder->updateStyle(state);
}
}
@@ -1190,7 +1199,7 @@
color.c[i] = dblToCol(args[i].getNum());
}
}
- state->setStrokeColor(&color);
+ state->_POPPLER_SET_STROKE_COLOR(color);
builder->updateStyle(state);
}
if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) {
@@ -1209,7 +1218,7 @@
color.c[i] = dblToCol(args[i].getNum());
}
}
- state->setStrokeColor(&color);
+ state->_POPPLER_SET_STROKE_COLOR(color);
builder->updateStyle(state);
}
}
@@ -1565,7 +1574,13 @@
// restore graphics state
restoreState();
+#if POPPLER_CHECK_VERSION(26, 2, 0)
+ state->clearPath();
+ GfxPath *currPath = const_cast<GfxPath*>(state->getPath());
+ currPath->append(savedPath);
+#else
state->setPath(savedPath);
+#endif
}
// TODO not good that numArgs is ignored but args[] is used:
@@ -1626,7 +1641,13 @@
// restore graphics state
if (savedState) {
restoreState();
+#if POPPLER_CHECK_VERSION(26, 2, 0)
+ state->clearPath();
+ GfxPath *currPath = const_cast<GfxPath*>(state->getPath());
+ currPath->append(savedPath);
+#else
state->setPath(savedPath);
+#endif
}
}
@@ -1680,7 +1701,7 @@
// use the center color
shading->getColor(xM, yM, &fillColor);
- state->setFillColor(&fillColor);
+ state->_POPPLER_SET_FILL_COLOR(fillColor);
// fill the rectangle
state->moveTo(x0 * matrix[0] + y0 * matrix[2] + matrix[4],
@@ -1779,7 +1800,7 @@
}
}
if (i == nComps || depth == maxDepths[pdfGouraudTriangleShading-1]) {
- state->setFillColor(color0);
+ state->_POPPLER_SET_FILL_COLOR(*color0);
state->moveTo(x0, y0);
state->lineTo(x1, y1);
state->lineTo(x2, y2);
@@ -1857,7 +1878,7 @@
color.c[i] = GfxColorComp(patch->color[0][0].c[i]);
}
if (i == nComps || depth == maxDepths[pdfPatchMeshShading-1]) {
- state->setFillColor(&color);
+ state->_POPPLER_SET_FILL_COLOR(color);
state->moveTo(patch->x[0][0], patch->y[0][0]);
state->curveTo(patch->x[0][1], patch->y[0][1],
patch->x[0][2], patch->y[0][2],
@@ -2213,7 +2234,7 @@
{
Array *a = nullptr;
Object obj;
- int wMode = 0; // Writing mode (horizontal/vertical).
+ _POPPLER_WMODE wMode = _POPPLER_WMODE_HORIZONTAL; // Writing mode
(horizontal/vertical).
if (!state->getFont()) {
error(errSyntaxError, getPos(), "No font in show/space");
@@ -2227,7 +2248,7 @@
if (obj.isNum()) {
// this uses the absolute value of the font size to match
// Acrobat's behavior
- if (wMode) {
+ if (wMode != _POPPLER_WMODE_HORIZONTAL) {
state->textShift(0, -obj.getNum() * 0.001 *
fabs(state->getFontSize()));
} else {
@@ -2248,15 +2269,11 @@
* This adds a string from a PDF file that is contained in one command ('Tj',
''', '"')
* or is one string in ShowSpacetext ('TJ').
*/
-#if POPPLER_CHECK_VERSION(0,64,0)
-void PdfParser::doShowText(const GooString *s) {
-#else
-void PdfParser::doShowText(GooString *s) {
-#endif
+void PdfParser::doShowText(const std::string &s) {
auto font = state->getFont();
- int wMode = font->getWMode(); // Vertical/Horizontal/Invalid
+ _POPPLER_WMODE wMode = font->getWMode(); // Vertical/Horizontal/Invalid
- builder->beginString(state, get_goostring_length(*s));
+ builder->beginString(state, s.size());
// handle a Type 3 char
if (font->getType() == fontType3) {
@@ -2266,8 +2283,8 @@
double riseX, riseY;
state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
- auto p = s->getCString(); // char* or const char*
- int len = get_goostring_length(*s);
+ auto p = s.c_str(); // char* or const char*
+ int len = s.size();
while (len > 0) {
@@ -2289,7 +2306,7 @@
auto ax = dx;
auto ay = dy;
- if (wMode != 0) {
+ if (wMode != _POPPLER_WMODE_HORIZONTAL) {
// Vertical text (or invalid value).
dy += state->getCharSpace();
if (n == 1 && *p == ' ') {
@@ -2324,6 +2341,15 @@
builder->endString(state);
}
+#if POPPLER_CHECK_VERSION(0,64,0)
+void PdfParser::doShowText(const GooString *s) {
+#else
+void PdfParser::doShowText(GooString *s) {
+#endif
+ const std::string str = s->toStr();
+ doShowText(str);
+}
+
//------------------------------------------------------------------------
// XObject operators
@@ -2352,7 +2378,7 @@
}
//add layer at root if xObject has type OCG
- _POPPLER_CALL_ARGS(obj2, obj1.streamGetDict()->lookup, "OC");
+ _POPPLER_CALL_ARGS(obj2, obj1.getStream()->getDict()->lookup, "OC");
if(obj2.isDict()){
auto type_dict = obj2.getDict();
if (type_dict->lookup("Type").isName("OCG")) {
@@ -2370,7 +2396,7 @@
}
}
- _POPPLER_CALL_ARGS(obj2, obj1.streamGetDict()->lookup, "Subtype");
+ _POPPLER_CALL_ARGS(obj2, obj1.getStream()->getDict()->lookup, "Subtype");
if (obj2.isName(const_cast<char*>("Image"))) {
_POPPLER_CALL_ARGS(refObj, res->lookupXObjectNF, name);
doImage(&refObj, obj1.getStream(), gFalse);
@@ -2378,7 +2404,7 @@
} else if (obj2.isName(const_cast<char*>("Form"))) {
doForm(&obj1);
} else if (obj2.isName(const_cast<char*>("PS"))) {
- _POPPLER_CALL_ARGS(obj3, obj1.streamGetDict()->lookup, "Level1");
+ _POPPLER_CALL_ARGS(obj3, obj1.getStream()->getDict()->lookup,
"Level1");
} else if (obj2.isName()) {
error(errSyntaxError, getPos(), "Unknown XObject subtype '{0:s}'",
obj2.getName());
} else {
@@ -2571,7 +2597,7 @@
goto err1;
}
maskStr = smaskObj.getStream();
- maskDict = smaskObj.streamGetDict();
+ maskDict = smaskObj.getStream()->getDict();
_POPPLER_CALL_ARGS(obj1, maskDict->lookup, "Width");
if (obj1.isNull()) {
_POPPLER_FREE(obj1);
@@ -2649,7 +2675,7 @@
goto err1;
}
maskStr = maskObj.getStream();
- maskDict = maskObj.streamGetDict();
+ maskDict = maskObj.getStream()->getDict();
_POPPLER_CALL_ARGS(obj1, maskDict->lookup, "Width");
if (obj1.isNull()) {
_POPPLER_FREE(obj1);
@@ -2749,7 +2775,7 @@
}
// get stream dict
- dict = str->streamGetDict();
+ dict = str->getStream()->getDict();
// check form type
_POPPLER_CALL_ARGS(obj1, dict->lookup, "FormType");
@@ -2931,7 +2957,12 @@
// build dictionary
#if defined(POPPLER_NEW_OBJECT_API)
+#if POPPLER_CHECK_VERSION(26, 6, 0)
+ // poppler 26.06 removed the Object(Dict *) constructor
+ dict = Object(std::make_unique<Dict>(xref));
+#else
dict = Object(new Dict(xref));
+#endif
#else
dict.initDict(xref);
#endif
@@ -2964,7 +2995,11 @@
// make stream
#if defined(POPPLER_NEW_OBJECT_API)
str = new EmbedStream(parser->getStream(), dict.copy(), gFalse, 0);
+#if POPPLER_CHECK_VERSION(26, 2, 0)
+ str = str->addFilters(std::unique_ptr<Stream>(str),
dict.getDict()).release();
+#else
str = str->addFilters(dict.getDict());
+#endif
#else
str = new EmbedStream(parser->getStream(), &dict, gFalse, 0);
str = str->addFilters(&dict);
@@ -3137,10 +3172,17 @@
auto visible = true;
// Normally we'd use poppler optContentIsVisible, but these dict
// objects don't retain their references so can't be used directly.
+#if POPPLER_CHECK_VERSION(26, 2, 0)
+ for (auto &[ref, ocg] : ocgs->getOCGs()) {
+ if (ocg->getName()->toStr() == label)
+ visible = ocg->getState() == OptionalContentGroup::On;
+ }
+#else
for (auto &[ref, ocg] : ocgs->getOCGs()) {
if (ocg->getName()->cmp(label) == 0)
visible = ocg->getState() == OptionalContentGroup::On;
}
+#endif
builder->addOptionalGroup(dict->getKey(j), label, visible);
}
}
--- a/src/extension/internal/pdfinput/pdf-parser.h
+++ b/src/extension/internal/pdfinput/pdf-parser.h
@@ -29,6 +29,7 @@
#include <glib/poppler-features.h>
#include <map>
#include <memory>
+#include <optional>
#include <poppler/Object.h>
#include <string>
@@ -113,7 +114,7 @@
public:
// Constructor for regular output.
- PdfParser(std::shared_ptr<PDFDoc> pdf_doc, SvgBuilder *builderA, Page
*page, _POPPLER_CONST PDFRectangle *cropBox);
+ PdfParser(std::shared_ptr<PDFDoc> pdf_doc, SvgBuilder *builderA, Page
*page, const std::optional<PDFRectangle> &cropBox);
// Constructor for a sub-page object.
PdfParser(XRef *xrefA, SvgBuilder *builderA, Dict *resDict, _POPPLER_CONST
PDFRectangle *box);
@@ -283,10 +284,11 @@
void opMoveShowText(Object args[], int numArgs);
void opMoveSetShowText(Object args[], int numArgs);
void opShowSpaceText(Object args[], int numArgs);
+ void doShowText(const std::string &s);
#if POPPLER_CHECK_VERSION(0,64,0)
- void doShowText(const GooString *s);
+ void doShowText(const GooString *s);
#else
- void doShowText(GooString *s);
+ void doShowText(GooString *s);
#endif
--- a/src/extension/internal/pdfinput/pdf-utils.cpp
+++ b/src/extension/internal/pdfinput/pdf-utils.cpp
@@ -133,6 +133,11 @@
return Geom::Rect(box->x1, box->y1, box->x2, box->y2);
}
+Geom::Rect getRect(_POPPLER_CONST PDFRectangle &box)
+{
+ return Geom::Rect(box.x1, box.y1, box.x2, box.y2);
+}
+
Geom::PathVector getPathV(GfxPath *path)
{
if (!path) {
--- a/src/extension/internal/pdfinput/pdf-utils.h
+++ b/src/extension/internal/pdfinput/pdf-utils.h
@@ -59,6 +59,7 @@
};
Geom::Rect getRect(_POPPLER_CONST PDFRectangle *box);
+Geom::Rect getRect(_POPPLER_CONST PDFRectangle &box);
Geom::PathVector getPathV(GfxPath *gPath);
#endif /* PDF_UTILS_H */
--- a/src/extension/internal/pdfinput/poppler-transition-api.h
+++ b/src/extension/internal/pdfinput/poppler-transition-api.h
@@ -15,6 +15,38 @@
#include <glib/poppler-features.h>
#include <poppler/UTF.h>
+#if POPPLER_CHECK_VERSION(26, 7, 0)
+#define _POPPLER_STRING_26_7 std::string
+#else
+#define _POPPLER_STRING_26_7 GooString
+#endif
+
+#if POPPLER_CHECK_VERSION(26, 6, 0)
+#define _POPPLER_GET_GRAY(color, gray) getGray(color, gray)
+#define _POPPLER_GET_RGB(color, rgb) getRGB(color, rgb)
+#define _POPPLER_GET_CMYK(color, cmyk) getCMYK(color, cmyk)
+#define _POPPLER_SET_FILL_COLOR(color) setFillColor(color)
+#define _POPPLER_SET_STROKE_COLOR(color) setStrokeColor(color)
+#define _POPPLER_GFX_STATE(h, v, Rect, rotateA, upsideDown) GfxState(h, v,
Rect, rotateA, upsideDown)
+#else
+#define _POPPLER_GET_GRAY(color, gray) getGray(&color, gray)
+#define _POPPLER_GET_RGB(color, rgb) getRGB(&color, rgb)
+#define _POPPLER_GET_CMYK(color, cmyk) getCMYK(&color, cmyk)
+#define _POPPLER_SET_FILL_COLOR(color) setFillColor(&color)
+#define _POPPLER_SET_STROKE_COLOR(color) setStrokeColor(&color)
+#define _POPPLER_GFX_STATE(h, v, Rect, rotateA, upsideDown) GfxState(h, v,
&Rect, rotateA, upsideDown)
+#endif
+
+#if POPPLER_CHECK_VERSION(26, 2, 0)
+#define _POPPLER_WMODE GfxFont::WritingMode
+#define _POPPLER_WMODE_HORIZONTAL GfxFont::WritingMode::Horizontal
+#define _POPPLER_WMODE_VERTICAL GfxFont::WritingMode::Vertical
+#else
+#define _POPPLER_WMODE int
+#define _POPPLER_WMODE_HORIZONTAL 0
+#define _POPPLER_WMODE_VERTICAL 1
+#endif
+
#if POPPLER_CHECK_VERSION(25, 7, 0)
#define _POPPLER_TEXT_SHIFT_WITH_USER_COORDS(dx, dy)
textShiftWithUserCoords(dx, dy)
#define _POPPLER_FOFI_TRUETYPE_MAKE(font_data, faceIndex)
FoFiTrueType::make(std::span(font_data), faceIndex)
@@ -62,11 +94,11 @@
#endif
#if POPPLER_CHECK_VERSION(24, 5, 0)
-#define _POPPLER_HAS_UNICODE_BOM(value)
(hasUnicodeByteOrderMark(value->toStr()))
-#define _POPPLER_HAS_UNICODE_BOMLE(value)
(hasUnicodeByteOrderMarkLE(value->toStr()))
+#define _POPPLER_HAS_UNICODE_BOM(value) (hasUnicodeByteOrderMark(value))
+#define _POPPLER_HAS_UNICODE_BOMLE(value) (hasUnicodeByteOrderMarkLE(value))
#else
-#define _POPPLER_HAS_UNICODE_BOM(value) (value->hasUnicodeMarker())
-#define _POPPLER_HAS_UNICODE_BOMLE(value) (value->hasUnicodeMarkerLE())
+#define _POPPLER_HAS_UNICODE_BOM(value) (GooString(value).hasUnicodeMarker())
+#define _POPPLER_HAS_UNICODE_BOMLE(value)
(GooString(value).hasUnicodeMarkerLE())
#endif
#if POPPLER_CHECK_VERSION(24, 3, 0)
--- a/src/extension/internal/pdfinput/poppler-utils.cpp
+++ b/src/extension/internal/pdfinput/poppler-utils.cpp
@@ -88,7 +88,12 @@
r.num = hashFontObject(&obj2);
}
// Newer poppler will require some reworking as it gives a shared
ptr.
+#if POPPLER_CHECK_VERSION(26, 3, 0)
+ // poppler 26.03 made GfxFont::makeFont() take a const Dict&
fontDict
+ fonts[i] = GfxFont::makeFont(xref, fontDict->getKey(i), r,
*obj2.getDict());
+#else
fonts[i] = GfxFont::makeFont(xref, fontDict->getKey(i), r,
obj2.getDict());
+#endif
if (fonts[i] && !fonts[i]->isOk()) {
fonts[i] = nullptr;
}
@@ -145,7 +150,6 @@
void InkFontDict::hashFontObject1(const Object *obj, FNVHash *h)
{
- const GooString *s;
const char *p;
double r;
int n, i;
@@ -165,11 +169,16 @@
r = obj->getReal();
h->hash((char *)&r, sizeof(double));
break;
- case objString:
+ case objString: {
h->hash('s');
- s = obj->getString();
+#if POPPLER_CHECK_VERSION(26, 4, 0)
+ const auto &s = obj->getString();
+ h->hash(s.c_str(), s.size());
+#else
+ const GooString* s = obj->getString();
h->hash(s->c_str(), get_goostring_length(*s));
- break;
+#endif
+ } break;
case objName:
h->hash('n');
p = obj->getName();
@@ -178,26 +187,28 @@
case objNull:
h->hash('z');
break;
- case objArray:
- h->hash('a');
- n = obj->arrayGetLength();
- h->hash((char *)&n, sizeof(int));
- for (i = 0; i < n; ++i) {
- const Object &obj2 = obj->arrayGetNF(i);
- hashFontObject1(&obj2, h);
- }
- break;
- case objDict:
- h->hash('d');
- n = obj->dictGetLength();
- h->hash((char *)&n, sizeof(int));
- for (i = 0; i < n; ++i) {
- p = obj->dictGetKey(i);
- h->hash(p, (int)strlen(p));
- const Object &obj2 = obj->dictGetValNF(i);
- hashFontObject1(&obj2, h);
- }
- break;
+ case objArray: {
+ h->hash('a');
+ Array * objArray = obj->getArray();
+ n = objArray->getLength();
+ h->hash((char *)&n, sizeof(int));
+ for (i = 0; i < n; ++i) {
+ const Object &obj2 = objArray->getNF(i);
+ hashFontObject1(&obj2, h);
+ }
+ } break;
+ case objDict: {
+ h->hash('d');
+ auto objdict = obj->getDict();
+ n = objdict->getLength();
+ h->hash((char *)&n, sizeof(int));
+ for (i = 0; i < n; ++i) {
+ auto p = std::string(objdict->getKey(i));
+ h->hash(p.c_str(), p.length());
+ const Object &obj2 = objdict->getValNF(i);
+ hashFontObject1(&obj2, h);
+ }
+ } break;
case objStream:
// this should never happen - streams must be indirect refs
break;
@@ -535,7 +546,7 @@
continue;
Ref resourcesRef;
- const Object resObj = obj2.streamGetDict()->lookup("Resources",
&resourcesRef);
+ const Object resObj =
obj2.getStream()->getDict()->lookup("Resources", &resourcesRef);
if (resourcesRef != Ref::INVALID() &&
!visitedObjects.insert(resourcesRef.num).second)
continue;
@@ -590,16 +601,29 @@
* Convert PDF strings, which can be formatted as UTF8, UTF16BE or UTF16LE into
* a predictable UTF8 string consistant with svg requirements.
*/
-std::string getString(const GooString *value)
+std::string getString(const std::string &value)
{
if (_POPPLER_HAS_UNICODE_BOM(value)) {
- return g_convert(value->getCString () + 2,
get_goostring_length(*value) - 2,
+ return g_convert(value.c_str() + 2, value.size() - 2,
"UTF-8", "UTF-16BE", NULL, NULL, NULL);
} else if (_POPPLER_HAS_UNICODE_BOMLE(value)) {
- return g_convert(value->getCString () + 2,
get_goostring_length(*value) - 2,
+ return g_convert(value.c_str() + 2, value.size() - 2,
"UTF-8", "UTF-16LE", NULL, NULL, NULL);
}
- return value->toStr();
+ return value;
+}
+
+std::string getString(const GooString *value)
+{
+ if (value) {
+ return getString(value->toStr());
+ }
+ return "";
+}
+
+std::string getString(const GooString &value)
+{
+ return getString(value.toStr());
}
void pdf_debug_array(const Array *array, int depth, XRef *xref)
@@ -656,7 +680,11 @@
} else if (obj->isArray()) {
pdf_debug_array(obj->getArray(), depth, xref);
} else if (obj->isString()) {
+#if POPPLER_CHECK_VERSION(26, 4, 0)
+ std::cout << " STR '" << obj->getString().c_str() << "'";
+#else
std::cout << " STR '" << obj->getString()->getCString() << "'";
+#endif
} else if (obj->isName()) {
std::cout << " NAME '" << obj->getName() << "'";
} else if (obj->isBool()) {
--- a/src/extension/internal/pdfinput/poppler-utils.h
+++ b/src/extension/internal/pdfinput/poppler-utils.h
@@ -83,7 +83,9 @@
FontList getPdfFonts(std::shared_ptr<PDFDoc> pdf_doc);
std::string getNameWithoutSubsetTag(std::string name);
std::string getDictString(Dict *dict, const char *key);
+std::string getString(const std::string &value);
std::string getString(const GooString *value);
+std::string getString(const GooString &value);
std::string validateString(std::string const &in);
// Replacate poppler FontDict
--- a/src/extension/internal/pdfinput/svg-builder.cpp
+++ b/src/extension/internal/pdfinput/svg-builder.cpp
@@ -392,7 +392,15 @@
return svgConvertRGBToText(r, g, b);
}
-std::string SvgBuilder::convertGfxColor(const GfxColor *color, GfxColorSpace
*space)
+// for poppler < 26.06.0
+std::string SvgBuilder::convertGfxColor(const GfxColor *color, GfxColorSpace
*space) {
+ if (!color) {
+ return "";
+ }
+ return convertGfxColor(*color, space);
+}
+
+std::string SvgBuilder::convertGfxColor(const GfxColor &color, GfxColorSpace
*space)
{
std::string icc = "";
switch (space->getMode()) {
@@ -412,14 +420,14 @@
}
GfxRGB rgb;
- space->getRGB(color, &rgb);
+ space->_POPPLER_GET_RGB(color, &rgb);
auto rgb_color = svgConvertGfxRGB(&rgb);
if (!icc.empty()) {
Inkscape::CSSOStringStream icc_color;
icc_color << rgb_color << " icc-color(" << icc;
for (int i = 0; i < space->getNComps(); ++i) {
- icc_color << ", " << colToDbl((*color).c[i]);
+ icc_color << ", " << colToDbl((color).c[i]);
}
icc_color << ");";
return icc_color.str();
@@ -1204,7 +1212,7 @@
/**
* \brief Adds a stop with the given properties to the gradient's
representation
*/
-void SvgBuilder::_addStopToGradient(Inkscape::XML::Node *gradient, double
offset, GfxColor *color, GfxColorSpace *space,
+void SvgBuilder::_addStopToGradient(Inkscape::XML::Node *gradient, double
offset, GfxColor &color, GfxColorSpace *space,
double opacity)
{
Inkscape::XML::Node *stop = _xml_doc->createElement("svg:stop");
@@ -1214,7 +1222,7 @@
if (space->getMode() == csDeviceGray) {
// This is a transparency mask.
GfxRGB rgb;
- space->getRGB(color, &rgb);
+ space->_POPPLER_GET_RGB(color, &rgb);
double gray = (double)rgb.r / 65535.0;
gray = CLAMP(gray, 0.0, 1.0);
os_opacity << gray;
@@ -1255,8 +1263,8 @@
if (!svgGetShadingColor(shading, 0.0, &stop1) ||
!svgGetShadingColor(shading, 1.0, &stop2)) {
return false;
} else {
- _addStopToGradient(gradient, 0.0, &stop1, space, 1.0);
- _addStopToGradient(gradient, 1.0, &stop2, space, 1.0);
+ _addStopToGradient(gradient, 0.0, stop1, space, 1.0);
+ _addStopToGradient(gradient, 1.0, stop2, space, 1.0);
}
} else if (type == _POPPLER_FUNCTION_TYPE_STITCHING) {
auto stitchingFunc = static_cast<_POPPLER_CONST
StitchingFunction*>(func);
@@ -1269,7 +1277,7 @@
// Add stops from all the stitched functions
GfxColor prev_color, color;
svgGetShadingColor(shading, bounds[0], &prev_color);
- _addStopToGradient(gradient, bounds[0], &prev_color, space, 1.0);
+ _addStopToGradient(gradient, bounds[0], prev_color, space, 1.0);
for ( int i = 0 ; i < num_funcs ; i++ ) {
svgGetShadingColor(shading, bounds[i + 1], &color);
// Add stops
@@ -1279,14 +1287,14 @@
expE = (bounds[i + 1] - bounds[i])/expE; // approximate
exponential as a single straight line at x=1
if (encode[2*i] == 0) { // normal sequence
auto offset = (bounds[i + 1] - expE) / max_bound;
- _addStopToGradient(gradient, offset, &prev_color,
space, 1.0);
+ _addStopToGradient(gradient, offset, prev_color,
space, 1.0);
} else { // reflected sequence
auto offset = (bounds[i] + expE) / max_bound;
- _addStopToGradient(gradient, offset, &color, space,
1.0);
+ _addStopToGradient(gradient, offset, color, space,
1.0);
}
}
}
- _addStopToGradient(gradient, bounds[i + 1] / max_bound, &color,
space, 1.0);
+ _addStopToGradient(gradient, bounds[i + 1] / max_bound, color,
space, 1.0);
prev_color = color;
}
} else { // Unsupported function type
@@ -1386,7 +1394,7 @@
sp_repr_css_set_property(_css_font, "font-variant", "normal");
// Writing mode
- if ( font->getWMode() == 0 ) {
+ if ( font->getWMode() == _POPPLER_WMODE_HORIZONTAL ) {
sp_repr_css_set_property(_css_font, "writing-mode", "lr");
} else {
sp_repr_css_set_property(_css_font, "writing-mode", "tb");
@@ -1398,7 +1406,7 @@
*/
void SvgBuilder::updateTextShift(GfxState *state, double shift) {
double shift_value = -shift * 0.001 * fabs(state->getFontSize());
- if (state->getFont()->getWMode()) {
+ if (state->getFont()->getWMode() != _POPPLER_WMODE_HORIZONTAL) {
_text_position[1] += shift_value;
} else {
_text_position[0] += shift_value;
@@ -1452,7 +1460,7 @@
// Text direction is a property of the <text> element.
auto font = state->getFont();
- if (font->getWMode() == 1) {
+ if (font->getWMode() == _POPPLER_WMODE_VERTICAL) {
// Only set if vertical.
auto css_text = sp_repr_css_attr_new();
sp_repr_css_set_property(css_text, "writing-mode", "tb");
@@ -1546,8 +1554,8 @@
bool output_tspan =
next_it == _glyphs.end() ||
next_it->style_changed ||
- (writing_mode == 0 && std::abs(glyph.text_position[1] -
next_it->text_position[1]) > 0.1) ||
- (writing_mode == 1 && std::abs(glyph.text_position[0] -
next_it->text_position[0]) > 0.1);
+ (writing_mode == _POPPLER_WMODE_HORIZONTAL &&
std::abs(glyph.text_position[1] - next_it->text_position[1]) > 0.1) ||
+ (writing_mode == _POPPLER_WMODE_VERTICAL &&
std::abs(glyph.text_position[0] - next_it->text_position[0]) > 0.1);
if (output_tspan) {
--- a/src/extension/internal/pdfinput/svg-builder.h
+++ b/src/extension/internal/pdfinput/svg-builder.h
@@ -186,7 +186,7 @@
// Pattern creation
gchar *_createPattern(GfxPattern *pattern, GfxState *state, bool
is_stroke=false);
gchar *_createGradient(GfxShading *shading, const Geom::Affine pat_matrix,
bool for_shading = false);
- void _addStopToGradient(Inkscape::XML::Node *gradient, double offset,
GfxColor *color, GfxColorSpace *space,
+ void _addStopToGradient(Inkscape::XML::Node *gradient, double offset,
GfxColor &color, GfxColorSpace *space,
double opacity);
bool _addGradientStops(Inkscape::XML::Node *gradient, GfxShading *shading,
_POPPLER_CONST Function *func);
@@ -239,6 +239,7 @@
static bool _attrEqual(Inkscape::XML::Node *a, Inkscape::XML::Node *b,
char const *attr);
// Colors
+ std::string convertGfxColor(const GfxColor &color, GfxColorSpace *space);
std::string convertGfxColor(const GfxColor *color, GfxColorSpace *space);
std::string _getColorProfile(cmsHPROFILE hp);
--- a/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp
+++ b/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp
@@ -313,7 +313,11 @@
#else
GfxFontLoc *fontLoc;
#endif
+#if POPPLER_CHECK_VERSION(26, 5, 0)
+ const char * const *enc;
+#else
char **enc;
+#endif
const char *name;
#if POPPLER_CHECK_VERSION(25, 7, 0)
std::unique_ptr<FoFiType1C> ff1c;
@@ -385,7 +389,11 @@
goto err2;
}
+#if POPPLER_CHECK_VERSION(26, 5, 0)
+ enc = gfx8bit->getEncoding().data();
+#else
enc = gfx8bit->getEncoding();
+#endif
codeToGID.resize(256);
for (i = 0; i < 256; ++i) {
@@ -677,7 +685,7 @@
#endif
std::vector<int> codeToGID;
- char *name;
+ const char *name;
Dict *charProcs = gfx8bit->getCharProcs();
Ref ref = *gfxFont->getID();
@@ -694,13 +702,17 @@
cairo_font_face_set_user_data(font_face, &type3_font_key, (void *)info,
_free_type3_font_info);
+#if POPPLER_CHECK_VERSION(26, 5, 0)
+ const char * const *enc = gfx8bit->getEncoding().data();
+#else
char **enc = gfx8bit->getEncoding();
+#endif
codeToGID.resize(256);
for (int i = 0; i < 256; ++i) {
codeToGID[i] = 0;
if (charProcs && (name = enc[i])) {
for (int j = 0; j < charProcs->getLength(); j++) {
- if (strcmp(name, charProcs->getKey(j)) == 0) {
+ if (std::string(charProcs->getKey(j)).compare(name) == 0) {
codeToGID[i] = j;
}
}
--- End Message ---