desktop/source/lib/init.cxx | 1 filter/source/svg/svgexport.cxx | 6 +++ filter/source/svg/svgfilter.cxx | 55 ++++++++++++++++++++---------------- filter/source/svg/svgfilter.hxx | 1 filter/source/svg/svgwriter.cxx | 25 +++++++++++++++- filter/source/svg/svgwriter.hxx | 2 + sfx2/source/doc/objstor.cxx | 16 ++++++++++ sw/inc/cmdid.h | 1 sw/inc/unoprnms.hxx | 1 sw/source/core/unocore/unoframe.cxx | 16 +++++++++- sw/source/core/unocore/unomap1.cxx | 1 11 files changed, 98 insertions(+), 27 deletions(-)
New commits: commit d3cf630e91a5bab204de8d4b7d3429054d6d8aac Author: Stephan Bergmann <sberg...@redhat.com> AuthorDate: Sun Feb 6 18:36:12 2022 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Feb 20 14:18:49 2022 +0100 Missing initialization of SVGActionWriter::mbIsPreview ...introduced with f609a16a52f1ac37f1edd297cf1d9e5f2a294724 "lok: render image preview with lower resolution", > /filter/source/svg/svgwriter.cxx:2949:9: runtime error: load of value 190, which is not a valid value for type 'bool' > #0 0x2b2ee3c573d5 in SVGActionWriter::ImplWriteBmp(BitmapEx const&, Point const&, Size const&, Point const&, Size const&, com::sun::star::uno::Reference<com::sun::star::drawing::XShape> const*) /filter/source/svg/svgwriter.cxx:2949:9 > #1 0x2b2ee3c3b670 in SVGActionWriter::ImplWriteActions(GDIMetaFile const&, unsigned int, rtl::OUString const&, com::sun::star::uno::Reference<com::sun::star::drawing::XShape> const*, GDIMetaFile const*) /filter/source/svg/svgwriter.cxx:3782:25 > #2 0x2b2ee3c5b3a8 in SVGActionWriter::WriteMetaFile(Point const&, Size const&, GDIMetaFile const&, unsigned int, rtl::OUString const&, com::sun::star::uno::Reference<com::sun::star::drawing::XShape> const*, GDIMetaFile const*) /filter/source/svg/svgwriter.cxx:4015:5 > #3 0x2b2ee3a86ae2 in SVGFilter::implExportShape(com::sun::star::uno::Reference<com::sun::star::drawing::XShape> const&, bool) /filter/source/svg/svgexport.cxx:2227:42 > #4 0x2b2ee3a7e1e2 in SVGFilter::implExportShapes(com::sun::star::uno::Reference<com::sun::star::drawing::XShapes> const&, bool) /filter/source/svg/svgexport.cxx:2050:20 during CppunitTest_sd_svg_export_tests (<https://ci.libreoffice.org/job/lo_ubsan/2291/>) Change-Id: Ied5a2cc8599466949f57caae05f9fb90c92266b0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129582 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sberg...@redhat.com> diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index d9c74d0081c3..4ad2d95b4085 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -1815,7 +1815,8 @@ SVGActionWriter::SVGActionWriter( SVGExport& rExport, SVGFontExport& rFontExport mpVDev(VclPtr<VirtualDevice>::Create()), mbClipAttrChanged( false ), mbIsPlaceholderShape( false ), - mpEmbeddedBitmapsMap( nullptr ) + mpEmbeddedBitmapsMap( nullptr ), + mbIsPreview( false ) { mpVDev->EnableOutput( false ); maTargetMapMode = MapMode(MapUnit::Map100thMM); commit b2f4d1a3f345bd5439143f5260d7610fa8f32595 Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Mon Jan 31 17:15:21 2022 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Sun Feb 20 14:18:35 2022 +0100 lok: render image preview with lower resolution renderShapeSelection callback is used to render image previews which are later used during eg. rotation. Do not render preview with original size which slows down app a lot. Use 1280x720 max. Change-Id: Ia8365a67d87cea869ef74cb70ce4830439a523b6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129376 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129497 Tested-by: Jenkins Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 719013274be3..91a4d80ca128 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -3960,6 +3960,7 @@ static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOu } aMediaDescriptor["SelectionOnly"] <<= true; aMediaDescriptor["OutputStream"] <<= xOut; + aMediaDescriptor["IsPreview"] <<= true; // will down-scale graphics xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList()); diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx index 260de5b56d17..cd8675877e49 100644 --- a/filter/source/svg/svgexport.cxx +++ b/filter/source/svg/svgexport.cxx @@ -798,7 +798,9 @@ bool SVGFilter::implExportWriterTextGraphic( const Reference< view::XSelectionSu const Graphic aOriginalGraphic(xOriginalGraphic); uno::Reference<graphic::XGraphic> xTransformedGraphic; - xPropertySet->getPropertyValue("TransformedGraphic") >>= xTransformedGraphic; + xPropertySet->getPropertyValue( + mbIsPreview ? OUString("GraphicPreview") : OUString("TransformedGraphic")) + >>= xTransformedGraphic; if (!xTransformedGraphic.is()) return false; @@ -974,6 +976,8 @@ bool SVGFilter::implExportDocument() mpSVGWriter->SetEmbeddedBitmapRefs( &maBitmapActionMap ); implExportTiledBackground(); } + if( mbIsPreview ) + mpSVGWriter->SetPreviewMode(); // #i124608# export a given object selection, so no MasterPage export at all if (!mbExportShapeSelection) diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx index 359bd34e3dd8..db5488064712 100644 --- a/filter/source/svg/svgfilter.cxx +++ b/filter/source/svg/svgfilter.cxx @@ -76,6 +76,7 @@ SVGFilter::SVGFilter( const Reference< XComponentContext >& rxCtx ) : mnVisiblePage( -1 ), mpObjects( nullptr ), mbExportShapeSelection(false), + mbIsPreview(false), mbWriterFilter(false), mbCalcFilter(false), mbImpressFilter(false), @@ -102,35 +103,43 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto if(mxDstDoc.is()) // Import works for Impress / draw only return filterImpressOrDraw(rDescriptor); - if(mxSrcDoc.is()) + if(!mxSrcDoc) + return false; + + for (const PropertyValue& rProp : rDescriptor) + { + if (rProp.Name == "IsPreview") + { + rProp.Value >>= mbIsPreview; + break; + } + } + + for (const PropertyValue& rProp : rDescriptor) { - for (const PropertyValue& rProp : rDescriptor) + if (rProp.Name == "FilterName") { - if (rProp.Name == "FilterName") + OUString sFilterName; + rProp.Value >>= sFilterName; + if(sFilterName == "impress_svg_Export") { - OUString sFilterName; - rProp.Value >>= sFilterName; - if(sFilterName == "impress_svg_Export") - { - mbImpressFilter = true; - return filterImpressOrDraw(rDescriptor); - } - else if(sFilterName == "writer_svg_Export") - { - mbWriterFilter = true; - return filterWriterOrCalc(rDescriptor); - } - else if(sFilterName == "calc_svg_Export") - { - mbCalcFilter = true; - return filterWriterOrCalc(rDescriptor); - } - break; + mbImpressFilter = true; + return filterImpressOrDraw(rDescriptor); } + else if(sFilterName == "writer_svg_Export") + { + mbWriterFilter = true; + return filterWriterOrCalc(rDescriptor); + } + else if(sFilterName == "calc_svg_Export") + { + mbCalcFilter = true; + return filterWriterOrCalc(rDescriptor); + } + break; } - return filterImpressOrDraw(rDescriptor); } - return false; + return filterImpressOrDraw(rDescriptor); } bool SVGFilter::filterImpressOrDraw( const Sequence< PropertyValue >& rDescriptor ) diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx index eb889e81662e..93e14ec41671 100644 --- a/filter/source/svg/svgfilter.hxx +++ b/filter/source/svg/svgfilter.hxx @@ -209,6 +209,7 @@ private: Sequence< PropertyValue > maFilterData; Reference< css::drawing::XDrawPage > mxDefaultPage; std::vector< Reference< css::drawing::XDrawPage > > mSelectedPages; + bool mbIsPreview; bool mbWriterFilter; bool mbCalcFilter; diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index 6178da0549db..d9c74d0081c3 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -2943,7 +2943,27 @@ void SVGActionWriter::ImplWriteBmp( const BitmapEx& rBmpEx, } } - if( !(bCached || GraphicConverter::Export( aOStm, rBmpEx, ConvertDataFormat::PNG ) == ERRCODE_NONE) ) + const BitmapEx* pBitmap = &rBmpEx; + std::unique_ptr<BitmapEx> pNewBitmap; + + // for preview we generate downscaled images (1280x720 max) + if (mbIsPreview) + { + Size aSize = rBmpEx.GetSizePixel(); + double fX = static_cast<double>(aSize.getWidth()) / 1280; + double fY = static_cast<double>(aSize.getHeight()) / 720; + double fFactor = fX > fY ? fX : fY; + if (fFactor > 1.0) + { + aSize.setWidth(aSize.getWidth() / fFactor); + aSize.setHeight(aSize.getHeight() / fFactor); + pNewBitmap = std::make_unique<BitmapEx>(rBmpEx); + pNewBitmap->Scale(aSize); + pBitmap = pNewBitmap.get(); + } + } + + if( !(bCached || GraphicConverter::Export( aOStm, *pBitmap, ConvertDataFormat::PNG ) == ERRCODE_NONE) ) return; Point aPt; diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx index fdfcd24d32b2..d48d68bdec72 100644 --- a/filter/source/svg/svgwriter.hxx +++ b/filter/source/svg/svgwriter.hxx @@ -318,6 +318,7 @@ private: bool mbClipAttrChanged; bool mbIsPlaceholderShape; const MetaBitmapActionMap* mpEmbeddedBitmapsMap; + bool mbIsPreview; tools::Long ImplMap( sal_Int32 nVal ) const; @@ -377,6 +378,7 @@ public: void SetEmbeddedBitmapRefs( const MetaBitmapActionMap* pEmbeddedBitmapsMap ); void StartMask(const Point& rDestPt, const Size& rDestSize, const Gradient& rGradient, sal_uInt32 nWriteFlags, OUString* pTextStyle = nullptr); + void SetPreviewMode(bool bState = true) { mbIsPreview = bState; } }; diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 06602206cfe9..548ce34b1c21 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -2411,6 +2411,7 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium ) bool bHasBaseURL = false; bool bHasFilterName = false; bool bIsRedactMode = false; + bool bIsPreview = false; sal_Int32 nEnd = aOldArgs.getLength(); for ( sal_Int32 i = 0; i < nEnd; i++ ) @@ -2428,6 +2429,13 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium ) bHasFilterName = true; } + const css::uno::Sequence<css::beans::PropertyValue>& rMediumArgs = rMedium.GetArgs(); + for ( sal_Int32 i = 0; i < rMediumArgs.getLength(); i++ ) + { + if( rMediumArgs[i].Name == "IsPreview" ) + rMediumArgs[i].Value >>= bIsPreview; + } + // FIXME: Handle this inside TransformItems() if (pItems->GetItemState(SID_IS_REDACT_MODE) == SfxItemState::SET) bIsRedactMode = true; @@ -2473,6 +2481,14 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium ) pArgs[nEnd-1].Value <<= bIsRedactMode; } + if (bIsPreview) + { + aArgs.realloc( ++nEnd ); + auto pArgs = aArgs.getArray(); + pArgs[nEnd-1].Name = "IsPreview"; + pArgs[nEnd-1].Value <<= bIsPreview; + } + return xFilter->filter( aArgs ); }catch(...) {} diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index ef4e79e7225c..687f5980d81d 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -633,6 +633,7 @@ #define FN_UNO_VISIBLE_AREA_HEIGHT (FN_EXTRA2 + 126) #define FN_UNO_TRANSFORMED_GRAPHIC (FN_EXTRA2 + 127) +#define FN_UNO_GRAPHIC_PREVIEW (FN_EXTRA2 + 128) // Area: Help // Region: Traveling & Selection diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 7ef5d0a58cd7..5d8684c47f53 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -160,6 +160,7 @@ #define UNO_NAME_FILE_LINK "FileLink" #define UNO_NAME_GRAPHIC "Graphic" #define UNO_NAME_TRANSFORMED_GRAPHIC "TransformedGraphic" +#define UNO_NAME_GRAPHIC_PREVIEW "GraphicPreview" #define UNO_NAME_IS_PROTECTED "IsProtected" #define UNO_NAME_PARA_KEEP_TOGETHER "ParaKeepTogether" #define UNO_NAME_KEEP_TOGETHER "KeepTogether" diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx index 4c35a9248665..6b21f34b25ce 100644 --- a/sw/source/core/unocore/unoframe.cxx +++ b/sw/source/core/unocore/unoframe.cxx @@ -2112,7 +2112,8 @@ uno::Any SwXFrame::getPropertyValue(const OUString& rPropertyName) aAny <<= pGrfNode->GetGrf().GetXGraphic(); } } - else if( FN_UNO_TRANSFORMED_GRAPHIC == pEntry->nWID ) + else if( FN_UNO_TRANSFORMED_GRAPHIC == pEntry->nWID + || FN_UNO_GRAPHIC_PREVIEW == pEntry->nWID ) { const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx(); if(pIdx) @@ -2136,6 +2137,19 @@ uno::Any SwXFrame::getPropertyValue(const OUString& rPropertyName) awt::Size aFrameSize = getSize(); Size aSize100thmm(aFrameSize.Width, aFrameSize.Height); Size aSize = OutputDevice::LogicToLogic(aSize100thmm, MapMode(MapUnit::Map100thMM), aGraphicObj.GetPrefMapMode()); + + if (FN_UNO_GRAPHIC_PREVIEW == pEntry->nWID) + { + double fX = static_cast<double>(aSize.getWidth()) / 1280; + double fY = static_cast<double>(aSize.getHeight()) / 720; + double fFactor = fX > fY ? fX : fY; + if (fFactor > 1.0) + { + aSize.setWidth(aSize.getWidth() / fFactor); + aSize.setHeight(aSize.getHeight() / fFactor); + } + } + Graphic aGraphic = aGraphicObj.GetTransformedGraphic(aSize, aGraphicObj.GetPrefMapMode(), aGraphicAttr); aAny <<= aGraphic.GetXGraphic(); } diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx index 9a186b05d280..3e2bb53faab5 100644 --- a/sw/source/core/unocore/unomap1.cxx +++ b/sw/source/core/unocore/unomap1.cxx @@ -818,6 +818,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetGraphicPropertyMap( { u"" UNO_NAME_GRAPHIC, FN_UNO_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 }, { u"" UNO_NAME_GRAPHIC_URL, FN_UNO_GRAPHIC_URL, cppu::UnoType<css::uno::Any>::get(), 0, 0 }, { u"" UNO_NAME_TRANSFORMED_GRAPHIC, FN_UNO_TRANSFORMED_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 }, + { u"" UNO_NAME_GRAPHIC_PREVIEW, FN_UNO_GRAPHIC_PREVIEW, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 }, { u"" UNO_NAME_ACTUAL_SIZE, FN_UNO_ACTUAL_SIZE, cppu::UnoType<css::awt::Size>::get(), PropertyAttribute::READONLY, CONVERT_TWIPS}, { u"" UNO_NAME_CONTOUR_POLY_POLYGON, FN_PARAM_CONTOUR_PP, cppu::UnoType<css::drawing::PointSequenceSequence>::get(), PropertyAttribute::MAYBEVOID, 0 }, { u"" UNO_NAME_IS_PIXEL_CONTOUR, FN_UNO_IS_PIXEL_CONTOUR, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },