class HexaPDF::Type::Annotation

See: PDF2.0 s12.5
PDF page or allow the user to interact with a PDF document using a keyboard or mouse.
Annotations are used to associate objects like notes, sounds or movies with a location on a

def appearance(type: :normal, state_name: self[:AS])

necessary.
The appearance state in /AS or the one provided via +state_name+ is taken into account if

or +nil+ if it doesn't exist.
Returns the annotation's appearance stream of the given type (:normal, :rollover, or :down)
def appearance(type: :normal, state_name: self[:AS])
  entry = appearance_dict&.send("#{type}_appearance")
  if entry.kind_of?(HexaPDF::Dictionary) && !entry.kind_of?(HexaPDF::Stream)
    entry = entry[state_name]
  end
  return unless entry.kind_of?(HexaPDF::Stream)
  if entry.type == :XObject && entry[:Subtype] == :Form && !entry.instance_of?(HexaPDF::Stream)
    entry
  elsif (entry[:Type].nil? || entry[:Type] == :XObject) &&
      (entry[:Subtype].nil? || entry[:Subtype] == :Form) && entry[:BBox]
    document.wrap(entry, type: :XObject, subtype: :Form)
  end
end

def appearance_dict

set.
Returns the AppearanceDictionary instance associated with the annotation or +nil+ if none is
def appearance_dict
  self[:AP]
end

def contents(text = :UNSET)

A value of +nil+ means deleting the existing contents entry.

contents.
that should be displayed for the annotation or an alternate description of the annotation's
The contents is used differently depending on the annotation type. It is either the text

returns self.
Returns the text of the annotation when no argument is given. Otherwise sets the text and

annot.contents(text) => annot
annot.contents => contents or +nil+
:call-seq:
def contents(text = :UNSET)
  if text == :UNSET
    self[:Contents]
  else
    self[:Contents] = text
    self
  end
end

def create_appearance(type: :normal, state_name: self[:AS])

argument to provide the appearance state name.
If there can be multiple appearance streams for the annotation, use the +state_name+

or :down) and returns it. If an appearance stream already exist, it is overwritten.
Creates an empty appearance stream (a Form XObject) of the given type (:normal, :rollover,
def create_appearance(type: :normal, state_name: self[:AS])
  xobject = document.add({Type: :XObject, Subtype: :Form,
                          BBox: [0, 0, self[:Rect].width, self[:Rect].height]})
  self[:AP] ||= {}
  appearance_dict.set_appearance(xobject, type: type, state_name: state_name)
  xobject
end

def must_be_indirect?

Returns +true+ because annotation objects must always be indirect objects.
def must_be_indirect?
  true
end

def opacity(fill_alpha: nil, stroke_alpha: nil)

applies not just to fill values but to all non-stroking operations (e.g. images, ...).
stream and determine how opaque drawn elements will be. Note that the fill alpha value
The fill and stroke alpha values are used when regenerating the annotation's appearance

are given. Otherwise sets the provided alpha values and returns self.
Returns an Opacity instance representing the fill and stroke alpha values when no arguments

annotation.opacity(fill_alpha:, stroke_alpha:) => annotation
annotation.opacity(stroke_alpha:) => annotation
annotation.opacity(fill_alpha:) => annotation
annotation.opacity => current_values
:call-seq:
def opacity(fill_alpha: nil, stroke_alpha: nil)
  if !fill_alpha.nil? || !stroke_alpha.nil?
    self[:CA] = stroke_alpha unless stroke_alpha.nil?
    self[:ca] = fill_alpha unless fill_alpha.nil?
    self
  else
    Opacity.new(key?(:ca) ? self[:ca] : self[:CA], self[:CA])
  end
end

def perform_validation(&block) #:nodoc:

:nodoc:
def perform_validation(&block) #:nodoc:
  # Make sure empty appearance dictionaries don't cause validation errors
  if key?(:AP) && self[:AP]&.empty?
    yield("An annotation's appearance dictionary must not be empty", true)
    delete(:AP)
  end
  super
end

def regenerate_appearance

See: Annotations::AppearanceGenerator

This uses the information stored in the annotation to regenerate the appearance.

Regenerates the appearance stream of the annotation.
def regenerate_appearance
  appearance_generator_class = document.config.constantize('annotation.appearance_generator')
  appearance_generator_class.new(self).create_appearance
end