From 50ce44213d2609f892554bdfccbbc8322dbfc01e Mon Sep 17 00:00:00 2001 From: airgalss <45360387+airgalss@users.noreply.github.com> Date: Tue, 28 Nov 2023 23:06:19 +0800 Subject: [PATCH] Fixed the bug where `button_states()` returns None when `/AP` points to an indirect object. Description: Some PDF widget objects may not have their `/AP`(Appearance Dictionary) directly pointing to a dictionary, which is enclosed with '<< >>', but rather pointing to an indirect object, expressed by an xref number in the format 'NNN 0 R'. Therefore, the current button_states() only can correctly handle cases where `/AP` points to a dictionary and cannot handle cases where it points to an indirect object. Consequently, I have introduced additional logic to handle the latter scenario, ensuring that `button_states()` can accurately return the on/off state names for button widgets even when `/AP` points to an indirect object. Test: I have tested the modified `button_states()` function on the mentioned type of PDF, and it now correctly returns the states instead of None. I have copied the method's code to the same-named method in `src/__init__.py`. --- fitz/helper-fields.i | 16 ++++++++++++++++ src/__init__.py | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/fitz/helper-fields.i b/fitz/helper-fields.i index 3a6805a62..721dc34fe 100644 --- a/fitz/helper-fields.i +++ b/fitz/helper-fields.i @@ -1097,6 +1097,14 @@ class Widget(object): for x in apnt: nstates.append(x.split()[0]) states["normal"] = nstates + if APN[0] == "xref": + nstates = [] + nxref = int(APN[1].split(" ")[0]) + APN = doc.xref_object(nxref) + apnt = APN.split("/")[1:] + for x in apnt: + nstates.append(x.split()[0]) + states["normal"] = nstates APD = doc.xref_get_key(xref, "AP/D") if APD[0] == "dict": dstates = [] @@ -1105,6 +1113,14 @@ class Widget(object): for x in apdt: dstates.append(x.split()[0]) states["down"] = dstates + if APD[0] == "xref": + dstates = [] + dxref = int(APD[1].split(" ")[0]) + APD = doc.xref_object(dxref) + apdt = APD.split("/")[1:] + for x in apdt: + dstates.append(x.split()[0]) + states["down"] = dstates return states def on_state(self): diff --git a/src/__init__.py b/src/__init__.py index cd50d029d..3ae84cad7 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -6992,6 +6992,14 @@ def button_states(self): for x in apnt: nstates.append(x.split()[0]) states["normal"] = nstates + if APN[0] == "xref": + nstates = [] + nxref = int(APN[1].split(" ")[0]) + APN = doc.xref_object(nxref) + apnt = APN.split("/")[1:] + for x in apnt: + nstates.append(x.split()[0]) + states["normal"] = nstates APD = doc.xref_get_key(xref, "AP/D") if APD[0] == "dict": dstates = [] @@ -7000,6 +7008,14 @@ def button_states(self): for x in apdt: dstates.append(x.split()[0]) states["down"] = dstates + if APD[0] == "xref": + dstates = [] + dxref = int(APD[1].split(" ")[0]) + APD = doc.xref_object(dxref) + apdt = APD.split("/")[1:] + for x in apdt: + dstates.append(x.split()[0]) + states["down"] = dstates return states @property