acro_that 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile.lock +1 -1
- data/README.md +49 -0
- data/docs/README.md +12 -0
- data/docs/clear_fields.md +202 -0
- data/issues/README.md +38 -0
- data/issues/refactoring-opportunities.md +269 -0
- data/lib/acro_that/actions/add_field.rb +2 -55
- data/lib/acro_that/actions/add_signature_appearance.rb +3 -3
- data/lib/acro_that/actions/base.rb +4 -0
- data/lib/acro_that/actions/remove_field.rb +1 -5
- data/lib/acro_that/dict_scan.rb +7 -0
- data/lib/acro_that/document.rb +480 -45
- data/lib/acro_that/version.rb +1 -1
- data/lib/acro_that.rb +1 -0
- data/publish +183 -0
- metadata +5 -1
|
@@ -153,61 +153,8 @@ module AcroThat
|
|
|
153
153
|
end
|
|
154
154
|
|
|
155
155
|
def find_page_ref(page_num)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
next unless body
|
|
159
|
-
|
|
160
|
-
# Check for /Type /Page with or without space, or /Type/Page
|
|
161
|
-
is_page = body.include?("/Type /Page") ||
|
|
162
|
-
body.include?("/Type/Page") ||
|
|
163
|
-
(body.include?("/Type") && body.include?("/Page") && body =~ %r{/Type\s*/Page})
|
|
164
|
-
next unless is_page
|
|
165
|
-
|
|
166
|
-
page_objects << ref
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
# If still no pages found, try to find them via the page tree
|
|
170
|
-
if page_objects.empty?
|
|
171
|
-
# Find the document catalog's /Pages entry
|
|
172
|
-
root_ref = resolver.root_ref
|
|
173
|
-
if root_ref
|
|
174
|
-
catalog_body = resolver.object_body(root_ref)
|
|
175
|
-
if catalog_body && catalog_body =~ %r{/Pages\s+(\d+)\s+(\d+)\s+R}
|
|
176
|
-
pages_ref = [Integer(::Regexp.last_match(1)), Integer(::Regexp.last_match(2))]
|
|
177
|
-
pages_body = resolver.object_body(pages_ref)
|
|
178
|
-
|
|
179
|
-
# Extract /Kids array from Pages object
|
|
180
|
-
if pages_body && pages_body =~ %r{/Kids\s*\[(.*?)\]}m
|
|
181
|
-
kids_array = ::Regexp.last_match(1)
|
|
182
|
-
# Extract all object references from Kids array
|
|
183
|
-
kids_array.scan(/(\d+)\s+(\d+)\s+R/) do |num_str, gen_str|
|
|
184
|
-
kid_ref = [num_str.to_i, gen_str.to_i]
|
|
185
|
-
kid_body = resolver.object_body(kid_ref)
|
|
186
|
-
# Check if this kid is a page or another Pages node
|
|
187
|
-
if kid_body && (kid_body.include?("/Type /Page") || kid_body.include?("/Type/Page") || (kid_body.include?("/Type") && kid_body.include?("/Page")))
|
|
188
|
-
page_objects << kid_ref
|
|
189
|
-
elsif kid_body && kid_body.include?("/Type /Pages")
|
|
190
|
-
# Recursively find pages in this Pages node
|
|
191
|
-
if kid_body =~ %r{/Kids\s*\[(.*?)\]}m
|
|
192
|
-
kid_body[::Regexp.last_match(0)..].scan(/(\d+)\s+(\d+)\s+R/) do |n, g|
|
|
193
|
-
grandkid_ref = [n.to_i, g.to_i]
|
|
194
|
-
grandkid_body = resolver.object_body(grandkid_ref)
|
|
195
|
-
if grandkid_body && (grandkid_body.include?("/Type /Page") || grandkid_body.include?("/Type/Page"))
|
|
196
|
-
page_objects << grandkid_ref
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
return page_objects[0] if page_objects.empty?
|
|
208
|
-
return page_objects[page_num - 1] if page_num.positive? && page_num <= page_objects.length
|
|
209
|
-
|
|
210
|
-
page_objects[0]
|
|
156
|
+
# Use Document's unified page-finding method
|
|
157
|
+
find_page_by_number(page_num)
|
|
211
158
|
end
|
|
212
159
|
|
|
213
160
|
def add_widget_to_page(widget_obj_num, page_num)
|
|
@@ -336,10 +336,10 @@ module AcroThat
|
|
|
336
336
|
end
|
|
337
337
|
|
|
338
338
|
def create_form_xobject(_obj_num, image_obj_num, field_width, field_height, _scale_factor, scaled_width,
|
|
339
|
-
|
|
339
|
+
scaled_height)
|
|
340
340
|
# Calculate offset to left-align the image horizontally and center vertically
|
|
341
|
-
offset_x = 0.0
|
|
342
|
-
offset_y = (field_height - scaled_height) / 2.0
|
|
341
|
+
offset_x = 0.0 # Left-aligned (no horizontal offset)
|
|
342
|
+
offset_y = (field_height - scaled_height) / 2.0 # Center vertically
|
|
343
343
|
|
|
344
344
|
# PDF content stream that draws the image
|
|
345
345
|
# q = save graphics state
|
|
@@ -107,11 +107,7 @@ module AcroThat
|
|
|
107
107
|
page_objects = []
|
|
108
108
|
resolver.each_object do |ref, body|
|
|
109
109
|
next unless body
|
|
110
|
-
|
|
111
|
-
is_page = body.include?("/Type /Page") ||
|
|
112
|
-
body.include?("/Type/Page") ||
|
|
113
|
-
(body.include?("/Type") && body.include?("/Page") && body =~ %r{/Type\s*/Page})
|
|
114
|
-
next unless is_page
|
|
110
|
+
next unless DictScan.is_page?(body)
|
|
115
111
|
|
|
116
112
|
page_objects << ref
|
|
117
113
|
end
|
data/lib/acro_that/dict_scan.rb
CHANGED
|
@@ -316,6 +316,13 @@ module AcroThat
|
|
|
316
316
|
body.include?("/Subtype") && body.include?("/Widget") && body =~ %r{/Subtype\s*/Widget}
|
|
317
317
|
end
|
|
318
318
|
|
|
319
|
+
# Check if a body represents a page object (not /Type/Pages)
|
|
320
|
+
def is_page?(body)
|
|
321
|
+
return false unless body
|
|
322
|
+
|
|
323
|
+
body.include?("/Type /Page") || body =~ %r{/Type\s*/Page(?!s)\b}
|
|
324
|
+
end
|
|
325
|
+
|
|
319
326
|
# Check if a field is multiline by checking /Ff flag bit 12 (0x1000)
|
|
320
327
|
def is_multiline_field?(dict_body)
|
|
321
328
|
return false unless dict_body
|