158 lines
4.2 KiB
Ruby
158 lines
4.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative '../table'
|
|
|
|
module TTFunk
|
|
class Table
|
|
# PostScript (`post`) table.
|
|
#
|
|
# This class can be extended with version-specific modules.
|
|
#
|
|
# @see TTFunk::Table::Post::Format10
|
|
# @see TTFunk::Table::Post::Format20
|
|
# @see TTFunk::Table::Post::Format30
|
|
# @see TTFunk::Table::Post::Format40
|
|
class Post < Table
|
|
# Table version.
|
|
# @return [Integer]
|
|
attr_reader :format
|
|
|
|
# Italic angle in counter-clockwise degrees from the vertical.
|
|
# @return [Integer]
|
|
attr_reader :italic_angle
|
|
|
|
# Suggested distance of the top of the underline from the baseline
|
|
# @return [Integer]
|
|
attr_reader :underline_position
|
|
|
|
# Suggested values for the underline thickness.
|
|
# @return [Integer]
|
|
attr_reader :underline_thickness
|
|
|
|
# 0 if the font is proportionally spaced, non-zero if the font is not
|
|
# proportionally spaced.
|
|
# @return [Integer]
|
|
attr_reader :fixed_pitch
|
|
|
|
# Minimum memory usage when an OpenType font is downloaded.
|
|
# @return [Integer]
|
|
attr_reader :min_mem_type42
|
|
|
|
# Maximum memory usage when an OpenType font is downloaded.
|
|
# @return [Integer]
|
|
attr_reader :max_mem_type42
|
|
|
|
# Minimum memory usage when an OpenType font is downloaded as
|
|
# a Type 1 font.
|
|
# @return [Integer]
|
|
attr_reader :min_mem_type1
|
|
|
|
# Maximum memory usage when an OpenType font is downloaded as
|
|
# a Type 1 font.
|
|
# @return [Integer]
|
|
attr_reader :max_mem_type1
|
|
|
|
# Version-specific fields.
|
|
# @return [TTFunk::Table::Post::Format10, TTFunk::Table::Post::Format20,
|
|
# TTFunk::Table::Post::Format30, TTFunk::Table::Post::Format40]
|
|
attr_reader :subtable
|
|
|
|
# Encode table.
|
|
#
|
|
# @param post [TTFunk::Table::Post]
|
|
# @param mapping [Hash{Integer => Integer}] keys are new glyph IDs, values
|
|
# are old glyph IDs
|
|
# @return [String, nil]
|
|
def self.encode(post, mapping)
|
|
return if post.nil?
|
|
|
|
post.recode(mapping)
|
|
end
|
|
|
|
# Is this font monospaced?
|
|
#
|
|
# @return [Boolean]
|
|
def fixed_pitch?
|
|
@fixed_pitch != 0
|
|
end
|
|
|
|
# Get glyph name for character code.
|
|
#
|
|
# This is a placeholder.
|
|
#
|
|
# @param _code [Integer]
|
|
# @return [String]
|
|
def glyph_for(_code)
|
|
'.notdef'
|
|
end
|
|
|
|
# Re-encode this table.
|
|
#
|
|
# @param mapping [Hash{Integer => Integer}] keys are new glyph IDs, values
|
|
# are old glyph IDs
|
|
# @return [String]
|
|
def recode(mapping)
|
|
return raw if format == 0x00030000
|
|
|
|
table = raw[0, 32]
|
|
table[0, 4] = [0x00020000].pack('N')
|
|
|
|
index = []
|
|
strings = []
|
|
|
|
mapping.keys.sort.each do |new_id|
|
|
post_glyph = glyph_for(mapping[new_id])
|
|
position = Format10::POSTSCRIPT_GLYPHS.index(post_glyph)
|
|
if position
|
|
index << position
|
|
else
|
|
index << (257 + strings.length)
|
|
strings << post_glyph
|
|
end
|
|
end
|
|
|
|
table << [mapping.length, *index].pack('n*')
|
|
strings.each do |string|
|
|
table << [string.length, string].pack('CA*')
|
|
end
|
|
|
|
table
|
|
end
|
|
|
|
private
|
|
|
|
def parse!
|
|
@format, @italic_angle, @underline_position, @underline_thickness,
|
|
@fixed_pitch, @min_mem_type42, @max_mem_type42,
|
|
@min_mem_type1, @max_mem_type1 = read(32, 'N2n2N*')
|
|
|
|
@subtable =
|
|
case @format
|
|
when 0x00010000
|
|
extend(Post::Format10)
|
|
when 0x00020000
|
|
extend(Post::Format20)
|
|
when 0x00025000
|
|
raise NotImplementedError,
|
|
'Post format 2.5 is not supported by TTFunk'
|
|
when 0x00030000
|
|
extend(Post::Format30)
|
|
when 0x00040000
|
|
extend(Post::Format40)
|
|
end
|
|
|
|
parse_format!
|
|
end
|
|
|
|
def parse_format!
|
|
warn(Kernel.format('postscript table format 0x%08X is not supported', @format))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
require_relative 'post/format10'
|
|
require_relative 'post/format20'
|
|
require_relative 'post/format30'
|
|
require_relative 'post/format40'
|