summaryrefslogtreecommitdiff
path: root/vcl/source/filter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-04-07 12:27:40 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-04-07 13:00:15 +0000
commit4db4b9f016256fc8d2b637ed7a8f2b097aaa864b (patch)
treee59cca792bb0f896366cb24f3f3f66f054264ca2 /vcl/source/filter
parent209dc36408dd5e1775db2c54b08c3e674158fd2f (diff)
tdf#107013 PDF export of PDF images: handle page tree and content streams
Handle when the page objects are not contained in a single list, but a tree of "pages" objects. Also handle when the page object has multiple content streams. Change-Id: I7c5b0949314768af5915d37830a45e843e629446 Reviewed-on: https://gerrit.libreoffice.org/36256 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'vcl/source/filter')
-rw-r--r--vcl/source/filter/ipdf/pdfdocument.cxx46
1 files changed, 31 insertions, 15 deletions
diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx
index 444ec9239d20..43d4248cc8ad 100644
--- a/vcl/source/filter/ipdf/pdfdocument.cxx
+++ b/vcl/source/filter/ipdf/pdfdocument.cxx
@@ -1749,6 +1749,36 @@ const std::vector< std::unique_ptr<PDFElement> >& PDFDocument::GetElements()
return m_aElements;
}
+/// Visits the page tree recursively, looking for page objects.
+static void visitPages(PDFObjectElement* pPages, std::vector<PDFObjectElement*>& rRet)
+{
+ auto pKids = dynamic_cast<PDFArrayElement*>(pPages->Lookup("Kids"));
+ if (!pKids)
+ {
+ SAL_WARN("vcl.filter", "visitPages: pages has no kids");
+ return;
+ }
+
+ for (const auto& pKid : pKids->GetElements())
+ {
+ auto pReference = dynamic_cast<PDFReferenceElement*>(pKid);
+ if (!pReference)
+ continue;
+
+ PDFObjectElement* pKidObject = pReference->LookupObject();
+ if (!pKidObject)
+ continue;
+
+ auto pName = dynamic_cast<PDFNameElement*>(pKidObject->Lookup("Type"));
+ if (pName && pName->GetValue() == "Pages")
+ // Pages inside pages: recurse.
+ visitPages(pKidObject, rRet);
+ else
+ // Found an actual page.
+ rRet.push_back(pKidObject);
+ }
+}
+
std::vector<PDFObjectElement*> PDFDocument::GetPages()
{
std::vector<PDFObjectElement*> aRet;
@@ -1779,21 +1809,7 @@ std::vector<PDFObjectElement*> PDFDocument::GetPages()
return aRet;
}
- auto pKids = dynamic_cast<PDFArrayElement*>(pPages->Lookup("Kids"));
- if (!pKids)
- {
- SAL_WARN("vcl.filter", "PDFDocument::GetPages: pages has no kids");
- return aRet;
- }
-
- for (const auto& pKid : pKids->GetElements())
- {
- auto pReference = dynamic_cast<PDFReferenceElement*>(pKid);
- if (!pReference)
- continue;
-
- aRet.push_back(pReference->LookupObject());
- }
+ visitPages(pPages, aRet);
return aRet;
}