Class: TTFunk::ResourceFile

Inherits:
Object
  • Object
show all
Defined in:
lib/ttfunk/resource_file.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io) ⇒ ResourceFile

Returns a new instance of ResourceFile.



12
13
14
15
16
17
18
19
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
# File 'lib/ttfunk/resource_file.rb', line 12

def initialize(io)
  @io = io

  data_offset, map_offset, map_length = @io.read(16).unpack("NNx4N")

  @map = {}
  @io.pos = map_offset + 24 # skip header copy, next map handle, file reference, and attrs
  type_list_offset, name_list_offset = @io.read(4).unpack("n*")

  type_list_offset += map_offset
  name_list_offset += map_offset

  @io.pos = type_list_offset
  max_index = @io.read(2).unpack("n").first
  0.upto(max_index) do
    type, max_type_index, ref_list_offset = @io.read(8).unpack("A4nn")
    @map[type] = { :list => [], :named => {} }

    parse_from(type_list_offset + ref_list_offset) do
      0.upto(max_type_index) do
        id, name_ofs, attr = @io.read(5).unpack("nnC")
        data_ofs = @io.read(3)
        data_ofs = data_offset + [0, data_ofs].pack("CA*").unpack("N").first
        handle = @io.read(4).unpack("N").first

        entry = { :id => id, :attributes => attr, :offset => data_ofs, :handle => handle }

        if name_list_offset + name_ofs < map_offset + map_length
          parse_from(name_ofs + name_list_offset) do
            len = @io.read(1).unpack("C").first
            entry[:name] = @io.read(len)
          end
        end

        @map[type][:list] << entry
        @map[type][:named][entry[:name]] = entry if entry[:name]
      end
    end
  end
end

Instance Attribute Details

#mapObject (readonly)

Returns the value of attribute map.



3
4
5
# File 'lib/ttfunk/resource_file.rb', line 3

def map
  @map
end

Class Method Details

.open(path) ⇒ Object



5
6
7
8
9
10
# File 'lib/ttfunk/resource_file.rb', line 5

def self.open(path)
  ::File.open(path, "rb") do |io|
    file = new(io)
    yield file
  end
end

Instance Method Details

#[](type, index = 0) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/ttfunk/resource_file.rb', line 53

def [](type, index=0)
  if @map[type]
    collection = index.is_a?(Fixnum) ? :list : :named
    if @map[type][collection][index]
      parse_from(@map[type][collection][index][:offset]) do
        length = @io.read(4).unpack("N").first
        return @io.read(length)
      end
    end
  end
end

#resources_for(type) ⇒ Object



65
66
67
# File 'lib/ttfunk/resource_file.rb', line 65

def resources_for(type)
  (@map[type] && @map[type][:named] || {}).keys
end