summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorJan Holesovsky <kendy@collabora.com>2019-10-18 11:19:04 +0200
committerTomaž Vajngerl <quikee@gmail.com>2020-06-06 19:23:54 +0200
commit15834ad4dee944374f4b6298f2d384d185a49815 (patch)
treebb52eb53d8e48fbab826374bb982b18341a373cd /vcl
parent3862929efcc5e9275d878bbe64cb034796e4012d (diff)
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> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95618 Tested-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/impgraph.hxx13
-rw-r--r--vcl/source/filter/ipdf/pdfread.cxx134
-rw-r--r--vcl/source/gdi/graph.cxx17
-rw-r--r--vcl/source/gdi/impgraph.cxx81
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx16
-rw-r--r--vcl/source/gdi/vectorgraphicdata.cxx67
-rw-r--r--vcl/source/graphic/GraphicID.cxx10
7 files changed, 122 insertions, 216 deletions
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index 62a44b7e17a9..d49856011996 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -71,10 +71,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;
@@ -124,11 +120,6 @@ private:
return mpGraphicID->getIDString();
}
- bool hasPdfData() const
- {
- return mpPdfData && !mpPdfData->empty();
- }
-
void ImplCreateSwapInfo();
void ImplClearGraphics();
void ImplClear();
@@ -211,10 +202,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);
-
/// Gets the bitmap replacement for a vector graphic.
BitmapEx getVectorGraphicReplacement() const;
diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index 1d253d023424..b960c41483ec 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -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,63 +221,24 @@ 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;
-
- rPdfData = std::vector<sal_Int8>(aMemoryStream.TellEnd());
+ const sal_uInt32 nStreamLength = aMemoryStream.TellEnd();
+ VectorGraphicDataArray aPdfData(nStreamLength);
aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
- aMemoryStream.ReadBytes(rPdfData.data(), rPdfData.size());
-
- 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;
+ 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);
- return rBitmaps.size();
+ rGraphic = Graphic(aVectorGraphicDataPtr);
+ return true;
}
size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Size>>& rGraphics,
@@ -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);
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
index ec2de64a74fe..250c01f674d0 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -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;
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index e55fb7f12395..f60b165d0084 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -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()
@@ -1623,10 +1598,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
@@ -1780,12 +1751,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);
@@ -1809,35 +1781,16 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
{
aDataType = VectorGraphicDataType::Emf;
}
+ else if (nPdfMagic == nMagic)
+ {
+ aDataType = VectorGraphicDataType::Pdf;
+ }
VectorGraphicDataPtr aVectorGraphicDataPtr(new 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);
@@ -1865,8 +1818,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 );
@@ -1913,12 +1865,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() );
@@ -1927,17 +1885,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 );
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 35ac2e7dc6e0..807c2b5a60d8 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -9423,20 +9423,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();
@@ -9491,7 +9495,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 );
@@ -9595,7 +9599,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.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();
diff --git a/vcl/source/gdi/vectorgraphicdata.cxx b/vcl/source/gdi/vectorgraphicdata.cxx
index 09e1d45974c5..9d877b35a73a 100644
--- a/vcl/source/gdi/vectorgraphicdata.cxx
+++ b/vcl/source/gdi/vectorgraphicdata.cxx
@@ -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;
}
}
diff --git a/vcl/source/graphic/GraphicID.cxx b/vcl/source/graphic/GraphicID.cxx
index 7220853b998b..15de2a0d6f0f 100644
--- a/vcl/source/graphic/GraphicID.cxx
+++ b/vcl/source/graphic/GraphicID.cxx
@@ -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());