summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-03-13 23:55:26 -0400
committerAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-06-04 12:36:28 -0400
commit5c0b46d3c899d85b16ab9866ae0575ddaef3a81e (patch)
treeede9ce8682a8a29a78854edfe1465aacf43d741a
parent498b14d8a8f4b51b137d03c4fb5c6f8c2747e7cd (diff)
sd: import PDFs as images using Pdfium new SdPdfFilter
LOK now opens PDFs as images using Pdfium, which has a superior accuracy and support to poppler, the default pdf reader. (cherry picked from commit 0e8f4f45b44935c7c8002d606b97a48e60e37b23) (cherry picked from commit 42733c51385b6518678a8d5483c234909db2af40) Change-Id: Ifbbecf7f048f001836fb98886705cba47e6bed4e
-rw-r--r--include/vcl/graph.hxx10
-rw-r--r--include/vcl/pdfread.hxx (renamed from vcl/inc/pdfread.hxx)4
-rw-r--r--sd/Library_sd.mk1
-rw-r--r--sd/inc/sdpdffilter.hxx40
-rw-r--r--sd/source/filter/pdf/sdpdffilter.cxx170
-rw-r--r--sd/source/ui/docshell/docshel4.cxx9
-rw-r--r--sdext/CppunitTest_sdext_pdfimport.mk2
-rw-r--r--sdext/Executable_pdf2xml.mk1
-rw-r--r--sdext/Executable_pdfunzip.mk1
-rw-r--r--sdext/Library_pdfimport.mk1
-rw-r--r--sdext/source/pdfimport/wrapper/wrapper.cxx40
-rw-r--r--sfx2/source/doc/objstor.cxx7
-rw-r--r--svx/source/svdraw/svdograf.cxx2
-rw-r--r--svx/source/xml/xmlgrhlp.cxx6
-rw-r--r--svx/source/xoutdev/_xoutbmp.cxx6
-rw-r--r--sw/source/core/graphic/ndgrf.cxx2
-rw-r--r--vcl/inc/impgraph.hxx14
-rw-r--r--vcl/source/filter/graphicfilter.cxx2
-rw-r--r--vcl/source/filter/ipdf/pdfread.cxx28
-rw-r--r--vcl/source/gdi/graph.cxx20
-rw-r--r--vcl/source/gdi/impgraph.cxx38
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx20
-rw-r--r--vcl/source/gdi/pdfwriter_impl.hxx4
23 files changed, 350 insertions, 78 deletions
diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx
index 3eb7c79e7c1e..24c3f4e796a2 100644
--- a/include/vcl/graph.hxx
+++ b/include/vcl/graph.hxx
@@ -230,8 +230,14 @@ public:
const VectorGraphicDataPtr& getVectorGraphicData() const;
- void setPdfData(const css::uno::Sequence<sal_Int8>& rPdfData);
- const css::uno::Sequence<sal_Int8>& getPdfData() const;
+ void setPdfData(const std::shared_ptr<css::uno::Sequence<sal_Int8>>& rPdfData);
+ const std::shared_ptr<css::uno::Sequence<sal_Int8>>& getPdfData() const;
+ bool hasPdfData() 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;
static css::uno::Sequence<sal_Int8> getUnoTunnelId();
};
diff --git a/vcl/inc/pdfread.hxx b/include/vcl/pdfread.hxx
index 2e16e4474c17..30015be22627 100644
--- a/vcl/inc/pdfread.hxx
+++ b/include/vcl/pdfread.hxx
@@ -10,6 +10,7 @@
#ifndef INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX
#define INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX
+#include <vector>
#include <tools/stream.hxx>
namespace com
@@ -36,6 +37,9 @@ VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap& rBitmap,
sal_uInt64 nPos = STREAM_SEEK_TO_BEGIN,
sal_uInt64 nSize = STREAM_SEEK_TO_END);
VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic);
+
+VCL_DLLPUBLIC size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps,
+ css::uno::Sequence<sal_Int8>& rPdfData);
}
#endif // INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index ae4592e340f3..7e165c3ec7a6 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -154,6 +154,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
sd/source/filter/html/buttonset \
sd/source/filter/html/htmlex \
sd/source/filter/html/sdhtmlfilter \
+ sd/source/filter/pdf/sdpdffilter \
sd/source/filter/sdfilter \
sd/source/filter/sdpptwrp \
sd/source/filter/xml/sdtransform \
diff --git a/sd/inc/sdpdffilter.hxx b/sd/inc/sdpdffilter.hxx
new file mode 100644
index 000000000000..8971eb745179
--- /dev/null
+++ b/sd/inc/sdpdffilter.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SD_INC_SDPDFIUMFILTER_HXX
+#define INCLUDED_SD_INC_SDPDFIUMFILTER_HXX
+
+#include <com/sun/star/drawing/XShape.hpp>
+
+#include "sdfilter.hxx"
+
+class SdPdfFilter : public SdFilter
+{
+public:
+ SdPdfFilter(SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell);
+
+ virtual ~SdPdfFilter() override;
+
+ bool Import();
+ bool Export() override;
+};
+
+#endif // INCLUDED_SD_INC_SDGRFFILTER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx
new file mode 100644
index 000000000000..8291ea5b05bc
--- /dev/null
+++ b/sd/source/filter/pdf/sdpdffilter.cxx
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/drawing/GraphicExportFilter.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/graphic/GraphicType.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
+
+#include <unotools/localfilehelper.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/virdev.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/frame.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdpagv.hxx>
+
+#include <strings.hrc>
+#include <DrawViewShell.hxx>
+#include <DrawDocShell.hxx>
+#include <ClientView.hxx>
+#include <FrameView.hxx>
+
+#include <comphelper/anytostring.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <svx/xoutbmp.hxx>
+
+#include <sdpage.hxx>
+#include <drawdoc.hxx>
+#include <sdresid.hxx>
+#include <sdpdffilter.hxx>
+#include <ViewShellBase.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <DrawController.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+#include <com/sun/star/drawing/GraphicFilterRequest.hpp>
+
+#include <vcl/bitmap.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/pdfread.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::ucb;
+using namespace com::sun::star::ui::dialogs;
+using namespace ::sfx2;
+
+SdPdfFilter::SdPdfFilter(SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell)
+ : SdFilter(rMedium, rDocShell)
+{
+}
+
+SdPdfFilter::~SdPdfFilter() {}
+
+bool SdPdfFilter::Import()
+{
+ //FIXME: Replace with parsing the PDF elements to allow editing.
+ //FIXME: For now we import as images for simplicity.
+
+ const OUString aFileName(
+ mrMedium.GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::NONE));
+
+ uno::Sequence<sal_Int8> aPdfData;
+ std::vector<Bitmap> aBitmaps;
+ if (vcl::ImportPDF(aFileName, aBitmaps, aPdfData) == 0)
+ return false;
+
+ // Prepare the link with the PDF stream.
+ const size_t nGraphicContentSize = aPdfData.getLength();
+ std::unique_ptr<sal_uInt8[]> pGraphicContent(new sal_uInt8[nGraphicContentSize]);
+ memcpy(pGraphicContent.get(), aPdfData.get(), nGraphicContentSize);
+ GfxLink aGfxLink(std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf);
+
+ mrDocument.CreateFirstPages();
+ for (int i = 0; i < aBitmaps.size() - 1; ++i)
+ {
+ mrDocument.DuplicatePage(0);
+ }
+
+ size_t nPageNumber = 0;
+ for (Bitmap& aBitmap : aBitmaps)
+ {
+ // Create the Graphic and link the original PDF stream.
+ Graphic aGraphic(aBitmap);
+ aGraphic.setPdfData(std::make_shared<uno::Sequence<sal_Int8>>(aPdfData));
+ aGraphic.SetGfxLink(aGfxLink);
+ aGraphic.setOriginURL(aFileName);
+
+ // Create the page and insert the Graphic.
+ SdPage* pPage = mrDocument.GetSdPage(nPageNumber++, PageKind::Standard);
+ Size aGrfSize(OutputDevice::LogicToLogic(aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(),
+ MapMode(MapUnit::Map100thMM)));
+
+ Size aPagSize(pPage->GetSize());
+ aPagSize.AdjustWidth(-(pPage->GetLeftBorder() + pPage->GetRightBorder()));
+ aPagSize.AdjustHeight(-(pPage->GetUpperBorder() + pPage->GetLowerBorder()));
+
+ // scale to fit page
+ if (((aGrfSize.Height() > aPagSize.Height()) || (aGrfSize.Width() > aPagSize.Width()))
+ && aGrfSize.Height() && aPagSize.Height())
+ {
+ double fGrfWH = static_cast<double>(aGrfSize.Width()) / aGrfSize.Height();
+ double fWinWH = static_cast<double>(aPagSize.Width()) / aPagSize.Height();
+
+ // adjust graphic to page size (scales)
+ if (fGrfWH < fWinWH)
+ {
+ aGrfSize.setWidth(static_cast<long>(aPagSize.Height() * fGrfWH));
+ aGrfSize.setHeight(aPagSize.Height());
+ }
+ else if (fGrfWH > 0.F)
+ {
+ aGrfSize.setWidth(aPagSize.Width());
+ aGrfSize.setHeight(static_cast<long>(aPagSize.Width() / fGrfWH));
+ }
+ }
+
+ // Set the output rectangle of the Graphic.
+ Point aPos;
+ aPos.setX(((aPagSize.Width() - aGrfSize.Width()) >> 1) + pPage->GetLeftBorder());
+ aPos.setY(((aPagSize.Height() - aGrfSize.Height()) >> 1) + pPage->GetUpperBorder());
+
+ pPage->InsertObject(new SdrGrafObj(pPage->getSdrModelFromSdrPage(), aGraphic,
+ tools::Rectangle(aPos, aGrfSize)));
+ }
+
+ return true;
+}
+
+bool SdPdfFilter::Export() { return false; }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/docshell/docshel4.cxx b/sd/source/ui/docshell/docshel4.cxx
index fb979fbfafa9..975b9af9dd56 100644
--- a/sd/source/ui/docshell/docshel4.cxx
+++ b/sd/source/ui/docshell/docshel4.cxx
@@ -79,6 +79,7 @@
#include <sdcgmfilter.hxx>
#include <sdgrffilter.hxx>
#include <sdhtmlfilter.hxx>
+#include <sdpdffilter.hxx>
#include <framework/FrameworkHelper.hxx>
#include <SdUnoDrawView.hxx>
@@ -489,12 +490,18 @@ bool DrawDocShell::ConvertFrom( SfxMedium& rMedium )
ErrCode nError = ERRCODE_NONE;
bRet = SdXMLFilter( rMedium, *this, SDXMLMODE_Normal, SOFFICE_FILEFORMAT_60 ).Import( nError );
}
- else if( aFilterName == "CGM - Computer Graphics Metafile" )
+ else if (aFilterName == "CGM - Computer Graphics Metafile")
{
mpDoc->CreateFirstPages();
mpDoc->StopWorkStartupDelay();
bRet = SdCGMFilter( rMedium, *this ).Import();
}
+ else if (aFilterName == "draw_pdf_import")
+ {
+ mpDoc->CreateFirstPages();
+ mpDoc->StopWorkStartupDelay();
+ bRet = SdPdfFilter(rMedium, *this).Import();
+ }
else
{
mpDoc->CreateFirstPages();
diff --git a/sdext/CppunitTest_sdext_pdfimport.mk b/sdext/CppunitTest_sdext_pdfimport.mk
index f5fc54696329..d1617cc0eb49 100644
--- a/sdext/CppunitTest_sdext_pdfimport.mk
+++ b/sdext/CppunitTest_sdext_pdfimport.mk
@@ -30,6 +30,8 @@ $(eval $(call gb_CppunitTest_use_libraries,sdext_pdfimport,\
sal \
test \
unotest \
+ $(gb_UWINAPI) \
+ tl \
xo \
))
diff --git a/sdext/Executable_pdf2xml.mk b/sdext/Executable_pdf2xml.mk
index c0f7fe6f5727..b2439164a1ed 100644
--- a/sdext/Executable_pdf2xml.mk
+++ b/sdext/Executable_pdf2xml.mk
@@ -30,6 +30,7 @@ $(eval $(call gb_Executable_use_libraries,pdf2xml,\
unotest \
cppuhelper \
sal \
+ tl \
xo \
))
diff --git a/sdext/Executable_pdfunzip.mk b/sdext/Executable_pdfunzip.mk
index 006f8e5c9430..1fcca8a863d7 100644
--- a/sdext/Executable_pdfunzip.mk
+++ b/sdext/Executable_pdfunzip.mk
@@ -28,6 +28,7 @@ $(eval $(call gb_Executable_use_libraries,pdfunzip,\
cppuhelper \
sal \
vcl \
+ tl \
xo \
))
diff --git a/sdext/Library_pdfimport.mk b/sdext/Library_pdfimport.mk
index 465a406b66b8..f0d38e624d1d 100644
--- a/sdext/Library_pdfimport.mk
+++ b/sdext/Library_pdfimport.mk
@@ -27,6 +27,7 @@ $(eval $(call gb_Library_use_libraries,pdfimport,\
cppu \
cppuhelper \
sal \
+ tl \
xo \
))
diff --git a/sdext/source/pdfimport/wrapper/wrapper.cxx b/sdext/source/pdfimport/wrapper/wrapper.cxx
index 7d3d68901e37..d34573d65ee6 100644
--- a/sdext/source/pdfimport/wrapper/wrapper.cxx
+++ b/sdext/source/pdfimport/wrapper/wrapper.cxx
@@ -35,6 +35,7 @@
#include <rtl/strbuf.hxx>
#include <rtl/byteseq.hxx>
+#include <comphelper/lok.hxx>
#include <comphelper/propertysequence.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <com/sun/star/io/XInputStream.hpp>
@@ -71,6 +72,12 @@
#include <rtl/character.hxx>
+#include <vcl/bitmapaccess.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/pdfread.hxx>
+#include <vcl/pngwrite.hxx>
+
using namespace com::sun::star;
namespace pdfi
@@ -1001,20 +1008,12 @@ public:
}
};
-bool xpdf_ImportFromFile_Poppler(const OUString& aSysUPath,
- const ContentSinkSharedPtr& rSink,
- const uno::Reference<task::XInteractionHandler>& xIHdl,
- const bool bIsEncrypted,
- const OUString& aPwd,
- const uno::Reference<uno::XComponentContext>& xContext,
- const OUString& rFilterOptions);
-
-bool xpdf_ImportFromFile( const OUString& rURL,
- const ContentSinkSharedPtr& rSink,
- const uno::Reference< task::XInteractionHandler >& xIHdl,
- const OUString& rPwd,
- const uno::Reference< uno::XComponentContext >& xContext,
- const OUString& rFilterOptions )
+bool xpdf_ImportFromFile(const OUString& rURL,
+ const ContentSinkSharedPtr& rSink,
+ const uno::Reference<task::XInteractionHandler>& xIHdl,
+ const OUString& rPwd,
+ const uno::Reference<uno::XComponentContext>& xContext,
+ const OUString& rFilterOptions)
{
OSL_ASSERT(rSink);
@@ -1039,19 +1038,6 @@ bool xpdf_ImportFromFile( const OUString& rURL,
return false;
}
- return xpdf_ImportFromFile_Poppler(aSysUPath, rSink, xIHdl, bIsEncrypted, aPwd, xContext, rFilterOptions);
-}
-
-/// Parse PDf file using libpoppler, which is quite limited
-/// to be phased out in favor of pdfium.
-bool xpdf_ImportFromFile_Poppler(const OUString& aSysUPath,
- const ContentSinkSharedPtr& rSink,
- const uno::Reference<task::XInteractionHandler>& /*xIHdl*/,
- const bool bIsEncrypted,
- const OUString& aPwd,
- const uno::Reference<uno::XComponentContext>& xContext,
- const OUString& rFilterOptions)
-{
// Determine xpdfimport executable URL:
OUString converterURL("$BRAND_BASE_DIR/" LIBO_BIN_FOLDER "/xpdfimport");
rtl::Bootstrap::expandMacros(converterURL); //TODO: detect failure
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index 244de5869a34..e30643b71b7e 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -103,6 +103,7 @@
#include <officecfg/Office/Common.hxx>
#include <osl/file.hxx>
#include <comphelper/scopeguard.hxx>
+#include <comphelper/lok.hxx>
#include <sfx2/signaturestate.hxx>
#include <sfx2/app.hxx>
@@ -748,9 +749,13 @@ bool SfxObjectShell::DoLoad( SfxMedium *pMed )
if ( GetError() == ERRCODE_NONE )
{
+ // Experimental PDF importing using PDFium. This is currently enabled for LOK only and
+ // we handle it not via XmlFilterAdaptor but a new SdPdfFiler.
+ const bool bPdfiumImport = comphelper::LibreOfficeKit::isActive() && pMedium->GetFilter() &&
+ (pMedium->GetFilter()->GetFilterName() == "draw_pdf_import");
pImpl->nLoadedFlags = SfxLoadedFlags::NONE;
pImpl->bModelInitialized = false;
- if ( pMedium->GetFilter() && ( pMedium->GetFilter()->GetFilterFlags() & SfxFilterFlags::STARONEFILTER ) )
+ if ( pMedium->GetFilter() && ( pMedium->GetFilter()->GetFilterFlags() & SfxFilterFlags::STARONEFILTER ) && !bPdfiumImport )
{
uno::Reference < beans::XPropertySet > xSet( GetModel(), uno::UNO_QUERY );
const OUString sLockUpdates("LockUpdates");
diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index 0c6f2cfb936f..3dd1356c547e 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -434,7 +434,7 @@ const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
{
const_cast< SdrGrafObj* >(this)->mpReplacementGraphicObject.reset(new GraphicObject(rVectorGraphicDataPtr->getReplacement()));
}
- else if (mpGraphicObject->GetGraphic().getPdfData().hasElements() ||
+ else if (mpGraphicObject->GetGraphic().getPdfData()->hasElements() ||
mpGraphicObject->GetGraphic().GetType() == GraphicType::GdiMetafile)
{
// Replacement graphic for PDF and metafiles is just the bitmap.
diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx
index a0f01b8671ac..3f98e4af7ab4 100644
--- a/svx/source/xml/xmlgrhlp.cxx
+++ b/svx/source/xml/xmlgrhlp.cxx
@@ -764,14 +764,14 @@ OUString SvXMLGraphicHelper::implSaveGraphic(css::uno::Reference<css::graphic::X
std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(aStream.xStream));
if (bUseGfxLink && aGfxLink.GetDataSize() && aGfxLink.GetData())
{
- const uno::Sequence<sal_Int8>& rPdfData = aGraphic.getPdfData();
- if (rPdfData.hasElements())
+ const std::shared_ptr<uno::Sequence<sal_Int8>>& rPdfData = aGraphic.getPdfData();
+ if (rPdfData->hasElements())
{
// The graphic has PDF data attached to it, use that.
// vcl::ImportPDF() possibly downgraded the PDF data from a
// higher PDF version, while aGfxLink still contains the
// original data provided by the user.
- pStream->WriteBytes(rPdfData.getConstArray(), rPdfData.getLength());
+ pStream->WriteBytes(rPdfData->getConstArray(), rPdfData->getLength());
}
else
{
diff --git a/svx/source/xoutdev/_xoutbmp.cxx b/svx/source/xoutdev/_xoutbmp.cxx
index 55128d08f7d8..ecabc1a466bc 100644
--- a/svx/source/xoutdev/_xoutbmp.cxx
+++ b/svx/source/xoutdev/_xoutbmp.cxx
@@ -173,7 +173,7 @@ ErrCode XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileName,
}
// Write PDF data in original form if possible.
- if (rGraphic.getPdfData().hasElements() && rFilterName.equalsIgnoreAsciiCase("pdf"))
+ if (rGraphic.getPdfData()->hasElements() && rFilterName.equalsIgnoreAsciiCase("pdf"))
{
if (!(nFlags & XOutFlags::DontAddExtension))
aURL.setExtension(rFilterName);
@@ -182,8 +182,8 @@ ErrCode XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileName,
SfxMedium aMedium(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::WRITE|StreamMode::SHARE_DENYNONE|StreamMode::TRUNC);
if (SvStream* pOutStream = aMedium.GetOutStream())
{
- uno::Sequence<sal_Int8> aPdfData = rGraphic.getPdfData();
- pOutStream->WriteBytes(aPdfData.getConstArray(), aPdfData.getLength());
+ const std::shared_ptr<uno::Sequence<sal_Int8>>& aPdfData = rGraphic.getPdfData();
+ pOutStream->WriteBytes(aPdfData->getConstArray(), aPdfData->getLength());
aMedium.Commit();
if (!aMedium.GetError())
nErr = ERRCODE_NONE;
diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx
index 5cfd3ce51508..52366d28c1f9 100644
--- a/sw/source/core/graphic/ndgrf.cxx
+++ b/sw/source/core/graphic/ndgrf.cxx
@@ -395,7 +395,7 @@ const GraphicObject* SwGrfNode::GetReplacementGrfObj() const
{
const_cast< SwGrfNode* >(this)->mpReplacementGraphic = new GraphicObject(rVectorGraphicDataPtr->getReplacement());
}
- else if (GetGrfObj().GetGraphic().getPdfData().hasElements()
+ else if (GetGrfObj().GetGraphic().getPdfData()->hasElements()
|| GetGrfObj().GetGraphic().GetType() == GraphicType::GdiMetafile)
{
// Replacement graphic for PDF and metafiles is just the bitmap.
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index 4338ed20021d..a678aea0edcb 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -88,10 +88,18 @@ private:
bool mbSwapOut;
bool mbDummyContext;
VectorGraphicDataPtr maVectorGraphicData;
- css::uno::Sequence<sal_Int8> maPdfData;
+ /// The PDF stream from which this Graphic is rendered,
+ /// as converted (version downgraded) from the original,
+ /// which should be in GfxLink.
+ std::shared_ptr<css::uno::Sequence<sal_Int8>> mpPdfData;
std::unique_ptr<GraphicID> mpGraphicID;
GraphicExternalLink maGraphicExternalLink;
+ /// 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;
+
std::chrono::high_resolution_clock::time_point maLastUsed;
bool mbPrepared;
@@ -214,9 +222,9 @@ private:
const VectorGraphicDataPtr& getVectorGraphicData() const;
- const css::uno::Sequence<sal_Int8>& getPdfData() const;
+ const std::shared_ptr<css::uno::Sequence<sal_Int8>>& getPdfData() const;
- void setPdfData(const css::uno::Sequence<sal_Int8>& rPdfData);
+ void setPdfData(const std::shared_ptr<css::uno::Sequence<sal_Int8>>& rPdfData);
bool ensureAvailable () const;
diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx
index 1ba3d1d776ec..f713264cacfb 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -44,7 +44,7 @@
#include <vcl/wmf.hxx>
#include <vcl/settings.hxx>
#include "igif/gifread.hxx"
-#include <pdfread.hxx>
+#include <vcl/pdfread.hxx>
#include "jpeg/jpeg.hxx"
#include "ixbm/xbmread.hxx"
#include "ixpm/xpmread.hxx"
diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index b37b6339155e..f94e6b320dd2 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -7,7 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#include <pdfread.hxx>
+#include <vcl/pdfread.hxx>
#include <config_features.h>
@@ -17,8 +17,10 @@
#include <fpdf_save.h>
#endif
+#include <vcl/bitmapaccess.hxx>
#include <vcl/graph.hxx>
#include <bitmapwriteaccess.hxx>
+#include <unotools/ucbstreamhelper.hxx>
using namespace com::sun::star;
@@ -243,9 +245,31 @@ bool ImportPDF(SvStream& rStream, Graphic& rGraphic)
Bitmap aBitmap;
const bool bRet = ImportPDF(rStream, aBitmap, aPdfData);
rGraphic = aBitmap;
- rGraphic.setPdfData(aPdfData);
+ rGraphic.setPdfData(std::make_shared<css::uno::Sequence<sal_Int8>>(aPdfData));
return bRet;
}
+
+size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps,
+ css::uno::Sequence<sal_Int8>& rPdfData)
+{
+ std::unique_ptr<SvStream> xStream(
+ ::utl::UcbStreamHelper::CreateStream(rURL, StreamMode::READ | StreamMode::SHARE_DENYNONE));
+
+ if (generatePreview(*xStream, rBitmaps, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END, 0, -1) == 0)
+ return 0;
+
+ // Save the original PDF stream for later use.
+ SvMemoryStream aMemoryStream;
+ if (!getCompatibleStream(*xStream, aMemoryStream, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END))
+ return 0;
+
+ aMemoryStream.Seek(STREAM_SEEK_TO_END);
+ rPdfData = css::uno::Sequence<sal_Int8>(aMemoryStream.Tell());
+ aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+ aMemoryStream.ReadBytes(rPdfData.getArray(), rPdfData.getLength());
+
+ return rBitmaps.size();
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
index 19bb99d254e4..52e4e9e74ae8 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -557,17 +557,33 @@ const VectorGraphicDataPtr& Graphic::getVectorGraphicData() const
return mxImpGraphic->getVectorGraphicData();
}
-void Graphic::setPdfData(const uno::Sequence<sal_Int8>& rPdfData)
+void Graphic::setPdfData(const std::shared_ptr<uno::Sequence<sal_Int8>>& rPdfData)
{
ImplTestRefCount();
mxImpGraphic->setPdfData(rPdfData);
}
-const uno::Sequence<sal_Int8>& Graphic::getPdfData() const
+const std::shared_ptr<uno::Sequence<sal_Int8>>& Graphic::getPdfData() const
{
return mxImpGraphic->getPdfData();
}
+bool Graphic::hasPdfData() const
+{
+ std::shared_ptr<uno::Sequence<sal_Int8>> pPdfData = getPdfData();
+ return pPdfData && pPdfData->hasElements();
+}
+
+void Graphic::setPageNumber(sal_Int32 nPageNumber)
+{
+ mxImpGraphic->mnPageNumber = nPageNumber;
+}
+
+sal_Int32 Graphic::getPageNumber() const
+{
+ return mxImpGraphic->mnPageNumber;
+}
+
OUString Graphic::getOriginURL() const
{
if (mxImpGraphic)
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index c718f9673610..fe8eb1166250 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -43,7 +43,7 @@
#include <o3tl/make_unique.hxx>
#include <vcl/gdimetafiletools.hxx>
-#include <pdfread.hxx>
+#include <vcl/pdfread.hxx>
#define GRAPHIC_MTFTOBMP_MAXEXT 2048
#define GRAPHIC_STREAMBUFSIZE 8192UL
@@ -195,7 +195,7 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic)
, mbSwapOut(rImpGraphic.mbSwapOut)
, mbDummyContext(rImpGraphic.mbDummyContext)
, maVectorGraphicData(rImpGraphic.maVectorGraphicData)
- , maPdfData(rImpGraphic.maPdfData)
+ , mpPdfData(rImpGraphic.mpPdfData)
, maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
, maLastUsed (std::chrono::high_resolution_clock::now())
, mbPrepared (rImpGraphic.mbPrepared)
@@ -223,7 +223,7 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic)
, mbSwapOut(rImpGraphic.mbSwapOut)
, mbDummyContext(rImpGraphic.mbDummyContext)
, maVectorGraphicData(std::move(rImpGraphic.maVectorGraphicData))
- , maPdfData(std::move(rImpGraphic.maPdfData))
+ , mpPdfData(std::move(rImpGraphic.mpPdfData))
, maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
, maLastUsed (std::chrono::high_resolution_clock::now())
, mbPrepared (rImpGraphic.mbPrepared)
@@ -341,7 +341,7 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
mpGfxLink = o3tl::make_unique<GfxLink>( *rImpGraphic.mpGfxLink );
maVectorGraphicData = rImpGraphic.maVectorGraphicData;
- maPdfData = rImpGraphic.maPdfData;
+ mpPdfData = rImpGraphic.mpPdfData;
maLastUsed = std::chrono::high_resolution_clock::now();
vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
@@ -366,7 +366,7 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic)
mpSwapFile = std::move(rImpGraphic.mpSwapFile);
mpGfxLink = std::move(rImpGraphic.mpGfxLink);
maVectorGraphicData = std::move(rImpGraphic.maVectorGraphicData);
- maPdfData = std::move(rImpGraphic.maPdfData);
+ mpPdfData = std::move(rImpGraphic.mpPdfData);
maGraphicExternalLink = rImpGraphic.maGraphicExternalLink;
mbPrepared = rImpGraphic.mbPrepared;
@@ -419,9 +419,9 @@ bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
bRet = (*maVectorGraphicData) == (*rImpGraphic.maVectorGraphicData);
}
}
- else if (maPdfData.hasElements())
+ else if (mpPdfData->hasElements())
{
- bRet = maPdfData == rImpGraphic.maPdfData;
+ bRet = mpPdfData == rImpGraphic.mpPdfData;
}
else if( mpAnimation )
{
@@ -450,18 +450,18 @@ const VectorGraphicDataPtr& ImpGraphic::getVectorGraphicData() const
return maVectorGraphicData;
}
-void ImpGraphic::setPdfData(const uno::Sequence<sal_Int8>& rPdfData)
+void ImpGraphic::setPdfData(const std::shared_ptr<uno::Sequence<sal_Int8>>& rPdfData)
{
ensureAvailable();
- maPdfData = rPdfData;
+ mpPdfData = rPdfData;
}
-const uno::Sequence<sal_Int8>& ImpGraphic::getPdfData() const
+const std::shared_ptr<uno::Sequence<sal_Int8>>& ImpGraphic::getPdfData() const
{
ensureAvailable();
- return maPdfData;
+ return mpPdfData;
}
void ImpGraphic::ImplCreateSwapInfo()
@@ -485,7 +485,7 @@ void ImpGraphic::ImplClearGraphics()
mpAnimation.reset();
mpGfxLink.reset();
maVectorGraphicData.reset();
- maPdfData = uno::Sequence<sal_Int8>();
+ mpPdfData.reset();
}
ImpSwapFile::~ImpSwapFile()
@@ -1681,10 +1681,10 @@ BitmapChecksum ImpGraphic::ImplGetChecksum() const
nRet = maEx.GetChecksum();
}
- if (maPdfData.hasElements())
+ if (mpPdfData->hasElements())
// Include the PDF data in the checksum, so a metafile with
// and without PDF data is considered to be different.
- nRet = vcl_get_checksum(nRet, maPdfData.getConstArray(), maPdfData.getLength());
+ nRet = vcl_get_checksum(nRet, mpPdfData->getConstArray(), mpPdfData->getLength());
}
break;
@@ -1875,7 +1875,7 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
Bitmap aBitmap;
if (nPdfDataLength && !rIStm.GetError() &&
- vcl::ImportPDF(rIStm, aBitmap, rImpGraphic.maPdfData,
+ vcl::ImportPDF(rIStm, aBitmap, *rImpGraphic.mpPdfData,
rIStm.Tell(), nPdfDataLength))
{
rImpGraphic.maEx = aBitmap;
@@ -1910,7 +1910,7 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic)
if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) &&
( rOStm.GetCompressMode() & SvStreamCompressFlags::NATIVE ) &&
rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() &&
- !rImpGraphic.maPdfData.hasElements())
+ !rImpGraphic.mpPdfData->hasElements())
{
// native format
rOStm.WriteUInt32( NATIVE_FORMAT_50 );
@@ -1971,12 +1971,12 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic)
rOStm.WriteUniOrByteString(rImpGraphic.getVectorGraphicData()->getPath(),
rOStm.GetStreamCharSet());
}
- else if (rImpGraphic.maPdfData.hasElements())
+ else if (rImpGraphic.mpPdfData->hasElements())
{
// Stream out PDF data.
rOStm.WriteUInt32(nPdfMagic);
- rOStm.WriteUInt32(rImpGraphic.maPdfData.getLength());
- rOStm.WriteBytes(rImpGraphic.maPdfData.getConstArray(), rImpGraphic.maPdfData.getLength());
+ rOStm.WriteUInt32(rImpGraphic.mpPdfData->getLength());
+ rOStm.WriteBytes(rImpGraphic.mpPdfData->getConstArray(), rImpGraphic.mpPdfData->getLength());
}
else if( rImpGraphic.ImplIsAnimated())
{
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index b72078caa819..eff39aaab0da 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -4932,12 +4932,12 @@ bool PDFWriterImpl::emitEmbeddedFiles()
aLine.append(rEmbeddedFile.m_nObject);
aLine.append(" 0 obj\n");
aLine.append("<< /Type /EmbeddedFile /Length ");
- aLine.append(static_cast<sal_Int64>(rEmbeddedFile.m_aData.getLength()));
+ aLine.append(static_cast<sal_Int64>(rEmbeddedFile.m_pData->getLength()));
aLine.append(" >>\nstream\n");
CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength()));
aLine.setLength(0);
- CHECK_RETURN(writeBuffer(rEmbeddedFile.m_aData.getArray(), rEmbeddedFile.m_aData.getLength()));
+ CHECK_RETURN(writeBuffer(rEmbeddedFile.m_pData->getArray(), rEmbeddedFile.m_pData->getLength()));
aLine.append("\nendstream\nendobj\n\n");
CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength()));
@@ -8872,7 +8872,7 @@ bool PDFWriterImpl::writeGradientFunction( GradientEmit const & rObject )
void PDFWriterImpl::writeJPG( JPGEmit& rObject )
{
- if (rObject.m_aReferenceXObject.m_aPDFData.hasElements() && !m_aContext.UseReferenceXObject)
+ if (rObject.m_aReferenceXObject.m_pPDFData->hasElements() && !m_aContext.UseReferenceXObject)
{
writeReferenceXObject(rObject.m_aReferenceXObject);
return;
@@ -9180,7 +9180,7 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit)
// Parse the PDF data, we need that to write the PDF dictionary of our
// object.
SvMemoryStream aPDFStream;
- aPDFStream.WriteBytes(rEmit.m_aPDFData.getArray(), rEmit.m_aPDFData.getLength());
+ aPDFStream.WriteBytes(rEmit.m_pPDFData->getArray(), rEmit.m_pPDFData->getLength());
aPDFStream.Seek(0);
filter::PDFDocument aPDFDocument;
if (!aPDFDocument.Read(aPDFStream))
@@ -9416,7 +9416,7 @@ namespace
bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
{
- if (rObject.m_aReferenceXObject.m_aPDFData.hasElements() && !m_aContext.UseReferenceXObject)
+ if (rObject.m_aReferenceXObject.m_pPDFData->hasElements() && !m_aContext.UseReferenceXObject)
{
writeReferenceXObject(rObject.m_aReferenceXObject);
return true;
@@ -9734,7 +9734,7 @@ void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObject
// no pdf data.
rEmit.m_nBitmapObject = nBitmapObject;
- if (!rGraphic.getPdfData().hasElements())
+ if (!rGraphic.getPdfData()->hasElements())
return;
if (m_aContext.UseReferenceXObject)
@@ -9742,12 +9742,12 @@ void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObject
// Store the original PDF data as an embedded file.
m_aEmbeddedFiles.emplace_back();
m_aEmbeddedFiles.back().m_nObject = createObject();
- m_aEmbeddedFiles.back().m_aData = rGraphic.getPdfData();
+ m_aEmbeddedFiles.back().m_pData = rGraphic.getPdfData();
rEmit.m_nEmbeddedObject = m_aEmbeddedFiles.back().m_nObject;
}
else
- rEmit.m_aPDFData = rGraphic.getPdfData();
+ rEmit.m_pPDFData = rGraphic.getPdfData();
rEmit.m_nFormObject = createObject();
rEmit.m_aPixelSize = rGraphic.GetPrefSize();
@@ -9802,7 +9802,7 @@ void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const
{
m_aJPGs.emplace( m_aJPGs.begin() );
JPGEmit& rEmit = m_aJPGs.front();
- if (!rGraphic.getPdfData().hasElements() || m_aContext.UseReferenceXObject)
+ if (!rGraphic.getPdfData()->hasElements() || m_aContext.UseReferenceXObject)
rEmit.m_nObject = createObject();
rEmit.m_aID = aID;
rEmit.m_pStream.reset( pStream );
@@ -9910,7 +9910,7 @@ const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx
m_aBitmaps.push_front( BitmapEmit() );
m_aBitmaps.front().m_aID = aID;
m_aBitmaps.front().m_aBitmap = aBitmap;
- if (!rGraphic.getPdfData().hasElements() || m_aContext.UseReferenceXObject)
+ if (!rGraphic.getPdfData()->hasElements() || m_aContext.UseReferenceXObject)
m_aBitmaps.front().m_nObject = createObject();
createEmbeddedFile(rGraphic, m_aBitmaps.front().m_aReferenceXObject, m_aBitmaps.front().m_nObject);
it = m_aBitmaps.begin();
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index b4c1b3a454e6..4d5df9325d5e 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -224,7 +224,7 @@ public:
/// Size of the bitmap replacement, in pixels.
Size m_aPixelSize;
/// PDF data from the graphic object, if not writing a reference XObject.
- css::uno::Sequence<sal_Int8> m_aPDFData;
+ std::shared_ptr<css::uno::Sequence<sal_Int8>> m_pPDFData;
ReferenceXObjectEmit()
: m_nFormObject(0),
@@ -446,7 +446,7 @@ public:
/// ID of the file.
sal_Int32 m_nObject;
/// Contents of the file.
- css::uno::Sequence<sal_Int8> m_aData;
+ std::shared_ptr<css::uno::Sequence<sal_Int8>> m_pData;
PDFEmbeddedFile()
: m_nObject(0)