pdfium: Make Insert -> Image... use VectorGraphicData for PDF.
In principle, the current Svg/Emf/Wmf and PDF handling is trying to achieve the same thing: Keep the original stream untouched, provide a replacement graphics, and a kind of rendering. To hold the data, the Svg/Emf/Wmf and PDF were using different structures though. This commit consolidatates that, and makes the Insert -> Image... (for PDF) actually using the VectorGraphicData to hold the original stream. This breaks loading the PDF as a document via PDFium - I'll fix it in the next commit(s). Change-Id: Iac102f32b757390a03438c165e430283851cc10b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90561 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
parent
dc3c59a1d9
commit
6ac2d66c78
28 changed files with 353 additions and 317 deletions
|
@ -49,10 +49,12 @@ $(eval $(call gb_Library_use_libraries,pdffilter,\
|
|||
cppuhelper \
|
||||
cppu \
|
||||
sal \
|
||||
drawinglayer \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Library_add_exception_objects,pdffilter,\
|
||||
filter/source/pdf/impdialog \
|
||||
filter/source/pdf/pdfdecomposer \
|
||||
filter/source/pdf/pdfdialog \
|
||||
filter/source/pdf/pdfexport \
|
||||
filter/source/pdf/pdffilter \
|
||||
|
|
106
filter/source/pdf/pdfdecomposer.cxx
Normal file
106
filter/source/pdf/pdfdecomposer.cxx
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "pdfdecomposer.hxx"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <basegfx/matrix/b2dhommatrixtools.hxx>
|
||||
#include <comphelper/processfactory.hxx>
|
||||
#include <cppuhelper/implbase2.hxx>
|
||||
#include <cppuhelper/supportsservice.hxx>
|
||||
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
|
||||
#include <vcl/bitmapex.hxx>
|
||||
#include <vcl/pdfread.hxx>
|
||||
#include <vcl/svapp.hxx>
|
||||
#include <vcl/outdev.hxx>
|
||||
|
||||
#include <com/sun/star/graphic/XPdfDecomposer.hpp>
|
||||
#include <com/sun/star/lang/XServiceInfo.hpp>
|
||||
#include <com/sun/star/uno/XComponentContext.hpp>
|
||||
|
||||
using namespace css;
|
||||
|
||||
namespace
|
||||
{
|
||||
/// Class to convert the PDF data into a XPrimitive2D (containing only a bitmap).
|
||||
class XPdfDecomposer
|
||||
: public ::cppu::WeakAggImplHelper2<graphic::XPdfDecomposer, lang::XServiceInfo>
|
||||
{
|
||||
public:
|
||||
explicit XPdfDecomposer(uno::Reference<uno::XComponentContext> const& context);
|
||||
XPdfDecomposer(const XPdfDecomposer&) = delete;
|
||||
XPdfDecomposer& operator=(const XPdfDecomposer&) = delete;
|
||||
|
||||
// XPdfDecomposer
|
||||
uno::Sequence<uno::Reference<graphic::XPrimitive2D>>
|
||||
SAL_CALL getDecomposition(const uno::Sequence<sal_Int8>& xPdfData) override;
|
||||
|
||||
// XServiceInfo
|
||||
OUString SAL_CALL getImplementationName() override;
|
||||
sal_Bool SAL_CALL supportsService(const OUString&) override;
|
||||
uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
|
||||
};
|
||||
|
||||
XPdfDecomposer::XPdfDecomposer(uno::Reference<uno::XComponentContext> const&) {}
|
||||
|
||||
uno::Sequence<uno::Reference<graphic::XPrimitive2D>>
|
||||
SAL_CALL XPdfDecomposer::getDecomposition(const uno::Sequence<sal_Int8>& xPdfData)
|
||||
{
|
||||
std::vector<Bitmap> aBitmaps;
|
||||
vcl::RenderPDFBitmaps(xPdfData.getConstArray(), xPdfData.getLength(), aBitmaps, 0,
|
||||
1 /*, fResolutionDPI*/);
|
||||
BitmapEx aReplacement(aBitmaps[0]);
|
||||
|
||||
// short form for scale and translate transformation
|
||||
const Size aDPI(
|
||||
Application::GetDefaultDevice()->LogicToPixel(Size(1, 1), MapMode(MapUnit::MapInch)));
|
||||
const Size aBitmapSize(aReplacement.GetSizePixel());
|
||||
const basegfx::B2DHomMatrix aBitmapTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(
|
||||
aBitmapSize.getWidth() * aDPI.getWidth(), aBitmapSize.getHeight() * aDPI.getHeight(), 0,
|
||||
0));
|
||||
|
||||
// create primitive
|
||||
uno::Sequence<uno::Reference<graphic::XPrimitive2D>> aSequence(1);
|
||||
aSequence[0] = new drawinglayer::primitive2d::BitmapPrimitive2D(aReplacement, aBitmapTransform);
|
||||
|
||||
return aSequence;
|
||||
}
|
||||
|
||||
OUString SAL_CALL XPdfDecomposer::getImplementationName()
|
||||
{
|
||||
return PDFDecomposer_getImplementationName();
|
||||
}
|
||||
|
||||
sal_Bool SAL_CALL XPdfDecomposer::supportsService(const OUString& rServiceName)
|
||||
{
|
||||
return cppu::supportsService(this, rServiceName);
|
||||
}
|
||||
|
||||
uno::Sequence<OUString> SAL_CALL XPdfDecomposer::getSupportedServiceNames()
|
||||
{
|
||||
return PDFDecomposer_getSupportedServiceNames();
|
||||
}
|
||||
}
|
||||
|
||||
OUString PDFDecomposer_getImplementationName() { return "com.sun.star.comp.PDF.PDFDecomposer"; }
|
||||
|
||||
uno::Sequence<OUString> PDFDecomposer_getSupportedServiceNames()
|
||||
{
|
||||
return uno::Sequence<OUString>{ "com.sun.star.graphic.PdfTools" };
|
||||
}
|
||||
|
||||
uno::Reference<uno::XInterface>
|
||||
PDFDecomposer_createInstance(const uno::Reference<lang::XMultiServiceFactory>& rSMgr)
|
||||
{
|
||||
return static_cast<cppu::OWeakObject*>(
|
||||
new XPdfDecomposer(comphelper::getComponentContext(rSMgr)));
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
22
filter/source/pdf/pdfdecomposer.hxx
Normal file
22
filter/source/pdf/pdfdecomposer.hxx
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_FILTER_SOURCE_PDF_PDFDECOMPOSER_HXX
|
||||
#define INCLUDED_FILTER_SOURCE_PDF_PDFDECOMPOSER_HXX
|
||||
|
||||
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
||||
|
||||
OUString PDFDecomposer_getImplementationName();
|
||||
css::uno::Sequence<OUString> PDFDecomposer_getSupportedServiceNames();
|
||||
css::uno::Reference<css::uno::XInterface>
|
||||
PDFDecomposer_createInstance(const css::uno::Reference<css::lang::XMultiServiceFactory>& rSMgr);
|
||||
|
||||
#endif // INCLUDED_FILTER_SOURCE_PDF_PDFDECOMPOSER_HXX
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
@ -28,4 +28,7 @@
|
|||
<implementation name="com.sun.star.comp.PDF.PDFExportInteractionHandler">
|
||||
<service name="com.sun.star.filter.pdfexport.PDFExportInteractionHandler"/>
|
||||
</implementation>
|
||||
<implementation name="com.sun.star.comp.PDF.PDFDecomposer">
|
||||
<service name="com.sun.star.graphic.PdfTools"/>
|
||||
</implementation>
|
||||
</component>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <cppuhelper/factory.hxx>
|
||||
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
|
||||
|
||||
#include "pdfdecomposer.hxx"
|
||||
#include "pdffilter.hxx"
|
||||
#include "pdfdialog.hxx"
|
||||
#include "pdfinteract.hxx"
|
||||
|
@ -62,6 +63,12 @@ extern "C"
|
|||
PDFInteractionHandler_createInstance, PDFInteractionHandler_getSupportedServiceNames() );
|
||||
|
||||
}
|
||||
else if (aImplName == PDFDecomposer_getImplementationName())
|
||||
{
|
||||
xFactory = createSingleFactory(static_cast<XMultiServiceFactory*>(pServiceManager),
|
||||
OUString::createFromAscii(pImplName),
|
||||
PDFDecomposer_createInstance, PDFDecomposer_getSupportedServiceNames());
|
||||
}
|
||||
|
||||
if( xFactory.is() )
|
||||
{
|
||||
|
|
|
@ -199,8 +199,6 @@ public:
|
|||
bool isEmbeddedVectorGraphicData() const;
|
||||
GDIMetaFile getMetafileFromEmbeddedVectorGraphicData() const;
|
||||
|
||||
bool isEmbeddedPdfData() const;
|
||||
const std::shared_ptr<std::vector<sal_Int8>> & getEmbeddedPdfData() const;
|
||||
/// Returns the page number of the embedded data (typically to re-render or import it).
|
||||
sal_Int32 getEmbeddedPageNumber() const;
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ private:
|
|||
|
||||
std::unordered_map<OUString, css::uno::Reference<css::graphic::XGraphic>> maGraphicObjects;
|
||||
std::unordered_map<Graphic, std::pair<OUString, OUString>> maExportGraphics;
|
||||
std::unordered_map<void*, std::pair<OUString, OUString>> maExportPdf;
|
||||
|
||||
SvXMLGraphicHelperMode meCreateMode;
|
||||
OUString maOutputMimeType;
|
||||
|
|
|
@ -204,10 +204,6 @@ public:
|
|||
|
||||
const VectorGraphicDataPtr& getVectorGraphicData() const;
|
||||
|
||||
void setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData);
|
||||
const std::shared_ptr<std::vector<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.
|
||||
|
|
|
@ -37,16 +37,8 @@ VCL_DLLPUBLIC size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vecto
|
|||
size_t nFirstPage = 0, int nPages = 1,
|
||||
double fResolutionDPI = 96.);
|
||||
|
||||
/// Imports a PDF stream into rGraphic as a GDIMetaFile.
|
||||
VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, size_t nPageIndex,
|
||||
std::vector<sal_Int8>& rPdfData,
|
||||
sal_uInt64 nPos = STREAM_SEEK_TO_BEGIN,
|
||||
sal_uInt64 nSize = STREAM_SEEK_TO_END, double fResolutionDPI = 96.);
|
||||
|
||||
VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic, double fResolutionDPI = 96.);
|
||||
|
||||
VCL_DLLPUBLIC size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps,
|
||||
std::vector<sal_Int8>& rPdfData, double fResolutionDPI = 96.);
|
||||
/// Imports a PDF stream into rGraphic as VectorGraphicData.
|
||||
VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic);
|
||||
|
||||
/// Import PDF as Graphic images (1 per page), all unloaded.
|
||||
/// Since Graphic is unloaded, we need to return the page size (in pixels) separately.
|
||||
|
|
|
@ -46,7 +46,8 @@ enum class VectorGraphicDataType
|
|||
{
|
||||
Svg = 0,
|
||||
Emf = 1,
|
||||
Wmf = 2
|
||||
Wmf = 2,
|
||||
Pdf = 3
|
||||
};
|
||||
|
||||
class VCL_DLLPUBLIC VectorGraphicData
|
||||
|
@ -70,6 +71,7 @@ private:
|
|||
std::unique_ptr<WmfExternal> mpExternalHeader;
|
||||
|
||||
// on demand creators
|
||||
void ensurePdfReplacement();
|
||||
void ensureReplacement();
|
||||
void ensureSequenceAndRange();
|
||||
|
||||
|
|
|
@ -212,6 +212,7 @@ $(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/graphic,\
|
|||
Primitive2DTools \
|
||||
SvgTools \
|
||||
EmfTools \
|
||||
PdfTools \
|
||||
))
|
||||
$(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/inspection,\
|
||||
DefaultHelpProvider \
|
||||
|
@ -2722,6 +2723,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/graphic,\
|
|||
XPrimitiveFactory2D \
|
||||
XSvgParser \
|
||||
XEmfParser \
|
||||
XPdfDecomposer \
|
||||
))
|
||||
$(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/i18n,\
|
||||
AmPmValue \
|
||||
|
|
27
offapi/com/sun/star/graphic/PdfTools.idl
Normal file
27
offapi/com/sun/star/graphic/PdfTools.idl
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* -*- 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/.
|
||||
*/
|
||||
|
||||
#ifndef com_sun_star_graphic_PdfTools_idl
|
||||
#define com_sun_star_graphic_PdfTools_idl
|
||||
|
||||
#include <com/sun/star/graphic/XPdfDecomposer.idl>
|
||||
|
||||
module com { module sun { module star { module graphic
|
||||
{
|
||||
|
||||
/** Service to convert a PDF stream into a bitmap primitive.
|
||||
*/
|
||||
|
||||
service PdfTools : XPdfDecomposer;
|
||||
|
||||
} ; } ; } ; } ;
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
39
offapi/com/sun/star/graphic/XPdfDecomposer.idl
Normal file
39
offapi/com/sun/star/graphic/XPdfDecomposer.idl
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* -*- 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/.
|
||||
*/
|
||||
|
||||
#ifndef __com_sun_star_graphic_XPdfDecomposer_idl__
|
||||
#define __com_sun_star_graphic_XPdfDecomposer_idl__
|
||||
|
||||
#include <com/sun/star/uno/XInterface.idl>
|
||||
|
||||
module com { module sun { module star { module graphic {
|
||||
|
||||
interface XPrimitive2D;
|
||||
|
||||
/** XPdfDecomposer interface
|
||||
|
||||
This renders a PDF data into a bitmap and returns it as a primitive.
|
||||
*/
|
||||
interface XPdfDecomposer : ::com::sun::star::uno::XInterface
|
||||
{
|
||||
/** Retrieve decomposed list - in this case a bitmap with the rendered PDF.
|
||||
|
||||
@param xPdfData
|
||||
The PDF data.
|
||||
|
||||
@since LibreOffice 7.0
|
||||
*/
|
||||
sequence<XPrimitive2D> getDecomposition([in] sequence<byte> xPdfData);
|
||||
};
|
||||
|
||||
}; }; }; };
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
@ -81,6 +81,7 @@ $(eval $(call gb_CppunitTest_use_components,sd_import_tests,\
|
|||
filter/source/config/cache/filterconfig1 \
|
||||
filter/source/odfflatxml/odfflatxml \
|
||||
filter/source/svg/svgfilter \
|
||||
filter/source/pdf/pdffilter \
|
||||
filter/source/xmlfilteradaptor/xmlfa \
|
||||
filter/source/xmlfilterdetect/xmlfd \
|
||||
filter/source/storagefilterdetect/storagefd \
|
||||
|
|
|
@ -1301,8 +1301,7 @@ void SdImportTest::testPDFImportShared()
|
|||
// PDF with each image to allow for advanced editing.
|
||||
// Here we iterate over all Graphic instances embedded in the pages
|
||||
// and verify that they all point to the same object in memory.
|
||||
std::vector<std::shared_ptr<std::vector<sal_Int8>>> aPdfSeqSharedPtrs;
|
||||
std::vector<std::shared_ptr<GfxLink>> aGfxLinkSharedPtrs;
|
||||
std::vector<Graphic> aGraphics;
|
||||
|
||||
for (int nPageIndex = 0; nPageIndex < pDoc->GetPageCount(); ++nPageIndex)
|
||||
{
|
||||
|
@ -1322,23 +1321,23 @@ void SdImportTest::testPDFImportShared()
|
|||
|
||||
const GraphicObject& rGraphicObject = pSdrGrafObj->GetGraphicObject().GetGraphic();
|
||||
const Graphic& rGraphic = rGraphicObject.GetGraphic();
|
||||
aPdfSeqSharedPtrs.push_back(rGraphic.getPdfData());
|
||||
aGfxLinkSharedPtrs.push_back(rGraphic.GetSharedGfxLink());
|
||||
aGraphics.push_back(rGraphic);
|
||||
}
|
||||
}
|
||||
|
||||
CPPUNIT_ASSERT_MESSAGE("Expected more than one page.", aPdfSeqSharedPtrs.size() > 1);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected as many PDF streams as GfxLinks.",
|
||||
aPdfSeqSharedPtrs.size(), aGfxLinkSharedPtrs.size());
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected more than one page.", size_t(3), aGraphics.size());
|
||||
|
||||
const std::shared_ptr<std::vector<sal_Int8>> pPdfSeq = aPdfSeqSharedPtrs[0];
|
||||
const std::shared_ptr<GfxLink> pGfxLink = aGfxLinkSharedPtrs[0];
|
||||
for (size_t i = 0; i < aPdfSeqSharedPtrs.size(); ++i)
|
||||
Graphic aFirstGraphic = aGraphics[0];
|
||||
|
||||
for (size_t i = 1; i < aGraphics.size(); ++i)
|
||||
{
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all PDF streams to be identical.",
|
||||
aPdfSeqSharedPtrs[i].get(), pPdfSeq.get());
|
||||
aFirstGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(),
|
||||
aGraphics[i].getVectorGraphicData()->getVectorGraphicDataArray().getConstArray());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all GfxLinks to be identical.",
|
||||
aGfxLinkSharedPtrs[i].get(), pGfxLink.get());
|
||||
aFirstGraphic.GetSharedGfxLink().get(),
|
||||
aGraphics[i].GetSharedGfxLink().get());
|
||||
}
|
||||
|
||||
xDocShRef->DoClose();
|
||||
|
|
|
@ -607,8 +607,7 @@ void SdrEditView::CheckPossibilities()
|
|||
if (pSdrGrafObj != nullptr)
|
||||
{
|
||||
if ((pSdrGrafObj->HasGDIMetaFile() && !pSdrGrafObj->IsEPS()) ||
|
||||
pSdrGrafObj->isEmbeddedVectorGraphicData() ||
|
||||
pSdrGrafObj->isEmbeddedPdfData())
|
||||
pSdrGrafObj->isEmbeddedVectorGraphicData())
|
||||
{
|
||||
m_bImportMtfPossible = true;
|
||||
}
|
||||
|
|
|
@ -2106,17 +2106,6 @@ void SdrEditView::DoImportMarkedMtf(SvdProgressInfo *pProgrInfo)
|
|||
nInsCnt = aFilter.DoImport(aMetaFile, *pOL, nInsPos, pProgrInfo);
|
||||
}
|
||||
}
|
||||
else if (pGraf->isEmbeddedPdfData())
|
||||
{
|
||||
#if HAVE_FEATURE_PDFIUM
|
||||
aLogicRect = pGraf->GetLogicRect();
|
||||
ImpSdrPdfImport aFilter(*mpModel, pObj->GetLayer(), aLogicRect, pGraf->getEmbeddedPdfData());
|
||||
if (pGraf->getEmbeddedPageNumber() < aFilter.GetPageCount())
|
||||
{
|
||||
nInsCnt = aFilter.DoImport(*pOL, nInsPos, pGraf->getEmbeddedPageNumber(), pProgrInfo);
|
||||
}
|
||||
#endif // HAVE_FEATURE_PDFIUM
|
||||
}
|
||||
}
|
||||
|
||||
SdrOle2Obj* pOle2 = dynamic_cast<SdrOle2Obj*>(pObj);
|
||||
|
|
|
@ -282,8 +282,7 @@ const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
|
|||
{
|
||||
const_cast< SdrGrafObj* >(this)->mpReplacementGraphicObject.reset(new GraphicObject(rVectorGraphicDataPtr->getReplacement()));
|
||||
}
|
||||
else if (mpGraphicObject->GetGraphic().hasPdfData() ||
|
||||
mpGraphicObject->GetGraphic().GetType() == GraphicType::GdiMetafile)
|
||||
else if (mpGraphicObject->GetGraphic().GetType() == GraphicType::GdiMetafile)
|
||||
{
|
||||
// Replacement graphic for PDF and metafiles is just the bitmap.
|
||||
const_cast<SdrGrafObj*>(this)->mpReplacementGraphicObject.reset(new GraphicObject(mpGraphicObject->GetGraphic().GetBitmapEx()));
|
||||
|
@ -882,16 +881,6 @@ GDIMetaFile SdrGrafObj::GetMetaFile(GraphicType &rGraphicType) const
|
|||
return GDIMetaFile();
|
||||
}
|
||||
|
||||
bool SdrGrafObj::isEmbeddedPdfData() const
|
||||
{
|
||||
return mpGraphicObject->GetGraphic().hasPdfData();
|
||||
}
|
||||
|
||||
const std::shared_ptr<std::vector<sal_Int8>> & SdrGrafObj::getEmbeddedPdfData() const
|
||||
{
|
||||
return mpGraphicObject->GetGraphic().getPdfData();
|
||||
}
|
||||
|
||||
sal_Int32 SdrGrafObj::getEmbeddedPageNumber() const
|
||||
{
|
||||
return mpGraphicObject->GetGraphic().getPageNumber();
|
||||
|
|
|
@ -754,29 +754,7 @@ 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 std::shared_ptr<std::vector<sal_Int8>> rPdfData = aGraphic.getPdfData();
|
||||
if (rPdfData && !rPdfData->empty())
|
||||
{
|
||||
// See if we have this PDF already, and avoid duplicate storage.
|
||||
auto aIt = maExportPdf.find(rPdfData.get());
|
||||
if (aIt != maExportPdf.end())
|
||||
{
|
||||
auto const& aURLAndMimePair = aIt->second;
|
||||
rOutSavedMimeType = aURLAndMimePair.second;
|
||||
return aURLAndMimePair.first;
|
||||
}
|
||||
|
||||
// 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->data(), rPdfData->size());
|
||||
}
|
||||
else
|
||||
{
|
||||
pStream->WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
|
||||
}
|
||||
|
||||
pStream->WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
|
||||
rOutSavedMimeType = aMimeType;
|
||||
bSuccess = (pStream->GetError() == ERRCODE_NONE);
|
||||
}
|
||||
|
@ -842,8 +820,6 @@ OUString SvXMLGraphicHelper::implSaveGraphic(css::uno::Reference<css::graphic::X
|
|||
|
||||
// put into cache
|
||||
maExportGraphics[aGraphic] = std::make_pair(aStoragePath, rOutSavedMimeType);
|
||||
if (aGraphic.hasPdfData())
|
||||
maExportPdf[aGraphic.getPdfData().get()] = std::make_pair(aStoragePath, rOutSavedMimeType);
|
||||
|
||||
return aStoragePath;
|
||||
}
|
||||
|
|
|
@ -138,8 +138,9 @@ ErrCode XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileName,
|
|||
const bool bIsSvg(rFilterName.equalsIgnoreAsciiCase("svg") && VectorGraphicDataType::Svg == aVectorGraphicDataPtr->getVectorGraphicDataType());
|
||||
const bool bIsWmf(rFilterName.equalsIgnoreAsciiCase("wmf") && VectorGraphicDataType::Wmf == aVectorGraphicDataPtr->getVectorGraphicDataType());
|
||||
const bool bIsEmf(rFilterName.equalsIgnoreAsciiCase("emf") && VectorGraphicDataType::Emf == aVectorGraphicDataPtr->getVectorGraphicDataType());
|
||||
const bool bIsPdf(rFilterName.equalsIgnoreAsciiCase("pdf") && VectorGraphicDataType::Pdf == aVectorGraphicDataPtr->getVectorGraphicDataType());
|
||||
|
||||
if (bIsSvg || bIsWmf || bIsEmf)
|
||||
if (bIsSvg || bIsWmf || bIsEmf || bIsPdf)
|
||||
{
|
||||
if (!(nFlags & XOutFlags::DontAddExtension))
|
||||
{
|
||||
|
@ -163,24 +164,6 @@ ErrCode XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileName,
|
|||
}
|
||||
}
|
||||
|
||||
// Write PDF data in original form if possible.
|
||||
if (rGraphic.hasPdfData() && rFilterName.equalsIgnoreAsciiCase("pdf"))
|
||||
{
|
||||
if (!(nFlags & XOutFlags::DontAddExtension))
|
||||
aURL.setExtension(rFilterName);
|
||||
|
||||
rFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
|
||||
SfxMedium aMedium(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::WRITE|StreamMode::SHARE_DENYNONE|StreamMode::TRUNC);
|
||||
if (SvStream* pOutStream = aMedium.GetOutStream())
|
||||
{
|
||||
const std::shared_ptr<std::vector<sal_Int8>> rPdfData(rGraphic.getPdfData());
|
||||
pOutStream->WriteBytes(rPdfData->data(), rPdfData->size());
|
||||
aMedium.Commit();
|
||||
if (!aMedium.GetError())
|
||||
nErr = ERRCODE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if( ERRCODE_NONE != nErr )
|
||||
{
|
||||
if( ( nFlags & XOutFlags::UseNativeIfPossible ) &&
|
||||
|
|
|
@ -381,8 +381,7 @@ const GraphicObject* SwGrfNode::GetReplacementGrfObj() const
|
|||
{
|
||||
const_cast< SwGrfNode* >(this)->mpReplacementGraphic.reset( new GraphicObject(rVectorGraphicDataPtr->getReplacement()) );
|
||||
}
|
||||
else if (GetGrfObj().GetGraphic().hasPdfData() ||
|
||||
GetGrfObj().GetGraphic().GetType() == GraphicType::GdiMetafile)
|
||||
else if (GetGrfObj().GetGraphic().GetType() == GraphicType::GdiMetafile)
|
||||
{
|
||||
// Replacement graphic for PDF and metafiles is just the bitmap.
|
||||
const_cast<SwGrfNode*>(this)->mpReplacementGraphic.reset( new GraphicObject(GetGrfObj().GetGraphic().GetBitmapEx()) );
|
||||
|
|
|
@ -69,10 +69,6 @@ private:
|
|||
// cache checksum computation
|
||||
mutable BitmapChecksum mnChecksum = 0;
|
||||
|
||||
/// The PDF stream from which this Graphic is rendered,
|
||||
/// as converted (version downgraded) from the original,
|
||||
/// which should be in GfxLink.
|
||||
std::shared_ptr<std::vector<sal_Int8>> mpPdfData;
|
||||
std::unique_ptr<GraphicID> mpGraphicID;
|
||||
GraphicExternalLink maGraphicExternalLink;
|
||||
|
||||
|
@ -122,11 +118,6 @@ private:
|
|||
return mpGraphicID->getIDString();
|
||||
}
|
||||
|
||||
bool hasPdfData() const
|
||||
{
|
||||
return mpPdfData && !mpPdfData->empty();
|
||||
}
|
||||
|
||||
void ImplCreateSwapInfo();
|
||||
void ImplClearGraphics();
|
||||
void ImplClear();
|
||||
|
@ -209,10 +200,6 @@ private:
|
|||
|
||||
const VectorGraphicDataPtr& getVectorGraphicData() const;
|
||||
|
||||
const std::shared_ptr<std::vector<sal_Int8>> & getPdfData() const;
|
||||
|
||||
void setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData);
|
||||
|
||||
bool ensureAvailable () const;
|
||||
|
||||
bool loadPrepared();
|
||||
|
|
|
@ -46,20 +46,6 @@ inline double pointToPixel(const double fPoint, const double fResolutionDPI)
|
|||
return fPoint * fResolutionDPI / 72.;
|
||||
}
|
||||
|
||||
/// Does PDF to bitmap conversion using pdfium.
|
||||
size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps, sal_uInt64 nPos,
|
||||
sal_uInt64 nSize, const size_t nFirstPage = 0, int nPages = 1,
|
||||
const double fResolutionDPI = 96.)
|
||||
{
|
||||
// Read input into a buffer.
|
||||
SvMemoryStream aInBuffer;
|
||||
rStream.Seek(nPos);
|
||||
aInBuffer.WriteStream(rStream, nSize);
|
||||
|
||||
return vcl::RenderPDFBitmaps(aInBuffer.GetData(), aInBuffer.GetSize(), rBitmaps, nFirstPage,
|
||||
nPages, fResolutionDPI);
|
||||
}
|
||||
|
||||
/// Decide if PDF data is old enough to be compatible.
|
||||
bool isCompatible(SvStream& rInStream, sal_uInt64 nPos, sal_uInt64 nSize)
|
||||
{
|
||||
|
@ -130,12 +116,6 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, sal_uInt64 n
|
|||
return rOutStream.good();
|
||||
}
|
||||
#else
|
||||
size_t generatePreview(SvStream&, std::vector<Bitmap>&, sal_uInt64, sal_uInt64, size_t, int,
|
||||
const double)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, sal_uInt64 nPos,
|
||||
sal_uInt64 nSize)
|
||||
{
|
||||
|
@ -144,8 +124,28 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, sal_uInt64 n
|
|||
return rOutStream.good();
|
||||
}
|
||||
#endif // HAVE_FEATURE_PDFIUM
|
||||
|
||||
VectorGraphicDataArray createVectorGraphicDataArray(SvStream& rStream)
|
||||
{
|
||||
// Save the original PDF stream for later use.
|
||||
SvMemoryStream aMemoryStream;
|
||||
if (!getCompatibleStream(rStream, aMemoryStream, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END))
|
||||
return VectorGraphicDataArray();
|
||||
|
||||
const sal_uInt32 nStreamLength = aMemoryStream.TellEnd();
|
||||
|
||||
VectorGraphicDataArray aPdfData(nStreamLength);
|
||||
|
||||
aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
|
||||
aMemoryStream.ReadBytes(aPdfData.begin(), nStreamLength);
|
||||
if (aMemoryStream.GetError())
|
||||
return VectorGraphicDataArray();
|
||||
|
||||
return aPdfData;
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace vcl
|
||||
{
|
||||
size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBitmaps,
|
||||
|
@ -221,65 +221,26 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBi
|
|||
#endif // HAVE_FEATURE_PDFIUM
|
||||
}
|
||||
|
||||
bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, size_t nPageIndex,
|
||||
std::vector<sal_Int8>& rPdfData, sal_uInt64 nPos, sal_uInt64 nSize,
|
||||
const double fResolutionDPI)
|
||||
bool ImportPDF(SvStream& rStream, Graphic& rGraphic)
|
||||
{
|
||||
// Get the preview of the first page.
|
||||
std::vector<Bitmap> aBitmaps;
|
||||
if (generatePreview(rStream, aBitmaps, nPos, nSize, nPageIndex, 1, fResolutionDPI) != 1
|
||||
|| aBitmaps.empty())
|
||||
return false;
|
||||
|
||||
rBitmap = aBitmaps[0];
|
||||
|
||||
// Save the original PDF stream for later use.
|
||||
SvMemoryStream aMemoryStream;
|
||||
if (!getCompatibleStream(rStream, aMemoryStream, nPos, nSize))
|
||||
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())
|
||||
return false;
|
||||
|
||||
rPdfData = std::vector<sal_Int8>(aMemoryStream.TellEnd());
|
||||
aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
|
||||
aMemoryStream.ReadBytes(rPdfData.data(), rPdfData.size());
|
||||
auto aVectorGraphicDataPtr
|
||||
= std::make_shared<VectorGraphicData>(aPdfData, OUString(), VectorGraphicDataType::Pdf);
|
||||
|
||||
rGraphic = Graphic(aVectorGraphicDataPtr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImportPDF(SvStream& rStream, Graphic& rGraphic, const double fResolutionDPI)
|
||||
{
|
||||
std::vector<sal_Int8> aPdfData;
|
||||
Bitmap aBitmap;
|
||||
const bool bRet = ImportPDF(rStream, aBitmap, 0, aPdfData, STREAM_SEEK_TO_BEGIN,
|
||||
STREAM_SEEK_TO_END, fResolutionDPI);
|
||||
rGraphic = aBitmap;
|
||||
rGraphic.setPdfData(std::make_shared<std::vector<sal_Int8>>(aPdfData));
|
||||
rGraphic.setPageNumber(0); // We currently import only the first page.
|
||||
return bRet;
|
||||
}
|
||||
|
||||
size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps,
|
||||
std::vector<sal_Int8>& rPdfData, const double fResolutionDPI)
|
||||
{
|
||||
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,
|
||||
fResolutionDPI)
|
||||
== 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;
|
||||
|
||||
rPdfData = std::vector<sal_Int8>(aMemoryStream.TellEnd());
|
||||
aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
|
||||
aMemoryStream.ReadBytes(rPdfData.data(), rPdfData.size());
|
||||
|
||||
return rBitmaps.size();
|
||||
}
|
||||
|
||||
size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Size>>& rGraphics,
|
||||
const double fResolutionDPI)
|
||||
{
|
||||
|
@ -288,22 +249,18 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si
|
|||
::utl::UcbStreamHelper::CreateStream(rURL, StreamMode::READ | StreamMode::SHARE_DENYNONE));
|
||||
|
||||
// Save the original PDF stream for later use.
|
||||
SvMemoryStream aMemoryStream;
|
||||
if (!getCompatibleStream(*xStream, aMemoryStream, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END))
|
||||
VectorGraphicDataArray aPdfDataArray = createVectorGraphicDataArray(*xStream);
|
||||
if (!aPdfDataArray.hasElements())
|
||||
return 0;
|
||||
|
||||
// Copy into PdfData
|
||||
aMemoryStream.Seek(STREAM_SEEK_TO_END);
|
||||
auto pPdfData = std::make_shared<std::vector<sal_Int8>>(aMemoryStream.Tell());
|
||||
aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
|
||||
aMemoryStream.ReadBytes(pPdfData->data(), pPdfData->size());
|
||||
|
||||
// Prepare the link with the PDF stream.
|
||||
const size_t nGraphicContentSize = pPdfData->size();
|
||||
const size_t nGraphicContentSize = aPdfDataArray.getLength();
|
||||
std::unique_ptr<sal_uInt8[]> pGraphicContent(new sal_uInt8[nGraphicContentSize]);
|
||||
memcpy(pGraphicContent.get(), pPdfData->data(), nGraphicContentSize);
|
||||
std::shared_ptr<GfxLink> pGfxLink(std::make_shared<GfxLink>(
|
||||
std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf));
|
||||
|
||||
std::copy(aPdfDataArray.begin(), aPdfDataArray.end(), pGraphicContent.get());
|
||||
|
||||
auto pGfxLink = std::make_shared<GfxLink>(std::move(pGraphicContent), nGraphicContentSize,
|
||||
GfxLinkType::NativePdf);
|
||||
|
||||
FPDF_LIBRARY_CONFIG aConfig;
|
||||
aConfig.version = 2;
|
||||
|
@ -314,7 +271,7 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si
|
|||
|
||||
// Load the buffer using pdfium.
|
||||
FPDF_DOCUMENT pPdfDocument
|
||||
= FPDF_LoadMemDocument(pPdfData->data(), pPdfData->size(), /*password=*/nullptr);
|
||||
= FPDF_LoadMemDocument(pGfxLink->GetData(), pGfxLink->GetDataSize(), /*password=*/nullptr);
|
||||
if (!pPdfDocument)
|
||||
return 0;
|
||||
|
||||
|
@ -322,9 +279,6 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si
|
|||
if (nPageCount <= 0)
|
||||
return 0;
|
||||
|
||||
// dummy Bitmap
|
||||
Bitmap aBitmap(Size(1, 1), 24);
|
||||
|
||||
for (int nPageIndex = 0; nPageIndex < nPageCount; ++nPageIndex)
|
||||
{
|
||||
double fPageWidth = 0;
|
||||
|
@ -336,11 +290,13 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si
|
|||
const size_t nPageWidth = pointToPixel(fPageWidth, fResolutionDPI);
|
||||
const size_t nPageHeight = pointToPixel(fPageHeight, fResolutionDPI);
|
||||
|
||||
// Create the Graphic with a dummy Bitmap and link the original PDF stream.
|
||||
auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(
|
||||
aPdfDataArray, OUString(), VectorGraphicDataType::Pdf);
|
||||
|
||||
// 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(aBitmap);
|
||||
aGraphic.setPdfData(pPdfData);
|
||||
Graphic aGraphic(aVectorGraphicDataPtr);
|
||||
aGraphic.setPageNumber(nPageIndex);
|
||||
aGraphic.SetGfxLink(pGfxLink);
|
||||
|
||||
|
|
|
@ -560,23 +560,6 @@ const VectorGraphicDataPtr& Graphic::getVectorGraphicData() const
|
|||
return mxImpGraphic->getVectorGraphicData();
|
||||
}
|
||||
|
||||
void Graphic::setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData)
|
||||
{
|
||||
ImplTestRefCount();
|
||||
mxImpGraphic->setPdfData(rPdfData);
|
||||
}
|
||||
|
||||
const std::shared_ptr<std::vector<sal_Int8>> & Graphic::getPdfData() const
|
||||
{
|
||||
return mxImpGraphic->getPdfData();
|
||||
}
|
||||
|
||||
bool Graphic::hasPdfData() const
|
||||
{
|
||||
std::shared_ptr<std::vector<sal_Int8>> pPdfData(getPdfData());
|
||||
return pPdfData && !pPdfData->empty();
|
||||
}
|
||||
|
||||
void Graphic::setPageNumber(sal_Int32 nPageNumber)
|
||||
{
|
||||
mxImpGraphic->mnPageNumber = nPageNumber;
|
||||
|
|
|
@ -58,8 +58,6 @@
|
|||
#define GRAPHIC_FORMAT_50 COMPAT_FORMAT( 'G', 'R', 'F', '5' )
|
||||
#define NATIVE_FORMAT_50 COMPAT_FORMAT( 'N', 'A', 'T', '5' )
|
||||
|
||||
const sal_uInt32 nPdfMagic((sal_uInt32('p') << 24) | (sal_uInt32('d') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
||||
struct ImpSwapFile
|
||||
|
@ -92,7 +90,6 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic)
|
|||
, mbSwapOut(rImpGraphic.mbSwapOut)
|
||||
, mbDummyContext(rImpGraphic.mbDummyContext)
|
||||
, maVectorGraphicData(rImpGraphic.maVectorGraphicData)
|
||||
, mpPdfData(rImpGraphic.mpPdfData)
|
||||
, maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
|
||||
, maLastUsed (std::chrono::high_resolution_clock::now())
|
||||
, mbPrepared (rImpGraphic.mbPrepared)
|
||||
|
@ -118,7 +115,6 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) noexcept
|
|||
, mbSwapOut(rImpGraphic.mbSwapOut)
|
||||
, mbDummyContext(rImpGraphic.mbDummyContext)
|
||||
, maVectorGraphicData(std::move(rImpGraphic.maVectorGraphicData))
|
||||
, mpPdfData(std::move(rImpGraphic.mpPdfData))
|
||||
, maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
|
||||
, maLastUsed (std::chrono::high_resolution_clock::now())
|
||||
, mbPrepared (rImpGraphic.mbPrepared)
|
||||
|
@ -241,7 +237,6 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
|
|||
mpGfxLink = rImpGraphic.mpGfxLink;
|
||||
|
||||
maVectorGraphicData = rImpGraphic.maVectorGraphicData;
|
||||
mpPdfData = rImpGraphic.mpPdfData;
|
||||
maLastUsed = std::chrono::high_resolution_clock::now();
|
||||
|
||||
vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes);
|
||||
|
@ -267,7 +262,6 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic)
|
|||
mpSwapFile = std::move(rImpGraphic.mpSwapFile);
|
||||
mpGfxLink = std::move(rImpGraphic.mpGfxLink);
|
||||
maVectorGraphicData = std::move(rImpGraphic.maVectorGraphicData);
|
||||
mpPdfData = std::move(rImpGraphic.mpPdfData);
|
||||
maGraphicExternalLink = rImpGraphic.maGraphicExternalLink;
|
||||
mbPrepared = rImpGraphic.mbPrepared;
|
||||
|
||||
|
@ -322,10 +316,6 @@ bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
|
|||
bRet = (*maVectorGraphicData) == (*rImpGraphic.maVectorGraphicData);
|
||||
}
|
||||
}
|
||||
else if (mpPdfData && !mpPdfData->empty())
|
||||
{
|
||||
bRet = (rImpGraphic.mpPdfData && *mpPdfData == *rImpGraphic.mpPdfData);
|
||||
}
|
||||
else if( mpAnimation )
|
||||
{
|
||||
if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) )
|
||||
|
@ -353,20 +343,6 @@ const VectorGraphicDataPtr& ImpGraphic::getVectorGraphicData() const
|
|||
return maVectorGraphicData;
|
||||
}
|
||||
|
||||
void ImpGraphic::setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData)
|
||||
{
|
||||
ensureAvailable();
|
||||
|
||||
mpPdfData = rPdfData;
|
||||
}
|
||||
|
||||
const std::shared_ptr<std::vector<sal_Int8>> & ImpGraphic::getPdfData() const
|
||||
{
|
||||
ensureAvailable();
|
||||
|
||||
return mpPdfData;
|
||||
}
|
||||
|
||||
void ImpGraphic::ImplCreateSwapInfo()
|
||||
{
|
||||
if (!ImplIsSwapOut())
|
||||
|
@ -388,7 +364,6 @@ void ImpGraphic::ImplClearGraphics()
|
|||
mpAnimation.reset();
|
||||
mpGfxLink.reset();
|
||||
maVectorGraphicData.reset();
|
||||
mpPdfData.reset();
|
||||
}
|
||||
|
||||
ImpSwapFile::~ImpSwapFile()
|
||||
|
@ -1601,10 +1576,6 @@ BitmapChecksum ImpGraphic::ImplGetChecksum() const
|
|||
{
|
||||
if(maVectorGraphicData)
|
||||
nRet = maVectorGraphicData->GetChecksum();
|
||||
else if (mpPdfData && !mpPdfData->empty())
|
||||
// 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, mpPdfData->data(), mpPdfData->size());
|
||||
else if( mpAnimation )
|
||||
nRet = mpAnimation->GetChecksum();
|
||||
else
|
||||
|
@ -1760,12 +1731,13 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
|
|||
const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
|
||||
const sal_uInt32 nWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
|
||||
const sal_uInt32 nEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
|
||||
const sal_uInt32 nPdfMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
|
||||
sal_uInt32 nMagic;
|
||||
rIStm.Seek(nStmPos1);
|
||||
rIStm.ResetError();
|
||||
rIStm.ReadUInt32( nMagic );
|
||||
|
||||
if (nSvgMagic == nMagic || nWmfMagic == nMagic || nEmfMagic == nMagic)
|
||||
if (nSvgMagic == nMagic || nWmfMagic == nMagic || nEmfMagic == nMagic || nPdfMagic == nMagic)
|
||||
{
|
||||
sal_uInt32 nVectorGraphicDataArrayLength(0);
|
||||
rIStm.ReadUInt32(nVectorGraphicDataArrayLength);
|
||||
|
@ -1789,35 +1761,16 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
|
|||
{
|
||||
aDataType = VectorGraphicDataType::Emf;
|
||||
}
|
||||
else if (nPdfMagic == nMagic)
|
||||
{
|
||||
aDataType = VectorGraphicDataType::Pdf;
|
||||
}
|
||||
|
||||
VectorGraphicDataPtr aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aNewData, aPath, aDataType);
|
||||
rImpGraphic = aVectorGraphicDataPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nMagic == nPdfMagic)
|
||||
{
|
||||
// Stream in PDF data.
|
||||
BitmapChecksum nPdfId = 0;
|
||||
rIStm.ReadUInt64(nPdfId);
|
||||
|
||||
rImpGraphic.mnPageNumber = 0;
|
||||
rIStm.ReadInt32(rImpGraphic.mnPageNumber);
|
||||
|
||||
auto it = sPdfDataCache.find(nPdfId);
|
||||
assert(it != sPdfDataCache.end());
|
||||
|
||||
rImpGraphic.mpPdfData = it->second;
|
||||
|
||||
Bitmap aBitmap;
|
||||
rImpGraphic.maEx = aBitmap;
|
||||
|
||||
std::vector<Bitmap> aBitmaps;
|
||||
if (vcl::RenderPDFBitmaps(rImpGraphic.mpPdfData->data(), rImpGraphic.mpPdfData->size(), aBitmaps, rImpGraphic.mnPageNumber, 1) == 1)
|
||||
rImpGraphic.maEx = aBitmaps[0];
|
||||
|
||||
rImpGraphic.meType = GraphicType::Bitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
rIStm.SetError(nOrigError);
|
||||
|
@ -1845,8 +1798,7 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic)
|
|||
|
||||
if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) &&
|
||||
( rOStm.GetCompressMode() & SvStreamCompressFlags::NATIVE ) &&
|
||||
rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() &&
|
||||
!rImpGraphic.hasPdfData())
|
||||
rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative())
|
||||
{
|
||||
// native format
|
||||
rOStm.WriteUInt32( NATIVE_FORMAT_50 );
|
||||
|
@ -1894,12 +1846,18 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic)
|
|||
rOStm.WriteUInt32(nEmfMagic);
|
||||
break;
|
||||
}
|
||||
default: // case VectorGraphicDataType::Svg:
|
||||
case VectorGraphicDataType::Svg:
|
||||
{
|
||||
const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
|
||||
rOStm.WriteUInt32(nSvgMagic);
|
||||
break;
|
||||
}
|
||||
case VectorGraphicDataType::Pdf:
|
||||
{
|
||||
const sal_uInt32 nSvgMagic((sal_uInt32('p') << 24) | (sal_uInt32('d') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0'));
|
||||
rOStm.WriteUInt32(nSvgMagic);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rOStm.WriteUInt32( rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength() );
|
||||
|
@ -1908,17 +1866,6 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic)
|
|||
rOStm.WriteUniOrByteString(rImpGraphic.getVectorGraphicData()->getPath(),
|
||||
rOStm.GetStreamCharSet());
|
||||
}
|
||||
else if (rImpGraphic.hasPdfData())
|
||||
{
|
||||
BitmapChecksum nPdfId = vcl_get_checksum(0, rImpGraphic.mpPdfData->data(), rImpGraphic.mpPdfData->size());
|
||||
if (sPdfDataCache.find(nPdfId) == sPdfDataCache.end())
|
||||
sPdfDataCache.emplace(nPdfId, rImpGraphic.mpPdfData);
|
||||
|
||||
// Stream out PDF data.
|
||||
rOStm.WriteUInt32(nPdfMagic);
|
||||
rOStm.WriteUInt64(nPdfId);
|
||||
rOStm.WriteInt32(rImpGraphic.mnPageNumber);
|
||||
}
|
||||
else if( rImpGraphic.ImplIsAnimated())
|
||||
{
|
||||
WriteAnimation( rOStm, *rImpGraphic.mpAnimation );
|
||||
|
|
|
@ -9139,20 +9139,24 @@ void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObject
|
|||
// no pdf data.
|
||||
rEmit.m_nBitmapObject = nBitmapObject;
|
||||
|
||||
if (!rGraphic.hasPdfData())
|
||||
if (!rGraphic.getVectorGraphicData().get() || rGraphic.getVectorGraphicData()->getVectorGraphicDataType() != VectorGraphicDataType::Pdf)
|
||||
return;
|
||||
|
||||
sal_uInt32 nLength = rGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength();
|
||||
auto const & rArray = rGraphic.getVectorGraphicData()->getVectorGraphicDataArray();
|
||||
|
||||
auto pPDFData = std::make_shared<std::vector<sal_Int8>>(rArray.getConstArray(), rArray.getConstArray() + nLength);
|
||||
|
||||
if (m_aContext.UseReferenceXObject)
|
||||
{
|
||||
// Store the original PDF data as an embedded file.
|
||||
m_aEmbeddedFiles.emplace_back();
|
||||
m_aEmbeddedFiles.back().m_nObject = createObject();
|
||||
m_aEmbeddedFiles.back().m_pData = rGraphic.getPdfData();
|
||||
|
||||
m_aEmbeddedFiles.back().m_pData = pPDFData;
|
||||
rEmit.m_nEmbeddedObject = m_aEmbeddedFiles.back().m_nObject;
|
||||
}
|
||||
else
|
||||
rEmit.m_aPDFData = *rGraphic.getPdfData();
|
||||
rEmit.m_aPDFData = *pPDFData;
|
||||
|
||||
rEmit.m_nFormObject = createObject();
|
||||
rEmit.m_aPixelSize = rGraphic.GetPrefSize();
|
||||
|
@ -9207,7 +9211,7 @@ void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const
|
|||
{
|
||||
m_aJPGs.emplace( m_aJPGs.begin() );
|
||||
JPGEmit& rEmit = m_aJPGs.front();
|
||||
if (!rGraphic.hasPdfData() || m_aContext.UseReferenceXObject)
|
||||
if (!rGraphic.getVectorGraphicData().get() || rGraphic.getVectorGraphicData()->getVectorGraphicDataType() != VectorGraphicDataType::Pdf || m_aContext.UseReferenceXObject)
|
||||
rEmit.m_nObject = createObject();
|
||||
rEmit.m_aID = aID;
|
||||
rEmit.m_pStream = std::move( pStream );
|
||||
|
@ -9311,7 +9315,7 @@ const BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx& i_rBitmap, co
|
|||
m_aBitmaps.push_front( BitmapEmit() );
|
||||
m_aBitmaps.front().m_aID = aID;
|
||||
m_aBitmaps.front().m_aBitmap = aBitmap;
|
||||
if (!rGraphic.hasPdfData() || m_aContext.UseReferenceXObject)
|
||||
if (!rGraphic.getVectorGraphicData().get() || rGraphic.getVectorGraphicData()->getVectorGraphicDataType() != VectorGraphicDataType::Pdf || 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();
|
||||
|
|
|
@ -22,17 +22,21 @@
|
|||
#include <sal/log.hxx>
|
||||
#include <vcl/vectorgraphicdata.hxx>
|
||||
#include <comphelper/processfactory.hxx>
|
||||
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
||||
#include <com/sun/star/graphic/PdfTools.hpp>
|
||||
#include <com/sun/star/graphic/SvgTools.hpp>
|
||||
#include <com/sun/star/graphic/EmfTools.hpp>
|
||||
#include <com/sun/star/graphic/Primitive2DTools.hpp>
|
||||
#include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
|
||||
#include <com/sun/star/util/XAccounting.hpp>
|
||||
#include <basegfx/matrix/b2dhommatrixtools.hxx>
|
||||
#include <vcl/canvastools.hxx>
|
||||
#include <comphelper/seqstream.hxx>
|
||||
#include <comphelper/sequence.hxx>
|
||||
#include <vcl/svapp.hxx>
|
||||
#include <vcl/outdev.hxx>
|
||||
#include <vcl/wmfexternal.hxx>
|
||||
#include <vcl/pdfread.hxx>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
|
||||
|
@ -133,11 +137,35 @@ void VectorGraphicData::setWmfExternalHeader(const WmfExternal& aExtHeader)
|
|||
*mpExternalHeader = aExtHeader;
|
||||
}
|
||||
|
||||
void VectorGraphicData::ensurePdfReplacement()
|
||||
{
|
||||
assert(getVectorGraphicDataType() == VectorGraphicDataType::Pdf);
|
||||
|
||||
if (!maReplacement.IsEmpty())
|
||||
return; // nothing to do
|
||||
|
||||
// use PDFium directly
|
||||
std::vector<Bitmap> aBitmaps;
|
||||
vcl::RenderPDFBitmaps(maVectorGraphicDataArray.getConstArray(), maVectorGraphicDataArray.getLength(), aBitmaps, 0, 1/*, fResolutionDPI*/);
|
||||
maReplacement = aBitmaps[0];
|
||||
}
|
||||
|
||||
void VectorGraphicData::ensureReplacement()
|
||||
{
|
||||
if (!maReplacement.IsEmpty())
|
||||
return; // nothing to do
|
||||
|
||||
// shortcut for PDF - PDFium can generate the replacement bitmap for us
|
||||
// directly
|
||||
if (getVectorGraphicDataType() == VectorGraphicDataType::Pdf)
|
||||
{
|
||||
ensurePdfReplacement();
|
||||
return;
|
||||
}
|
||||
|
||||
ensureSequenceAndRange();
|
||||
|
||||
if(maReplacement.IsEmpty() && !maSequence.empty())
|
||||
if (!maSequence.empty())
|
||||
{
|
||||
maReplacement = convertPrimitive2DSequenceToBitmapEx(maSequence, getRange());
|
||||
}
|
||||
|
@ -150,32 +178,43 @@ void VectorGraphicData::ensureSequenceAndRange()
|
|||
// import SVG to maSequence, also set maRange
|
||||
maRange.reset();
|
||||
|
||||
// create stream
|
||||
const uno::Reference< io::XInputStream > myInputStream(new comphelper::SequenceInputStream(maVectorGraphicDataArray));
|
||||
// create Vector Graphic Data interpreter
|
||||
uno::Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext());
|
||||
|
||||
if(myInputStream.is())
|
||||
switch (getVectorGraphicDataType())
|
||||
{
|
||||
// create Vector Graphic Data interpreter
|
||||
uno::Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext());
|
||||
case VectorGraphicDataType::Svg:
|
||||
{
|
||||
const uno::Reference< graphic::XSvgParser > xSvgParser = graphic::SvgTools::create(xContext);
|
||||
const uno::Reference< io::XInputStream > myInputStream(new comphelper::SequenceInputStream(maVectorGraphicDataArray));
|
||||
|
||||
if (VectorGraphicDataType::Emf == getVectorGraphicDataType()
|
||||
|| VectorGraphicDataType::Wmf == getVectorGraphicDataType())
|
||||
if (myInputStream.is())
|
||||
maSequence = comphelper::sequenceToContainer<std::deque<css::uno::Reference< css::graphic::XPrimitive2D >>>(xSvgParser->getDecomposition(myInputStream, maPath));
|
||||
|
||||
break;
|
||||
}
|
||||
case VectorGraphicDataType::Emf:
|
||||
case VectorGraphicDataType::Wmf:
|
||||
{
|
||||
const uno::Reference< graphic::XEmfParser > xEmfParser = graphic::EmfTools::create(xContext);
|
||||
const uno::Reference< io::XInputStream > myInputStream(new comphelper::SequenceInputStream(maVectorGraphicDataArray));
|
||||
uno::Sequence< ::beans::PropertyValue > aSequence;
|
||||
|
||||
if (mpExternalHeader)
|
||||
{
|
||||
aSequence = mpExternalHeader->getSequence();
|
||||
}
|
||||
|
||||
maSequence = comphelper::sequenceToContainer<std::deque<css::uno::Reference< css::graphic::XPrimitive2D >>>(xEmfParser->getDecomposition(myInputStream, maPath, aSequence));
|
||||
if (myInputStream.is())
|
||||
maSequence = comphelper::sequenceToContainer<std::deque<css::uno::Reference< css::graphic::XPrimitive2D >>>(xEmfParser->getDecomposition(myInputStream, maPath, aSequence));
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
case VectorGraphicDataType::Pdf:
|
||||
{
|
||||
const uno::Reference< graphic::XSvgParser > xSvgParser = graphic::SvgTools::create(xContext);
|
||||
const uno::Reference<graphic::XPdfDecomposer> xPdfDecomposer = graphic::PdfTools::create(xContext);
|
||||
auto xPrimitive2D = xPdfDecomposer->getDecomposition(maVectorGraphicDataArray);
|
||||
maSequence = comphelper::sequenceToContainer<std::deque<uno::Reference<graphic::XPrimitive2D>>>(xPrimitive2D);
|
||||
|
||||
maSequence = comphelper::sequenceToContainer<std::deque<css::uno::Reference< css::graphic::XPrimitive2D >>>(xSvgParser->getDecomposition(myInputStream, maPath));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,16 +42,6 @@ GraphicID::GraphicID(ImpGraphic const& rGraphic)
|
|||
0, rVectorGraphicDataPtr->getVectorGraphicDataArray().getConstArray(),
|
||||
rVectorGraphicDataPtr->getVectorGraphicDataArrayLength());
|
||||
}
|
||||
else if (rGraphic.hasPdfData())
|
||||
{
|
||||
std::shared_ptr<std::vector<sal_Int8>> pPdfData = rGraphic.getPdfData();
|
||||
const BitmapEx& rBmpEx = rGraphic.ImplGetBitmapExRef();
|
||||
|
||||
mnID1 |= (rGraphic.mnPageNumber & 0x0fffffff);
|
||||
mnID2 = rBmpEx.GetSizePixel().Width();
|
||||
mnID3 = rBmpEx.GetSizePixel().Height();
|
||||
mnID4 = vcl_get_checksum(0, pPdfData->data(), pPdfData->size());
|
||||
}
|
||||
else if (rGraphic.ImplIsAnimated())
|
||||
{
|
||||
const Animation aAnimation(rGraphic.ImplGetAnimation());
|
||||
|
|
Loading…
Reference in a new issue