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;
                 }
             }

Reply via email to