Class: Acrofill::Appearance
- Inherits:
-
Object
- Object
- Acrofill::Appearance
- Defined in:
- lib/acrofill/appearance.rb
Overview
Builds the /AP /N appearance stream (a Form XObject) for a filled text-field widget, honouring the field's /DA string and /Q alignment.
Constant Summary collapse
- PADDING =
2.0- ASCENT =
Helvetica cap-height-ish ascent, em fractions
0.718- DESCENT =
0.207- COLOR_OP_ARITY =
Colour-setting operators allowed in a /DA string, and their operand counts.
{ 'g' => 1, 'rg' => 3, 'k' => 4 }.freeze
Instance Method Summary collapse
-
#build(field_node, widget, value, multiline: false) ⇒ Object
Returns a Reference to the new appearance XObject, or nil when the widget geometry is unusable.
-
#initialize(doc, acroform) ⇒ Appearance
constructor
A new instance of Appearance.
Constructor Details
#initialize(doc, acroform) ⇒ Appearance
Returns a new instance of Appearance.
13 14 15 16 |
# File 'lib/acrofill/appearance.rb', line 13 def initialize(doc, acroform) @doc = doc @acroform = acroform end |
Instance Method Details
#build(field_node, widget, value, multiline: false) ⇒ Object
Returns a Reference to the new appearance XObject, or nil when the widget geometry is unusable.
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/acrofill/appearance.rb', line 20 def build(field_node, , value, multiline: false) rect = normalized_rect([:Rect] || @doc.inherited_value(field_node, :Rect)) return nil unless rect width = rect[2] - rect[0] height = rect[3] - rect[1] return nil if width <= 0 || height <= 0 font_name, size, color_ops = parse_da(field_node) base_font = base_font_for(font_name) align = alignment(field_node) body = if multiline size = 12.0 if size <= 0 size = size.clamp(2.0, 144.0) multiline_body(value, base_font, size, width, height, align) else text = printable_text(value) size = [height * 0.66, 12.0].min if size.zero? size = shrink_to_fit(text, base_font, size, width) # Vertically center the ascent box, matching pdftk's baseline # placement exactly: ty = (h - ascent*size) / 2. ty = [(height - (size * ASCENT)) / 2.0, size * DESCENT].max "#{fmt(line_x(text, base_font, size, width, align))} #{fmt(ty)} Td\n" \ "(#{escape_literal(text)}) Tj\n" end content = +"/Tx BMC\nq\nBT\n" content << "#{color_ops}\n" unless color_ops.empty? content << "/#{font_name} #{fmt(size)} Tf\n" content << body content << "ET\nQ\nEMC\n" dict = { Type: :XObject, Subtype: :Form, FormType: 1, BBox: [0, 0, width, height], Resources: { Font: { font_name.to_sym => font_ref(font_name) } } } @doc.add(StreamObject.new(dict, content.b)) end |