class TTFunk::Table::Cff::Charstring
Constants
- CODE_MAP
- FLEX_CODE_MAP
Attributes
glyph_id[R]
raw[R]
Public Class Methods
new(glyph_id, top_dict, font_dict, raw)
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 43 def initialize(glyph_id, top_dict, font_dict, raw) @glyph_id = glyph_id @top_dict = top_dict @font_dict = font_dict @raw = raw default_width_x = (@font_dict || @top_dict).private_dict.default_width_x @nominal_width_x = (@font_dict || @top_dict).private_dict.nominal_width_x @subrs = (@font_dict || @top_dict).private_dict.subr_index @gsubrs = @top_dict.cff.global_subr_index @subrs_bias = @subrs.bias if @subrs @gsubrs_bias = @gsubrs.bias if @gsubrs @stack = [] @data = raw.bytes @index = 0 @n_stems = 0 @have_width = false @open = false @width = default_width_x @x = 0 @y = 0 end
Public Instance Methods
encode()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 94 def encode raw end
glyph()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 77 def glyph @glyph ||= begin horizontal_metrics = @top_dict.file.horizontal_metrics.for(glyph_id) Glyf::PathBased.new(path, horizontal_metrics) end end
path()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 69 def path @path || begin @path = Path.new parse! @path end end
render(x: 0, y: 0, font_size: 72)
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 85 def render(x: 0, y: 0, font_size: 72) path.render( x: x, y: y, font_size: font_size, units_per_em: @top_dict.file.header.units_per_em ) end
Private Instance Methods
add_contour(x, y)
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 169 def add_contour(x, y) if @open @path.close_path end @path.move_to(x, y) @open = true end
callgsubr()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 434 def callgsubr code_index = @stack.pop + @gsubrs_bias subr_code = @gsubrs[code_index].bytes @data[@index, 0] = subr_code end
callsubr()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 222 def callsubr code_index = @stack.pop + @subrs_bias subr_code = @subrs[code_index].bytes @data[@index, 0] = subr_code end
cntrmask()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 329 def cntrmask stem # skip past hinting data, no need to worry about it since we're not # very concerned about rendering glyphs read_bytes((@n_stems + 7) >> 3) end
endchar()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 309 def endchar if !@stack.empty? && !@have_width @width = @stack.shift + @nominal_width_x @have_width = true end if @open @path.close_path @open = false end end
flex()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 234 def flex c1x = @x + @stack.shift # dx1 c1y = @y + @stack.shift # dy1 c2x = c1x + @stack.shift # dx2 c2y = c1y + @stack.shift # dy2 jpx = c2x + @stack.shift # dx3 jpy = c2y + @stack.shift # dy3 c3x = jpx + @stack.shift # dx4 c3y = jpy + @stack.shift # dy4 c4x = c3x + @stack.shift # dx5 c4y = c3y + @stack.shift # dy5 @x = c4x + @stack.shift # dx6 @y = c4y + @stack.shift # dy6 @stack.shift # flex depth @path.curve_to(c1x, c1y, c2x, c2y, jpx, jpy) @path.curve_to(c3x, c3y, c4x, c4y, @x, @y) end
flex1()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 287 def flex1 c1x = @x + @stack.shift # dx1 c1y = @y + @stack.shift # dy1 c2x = c1x + @stack.shift # dx2 c2y = c1y + @stack.shift # dy2 jpx = c2x + @stack.shift # dx3 jpy = c2y + @stack.shift # dy3 c3x = jpx + @stack.shift # dx4 c3y = jpy + @stack.shift # dy4 c4x = c3x + @stack.shift # dx5 c4y = c3y + @stack.shift # dy5 if (c4x - @x).abs > (c4y - @y).abs @x = c4x + @stack.shift else @y = c4y + @stack.shift end @path.curve_to(c1x, c1y, c2x, c2y, jpx, jpy) @path.curve_to(c3x, c3y, c4x, c4y, @x, @y) end
flex_select()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 228 def flex_select flex_code = @data[@index] @index += 1 __send__(FLEX_CODE_MAP[flex_code]) end
hflex()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 253 def hflex c1x = @x + @stack.shift # dx1 c1y = @y # dy1 c2x = c1x + @stack.shift # dx2 c2y = c1y + @stack.shift # dy2 jpx = c2x + @stack.shift # dx3 jpy = c2y # dy3 c3x = jpx + stack.shift # dx4 c3y = c2y # dy4 c4x = c3x + stack.shift # dx5 c4y = @y # dy5 @x = c4x + stack.shift # dx6 @path.curve_to(c1x, c1y, c2x, c2y, jpx, jpy) @path.curve_to(c3x, c3y, c4x, c4y, @x, @y) end
hflex1()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 270 def hflex1 c1x = @x + @stack.shift # dx1 c1y = @y + @stack.shift # dy1 c2x = c1x + @stack.shift # dx2 c2y = c1y + @stack.shift # dy2 jpx = c2x + @stack.shift # dx3 jpy = c2y # dy3 c3x = jpx + @stack.shift # dx4 c3y = c2y # dy4 c4x = c3x + @stack.shift # dx5 c4y = c3y + @stack.shift # dy5 @x = c4x + @stack.shift # dx6 @path.curve_to(c1x, c1y, c2x, c2y, jpx, jpy) @path.curve_to(c3x, c3y, c4x, c4y, @x, @y) end
hhcurveto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 412 def hhcurveto if @stack.size % 2 == 1 @y += @stack.shift end until @stack.empty? c1x = @x + @stack.shift c1y = @y c2x = c1x + @stack.shift c2y = c1y + @stack.shift @x = c2x + @stack.shift @y = c2y @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) end end
hintmask()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 325 def hintmask cntrmask end
hlineto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 186 def hlineto until @stack.empty? @x += @stack.shift @path.line_to(@x, @y) break if @stack.empty? @y += @stack.shift @path.line_to(@x, @y) end end
hmoveto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 348 def hmoveto if @stack.size > 1 && !@have_width @width = @stack.shift + @nominal_width_x @have_width = true end @x += @stack.pop add_contour(@x, @y) end
hstem()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 135 def hstem stem end
hstemhm()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 321 def hstemhm stem end
hvcurveto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 462 def hvcurveto until @stack.empty? c1x = @x + @stack.shift c1y = @y c2x = c1x + @stack.shift c2y = c1y + @stack.shift @y = c2y + @stack.shift @x = c2x + (@stack.size == 1 ? @stack.shift : 0) @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) break if @stack.empty? c1x = @x c1y = @y + @stack.shift c2x = c1x + @stack.shift c2y = c1y + @stack.shift @x = c2x + @stack.shift @y = c2y + (@stack.size == 1 ? @stack.shift : 0) @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) end end
parse!()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 100 def parse! until @index >= @data.size code = @data[@index] @index += 1 # return from callgsubr - do nothing since we inline subrs next if code == 11 if code >= 32 && code <= 246 @stack << code - 139 elsif (m = CODE_MAP[code]) __send__(m) elsif code >= 247 && code <= 250 b0 = code b1 = @data[@index] @index += 1 @stack << (b0 - 247) * 256 + b1 + 108 elsif code >= 251 && code <= 254 b0 = code b1 = @data[@index] @index += 1 @stack << -(b0 - 251) * 256 - b1 - 108 else b1, b2, b3, b4 = read_bytes(4) @stack << ((b1 << 24) | (b2 << 16) | (b3 << 8) | b4) / 65_536 end end end
rcurveline()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 362 def rcurveline while @stack.size > 2 c1x = @x + @stack.shift c1y = @y + @stack.shift c2x = c1x + @stack.shift c2y = c1y + @stack.shift @x = c2x + @stack.shift @y = c2y + @stack.shift @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) end @x += @stack.shift @y += @stack.shift @path.line_to(@x, @y) end
read_bytes(length)
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 129 def read_bytes(length) bytes = @data[@index, length] @index += length bytes end
rlinecurve()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 378 def rlinecurve while @stack.size > 6 @x += @stack.shift @y += @stack.shift @path.line_to(@x, @y) end c1x = @x + @stack.shift c1y = @y + @stack.shift c2x = c1x + @stack.shift c2y = c1y + @stack.shift @x = c2x + @stack.shift @y = c2y + @stack.shift @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) end
rlineto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 178 def rlineto until @stack.empty? @x += @stack.shift @y += @stack.shift @path.line_to(@x, @y) end end
rmoveto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 337 def rmoveto if @stack.size > 2 && !@have_width @width = @stack.shift + @nominal_width_x @have_width = true end @y += @stack.pop @x += @stack.pop add_contour(@x, @y) end
rrcurveto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 210 def rrcurveto until @stack.empty? c1x = @x + @stack.shift c1y = @y + @stack.shift c2x = c1x + @stack.shift c2y = c1y + @stack.shift @x = c2x + @stack.shift @y = c2y + @stack.shift @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) end end
shortint()
click to toggle source
rubocop:enable Style/EvenOdd
# File lib/ttfunk/table/cff/charstring.rb, line 429 def shortint b1, b2 = read_bytes(2) @stack << (((b1 << 24) | (b2 << 16)) >> 16) end
stem()
click to toggle source
rubocop:disable Style/EvenOdd
# File lib/ttfunk/table/cff/charstring.rb, line 144 def stem # The number of stem operators on the stack is always even. # If the value is uneven, that means a width is specified. has_width_arg = @stack.size % 2 == 1 if has_width_arg && !@have_width @width = @stack.shift + @nominal_width_x end @n_stems += @stack.length >> 1 @stack.clear @have_width = true end
vhcurveto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 440 def vhcurveto until @stack.empty? c1x = @x c1y = @y + @stack.shift c2x = c1x + @stack.shift c2y = c1y + @stack.shift @x = c2x + @stack.shift @y = c2y + (@stack.size == 1 ? @stack.shift : 0) @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) break if @stack.empty? c1x = @x + @stack.shift c1y = @y c2x = c1x + @stack.shift c2y = c1y + @stack.shift @y = c2y + @stack.shift @x = c2x + (@stack.size == 1 ? @stack.shift : 0) @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) end end
vlineto()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 198 def vlineto until @stack.empty? @y += @stack.shift @path.line_to(@x, @y) break if @stack.empty? @x += @stack.shift @path.line_to(@x, @y) end end
vmoveto()
click to toggle source
rubocop:enable Style/EvenOdd
# File lib/ttfunk/table/cff/charstring.rb, line 159 def vmoveto if @stack.size > 1 && !@have_width @width = @stack.shift + @nominal_width_x @have_width = true end @y += @stack.pop add_contour(@x, @y) end
vstem()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 139 def vstem stem end
vstemhm()
click to toggle source
# File lib/ttfunk/table/cff/charstring.rb, line 358 def vstemhm stem end
vvcurveto()
click to toggle source
rubocop:disable Style/EvenOdd
# File lib/ttfunk/table/cff/charstring.rb, line 396 def vvcurveto if @stack.size % 2 == 1 @x += @stack.shift end until @stack.empty? c1x = @x c1y = @y + @stack.shift c2x = c1x + @stack.shift c2y = c1y + @stack.shift @x = c2x @y = c2y + @stack.shift @path.curve_to(c1x, c1y, c2x, c2y, @x, @y) end end