desktop/source/lib/init.cxx         |    1 +
 filter/source/svg/svgexport.cxx     |    6 +++++-
 filter/source/svg/svgfilter.cxx     |   10 ++++++++++
 filter/source/svg/svgfilter.hxx     |    1 +
 filter/source/svg/svgwriter.cxx     |   22 +++++++++++++++++++++-
 filter/source/svg/svgwriter.hxx     |    2 ++
 sfx2/source/doc/objstor.cxx         |   15 +++++++++++++++
 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, 73 insertions(+), 3 deletions(-)

New commits:
commit d01b1b174f4e18b8bef23f7409d4e9cf4f07d232
Author:     Szymon Kłos <[email protected]>
AuthorDate: Mon Jan 31 17:15:21 2022 +0100
Commit:     Szymon Kłos <[email protected]>
CommitDate: Thu Feb 3 10:06:16 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
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Szymon Kłos <[email protected]>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 920041060d88..4693e79ec3f6 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3969,6 +3969,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 fc8de3b18f68..d0eb6b9c6a8c 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -802,7 +802,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;
@@ -978,6 +980,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 8025550b5837..67ff2dd80680 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -82,6 +82,7 @@ SVGFilter::SVGFilter( const Reference< XComponentContext >& 
rxCtx ) :
     mbExportShapeSelection(false),
     maFilterData(),
     mxDefaultPage(),
+    mbIsPreview(false),
     mbWriterFilter(false),
     mbCalcFilter(false),
     mbImpressFilter(false),
@@ -111,6 +112,15 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< 
PropertyValue >& rDescripto
 
     if(mxSrcDoc.is())
     {
+        for (const PropertyValue& rProp : rDescriptor)
+        {
+            if (rProp.Name == "IsPreview")
+            {
+                rProp.Value >>= mbIsPreview;
+                break;
+            }
+        }
+
         for (const PropertyValue& rProp : rDescriptor)
         {
             if (rProp.Name == "FilterName")
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index aab158971e0b..975eb4ae2d02 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 f5c96878d4f4..9677c9e092fd 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -2949,7 +2949,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 a052fba16e87..57c261fad7a5 100644
--- a/filter/source/svg/svgwriter.hxx
+++ b/filter/source/svg/svgwriter.hxx
@@ -319,6 +319,7 @@ private:
     bool                                        mbClipAttrChanged;
     bool                                        mbIsPlaceholderShape;
     const MetaBitmapActionMap*                  mpEmbeddedBitmapsMap;
+    bool                                        mbIsPreview;
 
 
     tools::Long                    ImplMap( sal_Int32 nVal ) const;
@@ -378,6 +379,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 9b696bdc0bcb..7ccee4f3a970 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;
@@ -2468,6 +2476,13 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium )
             aArgs[nEnd-1].Value <<= bIsRedactMode;
         }
 
+        if (bIsPreview)
+        {
+            aArgs.realloc( ++nEnd );
+            aArgs[nEnd-1].Name = "IsPreview";
+            aArgs[nEnd-1].Value <<= bIsPreview;
+        }
+
         return xFilter->filter( aArgs );
         }catch(...)
         {}
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index 6913de65c595..7eb7e1b347f2 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -632,6 +632,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 987e913a03f8..321fdcf59897 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -159,6 +159,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 a73b8e74fa95..775219183977 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -2095,7 +2095,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)
@@ -2119,6 +2120,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 07212a10f0e4..45b64220fda6 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -817,6 +817,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 },

Reply via email to