From 82f3ff4824cdbf750312c5c3d757937f42d84daa Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Sun, 18 May 2025 09:44:55 +0300 Subject: [PATCH] fix narrow signatures --- app/javascript/submission_form/area.vue | 12 +- app/views/submissions/_value.html.erb | 7 +- .../generate_result_attachments.rb | 120 ++++++++++++------ 3 files changed, 95 insertions(+), 44 deletions(-) diff --git a/app/javascript/submission_form/area.vue b/app/javascript/submission_form/area.vue index d18aae5f..01819533 100644 --- a/app/javascript/submission_form/area.vue +++ b/app/javascript/submission_form/area.vue @@ -55,10 +55,12 @@ >
ID: {{ signature.uuid }} @@ -444,6 +447,9 @@ export default { } return style + }, + isNarrow () { + return this.area.h > 0 && (this.area.w / this.area.h) > 6 } }, watch: { diff --git a/app/views/submissions/_value.html.erb b/app/views/submissions/_value.html.erb index c9ab473d..852711fa 100644 --- a/app/views/submissions/_value.html.erb +++ b/app/views/submissions/_value.html.erb @@ -5,12 +5,13 @@ <% font_type = field.dig('preferences', 'font_type') %> width: <%= area['w'] * 100 %>%; height: <%= area['h'] * 100 %>%; left: <%= area['x'] * 100 %>%; top: <%= area['y'] * 100 %>%; <%= "font-size: clamp(4pt, 1.6vw, #{field['preferences']['font_size'].to_i * 1.23}pt); line-height: `clamp(6pt, 2.0vw, #{(field['preferences']['font_size'].to_i * 1.23) + 3}pt)`" if field.dig('preferences', 'font_size') %>"> <% if field['type'] == 'signature' %> -
-
+ <% is_narrow = area['h']&.positive? && (area['w'].to_f / area['h']) > 6 %> +
+
<% if local_assigns[:with_signature_id] && attachment = attachments_index[value] %> -
+
ID: <%= attachment.uuid %>
diff --git a/lib/submissions/generate_result_attachments.rb b/lib/submissions/generate_result_attachments.rb index 5414ff22..0a5da813 100644 --- a/lib/submissions/generate_result_attachments.rb +++ b/lib/submissions/generate_result_attachments.rb @@ -254,22 +254,6 @@ module Submissions image = Vips::Image.new_from_buffer(attachments_data_cache[attachment.uuid], '').autorot - id_string = "ID: #{attachment.uuid}".upcase - - while true - text = HexaPDF::Layout::TextFragment.create(id_string, - font:, - font_size: (font_size / 1.8).to_i) - - result = layouter.fit([text], area['w'] * width, (font_size / 1.8) / 0.65) - - break if result.status == :success - - id_string = "#{id_string.delete_suffix('...')[0..-2]}..." - - break if id_string.length < 8 - end - reason_value = submitter.values[field.dig('preferences', 'reason_field_uuid')].presence reason_string = @@ -284,35 +268,95 @@ module Submissions font:, font_size: (font_size / 1.8).to_i) - reason_result = layouter.fit([reason_text], area['w'] * width, height) + if area['h']&.positive? && (area['w'].to_f / area['h']) > 6 + area_x = area['x'] * width + area_y = area['y'] * height + area_w = area['w'] * width + area_h = area['h'] * height - text_height = result.lines.sum(&:height) + reason_result.lines.sum(&:height) + half_width = area_w / 2.0 + scale = [half_width / image.width, area_h / image.height].min + image_width = image.width * scale + image_height = image.height * scale + image_x = area_x + ((half_width - image_width) / 2.0) + image_y = height - area_y - image_height - image_height = (area['h'] * height) - text_height - image_height = (area['h'] * height) / 2 if image_height < (area['h'] * height) / 2 + io = StringIO.new(image.resize([scale * 4, 1].select(&:positive?).min).write_to_buffer('.png')) - scale = [(area['w'] * width) / image.width, image_height / image.height].min + canvas.image(io, at: [image_x, image_y], width: image_width, height: image_height) - io = StringIO.new(image.resize([scale * 4, 1].select(&:positive?).min).write_to_buffer('.png')) + id_string = "ID: #{attachment.uuid}".upcase - layouter.fit([text], area['w'] * width, (font_size / 1.8) / 0.65) - .draw(canvas, (area['x'] * width) + TEXT_LEFT_MARGIN, - height - (area['y'] * height) - TEXT_TOP_MARGIN - image_height) + while true + text = HexaPDF::Layout::TextFragment.create(id_string, + font:, + font_size: (font_size / 1.8).to_i) - layouter.fit([reason_text], area['w'] * width, reason_result.lines.sum(&:height)) - .draw(canvas, (area['x'] * width) + TEXT_LEFT_MARGIN, - height - (area['y'] * height) - TEXT_TOP_MARGIN - - result.lines.sum(&:height) - image_height) + result = layouter.fit([text], half_width, (font_size / 1.8) / 0.65) - canvas.image( - io, - at: [ - (area['x'] * width) + (area['w'] * width / 2) - ((image.width * scale) / 2), - height - (area['y'] * height) - (image.height * scale / 2) - (image_height / 2) - ], - width: image.width * scale, - height: image.height * scale - ) + break if result.status == :success + + id_string = "#{id_string.delete_suffix('...')[0..-2]}..." + + break if id_string.length < 8 + end + + text_x = area_x + half_width + text_y = height - area_y + + reason_result = layouter.fit([reason_text], half_width, height) + + layouter.fit([text], half_width, (font_size / 1.8) / 0.65) + .draw(canvas, text_x + TEXT_LEFT_MARGIN, text_y) + + layouter.fit([reason_text], half_width, reason_result.lines.sum(&:height)) + .draw(canvas, text_x + TEXT_LEFT_MARGIN, text_y - TEXT_TOP_MARGIN - result.lines.sum(&:height)) + else + id_string = "ID: #{attachment.uuid}".upcase + + loop do + text = HexaPDF::Layout::TextFragment.create(id_string, + font:, + font_size: (font_size / 1.8).to_i) + + result = layouter.fit([text], area['w'] * width, (font_size / 1.8) / 0.65) + + break if result.status == :success + + id_string = "#{id_string.delete_suffix('...')[0..-2]}..." + + break if id_string.length < 8 + end + + reason_result = layouter.fit([reason_text], area['w'] * width, height) + text_height = result.lines.sum(&:height) + reason_result.lines.sum(&:height) + + image_height = (area['h'] * height) - text_height + image_height = (area['h'] * height) / 2 if image_height < (area['h'] * height) / 2 + + scale = [(area['w'] * width) / image.width, image_height / image.height].min + + io = StringIO.new(image.resize([scale * 4, 1].select(&:positive?).min).write_to_buffer('.png')) + + layouter.fit([text], area['w'] * width, (font_size / 1.8) / 0.65) + .draw(canvas, (area['x'] * width) + TEXT_LEFT_MARGIN, + height - (area['y'] * height) - TEXT_TOP_MARGIN - image_height) + + layouter.fit([reason_text], area['w'] * width, reason_result.lines.sum(&:height)) + .draw(canvas, (area['x'] * width) + TEXT_LEFT_MARGIN, + height - (area['y'] * height) - TEXT_TOP_MARGIN - + result.lines.sum(&:height) - image_height) + + canvas.image( + io, + at: [ + (area['x'] * width) + (area['w'] * width / 2) - ((image.width * scale) / 2), + height - (area['y'] * height) - (image.height * scale / 2) - (image_height / 2) + ], + width: image.width * scale, + height: image.height * scale + ) + end when 'image', 'signature', 'initials', 'stamp' attachment = submitter.attachments.find { |a| a.uuid == value }