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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
# 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'
|