From d5d179f4419dfbbbc3598b91071f6ca7cc44357c Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Tue, 18 Dec 2018 21:08:53 -0500 Subject: Add document and object helpers for outlines (bookmarks) --- ChangeLog | 7 + include/qpdf/QPDFOutlineDocumentHelper.hh | 108 ++ include/qpdf/QPDFOutlineObjectHelper.hh | 122 ++ libqpdf/QPDFOutlineDocumentHelper.cc | 137 ++ libqpdf/QPDFOutlineObjectHelper.cc | 117 ++ libqpdf/build.mk | 2 + qpdf/qpdf.testcov | 6 + qpdf/qtest/qpdf.test | 18 + qpdf/qtest/qpdf/outlines-with-actions.out | 12 + qpdf/qtest/qpdf/outlines-with-actions.pdf | 1575 ++++++++++++++++++++++ qpdf/qtest/qpdf/outlines-with-loop.out | 11 + qpdf/qtest/qpdf/outlines-with-loop.pdf | 1575 ++++++++++++++++++++++ qpdf/qtest/qpdf/outlines-with-old-root-dests.out | 12 + qpdf/qtest/qpdf/outlines-with-old-root-dests.pdf | 1567 +++++++++++++++++++++ qpdf/qtest/qpdf/page-labels-and-outlines.out | 12 + qpdf/test_driver.cc | 24 + 16 files changed, 5305 insertions(+) create mode 100644 include/qpdf/QPDFOutlineDocumentHelper.hh create mode 100644 include/qpdf/QPDFOutlineObjectHelper.hh create mode 100644 libqpdf/QPDFOutlineDocumentHelper.cc create mode 100644 libqpdf/QPDFOutlineObjectHelper.cc create mode 100644 qpdf/qtest/qpdf/outlines-with-actions.out create mode 100644 qpdf/qtest/qpdf/outlines-with-actions.pdf create mode 100644 qpdf/qtest/qpdf/outlines-with-loop.out create mode 100644 qpdf/qtest/qpdf/outlines-with-loop.pdf create mode 100644 qpdf/qtest/qpdf/outlines-with-old-root-dests.out create mode 100644 qpdf/qtest/qpdf/outlines-with-old-root-dests.pdf create mode 100644 qpdf/qtest/qpdf/page-labels-and-outlines.out diff --git a/ChangeLog b/ChangeLog index dbd589fc..447c35b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2018-12-19 Jay Berkenbilt + + * Add QPDFOutlineDocumentHelper and QPDFOutlineObjectHelper for + handling outlines (bookmarks) including bidirectionally mapping + between bookmarks and pages. Initially there is no support for + modifying the outlines hierarchy. + 2018-12-18 Jay Berkenbilt * New method QPDFObjectHandle::getJSON() returns a JSON object diff --git a/include/qpdf/QPDFOutlineDocumentHelper.hh b/include/qpdf/QPDFOutlineDocumentHelper.hh new file mode 100644 index 00000000..f6fc74a7 --- /dev/null +++ b/include/qpdf/QPDFOutlineDocumentHelper.hh @@ -0,0 +1,108 @@ +// Copyright (c) 2005-2018 Jay Berkenbilt +// +// This file is part of qpdf. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Versions of qpdf prior to version 7 were released under the terms +// of version 2.0 of the Artistic License. At your option, you may +// continue to consider qpdf to be licensed under those terms. Please +// see the manual for additional information. + +#ifndef QPDFOUTLINEDOCUMENTHELPER_HH +#define QPDFOUTLINEDOCUMENTHELPER_HH + +#include +#include +#include + +#include +#include +#include +#include + +#include + +// This is a document helper for outlines, also known as bookmarks. +// Outlines are discussed in section 12.3.3 of the PDF spec +// (ISO-32000). With the help of QPDFOutlineObjectHelper, the outlines +// tree is traversed, and a bidirectional map is made between pages +// and outlines. See also QPDFOutlineObjectHelper. + +class QPDFOutlineDocumentHelper: public QPDFDocumentHelper +{ + public: + QPDF_DLL + QPDFOutlineDocumentHelper(QPDF&); + QPDF_DLL + virtual ~QPDFOutlineDocumentHelper(); + + QPDF_DLL + bool hasOutlines(); + + QPDF_DLL + std::list getTopLevelOutlines(); + + // If the name is a name object, look it up in the /Dests key of + // the document catalog. If the name is a string, look it up in + // the name tree pointed to by the /Dests key of the names + // dictionary. + QPDF_DLL + QPDFObjectHandle + resolveNamedDest(QPDFObjectHandle name); + + // Return a list outlines that are known to target the specified + // page + QPDF_DLL + std::list getOutlinesForPage(QPDFObjGen const&); + + class Accessor + { + friend class QPDFOutlineObjectHelper; + + QPDF_DLL + static bool + checkSeen(QPDFOutlineDocumentHelper& dh, QPDFObjGen const& og) + { + return dh.checkSeen(og); + } + }; + friend class Accessor; + + private: + bool checkSeen(QPDFObjGen const& og); + void initializeByPage(); + + class Members + { + friend class QPDFOutlineDocumentHelper; + + public: + QPDF_DLL + ~Members(); + + private: + Members(); + Members(Members const&); + + std::list outlines; + std::set seen; + QPDFObjectHandle dest_dict; + PointerHolder names_dest; + std::map > by_page; + }; + + PointerHolder m; +}; + +#endif // QPDFOUTLINEDOCUMENTHELPER_HH diff --git a/include/qpdf/QPDFOutlineObjectHelper.hh b/include/qpdf/QPDFOutlineObjectHelper.hh new file mode 100644 index 00000000..f3d608bc --- /dev/null +++ b/include/qpdf/QPDFOutlineObjectHelper.hh @@ -0,0 +1,122 @@ +// Copyright (c) 2005-2018 Jay Berkenbilt +// +// This file is part of qpdf. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Versions of qpdf prior to version 7 were released under the terms +// of version 2.0 of the Artistic License. At your option, you may +// continue to consider qpdf to be licensed under those terms. Please +// see the manual for additional information. + +#ifndef QPDFOUTLINEOBJECTHELPER_HH +#define QPDFOUTLINEOBJECTHELPER_HH + +#include +#include +#include + +class QPDFOutlineDocumentHelper; + +#include + +// This is an object helper for outline items. Outlines, also known as +// bookmarks, are described in section 12.3.3 of the PDF spec +// (ISO-32000). See comments below for details. + +class QPDFOutlineObjectHelper: public QPDFObjectHelper +{ + public: + QPDF_DLL + virtual ~QPDFOutlineObjectHelper() + { + // This must be cleared explicitly to avoid circular references + // that prevent cleanup of pointer holders. + this->m->parent = 0; + } + + // All constructors are private. You can only create one of these + // using QPDFOutlineDocumentHelper. + + // Return parent pointer. Returns a null pointer if this is a + // top-level outline. + QPDF_DLL + PointerHolder getParent(); + + // Return children as a list. + QPDF_DLL + std::list getKids(); + + // Return the destination, regardless of whether it is named or + // explicit and whether it is directly provided or in a GoTo + // action. Returns a null object if the destination can't be + // determined. Named destinations can be resolved using the older + // root /Dest dictionary or the current names tree. + QPDF_DLL + QPDFObjectHandle getDest(); + + // Return the page that the outline points to. Returns a null + // object if the destination page can't be determined. + QPDF_DLL + QPDFObjectHandle getDestPage(); + + // Returns the value of /Count as present in the object, or 0 if + // not present. If count is positive, the outline is open. If + // negative, it is closed. Either way, the absolute value is the + // number descendant items that would be visible if this were + // open. + QPDF_DLL + int getCount(); + + // Returns the title as a UTF-8 string. Returns the empty string + // if there is no title. + QPDF_DLL + std::string getTitle(); + + class Accessor + { + friend class QPDFOutlineDocumentHelper; + + static QPDFOutlineObjectHelper + create(QPDFObjectHandle oh, QPDFOutlineDocumentHelper& dh, int depth) + { + return QPDFOutlineObjectHelper(oh, dh, depth); + } + }; + friend class Accessor; + + private: + QPDF_DLL + QPDFOutlineObjectHelper(QPDFObjectHandle, QPDFOutlineDocumentHelper&, int); + + class Members + { + friend class QPDFOutlineObjectHelper; + + public: + QPDF_DLL + ~Members(); + + private: + Members(QPDFOutlineDocumentHelper& dh); + Members(Members const&); + + QPDFOutlineDocumentHelper& dh; + PointerHolder parent; + std::list kids; + }; + + PointerHolder m; +}; + +#endif // QPDFOUTLINEOBJECTHELPER_HH diff --git a/libqpdf/QPDFOutlineDocumentHelper.cc b/libqpdf/QPDFOutlineDocumentHelper.cc new file mode 100644 index 00000000..411ccf34 --- /dev/null +++ b/libqpdf/QPDFOutlineDocumentHelper.cc @@ -0,0 +1,137 @@ +#include +#include + +QPDFOutlineDocumentHelper::Members::~Members() +{ +} + +QPDFOutlineDocumentHelper::Members::Members() +{ +} + +QPDFOutlineDocumentHelper::QPDFOutlineDocumentHelper(QPDF& qpdf) : + QPDFDocumentHelper(qpdf), + m(new Members()) +{ + QPDFObjectHandle root = qpdf.getRoot(); + if (! root.hasKey("/Outlines")) + { + return; + } + QPDFObjectHandle outlines = root.getKey("/Outlines"); + if (! (outlines.isDictionary() && outlines.hasKey("/First"))) + { + return; + } + QPDFObjectHandle cur = outlines.getKey("/First"); + while (! cur.isNull()) + { + this->m->outlines.push_back( + QPDFOutlineObjectHelper::Accessor::create(cur, *this, 1)); + cur = cur.getKey("/Next"); + } +} + +QPDFOutlineDocumentHelper::~QPDFOutlineDocumentHelper() +{ +} + +bool +QPDFOutlineDocumentHelper::hasOutlines() +{ + return ! this->m->outlines.empty(); +} + +std::list +QPDFOutlineDocumentHelper::getTopLevelOutlines() +{ + return this->m->outlines; +} + +void +QPDFOutlineDocumentHelper::initializeByPage() +{ + std::list queue; + queue.insert(queue.end(), this->m->outlines.begin(), this->m->outlines.end()); + + while (! queue.empty()) + { + QPDFOutlineObjectHelper oh = queue.front(); + queue.pop_front(); + this->m->by_page[oh.getDestPage().getObjGen()].push_back(oh); + std::list kids = oh.getKids(); + queue.insert(queue.end(), kids.begin(), kids.end()); + } +} + +std::list +QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen const& og) +{ + if (this->m->by_page.empty()) + { + initializeByPage(); + } + std::list result; + if (this->m->by_page.count(og)) + { + result = this->m->by_page[og]; + } + return result; +} + +QPDFObjectHandle +QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name) +{ + QPDFObjectHandle result; + if (name.isName()) + { + if (! this->m->dest_dict.isInitialized()) + { + this->m->dest_dict = this->qpdf.getRoot().getKey("/Dests"); + } + if (this->m->dest_dict.isDictionary()) + { + QTC::TC("qpdf", "QPDFOutlineDocumentHelper name named dest"); + result = this->m->dest_dict.getKey(name.getName()); + } + } + else if (name.isString()) + { + if (0 == this->m->names_dest.getPointer()) + { + QPDFObjectHandle names = this->qpdf.getRoot().getKey("/Names"); + if (names.isDictionary()) + { + QPDFObjectHandle dests = names.getKey("/Dests"); + if (dests.isDictionary()) + { + this->m->names_dest = + new QPDFNameTreeObjectHelper(dests); + } + } + } + if (this->m->names_dest.getPointer()) + { + if (this->m->names_dest->findObject(name.getUTF8Value(), result)) + { + QTC::TC("qpdf", "QPDFOutlineDocumentHelper string named dest"); + } + } + } + if (! result.isInitialized()) + { + result = QPDFObjectHandle::newNull(); + } + return result; +} + +bool +QPDFOutlineDocumentHelper::checkSeen(QPDFObjGen const& og) +{ + if (this->m->seen.count(og) > 0) + { + return true; + } + this->m->seen.insert(og); + return false; +} diff --git a/libqpdf/QPDFOutlineObjectHelper.cc b/libqpdf/QPDFOutlineObjectHelper.cc new file mode 100644 index 00000000..e8eb11d0 --- /dev/null +++ b/libqpdf/QPDFOutlineObjectHelper.cc @@ -0,0 +1,117 @@ +#include +#include +#include + +QPDFOutlineObjectHelper::Members::~Members() +{ +} + +QPDFOutlineObjectHelper::Members::Members(QPDFOutlineDocumentHelper& dh) : + dh(dh) +{ +} + +QPDFOutlineObjectHelper::QPDFOutlineObjectHelper( + QPDFObjectHandle oh, QPDFOutlineDocumentHelper& dh, int depth) : + QPDFObjectHelper(oh), + m(new Members(dh)) +{ + if (depth > 50) + { + // Not exercised in test suite, but was tested manually by + // temporarily changing max depth to 1. + return; + } + if (QPDFOutlineDocumentHelper::Accessor::checkSeen( + this->m->dh, this->oh.getObjGen())) + { + QTC::TC("qpdf", "QPDFOutlineObjectHelper loop"); + return; + } + + QPDFObjectHandle cur = oh.getKey("/First"); + while (! cur.isNull()) + { + QPDFOutlineObjectHelper new_ooh(cur, dh, 1 + depth); + new_ooh.m->parent = new QPDFOutlineObjectHelper(*this); + this->m->kids.push_back(new_ooh); + cur = cur.getKey("/Next"); + } +} + +PointerHolder +QPDFOutlineObjectHelper::getParent() +{ + return this->m->parent; +} + +std::list +QPDFOutlineObjectHelper::getKids() +{ + return this->m->kids; +} + +QPDFObjectHandle +QPDFOutlineObjectHelper::getDest() +{ + QPDFObjectHandle dest; + QPDFObjectHandle A; + if (this->oh.hasKey("/Dest")) + { + QTC::TC("qpdf", "QPDFOutlineObjectHelper direct dest"); + dest = this->oh.getKey("/Dest"); + } + else if ((A = this->oh.getKey("/A")).isDictionary() && + A.getKey("/S").isName() && + (A.getKey("/S").getName() == "/GoTo") && + A.hasKey("/D")) + { + QTC::TC("qpdf", "QPDFOutlineObjectHelper action dest"); + dest = A.getKey("/D"); + } + if (! dest.isInitialized()) + { + dest = QPDFObjectHandle::newNull(); + } + + if (dest.isName() || dest.isString()) + { + QTC::TC("qpdf", "QPDFOutlineObjectHelper named dest"); + dest = this->m->dh.resolveNamedDest(dest); + } + + return dest; +} + +QPDFObjectHandle +QPDFOutlineObjectHelper::getDestPage() +{ + QPDFObjectHandle dest = getDest(); + if ((dest.isArray()) && (dest.getArrayNItems() > 0)) + { + return dest.getArrayItem(0); + } + return QPDFObjectHandle::newNull(); +} + +int +QPDFOutlineObjectHelper::getCount() +{ + int count = 0; + if (this->oh.hasKey("/Count")) + { + count = this->oh.getKey("/Count").getIntValue(); + } + return count; +} + +std::string +QPDFOutlineObjectHelper::getTitle() +{ + std::string result; + if (this->oh.hasKey("/Title")) + { + result = this->oh.getKey("/Title").getUTF8Value(); + } + return result; +} diff --git a/libqpdf/build.mk b/libqpdf/build.mk index 87252b5a..e063df0c 100644 --- a/libqpdf/build.mk +++ b/libqpdf/build.mk @@ -46,6 +46,8 @@ SRCS_libqpdf = \ libqpdf/QPDFObjGen.cc \ libqpdf/QPDFObject.cc \ libqpdf/QPDFObjectHandle.cc \ + libqpdf/QPDFOutlineDocumentHelper.cc \ + libqpdf/QPDFOutlineObjectHelper.cc \ libqpdf/QPDFPageDocumentHelper.cc \ libqpdf/QPDFPageLabelDocumentHelper.cc \ libqpdf/QPDFPageObjectHelper.cc \ diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index 71858eec..ce7a4c80 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -361,3 +361,9 @@ qpdf keep files open n 0 qpdf keep files open y 0 qpdf don't disable keep files open 0 QPDFPageLabelDocumentHelper skip first 0 +QPDFOutlineObjectHelper direct dest 0 +QPDFOutlineObjectHelper action dest 0 +QPDFOutlineObjectHelper named dest 0 +QPDFOutlineDocumentHelper name named dest 0 +QPDFOutlineDocumentHelper string named dest 0 +QPDFOutlineObjectHelper loop 0 diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 0b8e561e..cc8a0755 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -256,6 +256,24 @@ $td->runtest("no page labels", {$td->FILE => "no-page-labels.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); +show_ntests(); +# ---------- +$td->notify("--- Outlines ---"); +my @outline_files = ( + 'page-labels-and-outlines', + 'outlines-with-actions', + 'outlines-with-old-root-dests', + 'outlines-with-loop', + ); +$n_tests += scalar(@outline_files); +foreach my $f (@outline_files) +{ + $td->runtest("outlines: $f", + {$td->COMMAND => "test_driver 49 $f.pdf"}, + {$td->FILE => "$f.out", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +} + show_ntests(); # ---------- $td->notify("--- Page API Tests ---"); diff --git a/qpdf/qtest/qpdf/outlines-with-actions.out b/qpdf/qtest/qpdf/outlines-with-actions.out new file mode 100644 index 00000000..6e5c58db --- /dev/null +++ b/qpdf/qtest/qpdf/outlines-with-actions.out @@ -0,0 +1,12 @@ +page 0: Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null -> [ 6 0 R /XYZ null null null ] +page 1: Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770 -> [ 7 0 R /FitR 66 714 180 770 ] +page 5: Potato 1 -> 5: /XYZ null null null -> [ 11 0 R /XYZ null null null ] +page 11: Mern 1.1 -> 11: /Fit -> [ 17 0 R /Fit ] +page 12: Biherbadem 1.1.1 -> 12: /FitV 100 -> [ 18 0 R /FitV 100 ] +page 12: Gawehwehweh 1.1.2 -> 12: /XYZ null null null -> [ 18 0 R /XYZ null null null ] +page 13: Squash ÷πʬ÷ 1.2 -> 13: /FitH 792 -> [ 19 0 R /FitH 792 ] +page 15: Salad 2 -> 15: /XYZ 66 756 3 -> [ 21 0 R /XYZ 66 756 3 ] +page 18: Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null -> [ 24 0 R /XYZ null null null ] +page 19: Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null -> [ 25 0 R /XYZ null null null ] +page 22: Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null -> [ 28 0 R /XYZ null null null ] +test 49 done diff --git a/qpdf/qtest/qpdf/outlines-with-actions.pdf b/qpdf/qtest/qpdf/outlines-with-actions.pdf new file mode 100644 index 00000000..bb038b37 --- /dev/null +++ b/qpdf/qtest/qpdf/outlines-with-actions.pdf @@ -0,0 +1,1575 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Outlines 2 0 R + /PageMode /UseOutlines + /Pages 3 0 R + /Type /Catalog + /Names << + /Dests 107 0 R + >> +>> +endobj + +2 0 obj +<< + /Count 6 + /First 4 0 R + /Last 5 0 R + /Type /Outlines +>> +endobj + +3 0 obj +<< + /Count 30 + /Kids [ + 6 0 R + 7 0 R + 8 0 R + 9 0 R + 10 0 R + 11 0 R + 12 0 R + 13 0 R + 14 0 R + 15 0 R + 16 0 R + 17 0 R + 18 0 R + 19 0 R + 20 0 R + 21 0 R + 22 0 R + 23 0 R + 24 0 R + 25 0 R + 26 0 R + 27 0 R + 28 0 R + 29 0 R + 30 0 R + 31 0 R + 32 0 R + 33 0 R + 34 0 R + 35 0 R + ] + /Type /Pages +>> +endobj + +4 0 obj +<< + /Count 4 + /Dest [ + 11 0 R + /XYZ + null + null + null + ] + /First 36 0 R + /Last 37 0 R + /Next 5 0 R + /Parent 2 0 R + /Title (Potato 1 -> 5: /XYZ null null null) + /Type /Outline +>> +endobj + +5 0 obj +<< + /Dest [ + 21 0 R + /XYZ + 66 + 756 + 3 + ] + /Parent 2 0 R + /Prev 4 0 R + /Title (Salad 2 -> 15: /XYZ 66 756 3) + /Type /Outline +>> +endobj + +%% Page 1 +6 0 obj +<< + /Contents 38 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 2 +7 0 obj +<< + /Contents 42 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 3 +8 0 obj +<< + /Contents 44 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 4 +9 0 obj +<< + /Contents 46 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 5 +10 0 obj +<< + /Contents 48 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 6 +11 0 obj +<< + /Contents 50 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 7 +12 0 obj +<< + /Contents 52 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 8 +13 0 obj +<< + /Contents 54 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 9 +14 0 obj +<< + /Contents 56 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 10 +15 0 obj +<< + /Contents 58 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 11 +16 0 obj +<< + /Contents 60 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 12 +17 0 obj +<< + /Contents 62 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 13 +18 0 obj +<< + /Contents 64 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 14 +19 0 obj +<< + /Contents 66 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 15 +20 0 obj +<< + /Contents 68 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 16 +21 0 obj +<< + /Contents 70 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 17 +22 0 obj +<< + /Contents 72 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 18 +23 0 obj +<< + /Contents 74 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 19 +24 0 obj +<< + /Contents 76 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 20 +25 0 obj +<< + /Contents 78 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 21 +26 0 obj +<< + /Contents 80 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 22 +27 0 obj +<< + /Contents 82 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 23 +28 0 obj +<< + /Contents 84 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 24 +29 0 obj +<< + /Contents 86 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 25 +30 0 obj +<< + /Contents 88 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 26 +31 0 obj +<< + /Contents 90 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 27 +32 0 obj +<< + /Contents 92 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 28 +33 0 obj +<< + /Contents 94 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 29 +34 0 obj +<< + /Contents 96 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 30 +35 0 obj +<< + /Contents 98 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +36 0 obj +<< + /Count -3 + /Dest [ + 17 0 R + /Fit + ] + /First 100 0 R + /Last 101 0 R + /Next 37 0 R + /Parent 4 0 R + /Title (Mern 1.1 -> 11: /Fit) + /Type /Outline +>> +endobj + +37 0 obj +<< + /Count 2 + /Dest [ + 19 0 R + /FitH + 792 + ] + /First 102 0 R + /Last 103 0 R + /Parent 4 0 R + /Prev 36 0 R + /Title + /Type /Outline +>> +endobj + +%% Contents for page 1 +38 0 obj +<< + /Length 39 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 0) Tj +ET +endstream +endobj + +39 0 obj +45 +endobj + +40 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +41 0 obj +[ + /PDF + /Text +] +endobj + +%% Contents for page 2 +42 0 obj +<< + /Length 43 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 1) Tj +ET +endstream +endobj + +43 0 obj +45 +endobj + +%% Contents for page 3 +44 0 obj +<< + /Length 45 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 2) Tj +ET +endstream +endobj + +45 0 obj +45 +endobj + +%% Contents for page 4 +46 0 obj +<< + /Length 47 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 3) Tj +ET +endstream +endobj + +47 0 obj +45 +endobj + +%% Contents for page 5 +48 0 obj +<< + /Length 49 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 4) Tj +ET +endstream +endobj + +49 0 obj +45 +endobj + +%% Contents for page 6 +50 0 obj +<< + /Length 51 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 5) Tj +ET +endstream +endobj + +51 0 obj +45 +endobj + +%% Contents for page 7 +52 0 obj +<< + /Length 53 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 6) Tj +ET +endstream +endobj + +53 0 obj +45 +endobj + +%% Contents for page 8 +54 0 obj +<< + /Length 55 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 7) Tj +ET +endstream +endobj + +55 0 obj +45 +endobj + +%% Contents for page 9 +56 0 obj +<< + /Length 57 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 8) Tj +ET +endstream +endobj + +57 0 obj +45 +endobj + +%% Contents for page 10 +58 0 obj +<< + /Length 59 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 9) Tj +ET +endstream +endobj + +59 0 obj +45 +endobj + +%% Contents for page 11 +60 0 obj +<< + /Length 61 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 10) Tj +ET +endstream +endobj + +61 0 obj +46 +endobj + +%% Contents for page 12 +62 0 obj +<< + /Length 63 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 11) Tj +ET +endstream +endobj + +63 0 obj +46 +endobj + +%% Contents for page 13 +64 0 obj +<< + /Length 65 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 12) Tj +ET +endstream +endobj + +65 0 obj +46 +endobj + +%% Contents for page 14 +66 0 obj +<< + /Length 67 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 13) Tj +ET +endstream +endobj + +67 0 obj +46 +endobj + +%% Contents for page 15 +68 0 obj +<< + /Length 69 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 14) Tj +ET +endstream +endobj + +69 0 obj +46 +endobj + +%% Contents for page 16 +70 0 obj +<< + /Length 71 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 15) Tj +ET +endstream +endobj + +71 0 obj +46 +endobj + +%% Contents for page 17 +72 0 obj +<< + /Length 73 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 16) Tj +ET +endstream +endobj + +73 0 obj +46 +endobj + +%% Contents for page 18 +74 0 obj +<< + /Length 75 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 17) Tj +ET +endstream +endobj + +75 0 obj +46 +endobj + +%% Contents for page 19 +76 0 obj +<< + /Length 77 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 18) Tj +ET +endstream +endobj + +77 0 obj +46 +endobj + +%% Contents for page 20 +78 0 obj +<< + /Length 79 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 19) Tj +ET +endstream +endobj + +79 0 obj +46 +endobj + +%% Contents for page 21 +80 0 obj +<< + /Length 81 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 20) Tj +ET +endstream +endobj + +81 0 obj +46 +endobj + +%% Contents for page 22 +82 0 obj +<< + /Length 83 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 21) Tj +ET +endstream +endobj + +83 0 obj +46 +endobj + +%% Contents for page 23 +84 0 obj +<< + /Length 85 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 22) Tj +ET +endstream +endobj + +85 0 obj +46 +endobj + +%% Contents for page 24 +86 0 obj +<< + /Length 87 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 23) Tj +ET +endstream +endobj + +87 0 obj +46 +endobj + +%% Contents for page 25 +88 0 obj +<< + /Length 89 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 24) Tj +ET +endstream +endobj + +89 0 obj +46 +endobj + +%% Contents for page 26 +90 0 obj +<< + /Length 91 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 25) Tj +ET +endstream +endobj + +91 0 obj +46 +endobj + +%% Contents for page 27 +92 0 obj +<< + /Length 93 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 26) Tj +ET +endstream +endobj + +93 0 obj +46 +endobj + +%% Contents for page 28 +94 0 obj +<< + /Length 95 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 27) Tj +ET +endstream +endobj + +95 0 obj +46 +endobj + +%% Contents for page 29 +96 0 obj +<< + /Length 97 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 28) Tj +ET +endstream +endobj + +97 0 obj +46 +endobj + +%% Contents for page 30 +98 0 obj +<< + /Length 99 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 29) Tj +ET +endstream +endobj + +99 0 obj +46 +endobj + +100 0 obj +<< + /Count -2 + /Dest [ + 18 0 R + /FitV + 100 + ] + /First 104 0 R + /Last 105 0 R + /Next 101 0 R + /Parent 36 0 R + /Title (Biherbadem 1.1.1 -> 12: /FitV 100) + /Type /Outline +>> +endobj + +101 0 obj +<< + /Count 1 + /Dest [ + 18 0 R + /XYZ + null + null + null + ] + /First 106 0 R + /Last 106 0 R + /Parent 36 0 R + /Prev 100 0 R + /Title (Gawehwehweh 1.1.2 -> 12: /XYZ null null null) + /Type /Outline +>> +endobj + +102 0 obj +<< + /Dest (gabeebee) + /Next 103 0 R + /Parent 37 0 R + /Title (Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770) + /Type /Outline +>> +endobj + +103 0 obj +<< + /A << + /Type /Action + /S /GoTo + /D [ + 6 0 R + /XYZ + null + null + null + ] + >> + /Parent 37 0 R + /Prev 102 0 R + /Title (Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null) + /Type /Outline +>> +endobj + +104 0 obj +<< + /A << + /Type /Action + /S /GoTo + /D (glarp) + >> + /Next 105 0 R + /Parent 100 0 R + /Title (Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null) + /Type /Outline +>> +endobj + +105 0 obj +<< + /Dest [ + 25 0 R + /XYZ + null + null + null + ] + /Parent 100 0 R + /Prev 104 0 R + /Title (Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null) + /Type /Outline +>> +endobj + +106 0 obj +<< + /Dest 108 0 R + /Parent 101 0 R + /Title (Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null) + /Type /Outline +>> +endobj + +107 0 obj +<< + /Names [ + (gabeebee) [ + 7 0 R + /FitR + 66 + 714 + 180 + 770 + ] + (glarp) [ + 24 0 R + /XYZ + null + null + null + ] + ] +>> +endobj + +108 0 obj +[ + 28 0 R + /XYZ + null + null + null +] +endobj + +xref +0 109 +0000000000 65535 f +0000000025 00000 n +0000000158 00000 n +0000000238 00000 n +0000000627 00000 n +0000000845 00000 n +0000001019 00000 n +0000001224 00000 n +0000001429 00000 n +0000001634 00000 n +0000001839 00000 n +0000002045 00000 n +0000002251 00000 n +0000002457 00000 n +0000002663 00000 n +0000002870 00000 n +0000003077 00000 n +0000003284 00000 n +0000003491 00000 n +0000003698 00000 n +0000003905 00000 n +0000004112 00000 n +0000004319 00000 n +0000004526 00000 n +0000004733 00000 n +0000004940 00000 n +0000005147 00000 n +0000005354 00000 n +0000005561 00000 n +0000005768 00000 n +0000005975 00000 n +0000006182 00000 n +0000006389 00000 n +0000006596 00000 n +0000006803 00000 n +0000007010 00000 n +0000007206 00000 n +0000007388 00000 n +0000007713 00000 n +0000007815 00000 n +0000007835 00000 n +0000007954 00000 n +0000008013 00000 n +0000008115 00000 n +0000008158 00000 n +0000008260 00000 n +0000008303 00000 n +0000008405 00000 n +0000008448 00000 n +0000008550 00000 n +0000008593 00000 n +0000008695 00000 n +0000008738 00000 n +0000008840 00000 n +0000008883 00000 n +0000008985 00000 n +0000009028 00000 n +0000009130 00000 n +0000009174 00000 n +0000009276 00000 n +0000009320 00000 n +0000009423 00000 n +0000009467 00000 n +0000009570 00000 n +0000009614 00000 n +0000009717 00000 n +0000009761 00000 n +0000009864 00000 n +0000009908 00000 n +0000010011 00000 n +0000010055 00000 n +0000010158 00000 n +0000010202 00000 n +0000010305 00000 n +0000010349 00000 n +0000010452 00000 n +0000010496 00000 n +0000010599 00000 n +0000010643 00000 n +0000010746 00000 n +0000010790 00000 n +0000010893 00000 n +0000010937 00000 n +0000011040 00000 n +0000011084 00000 n +0000011187 00000 n +0000011231 00000 n +0000011334 00000 n +0000011378 00000 n +0000011481 00000 n +0000011525 00000 n +0000011628 00000 n +0000011672 00000 n +0000011775 00000 n +0000011819 00000 n +0000011922 00000 n +0000011966 00000 n +0000012069 00000 n +0000012113 00000 n +0000012216 00000 n +0000012236 00000 n +0000012443 00000 n +0000012678 00000 n +0000012834 00000 n +0000013086 00000 n +0000013290 00000 n +0000013488 00000 n +0000013627 00000 n +0000013829 00000 n +trailer << + /Root 1 0 R + /Size 109 + /ID [] +>> +startxref +13888 +%%EOF diff --git a/qpdf/qtest/qpdf/outlines-with-loop.out b/qpdf/qtest/qpdf/outlines-with-loop.out new file mode 100644 index 00000000..9ca99dd2 --- /dev/null +++ b/qpdf/qtest/qpdf/outlines-with-loop.out @@ -0,0 +1,11 @@ +page 5: Potato 1 -> 5: /XYZ null null null -> [ 11 0 R /XYZ null null null ] +page 5: Potato 1 -> 5: /XYZ null null null -> [ 11 0 R /XYZ null null null ] +page 11: Mern 1.1 -> 11: /Fit -> [ 17 0 R /Fit ] +page 12: Biherbadem 1.1.1 -> 12: /FitV 100 -> [ 18 0 R /FitV 100 ] +page 12: Gawehwehweh 1.1.2 -> 12: /XYZ null null null -> [ 18 0 R /XYZ null null null ] +page 15: Salad 2 -> 15: /XYZ 66 756 3 -> [ 21 0 R /XYZ 66 756 3 ] +page 15: Salad 2 -> 15: /XYZ 66 756 3 -> [ 21 0 R /XYZ 66 756 3 ] +page 18: Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null -> [ 24 0 R /XYZ null null null ] +page 19: Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null -> [ 25 0 R /XYZ null null null ] +page 22: Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null -> [ 28 0 R /XYZ null null null ] +test 49 done diff --git a/qpdf/qtest/qpdf/outlines-with-loop.pdf b/qpdf/qtest/qpdf/outlines-with-loop.pdf new file mode 100644 index 00000000..7eafd465 --- /dev/null +++ b/qpdf/qtest/qpdf/outlines-with-loop.pdf @@ -0,0 +1,1575 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Outlines 2 0 R + /PageMode /UseOutlines + /Pages 3 0 R + /Type /Catalog + /Names << + /Dests 107 0 R + >> +>> +endobj + +2 0 obj +<< + /Count 6 + /First 4 0 R + /Last 5 0 R + /Type /Outlines +>> +endobj + +3 0 obj +<< + /Count 30 + /Kids [ + 6 0 R + 7 0 R + 8 0 R + 9 0 R + 10 0 R + 11 0 R + 12 0 R + 13 0 R + 14 0 R + 15 0 R + 16 0 R + 17 0 R + 18 0 R + 19 0 R + 20 0 R + 21 0 R + 22 0 R + 23 0 R + 24 0 R + 25 0 R + 26 0 R + 27 0 R + 28 0 R + 29 0 R + 30 0 R + 31 0 R + 32 0 R + 33 0 R + 34 0 R + 35 0 R + ] + /Type /Pages +>> +endobj + +4 0 obj +<< + /Count 4 + /Dest [ + 11 0 R + /XYZ + null + null + null + ] + /First 36 0 R + /Last 37 0 R + /Next 5 0 R + /Parent 2 0 R + /Title (Potato 1 -> 5: /XYZ null null null) + /Type /Outline +>> +endobj + +5 0 obj +<< + /Dest [ + 21 0 R + /XYZ + 66 + 756 + 3 + ] + /Parent 2 0 R + /Prev 4 0 R + /Title (Salad 2 -> 15: /XYZ 66 756 3) + /Type /Outline +>> +endobj + +%% Page 1 +6 0 obj +<< + /Contents 38 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 2 +7 0 obj +<< + /Contents 42 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 3 +8 0 obj +<< + /Contents 44 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 4 +9 0 obj +<< + /Contents 46 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 5 +10 0 obj +<< + /Contents 48 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 6 +11 0 obj +<< + /Contents 50 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 7 +12 0 obj +<< + /Contents 52 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 8 +13 0 obj +<< + /Contents 54 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 9 +14 0 obj +<< + /Contents 56 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 10 +15 0 obj +<< + /Contents 58 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 11 +16 0 obj +<< + /Contents 60 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 12 +17 0 obj +<< + /Contents 62 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 13 +18 0 obj +<< + /Contents 64 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 14 +19 0 obj +<< + /Contents 66 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 15 +20 0 obj +<< + /Contents 68 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 16 +21 0 obj +<< + /Contents 70 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 17 +22 0 obj +<< + /Contents 72 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 18 +23 0 obj +<< + /Contents 74 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 19 +24 0 obj +<< + /Contents 76 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 20 +25 0 obj +<< + /Contents 78 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 21 +26 0 obj +<< + /Contents 80 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 22 +27 0 obj +<< + /Contents 82 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 23 +28 0 obj +<< + /Contents 84 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 24 +29 0 obj +<< + /Contents 86 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 25 +30 0 obj +<< + /Contents 88 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 26 +31 0 obj +<< + /Contents 90 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 27 +32 0 obj +<< + /Contents 92 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 28 +33 0 obj +<< + /Contents 94 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 29 +34 0 obj +<< + /Contents 96 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 30 +35 0 obj +<< + /Contents 98 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +36 0 obj +<< + /Count -3 + /Dest [ + 17 0 R + /Fit + ] + /First 100 0 R + /Last 101 0 R + /Next 4 0 R + /Parent 4 0 R + /Title (Mern 1.1 -> 11: /Fit) + /Type /Outline +>> +endobj + +37 0 obj +<< + /Count 2 + /Dest [ + 19 0 R + /FitH + 792 + ] + /First 102 0 R + /Last 103 0 R + /Parent 4 0 R + /Prev 36 0 R + /Title + /Type /Outline +>> +endobj + +%% Contents for page 1 +38 0 obj +<< + /Length 39 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 0) Tj +ET +endstream +endobj + +39 0 obj +45 +endobj + +40 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +41 0 obj +[ + /PDF + /Text +] +endobj + +%% Contents for page 2 +42 0 obj +<< + /Length 43 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 1) Tj +ET +endstream +endobj + +43 0 obj +45 +endobj + +%% Contents for page 3 +44 0 obj +<< + /Length 45 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 2) Tj +ET +endstream +endobj + +45 0 obj +45 +endobj + +%% Contents for page 4 +46 0 obj +<< + /Length 47 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 3) Tj +ET +endstream +endobj + +47 0 obj +45 +endobj + +%% Contents for page 5 +48 0 obj +<< + /Length 49 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 4) Tj +ET +endstream +endobj + +49 0 obj +45 +endobj + +%% Contents for page 6 +50 0 obj +<< + /Length 51 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 5) Tj +ET +endstream +endobj + +51 0 obj +45 +endobj + +%% Contents for page 7 +52 0 obj +<< + /Length 53 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 6) Tj +ET +endstream +endobj + +53 0 obj +45 +endobj + +%% Contents for page 8 +54 0 obj +<< + /Length 55 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 7) Tj +ET +endstream +endobj + +55 0 obj +45 +endobj + +%% Contents for page 9 +56 0 obj +<< + /Length 57 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 8) Tj +ET +endstream +endobj + +57 0 obj +45 +endobj + +%% Contents for page 10 +58 0 obj +<< + /Length 59 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 9) Tj +ET +endstream +endobj + +59 0 obj +45 +endobj + +%% Contents for page 11 +60 0 obj +<< + /Length 61 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 10) Tj +ET +endstream +endobj + +61 0 obj +46 +endobj + +%% Contents for page 12 +62 0 obj +<< + /Length 63 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 11) Tj +ET +endstream +endobj + +63 0 obj +46 +endobj + +%% Contents for page 13 +64 0 obj +<< + /Length 65 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 12) Tj +ET +endstream +endobj + +65 0 obj +46 +endobj + +%% Contents for page 14 +66 0 obj +<< + /Length 67 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 13) Tj +ET +endstream +endobj + +67 0 obj +46 +endobj + +%% Contents for page 15 +68 0 obj +<< + /Length 69 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 14) Tj +ET +endstream +endobj + +69 0 obj +46 +endobj + +%% Contents for page 16 +70 0 obj +<< + /Length 71 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 15) Tj +ET +endstream +endobj + +71 0 obj +46 +endobj + +%% Contents for page 17 +72 0 obj +<< + /Length 73 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 16) Tj +ET +endstream +endobj + +73 0 obj +46 +endobj + +%% Contents for page 18 +74 0 obj +<< + /Length 75 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 17) Tj +ET +endstream +endobj + +75 0 obj +46 +endobj + +%% Contents for page 19 +76 0 obj +<< + /Length 77 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 18) Tj +ET +endstream +endobj + +77 0 obj +46 +endobj + +%% Contents for page 20 +78 0 obj +<< + /Length 79 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 19) Tj +ET +endstream +endobj + +79 0 obj +46 +endobj + +%% Contents for page 21 +80 0 obj +<< + /Length 81 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 20) Tj +ET +endstream +endobj + +81 0 obj +46 +endobj + +%% Contents for page 22 +82 0 obj +<< + /Length 83 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 21) Tj +ET +endstream +endobj + +83 0 obj +46 +endobj + +%% Contents for page 23 +84 0 obj +<< + /Length 85 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 22) Tj +ET +endstream +endobj + +85 0 obj +46 +endobj + +%% Contents for page 24 +86 0 obj +<< + /Length 87 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 23) Tj +ET +endstream +endobj + +87 0 obj +46 +endobj + +%% Contents for page 25 +88 0 obj +<< + /Length 89 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 24) Tj +ET +endstream +endobj + +89 0 obj +46 +endobj + +%% Contents for page 26 +90 0 obj +<< + /Length 91 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 25) Tj +ET +endstream +endobj + +91 0 obj +46 +endobj + +%% Contents for page 27 +92 0 obj +<< + /Length 93 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 26) Tj +ET +endstream +endobj + +93 0 obj +46 +endobj + +%% Contents for page 28 +94 0 obj +<< + /Length 95 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 27) Tj +ET +endstream +endobj + +95 0 obj +46 +endobj + +%% Contents for page 29 +96 0 obj +<< + /Length 97 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 28) Tj +ET +endstream +endobj + +97 0 obj +46 +endobj + +%% Contents for page 30 +98 0 obj +<< + /Length 99 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Salad 29) Tj +ET +endstream +endobj + +99 0 obj +46 +endobj + +100 0 obj +<< + /Count -2 + /Dest [ + 18 0 R + /FitV + 100 + ] + /First 104 0 R + /Last 105 0 R + /Next 101 0 R + /Parent 36 0 R + /Title (Biherbadem 1.1.1 -> 12: /FitV 100) + /Type /Outline +>> +endobj + +101 0 obj +<< + /Count 1 + /Dest [ + 18 0 R + /XYZ + null + null + null + ] + /First 106 0 R + /Last 106 0 R + /Parent 36 0 R + /Prev 100 0 R + /Title (Gawehwehweh 1.1.2 -> 12: /XYZ null null null) + /Type /Outline +>> +endobj + +102 0 obj +<< + /Dest (gabeebee) + /Next 103 0 R + /Parent 37 0 R + /Title (Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770) + /Type /Outline +>> +endobj + +103 0 obj +<< + /A << + /Type /Action + /S /GoTo + /D [ + 6 0 R + /XYZ + null + null + null + ] + >> + /Parent 37 0 R + /Prev 102 0 R + /Title (Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null) + /Type /Outline +>> +endobj + +104 0 obj +<< + /A << + /Type /Action + /S /GoTo + /D (glarp) + >> + /Next 105 0 R + /Parent 100 0 R + /Title (Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null) + /Type /Outline +>> +endobj + +105 0 obj +<< + /Dest [ + 25 0 R + /XYZ + null + null + null + ] + /Parent 100 0 R + /Prev 104 0 R + /Title (Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null) + /Type /Outline +>> +endobj + +106 0 obj +<< + /Dest 108 0 R + /Parent 101 0 R + /Title (Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null) + /Type /Outline +>> +endobj + +107 0 obj +<< + /Names [ + (gabeebee) [ + 7 0 R + /FitR + 66 + 714 + 180 + 770 + ] + (glarp) [ + 24 0 R + /XYZ + null + null + null + ] + ] +>> +endobj + +108 0 obj +[ + 28 0 R + /XYZ + null + null + null +] +endobj + +xref +0 109 +0000000000 65535 f +0000000025 00000 n +0000000158 00000 n +0000000238 00000 n +0000000627 00000 n +0000000845 00000 n +0000001019 00000 n +0000001224 00000 n +0000001429 00000 n +0000001634 00000 n +0000001839 00000 n +0000002045 00000 n +0000002251 00000 n +0000002457 00000 n +0000002663 00000 n +0000002870 00000 n +0000003077 00000 n +0000003284 00000 n +0000003491 00000 n +0000003698 00000 n +0000003905 00000 n +0000004112 00000 n +0000004319 00000 n +0000004526 00000 n +0000004733 00000 n +0000004940 00000 n +0000005147 00000 n +0000005354 00000 n +0000005561 00000 n +0000005768 00000 n +0000005975 00000 n +0000006182 00000 n +0000006389 00000 n +0000006596 00000 n +0000006803 00000 n +0000007010 00000 n +0000007206 00000 n +0000007387 00000 n +0000007712 00000 n +0000007814 00000 n +0000007834 00000 n +0000007953 00000 n +0000008012 00000 n +0000008114 00000 n +0000008157 00000 n +0000008259 00000 n +0000008302 00000 n +0000008404 00000 n +0000008447 00000 n +0000008549 00000 n +0000008592 00000 n +0000008694 00000 n +0000008737 00000 n +0000008839 00000 n +0000008882 00000 n +0000008984 00000 n +0000009027 00000 n +0000009129 00000 n +0000009173 00000 n +0000009275 00000 n +0000009319 00000 n +0000009422 00000 n +0000009466 00000 n +0000009569 00000 n +0000009613 00000 n +0000009716 00000 n +0000009760 00000 n +0000009863 00000 n +0000009907 00000 n +0000010010 00000 n +0000010054 00000 n +0000010157 00000 n +0000010201 00000 n +0000010304 00000 n +0000010348 00000 n +0000010451 00000 n +0000010495 00000 n +0000010598 00000 n +0000010642 00000 n +0000010745 00000 n +0000010789 00000 n +0000010892 00000 n +0000010936 00000 n +0000011039 00000 n +0000011083 00000 n +0000011186 00000 n +0000011230 00000 n +0000011333 00000 n +0000011377 00000 n +0000011480 00000 n +0000011524 00000 n +0000011627 00000 n +0000011671 00000 n +0000011774 00000 n +0000011818 00000 n +0000011921 00000 n +0000011965 00000 n +0000012068 00000 n +0000012112 00000 n +0000012215 00000 n +0000012235 00000 n +0000012442 00000 n +0000012677 00000 n +0000012833 00000 n +0000013085 00000 n +0000013289 00000 n +0000013487 00000 n +0000013626 00000 n +0000013828 00000 n +trailer << + /Root 1 0 R + /Size 109 + /ID [] +>> +startxref +13887 +%%EOF diff --git a/qpdf/qtest/qpdf/outlines-with-old-root-dests.out b/qpdf/qtest/qpdf/outlines-with-old-root-dests.out new file mode 100644 index 00000000..519623a7 --- /dev/null +++ b/qpdf/qtest/qpdf/outlines-with-old-root-dests.out @@ -0,0 +1,12 @@ +page 0: •Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null -> [ 6 0 R /XYZ null null null ] +page 1: •Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770 -> [ 7 0 R /FitR 66 714 180 770 ] +page 5: •Potato 1 -> 5: /XYZ null null null -> [ 11 0 R /XYZ null null null ] +page 11: •Mern 1.1 -> 11: /Fit -> [ 17 0 R /Fit ] +page 12: •Biherbadem 1.1.1 -> 12: /FitV 100 -> [ 18 0 R /FitV 100 ] +page 12: •Gawehwehweh 1.1.2 -> 12: /XYZ null null null -> [ 18 0 R /XYZ null null null ] +page 13: •Squash ÷πʬ÷ 1.2 -> 13: /FitH 792 -> [ 19 0 R /FitH 792 ] +page 15: •Salad 2 -> 15: /XYZ 66 756 3 -> [ 21 0 R /XYZ 66 756 3 ] +page 18: •Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null -> [ 24 0 R /XYZ null null null ] +page 19: •Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null -> [ 25 0 R /XYZ null null null ] +page 22: •Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null -> [ 28 0 R /XYZ null null null ] +test 49 done diff --git a/qpdf/qtest/qpdf/outlines-with-old-root-dests.pdf b/qpdf/qtest/qpdf/outlines-with-old-root-dests.pdf new file mode 100644 index 00000000..aa683b5e --- /dev/null +++ b/qpdf/qtest/qpdf/outlines-with-old-root-dests.pdf @@ -0,0 +1,1567 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /PageLabels << /Nums [ 0 << /P (0) >> 1 << /S /R >> ] >> + /Outlines 2 0 R + /PageMode /UseOutlines + /Pages 3 0 R + /Type /Catalog + /Dests 107 0 R +>> +endobj + +2 0 obj +<< + /Count 6 + /First 4 0 R + /Last 5 0 R + /Type /Outlines +>> +endobj + +3 0 obj +<< + /Count 30 + /Kids [ + 6 0 R + 7 0 R + 8 0 R + 9 0 R + 10 0 R + 11 0 R + 12 0 R + 13 0 R + 14 0 R + 15 0 R + 16 0 R + 17 0 R + 18 0 R + 19 0 R + 20 0 R + 21 0 R + 22 0 R + 23 0 R + 24 0 R + 25 0 R + 26 0 R + 27 0 R + 28 0 R + 29 0 R + 30 0 R + 31 0 R + 32 0 R + 33 0 R + 34 0 R + 35 0 R + ] + /Type /Pages +>> +endobj + +4 0 obj +<< + /Count 4 + /Dest [ + 11 0 R + /XYZ + null + null + null + ] + /First 36 0 R + /Last 37 0 R + /Next 5 0 R + /Parent 2 0 R + /Title (€Potato 1 -> 5: /XYZ null null null) + /Type /Outline +>> +endobj + +5 0 obj +<< + /Dest [ + 21 0 R + /XYZ + 66 + 756 + 3 + ] + /Parent 2 0 R + /Prev 4 0 R + /Title (€Salad 2 -> 15: /XYZ 66 756 3) + /Type /Outline +>> +endobj + +%% Page 1 +6 0 obj +<< + /Contents 38 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 2 +7 0 obj +<< + /Contents 42 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 3 +8 0 obj +<< + /Contents 44 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 4 +9 0 obj +<< + /Contents 46 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 5 +10 0 obj +<< + /Contents 48 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 6 +11 0 obj +<< + /Contents 50 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 7 +12 0 obj +<< + /Contents 52 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 8 +13 0 obj +<< + /Contents 54 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 9 +14 0 obj +<< + /Contents 56 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 10 +15 0 obj +<< + /Contents 58 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 11 +16 0 obj +<< + /Contents 60 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 12 +17 0 obj +<< + /Contents 62 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 13 +18 0 obj +<< + /Contents 64 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 14 +19 0 obj +<< + /Contents 66 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 15 +20 0 obj +<< + /Contents 68 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 16 +21 0 obj +<< + /Contents 70 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 17 +22 0 obj +<< + /Contents 72 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 18 +23 0 obj +<< + /Contents 74 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 19 +24 0 obj +<< + /Contents 76 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 20 +25 0 obj +<< + /Contents 78 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 21 +26 0 obj +<< + /Contents 80 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 22 +27 0 obj +<< + /Contents 82 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 23 +28 0 obj +<< + /Contents 84 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 24 +29 0 obj +<< + /Contents 86 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 25 +30 0 obj +<< + /Contents 88 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 26 +31 0 obj +<< + /Contents 90 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 27 +32 0 obj +<< + /Contents 92 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 28 +33 0 obj +<< + /Contents 94 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 29 +34 0 obj +<< + /Contents 96 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +%% Page 30 +35 0 obj +<< + /Contents 98 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 40 0 R + >> + /ProcSet 41 0 R + >> + /Type /Page +>> +endobj + +36 0 obj +<< + /Count 3 + /Dest [ + 17 0 R + /Fit + ] + /First 100 0 R + /Last 101 0 R + /Next 37 0 R + /Parent 4 0 R + /Title (€Mern 1.1 -> 11: /Fit) + /Type /Outline +>> +endobj + +37 0 obj +<< + /Count 2 + /Dest [ + 19 0 R + /FitH + 792 + ] + /First 102 0 R + /Last 103 0 R + /Parent 4 0 R + /Prev 36 0 R + /Title + /Type /Outline +>> +endobj + +%% Contents for page 1 +38 0 obj +<< + /Length 39 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 0) Tj +ET +endstream +endobj + +39 0 obj +44 +endobj + +40 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +41 0 obj +[ + /PDF + /Text +] +endobj + +%% Contents for page 2 +42 0 obj +<< + /Length 43 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 1) Tj +ET +endstream +endobj + +43 0 obj +44 +endobj + +%% Contents for page 3 +44 0 obj +<< + /Length 45 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 2) Tj +ET +endstream +endobj + +45 0 obj +44 +endobj + +%% Contents for page 4 +46 0 obj +<< + /Length 47 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 3) Tj +ET +endstream +endobj + +47 0 obj +44 +endobj + +%% Contents for page 5 +48 0 obj +<< + /Length 49 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 4) Tj +ET +endstream +endobj + +49 0 obj +44 +endobj + +%% Contents for page 6 +50 0 obj +<< + /Length 51 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 5) Tj +ET +endstream +endobj + +51 0 obj +44 +endobj + +%% Contents for page 7 +52 0 obj +<< + /Length 53 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 6) Tj +ET +endstream +endobj + +53 0 obj +44 +endobj + +%% Contents for page 8 +54 0 obj +<< + /Length 55 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 7) Tj +ET +endstream +endobj + +55 0 obj +44 +endobj + +%% Contents for page 9 +56 0 obj +<< + /Length 57 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 8) Tj +ET +endstream +endobj + +57 0 obj +44 +endobj + +%% Contents for page 10 +58 0 obj +<< + /Length 59 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 9) Tj +ET +endstream +endobj + +59 0 obj +44 +endobj + +%% Contents for page 11 +60 0 obj +<< + /Length 61 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 10) Tj +ET +endstream +endobj + +61 0 obj +45 +endobj + +%% Contents for page 12 +62 0 obj +<< + /Length 63 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 11) Tj +ET +endstream +endobj + +63 0 obj +45 +endobj + +%% Contents for page 13 +64 0 obj +<< + /Length 65 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 12) Tj +ET +endstream +endobj + +65 0 obj +45 +endobj + +%% Contents for page 14 +66 0 obj +<< + /Length 67 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 13) Tj +ET +endstream +endobj + +67 0 obj +45 +endobj + +%% Contents for page 15 +68 0 obj +<< + /Length 69 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 14) Tj +ET +endstream +endobj + +69 0 obj +45 +endobj + +%% Contents for page 16 +70 0 obj +<< + /Length 71 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 15) Tj +ET +endstream +endobj + +71 0 obj +45 +endobj + +%% Contents for page 17 +72 0 obj +<< + /Length 73 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 16) Tj +ET +endstream +endobj + +73 0 obj +45 +endobj + +%% Contents for page 18 +74 0 obj +<< + /Length 75 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 17) Tj +ET +endstream +endobj + +75 0 obj +45 +endobj + +%% Contents for page 19 +76 0 obj +<< + /Length 77 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 18) Tj +ET +endstream +endobj + +77 0 obj +45 +endobj + +%% Contents for page 20 +78 0 obj +<< + /Length 79 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 19) Tj +ET +endstream +endobj + +79 0 obj +45 +endobj + +%% Contents for page 21 +80 0 obj +<< + /Length 81 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 20) Tj +ET +endstream +endobj + +81 0 obj +45 +endobj + +%% Contents for page 22 +82 0 obj +<< + /Length 83 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 21) Tj +ET +endstream +endobj + +83 0 obj +45 +endobj + +%% Contents for page 23 +84 0 obj +<< + /Length 85 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 22) Tj +ET +endstream +endobj + +85 0 obj +45 +endobj + +%% Contents for page 24 +86 0 obj +<< + /Length 87 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 23) Tj +ET +endstream +endobj + +87 0 obj +45 +endobj + +%% Contents for page 25 +88 0 obj +<< + /Length 89 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 24) Tj +ET +endstream +endobj + +89 0 obj +45 +endobj + +%% Contents for page 26 +90 0 obj +<< + /Length 91 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 25) Tj +ET +endstream +endobj + +91 0 obj +45 +endobj + +%% Contents for page 27 +92 0 obj +<< + /Length 93 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 26) Tj +ET +endstream +endobj + +93 0 obj +45 +endobj + +%% Contents for page 28 +94 0 obj +<< + /Length 95 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 27) Tj +ET +endstream +endobj + +95 0 obj +45 +endobj + +%% Contents for page 29 +96 0 obj +<< + /Length 97 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 28) Tj +ET +endstream +endobj + +97 0 obj +45 +endobj + +%% Contents for page 30 +98 0 obj +<< + /Length 99 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Soup 29) Tj +ET +endstream +endobj + +99 0 obj +45 +endobj + +100 0 obj +<< + /Count -2 + /Dest [ + 18 0 R + /FitV + 100 + ] + /First 104 0 R + /Last 105 0 R + /Next 101 0 R + /Parent 36 0 R + /Title (€Biherbadem 1.1.1 -> 12: /FitV 100) + /Type /Outline +>> +endobj + +101 0 obj +<< + /Count 1 + /Dest [ + 18 0 R + /XYZ + null + null + null + ] + /First 106 0 R + /Last 106 0 R + /Parent 36 0 R + /Prev 100 0 R + /Title (€Gawehwehweh 1.1.2 -> 12: /XYZ null null null) + /Type /Outline +>> +endobj + +102 0 obj +<< + /Dest /gabeebee + /Next 103 0 R + /Parent 37 0 R + /Title (€Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770) + /Type /Outline +>> +endobj + +103 0 obj +<< + /A << + /Type /Action + /S /GoTo + /D [ + 6 0 R + /XYZ + null + null + null + ] + >> + /Parent 37 0 R + /Prev 102 0 R + /Title (€Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null) + /Type /Outline +>> +endobj + +104 0 obj +<< + /A << + /Type /Action + /S /GoTo + /D /glarp + >> + /Next 105 0 R + /Parent 100 0 R + /Title (€Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null) + /Type /Outline +>> +endobj + +105 0 obj +<< + /Dest [ + 25 0 R + /XYZ + null + null + null + ] + /Parent 100 0 R + /Prev 104 0 R + /Title (€Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null) + /Type /Outline +>> +endobj + +106 0 obj +<< + /Dest [ + 28 0 R + /XYZ + null + null + null + ] + /Parent 101 0 R + /Title (€Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null) + /Type /Outline +>> +endobj + +107 0 obj +<< + /gabeebee [ + 7 0 R + /FitR + 66 + 714 + 180 + 770 + ] + /glarp [ + 24 0 R + /XYZ + null + null + null + ] +>> +endobj + +xref +0 108 +0000000000 65535 f +0000000025 00000 n +0000000198 00000 n +0000000278 00000 n +0000000667 00000 n +0000000886 00000 n +0000001061 00000 n +0000001266 00000 n +0000001471 00000 n +0000001676 00000 n +0000001881 00000 n +0000002087 00000 n +0000002293 00000 n +0000002499 00000 n +0000002705 00000 n +0000002912 00000 n +0000003119 00000 n +0000003326 00000 n +0000003533 00000 n +0000003740 00000 n +0000003947 00000 n +0000004154 00000 n +0000004361 00000 n +0000004568 00000 n +0000004775 00000 n +0000004982 00000 n +0000005189 00000 n +0000005396 00000 n +0000005603 00000 n +0000005810 00000 n +0000006017 00000 n +0000006224 00000 n +0000006431 00000 n +0000006638 00000 n +0000006845 00000 n +0000007052 00000 n +0000007248 00000 n +0000007430 00000 n +0000007759 00000 n +0000007860 00000 n +0000007880 00000 n +0000007999 00000 n +0000008058 00000 n +0000008159 00000 n +0000008202 00000 n +0000008303 00000 n +0000008346 00000 n +0000008447 00000 n +0000008490 00000 n +0000008591 00000 n +0000008634 00000 n +0000008735 00000 n +0000008778 00000 n +0000008879 00000 n +0000008922 00000 n +0000009023 00000 n +0000009066 00000 n +0000009167 00000 n +0000009211 00000 n +0000009312 00000 n +0000009356 00000 n +0000009458 00000 n +0000009502 00000 n +0000009604 00000 n +0000009648 00000 n +0000009750 00000 n +0000009794 00000 n +0000009896 00000 n +0000009940 00000 n +0000010042 00000 n +0000010086 00000 n +0000010188 00000 n +0000010232 00000 n +0000010334 00000 n +0000010378 00000 n +0000010480 00000 n +0000010524 00000 n +0000010626 00000 n +0000010670 00000 n +0000010772 00000 n +0000010816 00000 n +0000010918 00000 n +0000010962 00000 n +0000011064 00000 n +0000011108 00000 n +0000011210 00000 n +0000011254 00000 n +0000011356 00000 n +0000011400 00000 n +0000011502 00000 n +0000011546 00000 n +0000011648 00000 n +0000011692 00000 n +0000011794 00000 n +0000011838 00000 n +0000011940 00000 n +0000011984 00000 n +0000012086 00000 n +0000012130 00000 n +0000012232 00000 n +0000012252 00000 n +0000012460 00000 n +0000012696 00000 n +0000012852 00000 n +0000013105 00000 n +0000013309 00000 n +0000013508 00000 n +0000013693 00000 n +trailer << + /Root 1 0 R + /Size 108 + /ID [] +>> +startxref +13848 +%%EOF diff --git a/qpdf/qtest/qpdf/page-labels-and-outlines.out b/qpdf/qtest/qpdf/page-labels-and-outlines.out new file mode 100644 index 00000000..2d40786a --- /dev/null +++ b/qpdf/qtest/qpdf/page-labels-and-outlines.out @@ -0,0 +1,12 @@ +page 0: Trepsicle 1.2.2 -> 0: /XYZ null null null -> [ 3 0 R /XYZ null null null ] +page 1: Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770 -> [ 4 0 R /FitR 66 714 180 770 ] +page 5: Isís 1 -> 5: /XYZ null null null -> [ 8 0 R /XYZ null null null ] +page 11: Amanda 1.1 -> 11: /Fit -> [ 14 0 R /Fit ] +page 12: Isosicle 1.1.1 -> 12: /FitV 100 -> [ 15 0 R /FitV 100 ] +page 12: Isosicle 1.1.2 -> 12: /XYZ null null null -> [ 15 0 R /XYZ null null null ] +page 13: Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792 -> [ 16 0 R /FitH 792 ] +page 15: Trepak 2 -> 15: /XYZ 66 756 3 -> [ 18 0 R /XYZ 66 756 3 ] +page 18: Isosicle 1.1.1.1 -> 18: /XYZ null null null -> [ 21 0 R /XYZ null null null ] +page 19: Isosicle 1.1.1.2 -> 19: /XYZ null null null -> [ 22 0 R /XYZ null null null ] +page 22: Isosicle 1.1.2.1 -> 22: /XYZ null null null -> [ 25 0 R /XYZ null null null ] +test 49 done diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 2708285b..eae25a5c 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -1730,6 +1731,29 @@ void runtest(int n, char const* filename1, char const* arg2) assert(ntoh.findObject("07 sev\xe2\x80\xa2n", oh)); assert("seven!" == oh.getStringValue()); } + else if (n == 49) + { + // Outlines + std::vector pages = + QPDFPageDocumentHelper(pdf).getAllPages(); + QPDFOutlineDocumentHelper odh(pdf); + int pageno = 0; + for (std::vector::iterator iter = pages.begin(); + iter != pages.end(); ++iter, ++pageno) + { + std::list outlines = + odh.getOutlinesForPage((*iter).getObjectHandle().getObjGen()); + for (std::list::iterator oiter = + outlines.begin(); + oiter != outlines.end(); ++oiter) + { + std::cout + << "page " << pageno << ": " + << (*oiter).getTitle() << " -> " + << (*oiter).getDest().unparseResolved() << std::endl; + } + } + } else { throw std::runtime_error(std::string("invalid test ") + -- cgit v1.2.3-54-g00ecf