Class: HexaPDF::Type::Annotations::Widget

Inherits:
HexaPDF::Type::Annotation show all
Includes:
BorderStyling
Defined in:
lib/hexapdf/type/annotations/widget.rb

Overview

Widget annotations are used by interactive forms to represent the appearance of fields and to manage user interactions.

See: PDF2.0 s12.5.6.19, HexaPDF::Type::Annotation

Defined Under Namespace

Classes: AppearanceCharacteristics, MarkerStyle

Constant Summary

Constants included from DictionaryFields

DictionaryFields::Boolean, DictionaryFields::PDFByteString, DictionaryFields::PDFDate

Instance Attribute Summary

Attributes inherited from Object

#data, #document, #must_be_indirect

Instance Method Summary collapse

Methods included from BorderStyling

#border_style

Methods inherited from HexaPDF::Type::Annotation

#appearance, #appearance_dict, #contents, #create_appearance, #flags, #must_be_indirect?, #opacity, #regenerate_appearance

Methods included from Utils::BitField

#bit_field

Methods inherited from Dictionary

#[], #[]=, define_field, define_type, #delete, #each, each_field, #empty?, field, #key?, #to_hash, type, #type

Methods inherited from Object

#<=>, #==, #cache, #cached?, #clear_cache, deep_copy, #deep_copy, #document?, #eql?, field, #gen, #gen=, #hash, #indirect?, #initialize, #inspect, make_direct, #must_be_indirect?, #null?, #oid, #oid=, #type, #validate, #value, #value=

Constructor Details

This class inherits a constructor from HexaPDF::Object

Instance Method Details

#background_color(*color) ⇒ Object

:call-seq:

widget.background_color                => background_color or nil
widget.background_color(*color)        => widget

Returns the current background color as device color object, or nil if no background color is set, when no argument is given. Otherwise sets the background color using the color argument and returns self.

See HexaPDF::Content::ColorSpace.device_color_from_specification for information on the allowed arguments.



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/hexapdf/type/annotations/widget.rb', line 114

def background_color(*color)
  if color.empty?
    components = self[:MK]&.[](:BG)
    if components && !components.empty?
      Content::ColorSpace.prenormalized_device_color(components)
    end
  else
    color = Content::ColorSpace.device_color_from_specification(color)
    (self[:MK] ||= {})[:BG] = color.components
    self
  end
end

#form_fieldObject

Returns the AcroForm field object to which this widget annotation belongs.

Since a widget and a field can share the same dictionary object, the returned object is often just the widget re-wrapped in the correct field class.



94
95
96
97
98
99
100
101
102
# File 'lib/hexapdf/type/annotations/widget.rb', line 94

def form_field
  field = if key?(:Parent) &&
              (tmp = document.wrap(self[:Parent], type: :XXAcroFormField)).terminal_field?
            tmp
          else
            document.wrap(self, type: :XXAcroFormField)
          end
  document.wrap(field, type: :XXAcroFormField, subtype: field[:FT])
end

#marker_style(style: nil, size: nil, color: nil, font_name: nil) ⇒ Object

:call-seq:

widget.marker_style                                                      => marker_style
widget.marker_style(style: nil, size: nil, color: nil, font_name: nil)   => widget

Returns a MarkerStyle instance representing the marker style of the widget when no argument is given. Otherwise sets the button marker style of the widget and returns self.

This method returns valid information only for check boxes, radio buttons and push buttons!

When setting a marker style, arguments that are not provided will use the default:

  • For check boxes a black auto-sized checkmark (i.e. :check)

  • For radio buttons a black auto-sized circle (i.e. :circle)

  • For push buttons a black 9pt empty text using Helvetica

This also means that multiple invocations will reset all prior values.

Note that the font_name argument must be a valid HexaPDF font name (this is in contrast to MarkerStyle#font_name which returns the resource name of the font).

Note: The marker is called “normal caption” in the PDF 2.0 spec and the /CA entry of the associated appearance characteristics dictionary. The marker size and color are set using the /DA key on the widget (although /DA is not defined for widget, this is how Acrobat does it).

See: PDF2.0 s12.5.6.19 and s12.7.4.3



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/hexapdf/type/annotations/widget.rb', line 193

def marker_style(style: nil, size: nil, color: nil, font_name: nil)
  field = form_field
  if style || size || color || font_name
    style ||= case field.concrete_field_type
              when :check_box then :check
              when :radio_button then :circle
              when :push_button then ''
              end
    size ||= (field.push_button? ? 9 : 0)
    color = Content::ColorSpace.device_color_from_specification(color || 0)
    serialized_color = Content::ColorSpace.serialize_device_color(color)
    font_name ||= 'Helvetica'

    self[:MK] ||= {}
    self[:MK][:CA] = case style
                     when :check   then '4'
                     when :circle  then 'l'
                     when :cross   then '8'
                     when :diamond then 'u'
                     when :square  then 'n'
                     when :star    then 'H'
                     when String   then style
                     else
                       raise ArgumentError, "Unknown value #{style} for argument 'style'"
                     end
    self[:DA] = if field.push_button?
                  name = document.acro_form(create: true).default_resources.
                    add_font(document.fonts.add(font_name).pdf_object)
                  "/#{name} #{size} Tf #{serialized_color}".strip
                else
                  "/ZaDb #{size} Tf #{serialized_color}".strip
                end
  else
    style = case self[:MK]&.[](:CA)
            when '4' then :check
            when 'l' then :circle
            when '8' then :cross
            when 'u' then :diamond
            when 'n' then :square
            when 'H' then :star
            when String then self[:MK][:CA]
            else
              if field.check_box?
                :check
              else
                :circle
              end
            end
    size = 0
    color = HexaPDF::Content::ColorSpace.prenormalized_device_color([0])
    if (da = self[:DA] || field[:DA])
      font_name, da_size, da_color = AcroForm::VariableTextField.parse_appearance_string(da)
      size = da_size || size
      color = da_color || color
    end

    MarkerStyle.new(style, size, color, font_name)
  end
end