This commit is contained in:
@@ -0,0 +1,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'
|
||||
Reference in New Issue
Block a user