class HexaPDF::Type::Resources

Represents the resources needed by a content stream.

See: PDF1.7 s7.8.3

Public Instance Methods

add_color_space(color_space) click to toggle source

Adds the color space to the resources and returns the name under which it is stored.

If there already exists a color space with the same definition, it is reused. The device color spaces :DeviceGray, :DeviceRGB and :DeviceCMYK are never stored, their respective name is just returned.

# File lib/hexapdf/type/resources.rb, line 92
def add_color_space(color_space)
  family = color_space.family
  return family if family == :DeviceRGB || family == :DeviceGray || family == :DeviceCMYK

  definition = color_space.definition
  self[:ColorSpace] = {} unless key?(:ColorSpace)
  color_space_dict = self[:ColorSpace]

  name, _value = color_space_dict.value.find do |_k, v|
    v.map! {|item| document.deref(item) }
    v == definition
  end
  unless name
    name = create_resource_name(color_space_dict.value, 'CS')
    color_space_dict[name] = definition
  end
  name
end
add_ext_gstate(object) click to toggle source

Adds the graphics state parameter dictionary to the resources and returns the name under which it is stored.

If there already exists a name for the given dictionary, it is just returned.

# File lib/hexapdf/type/resources.rb, line 137
def add_ext_gstate(object)
  object_setter(:ExtGState, 'GS', object)
end
add_font(object) click to toggle source

Adds the font dictionary to the resources and returns the name under which it is stored.

If there already exists a name for the given dictionary, it is just returned.

# File lib/hexapdf/type/resources.rb, line 151
def add_font(object)
  object_setter(:Font, 'F', object)
end
add_pattern(object) click to toggle source

Adds the pattern dictionary to the resources and returns the name under which it is stored.

If there already exists a name for the given dictionary, it is just returned.

# File lib/hexapdf/type/resources.rb, line 179
def add_pattern(object)
  object_setter(:Pattern, 'P', object)
end
add_property_list(dict) click to toggle source

Adds the property list to the resources and returns the name under which it is stored.

If there already exists a name for the given property list, it is just returned.

# File lib/hexapdf/type/resources.rb, line 165
def add_property_list(dict)
  object_setter(:Properties, 'P', dict)
end
add_xobject(object) click to toggle source

Adds the XObject to the resources and returns the name under which it is stored.

If there already exists a name for the given XObject, it is just returned.

# File lib/hexapdf/type/resources.rb, line 121
def add_xobject(object)
  object_setter(:XObject, 'XO', object)
end
color_space(name) click to toggle source

Returns the color space stored under the given name.

If the color space is not found, an error is raised.

Note: The color spaces :DeviceGray, :DeviceRGB and :DeviceCMYK are returned without a lookup since they are fixed.

# File lib/hexapdf/type/resources.rb, line 66
def color_space(name)
  case name
  when :DeviceRGB, :DeviceGray, :DeviceCMYK
    GlobalConfiguration.constantize('color_space.map', name).new
  else
    space_definition = (name == :Pattern ? name : self[:ColorSpace]&.[](name))
    if space_definition.nil?
      raise HexaPDF::Error, "Color space '#{name}' not found in the resources"
    elsif space_definition.kind_of?(Array)
      space_family = space_definition[0]
    else
      space_family = space_definition
      space_definition = [space_definition]
    end

    GlobalConfiguration.constantize('color_space.map', space_family) do
      HexaPDF::Content::ColorSpace::Universal
    end.new(space_definition)
  end
end
ext_gstate(name) click to toggle source

Returns the graphics state parameter dictionary (see Type::GraphicsStateParameter) stored under the given name.

If the dictionary is not found, an error is raised.

# File lib/hexapdf/type/resources.rb, line 129
def ext_gstate(name)
  object_getter(:ExtGState, name)
end
font(name) click to toggle source

Returns the font dictionary stored under the given name.

If the dictionary is not found, an error is raised.

# File lib/hexapdf/type/resources.rb, line 144
def font(name)
  object_getter(:Font, name)
end
pattern(name) click to toggle source

Returns the pattern dictionary stored under the given name.

If the dictionary is not found, an error is raised.

# File lib/hexapdf/type/resources.rb, line 172
def pattern(name)
  object_getter(:Pattern, name)
end
property_list(name) click to toggle source

Returns the property list stored under the given name.

If the property list is not found, an error is raised.

# File lib/hexapdf/type/resources.rb, line 158
def property_list(name)
  object_getter(:Properties, name)
end
xobject(name) click to toggle source

Returns the XObject stored under the given name.

If the XObject is not found, an error is raised.

# File lib/hexapdf/type/resources.rb, line 114
def xobject(name)
  object_getter(:XObject, name)
end

Private Instance Methods

create_resource_name(hash, prefix) click to toggle source

Returns a unique name that can be used to store a resource in the given hash.

# File lib/hexapdf/type/resources.rb, line 207
def create_resource_name(hash, prefix)
  n = hash.size + 1
  while true
    name = :"#{prefix}#{n}"
    return name unless hash.key?(name)
    n += 1
  end
end
object_getter(dict_name, name) click to toggle source

Helper method for returning an entry of a subdictionary.

# File lib/hexapdf/type/resources.rb, line 186
def object_getter(dict_name, name)
  obj = self[dict_name] && self[dict_name][name]
  if obj.nil?
    raise HexaPDF::Error, "No object called '#{name}' stored under /#{dict_name}"
  end
  obj
end
object_setter(dict_name, prefix, object) click to toggle source

Helper method for setting an entry of a subdictionary.

# File lib/hexapdf/type/resources.rb, line 195
def object_setter(dict_name, prefix, object)
  self[dict_name] = {} unless key?(dict_name)
  dict = self[dict_name]
  name, _value = dict.each.find {|_, dict_obj| dict_obj == object }
  unless name
    name = create_resource_name(dict.value, prefix)
    dict[name] = object
  end
  name
end
perform_validation() { |"No procedure set specified", true| ... } click to toggle source

Ensures that a valid procedure set is available.

Calls superclass method HexaPDF::Dictionary#perform_validation
# File lib/hexapdf/type/resources.rb, line 217
def perform_validation
  super
  val = self[:ProcSet]
  if !val
    yield("No procedure set specified", true)
    self[:ProcSet] = [:PDF, :Text, :ImageB, :ImageC, :ImageI]
  else
    if val.kind_of?(Symbol)
      yield("Procedure set is a single value instead of an Array", true)
      val = value[:ProcSet] = [val]
    end
    val.reject! do |name|
      case name
      when :PDF, :Text, :ImageB, :ImageC, :ImageI
        false
      else
        yield("Invalid page procedure set name /#{name}", true)
        true
      end
    end
  end
end