diff --git a/configure.ac b/configure.ac index c2b896b9c..33c86ba6e 100644 --- a/configure.ac +++ b/configure.ac @@ -12816,9 +12816,9 @@ then qt5_test_include="QtWidgets/qapplication.h" if test "$_os" = "Emscripten"; then - qt5_test_library="libQt5Widgets.a" + qt5_test_library="libQt5Svg.a" else - qt5_test_library="libQt5Widgets.so" + qt5_test_library="libQt5Svg.so" fi dnl Check for qmake5 @@ -12893,7 +12893,7 @@ then QT5_CFLAGS="-I$qt5_incdir -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT -DQT_NO_VERSION_TAGGING" QT5_CFLAGS=$(printf '%s' "$QT5_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") - QT5_LIBS="-L$qt5_libdir -lQt5Core -lQt5Gui -lQt5Widgets -lQt5Network" + QT5_LIBS="-L$qt5_libdir -lQt5Core -lQt5Gui -lQt5Widgets -lQt5Network -lQt5Svg" if test "$_os" = "Emscripten"; then QT5_LIBS="$QT5_LIBS -lqtpcre2 -lQt5EventDispatcherSupport -lQt5FontDatabaseSupport -L${qt5_platformsdir} -lqwasm" fi diff --git a/svx/source/tbxctrls/tbxcolorupdate.cxx b/svx/source/tbxctrls/tbxcolorupdate.cxx index f9ca173d6..cf6fde443 100644 --- a/svx/source/tbxctrls/tbxcolorupdate.cxx +++ b/svx/source/tbxctrls/tbxcolorupdate.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -163,6 +164,17 @@ namespace svx auto xImage = vcl::CommandInfoProvider::GetXGraphicForCommand(maCommandURL, mxFrame, meImageType); Image aImage(xImage); + BitmapEx aBitmapEx = aImage.GetBitmapEx(); + if (aBitmapEx.GetBitmap().getPixelFormat() == vcl::PixelFormat::N32_BPP) + { + BitmapEx aBitmapExConverted; + + if (!vcl::bitmap::convertBitmap32To24Plus8(aBitmapEx, aBitmapExConverted)) + return; + + aImage = Image(aBitmapExConverted); + } + Size aItemSize = GetItemSize(aImage.GetSizePixel()); if (!aItemSize.Width() || !aItemSize.Height()) return; diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx index 9a9853a7a..886ace665 100644 --- a/vcl/inc/qt5/QtInstance.hxx +++ b/vcl/inc/qt5/QtInstance.hxx @@ -137,6 +137,8 @@ public: virtual SalTimer* CreateSalTimer() override; virtual SalSystem* CreateSalSystem() override; virtual std::shared_ptr CreateSalBitmap() override; + virtual bool LoadImageFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx, + double fScalingFactor) override; virtual bool DoYield(bool bWait, bool bHandleAllCurrentEvents) override; virtual bool AnyInput(VclInputFlags nType) override; diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx index 7d42cb510..25da96234 100644 --- a/vcl/inc/salinst.hxx +++ b/vcl/inc/salinst.hxx @@ -68,6 +68,7 @@ struct SystemWindowData; class Menu; enum class VclInputFlags; enum class SalFrameStyleFlags; +class BitmapEx; typedef struct _cairo_font_options cairo_font_options_t; @@ -133,6 +134,7 @@ public: virtual SalSystem* CreateSalSystem() = 0; // SalBitmap virtual std::shared_ptr CreateSalBitmap() = 0; + virtual bool LoadImageFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx, double fScalingFactor); // YieldMutex comphelper::SolarMutex* GetYieldMutex(); diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx index d252109e1..b48b6ce98 100644 --- a/vcl/qt5/QtInstance.cxx +++ b/vcl/qt5/QtInstance.cxx @@ -21,6 +21,9 @@ #include #include +#include +#include +#include #include #include @@ -34,6 +37,7 @@ #include "QtSvpVirtualDevice.hxx" #include #include +#include #include #include @@ -41,11 +45,18 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -397,6 +408,81 @@ std::shared_ptr QtInstance::CreateSalBitmap() return std::make_shared(); } +bool QtInstance::LoadImageFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx, + double fScalingFactor) +{ + using namespace ::com::sun::star; + using drawinglayer::primitive2d::Primitive2DSequence; + using drawinglayer::primitive2d::Primitive2DReference; + + uno::Reference xContext(comphelper::getProcessComponentContext()); + const uno::Reference xSvgParser = graphic::SvgTools::create(xContext); + + std::size_t nSize = rStream.remainingSize(); + std::vector aBuffer(nSize + 1); + rStream.ReadBytes(aBuffer.data(), nSize); + aBuffer[nSize] = 0; + + uno::Sequence aData(aBuffer.data(), nSize + 1); + uno::Reference aInputStream(new comphelper::SequenceInputStream(aData)); + + const Primitive2DSequence aPrimitiveSequence + = xSvgParser->getDecomposition(aInputStream, sPath); + + if (!aPrimitiveSequence.hasElements()) + return false; + + uno::Sequence aViewParameters; + + basegfx::B2DRange aRange; + for (Primitive2DReference const& xReference : aPrimitiveSequence) + { + if (xReference.is()) + { + geometry::RealRectangle2D aRealRect; + aRealRect = xReference->getRange(aViewParameters); + aRange.expand( + basegfx::B2DRange(aRealRect.X1, aRealRect.Y1, aRealRect.X2, aRealRect.Y2)); + } + } + + const basegfx::B2DRange aRealRect(aRange.getMinX(), aRange.getMinY(), aRange.getMaxX(), + aRange.getMaxY()); + + double nDPI = 96 * fScalingFactor; + + o3tl::Length eRangeUnit = o3tl::Length::mm100; + comphelper::SequenceAsHashMap aViewInformationMap(aViewParameters); + auto it = aViewInformationMap.find("RangeUnit"); + if (it != aViewInformationMap.end()) + { + sal_Int32 nVal{}; + it->second >>= nVal; + eRangeUnit = static_cast(nVal); + } + + const sal_uInt32 nDiscreteWidth( + basegfx::fround(o3tl::convert(aRealRect.getWidth(), eRangeUnit, o3tl::Length::in) * nDPI)); + const sal_uInt32 nDiscreteHeight( + basegfx::fround(o3tl::convert(aRealRect.getHeight(), eRangeUnit, o3tl::Length::in) * nDPI)); + + QImage aImage(nDiscreteWidth, nDiscreteHeight, Qt_DefaultFormat32); + aImage.fill(Qt::transparent); + + { + QSvgRenderer aRenderer( + QByteArray(reinterpret_cast(aBuffer.data()), static_cast(nSize))); + + QPainter aPainter(&aImage); + aRenderer.render(&aPainter); + } + + rBitmapEx = BitmapEx(Bitmap( + std::shared_ptr(new QtBitmap(aImage.convertToFormat(Qt_DefaultFormat32))))); + + return true; +} + bool QtInstance::ImplYield(bool bWait, bool bHandleAllCurrentEvents) { // Re-acquire the guard for user events when called via Q_EMIT ImplYieldSignal diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 20e8db2e7..f1b49de17 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -115,6 +115,8 @@ SalInstance::SalInstance(std::unique_ptr pMutex) SalInstance::~SalInstance() {} +bool SalInstance::LoadImageFromSvg(SvStream&, const OUString&, BitmapEx&, double) { return false; } + comphelper::SolarMutex* SalInstance::GetYieldMutex() { return m_pYieldMutex.get(); } sal_uInt32 SalInstance::ReleaseYieldMutexAll() { return m_pYieldMutex->release(true); } diff --git a/vcl/source/image/ImplImageTree.cxx b/vcl/source/image/ImplImageTree.cxx index a54514eb4..a0460ea09 100644 --- a/vcl/source/image/ImplImageTree.cxx +++ b/vcl/source/image/ImplImageTree.cxx @@ -57,6 +57,9 @@ #include +#include +#include + using namespace css; bool ImageRequestParameters::convertToDarkTheme() @@ -169,7 +172,15 @@ void loadImageFromStream(std::shared_ptr const & xStream, OUString con else if (rPath.endsWith(".svg")) { rParameters.mbWriteImageToCache = true; // We always want to cache a SVG image - vcl::bitmap::loadFromSvg(*xStream, rPath, rParameters.mrBitmap, aScalePercentage / 100.0); + + bool bLoadedSvg = false; + + ImplSVData *pSVData = ImplGetSVData(); + if (pSVData && pSVData->mpDefInst) + bLoadedSvg = pSVData->mpDefInst->LoadImageFromSvg(*xStream, rPath, rParameters.mrBitmap, aScalePercentage / 100.0); + + if (!bLoadedSvg) + vcl::bitmap::loadFromSvg(*xStream, rPath, rParameters.mrBitmap, aScalePercentage / 100.0); if (bConvertToDarkTheme) BitmapFilter::Filter(rParameters.mrBitmap, BitmapLightenFilter()); diff --git a/vcl/unx/kf5/KF5SalInstance.cxx b/vcl/unx/kf5/KF5SalInstance.cxx index efcfd0963..c2db0a3c9 100644 --- a/vcl/unx/kf5/KF5SalInstance.cxx +++ b/vcl/unx/kf5/KF5SalInstance.cxx @@ -88,6 +88,11 @@ KF5SalInstance::createPicker(css::uno::Reference co return QtInstance::createPicker(context, eMode); } +bool KF5SalInstance::LoadImageFromSvg(SvStream&, const OUString&, BitmapEx&, double) +{ + return false; +} + extern "C" { VCLPLUG_KF5_PUBLIC SalInstance* create_SalInstance() { diff --git a/vcl/unx/kf5/KF5SalInstance.hxx b/vcl/unx/kf5/KF5SalInstance.hxx index add3b112a..84e34229a 100644 --- a/vcl/unx/kf5/KF5SalInstance.hxx +++ b/vcl/unx/kf5/KF5SalInstance.hxx @@ -33,6 +33,9 @@ class KF5SalInstance final : public QtInstance public: explicit KF5SalInstance(std::unique_ptr& pQApp, bool bUseCairo); + + virtual bool LoadImageFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx, + double fScalingFactor) override; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */