[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - filter/source include/vcl offapi/com sd/qa vcl/inc vcl/source

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Sat Jun 6 17:24:56 UTC 2020


 filter/source/pdf/pdfdecomposer.cxx            |   28 ++++++++++++++++----
 include/vcl/graph.hxx                          |    2 -
 include/vcl/vectorgraphicdata.hxx              |   12 +++++---
 offapi/com/sun/star/graphic/XPdfDecomposer.idl |    8 +++++
 sd/qa/unit/import-tests.cxx                    |   15 ++++++-----
 vcl/inc/impgraph.hxx                           |    7 +----
 vcl/source/filter/ipdf/pdfread.cxx             |   18 +++----------
 vcl/source/gdi/graph.cxx                       |    7 -----
 vcl/source/gdi/impgraph.cxx                    |   34 ++++++++++---------------
 vcl/source/gdi/vectorgraphicdata.cxx           |   22 ++++++++++++----
 10 files changed, 85 insertions(+), 68 deletions(-)

New commits:
commit c298489ba242b298e09e78069587e6f4707614af
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Fri Mar 13 20:04:45 2020 +0100
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Sat Jun 6 19:24:24 2020 +0200

    pdfium: support for pages when using PDF import with pdfium
    
    Moving PDF to use VectorGraphicData in Graphic has temporary
    removed the support for showing different PDF pages when opening
    the PDF using pdfium (LO_IMPORT_USE_PDFIUM=1).
    This adds the support for back by specifying whcih PDF page to
    render when creating the VectorGraphicData (and can't be changd
    afterwards), which is used to create a Graphic and contains the
    PDF source data array.
    
    Change-Id: Ib915216b8d4c0c063d0fead44ff156b1915a35d2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90562
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    (cherry picked from commit 27ee05f860e8225a41e15e0853fcef00a9d7a621)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95628
    Tested-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/filter/source/pdf/pdfdecomposer.cxx b/filter/source/pdf/pdfdecomposer.cxx
index c926b1b35a9d..a03e70bd5d1a 100644
--- a/filter/source/pdf/pdfdecomposer.cxx
+++ b/filter/source/pdf/pdfdecomposer.cxx
@@ -39,8 +39,9 @@ public:
     XPdfDecomposer& operator=(const XPdfDecomposer&) = delete;
 
     // XPdfDecomposer
-    uno::Sequence<uno::Reference<graphic::XPrimitive2D>>
-        SAL_CALL getDecomposition(const uno::Sequence<sal_Int8>& xPdfData) override;
+    uno::Sequence<uno::Reference<graphic::XPrimitive2D>> SAL_CALL
+    getDecomposition(const uno::Sequence<sal_Int8>& xPdfData,
+                     const uno::Sequence<beans::PropertyValue>& xDecompositionParameters) override;
 
     // XServiceInfo
     OUString SAL_CALL getImplementationName() override;
@@ -50,12 +51,27 @@ public:
 
 XPdfDecomposer::XPdfDecomposer(uno::Reference<uno::XComponentContext> const&) {}
 
-uno::Sequence<uno::Reference<graphic::XPrimitive2D>>
-    SAL_CALL XPdfDecomposer::getDecomposition(const uno::Sequence<sal_Int8>& xPdfData)
+uno::Sequence<uno::Reference<graphic::XPrimitive2D>> SAL_CALL XPdfDecomposer::getDecomposition(
+    const uno::Sequence<sal_Int8>& xPdfData, const uno::Sequence<beans::PropertyValue>& xParameters)
 {
+    sal_Int32 nPageIndex = -1;
+
+    for (sal_Int32 index = 0; index < xParameters.getLength(); index++)
+    {
+        const beans::PropertyValue& rProperty = xParameters[index];
+
+        if (rProperty.Name == "PageIndex")
+        {
+            rProperty.Value >>= nPageIndex;
+        }
+    }
+
+    if (nPageIndex < 0)
+        nPageIndex = 0;
+
     std::vector<Bitmap> aBitmaps;
-    vcl::RenderPDFBitmaps(xPdfData.getConstArray(), xPdfData.getLength(), aBitmaps, 0,
-                          1 /*, fResolutionDPI*/);
+    vcl::RenderPDFBitmaps(xPdfData.getConstArray(), xPdfData.getLength(), aBitmaps, nPageIndex, 1);
+
     BitmapEx aReplacement(aBitmaps[0]);
 
     // short form for scale and translate transformation
diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx
index 6e372a0bbaf9..fda9027cbd1f 100644
--- a/include/vcl/graph.hxx
+++ b/include/vcl/graph.hxx
@@ -204,8 +204,6 @@ public:
 
     const VectorGraphicDataPtr& getVectorGraphicData() const;
 
-    /// Set the page number of the multi-page source this Graphic is rendered from.
-    void setPageNumber(sal_Int32 nPageNumber);
     /// Get the page number of the multi-page source this Graphic is rendered from.
     sal_Int32 getPageNumber() const;
 
diff --git a/include/vcl/vectorgraphicdata.hxx b/include/vcl/vectorgraphicdata.hxx
index ce79961b5364..86b0e6e1ad2f 100644
--- a/include/vcl/vectorgraphicdata.hxx
+++ b/include/vcl/vectorgraphicdata.hxx
@@ -70,6 +70,9 @@ private:
     // extra:
     std::unique_ptr<WmfExternal> mpExternalHeader;
 
+    // If the vector format has more pages this denotes which page to render
+    sal_Int32 mnPageIndex;
+
     // on demand creators
     void ensurePdfReplacement();
     void ensureReplacement();
@@ -82,10 +85,9 @@ public:
     VectorGraphicData(
         const VectorGraphicDataArray& rVectorGraphicDataArray,
         const OUString& rPath,
-        VectorGraphicDataType eVectorDataType);
-    VectorGraphicData(
-        const OUString& rPath,
-        VectorGraphicDataType eVectorDataType);
+        VectorGraphicDataType eVectorDataType,
+        sal_Int32 nPageIndex = -1);
+    VectorGraphicData(const OUString& rPath, VectorGraphicDataType eVectorDataType);
     ~VectorGraphicData();
 
     /// compare op
@@ -107,6 +109,8 @@ public:
     const std::deque< css::uno::Reference< css::graphic::XPrimitive2D > >& getPrimitive2DSequence() const;
     const BitmapEx& getReplacement() const;
     BitmapChecksum GetChecksum() const;
+
+    sal_Int32 getPageIndex() const { return mnPageIndex; }
 };
 
 typedef std::shared_ptr< VectorGraphicData > VectorGraphicDataPtr;
diff --git a/offapi/com/sun/star/graphic/XPdfDecomposer.idl b/offapi/com/sun/star/graphic/XPdfDecomposer.idl
index 85b38c035c8c..aae6eda55347 100644
--- a/offapi/com/sun/star/graphic/XPdfDecomposer.idl
+++ b/offapi/com/sun/star/graphic/XPdfDecomposer.idl
@@ -27,9 +27,15 @@ interface XPdfDecomposer : ::com::sun::star::uno::XInterface
         @param xPdfData
         The PDF data.
 
+        @param xDecompositionParameters
+        Parameters for decomposition. Parameters include:
+
+        sal_Int32 Page - which page to use
+
         @since LibreOffice 7.0
      */
-    sequence<XPrimitive2D> getDecomposition([in] sequence<byte> xPdfData);
+    sequence<XPrimitive2D> getDecomposition([in] sequence<byte> xPdfData,
+                                            [in] sequence<com::sun::star::beans::PropertyValue> xDecompositionParameters);
 };
 
 }; }; }; };
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index df56d7d68838..006adedcd588 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -1289,17 +1289,20 @@ void SdImportTest::testPDFImportShared()
 
     CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected more than one page.", size_t(3), aGraphics.size());
 
-    Graphic aFirstGraphic = aGraphics[0];
+    Graphic const & rFirstGraphic = aGraphics[0];
 
-    for (size_t i = 1; i < aGraphics.size(); ++i)
+    for (size_t i = 0; i < aGraphics.size(); ++i)
     {
+        Graphic const & rGraphic = aGraphics[i];
         CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all PDF streams to be identical.",
-                                     aFirstGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(),
-                                     aGraphics[i].getVectorGraphicData()->getVectorGraphicDataArray().getConstArray());
+                                     rFirstGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(),
+                                     rGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray());
 
         CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all GfxLinks to be identical.",
-                                     aFirstGraphic.GetSharedGfxLink().get(),
-                                     aGraphics[i].GetSharedGfxLink().get());
+                                     rFirstGraphic.GetSharedGfxLink().get(),
+                                     rGraphic.GetSharedGfxLink().get());
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("Page number doesn't match expected", sal_Int32(i), rGraphic.getPageNumber());
     }
 
     xDocShRef->DoClose();
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index d49856011996..251a189c906a 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -77,11 +77,6 @@ private:
     std::chrono::high_resolution_clock::time_point maLastUsed;
     bool mbPrepared;
 
-    /// Used with GfxLink and/or PdfData when they store original media
-    /// which might be multi-page (PDF, f.e.) and we need to re-render
-    /// this Graphic (a page) from the source in GfxLink or PdfData.
-    sal_Int32                    mnPageNumber;
-
 public:
     ImpGraphic();
     ImpGraphic( const ImpGraphic& rImpGraphic );
@@ -208,6 +203,8 @@ private:
     bool ensureAvailable () const;
 
     bool loadPrepared();
+
+    sal_Int32 getPageNumber() const;
 };
 
 #endif // INCLUDED_VCL_INC_IMPGRAPH_HXX
diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index b960c41483ec..b734a7bc4420 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -223,19 +223,12 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBi
 
 bool ImportPDF(SvStream& rStream, Graphic& rGraphic)
 {
-    // Save the original PDF stream for later use.
-    SvMemoryStream aMemoryStream;
-    if (!getCompatibleStream(rStream, aMemoryStream, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END))
-        return false;
-    const sal_uInt32 nStreamLength = aMemoryStream.TellEnd();
-    VectorGraphicDataArray aPdfData(nStreamLength);
-    aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
-    aMemoryStream.ReadBytes(aPdfData.begin(), nStreamLength);
-    if (aMemoryStream.GetError())
+    VectorGraphicDataArray aPdfDataArray = createVectorGraphicDataArray(rStream);
+    if (!aPdfDataArray.hasElements())
         return false;
 
-    auto aVectorGraphicDataPtr
-        = std::make_shared<VectorGraphicData>(aPdfData, OUString(), VectorGraphicDataType::Pdf);
+    auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aPdfDataArray, OUString(),
+                                                                     VectorGraphicDataType::Pdf);
 
     rGraphic = Graphic(aVectorGraphicDataPtr);
     return true;
@@ -291,13 +284,12 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si
         const size_t nPageHeight = pointToPixel(fPageHeight, fResolutionDPI);
 
         auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(
-            aPdfDataArray, OUString(), VectorGraphicDataType::Pdf);
+            aPdfDataArray, OUString(), VectorGraphicDataType::Pdf, nPageIndex);
 
         // Create the Graphic with the VectorGraphicDataPtr and link the original PDF stream.
         // We swap out this Graphic as soon as possible, and a later swap in
         // actually renders the correct Bitmap on demand.
         Graphic aGraphic(aVectorGraphicDataPtr);
-        aGraphic.setPageNumber(nPageIndex);
         aGraphic.SetGfxLink(pGfxLink);
 
         rGraphics.emplace_back(std::move(aGraphic), Size(nPageWidth, nPageHeight));
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
index 250c01f674d0..88a9088b823b 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -560,14 +560,9 @@ const VectorGraphicDataPtr& Graphic::getVectorGraphicData() const
     return mxImpGraphic->getVectorGraphicData();
 }
 
-void Graphic::setPageNumber(sal_Int32 nPageNumber)
-{
-    mxImpGraphic->mnPageNumber = nPageNumber;
-}
-
 sal_Int32 Graphic::getPageNumber() const
 {
-    return mxImpGraphic->mnPageNumber;
+    return mxImpGraphic->getPageNumber();
 }
 
 OUString Graphic::getOriginURL() const
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index f60b165d0084..a8dbb0fb99a7 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -73,8 +73,7 @@ ImpGraphic::ImpGraphic() :
         mbSwapOut       ( false ),
         mbDummyContext  ( false ),
         maLastUsed (std::chrono::high_resolution_clock::now()),
-        mbPrepared      ( false ),
-        mnPageNumber(-1)
+        mbPrepared      ( false )
 {
 }
 
@@ -93,7 +92,6 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic)
     , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
     , maLastUsed (std::chrono::high_resolution_clock::now())
     , mbPrepared (rImpGraphic.mbPrepared)
-    , mnPageNumber(rImpGraphic.mnPageNumber)
 {
     if( rImpGraphic.mpAnimation )
     {
@@ -118,7 +116,6 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) noexcept
     , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
     , maLastUsed (std::chrono::high_resolution_clock::now())
     , mbPrepared (rImpGraphic.mbPrepared)
-    , mnPageNumber(rImpGraphic.mnPageNumber)
 {
     rImpGraphic.ImplClear();
     rImpGraphic.mbDummyContext = false;
@@ -131,8 +128,7 @@ ImpGraphic::ImpGraphic(GraphicExternalLink const & rGraphicExternalLink) :
         mbDummyContext  ( false ),
         maGraphicExternalLink(rGraphicExternalLink),
         maLastUsed (std::chrono::high_resolution_clock::now()),
-        mbPrepared (false),
-        mnPageNumber(-1)
+        mbPrepared (false)
 {
 }
 
@@ -143,8 +139,7 @@ ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) :
         mbSwapOut       ( false ),
         mbDummyContext  ( false ),
         maLastUsed (std::chrono::high_resolution_clock::now()),
-        mbPrepared (false),
-        mnPageNumber(-1)
+        mbPrepared (false)
 {
 }
 
@@ -155,8 +150,7 @@ ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
         mbSwapOut       ( false ),
         mbDummyContext  ( false ),
         maLastUsed (std::chrono::high_resolution_clock::now()),
-        mbPrepared (false),
-        mnPageNumber(-1)
+        mbPrepared (false)
 {
 }
 
@@ -167,8 +161,7 @@ ImpGraphic::ImpGraphic(const VectorGraphicDataPtr& rVectorGraphicDataPtr)
     mbDummyContext  ( false ),
     maVectorGraphicData(rVectorGraphicDataPtr),
     maLastUsed (std::chrono::high_resolution_clock::now()),
-    mbPrepared (false),
-    mnPageNumber(-1)
+    mbPrepared (false)
 {
 }
 
@@ -180,8 +173,7 @@ ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
         mbSwapOut       ( false ),
         mbDummyContext  ( false ),
         maLastUsed (std::chrono::high_resolution_clock::now()),
-        mbPrepared (false),
-        mnPageNumber(-1)
+        mbPrepared (false)
 {
 }
 
@@ -192,8 +184,7 @@ ImpGraphic::ImpGraphic( const GDIMetaFile& rMtf ) :
         mbSwapOut       ( false ),
         mbDummyContext  ( false ),
         maLastUsed (std::chrono::high_resolution_clock::now()),
-        mbPrepared (false),
-        mnPageNumber(-1)
+        mbPrepared (false)
 {
 }
 
@@ -215,7 +206,6 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
         maSwapInfo = rImpGraphic.maSwapInfo;
         mpContext = rImpGraphic.mpContext;
         mbDummyContext = rImpGraphic.mbDummyContext;
-        mnPageNumber = rImpGraphic.mnPageNumber;
         maGraphicExternalLink = rImpGraphic.maGraphicExternalLink;
 
         mpAnimation.reset();
@@ -255,7 +245,6 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic)
     maSwapInfo = std::move(rImpGraphic.maSwapInfo);
     mpContext = std::move(rImpGraphic.mpContext);
     mbDummyContext = rImpGraphic.mbDummyContext;
-    mnPageNumber = rImpGraphic.mnPageNumber;
     mpAnimation = std::move(rImpGraphic.mpAnimation);
     maEx = std::move(rImpGraphic.maEx);
     mbSwapOut = rImpGraphic.mbSwapOut;
@@ -271,8 +260,6 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic)
 
     vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
 
-    rImpGraphic.mnPageNumber = -1;
-
     return *this;
 }
 
@@ -1640,6 +1627,13 @@ bool ImpGraphic::ImplExportNative( SvStream& rOStm ) const
     return bResult;
 }
 
+sal_Int32 ImpGraphic::getPageNumber() const
+{
+    if (maVectorGraphicData)
+        return maVectorGraphicData->getPageIndex();
+    return -1;
+}
+
 static std::map<BitmapChecksum, std::shared_ptr<std::vector<sal_Int8>>> sPdfDataCache;
 
 void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
