Submitted By: Joe Locash Date: 2026-04-06 Initial Package Version: 1.4.3 Upstream Status: Applied Origin: Upstream commits: Fix for poppler-26.01.0: 3a528728ebe33e10bb44d152f47cfedfddbfe18a Fix for poppler-26.02.0: 47e20c0503ab1464d528f2cc7dd5e6a6a85b70dc Fix for poppler-26.03.0: 754a866b878623554ade26d53496eeb8687c4685 Fix for poppler-26.04.0: https://gitlab.com/inkscape/inkscape/-/merge_requests/7839 (Approved) Description: Fixes building Inkscape-1.4.3 against poppler-26.01.0 through poppler-26.04.0. All failed hunks backported to 1.4.3. diff -Nuarp inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/pdf-input.cpp inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/pdf-input.cpp --- inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/pdf-input.cpp 2025-12-25 19:35:50.000000000 -0500 +++ inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/pdf-input.cpp 2026-04-06 13:05:07.795505297 -0400 @@ -33,6 +33,7 @@ #include #include #include +#include #endif #include diff -Nuarp inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/pdf-parser.cpp inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/pdf-parser.cpp --- inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/pdf-parser.cpp 2025-12-25 19:35:50.000000000 -0500 +++ inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/pdf-parser.cpp 2026-04-06 13:05:32.710924687 -0400 @@ -653,7 +653,11 @@ void PdfParser::opSetFlat(Object args[], 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 +665,11 @@ void PdfParser::opSetLineJoin(Object arg 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); } @@ -1565,7 +1573,13 @@ void PdfParser::doShadingPatternFillFall // restore graphics state restoreState(); +#if POPPLER_CHECK_VERSION(26, 2, 0) + state->clearPath(); + GfxPath *currPath = const_cast(state->getPath()); + currPath->append(savedPath); +#else state->setPath(savedPath); +#endif } // TODO not good that numArgs is ignored but args[] is used: @@ -1626,7 +1640,13 @@ void PdfParser::opShFill(Object args[], // restore graphics state if (savedState) { restoreState(); +#if POPPLER_CHECK_VERSION(26, 2, 0) + state->clearPath(); + GfxPath *currPath = const_cast(state->getPath()); + currPath->append(savedPath); +#else state->setPath(savedPath); +#endif } } @@ -2213,7 +2233,7 @@ void PdfParser::opShowSpaceText(Object a { 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 +2247,7 @@ void PdfParser::opShowSpaceText(Object a 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 +2268,11 @@ void PdfParser::opShowSpaceText(Object a * 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 +2282,8 @@ void PdfParser::doShowText(GooString *s) 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 +2305,7 @@ void PdfParser::doShowText(GooString *s) 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 +2340,15 @@ void PdfParser::doShowText(GooString *s) 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 @@ -2931,7 +2956,11 @@ Stream *PdfParser::buildImageStream() { // build dictionary #if defined(POPPLER_NEW_OBJECT_API) +#if POPPLER_CHECK_VERSION(26, 3, 0) + dict = Object(std::make_unique(xref)); +#else dict = Object(new Dict(xref)); +#endif #else dict.initDict(xref); #endif @@ -2964,7 +2993,11 @@ Stream *PdfParser::buildImageStream() { // 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(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 +3170,17 @@ void PdfParser::loadOptionalContentLayer 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); } } diff -Nuarp inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/pdf-parser.h inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/pdf-parser.h --- inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/pdf-parser.h 2025-12-25 19:35:50.000000000 -0500 +++ inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/pdf-parser.h 2026-04-06 13:05:32.711297631 -0400 @@ -283,10 +283,11 @@ private: 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 diff -Nuarp inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/poppler-transition-api.h inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/poppler-transition-api.h --- inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/poppler-transition-api.h 2025-07-25 06:14:52.000000000 -0400 +++ inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/poppler-transition-api.h 2026-04-06 13:05:32.711390967 -0400 @@ -15,6 +15,16 @@ #include #include +#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 +72,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) diff -Nuarp inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/poppler-utils.cpp inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/poppler-utils.cpp --- inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/poppler-utils.cpp 2025-12-25 19:35:50.000000000 -0500 +++ inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/poppler-utils.cpp 2026-04-06 13:51:26.663274614 -0400 @@ -88,7 +88,11 @@ InkFontDict::InkFontDict(XRef *xref, Ref r.num = hashFontObject(&obj2); } // Newer poppler will require some reworking as it gives a shared ptr. +#if POPPLER_CHECK_VERSION(26,3,0) + 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 +149,11 @@ int InkFontDict::hashFontObject(Object * void InkFontDict::hashFontObject1(const Object *obj, FNVHash *h) { +#if POPPLER_CHECK_VERSION(26, 4, 0) + const std::string *s; +#else const GooString *s; +#endif const char *p; double r; int n, i; @@ -167,8 +175,13 @@ void InkFontDict::hashFontObject1(const break; case objString: h->hash('s'); +#if POPPLER_CHECK_VERSION(26, 4, 0) + s = &obj->getString(); + h->hash(s->c_str(), s->size()); +#else s = obj->getString(); h->hash(s->c_str(), get_goostring_length(*s)); +#endif break; case objName: h->hash('n'); @@ -583,23 +596,40 @@ std::string getDictString(Dict *dict, co if (!obj.isString()) { return ""; } + std::cout << obj.getString() << std::endl; return getString(obj.getString()); } +std::string getString(const GooString *value) +{ + if (value) { + return getString(value->toStr()); + } + return ""; +} + /** * 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) { + char *str = nullptr; + if (_POPPLER_HAS_UNICODE_BOM(value)) { - return g_convert(value->getCString () + 2, get_goostring_length(*value) - 2, - "UTF-8", "UTF-16BE", NULL, NULL, NULL); + str = 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, - "UTF-8", "UTF-16LE", NULL, NULL, NULL); + str = g_convert(value.c_str() + 2, value.size() - 2, + "UTF-8", "UTF-16LE", NULL, NULL, NULL); } - return value->toStr(); + if (str) { + std::string copy = str; + g_free(str); + return copy; + } + g_warning("Couldn't parse text in PDF from UTF16."); + return ""; } void pdf_debug_array(const Array *array, int depth, XRef *xref) @@ -656,7 +686,11 @@ void pdf_debug_object(const Object *obj, } 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()) { diff -Nuarp inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/poppler-utils.h inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/poppler-utils.h --- inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/poppler-utils.h 2025-12-25 19:35:50.000000000 -0500 +++ inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/poppler-utils.h 2026-04-06 13:28:42.831480474 -0400 @@ -83,6 +83,8 @@ typedef std::shared_ptr 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 std::unique_ptr &value); std::string getString(const GooString *value); std::string validateString(std::string const &in); diff -Nuarp inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/svg-builder.cpp inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/svg-builder.cpp --- inkscape-1.4.3_2025-12-25_0d15f75042.orig/src/extension/internal/pdfinput/svg-builder.cpp 2025-12-25 19:35:50.000000000 -0500 +++ inkscape-1.4.3_2025-12-25_0d15f75042/src/extension/internal/pdfinput/svg-builder.cpp 2026-04-06 13:05:07.796902482 -0400 @@ -32,6 +32,7 @@ #include #include #include +#include #include "color.h" #include "color/cms-util.h" @@ -1385,7 +1386,7 @@ void SvgBuilder::updateFont(GfxState *st 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"); @@ -1397,7 +1398,7 @@ void SvgBuilder::updateFont(GfxState *st */ 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; @@ -1451,7 +1452,7 @@ Inkscape::XML::Node* SvgBuilder::_flushT // Text direction is a property of the 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"); @@ -1545,8 +1546,8 @@ Inkscape::XML::Node* SvgBuilder::_flushT 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) { @@ -2093,7 +2094,11 @@ Inkscape::XML::Node *SvgBuilder::_create } else { image_stream = new ImageStream(str, width, 1, 1); } +#if POPPLER_CHECK_VERSION(26, 0, 0) + image_stream->rewind(); +#else image_stream->reset(); +#endif // Convert grayscale values unsigned char *buffer = new unsigned char[width]; @@ -2119,7 +2124,11 @@ Inkscape::XML::Node *SvgBuilder::_create image_stream = new ImageStream(str, width, color_map->getNumPixelComps(), color_map->getBits()); +#if POPPLER_CHECK_VERSION(26, 0, 0) + image_stream->rewind(); +#else image_stream->reset(); +#endif // Convert RGB values unsigned int *buffer = new unsigned int[width];