diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-02-24 17:14:23 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-02-27 08:11:16 +0000 |
commit | 4e203ca3915e0cee2e7e02b95e78b3f5a8870098 (patch) | |
tree | 5a0e897019df5b6d463b9779caf9911aa6c61e26 | |
parent | 51eb2ad7a05938b69aa7874caf17079ed6c19e31 (diff) |
tdf#105461 vcl: add text highlight textcase
Fails with commit ee32c7d8083ae1449d6b379034be92995c142da9 (tdf#105461
PDF export: handle text fill color, 2017-02-01) reverted.
Change-Id: I3628a16d0810e3be3fb352340d06cdba472dcd3f
Reviewed-on: https://gerrit.libreoffice.org/34621
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | include/xmlsecurity/pdfio/pdfdocument.hxx | 17 | ||||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/data/tdf105461.odp | bin | 0 -> 10320 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/pdfexport.cxx | 50 | ||||
-rw-r--r-- | xmlsecurity/source/pdfio/pdfdocument.cxx | 26 |
4 files changed, 80 insertions, 13 deletions
diff --git a/include/xmlsecurity/pdfio/pdfdocument.hxx b/include/xmlsecurity/pdfio/pdfdocument.hxx index 0b27014c7418..5a8ea6c2c71d 100644 --- a/include/xmlsecurity/pdfio/pdfdocument.hxx +++ b/include/xmlsecurity/pdfio/pdfdocument.hxx @@ -80,6 +80,8 @@ public: void SetDictionary(PDFDictionaryElement* pDictionaryElement); void SetArray(PDFArrayElement* pArrayElement); void SetStream(PDFStreamElement* pStreamElement); + /// Access to the stream of the object, if it has any. + PDFStreamElement* GetStream() const; PDFArrayElement* GetArray() const; /// Parse objects stored in this object stream. void ParseStoredObjects(); @@ -88,6 +90,21 @@ public: void SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer); }; +/// Stream object: a byte array with a known length. +class XMLSECURITY_DLLPUBLIC PDFStreamElement : public PDFElement +{ + size_t m_nLength; + sal_uInt64 m_nOffset; + /// The byte array itself. + SvMemoryStream m_aMemory; + +public: + explicit PDFStreamElement(size_t nLength); + bool Read(SvStream& rStream) override; + sal_uInt64 GetOffset() const; + SvMemoryStream& GetMemory(); +}; + /// Name object: a key string. class XMLSECURITY_DLLPUBLIC PDFNameElement : public PDFElement { diff --git a/vcl/qa/cppunit/pdfexport/data/tdf105461.odp b/vcl/qa/cppunit/pdfexport/data/tdf105461.odp Binary files differnew file mode 100644 index 000000000000..9c86a3bd7901 --- /dev/null +++ b/vcl/qa/cppunit/pdfexport/data/tdf105461.odp diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 949ef6109043..1c665b8d2174 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -19,6 +19,7 @@ #include <unotools/mediadescriptor.hxx> #include <unotools/tempfile.hxx> #include <xmlsecurity/pdfio/pdfdocument.hxx> +#include <tools/zcodec.hxx> using namespace ::com::sun::star; @@ -39,11 +40,14 @@ public: #if HAVE_FEATURE_PDFIUM /// Tests that a pdf image is roundtripped back to PDF as a vector format. void testTdf106059(); + /// Tests that text highlight from Impress is not lost. + void testTdf105461(); #endif CPPUNIT_TEST_SUITE(PdfExportTest); #if HAVE_FEATURE_PDFIUM CPPUNIT_TEST(testTdf106059); + CPPUNIT_TEST(testTdf105461); #endif CPPUNIT_TEST_SUITE_END(); }; @@ -100,6 +104,52 @@ void PdfExportTest::testTdf106059() // This dictionary key was missing, so the XObject wasn't a reference one. CPPUNIT_ASSERT(pReferenceXObject->Lookup("Ref")); } + +void PdfExportTest::testTdf105461() +{ + // Import the bugdoc and export as PDF. + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf105461.odp"; + mxComponent = loadFromDesktop(aURL); + CPPUNIT_ASSERT(mxComponent.is()); + + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString("impress_pdf_Export"); + xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + + // Parse the export result. + xmlsecurity::pdfio::PDFDocument aDocument; + SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ); + CPPUNIT_ASSERT(aDocument.Read(aStream)); + + // The document has one page. + std::vector<xmlsecurity::pdfio::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size()); + + // The page has a stream. + xmlsecurity::pdfio::PDFObjectElement* pContents = aPages[0]->LookupObject("Contents"); + CPPUNIT_ASSERT(pContents); + xmlsecurity::pdfio::PDFStreamElement* pStream = pContents->GetStream(); + CPPUNIT_ASSERT(pStream); + SvMemoryStream& rObjectStream = pStream->GetMemory(); + // Uncompress it. + SvMemoryStream aUncompressed; + ZCodec aZCodec; + aZCodec.BeginCompression(); + rObjectStream.Seek(0); + aZCodec.Decompress(rObjectStream, aUncompressed); + CPPUNIT_ASSERT(aZCodec.EndCompression()); + + // Make sure there is a filled rectangle inside. + OString aFilledRectangle("re f*"); + auto pStart = static_cast<const char*>(aUncompressed.GetData()); + const char* pEnd = pStart + aUncompressed.GetSize(); + auto it = std::search(pStart, pEnd, aFilledRectangle.getStr(), aFilledRectangle.getStr() + aFilledRectangle.getLength()); + // This failed, stream contained no filled rectangle. + CPPUNIT_ASSERT(it != pEnd); +} #endif CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest); diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx index 50e00d79c067..50174483a832 100644 --- a/xmlsecurity/source/pdfio/pdfdocument.cxx +++ b/xmlsecurity/source/pdfio/pdfdocument.cxx @@ -118,18 +118,6 @@ public: int GetGenerationValue() const; }; -/// Stream object: a byte array with a known length. -class PDFStreamElement : public PDFElement -{ - size_t m_nLength; - sal_uInt64 m_nOffset; - -public: - explicit PDFStreamElement(size_t nLength); - bool Read(SvStream& rStream) override; - sal_uInt64 GetOffset() const; -}; - /// End of a stream: 'endstream' keyword. class PDFEndStreamElement : public PDFElement { @@ -3282,6 +3270,11 @@ void PDFObjectElement::SetStream(PDFStreamElement* pStreamElement) m_pStreamElement = pStreamElement; } +PDFStreamElement* PDFObjectElement::GetStream() const +{ + return m_pStreamElement; +} + PDFArrayElement* PDFObjectElement::GetArray() const { return m_pArrayElement; @@ -3668,11 +3661,18 @@ bool PDFStreamElement::Read(SvStream& rStream) { SAL_INFO("xmlsecurity.pdfio", "PDFStreamElement::Read: length is " << m_nLength); m_nOffset = rStream.Tell(); - rStream.SeekRel(m_nLength); + std::vector<unsigned char> aBytes(m_nLength); + rStream.ReadBytes(aBytes.data(), aBytes.size()); + m_aMemory.WriteBytes(aBytes.data(), aBytes.size()); return rStream.good(); } +SvMemoryStream& PDFStreamElement::GetMemory() +{ + return m_aMemory; +} + sal_uInt64 PDFStreamElement::GetOffset() const { return m_nOffset; |