1 2 3 4 5 6 7 8 9 10 11 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
# frozen_string_literal: true
module TTFunk
# TrueType font collection. Usually a file with `.ttc` extension.
class Collection
include Enumerable
# Load a TrueType collection.
#
# @overload open(io)
# @param io [IO] IO to read the collection from.
# @yieldparam collection [TTFunk::Collection]
# @return [any] whatever the block returns
# @overload open(file_path)
# @param file_path [String, Pathname] Path to the font collection file.
# @yieldparam collection [TTFunk::Collection]
# @return [any] whatever the block returns
def self.open(path)
if path.respond_to?(:read)
result = yield(new(path))
path.rewind
result
else
::File.open(path, 'rb') do |io|
yield(new(io))
end
end
end
# @param io [IO(#read & #rewind)]
# @raise [ArgumentError] if `io` doesn't start with a ttc tag
def initialize(io)
tag = io.read(4)
raise ArgumentError, 'not a TTC file' unless tag == 'ttcf'
_major, _minor = io.read(4).unpack('n*')
count = io.read(4).unpack1('N')
@offsets = io.read(count * 4).unpack('N*')
io.rewind
@contents = io.read
@cache = []
end
# Number of fonts in this collection.
#
# @return [Integer]
def count
@offsets.length
end
# Iterate over fonts in the collection.
#
# @yieldparam font [TTFunk::File]
# @return [self]
def each
count.times do |index|
yield(self[index])
end
self
end
# Get font by index.
#
# @param index [Integer]
# @return [TTFunk::File]
def [](index)
@cache[index] ||= TTFunk::File.new(@contents, @offsets[index])
end
end
end
|