1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sal/config.h>
14 #include <test/bootstrapfixture.hxx>
15 #include <unotest/macros_test.hxx>
17 #include <vcl/filter/pdfdocument.hxx>
19 class PDFDocumentTest
: public test::BootstrapFixture
, public unotest::MacrosTest
22 PDFDocumentTest() = default;
25 constexpr OUStringLiteral DATA_DIRECTORY
= u
"/vcl/qa/cppunit/data/";
27 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseBasicPDF
)
29 OUString aURL
= m_directories
.getURLFromSrc(DATA_DIRECTORY
) + "basic.pdf";
30 vcl::filter::PDFDocument aDocument
;
31 SvFileStream
aStream(aURL
, StreamMode::READ
);
32 CPPUNIT_ASSERT(aDocument
.Read(aStream
));
34 std::vector
<vcl::filter::PDFObjectElement
*> aPages
= aDocument
.GetPages();
35 CPPUNIT_ASSERT_EQUAL(size_t(1), aPages
.size());
37 vcl::filter::PDFObjectElement
* pResources
= aPages
[0]->LookupObject("Resources");
38 CPPUNIT_ASSERT(pResources
);
40 vcl::filter::PDFObjectElement
* pTest
= pResources
->LookupObject("Test");
41 CPPUNIT_ASSERT(pTest
);
43 vcl::filter::PDFObjectElement
* pTestArray1
= pTest
->LookupObject("TestArray1");
44 CPPUNIT_ASSERT(pTestArray1
);
46 CPPUNIT_ASSERT_EQUAL(size_t(5), pTestArray1
->GetArray()->GetElements().size());
49 vcl::filter::PDFObjectElement
* pTestArray2
= pTest
->LookupObject("TestArray2");
50 CPPUNIT_ASSERT(pTestArray2
);
52 CPPUNIT_ASSERT_EQUAL(size_t(2), pTestArray2
->GetArray()->GetElements().size());
55 vcl::filter::PDFObjectElement
* pTestDictionary
= pTest
->LookupObject("TestDictionary");
57 sal_uInt64 nOffset
= pTestDictionary
->GetDictionaryOffset();
58 sal_uInt64 nLength
= pTestDictionary
->GetDictionaryLength();
60 aStream
.Seek(nOffset
);
61 std::vector
<char> aBuffer(nLength
+ 1, 0);
62 aStream
.ReadBytes(aBuffer
.data(), nLength
);
63 OString
aString(aBuffer
.data());
66 OString("/TestReference 7 0 R/TestNumber "
67 "123/TestName/SomeName/TestDictionary<</Key/Value>>/TestArray[1 2 3]"),
71 CPPUNIT_ASSERT(pTestDictionary
);
73 auto const& rItems
= pTestDictionary
->GetDictionaryItems();
74 CPPUNIT_ASSERT_EQUAL(size_t(5), rItems
.size());
75 auto* pReference
= dynamic_cast<vcl::filter::PDFReferenceElement
*>(
76 pTestDictionary
->Lookup("TestReference"));
77 CPPUNIT_ASSERT(pReference
);
78 CPPUNIT_ASSERT_EQUAL(7, pReference
->GetObjectValue());
81 = dynamic_cast<vcl::filter::PDFNumberElement
*>(pTestDictionary
->Lookup("TestNumber"));
82 CPPUNIT_ASSERT(pNumber
);
83 CPPUNIT_ASSERT_EQUAL(123.0, pNumber
->GetValue());
86 = dynamic_cast<vcl::filter::PDFNameElement
*>(pTestDictionary
->Lookup("TestName"));
87 CPPUNIT_ASSERT(pName
);
88 CPPUNIT_ASSERT_EQUAL(OString("SomeName"), pName
->GetValue());
90 auto* pDictionary
= dynamic_cast<vcl::filter::PDFDictionaryElement
*>(
91 pTestDictionary
->Lookup("TestDictionary"));
92 CPPUNIT_ASSERT(pDictionary
);
95 = dynamic_cast<vcl::filter::PDFArrayElement
*>(pTestDictionary
->Lookup("TestArray"));
96 CPPUNIT_ASSERT(pArray
);
98 // Check offsets and lengths
100 sal_uInt64 nOffset
= pTestDictionary
->GetDictionary()->GetKeyOffset("TestReference");
102 = pTestDictionary
->GetDictionary()->GetKeyValueLength("TestReference");
104 aStream
.Seek(nOffset
);
105 std::vector
<char> aBuffer(nLength
+ 1, 0);
106 aStream
.ReadBytes(aBuffer
.data(), nLength
);
107 OString
aString(aBuffer
.data());
109 CPPUNIT_ASSERT_EQUAL(OString("TestReference 7 0 R"), aString
);
112 sal_uInt64 nOffset
= pTestDictionary
->GetDictionary()->GetKeyOffset("TestNumber");
113 sal_uInt64 nLength
= pTestDictionary
->GetDictionary()->GetKeyValueLength("TestNumber");
115 aStream
.Seek(nOffset
);
116 std::vector
<char> aBuffer(nLength
+ 1, 0);
117 aStream
.ReadBytes(aBuffer
.data(), nLength
);
118 OString
aString(aBuffer
.data());
120 CPPUNIT_ASSERT_EQUAL(OString("TestNumber 123"), aString
);
123 sal_uInt64 nOffset
= pTestDictionary
->GetDictionary()->GetKeyOffset("TestName");
124 sal_uInt64 nLength
= pTestDictionary
->GetDictionary()->GetKeyValueLength("TestName");
126 aStream
.Seek(nOffset
);
127 std::vector
<char> aBuffer(nLength
+ 1, 0);
128 aStream
.ReadBytes(aBuffer
.data(), nLength
);
129 OString
aString(aBuffer
.data());
131 CPPUNIT_ASSERT_EQUAL(OString("TestName/SomeName"), aString
);
134 sal_uInt64 nOffset
= pTestDictionary
->GetDictionary()->GetKeyOffset("TestDictionary");
136 = pTestDictionary
->GetDictionary()->GetKeyValueLength("TestDictionary");
138 aStream
.Seek(nOffset
);
139 std::vector
<char> aBuffer(nLength
+ 1, 0);
140 aStream
.ReadBytes(aBuffer
.data(), nLength
);
141 OString
aString(aBuffer
.data());
143 CPPUNIT_ASSERT_EQUAL(OString("TestDictionary<</Key/Value>>"), aString
);
146 sal_uInt64 nOffset
= pTestDictionary
->GetDictionary()->GetKeyOffset("TestArray");
147 sal_uInt64 nLength
= pTestDictionary
->GetDictionary()->GetKeyValueLength("TestArray");
149 aStream
.Seek(nOffset
);
150 std::vector
<char> aBuffer(nLength
+ 1, 0);
151 aStream
.ReadBytes(aBuffer
.data(), nLength
);
152 OString
aString(aBuffer
.data());
154 CPPUNIT_ASSERT_EQUAL(OString("TestArray[1 2 3]"), aString
);
159 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseDocumentWithNullAsWhitespace
)
162 // Bug document contained a null, which cause the parser to panic,
163 // but other PDF readers can handle the file well.
165 OUString aURL
= m_directories
.getURLFromSrc(DATA_DIRECTORY
) + "DocumentWithNull.pdf";
166 vcl::filter::PDFDocument aDocument
;
167 SvFileStream
aStream(aURL
, StreamMode::READ
);
168 CPPUNIT_ASSERT(aDocument
.Read(aStream
));
173 vcl::filter::PDFObjectElement
*
174 addObjectElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
,
175 vcl::filter::PDFDocument
& rDocument
, int nObjectNumber
, int nGenerationNumber
)
177 auto pObject
= std::make_unique
<vcl::filter::PDFObjectElement
>(rDocument
, nObjectNumber
,
179 auto pObjectPtr
= pObject
.get();
180 rElements
.push_back(std::move(pObject
));
184 vcl::filter::PDFTrailerElement
*
185 addTrailerObjectElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
,
186 vcl::filter::PDFDocument
& rDocument
)
188 auto pTrailer
= std::make_unique
<vcl::filter::PDFTrailerElement
>(rDocument
);
189 auto pTrailerPtr
= pTrailer
.get();
190 rElements
.push_back(std::move(pTrailer
));
193 void addEndObjectElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
)
195 rElements
.push_back(std::make_unique
<vcl::filter::PDFEndObjectElement
>());
198 void addDictionaryElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
)
200 rElements
.push_back(std::make_unique
<vcl::filter::PDFDictionaryElement
>());
203 void addEndDictionaryElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
)
205 rElements
.push_back(std::make_unique
<vcl::filter::PDFEndDictionaryElement
>());
208 void addNameElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
,
209 OString
const& rName
)
211 auto pNameElement
= std::make_unique
<vcl::filter::PDFNameElement
>();
212 pNameElement
->SetValue(rName
);
213 rElements
.push_back(std::move(pNameElement
));
216 vcl::filter::PDFNumberElement
*
217 addNumberElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
, double fNumber
)
219 auto pNumberElement
= std::make_unique
<vcl::filter::PDFNumberElement
>();
220 auto pNumberElementPtr
= pNumberElement
.get();
221 pNumberElement
->SetValue(fNumber
);
222 rElements
.push_back(std::move(pNumberElement
));
223 return pNumberElementPtr
;
226 void addReferenceElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
,
227 vcl::filter::PDFDocument
& rDocument
,
228 vcl::filter::PDFNumberElement
* pNumber1
,
229 vcl::filter::PDFNumberElement
* pNumber2
)
231 auto pReferenceElement
232 = std::make_unique
<vcl::filter::PDFReferenceElement
>(rDocument
, *pNumber1
, *pNumber2
);
233 rElements
.push_back(std::move(pReferenceElement
));
236 void addArrayElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
,
237 vcl::filter::PDFObjectElement
* pObjectPointer
)
239 auto pArray
= std::make_unique
<vcl::filter::PDFArrayElement
>(pObjectPointer
);
240 rElements
.push_back(std::move(pArray
));
243 void addEndArrayElement(std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>>& rElements
)
245 rElements
.push_back(std::make_unique
<vcl::filter::PDFEndArrayElement
>());
248 } // end anonymous namespace
250 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseEmptyDictionary
)
252 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
253 vcl::filter::PDFDocument aDocument
;
254 addObjectElement(aElements
, aDocument
, 1, 0);
255 addDictionaryElement(aElements
);
256 addEndDictionaryElement(aElements
);
257 addEndObjectElement(aElements
);
259 auto pObject
= dynamic_cast<vcl::filter::PDFObjectElement
*>(aElements
[0].get());
260 CPPUNIT_ASSERT(pObject
);
262 vcl::filter::PDFObjectParser
aParser(aElements
);
263 aParser
.parse(pObject
);
265 CPPUNIT_ASSERT(pObject
->GetDictionary());
266 CPPUNIT_ASSERT_EQUAL(size_t(0), pObject
->GetDictionary()->GetItems().size());
269 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseDictionaryWithName
)
271 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
272 vcl::filter::PDFDocument aDocument
;
274 addObjectElement(aElements
, aDocument
, 1, 0);
275 addDictionaryElement(aElements
);
276 addNameElement(aElements
, "Test");
277 addNumberElement(aElements
, 30.0);
278 addEndDictionaryElement(aElements
);
279 addEndObjectElement(aElements
);
282 auto pObject
= dynamic_cast<vcl::filter::PDFObjectElement
*>(aElements
[0].get());
283 CPPUNIT_ASSERT(pObject
);
285 vcl::filter::PDFObjectParser
aParser(aElements
);
286 aParser
.parse(pObject
);
288 CPPUNIT_ASSERT(pObject
->GetDictionary());
289 CPPUNIT_ASSERT_EQUAL(size_t(1), pObject
->GetDictionary()->GetItems().size());
290 auto& rItems
= pObject
->GetDictionary()->GetItems();
291 auto pNumberElement
= dynamic_cast<vcl::filter::PDFNumberElement
*>(rItems
.at("Test"));
292 CPPUNIT_ASSERT(pNumberElement
);
293 CPPUNIT_ASSERT_DOUBLES_EQUAL(30.0, pNumberElement
->GetValue(), 1e-4);
296 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseDictionaryNested
)
298 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
299 vcl::filter::PDFDocument aDocument
;
301 addObjectElement(aElements
, aDocument
, 1, 0);
302 addDictionaryElement(aElements
);
304 addNameElement(aElements
, "Nested1");
305 addDictionaryElement(aElements
);
307 addNameElement(aElements
, "Nested2");
308 addDictionaryElement(aElements
);
310 addNameElement(aElements
, "SomeOtherKey");
311 addNameElement(aElements
, "SomeOtherValue");
313 addEndDictionaryElement(aElements
);
315 addEndDictionaryElement(aElements
);
317 addNameElement(aElements
, "SomeOtherKey");
318 addNameElement(aElements
, "SomeOtherValue");
320 addEndObjectElement(aElements
);
323 auto pObject
= dynamic_cast<vcl::filter::PDFObjectElement
*>(aElements
[0].get());
324 CPPUNIT_ASSERT(pObject
);
326 vcl::filter::PDFObjectParser
aParser(aElements
);
327 aParser
.parse(pObject
);
329 CPPUNIT_ASSERT(pObject
->GetDictionary());
330 CPPUNIT_ASSERT_EQUAL(size_t(2), pObject
->GetDictionary()->GetItems().size());
331 CPPUNIT_ASSERT(pObject
->Lookup("Nested1"));
332 CPPUNIT_ASSERT(pObject
->Lookup("SomeOtherKey"));
335 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseEmptyArray
)
337 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
338 vcl::filter::PDFDocument aDocument
;
340 auto pObjectPtr
= addObjectElement(aElements
, aDocument
, 1, 0);
341 addArrayElement(aElements
, pObjectPtr
);
342 addEndArrayElement(aElements
);
343 addEndObjectElement(aElements
);
346 auto pObject
= dynamic_cast<vcl::filter::PDFObjectElement
*>(aElements
[0].get());
347 CPPUNIT_ASSERT(pObject
);
349 vcl::filter::PDFObjectParser
aParser(aElements
);
350 aParser
.parse(pObject
);
352 CPPUNIT_ASSERT(pObject
->GetArray());
353 CPPUNIT_ASSERT_EQUAL(size_t(0), pObject
->GetArray()->GetElements().size());
356 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseArrayWithSimpleElements
)
358 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
359 vcl::filter::PDFDocument aDocument
;
362 auto pObjectPtr
= addObjectElement(aElements
, aDocument
, 1, 0);
363 addArrayElement(aElements
, pObjectPtr
);
364 addNameElement(aElements
, "Test");
365 addNumberElement(aElements
, 30.0);
366 addEndArrayElement(aElements
);
367 addEndObjectElement(aElements
);
370 auto pObject
= dynamic_cast<vcl::filter::PDFObjectElement
*>(aElements
[0].get());
371 CPPUNIT_ASSERT(pObject
);
373 vcl::filter::PDFObjectParser
aParser(aElements
);
374 aParser
.parse(pObject
);
376 CPPUNIT_ASSERT(pObject
->GetArray());
377 CPPUNIT_ASSERT_EQUAL(size_t(2), pObject
->GetArray()->GetElements().size());
380 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseArrayNestedWithNumbers
)
382 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
383 vcl::filter::PDFDocument aDocument
;
387 auto pObjectPtr
= addObjectElement(aElements
, aDocument
, 1, 0);
388 addArrayElement(aElements
, pObjectPtr
);
390 addNumberElement(aElements
, 1.0);
391 addArrayElement(aElements
, pObjectPtr
);
392 addNumberElement(aElements
, 10.0);
393 addEndArrayElement(aElements
);
394 addNumberElement(aElements
, 2.0);
396 addEndArrayElement(aElements
);
397 addEndObjectElement(aElements
);
402 auto pObject
= dynamic_cast<vcl::filter::PDFObjectElement
*>(aElements
[0].get());
403 CPPUNIT_ASSERT(pObject
);
405 vcl::filter::PDFObjectParser
aParser(aElements
);
406 aParser
.parse(pObject
);
408 CPPUNIT_ASSERT(pObject
->GetArray());
409 CPPUNIT_ASSERT_EQUAL(size_t(3), pObject
->GetArray()->GetElements().size());
410 auto pRootArray
= pObject
->GetArray();
412 auto pNumber1
= dynamic_cast<vcl::filter::PDFNumberElement
*>(pRootArray
->GetElement(0));
413 CPPUNIT_ASSERT(pNumber1
);
414 CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, pNumber1
->GetValue(), 1e-4);
416 auto pArray3
= dynamic_cast<vcl::filter::PDFArrayElement
*>(pRootArray
->GetElement(1));
417 CPPUNIT_ASSERT(pArray3
);
418 CPPUNIT_ASSERT_EQUAL(size_t(1), pArray3
->GetElements().size());
420 auto pNumber2
= dynamic_cast<vcl::filter::PDFNumberElement
*>(pRootArray
->GetElement(2));
421 CPPUNIT_ASSERT(pNumber1
);
422 CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0, pNumber2
->GetValue(), 1e-4);
426 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseArrayNestedWithNames
)
428 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
429 vcl::filter::PDFDocument aDocument
;
431 // [/Inner1/Inner2[/Inner31][/Inner41/Inner42[/Inner431/Inner432]][/Inner51[/Inner521]]]
434 auto pObjectPtr
= addObjectElement(aElements
, aDocument
, 1, 0);
435 addArrayElement(aElements
, pObjectPtr
);
437 addNameElement(aElements
, "Inner1");
438 addNameElement(aElements
, "Inner2");
440 addArrayElement(aElements
, pObjectPtr
);
442 addNameElement(aElements
, "Inner31");
444 addEndArrayElement(aElements
);
446 addArrayElement(aElements
, pObjectPtr
);
448 addNameElement(aElements
, "Inner41");
449 addNameElement(aElements
, "Inner42");
450 addArrayElement(aElements
, pObjectPtr
);
452 addNameElement(aElements
, "Inner431");
453 addNameElement(aElements
, "Inner432");
455 addEndArrayElement(aElements
);
457 addEndArrayElement(aElements
);
459 addArrayElement(aElements
, pObjectPtr
);
461 addNameElement(aElements
, "Inner51");
462 addArrayElement(aElements
, pObjectPtr
);
464 addNameElement(aElements
, "Inner521");
466 addEndArrayElement(aElements
);
468 addEndArrayElement(aElements
);
470 addEndArrayElement(aElements
);
471 addEndObjectElement(aElements
);
476 auto pObject
= dynamic_cast<vcl::filter::PDFObjectElement
*>(aElements
[0].get());
477 CPPUNIT_ASSERT(pObject
);
479 vcl::filter::PDFObjectParser
aParser(aElements
);
480 aParser
.parse(pObject
);
482 CPPUNIT_ASSERT(pObject
->GetArray());
483 CPPUNIT_ASSERT_EQUAL(size_t(5), pObject
->GetArray()->GetElements().size());
484 auto pRootArray
= pObject
->GetArray();
486 auto pName1
= dynamic_cast<vcl::filter::PDFNameElement
*>(pRootArray
->GetElement(0));
487 CPPUNIT_ASSERT(pName1
);
488 CPPUNIT_ASSERT_EQUAL(OString("Inner1"), pName1
->GetValue());
490 auto pName2
= dynamic_cast<vcl::filter::PDFNameElement
*>(pRootArray
->GetElement(1));
491 CPPUNIT_ASSERT(pName2
);
492 CPPUNIT_ASSERT_EQUAL(OString("Inner2"), pName2
->GetValue());
494 auto pArray3
= dynamic_cast<vcl::filter::PDFArrayElement
*>(pRootArray
->GetElement(2));
495 CPPUNIT_ASSERT(pArray3
);
496 CPPUNIT_ASSERT_EQUAL(size_t(1), pArray3
->GetElements().size());
498 auto pInner31
= dynamic_cast<vcl::filter::PDFNameElement
*>(pArray3
->GetElement(0));
499 CPPUNIT_ASSERT(pInner31
);
500 CPPUNIT_ASSERT_EQUAL(OString("Inner31"), pInner31
->GetValue());
502 auto pArray4
= dynamic_cast<vcl::filter::PDFArrayElement
*>(pRootArray
->GetElement(3));
503 CPPUNIT_ASSERT(pArray4
);
504 CPPUNIT_ASSERT_EQUAL(size_t(3), pArray4
->GetElements().size());
506 auto pInner41
= dynamic_cast<vcl::filter::PDFNameElement
*>(pArray4
->GetElement(0));
507 CPPUNIT_ASSERT(pInner41
);
508 CPPUNIT_ASSERT_EQUAL(OString("Inner41"), pInner41
->GetValue());
510 auto pInner42
= dynamic_cast<vcl::filter::PDFNameElement
*>(pArray4
->GetElement(1));
511 CPPUNIT_ASSERT(pInner42
);
512 CPPUNIT_ASSERT_EQUAL(OString("Inner42"), pInner42
->GetValue());
514 auto pArray43
= dynamic_cast<vcl::filter::PDFArrayElement
*>(pArray4
->GetElement(2));
515 CPPUNIT_ASSERT(pArray43
);
516 CPPUNIT_ASSERT_EQUAL(size_t(2), pArray43
->GetElements().size());
518 auto pInner431
= dynamic_cast<vcl::filter::PDFNameElement
*>(pArray43
->GetElement(0));
519 CPPUNIT_ASSERT(pInner431
);
520 CPPUNIT_ASSERT_EQUAL(OString("Inner431"), pInner431
->GetValue());
522 auto pInner432
= dynamic_cast<vcl::filter::PDFNameElement
*>(pArray43
->GetElement(1));
523 CPPUNIT_ASSERT(pInner432
);
524 CPPUNIT_ASSERT_EQUAL(OString("Inner432"), pInner432
->GetValue());
526 auto pArray5
= dynamic_cast<vcl::filter::PDFArrayElement
*>(pRootArray
->GetElement(4));
527 CPPUNIT_ASSERT(pArray5
);
528 CPPUNIT_ASSERT_EQUAL(size_t(2), pArray5
->GetElements().size());
530 auto pInner51
= dynamic_cast<vcl::filter::PDFNameElement
*>(pArray5
->GetElement(0));
531 CPPUNIT_ASSERT(pInner51
);
532 CPPUNIT_ASSERT_EQUAL(OString("Inner51"), pInner51
->GetValue());
534 auto pArray52
= dynamic_cast<vcl::filter::PDFArrayElement
*>(pArray5
->GetElement(1));
535 CPPUNIT_ASSERT(pArray52
);
536 CPPUNIT_ASSERT_EQUAL(size_t(1), pArray52
->GetElements().size());
538 auto pInner521
= dynamic_cast<vcl::filter::PDFNameElement
*>(pArray52
->GetElement(0));
539 CPPUNIT_ASSERT(pInner521
);
540 CPPUNIT_ASSERT_EQUAL(OString("Inner521"), pInner521
->GetValue());
544 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseTrailer
)
546 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
547 vcl::filter::PDFDocument aDocument
;
550 addTrailerObjectElement(aElements
, aDocument
);
551 addDictionaryElement(aElements
);
552 addNameElement(aElements
, "Size");
553 addNumberElement(aElements
, 11.0);
554 addEndDictionaryElement(aElements
);
557 auto pTrailer
= dynamic_cast<vcl::filter::PDFTrailerElement
*>(aElements
[0].get());
558 CPPUNIT_ASSERT(pTrailer
);
560 vcl::filter::PDFObjectParser
aParser(aElements
);
561 aParser
.parse(pTrailer
);
563 CPPUNIT_ASSERT(pTrailer
->GetDictionary());
564 CPPUNIT_ASSERT_EQUAL(size_t(1), pTrailer
->GetDictionary()->GetItems().size());
568 CPPUNIT_TEST_FIXTURE(PDFDocumentTest
, testParseTrailerWithReference
)
570 std::vector
<std::unique_ptr
<vcl::filter::PDFElement
>> aElements
;
571 vcl::filter::PDFDocument aDocument
;
574 addTrailerObjectElement(aElements
, aDocument
);
575 addDictionaryElement(aElements
);
576 addNameElement(aElements
, "Reference");
577 auto pNumberElement1
= addNumberElement(aElements
, 11.0);
578 auto pNumberElement2
= addNumberElement(aElements
, 0.0);
579 addReferenceElement(aElements
, aDocument
, pNumberElement1
, pNumberElement2
);
580 addEndDictionaryElement(aElements
);
583 auto pTrailer
= dynamic_cast<vcl::filter::PDFTrailerElement
*>(aElements
[0].get());
584 CPPUNIT_ASSERT(pTrailer
);
586 vcl::filter::PDFObjectParser
aParser(aElements
);
587 aParser
.parse(pTrailer
);
589 CPPUNIT_ASSERT(pTrailer
->GetDictionary());
590 CPPUNIT_ASSERT_EQUAL(size_t(1), pTrailer
->GetDictionary()->GetItems().size());
591 auto pElement
= pTrailer
->Lookup("Reference");
592 CPPUNIT_ASSERT(pElement
);
593 auto pReference
= dynamic_cast<vcl::filter::PDFReferenceElement
*>(pElement
);
594 CPPUNIT_ASSERT(pReference
);
595 CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, pReference
->GetObjectValue(), 1e-4);
596 CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, pReference
->GetGenerationValue(), 1e-4);
600 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */