From 241ebb296b4640054bf805f068278dd8155e6ebc Mon Sep 17 00:00:00 2001 From: Mateusz Sylwestrzak Date: Sun, 23 Feb 2025 17:33:41 +0100 Subject: [PATCH] inkscape: revbump for libpoppler, fix pdf crashes --- .../patches/0001-poppler-fofitruetype.patch | 59 +++ .../patches/0002-poppler-gfxcolorspace.patch | 430 ++++++++++++++++++ .../patches/0003-poppler-includes.patch | 39 ++ .../patches/0004-poppler-getimageparams.patch | 53 +++ srcpkgs/inkscape/patches/6811.patch | 195 ++++++++ .../inkscape/patches/poppler_25.02.0.patch | 179 ++++++++ srcpkgs/inkscape/template | 2 +- 7 files changed, 956 insertions(+), 1 deletion(-) create mode 100644 srcpkgs/inkscape/patches/0001-poppler-fofitruetype.patch create mode 100644 srcpkgs/inkscape/patches/0002-poppler-gfxcolorspace.patch create mode 100644 srcpkgs/inkscape/patches/0003-poppler-includes.patch create mode 100644 srcpkgs/inkscape/patches/0004-poppler-getimageparams.patch create mode 100644 srcpkgs/inkscape/patches/6811.patch create mode 100644 srcpkgs/inkscape/patches/poppler_25.02.0.patch diff --git a/srcpkgs/inkscape/patches/0001-poppler-fofitruetype.patch b/srcpkgs/inkscape/patches/0001-poppler-fofitruetype.patch new file mode 100644 index 00000000000..fdfe0efa1a7 --- /dev/null +++ b/srcpkgs/inkscape/patches/0001-poppler-fofitruetype.patch @@ -0,0 +1,59 @@ +From 0399372ec240d23e0e70548237a541f2b5bf0f34 Mon Sep 17 00:00:00 2001 +From: KrIr17 +Date: Tue, 5 Nov 2024 00:40:15 +0100 +Subject: [PATCH] Fix building with Poppler 24.11 + +Poppler 24.11 no longer sets the default value for faceIndex to 0 in +`FoFiTrueType::make()` and `FoFiTrueType::load()` [1], so we do it +on our end instead. + +Fixes https://gitlab.com/inkscape/inkscape/-/issues/5370 + +[1] https://gitlab.freedesktop.org/poppler/poppler/-/commit/94467509a013dd5cf46c942baa598f2b296571f4 +--- + .../internal/pdfinput/poppler-cairo-font-engine.cpp | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp b/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp +index 34a8eed682d..728b1d1aac4 100644 +--- a/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp ++++ b/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp +@@ -419,9 +419,9 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + FoFiTrueType *ff; + #endif + if (!font_data.empty()) { +- ff = FoFiTrueType::make((fontchar)font_data.data(), font_data.size()); ++ ff = FoFiTrueType::make((fontchar)font_data.data(), font_data.size(), 0); + } else { +- ff = FoFiTrueType::load(fileName.c_str()); ++ ff = FoFiTrueType::load(fileName.c_str(), 0); + } + if (!ff) { + goto err2; +@@ -444,9 +444,9 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + FoFiTrueType *ff; + #endif + if (!font_data.empty()) { +- ff = FoFiTrueType::make((fontchar)font_data.data(), font_data.size()); ++ ff = FoFiTrueType::make((fontchar)font_data.data(), font_data.size(), 0); + } else { +- ff = FoFiTrueType::load(fileName.c_str()); ++ ff = FoFiTrueType::load(fileName.c_str(), 0); + } + if (!ff) { + error(errSyntaxError, -1, "failed to load truetype font\n"); +@@ -512,9 +512,9 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + FoFiTrueType *ff; + #endif + if (!font_data.empty()) { +- ff = FoFiTrueType::make((fontchar)font_data.data(), font_data.size()); ++ ff = FoFiTrueType::make((fontchar)font_data.data(), font_data.size(), 0); + } else { +- ff = FoFiTrueType::load(fileName.c_str()); ++ ff = FoFiTrueType::load(fileName.c_str(), 0); + } + if (ff) { + if (ff->isOpenTypeCFF()) { +-- +GitLab + diff --git a/srcpkgs/inkscape/patches/0002-poppler-gfxcolorspace.patch b/srcpkgs/inkscape/patches/0002-poppler-gfxcolorspace.patch new file mode 100644 index 00000000000..754f385c6ec --- /dev/null +++ b/srcpkgs/inkscape/patches/0002-poppler-gfxcolorspace.patch @@ -0,0 +1,430 @@ +From 22304ae8034d067670a9f95022083a75fac92b4c Mon Sep 17 00:00:00 2001 +From: PBS +Date: Tue, 22 Oct 2024 14:48:31 +0100 +Subject: [PATCH] Future-proof against poppler 24.10 changes + +--- + .../internal/pdfinput/pdf-parser.cpp | 120 ++++++++---------- + src/extension/internal/pdfinput/pdf-parser.h | 4 +- + .../pdfinput/poppler-transition-api.h | 6 + + 3 files changed, 61 insertions(+), 69 deletions(-) + +diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp +index 97b2909218a..28000a87b0c 100644 +--- a/src/extension/internal/pdfinput/pdf-parser.cpp ++++ b/src/extension/internal/pdfinput/pdf-parser.cpp +@@ -817,11 +817,11 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) + _POPPLER_FREE(obj3); + if (_POPPLER_CALL_ARGS_DEREF(obj3, obj2.dictLookup, "G").isStream()) { + if (_POPPLER_CALL_ARGS_DEREF(obj4, obj3.streamGetDict()->lookup, "Group").isDict()) { +- GfxColorSpace *blendingColorSpace = nullptr; ++ std::unique_ptr blendingColorSpace; + GBool isolated = gFalse; + GBool knockout = gFalse; + if (!_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup, "CS").isNull()) { +- blendingColorSpace = GfxColorSpace::parse(nullptr, &obj5, nullptr, state); ++ blendingColorSpace = std::unique_ptr(GfxColorSpace::parse(nullptr, &obj5, nullptr, state)); + } + _POPPLER_FREE(obj5); + if (_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup, "I").isBool()) { +@@ -842,7 +842,7 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) + } + } + } +- doSoftMask(&obj3, alpha, blendingColorSpace, isolated, knockout, funcs[0], &backdropColor); ++ doSoftMask(&obj3, alpha, blendingColorSpace.get(), isolated, knockout, funcs[0], &backdropColor); + if (funcs[0]) { + delete funcs[0]; + } +@@ -927,9 +927,6 @@ void PdfParser::doSoftMask(Object *str, GBool alpha, + alpha, transferFunc, backdropColor); + --formDepth; + +- if (blendingColorSpace) { +- delete blendingColorSpace; +- } + _POPPLER_FREE(obj1); + } + +@@ -946,42 +943,43 @@ void PdfParser::opSetRenderingIntent(Object /*args*/[], int /*numArgs*/) + * + * Maintains a cache for named color spaces to avoid expensive re-parsing. + */ +-GfxColorSpace *PdfParser::lookupColorSpaceCopy(Object &arg) ++std::unique_ptr PdfParser::lookupColorSpaceCopy(Object &arg) + { + assert(!arg.isNull()); +- GfxColorSpace *colorSpace = nullptr; + + if (char const *name = arg.isName() ? arg.getName() : nullptr) { + auto const cache_name = std::to_string(formDepth) + "-" + name; +- if ((colorSpace = colorSpacesCache[cache_name].get())) { +- return colorSpace->copy(); ++ if (auto cached = colorSpacesCache[cache_name].get()) { ++ return std::unique_ptr(cached->copy()); + } + +- Object obj = res->lookupColorSpace(name); +- if (obj.isNull()) { +- colorSpace = GfxColorSpace::parse(res, &arg, nullptr, state); ++ std::unique_ptr colorSpace; ++ if (auto obj = res->lookupColorSpace(name); !obj.isNull()) { ++ colorSpace = std::unique_ptr(GfxColorSpace::parse(res, &obj, nullptr, state)); + } else { +- colorSpace = GfxColorSpace::parse(res, &obj, nullptr, state); ++ colorSpace = std::unique_ptr(GfxColorSpace::parse(res, &arg, nullptr, state)); + } + + if (colorSpace && colorSpace->getMode() != csPattern) { +- colorSpacesCache[cache_name].reset(colorSpace->copy()); ++ colorSpacesCache[cache_name] = std::unique_ptr(colorSpace->copy()); + } ++ ++ return colorSpace; + } else { + // We were passed in an object directly. +- colorSpace = GfxColorSpace::parse(res, &arg, nullptr, state); ++ return std::unique_ptr(GfxColorSpace::parse(res, &arg, nullptr, state)); + } +- return colorSpace; + } + + /** + * Look up pattern/gradients from the GfxResource dictionary + */ +-GfxPattern *PdfParser::lookupPattern(Object *obj, GfxState *state) ++std::unique_ptr PdfParser::lookupPattern(Object *obj, GfxState *state) + { +- if (!obj->isName()) +- return nullptr; +- return res->lookupPattern(obj->getName(), nullptr, state); ++ if (!obj->isName()) { ++ return {}; ++ } ++ return std::unique_ptr(res->lookupPattern(obj->getName(), nullptr, state)); + } + + // TODO not good that numArgs is ignored but args[] is used: +@@ -990,7 +988,7 @@ void PdfParser::opSetFillGray(Object args[], int /*numArgs*/) + GfxColor color; + builder->beforeStateChange(state); + state->setFillPattern(nullptr); +- state->setFillColorSpace(new GfxDeviceGrayColorSpace()); ++ state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); + color.c[0] = dblToCol(args[0].getNum()); + state->setFillColor(&color); + builder->updateStyle(state); +@@ -1002,7 +1000,7 @@ void PdfParser::opSetStrokeGray(Object args[], int /*numArgs*/) + GfxColor color; + builder->beforeStateChange(state); + state->setStrokePattern(nullptr); +- state->setStrokeColorSpace(new GfxDeviceGrayColorSpace()); ++ state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); + color.c[0] = dblToCol(args[0].getNum()); + state->setStrokeColor(&color); + builder->updateStyle(state); +@@ -1015,7 +1013,7 @@ void PdfParser::opSetFillCMYKColor(Object args[], int /*numArgs*/) + int i; + builder->beforeStateChange(state); + state->setFillPattern(nullptr); +- state->setFillColorSpace(new GfxDeviceCMYKColorSpace()); ++ state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); + for (i = 0; i < 4; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } +@@ -1029,7 +1027,7 @@ void PdfParser::opSetStrokeCMYKColor(Object args[], int /*numArgs*/) + GfxColor color; + builder->beforeStateChange(state); + state->setStrokePattern(nullptr); +- state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace()); ++ state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); + for (int i = 0; i < 4; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } +@@ -1043,7 +1041,7 @@ void PdfParser::opSetFillRGBColor(Object args[], int /*numArgs*/) + GfxColor color; + builder->beforeStateChange(state); + state->setFillPattern(nullptr); +- state->setFillColorSpace(new GfxDeviceRGBColorSpace()); ++ state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); + for (int i = 0; i < 3; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } +@@ -1056,7 +1054,7 @@ void PdfParser::opSetStrokeRGBColor(Object args[], int /*numArgs*/) { + GfxColor color; + builder->beforeStateChange(state); + state->setStrokePattern(nullptr); +- state->setStrokeColorSpace(new GfxDeviceRGBColorSpace()); ++ state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); + for (int i = 0; i < 3; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } +@@ -1068,14 +1066,14 @@ void PdfParser::opSetStrokeRGBColor(Object args[], int /*numArgs*/) { + void PdfParser::opSetFillColorSpace(Object args[], int numArgs) + { + assert(numArgs >= 1); +- GfxColorSpace *colorSpace = lookupColorSpaceCopy(args[0]); ++ auto colorSpace = lookupColorSpaceCopy(args[0]); + builder->beforeStateChange(state); + state->setFillPattern(nullptr); + + if (colorSpace) { + GfxColor color; +- state->setFillColorSpace(colorSpace); + colorSpace->getDefaultColor(&color); ++ state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace)); + state->setFillColor(&color); + builder->updateStyle(state); + } else { +@@ -1089,14 +1087,14 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int numArgs) + assert(numArgs >= 1); + builder->beforeStateChange(state); + +- GfxColorSpace *colorSpace = lookupColorSpaceCopy(args[0]); ++ auto colorSpace = lookupColorSpaceCopy(args[0]); + + state->setStrokePattern(nullptr); + + if (colorSpace) { + GfxColor color; +- state->setStrokeColorSpace(colorSpace); + colorSpace->getDefaultColor(&color); ++ state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace)); + state->setStrokeColor(&color); + builder->updateStyle(state); + } else { +@@ -1159,7 +1157,7 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) { + builder->updateStyle(state); + } + if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) { +- state->setFillPattern(pattern); ++ state->setFillPattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern)); + builder->updateStyle(state); + } + +@@ -1202,7 +1200,7 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) { + builder->updateStyle(state); + } + if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) { +- state->setStrokePattern(pattern); ++ state->setStrokePattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern)); + builder->updateStyle(state); + } + +@@ -1579,11 +1577,11 @@ void PdfParser::doShadingPatternFillFallback(GfxShadingPattern *sPat, + // TODO not good that numArgs is ignored but args[] is used: + void PdfParser::opShFill(Object args[], int /*numArgs*/) + { +- GfxShading *shading = nullptr; + GfxPath *savedPath = nullptr; + bool savedState = false; + +- if (!(shading = res->lookupShading(args[0].getName(), nullptr, state))) { ++ auto shading = std::unique_ptr(res->lookupShading(args[0].getName(), nullptr, state)); ++ if (!shading) { + return; + } + +@@ -1615,19 +1613,19 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/) + // do shading type-specific operations + switch (shading->getType()) { + case 1: // Function-based shading +- doFunctionShFill(static_cast(shading)); ++ doFunctionShFill(static_cast(shading.get())); + break; + case 2: // Axial shading + case 3: // Radial shading +- builder->addClippedFill(shading, stateToAffine(state)); ++ builder->addClippedFill(shading.get(), stateToAffine(state)); + break; + case 4: // Free-form Gouraud-shaded triangle mesh + case 5: // Lattice-form Gouraud-shaded triangle mesh +- doGouraudTriangleShFill(static_cast(shading)); ++ doGouraudTriangleShFill(static_cast(shading.get())); + break; + case 6: // Coons patch mesh + case 7: // Tensor-product patch mesh +- doPatchMeshShFill(static_cast(shading)); ++ doPatchMeshShFill(static_cast(shading.get())); + break; + } + +@@ -1636,8 +1634,6 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/) + restoreState(); + state->setPath(savedPath); + } +- +- delete shading; + } + + void PdfParser::doFunctionShFill(GfxFunctionShading *shading) { +@@ -2528,7 +2524,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + + } else { + // get color space and color map +- GfxColorSpace *colorSpace; ++ std::unique_ptr colorSpace; + _POPPLER_CALL_ARGS(obj1, dict->lookup, "ColorSpace"); + if (obj1.isNull()) { + _POPPLER_FREE(obj1); +@@ -2537,13 +2533,11 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + if (!obj1.isNull()) { + colorSpace = lookupColorSpaceCopy(obj1); + } else if (csMode == streamCSDeviceGray) { +- colorSpace = new GfxDeviceGrayColorSpace(); ++ colorSpace = std::make_unique(); + } else if (csMode == streamCSDeviceRGB) { +- colorSpace = new GfxDeviceRGBColorSpace(); ++ colorSpace = std::make_unique(); + } else if (csMode == streamCSDeviceCMYK) { +- colorSpace = new GfxDeviceCMYKColorSpace(); +- } else { +- colorSpace = nullptr; ++ colorSpace = std::make_unique(); + } + _POPPLER_FREE(obj1); + if (!colorSpace) { +@@ -2554,10 +2548,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + _POPPLER_FREE(obj1); + _POPPLER_CALL_ARGS(obj1, dict->lookup, "D"); + } +- GfxImageColorMap *colorMap = new GfxImageColorMap(bits, &obj1, colorSpace); ++ auto colorMap = std::make_unique(bits, &obj1, _POPPLER_CONSUME_UNIQPTR_ARG(colorSpace)); + _POPPLER_FREE(obj1); + if (!colorMap->isOk()) { +- delete colorMap; + goto err1; + } + +@@ -2568,7 +2561,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + int maskWidth = 0; + int maskHeight = 0; + maskInvert = gFalse; +- GfxImageColorMap *maskColorMap = nullptr; ++ std::unique_ptr maskColorMap; + _POPPLER_CALL_ARGS(maskObj, dict->lookup, "Mask"); + _POPPLER_CALL_ARGS(smaskObj, dict->lookup, "SMask"); + Dict* maskDict; +@@ -2624,7 +2617,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + _POPPLER_FREE(obj1); + _POPPLER_CALL_ARGS(obj1, maskDict->lookup, "CS"); + } +- GfxColorSpace *maskColorSpace = lookupColorSpaceCopy(obj1); ++ auto maskColorSpace = lookupColorSpaceCopy(obj1); + _POPPLER_FREE(obj1); + if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) { + goto err1; +@@ -2634,10 +2627,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + _POPPLER_FREE(obj1); + _POPPLER_CALL_ARGS(obj1, maskDict->lookup, "D"); + } +- maskColorMap = new GfxImageColorMap(maskBits, &obj1, maskColorSpace); ++ maskColorMap = std::make_unique(maskBits, &obj1, _POPPLER_CONSUME_UNIQPTR_ARG(maskColorSpace)); + _POPPLER_FREE(obj1); + if (!maskColorMap->isOk()) { +- delete maskColorMap; + goto err1; + } + //~ handle the Matte entry +@@ -2718,17 +2710,15 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + + // draw it + if (haveSoftMask) { +- builder->addSoftMaskedImage(state, str, width, height, colorMap, interpolate, +- maskStr, maskWidth, maskHeight, maskColorMap, maskInterpolate); +- delete maskColorMap; ++ builder->addSoftMaskedImage(state, str, width, height, colorMap.get(), interpolate, ++ maskStr, maskWidth, maskHeight, maskColorMap.get(), maskInterpolate); + } else if (haveExplicitMask) { +- builder->addMaskedImage(state, str, width, height, colorMap, interpolate, ++ builder->addMaskedImage(state, str, width, height, colorMap.get(), interpolate, + maskStr, maskWidth, maskHeight, maskInvert, maskInterpolate); + } else { +- builder->addImage(state, str, width, height, colorMap, interpolate, +- haveColorKeyMask ? maskColors : static_cast(nullptr)); ++ builder->addImage(state, str, width, height, colorMap.get(), interpolate, ++ haveColorKeyMask ? maskColors : nullptr); + } +- delete colorMap; + + _POPPLER_FREE(maskObj); + _POPPLER_FREE(smaskObj); +@@ -2746,7 +2736,6 @@ void PdfParser::doForm(Object *str, double *offset) + { + Dict *dict; + GBool transpGroup, isolated, knockout; +- GfxColorSpace *blendingColorSpace; + Object matrixObj, bboxObj; + double m[6], bbox[4]; + Object resObj; +@@ -2812,12 +2801,12 @@ void PdfParser::doForm(Object *str, double *offset) + + // check for a transparency group + transpGroup = isolated = knockout = gFalse; +- blendingColorSpace = nullptr; ++ std::unique_ptr blendingColorSpace; + if (_POPPLER_CALL_ARGS_DEREF(obj1, dict->lookup, "Group").isDict()) { + if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup, "S").isName("Transparency")) { + transpGroup = gTrue; + if (!_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup, "CS").isNull()) { +- blendingColorSpace = GfxColorSpace::parse(nullptr, &obj3, nullptr, state); ++ blendingColorSpace = std::unique_ptr(GfxColorSpace::parse(nullptr, &obj3, nullptr, state)); + } + _POPPLER_FREE(obj3); + if (_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup, "I").isBool()) { +@@ -2835,12 +2824,9 @@ void PdfParser::doForm(Object *str, double *offset) + + // draw it + ++formDepth; +- doForm1(str, resDict, m, bbox, transpGroup, gFalse, blendingColorSpace, isolated, knockout); ++ doForm1(str, resDict, m, bbox, transpGroup, gFalse, blendingColorSpace.get(), isolated, knockout); + --formDepth; + +- if (blendingColorSpace) { +- delete blendingColorSpace; +- } + _POPPLER_FREE(resObj); + } + +diff --git a/src/extension/internal/pdfinput/pdf-parser.h b/src/extension/internal/pdfinput/pdf-parser.h +index c7c10caefed..8325ea24364 100644 +--- a/src/extension/internal/pdfinput/pdf-parser.h ++++ b/src/extension/internal/pdfinput/pdf-parser.h +@@ -137,7 +137,7 @@ public: + void loadPatternColorProfiles(Dict *resources); + void loadColorProfile(); + void loadColorSpaceProfile(GfxColorSpace *space, Object *obj); +- GfxPattern *lookupPattern(Object *obj, GfxState *state); ++ std::unique_ptr lookupPattern(Object *obj, GfxState *state); + + std::shared_ptr getFontEngine(); + +@@ -176,7 +176,7 @@ private: + //! Caches color spaces by name + std::map> colorSpacesCache; + +- GfxColorSpace *lookupColorSpaceCopy(Object &); ++ std::unique_ptr lookupColorSpaceCopy(Object &); + + void setDefaultApproximationPrecision(); // init color deltas + void pushOperator(const char *name); +diff --git a/src/extension/internal/pdfinput/poppler-transition-api.h b/src/extension/internal/pdfinput/poppler-transition-api.h +index 481aefadf46..8f03aa17779 100644 +--- a/src/extension/internal/pdfinput/poppler-transition-api.h ++++ b/src/extension/internal/pdfinput/poppler-transition-api.h +@@ -15,6 +15,12 @@ + #include + #include + ++#if POPPLER_CHECK_VERSION(24, 10, 0) ++#define _POPPLER_CONSUME_UNIQPTR_ARG(value) std::move(value) ++#else ++#define _POPPLER_CONSUME_UNIQPTR_ARG(value) value.release() ++#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())) +-- +GitLab + diff --git a/srcpkgs/inkscape/patches/0003-poppler-includes.patch b/srcpkgs/inkscape/patches/0003-poppler-includes.patch new file mode 100644 index 00000000000..c4721e4619b --- /dev/null +++ b/srcpkgs/inkscape/patches/0003-poppler-includes.patch @@ -0,0 +1,39 @@ +From 874dcfbd303bc7a1bddb6f34aebbb4dba8eda771 Mon Sep 17 00:00:00 2001 +From: Rafael Siejakowski +Date: Sun, 10 Nov 2024 13:20:48 +0100 +Subject: [PATCH] Fix Poppler private includes + +In the PDF parser, include the Poppler private headers using +the angular brackets and the poppler/ directory prefix, as is +done in other places in the code which need Poppler's private +headers. + +This fixes build against Poppler installed at a custom path. +--- + src/extension/internal/pdfinput/pdf-parser.h | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/extension/internal/pdfinput/pdf-parser.h b/src/extension/internal/pdfinput/pdf-parser.h +index 8325ea24364..7d9189dfc0a 100644 +--- a/src/extension/internal/pdfinput/pdf-parser.h ++++ b/src/extension/internal/pdfinput/pdf-parser.h +@@ -24,13 +24,12 @@ + #pragma interface + #endif + +-#include "glib/poppler-features.h" +-#include "Object.h" +- ++#include <2geom/affine.h> ++#include + #include + #include ++#include + #include +-#include <2geom/affine.h> + + #define Operator Operator_Gfx + #include +-- +GitLab + diff --git a/srcpkgs/inkscape/patches/0004-poppler-getimageparams.patch b/srcpkgs/inkscape/patches/0004-poppler-getimageparams.patch new file mode 100644 index 00000000000..f4e0a8391b7 --- /dev/null +++ b/srcpkgs/inkscape/patches/0004-poppler-getimageparams.patch @@ -0,0 +1,53 @@ +From c9046810d899a408bfbd489aad91872b1203ee6d Mon Sep 17 00:00:00 2001 +From: KrIr17 +Date: Thu, 5 Dec 2024 15:03:47 +0100 +Subject: [PATCH] Fix building with poppler 24.12.0 + +Fixes https://gitlab.com/inkscape/inkscape/-/issues/5415 +--- + src/extension/internal/pdfinput/pdf-parser.cpp | 4 +++- + src/extension/internal/pdfinput/poppler-transition-api.h | 6 ++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp +index 28000a87b0c..9ea30b90a48 100644 +--- a/src/extension/internal/pdfinput/pdf-parser.cpp ++++ b/src/extension/internal/pdfinput/pdf-parser.cpp +@@ -2403,6 +2403,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + int bits; + GBool interpolate; + StreamColorSpaceMode csMode; ++ GBool hasAlpha; + GBool mask; + GBool invert; + Object maskObj, smaskObj; +@@ -2414,7 +2415,8 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) + // get info from the stream + bits = 0; + csMode = streamCSNone; +- str->getImageParams(&bits, &csMode); ++ hasAlpha = false; ++ str->_POPPLER_GET_IMAGE_PARAMS(&bits, &csMode, &hasAlpha); + + // get stream dict + dict = str->getDict(); +diff --git a/src/extension/internal/pdfinput/poppler-transition-api.h b/src/extension/internal/pdfinput/poppler-transition-api.h +index 8f03aa17779..b7a54828e74 100644 +--- a/src/extension/internal/pdfinput/poppler-transition-api.h ++++ b/src/extension/internal/pdfinput/poppler-transition-api.h +@@ -39,6 +39,12 @@ + #define _POPPLER_FUNCTION_TYPE_STITCHING 3 + #endif + ++#if POPPLER_CHECK_VERSION(24,12,0) ++#define _POPPLER_GET_IMAGE_PARAMS(bits, csMode, hasAlpha) getImageParams(bits, csMode, hasAlpha) ++#else ++#define _POPPLER_GET_IMAGE_PARAMS(bits, csMode, hasAlpha) getImageParams(bits, csMode) ++#endif ++ + #if POPPLER_CHECK_VERSION(22, 4, 0) + #define _POPPLER_FONTPTR_TO_GFX8(font_ptr) ((Gfx8BitFont *)font_ptr.get()) + #else +-- +GitLab + diff --git a/srcpkgs/inkscape/patches/6811.patch b/srcpkgs/inkscape/patches/6811.patch new file mode 100644 index 00000000000..454a6022459 --- /dev/null +++ b/srcpkgs/inkscape/patches/6811.patch @@ -0,0 +1,195 @@ +From 6c330d56fdf54cb002b8a84b33f73d2a8dd40879 Mon Sep 17 00:00:00 2001 +From: Tavmjong Bah +Date: Fri, 8 Nov 2024 15:03:12 +0100 +Subject: [PATCH] Fixes two problems related to emojis in PDF import. + +1. UTF-8 conversion. + + If a "ToUnicode" table is included in an OpenType font in a PDF + file, one can find the Unicode code point that corresponds to a + given glyph (or group of glyphs). This is often the only way one + can reconstruct text from a PDF (which might contain only glyphs + and glyph positions). For Emoji, the code points are outside the + "Basic Plane" (code points that can be encode by four or fewer + hexadecimal digits) and in are located the "Supplementary + Multilingual Plane", a.k.a. "Plane 1". Code points in "Plane 1" are + represented by a hexadecimal number of the form "1xxxx", where 'x' + is any hex digit. + + Inkscape's PDF import code takes a Unicode code point and converts + it to its UTF-8 representation. This code assumes that the code + point can be represented by a gunichar2 which is typedef'ed from a + guint16. The glib function g_utf16_to_utf8 is then used for the + conversion. This in incorrect: a single guint16 can only represent + a 4 hex-digit code point and then not all possible values (some + values are used to indicate that a second 16-bit value is being used + to to enable encoding a code point outside the basic plane). + + We already use std::wstring_convert<> and std::codecvt<> earlier in + the same function to build up a string to store the original text + in the 'aria-label' attribute. I changed the code to reuse that + result. Note that these are deprecated and will be removed in C++26 + so we'll eventually need to find a different solution. + +2. Empty paths. + + Emoji fonts usually have color. There are four competing methods of + embedding color font data in an OpenType font. Two of these use + bitmaps. If a font has only bitmap glyph data then there is no + vector data to build a path. If there is no path, Inkscape's + current code returns 'nullptr' instead of a pointer to a Path + node. This triggers an assert. Simply removing the assert leads to + other problems down the line. The simplest solution is to return a + Path node with an empty "d" attribute. This also allows one to + store the original text in the "aria-label" attribute of the Path + node. + + In the future, we should be able to render bitmaps from fonts in + the same way the same way that we render SVG OpenType fonts (which + caches the glyphs as bitmaps). + +Unfixed problems: + + If the "Noto-Color-Emoji" font is present, it will be used for + rendering emoji even if "Noto-Emoji" or "Symbola" is specified. It + will also be used as a fallback font for rendering emoji. + "Noto-Color-Emoji" has to "glyf" table and thus lacks vectorized + paths. This leads to empty paths. It would be good to block the use + of "Noto-Color-Emoji" in this case. It's not clear how easy it + would be to do this. + + What is even stranger is that the terminal will not show an Emoji + if "Noto-Color-Emoji" is not installed even though the glyph that + is shown is not from "Noto-Color-Emoji"! (It's from "Symbola".) + + There appears to be incorrect logic in SvgBuider::_flushTextPath(). + If the style changes inside the function, the node existing node is + replaced, effectively orphaning the previous node. Whether this + actually happens in PDF input is unknown. +--- + .../internal/pdfinput/svg-builder.cpp | 54 +++++++++---------- + 1 file changed, 26 insertions(+), 28 deletions(-) + +diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp +index 73f57f04952..bb2ce5145e8 100644 +--- a/src/extension/internal/pdfinput/svg-builder.cpp ++++ b/src/extension/internal/pdfinput/svg-builder.cpp +@@ -1250,7 +1250,7 @@ void SvgBuilder::updateFont(GfxState *state, std::shared_ptr cairo_fo + TRACE(("updateFont()\n")); + updateTextMatrix(state, flip); // Ensure that we have a text matrix built + +- auto font = state->getFont(); ++ auto font = state->getFont(); // GfxFont + auto font_id = font->getID()->num; + + auto new_font_size = state->getFontSize(); +@@ -1711,6 +1711,10 @@ void SvgBuilder::_setTextStyle(Inkscape::XML::Node *node, GfxState *state, SPCSS + /** + * Renders the text as a path object using cairo and returns the node object. + * ++ * If the path is empty (e.g. due to trying to render a color bitmap font), ++ * return path node with empty "d" attribute. The aria attribute will still ++ * contain the original text. ++ * + * cairo_font - The font that cairo can use to convert text to path. + * font_size - The size of the text when drawing the path. + * transform - The matrix which will place the text on the page, this is critical +@@ -1722,8 +1726,13 @@ Inkscape::XML::Node *SvgBuilder::_renderText(std::shared_ptr cairo_fo + const Geom::Affine &transform, + cairo_glyph_t *cairo_glyphs, unsigned int count) + { +- if (!cairo_glyphs || !cairo_font || _aria_label.empty()) +- return nullptr; ++ Inkscape::XML::Node *path = _addToContainer("svg:path"); ++ path->setAttribute("d", ""); ++ ++ if (!cairo_glyphs || !cairo_font || _aria_label.empty()) { ++ std::cerr << "SvgBuilder::_renderText: Invalid argument!" << std::endl; ++ return path; ++ } + + // The surface isn't actually used, no rendering in cairo takes place. + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, _width, _height); +@@ -1738,16 +1747,17 @@ Inkscape::XML::Node *SvgBuilder::_renderText(std::shared_ptr cairo_fo + + // Failing to render text. + if (!pathv) { +- g_warning("Failed to render PDF text!"); +- return nullptr; ++ std::cerr << "SvgBuilder::_renderText: Failed to render PDF text! " << _aria_label << std::endl; ++ return path; + } + + auto textpath = sp_svg_write_path(*pathv); +- if (textpath.empty()) +- return nullptr; +- +- Inkscape::XML::Node *path = _addToContainer("svg:path"); + path->setAttribute("d", textpath); ++ ++ if (textpath.empty()) { ++ std::cerr << "SvgBuilder::_renderText: Empty path! " << _aria_label << std::endl; ++ } ++ + return path; + } + +@@ -1785,7 +1795,7 @@ void SvgBuilder::endString(GfxState *state) + * dx, dy: Advance of glyph. + * originX, originY + * code: 8-bit char code, 16 bit CID, or Unicode of glyph. +- * u: Unicode mapping of character. ++ * u: Unicode mapping of character. "Unicode" is an unsigned int. + */ + void SvgBuilder::addChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, + CharCode code, int /*nBytes*/, Unicode const *u, int uLen) +@@ -1801,9 +1811,13 @@ void SvgBuilder::addChar(GfxState *state, double x, double y, double dx, double + } + _aria_space = false; + ++ std::string utf8_code; + static std::wstring_convert, char32_t> conv1; ++ // Note std::wstring_convert and std::codecvt_utf are deprecated and will be removed in C++26. + if (u) { +- _aria_label += conv1.to_bytes(*u); ++ // 'u' maybe null if there is not a "ToUnicode" table in the PDF! ++ utf8_code = conv1.to_bytes(*u); ++ _aria_label += utf8_code; + } + + // Skip control characters, found in LaTeX generated PDFs +@@ -1835,6 +1849,7 @@ void SvgBuilder::addChar(GfxState *state, double x, double y, double dx, double + } + + SvgGlyph new_glyph; ++ new_glyph.code = utf8_code; + new_glyph.is_space = is_space; + new_glyph.delta = delta; + new_glyph.position = Geom::Point( x - originX, y - originY ); +@@ -1849,23 +1864,6 @@ void SvgBuilder::addChar(GfxState *state, double x, double y, double dx, double + } + _text_position += delta; + +- // Convert the character to UTF-8 since that's our SVG document's encoding +- { +- gunichar2 uu[8] = {0}; +- +- for (int i = 0; i < uLen; i++) { +- uu[i] = u[i]; +- } +- +- gchar *tmp = g_utf16_to_utf8(uu, uLen, nullptr, nullptr, nullptr); +- if ( tmp && *tmp ) { +- new_glyph.code = tmp; +- } else { +- new_glyph.code.clear(); +- } +- g_free(tmp); +- } +- + // Copy current style if it has changed since the previous glyph + if (_invalidated_style || _glyphs.empty()) { + _invalidated_style = false; +-- +GitLab + diff --git a/srcpkgs/inkscape/patches/poppler_25.02.0.patch b/srcpkgs/inkscape/patches/poppler_25.02.0.patch new file mode 100644 index 00000000000..21f41e1b155 --- /dev/null +++ b/srcpkgs/inkscape/patches/poppler_25.02.0.patch @@ -0,0 +1,179 @@ +From 5c4c6d116dae5250d75d34a45f0d9220824d2e20 Mon Sep 17 00:00:00 2001 +From: KrIr17 +Date: Sun, 9 Feb 2025 22:52:53 +0530 +Subject: [PATCH] Fix building with poppler 25.02.0 + +1. `getCodeToGIDMap`, `getCIDToGID`, `getCIDToGIDMap` are now `std::vector` + +2. `pdfDocEncodingToUTF16` returns an `std::string` +--- + .../pdfinput/poppler-cairo-font-engine.cpp | 50 +++++++++++++++---- + .../pdfinput/poppler-transition-api.h | 20 +++++--- + 3 files changed, 63 insertions(+), 16 deletions(-) + +diff --git a/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp b/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp +index 728b1d1aac4..bd1d4e49367 100644 +--- a/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp ++++ b/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp +@@ -405,14 +405,22 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + break; + case fontCIDType2: + case fontCIDType2OT: ++#if POPPLER_CHECK_VERSION(25,2,0) ++ if (!gfxcid->getCIDToGID().empty()) { ++ const auto src = gfxcid->getCIDToGID(); ++ codeToGID = std::move(src); ++ } ++#else + if (gfxcid->getCIDToGID()) { + n = gfxcid->getCIDToGIDLen(); + if (n) { +- const int *src = gfxcid->getCIDToGID(); ++ const auto src = gfxcid->getCIDToGID(); + codeToGID.reserve(n); + codeToGID.insert(codeToGID.begin(), src, src + n); + } +- } else { ++ } ++#endif ++ else { + #if POPPLER_CHECK_VERSION(22, 1, 0) + std::unique_ptr ff; + #else +@@ -427,13 +435,18 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + goto err2; + } + #if POPPLER_CHECK_VERSION(22, 1, 0) +- int *src = gfxcid->getCodeToGIDMap(ff.get(), &n); ++ auto src = gfxcid->_POPPLER_GET_CODE_TO_GID_MAP(ff.get(), &n); + #else +- int *src = gfxcid->getCodeToGIDMap(ff, &n); ++ auto src = gfxcid->_POPPLER_GET_CODE_TO_GID_MAP(ff, &n); + #endif ++ ++#if POPPLER_CHECK_VERSION(25,2,0) ++ codeToGID = std::move(src); ++#else + codeToGID.reserve(n); + codeToGID.insert(codeToGID.begin(), src, src + n); + gfree(src); ++#endif + } + /* Fall through */ + case fontTrueType: +@@ -455,13 +468,17 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + /* This might be set already for the CIDType2 case */ + if (fontType == fontTrueType || fontType == fontTrueTypeOT) { + #if POPPLER_CHECK_VERSION(22, 1, 0) +- int *src = gfx8bit->getCodeToGIDMap(ff.get()); ++ auto src = gfx8bit->getCodeToGIDMap(ff.get()); + #else +- int *src = gfx8bit->getCodeToGIDMap(ff); ++ auto src = gfx8bit->getCodeToGIDMap(ff); + #endif ++#if POPPLER_CHECK_VERSION(25,2,0) ++ codeToGID = std::move(src); ++#else + codeToGID.reserve(256); + codeToGID.insert(codeToGID.begin(), src, src + 256); + gfree(src); ++#endif + } + font_face = getFreeTypeFontFace(fontEngine, lib, fileName, std::move(font_data)); + if (!font_face) { +@@ -479,10 +496,14 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + ff1c = FoFiType1C::load(fileName.c_str()); + } + if (ff1c) { +- int *src = ff1c->getCIDToGIDMap(&n); ++ auto src = ff1c->_POPPLER_GET_CID_TO_GID_MAP(&n); ++#if POPPLER_CHECK_VERSION(25,2,0) ++ codeToGID = std::move(src); ++#else + codeToGID.reserve(n); + codeToGID.insert(codeToGID.begin(), src, src + n); + gfree(src); ++#endif + delete ff1c; + } + } +@@ -495,14 +516,21 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + break; + + case fontCIDType0COT: ++#if POPPLER_CHECK_VERSION(25,2,0) ++ if (!gfxcid->getCIDToGID().empty()) { ++ const auto src = gfxcid->getCIDToGID(); ++ codeToGID = std::move(src); ++ } ++#else + if (gfxcid->getCIDToGID()) { + n = gfxcid->getCIDToGIDLen(); + if (n) { +- const int *src = gfxcid->getCIDToGID(); ++ const auto src = gfxcid->getCIDToGID(); + codeToGID.reserve(n); + codeToGID.insert(codeToGID.begin(), src, src + n); + } + } ++#endif + + if (codeToGID.empty()) { + if (!useCIDs) { +@@ -518,10 +546,14 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, FT_Li + } + if (ff) { + if (ff->isOpenTypeCFF()) { +- int *src = ff->getCIDToGIDMap(&n); ++ auto src = ff1c->_POPPLER_GET_CID_TO_GID_MAP(&n); ++#if POPPLER_CHECK_VERSION(25,2,0) ++ codeToGID = std::move(src); ++#else + codeToGID.reserve(n); + codeToGID.insert(codeToGID.begin(), src, src + n); + gfree(src); ++#endif + } + } + } +diff --git a/src/extension/internal/pdfinput/poppler-transition-api.h b/src/extension/internal/pdfinput/poppler-transition-api.h +index b7a54828e74..a67132ba6bd 100644 +--- a/src/extension/internal/pdfinput/poppler-transition-api.h ++++ b/src/extension/internal/pdfinput/poppler-transition-api.h +@@ -15,6 +15,20 @@ + #include + #include + ++#if POPPLER_CHECK_VERSION(25,2,0) ++#define _POPPLER_GET_CODE_TO_GID_MAP(ff, len) getCodeToGIDMap(ff) ++#define _POPPLER_GET_CID_TO_GID_MAP(len) getCIDToGIDMap() ++#else ++#define _POPPLER_GET_CODE_TO_GID_MAP(ff, len) getCodeToGIDMap(ff, len) ++#define _POPPLER_GET_CID_TO_GID_MAP(len) getCIDToGIDMap(len) ++#endif ++ ++#if POPPLER_CHECK_VERSION(24,12,0) ++#define _POPPLER_GET_IMAGE_PARAMS(bits, csMode, hasAlpha) getImageParams(bits, csMode, hasAlpha) ++#else ++#define _POPPLER_GET_IMAGE_PARAMS(bits, csMode, hasAlpha) getImageParams(bits, csMode) ++#endif ++ + #if POPPLER_CHECK_VERSION(24, 10, 0) + #define _POPPLER_CONSUME_UNIQPTR_ARG(value) std::move(value) + #else +@@ -39,12 +53,6 @@ + #define _POPPLER_FUNCTION_TYPE_STITCHING 3 + #endif + +-#if POPPLER_CHECK_VERSION(24,12,0) +-#define _POPPLER_GET_IMAGE_PARAMS(bits, csMode, hasAlpha) getImageParams(bits, csMode, hasAlpha) +-#else +-#define _POPPLER_GET_IMAGE_PARAMS(bits, csMode, hasAlpha) getImageParams(bits, csMode) +-#endif +- + #if POPPLER_CHECK_VERSION(22, 4, 0) + #define _POPPLER_FONTPTR_TO_GFX8(font_ptr) ((Gfx8BitFont *)font_ptr.get()) + #else +-- +GitLab + diff --git a/srcpkgs/inkscape/template b/srcpkgs/inkscape/template index 710b83b730b..316f8c88670 100644 --- a/srcpkgs/inkscape/template +++ b/srcpkgs/inkscape/template @@ -1,7 +1,7 @@ # Template file for 'inkscape' pkgname=inkscape version=1.4 -revision=2 +revision=3 build_style=cmake make_check_target="check" hostmakedepends="automake gettext glib-devel intltool libgraphicsmagick-devel