acro_that 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40016774a590828e59c4c9ea4331a8d170ccd536d7522cbdb193fefda3f28333
4
- data.tar.gz: bade6f113359d96d1f7c1a85efd7033732350c0b19bf40dd412e104da359aa5a
3
+ metadata.gz: ffb2119b2d0c114ad029baeff45ebcc155c660ef16a9a8ed844a9a9759861b67
4
+ data.tar.gz: 4d1101c45ad53eb66cf9ef16851e182220bce3b5862fe99f2a3e7c0af8d5dd04
5
5
  SHA512:
6
- metadata.gz: 60e6c6afd93cfd8911c0b0a0d4b6b080cb2c8af85a104cf3fd09f8fc7f9ac642999a8d5694c374ad64b71d4aa769f6d8b390cc82829317abd64598aa42e7280f
7
- data.tar.gz: 31762cf9f6f285edd78976692e9c5bab7a67cf6298a03c8d4208b02927639be29e0d1f4ca1f14c3f1c170b9f617404e0931dc8bbedd17de79fcee5c80035dd29
6
+ metadata.gz: 1ee4b2210fabe9d92f7296fc2d093dd281704e932e6f885b96e28a5ac470a96966180086a6689e9c8dff37bf2d35f21262a2a45f5e73a7070b9a9b1f90d8dabc
7
+ data.tar.gz: 4a23c547e4d42fad651be35ed769abf42ef308bcf6083ae11c15b7535f972d24b55afdf583a0396c4477819d2e0b7a6ef3169860b2e747206a5f9ed2fb3a5ee6
data/CHANGELOG.md CHANGED
@@ -5,7 +5,15 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [0.1.3] - 2025-01-XX
8
+ ## [0.1.5] - 2025-11-01
9
+
10
+ ### Fixed
11
+ - Fixed signature field image data parsing when adding signature fields. Image data (base64 or data URI) is now properly detected and parsed when creating signature fields, matching the behavior of `update_field`.
12
+
13
+ ### Added
14
+ - Added support for `metadata` option in `add_field` to pass PDF widget properties. This allows setting properties like field flags (`Ff`) for multiline text fields, alignment (`Q`), and other PDF widget options directly when creating fields.
15
+
16
+ ## [0.1.4] - 2025-11-01
9
17
 
10
18
  ### Fixed
11
19
  - Fixed bug where fields added to multi-page PDFs were all placed on the same page. Fields now correctly appear on their specified pages when using the `page` option in `add_field`.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- acro_that (0.1.2)
4
+ acro_that (0.1.4)
5
5
  chunky_png (~> 1.4)
6
6
 
7
7
  GEM
@@ -12,6 +12,7 @@ module AcroThat
12
12
  @document = document
13
13
  @name = name
14
14
  @options = options
15
+ @metadata = options[:metadata] || {}
15
16
  end
16
17
 
17
18
  def call
@@ -60,6 +61,19 @@ module AcroThat
60
61
  # Add widget to the target page's /Annots
61
62
  add_widget_to_page(widget_obj_num, page_num)
62
63
 
64
+ # If this is a signature field with image data, add the signature appearance
65
+ if @field_type == "/Sig" && @field_value && !@field_value.empty?
66
+ image_data = @field_value
67
+ # Check if value looks like base64 image data or data URI (same logic as update_field)
68
+ if image_data.is_a?(String) && (image_data.start_with?("data:image/") || (image_data.length > 50 && image_data.match?(%r{^[A-Za-z0-9+/]*={0,2}$})))
69
+ field_ref = [@field_obj_num, 0]
70
+ # Try adding signature appearance - use width and height from options
71
+ action = Actions::AddSignatureAppearance.new(@document, field_ref, image_data, width: width, height: height)
72
+ # NOTE: We don't fail if appearance addition fails - field was still created successfully
73
+ action.call
74
+ end
75
+ end
76
+
63
77
  true
64
78
  end
65
79
 
@@ -69,9 +83,33 @@ module AcroThat
69
83
  dict = "<<\n"
70
84
  dict += " /FT #{type}\n"
71
85
  dict += " /T #{DictScan.encode_pdf_string(@name)}\n"
72
- dict += " /Ff 0\n"
86
+
87
+ # Apply /Ff from metadata, or use default 0
88
+ field_flags = @metadata[:Ff] || @metadata["Ff"] || 0
89
+ dict += " /Ff #{field_flags}\n"
90
+
73
91
  dict += " /DA (/Helv 0 Tf 0 g)\n"
