summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/source/pdf/pdfdecomposer.cxx28
-rw-r--r--include/vcl/graph.hxx2
-rw-r--r--include/vcl/vectorgraphicdata.hxx12
-rw-r--r--offapi/com/sun/star/graphic/XPdfDecomposer.idl8
-rw-r--r--sd/qa/unit/import-tests.cxx15
-rw-r--r--vcl/inc/impgraph.hxx7
-rw-r--r--vcl/source/filter/ipdf/pdfread.cxx18
-rw-r--r--vcl/source/gdi/graph.cxx7
-rw-r--r--vcl/source/gdi/impgraph.cxx34
-rw-r--r--vcl/source/gdi/vectorgraphicdata.cxx22
10 files changed, 85 insertions, 68 deletions
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 271de60d1605..6e70f66731ac 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 096c89e1aa56..8ccf45b51e5d 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 addf393630a1..954ef5b187ba 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -1327,17 +1327,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 965c41a4392e..a5435ee73b39 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -75,11 +75,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 );
@@ -203,6 +198,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 0dbb0fe455cb..b85a79d86e4a 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 c98212ad5c67..96414b43ad3a 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 9361aef3951d..90a1e4e58ed8 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;
}
@@ -1618,6 +1605,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())