Class: CorpPdf::Fields::Signature
- Inherits:
-
Object
- Object
- CorpPdf::Fields::Signature
- Includes:
- Base
- Defined in:
- lib/corp_pdf/fields/signature.rb
Overview
Handles signature field creation
Instance Attribute Summary collapse
-
#field_obj_num ⇒ Object
readonly
Returns the value of attribute field_obj_num.
Attributes included from Base
#document, #field_type, #field_value, #metadata, #name, #options
Class Method Summary collapse
-
.add_appearance(document, field_ref, image_data, width: nil, height: nil) ⇒ Object
Class method to add appearance to an existing signature field Can be called from both Signature field creation and UpdateField.
Instance Method Summary collapse
Methods included from Base
#height, #initialize, #page_num, #width, #x, #y
Methods included from Actions::Base
#acroform_ref, #apply_patch, #find_page_by_number, #get_object_body_with_patch, #next_fresh_object_number, #patches, #resolver
Instance Attribute Details
#field_obj_num ⇒ Object (readonly)
Returns the value of attribute field_obj_num.
11 12 13 |
# File 'lib/corp_pdf/fields/signature.rb', line 11 def field_obj_num @field_obj_num end |
Class Method Details
.add_appearance(document, field_ref, image_data, width: nil, height: nil) ⇒ Object
Class method to add appearance to an existing signature field Can be called from both Signature field creation and UpdateField
15 16 17 |
# File 'lib/corp_pdf/fields/signature.rb', line 15 def self.add_appearance(document, field_ref, image_data, width: nil, height: nil) new(document, "", {}).add_appearance_to_field(field_ref, image_data, width: width, height: height) end |
Instance Method Details
#add_appearance_to_field(field_ref, image_data, width: nil, height: nil) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/corp_pdf/fields/signature.rb', line 47 def add_appearance_to_field(field_ref, image_data, width: nil, height: nil) return false unless field_ref && image_data && !image_data.empty? # Decode image data if needed decoded_image_data = image_data.is_a?(String) && image_data.start_with?("data:") ? decode_base64_data_uri(image_data) : decode_base64_if_needed(image_data) return false unless decoded_image_data && !decoded_image_data.empty? # Detect image format and dimensions image_info = detect_image_format(decoded_image_data) return false unless image_info # Find widget annotation for this field = (field_ref) return false unless = get_object_body_with_patch() return false unless # Get widget rectangle for appearance size rect = extract_rect() return false unless rect # Ensure width and height are positive rect_width = (rect[:x2] - rect[:x1]).abs rect_height = (rect[:y2] - rect[:y1]).abs return false if rect_width <= 0 || rect_height <= 0 # Get field dimensions (use provided width/height or field rect) field_width = width || rect_width field_height = height || rect_height # Get image natural dimensions image_width = image_info[:width].to_f image_height = image_info[:height].to_f return false if image_width <= 0 || image_height <= 0 # Calculate scaling factor to fit image within field while maintaining aspect ratio scale_x = field_width / image_width scale_y = field_height / image_height scale_factor = [scale_x, scale_y].min # Calculate scaled dimensions (maintains aspect ratio, fits within field) scaled_width = image_width * scale_factor scaled_height = image_height * scale_factor # Create Image XObject(s) - use natural image dimensions (not scaled) image_obj_num = next_fresh_object_number image_result = create_image_xobject(image_obj_num, decoded_image_data, image_info, image_width, image_height) image_body = image_result[:body] mask_obj_num = image_result[:mask_obj_num] # Create Form XObject (appearance stream) - use field dimensions for bounding box form_obj_num = mask_obj_num ? mask_obj_num + 1 : image_obj_num + 1 form_body = create_form_xobject(form_obj_num, image_obj_num, field_width, field_height, scale_factor, scaled_width, scaled_height) # Queue new objects document.instance_variable_get(:@patches) << { ref: [image_obj_num, 0], body: image_body } if mask_obj_num document.instance_variable_get(:@patches) << { ref: [mask_obj_num, 0], body: image_result[:mask_body] } end document.instance_variable_get(:@patches) << { ref: [form_obj_num, 0], body: form_body } # Update widget annotation with /AP dictionary # Use already-loaded widget_body as original (we already have it from line 62) # Only reload if we don't have it (shouldn't happen, but for safety) = || resolver.object_body() = (, form_obj_num) apply_patch(, , ) true end |
#call ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/corp_pdf/fields/signature.rb', line 19 def call @field_obj_num = next_fresh_object_number = @field_obj_num + 1 field_body = create_field_dictionary(@field_value, @field_type) page_ref = find_page_ref(page_num) = (, [@field_obj_num, 0], page_ref, x, y, width, height, @field_type, @field_value) document.instance_variable_get(:@patches) << { ref: [@field_obj_num, 0], body: field_body } document.instance_variable_get(:@patches) << { ref: [, 0], body: } add_field_to_acroform_with_defaults(@field_obj_num) (, page_num) # If this is a signature field with image data, add the signature appearance if @field_value && !@field_value.empty? image_data = @field_value 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}$}))) field_ref = [@field_obj_num, 0] add_appearance_to_field(field_ref, image_data, width: width, height: height) end end true end |