74
- dict += " /V #{DictScan.encode_pdf_string(value)}\n" if value && !value.empty?
92
+
93
+ # For signature fields with image data, don't set /V (appearance stream will be added separately)
94
+ # For other fields or non-image signature values, set /V normally
95
+ should_set_value = if type == "/Sig" && value && !value.empty?
96
+ # Check if value looks like image data
97
+ !(value.is_a?(String) && (value.start_with?("data:image/") || (value.length > 50 && value.match?(%r{^[A-Za-z0-9+/]*={0,2}$}))))
98
+ else
99
+ true
100
+ end
101
+
102
+ dict += " /V #{DictScan.encode_pdf_string(value)}\n" if should_set_value && value && !value.empty?
103
+
104
+ # Apply other metadata entries (excluding Ff which we handled above)
105
+ @metadata.each do |key, val|
106
+ next if [:Ff, "Ff"].include?(key) # Already handled above
107
+
108
+ pdf_key = format_pdf_key(key)
109
+ pdf_value = format_pdf_value(val)
110
+ dict += " #{pdf_key} #{pdf_value}\n"
111
+ end
112
+
75
113
  dict += ">>"
76
114
  dict
77
115
  end
@@ -87,7 +125,29 @@ module AcroThat
87
125
  widget += " /Rect #{rect_array}\n"
88
126
  widget += " /F 4\n"
89
127
  widget += " /DA (/Helv 0 Tf 0 g)\n"
90
- widget += " /V #{DictScan.encode_pdf_string(value)}\n" if value && !value.empty?
128
+
129
+ # For signature fields with image data, don't set /V (appearance stream will be added separately)
130
+ # For other fields or non-image signature values, set /V normally
131
+ should_set_value = if type == "/Sig" && value && !value.empty?
132
+ # Check if value looks like image data
133
+ !(value.is_a?(String) && (value.start_with?("data:image/") || (value.length > 50 && value.match?(%r{^[A-Za-z0-9+/]*={0,2}$}))))
134
+ else
135
+ true
136
+ end
137
+
138
+ widget += " /V #{DictScan.encode_pdf_string(value)}\n" if should_set_value && value && !value.empty?
139
+
140
+ # Apply metadata entries that are valid for widgets
141
+ # Common widget properties: /Q (alignment), /Ff (field flags), /BS (border style), etc.
142
+ @metadata.each do |key, val|
143
+ pdf_key = format_pdf_key(key)
144
+ pdf_value = format_pdf_value(val)
145
+ # Only add if not already present (we've added /F above, /V above if value exists)
146
+ next if ["/F", "/V"].include?(pdf_key)
147
+
148
+ widget += " #{pdf_key} #{pdf_value}\n"
149
+ end
150
+
91
151
  widget += ">>"
92
152
  widget
93
153
  end
@@ -220,6 +280,42 @@ module AcroThat
220
280
  apply_patch(target_page_ref, new_body, page_body) if new_body && new_body != page_body
221
281
  true
222
282
  end
283
+
284
+ # Format a metadata key as a PDF dictionary key (ensure it starts with /)
285
+ def format_pdf_key(key)
286
+ key_str = key.to_s
287
+ key_str.start_with?("/") ? key_str : "/#{key_str}"
288
+ end
289
+
290
+ # Format a metadata value appropriately for PDF
291
+ def format_pdf_value(value)
292
+ case value
293
+ when Integer, Float
294
+ value.to_s
295
+ when String
296
+ # If it looks like a PDF string (starts with parenthesis or angle bracket), use as-is
297
+ if value.start_with?("(") || value.start_with?("<") || value.start_with?("/")
298
+ value
299
+ else
300
+ # Otherwise encode as a PDF string
301
+ DictScan.encode_pdf_string(value)
302
+ end
303
+ when Array
304
+ # Array format: [item1 item2 item3]
305
+ items = value.map { |v| format_pdf_value(v) }.join(" ")
306
+ "[#{items}]"
307
+ when Hash
308
+ # Dictionary format: << /Key1 value1 /Key2 value2 >>
309
+ dict = value.map do |k, v|
310
+ pdf_key = format_pdf_key(k)
311
+ pdf_val = format_pdf_value(v)
312
+ " #{pdf_key} #{pdf_val}"
313
+ end.join("\n")
314
+ "<<\n#{dict}\n>>"
315
+ else
316
+ value.to_s
317
+ end
318
+ end
223
319
  end
224
320
  end
225
321
  end
@@ -203,7 +203,7 @@ module AcroThat
203
203
  next unless body
204
204
 
205
205
  is_widget = DictScan.is_widget?(body)
206
-
206
+
207
207
  # Collect widget information if this is a widget
208
208
  if is_widget
209
209
  # Extract position from widget
@@ -88,4 +88,3 @@ module AcroThat
88
88
  end
89
89
  end
90
90
  end
91
-
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AcroThat
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acro_that
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Wynkoop