diff --git a/vcl/source/gdi/vectorgraphicdata.cxx b/vcl/source/gdi/vectorgraphicdata.cxx
index 9d877b35a73a..99e51f65cc71 100644
--- a/vcl/source/gdi/vectorgraphicdata.cxx
+++ b/vcl/source/gdi/vectorgraphicdata.cxx
@@ -33,6 +33,7 @@
 #include <vcl/canvastools.hxx>
 #include <comphelper/seqstream.hxx>
 #include <comphelper/sequence.hxx>
+#include <comphelper/propertysequence.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/outdev.hxx>
 #include <vcl/wmfexternal.hxx>
@@ -146,7 +147,10 @@ void VectorGraphicData::ensurePdfReplacement()
 
     // use PDFium directly
     std::vector<Bitmap> aBitmaps;
-    vcl::RenderPDFBitmaps(maVectorGraphicDataArray.getConstArray(), maVectorGraphicDataArray.getLength(), aBitmaps, 0, 1/*, fResolutionDPI*/);
+    sal_Int32 nUsePageIndex = 0;
+    if (mnPageIndex >= 0)
+        nUsePageIndex = mnPageIndex;
+    vcl::RenderPDFBitmaps(maVectorGraphicDataArray.getConstArray(), maVectorGraphicDataArray.getLength(), aBitmaps, nUsePageIndex, 1/*, fResolutionDPI*/);
     maReplacement = aBitmaps[0];
 }
 
@@ -201,7 +205,9 @@ void VectorGraphicData::ensureSequenceAndRange()
                 uno::Sequence< ::beans::PropertyValue > aSequence;
 
                 if (mpExternalHeader)
+                {
                     aSequence = mpExternalHeader->getSequence();
+                }
 
                 if (myInputStream.is())
                     maSequence = comphelper::sequenceToContainer<std::deque<css::uno::Reference< css::graphic::XPrimitive2D >>>(xEmfParser->getDecomposition(myInputStream, maPath, aSequence));
@@ -211,7 +217,10 @@ void VectorGraphicData::ensureSequenceAndRange()
             case VectorGraphicDataType::Pdf:
             {
                 const uno::Reference<graphic::XPdfDecomposer> xPdfDecomposer = graphic::PdfTools::create(xContext);
-                auto xPrimitive2D = xPdfDecomposer->getDecomposition(maVectorGraphicDataArray);
+                uno::Sequence<beans::PropertyValue> aDecompositionParameters = comphelper::InitPropertySequence({
+                    {"PageIndex", uno::makeAny<sal_Int32>(mnPageIndex)},
+                });
+                auto xPrimitive2D = xPdfDecomposer->getDecomposition(maVectorGraphicDataArray, aDecompositionParameters);
                 maSequence = comphelper::sequenceToContainer<std::deque<uno::Reference<graphic::XPrimitive2D>>>(xPrimitive2D);
 
                 break;
@@ -262,7 +271,8 @@ auto VectorGraphicData::getSizeBytes() const -> std::pair<State, size_t>
 VectorGraphicData::VectorGraphicData(
     const VectorGraphicDataArray& rVectorGraphicDataArray,
     const OUString& rPath,
-    VectorGraphicDataType eVectorDataType)
+    VectorGraphicDataType eVectorDataType,
+    sal_Int32 nPageIndex)
 :   maVectorGraphicDataArray(rVectorGraphicDataArray),
     maPath(rPath),
     mbSequenceCreated(false),
@@ -270,7 +280,8 @@ VectorGraphicData::VectorGraphicData(
     maSequence(),
     maReplacement(),
     mNestedBitmapSize(0),
-    meVectorGraphicDataType(eVectorDataType)
+    meVectorGraphicDataType(eVectorDataType),
+    mnPageIndex(nPageIndex)
 {
 }
 
@@ -284,7 +295,8 @@ VectorGraphicData::VectorGraphicData(
     maSequence(),
     maReplacement(),
     mNestedBitmapSize(0),
-    meVectorGraphicDataType(eVectorDataType)
+    meVectorGraphicDataType(eVectorDataType),
+    mnPageIndex(-1)
 {
     SvFileStream rIStm(rPath, StreamMode::STD_READ);
     if(rIStm.GetError())


More information about the Libreoffice-commits mailing list