Submitted By: Douglas R. Reno Date: 2024-12-03 Initial Package Version: 1.4 Upstream Status: Applied (custom hunk submitted) Origin: Upstream + Self Description: This patch fixes building Inkscape 1.4 with several different versions of poppler, adapting to API changes in 24.10.0-24.12.0. The fixes for 24.10.0 and 24.11.0 were brought to the lists by Joe Locash and Uwe Duffert. The fix for 24.12.0 (which was adjusting the call to getImageParams) was made by myself and submitted to upstream. diff -Naurp inkscape-1.4_2024-10-09_e7c3feb100.orig/src/extension/internal/pdfinput/pdf-parser.cpp inkscape-1.4_2024-10-09_e7c3feb100/src/extension/internal/pdfinput/pdf-parser.cpp --- inkscape-1.4_2024-10-09_e7c3feb100.orig/src/extension/internal/pdfinput/pdf-parser.cpp 2024-07-28 06:27:55.000000000 -0500 +++ inkscape-1.4_2024-10-09_e7c3feb100/src/extension/internal/pdfinput/pdf-parser.cpp 2024-12-03 15:45:30.457029407 -0600 @@ -810,11 +810,11 @@ void PdfParser::opSetExtGState(Object ar _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()) { @@ -835,7 +835,7 @@ void PdfParser::opSetExtGState(Object ar } } } - 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]; } @@ -920,9 +920,6 @@ void PdfParser::doSoftMask(Object *str, alpha, transferFunc, backdropColor); --formDepth; - if (blendingColorSpace) { - delete blendingColorSpace; - } _POPPLER_FREE(obj1); } @@ -939,42 +936,43 @@ void PdfParser::opSetRenderingIntent(Obj * * 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: @@ -983,7 +981,7 @@ void PdfParser::opSetFillGray(Object arg 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); @@ -995,7 +993,7 @@ void PdfParser::opSetStrokeGray(Object a 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); @@ -1008,7 +1006,7 @@ void PdfParser::opSetFillCMYKColor(Objec 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()); } @@ -1022,7 +1020,7 @@ void PdfParser::opSetStrokeCMYKColor(Obj 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()); } @@ -1036,7 +1034,7 @@ void PdfParser::opSetFillRGBColor(Object 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()); } @@ -1049,7 +1047,7 @@ void PdfParser::opSetStrokeRGBColor(Obje 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()); } @@ -1061,14 +1059,14 @@ void PdfParser::opSetStrokeRGBColor(Obje 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 { @@ -1082,14 +1080,14 @@ void PdfParser::opSetStrokeColorSpace(Ob 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 { @@ -1152,7 +1150,7 @@ void PdfParser::opSetFillColorN(Object a builder->updateStyle(state); } if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) { - state->setFillPattern(pattern); + state->setFillPattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern)); builder->updateStyle(state); } @@ -1195,7 +1193,7 @@ void PdfParser::opSetStrokeColorN(Object builder->updateStyle(state); } if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) { - state->setStrokePattern(pattern); + state->setStrokePattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern)); builder->updateStyle(state); } @@ -1572,11 +1570,11 @@ void PdfParser::doShadingPatternFillFall // 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; } @@ -1608,19 +1606,19 @@ void PdfParser::opShFill(Object args[], // 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; } @@ -1629,8 +1627,6 @@ void PdfParser::opShFill(Object args[], restoreState(); state->setPath(savedPath); } - - delete shading; } void PdfParser::doFunctionShFill(GfxFunctionShading *shading) { @@ -2411,7 +2407,8 @@ void PdfParser::doImage(Object * /*ref*/ // get info from the stream bits = 0; csMode = streamCSNone; - str->getImageParams(&bits, &csMode); + bool hasAlpha = false; + str->getImageParams(&bits, &csMode, &hasAlpha); // get stream dict dict = str->getDict(); @@ -2521,7 +2518,7 @@ void PdfParser::doImage(Object * /*ref*/ } 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); @@ -2530,13 +2527,11 @@ void PdfParser::doImage(Object * /*ref*/ 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) { @@ -2547,10 +2542,9 @@ void PdfParser::doImage(Object * /*ref*/ _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; } @@ -2561,7 +2555,7 @@ void PdfParser::doImage(Object * /*ref*/ 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; @@ -2617,7 +2611,7 @@ void PdfParser::doImage(Object * /*ref*/ _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; @@ -2627,10 +2621,9 @@ void PdfParser::doImage(Object * /*ref*/ _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 @@ -2711,17 +2704,15 @@ void PdfParser::doImage(Object * /*ref*/ // 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); @@ -2739,7 +2730,6 @@ void PdfParser::doForm(Object *str, doub { Dict *dict; GBool transpGroup, isolated, knockout; - GfxColorSpace *blendingColorSpace; Object matrixObj, bboxObj; double m[6], bbox[4]; Object resObj; @@ -2805,12 +2795,12 @@ void PdfParser::doForm(Object *str, doub // 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()) { @@ -2828,12 +2818,9 @@ void PdfParser::doForm(Object *str, doub // 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 -Naurp inkscape-1.4_2024-10-09_e7c3feb100.orig/src/extension/internal/pdfinput/pdf-parser.h inkscape-1.4_2024-10-09_e7c3feb100/src/extension/internal/pdfinput/pdf-parser.h --- inkscape-1.4_2024-10-09_e7c3feb100.orig/src/extension/internal/pdfinput/pdf-parser.h 2024-04-22 16:00:30.000000000 -0500 +++ inkscape-1.4_2024-10-09_e7c3feb100/src/extension/internal/pdfinput/pdf-parser.h 2024-12-03 15:37:46.590558735 -0600 @@ -138,7 +138,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(); @@ -177,7 +177,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 -Naurp inkscape-1.4_2024-10-09_e7c3feb100.orig/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp inkscape-1.4_2024-10-09_e7c3feb100/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp --- inkscape-1.4_2024-10-09_e7c3feb100.orig/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp 2024-04-22 16:00:30.000000000 -0500 +++ inkscape-1.4_2024-10-09_e7c3feb100/src/extension/internal/pdfinput/poppler-cairo-font-engine.cpp 2024-12-03 15:37:51.513566190 -0600 @@ -421,9 +421,9 @@ CairoFreeTypeFont *CairoFreeTypeFont::cr 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; @@ -446,9 +446,9 @@ CairoFreeTypeFont *CairoFreeTypeFont::cr 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"); @@ -514,9 +514,9 @@ CairoFreeTypeFont *CairoFreeTypeFont::cr 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()) { diff -Naurp inkscape-1.4_2024-10-09_e7c3feb100.orig/src/extension/internal/pdfinput/poppler-transition-api.h inkscape-1.4_2024-10-09_e7c3feb100/src/extension/internal/pdfinput/poppler-transition-api.h --- inkscape-1.4_2024-10-09_e7c3feb100.orig/src/extension/internal/pdfinput/poppler-transition-api.h 2024-05-22 13:57:29.000000000 -0500 +++ inkscape-1.4_2024-10-09_e7c3feb100/src/extension/internal/pdfinput/poppler-transition-api.h 2024-12-03 15:37:46.590558735 -0600 @@ -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()))