Make pdfium_test_dump_helper more readable, similar to Acrobat
Current dump for struct tree does not print keys. It also doesn't print
newly added fields. Improving it to match Acrobat's output.
Change-Id: I482cecc1449370d5b6aa4796b14aef36c2dd0e97
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/90490
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/samples/pdfium_test_dump_helper.cc b/samples/pdfium_test_dump_helper.cc
index 164f0d0..3f43a7f 100644
--- a/samples/pdfium_test_dump_helper.cc
+++ b/samples/pdfium_test_dump_helper.cc
@@ -42,24 +42,125 @@
rect.left, rect.bottom, rect.right, rect.top);
}
+void DumpStructureElementAttributes(FPDF_STRUCTELEMENT_ATTR attr, int indent) {
+ static const size_t kBufSize = 1024;
+ int count = FPDF_StructElement_Attr_GetCount(attr);
+ for (int i = 0; i < count; i++) {
+ char name[kBufSize] = {};
+ unsigned long len = ULONG_MAX;
+ if (!FPDF_StructElement_Attr_GetName(attr, i, name, sizeof(name), &len)) {
+ printf("%*s FPDF_StructElement_Attr_GetName failed for %d\n", indent, "",
+ i);
+ continue;
+ }
+
+ FPDF_OBJECT_TYPE type = FPDF_StructElement_Attr_GetType(attr, name);
+ if (type == FPDF_OBJECT_BOOLEAN) {
+ int value;
+ if (!FPDF_StructElement_Attr_GetBooleanValue(attr, name, &value)) {
+ printf("%*s %s: Failed FPDF_StructElement_Attr_GetBooleanValue\n",
+ indent, "", name);
+ continue;
+ }
+ printf("%*s %s: %d\n", indent, "", name, value);
+ } else if (type == FPDF_OBJECT_NUMBER) {
+ float value;
+ if (!FPDF_StructElement_Attr_GetNumberValue(attr, name, &value)) {
+ printf("%*s %s: Failed FPDF_StructElement_Attr_GetNumberValue\n",
+ indent, "", name);
+ continue;
+ }
+ printf("%*s %s: %f\n", indent, "", name, value);
+ } else if (type == FPDF_OBJECT_STRING || type == FPDF_OBJECT_NAME) {
+ unsigned short buffer[kBufSize] = {};
+ if (!FPDF_StructElement_Attr_GetStringValue(attr, name, buffer,
+ sizeof(buffer), &len)) {
+ printf("%*s %s: Failed FPDF_StructElement_Attr_GetStringValue\n",
+ indent, "", name);
+ continue;
+ }
+ printf("%*s %s: %ls\n", indent, "", name,
+ ConvertToWString(buffer, len).c_str());
+ } else if (type == FPDF_OBJECT_UNKNOWN) {
+ printf("%*s %s: FPDF_OBJECT_UNKNOWN\n", indent, "", name);
+ } else {
+ printf("%*s %s: NOT_YET_IMPLEMENTED: %d\n", indent, "", name, type);
+ }
+ }
+}
+
} // 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());
+ if (len > 0)
+ printf("%*s S: %ls\n", indent * 2, "", ConvertToWString(buf, len).c_str());
+
+ int attr_count = FPDF_StructElement_GetAttributeCount(child);
+ for (int i = 0; i < attr_count; i++) {
+ FPDF_STRUCTELEMENT_ATTR child_attr =
+ FPDF_StructElement_GetAttributeAtIndex(child, i);
+ if (!child_attr)
+ continue;
+ printf("%*s A[%d]:\n", indent * 2, "", i);
+ DumpStructureElementAttributes(child_attr, indent * 2 + 2);
+ }
memset(buf, 0, sizeof(buf));
- len = FPDF_StructElement_GetTitle(child, buf, kBufSize);
- if (len > 0)
- printf(": '%ls'", ConvertToWString(buf, len).c_str());
+ len = FPDF_StructElement_GetActualText(child, buf, kBufSize);
+ if (len > 0) {
+ printf("%*s ActualText: %ls\n", indent * 2, "",
+ ConvertToWString(buf, len).c_str());
+ }
memset(buf, 0, sizeof(buf));
len = FPDF_StructElement_GetAltText(child, buf, kBufSize);
+ if (len > 0) {
+ printf("%*s AltText: %ls\n", indent * 2, "",
+ ConvertToWString(buf, len).c_str());
+ }
+
+ memset(buf, 0, sizeof(buf));
+ len = FPDF_StructElement_GetID(child, buf, kBufSize);
if (len > 0)
- printf(" (%ls)", ConvertToWString(buf, len).c_str());
- printf("\n");
+ printf("%*s ID: %ls\n", indent * 2, "", ConvertToWString(buf, len).c_str());
+
+ memset(buf, 0, sizeof(buf));
+ len = FPDF_StructElement_GetLang(child, buf, kBufSize);
+ if (len > 0) {
+ printf("%*s Lang: %ls\n", indent * 2, "",
+ ConvertToWString(buf, len).c_str());
+ }
+
+ int mcid = FPDF_StructElement_GetMarkedContentID(child);
+ if (mcid != -1)
+ printf("%*s MCID: %d\n", indent * 2, "", mcid);
+
+ FPDF_STRUCTELEMENT parent = FPDF_StructElement_GetParent(child);
+ if (parent) {
+ memset(buf, 0, sizeof(buf));
+ len = FPDF_StructElement_GetID(parent, buf, kBufSize);
+ if (len > 0) {
+ printf("%*s Parent ID: %ls\n", indent * 2, "",
+ ConvertToWString(buf, len).c_str());
+ }
+ }
+
+ memset(buf, 0, sizeof(buf));
+ len = FPDF_StructElement_GetTitle(child, buf, kBufSize);
+ if (len > 0) {
+ printf("%*s Title: %ls\n", indent * 2, "",
+ ConvertToWString(buf, len).c_str());
+ }
+
+ memset(buf, 0, sizeof(buf));
+ len = FPDF_StructElement_GetObjType(child, buf, kBufSize);
+ if (len > 0) {
+ printf("%*s Type: %ls\n", indent * 2, "",
+ ConvertToWString(buf, len).c_str());
+ }
for (int i = 0; i < FPDF_StructElement_CountChildren(child); ++i) {
FPDF_STRUCTELEMENT sub_child = FPDF_StructElement_GetChildAtIndex(child, i);