From 878a860dff10bd91491d6c9f2f4e2308bfe4f0b2 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 23 Jun 2016 12:53:54 +0200 Subject: vcl: add initial PDF import-as-graphic filter This allows Insert -> Image e.g. in Writer to read a PDF file, and insert the metafile equivalent of the first page into the document. Currently the original PDF document is lost on import (unlike when inserting an SVG file). Change-Id: Ib0472c5d9bd9a1da054353fa3a3a638a1052721e Reviewed-on: https://gerrit.libreoffice.org/26586 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- vcl/source/filter/ipdf/pdfread.cxx | 107 +++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 vcl/source/filter/ipdf/pdfread.cxx (limited to 'vcl/source/filter/ipdf/pdfread.cxx') diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx new file mode 100644 index 000000000000..cc63415eba6d --- /dev/null +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -0,0 +1,107 @@ +/* -*- 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/. + */ + +#include "pdfread.hxx" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace com::sun::star; + +namespace +{ + +/// Imports a PDF stream into Draw. +uno::Reference importIntoDraw(SvStream& rStream) +{ + // Create an empty Draw component. + uno::Reference xDesktop = css::frame::Desktop::create(comphelper::getProcessComponentContext()); + uno::Reference xComponentLoader(xDesktop, uno::UNO_QUERY); + uno::Sequence aLoadArguments = + { + comphelper::makePropertyValue("Hidden", true) + }; + uno::Reference xComponent = xComponentLoader->loadComponentFromURL("private:factory/sdraw", "_default", 0, aLoadArguments); + + // Import the PDF into it. + uno::Reference xMultiServiceFactory(comphelper::getProcessServiceFactory()); + // Need to go via FilterFactory, otherwise XmlFilterAdaptor::initialize() is not called. + uno::Reference xFilterFactory(xMultiServiceFactory->createInstance("com.sun.star.document.FilterFactory"), uno::UNO_QUERY); + uno::Reference xFilter(xFilterFactory->createInstanceWithArguments("draw_pdf_import", uno::Sequence()), uno::UNO_QUERY); + uno::Reference xImporter(xFilter, uno::UNO_QUERY); + xImporter->setTargetDocument(xComponent); + + uno::Reference xStream(new utl::OStreamWrapper(rStream)); + uno::Sequence aImportArguments = + { + // XmlFilterAdaptor::importImpl() mandates URL, even if it's empty. + comphelper::makePropertyValue("URL", OUString()), + comphelper::makePropertyValue("InputStream", xStream), + }; + + if (xFilter->filter(aImportArguments)) + return xComponent; + else + { + xComponent->dispose(); + return uno::Reference(); + } +} + +} + +VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic) +{ + uno::Reference xComponent = importIntoDraw(rStream); + if (!xComponent.is()) + return false; + comphelper::ScopeGuard aGuard([&xComponent]() + { + xComponent->dispose(); + }); + + // Get the preview of the first page. + uno::Reference xDrawPagesSupplier(xComponent, uno::UNO_QUERY); + uno::Reference xDrawPages = xDrawPagesSupplier->getDrawPages(); + if (xDrawPages->getCount() <= 0) + return false; + + uno::Reference xFirstPage(xDrawPages->getByIndex(0), uno::UNO_QUERY); + uno::Sequence aSequence; + if (!(xFirstPage->getPropertyValue("Preview") >>= aSequence)) + return false; + + if (!aSequence.hasElements()) + return false; + + // Convert it into a GDIMetaFile. + SvMemoryStream aPreviewStream(aSequence.getLength()); + aPreviewStream.WriteBytes(aSequence.getArray(), aSequence.getLength()); + aPreviewStream.Seek(0); + GDIMetaFile aMtf; + if (!ConvertWMFToGDIMetaFile(aPreviewStream, aMtf)) + return false; + + rGraphic = aMtf; + + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.1