summaryrefslogtreecommitdiff
path: root/samples/pdfium_test_dump_helper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'samples/pdfium_test_dump_helper.cc')
-rw-r--r--samples/pdfium_test_dump_helper.cc88
1 files changed, 88 insertions, 0 deletions
diff --git a/samples/pdfium_test_dump_helper.cc b/samples/pdfium_test_dump_helper.cc
new file mode 100644
index 0000000000..5d7af1c257
--- /dev/null
+++ b/samples/pdfium_test_dump_helper.cc
@@ -0,0 +1,88 @@
+// Copyright 2018 The PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "samples/pdfium_test_dump_helper.h"
+
+#include <string>
+#include <utility>
+
+#include "public/cpp/fpdf_deleters.h"
+#include "testing/test_support.h"
+
+namespace {
+
+std::wstring ConvertToWString(const unsigned short* buf,
+ unsigned long buf_size) {
+ std::wstring result;
+ result.reserve(buf_size);
+ std::copy(buf, buf + buf_size, std::back_inserter(result));
+ return result;
+}
+
+} // namespace
+
+void DumpChildStructure(FPDF_STRUCTELEMENT child, int indent) {
+ static const size_t kBufSize = 1024;
+ unsigned short buf[kBufSize];
+ unsigned long len = FPDF_StructElement_GetType(child, buf, kBufSize);
+ printf("%*s%ls", indent * 2, "", ConvertToWString(buf, len).c_str());
+
+ memset(buf, 0, sizeof(buf));
+ len = FPDF_StructElement_GetTitle(child, buf, kBufSize);
+ if (len > 0)
+ printf(": '%ls'", ConvertToWString(buf, len).c_str());
+
+ memset(buf, 0, sizeof(buf));
+ len = FPDF_StructElement_GetAltText(child, buf, kBufSize);
+ if (len > 0)
+ printf(" (%ls)", ConvertToWString(buf, len).c_str());
+ printf("\n");
+
+ for (int i = 0; i < FPDF_StructElement_CountChildren(child); ++i) {
+ FPDF_STRUCTELEMENT sub_child = FPDF_StructElement_GetChildAtIndex(child, i);
+ // If the child is not an Element then this will return null. This can
+ // happen if the element is things like an object reference or a stream.
+ if (!sub_child)
+ continue;
+
+ DumpChildStructure(sub_child, indent + 1);
+ }
+}
+
+void DumpPageStructure(FPDF_PAGE page, const int page_idx) {
+ std::unique_ptr<void, FPDFStructTreeDeleter> tree(
+ FPDF_StructTree_GetForPage(page));
+ if (!tree) {
+ fprintf(stderr, "Failed to load struct tree for page %d\n", page_idx);
+ return;
+ }
+
+ printf("Structure Tree for Page %d\n", page_idx);
+ for (int i = 0; i < FPDF_StructTree_CountChildren(tree.get()); ++i) {
+ FPDF_STRUCTELEMENT child = FPDF_StructTree_GetChildAtIndex(tree.get(), i);
+ if (!child) {
+ fprintf(stderr, "Failed to load child %d for page %d\n", i, page_idx);
+ continue;
+ }
+ DumpChildStructure(child, 0);
+ }
+ printf("\n\n");
+}
+
+void DumpMetaData(FPDF_DOCUMENT doc) {
+ constexpr const char* meta_tags[] = {"Title", "Author", "Subject",
+ "Keywords", "Creator", "Producer",
+ "CreationDate", "ModDate"};
+ for (const char* meta_tag : meta_tags) {
+ char meta_buffer[4096];
+ unsigned long len =
+ FPDF_GetMetaText(doc, meta_tag, meta_buffer, sizeof(meta_buffer));
+ if (!len)
+ continue;
+
+ auto* meta_string = reinterpret_cast<unsigned short*>(meta_buffer);
+ printf("%-12s = %ls (%lu bytes)\n", meta_tag,
+ GetPlatformWString(meta_string).c_str(), len);
+ }
+}