class HexaPDF::Document::Destinations

See: PDF2.0 s12.3.2
with or without a name.
may be named and later referenced through the name. This class allows to create destinations
Such destinations may be directly specified where needed, e.g. for link annotations, or they
location and a magnification factor. See Destination for details.
A destination describes a particular view of a PDF document, consisting of the page, the view
This class provides methods for creating and managing the destinations of a PDF file.

def [](name)

destination was registered under that name.
Returns the destination registered under the given +name+ (a String) or +nil+ if no

destinations[name] -> destination
:call-seq:
def [](name)
  destinations.find_entry(name)
end

def add(name, destination)

If the name does already exist, an error is raised.

Adds the given +destination+ under +name+ (a String) to the destinations name tree.

destinations.add(name, destination)
:call-seq:
def add(name, destination)
  destinations.add_entry(name, destination)
end

def create(type, page, **options)

+create_type+ method.
type names; PDF internal type names are also allowed) and +page+ by calling the respective
Creates a new destination array with the given +type+ (see Destination for all available

destinations.create(type, page, **options) -> dest or name
:call-seq:
def create(type, page, **options)
  send("create_#{Destination::TYPE_MAPPING.fetch(type, type)}", page, **options)
end

def create_fit_bounding_box(page, name: nil)

name tree under that name for reuse later, overwriting an existing entry if there is one.
If the argument +name+ is given, the created destination array is added to the destinations

The argument +page+ is described in detail in the Destination class description.

or, in case a name is given, the name.
Creates a new fit to bounding box destination array for the given arguments and returns it

destinations.create_fit_bounding_box(page, name: nil) -> name
destinations.create_fit_bounding_box(page) -> dest
:call-seq:
def create_fit_bounding_box(page, name: nil)
  destination = [page, Destination::REVERSE_TYPE_MAPPING.fetch(:fit_bounding_box)]
  name ? (add(name, destination); name) : destination
end

def create_fit_bounding_box_horizontal(page, name: nil, top: nil)

name tree under that name for reuse later, overwriting an existing entry if there is one.
If the argument +name+ is given, the created destination array is added to the destinations

The arguments +page and +top+ are described in detail in the Destination class description.

returns it or, in case a name is given, the name.
Creates a new fit bounding box horizontal destination array for the given arguments and

destinations.create_fit_bounding_box_horizontal(page, name: nil, top: nil) -> name
destinations.create_fit_bounding_box_horizontal(page, top: nil) -> dest
:call-seq:
def create_fit_bounding_box_horizontal(page, name: nil, top: nil)
  destination = [page, Destination::REVERSE_TYPE_MAPPING.fetch(:fit_bounding_box_horizontal), top]
  name ? (add(name, destination); name) : destination
end

def create_fit_bounding_box_vertical(page, name: nil, left: nil)

name tree under that name for reuse later, overwriting an existing entry if there is one.
If the argument +name+ is given, the created destination array is added to the destinations

The arguments +page and +left+ are described in detail in the Destination class description.

returns it or, in case a name is given, the name.
Creates a new fit bounding box vertical destination array for the given arguments and

destinations.create_fit_bounding_box_vertical(page, name: nil, left: nil) -> name
destinations.create_fit_bounding_box_vertical(page, left: nil) -> dest
:call-seq:
def create_fit_bounding_box_vertical(page, name: nil, left: nil)
  destination = [page, Destination::REVERSE_TYPE_MAPPING.fetch(:fit_bounding_box_vertical), left]
  name ? (add(name, destination); name) : destination
end

def create_fit_page(page, name: nil)

name tree under that name for reuse later, overwriting an existing entry if there is one.
If the argument +name+ is given, the created destination array is added to the destinations

The argument +page+ is described in detail in the Destination class description.

case a name is given, the name.
Creates a new fit to page destination array for the given arguments and returns it or, in

destinations.create_fit_page(page, name: nil) -> name
destinations.create_fit_page(page) -> dest
:call-seq:
def create_fit_page(page, name: nil)
  destination = [page, Destination::REVERSE_TYPE_MAPPING.fetch(:fit_page)]
  name ? (add(name, destination); name) : destination
end

def create_fit_page_horizontal(page, name: nil, top: nil)

name tree under that name for reuse later, overwriting an existing entry if there is one.
If the argument +name+ is given, the created destination array is added to the destinations

The arguments +page and +top+ are described in detail in the Destination class description.

or, in case a name is given, the name.
Creates a new fit page horizontal destination array for the given arguments and returns it

destinations.create_fit_page_horizontal(page, name: nil, top: nil) -> name
destinations.create_fit_page_horizontal(page, top: nil) -> dest
:call-seq:
def create_fit_page_horizontal(page, name: nil, top: nil)
  destination = [page, Destination::REVERSE_TYPE_MAPPING.fetch(:fit_page_horizontal), top]
  name ? (add(name, destination); name) : destination
end

def create_fit_page_vertical(page, name: nil, left: nil)

name tree under that name for reuse later, overwriting an existing entry if there is one.
If the argument +name+ is given, the created destination array is added to the destinations

The arguments +page and +left+ are described in detail in the Destination class description.

in case a name is given, the name.
Creates a new fit page vertical destination array for the given arguments and returns it or,

destinations.create_fit_page_vertical(page, name: nil, left: nil) -> name
destinations.create_fit_page_vertical(page, left: nil) -> dest
:call-seq:
def create_fit_page_vertical(page, name: nil, left: nil)
  destination = [page, Destination::REVERSE_TYPE_MAPPING.fetch(:fit_page_vertical), left]
  name ? (add(name, destination); name) : destination
end

def create_fit_rectangle(page, left:, bottom:, right:, top:, name: nil)

name tree under that name for reuse later, overwriting an existing entry if there is one.
If the argument +name+ is given, the created destination array is added to the destinations

Destination class description.
The arguments +page+, +left+, +bottom+, +right+ and +top+ are described in detail in the

in case a name is given, the name.
Creates a new fit to rectangle destination array for the given arguments and returns it or,

destinations.create_fit_rectangle(page, name: nil, left:, bottom:, right:, top:) -> name
destinations.create_fit_rectangle(page, left:, bottom:, right:, top:) -> dest
:call-seq:
def create_fit_rectangle(page, left:, bottom:, right:, top:, name: nil)
  destination = [page, Destination::REVERSE_TYPE_MAPPING.fetch(:fit_rectangle),
                 left, bottom, right, top]
  name ? (add(name, destination); name) : destination
end

def create_xyz(page, name: nil, left: nil, top: nil, zoom: nil)

name tree under that name for reuse later, overwriting an existing entry if there is one.
If the argument +name+ is given, the created destination array is added to the destinations

class description.
The arguments +page+, +left+, +top+ and +zoom+ are described in detail in the Destination

a name is given, the name.
Creates a new xyz destination array for the given arguments and returns it or, in case

destinations.create_xyz(page, name: nil, left: nil, top: nil, zoom: nil) -> name
destinations.create_xyz(page, left: nil, top: nil, zoom: nil) -> dest
:call-seq:
def create_xyz(page, name: nil, left: nil, top: nil, zoom: nil)
  destination = [page, Destination::REVERSE_TYPE_MAPPING.fetch(:xyz), left, top, zoom]
  name ? (add(name, destination); name) : destination
end

def delete(name)

returns it or +nil+ if no destination was registered under that name.
Deletes the destination specified via +name+ (a String) from the destinations name tree and

destinations.delete(name) -> destination
:call-seq:
def delete(name)
  destinations.delete_entry(name)
end

def destinations

Returns the root of the destinations name tree.
def destinations
  @document.catalog.names.destinations
end

def each

wrapped into a Destination object.
Iterates over all named destinations of the PDF, yielding the name and the destination

destinations.each -> Enumerator
destinations.each {|name, dest| block } -> destinations
:call-seq:
def each
  return to_enum(__method__) unless block_given?
  destinations.each_entry do |name, dest|
    yield(name, Destination.new(dest))
  end
  self
end

def initialize(document)

Creates a new Destinations object for the given PDF document.
def initialize(document)
  @document = document
end

def resolve(value)

* If the given value is an array, it is treated as a destination array itself.

up in the destination dictionary.
* If the given value is a symbol, it is treated as an old-style destination name and looked

destination name tree.
* If the given value is a string, it is treated as a destination name and looked up in the

+nil+.
Resolves the given value to a valid destination object, if possible, or otherwise returns

destinations.resolve(dest_array) -> destination or nil
destinations.resolve(symbol_name) -> destination or nil
destinations.resolve(string_name) -> destination or nil
:call-seq:
def resolve(value)
  result = case value
           when String
             destinations.find_entry(value)
           when PDFArray
             value.value
           when Array
             value
           when Symbol
             @document.catalog[:Dests]&.[](value)
           end
  result = Destination.new(result) if result
  result&.valid? ? result : nil
end

def use_or_create(value)

the destination type, so see the various create_XXX methods. Uses #create to do the job.
be created and the :page key the target page. Which other keys are allowed depends on
If the value is a hash, the :type key specifies the type of the destination that should

Hash containing at least :type and :page::

page (#create_fit_page) destination array is created and returned.
If the value is an integer, it is interpreted as a zero-based page index and a fit to

Integer::

destination array is created and returned.
If the value is a valid page dictionary object, a fit to page (#create_fit_page)

Page dictionary::

If a valid destination array is provided, it is returned. Otherwise an error is raised.

Array::

destination exists, the destination itself is returned. Otherwise an error is raised.
If a string is provided, it is assumed to be a named destination. If the named

String::

array based on various different types of the given arguments:
This is the main utility method for other parts of HexaPDF for getting a valid destination

arguments.
Uses the given destination name/array or creates a destination array based on the given

destinations.use_or_create(type:, page, **options) -> destination
destinations.use_or_create(page) -> destination
destinations.use_or_create(destination) -> destination
destinations.use_or_create(name) -> name
:call-seq:
def use_or_create(value)
  case value
  when String
    if self[value]
      value
    else
      raise HexaPDF::Error, "Named destination '#{value}' doesn't exist"
    end
  when Array
    raise HexaPDF::Error, "Invalid destination array" unless Destination.new(value).valid?
    value
  when HexaPDF::Dictionary
    if value.type != :Page
      raise HexaPDF::Error, "Invalid dictionary type '#{value.type}' given, needs to be a page"
    end
    create_fit_page(value)
  when Integer
    if value < 0 || value >= @document.pages.count
      raise ArgumentError, "Page index #{value} out of bounds"
    end
    create_fit_page(@document.pages[value])
  when Hash
    type = value.delete(:type) { raise ArgumentError, "Missing keyword argument :type" }
    page = value.delete(:page) { raise ArgumentError, "Missing keyword argument :page" }
    create(type, page, **value)
  else
    raise ArgumentError, "Invalid argument type '#{value.class}'"
  end
end