text2path 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +14 -0
  4. data/README.md +40 -0
  5. data/lib/ext/savage/LICENSE +20 -0
  6. data/lib/ext/savage/README.rdoc +108 -0
  7. data/lib/ext/savage/Rakefile +39 -0
  8. data/lib/ext/savage/VERSION +1 -0
  9. data/lib/ext/savage/lib/savage/direction.rb +42 -0
  10. data/lib/ext/savage/lib/savage/direction_proxy.rb +19 -0
  11. data/lib/ext/savage/lib/savage/directions/arc_to.rb +29 -0
  12. data/lib/ext/savage/lib/savage/directions/close_path.rb +18 -0
  13. data/lib/ext/savage/lib/savage/directions/coordinate_target.rb +17 -0
  14. data/lib/ext/savage/lib/savage/directions/cubic_curve_to.rb +40 -0
  15. data/lib/ext/savage/lib/savage/directions/horizontal_to.rb +19 -0
  16. data/lib/ext/savage/lib/savage/directions/line_to.rb +15 -0
  17. data/lib/ext/savage/lib/savage/directions/move_to.rb +15 -0
  18. data/lib/ext/savage/lib/savage/directions/point_target.rb +17 -0
  19. data/lib/ext/savage/lib/savage/directions/quadratic_curve_to.rb +44 -0
  20. data/lib/ext/savage/lib/savage/directions/vertical_to.rb +19 -0
  21. data/lib/ext/savage/lib/savage/parser.rb +108 -0
  22. data/lib/ext/savage/lib/savage/path.rb +50 -0
  23. data/lib/ext/savage/lib/savage/sub_path.rb +54 -0
  24. data/lib/ext/savage/lib/savage/transformable.rb +48 -0
  25. data/lib/ext/savage/lib/savage/utils.rb +7 -0
  26. data/lib/ext/savage/lib/savage.rb +3 -0
  27. data/lib/ext/savage/savage.gemspec +80 -0
  28. data/lib/ext/savage/spec/savage/directions/arc_to_spec.rb +97 -0
  29. data/lib/ext/savage/spec/savage/directions/close_path_spec.rb +30 -0
  30. data/lib/ext/savage/spec/savage/directions/cubic_curve_to_spec.rb +146 -0
  31. data/lib/ext/savage/spec/savage/directions/horizontal_to_spec.rb +10 -0
  32. data/lib/ext/savage/spec/savage/directions/line_to_spec.rb +10 -0
  33. data/lib/ext/savage/spec/savage/directions/move_to_spec.rb +10 -0
  34. data/lib/ext/savage/spec/savage/directions/point_spec.rb +12 -0
  35. data/lib/ext/savage/spec/savage/directions/quadratic_curve_spec.rb +123 -0
  36. data/lib/ext/savage/spec/savage/directions/vertical_to_spec.rb +10 -0
  37. data/lib/ext/savage/spec/savage/parser_spec.rb +250 -0
  38. data/lib/ext/savage/spec/savage/path_spec.rb +105 -0
  39. data/lib/ext/savage/spec/savage/sub_path_spec.rb +195 -0
  40. data/lib/ext/savage/spec/savage/transformable_spec.rb +62 -0
  41. data/lib/ext/savage/spec/savage_spec.rb +5 -0
  42. data/lib/ext/savage/spec/shared/command.rb +13 -0
  43. data/lib/ext/savage/spec/shared/coordinate_target.rb +36 -0
  44. data/lib/ext/savage/spec/shared/direction.rb +29 -0
  45. data/lib/ext/savage/spec/shared/point_target.rb +45 -0
  46. data/lib/ext/savage/spec/spec_helper.rb +36 -0
  47. data/lib/text2path/converter.rb +65 -0
  48. data/lib/text2path/glyph.rb +13 -0
  49. data/lib/text2path/svg_font.rb +92 -0
  50. data/lib/text2path/svg_path.rb +38 -0
  51. data/lib/text2path/version.rb +3 -0
  52. data/lib/text2path.rb +10 -0
  53. data/libpeerconnection.log +0 -0
  54. data/out.svg +1 -0
  55. data/test.rb +6 -0
  56. metadata +127 -0
@@ -0,0 +1,62 @@
1
+ require_relative '../spec_helper'
2
+
3
+ include Savage
4
+
5
+ describe Transformable do
6
+ it 'should apply to Path, SubPath and Direction' do
7
+ [Path, SubPath, Direction, Directions::LineTo].each do |cls|
8
+ expect(cls.ancestors).to include(Transformable)
9
+ expect(cls.public_instance_methods).to include(:transform)
10
+ end
11
+ end
12
+
13
+ describe Path do
14
+ it 'should transfrom subpaths recursively' do
15
+ path = Parser.parse('M 0 100 L 100 200 L 200 200 H 30 M 0 100 Z')
16
+ path.translate( 100, -135 )
17
+ path.subpaths.first.to_command.should == "M100-35 200 65 300 65H130"
18
+ path.subpaths[1].to_command.should == "M100-35Z"
19
+ end
20
+ end
21
+
22
+ describe SubPath do
23
+ it 'should transfrom subpaths recursively' do
24
+ path = Parser.parse('M 0 100 L 100 200 L 200 200 H 30 M 0 100 Z')
25
+ subpath = path.subpaths.first
26
+ subpath.translate( 10, 15 )
27
+ subpath.directions.first.to_command.should == "M10 115"
28
+ subpath.directions[1].to_command.should == "L110 215"
29
+ subpath.directions[2].to_command.should == "L210 215"
30
+ subpath.directions[3].to_command.should == "H40"
31
+ end
32
+ end
33
+
34
+ describe Directions::LineTo do
35
+ it 'could be translate' do
36
+ x, y = 50, 80
37
+ dir = Directions::LineTo.new(x, y)
38
+ dir.translate( 130, 601 )
39
+ dir.target.x.should == 180
40
+ dir.target.y.should == 681
41
+ end
42
+
43
+ it 'should ignore translating if relative' do
44
+ x, y = 50, 80
45
+ dir = Directions::LineTo.new(x, y, false)
46
+ dir.translate( 130, 601 )
47
+ # notice: not changed
48
+ dir.target.x.should == 50
49
+ dir.target.y.should == 80
50
+ end
51
+
52
+ it 'could be rotated' do
53
+ x, y = 50, 80
54
+ dir = Directions::LineTo.new(x, y)
55
+ dir.rotate(90)
56
+ dir.target.x.should == 80
57
+ dir.target.y.round.should == -50
58
+ end
59
+ end
60
+ end
61
+
62
+
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Savage do
4
+
5
+ end
@@ -0,0 +1,13 @@
1
+ module Command
2
+ def extract_coordinates(command_string)
3
+ coordinates = []
4
+ command_string.scan /-?\d+(\.\d+)?/ do |match_group|
5
+ coordinates << $&.to_f
6
+ end
7
+ coordinates
8
+ end
9
+
10
+ def extract_command(command_string)
11
+ command_string[0,1]
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ shared_examples 'CoordinateTarget' do
2
+ before :each do
3
+ @dir = dir_class.new(100)
4
+ end
5
+ include Command
6
+ it_behaves_like 'Direction'
7
+ it 'should have an accessible target, based on the constructor argument' do
8
+ @dir.respond_to?(:target).should == true
9
+ @dir.target.should == 100
10
+ end
11
+ it 'should be constructed with at least a target parameter' do
12
+ lambda { dir_class.new }.should raise_error
13
+ lambda { dir_class.new 45 }.should_not raise_error
14
+ lambda { dir_class.new 45, true }.should_not raise_error
15
+ end
16
+ it 'should be relative if constructed with a false third parameter' do
17
+ direction = dir_class.new(45, false)
18
+ direction.absolute?.should == false
19
+ end
20
+ it 'should be absolute if constructed with a true third parameter' do
21
+ direction = dir_class.new(45, true)
22
+ direction.absolute?.should == true
23
+ end
24
+ it 'should be absolute if constructed with only two parameters' do
25
+ direction = dir_class.new(45)
26
+ direction.absolute?.should == true
27
+ end
28
+ describe '#to_command' do
29
+ it 'should have exactly 1 numerical parameter' do
30
+ extract_coordinates(@dir.to_command).length.should == 1
31
+ end
32
+ it 'should show the provided X value as the next parameter' do
33
+ extract_coordinates(@dir.to_command)[0].should == 100
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,29 @@
1
+ shared_examples "Direction" do
2
+ include Command
3
+ it 'should have a to_command method' do
4
+ @dir.respond_to?(:to_command).should == true
5
+ end
6
+ it 'should have an absolute? method' do
7
+ @dir.respond_to?(:absolute?).should == true
8
+ end
9
+ it 'should have a command_code method' do
10
+ @dir.respond_to?(:command_code).should == true
11
+ end
12
+ describe '#to_command' do
13
+ it "should start with the command\'s command code" do
14
+ @dir.to_command[0,1].should == @dir.command_code
15
+ end
16
+ it 'should only have one alphabetical command code' do
17
+ @dir.to_command.match(/[A-Za-z]/).size.should == 1
18
+ end
19
+ end
20
+ describe '#command_code' do
21
+ it 'should start with a lower-case letter when not absolute' do
22
+ rel_dir = create_relative
23
+ rel_dir.command_code.should == command_code.downcase
24
+ end
25
+ it 'should start with a capital letter when absolute' do
26
+ @dir.command_code.should == command_code.upcase
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,45 @@
1
+ shared_examples_for 'PointTarget' do
2
+ before :each do
3
+ @dir = dir_class.new(100,200)
4
+ end
5
+ include Command
6
+ it_behaves_like 'Direction'
7
+ it 'should have a target' do
8
+ @dir.respond_to?(:target).should == true
9
+ @dir.target.class.should == Point
10
+ end
11
+ it 'should have an accessible target x, based on the constructor argument' do
12
+ @dir.target.x.should == 100
13
+ end
14
+ it 'should have an accessible target y, based on the constructor argument' do
15
+ @dir.target.y.should == 200
16
+ end
17
+ it 'should be constructed with at least an x and y parameter' do
18
+ lambda { dir_class.new }.should raise_error
19
+ lambda { dir_class.new 45 }.should raise_error
20
+ lambda { dir_class.new 45, 50 }.should_not raise_error
21
+ end
22
+ it 'should be relative if constructed with a false third parameter' do
23
+ direction = dir_class.new(45, 50, false)
24
+ direction.absolute?.should == false
25
+ end
26
+ it 'should be absolute if constructed with a true third parameter' do
27
+ direction = dir_class.new(45, 50, true)
28
+ direction.absolute?.should == true
29
+ end
30
+ it 'should be absolute if constructed with only two parameters' do
31
+ direction = dir_class.new(45, 45)
32
+ direction.absolute?.should == true
33
+ end
34
+ describe '#to_command' do
35
+ it 'should have exactly 2 numerical parameters' do
36
+ extract_coordinates(@dir.to_command).length.should == 2
37
+ end
38
+ it 'should show the provided X value as the next parameter' do
39
+ extract_coordinates(@dir.to_command)[0].should == 100
40
+ end
41
+ it 'should show the provided Y value as the final parameter' do
42
+ extract_coordinates(@dir.to_command)[1].should == 200
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'spork'
3
+
4
+ Spork.prefork do
5
+ # Loading more in this block will cause your tests to run faster. However,
6
+ # if you change any configuration or code from libraries loaded here, you'll
7
+ # need to restart spork for it take effect.
8
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
9
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'shared'))
11
+
12
+ require 'savage'
13
+ require 'rspec'
14
+ require 'rspec/autorun'
15
+ RSpec.configure do |config|
16
+
17
+ end
18
+
19
+ Dir[File.join(File.dirname(__FILE__) << '/shared', "*.rb")].each {|file| require File.basename(file) }
20
+ end
21
+
22
+ Spork.each_run do
23
+ # This code will be run each time you run your specs.
24
+
25
+ end
26
+
27
+ # --- Instructions ---
28
+ # - Sort through your spec_helper file. Place as much environment loading
29
+ # code that you don't normally modify during development in the
30
+ # Spork.prefork block.
31
+ # - Place the rest under Spork.each_run block
32
+ # - Any code that is left outside of the blocks will be ran during preforking
33
+ # and during each_run!
34
+ # - These instructions should self-destruct in 10 seconds. If they don't,
35
+ # feel free to delete them.
36
+ #
@@ -0,0 +1,65 @@
1
+ module Text2Path
2
+
3
+ class Converter
4
+
5
+ attr_accessor :text, :font
6
+
7
+ def initialize( text, font, opt={} )
8
+ @text = text
9
+ @font = font
10
+ @opt = opt
11
+ end
12
+
13
+ def to_svg
14
+ paths = to_paths
15
+ %Q{<?xml version="1.0" standalone="no"?>} <<
16
+ <<-SVG
17
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
18
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
19
+ <g>#{paths.map {|p| path_element(p) }.join("\n") }</g>
20
+ </svg>
21
+ SVG
22
+
23
+ end
24
+
25
+ def to_paths
26
+ @advance_x = 0
27
+ @text.each_char.map do |letter|
28
+ letter_to_path( letter )
29
+ end.compact
30
+ end
31
+
32
+ def letter_to_path( lt )
33
+ glyph = @font.glyph( lt )
34
+ scale = font_size / @font.units_per_em
35
+
36
+ if glyph.empty?
37
+ @advance_x += glyph.horiz_adv_x * scale
38
+ nil
39
+ else
40
+ SvgPath.parse( glyph.path ) do |path|
41
+ path.scale scale, -scale
42
+ # TODO: support other text directions
43
+ path.translate advance_x, @font.default_glyph_height * scale
44
+ @advance_x += glyph.horiz_adv_x * scale
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def path_element( path )
52
+ %Q{<path d="#{path.to_command}" />}
53
+ end
54
+
55
+ def advance_x
56
+ @advance_x
57
+ end
58
+
59
+ def font_size
60
+ @font_size ||= @opt[:font_size] || font.units_per_em
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,13 @@
1
+ module Text2Path
2
+
3
+ Glyph = Struct.new :path, :horiz_adv_x, :horiz_adv_y
4
+
5
+ class Glyph
6
+
7
+ def empty?
8
+ !path || path.empty?
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,92 @@
1
+ require 'open-uri'
2
+ require 'nokogiri'
3
+ require 'htmlentities'
4
+
5
+ $: << File.expand_path('../ext/savage/lib', File.dirname(__FILE__))
6
+
7
+ require_relative 'svg_path'
8
+ require_relative 'glyph'
9
+
10
+ module Text2Path
11
+
12
+ # An SVG font is a font defined using SVG's ‘font’ element.
13
+ # You may be instested in the specification of svg font:
14
+ # -- http://www.w3.org/TR/SVG/fonts.html
15
+ class SvgFont
16
+
17
+ class << self
18
+ alias :load :new
19
+ end
20
+
21
+ attr_reader :advance_x, :advance_y
22
+ attr_reader :units_per_em, :glyphs
23
+
24
+ def initialize( font_path )
25
+ @font_path = font_path
26
+ load_font
27
+ yield self if block_given?
28
+ end
29
+
30
+ def default_glyph_height
31
+ units_per_em
32
+ end
33
+
34
+ def glyph( letter )
35
+ key = letter.respond_to?(:ord) ? letter.ord : letter.to_i
36
+ glyphs[key] #|| missing_glyph
37
+ end
38
+
39
+ private
40
+
41
+ def load_font
42
+ @xml = Nokogiri::XML( open( @font_path ) )
43
+ parse_font_face_info
44
+ parse_glyphs
45
+ end
46
+
47
+ def parse_font_face_info
48
+ font_element = @xml.css('font').first
49
+ face_element = @xml.css('font-face').first
50
+ %w[
51
+ horiz-origin-x horiz-adv-x
52
+ horiz-origin-y horiz-adv-y
53
+ ].each do |attr|
54
+ instance_variable_set "@#{attr.gsub('-', '_')}", font_element.attr(attr).to_f
55
+ end
56
+
57
+ %w[
58
+ units-per-em
59
+ panose-1
60
+ ].each do |attr|
61
+ instance_variable_set "@#{attr.gsub('-', '_')}", face_element.attr(attr).to_f
62
+ end
63
+
64
+ end
65
+
66
+ def parse_glyphs
67
+ decoder = HTMLEntities.new
68
+ @glyphs = @xml.css('glyph').inject({}) do |map, glyph|
69
+ name = glyph.attr('unicode')
70
+ key = case name
71
+ when /^&#x(\w+)$/
72
+ $1.hex
73
+ when /^.$/
74
+ name.ord
75
+ when /^&.+;$/
76
+ # e.g.
77
+ # &amp; &quot; ..
78
+ decoder.decode( name )[0].ord
79
+ else
80
+ raise "unknown name: #{name}"
81
+ end
82
+
83
+ adv_x = glyph.attr('horiz-adv-x') || @horiz_adv_x
84
+ map[key] = Glyph.new( glyph.attr('d'), adv_x.to_f )
85
+ map
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -0,0 +1,38 @@
1
+ require 'savage'
2
+
3
+ module Text2Path
4
+
5
+ # specification:
6
+ # http://www.w3.org/TR/SVG/paths.html#PathElement
7
+ #
8
+ # Attributes:
9
+ # d
10
+ # transform (not implemented)
11
+ # pathLength (not implemented)
12
+ #
13
+ class SvgPath < Savage::Path
14
+
15
+ class << self
16
+ def parse( str )
17
+ Savage::Parser.parse( str ).tap do |p|
18
+ yield p if block_given?
19
+ end
20
+ end
21
+ end
22
+
23
+ def advance( dx=0, dy=0 )
24
+ subpaths.each do |p|
25
+ #p.move_to dx, dy
26
+ p.directions.each do |dir|
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ module Savage
35
+ class Direction
36
+ attr_accessor :absolute
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module Text2Path
2
+ VERSION = '0.0.1'
3
+ end
data/lib/text2path.rb ADDED
@@ -0,0 +1,10 @@
1
+ require_relative 'text2path/svg_font'
2
+ require_relative 'text2path/converter'
3
+
4
+ module Text2Path
5
+
6
+ def self.convert( text, font, opt={} )
7
+ Converter.new( text, font, opt )
8
+ end
9
+
10
+ end
File without changes
data/out.svg ADDED
@@ -0,0 +1 @@
1
+ [#<Savage::Path:0x00000002c95bb0 @subpaths=[#<Savage::SubPath:0x00000002c95700 @directions=[#<Savage::Directions::MoveTo:0x00000002c7baf8 @target=#<struct Savage::Directions::Point x=24.609375, y=48.046875>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c7ab30 @target=25.390625, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c794b0 @control=#<struct Savage::Directions::Point x=29.1015625, y=48.2421875>, @target=#<struct Savage::Directions::Point x=29.1015625, y=44.140625>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c77d18 @target=35.3515625, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c770e8 @target=12.5, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c76378 @target=44.3359375, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c751a8 @control=#<struct Savage::Directions::Point x=12.3046875, y=48.2421875>, @target=#<struct Savage::Directions::Point x=16.40625, y=48.046875>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c74398 @target=17.1875, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c73790 @target=50.0, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c72b88 @target=1.171875, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c71ff8 @target=48.046875, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c711c0 @target=1.953125, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c70180 @control=#<struct Savage::Directions::Point x=5.6640625, y=48.2421875>, @target=#<struct Savage::Directions::Point x=5.6640625, y=44.3359375>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c43338 @target=24.4140625, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c42348 @control=#<struct Savage::Directions::Point x=5.6640625, y=20.8984375>, @target=#<struct Savage::Directions::Point x=1.953125, y=20.8984375>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c41560 @target=1.171875, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c40868 @target=18.9453125, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c3fb98 @target=17.1875, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c3eea0 @target=20.8984375, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c3e310 @target=16.40625, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c3d118 @control=#<struct Savage::Directions::Point x=12.3046875, y=20.8984375>, @target=#<struct Savage::Directions::Point x=12.5, y=24.4140625>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c3c380 @target=32.421875, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c376f0 @target=29.1015625, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c36ac0 @target=24.609375, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c35940 @control=#<struct Savage::Directions::Point x=29.1015625, y=20.8984375>, @target=#<struct Savage::Directions::Point x=25.0, y=20.8984375>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c34ab8 @target=24.609375, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c5fb00 @target=18.9453125, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c5e7f0 @target=40.625, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c5db48 @target=20.8984375, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c5d030 @target=39.6484375, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c27ea8 @control=#<struct Savage::Directions::Point x=35.7421875, y=20.8984375>, @target=#<struct Savage::Directions::Point x=35.9375, y=24.4140625>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c27228 @target=44.3359375, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c254a0 @control=#<struct Savage::Directions::Point x=35.7421875, y=48.2421875>, @target=#<struct Savage::Directions::Point x=39.84375, y=48.046875>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c23830 @target=40.625, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c22c28 @target=50.0, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c22070 @target=24.609375, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c213f0 @target=48.046875, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002c20c98 @absolute=true>]>]>, #<Savage::Path:0x00000002c1fdc0 @subpaths=[#<Savage::SubPath:0x00000002c1f820 @directions=[#<Savage::Directions::MoveTo:0x00000002c1eb00 @target=#<struct Savage::Directions::Point x=62.3046875, y=43.1640625>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002c1dc00 @target=#<struct Savage::Directions::Point x=63.4765625, y=44.140625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c1c968 @control=#<struct Savage::Directions::Point x=59.1796875, y=50.0>, @target=#<struct Savage::Directions::Point x=52.9296875, y=50.1953125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c1b658 @control=#<struct Savage::Directions::Point x=44.140625, y=50.0>, @target=#<struct Savage::Directions::Point x=43.75, y=40.234375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c1a3c0 @control=#<struct Savage::Directions::Point x=44.3359375, y=29.8828125>, @target=#<struct Savage::Directions::Point x=54.4921875, y=29.1015625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c191a0 @control=#<struct Savage::Directions::Point x=58.203125, y=29.1015625>, @target=#<struct Savage::Directions::Point x=60.7421875, y=31.4453125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c13e58 @control=#<struct Savage::Directions::Point x=62.3046875, y=33.203125>, @target=#<struct Savage::Directions::Point x=62.890625, y=35.9375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c12cb0 @control=#<struct Savage::Directions::Point x=63.0859375, y=37.6953125>, @target=#<struct Savage::Directions::Point x=64.0625, y=38.0859375>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c11f18 @target=39.453125, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c11360 @target=50.1953125, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c10370 @control=#<struct Savage::Directions::Point x=51.171875, y=46.2890625>, @target=#<struct Savage::Directions::Point x=56.25, y=46.875>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c0eef8 @control=#<struct Savage::Directions::Point x=58.7890625, y=47.0703125>, @target=#<struct Savage::Directions::Point x=62.3046875, y=43.1640625>, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002c0e610 @absolute=true>]>, #<Savage::SubPath:0x00000002c0e3e0 @directions=[#<Savage::Directions::MoveTo:0x00000002c0d3a0 @target=#<struct Savage::Directions::Point x=50.0, y=37.6953125>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002c0c540 @target=57.03125, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c0b258 @control=#<struct Savage::Directions::Point x=56.8359375, y=31.8359375>, @target=#<struct Savage::Directions::Point x=53.515625, y=31.4453125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c09ed0 @control=#<struct Savage::Directions::Point x=49.609375, y=32.2265625>, @target=#<struct Savage::Directions::Point x=50.0, y=37.6953125>, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002c094a8 @absolute=true>]>]>, #<Savage::Path:0x00000002c080f8 @subpaths=[#<Savage::SubPath:0x00000002c07bf8 @directions=[#<Savage::Directions::MoveTo:0x00000002c06f00 @target=#<struct Savage::Directions::Point x=75.1953125, y=16.6015625>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c060c8 @target=44.921875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002c04ed0 @control=#<struct Savage::Directions::Point x=75.0, y=48.6328125>, @target=#<struct Savage::Directions::Point x=78.125, y=48.4375>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002c04098 @target=50.0, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002bff318 @target=65.8203125, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002bfe788 @target=48.4375, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002bfdb80 @target=66.2109375, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bfca78 @control=#<struct Savage::Directions::Point x=69.140625, y=48.6328125>, @target=#<struct Savage::Directions::Point x=69.140625, y=44.921875>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002bfbd58 @target=24.21875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bfad68 @control=#<struct Savage::Directions::Point x=69.3359375, y=21.484375>, @target=#<struct Savage::Directions::Point x=67.7734375, y=21.2890625>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002bf9e18 @target=#<struct Savage::Directions::Point x=65.625, y=20.5078125>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002bf91c0 @target=19.140625, @absolute=true>, #<Savage::Directions::LineTo:0x00000002bf84c8 @target=#<struct Savage::Directions::Point x=74.21875, y=16.6015625>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002bf77f8 @target=75.1953125, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002bf7168 @absolute=true>]>]>, #<Savage::Path:0x00000002bf67b8 @subpaths=[#<Savage::SubPath:0x00000002bf6380 @directions=[#<Savage::Directions::MoveTo:0x00000002bf5570 @target=#<struct Savage::Directions::Point x=88.671875, y=16.6015625>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002bf4850 @target=44.921875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bef5d0 @control=#<struct Savage::Directions::Point x=88.4765625, y=48.6328125>, @target=#<struct Savage::Directions::Point x=91.6015625, y=48.4375>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002bee6a8 @target=50.0, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002bed2d0 @target=79.296875, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002bec768 @target=48.4375, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002bd7a20 @target=79.6875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bd6800 @control=#<struct Savage::Directions::Point x=82.6171875, y=48.6328125>, @target=#<struct Savage::Directions::Point x=82.6171875, y=44.921875>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002bd5450 @target=24.21875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bd3f88 @control=#<struct Savage::Directions::Point x=82.8125, y=21.484375>, @target=#<struct Savage::Directions::Point x=81.25, y=21.2890625>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002bd2e30 @target=#<struct Savage::Directions::Point x=79.1015625, y=20.5078125>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002bd20c0 @target=19.140625, @absolute=true>, #<Savage::Directions::LineTo:0x00000002bd0fe0 @target=#<struct Savage::Directions::Point x=87.6953125, y=16.6015625>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002bd0360 @target=88.671875, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002bcfaf0 @absolute=true>]>]>, #<Savage::Path:0x00000002bcec40 @subpaths=[#<Savage::SubPath:0x00000002bce7e0 @directions=[#<Savage::Directions::MoveTo:0x00000002bcd750 @target=#<struct Savage::Directions::Point x=94.53125, y=40.0390625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bcc3f0 @control=#<struct Savage::Directions::Point x=95.3125, y=30.078125>, @target=#<struct Savage::Directions::Point x=107.03125, y=29.1015625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bba150 @control=#<struct Savage::Directions::Point x=118.1640625, y=29.8828125>, @target=#<struct Savage::Directions::Point x=118.9453125, y=39.453125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bb8d28 @control=#<struct Savage::Directions::Point x=117.96875, y=49.609375>, @target=#<struct Savage::Directions::Point x=106.25, y=50.1953125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bb79a0 @control=#<struct Savage::Directions::Point x=95.1171875, y=50.0>, @target=#<struct Savage::Directions::Point x=94.53125, y=40.0390625>, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002bb6ff0 @absolute=true>]>, #<Savage::SubPath:0x00000002bb6fa0 @directions=[#<Savage::Directions::MoveTo:0x00000002bb5f38 @target=#<struct Savage::Directions::Point x=101.171875, y=37.109375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bb4d40 @control=#<struct Savage::Directions::Point x=101.7578125, y=48.046875>, @target=#<struct Savage::Directions::Point x=107.8125, y=48.4375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002baf778 @control=#<struct Savage::Directions::Point x=112.109375, y=48.2421875>, @target=#<struct Savage::Directions::Point x=112.3046875, y=42.1875>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002bae2b0 @control=#<struct Savage::Directions::Point x=111.71875, y=32.03125>, @target=#<struct Savage::Directions::Point x=105.859375, y=31.25>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002baced8 @control=#<struct Savage::Directions::Point x=101.171875, y=31.4453125>, @target=#<struct Savage::Directions::Point x=101.171875, y=37.109375>, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002bac528 @absolute=true>]>]>, #<Savage::Path:0x00000002b7b2c0 @subpaths=[#<Savage::SubPath:0x00000002b7ae10 @directions=[#<Savage::Directions::MoveTo:0x00000002b7a0c8 @target=#<struct Savage::Directions::Point x=125.1953125, y=56.8359375>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b786b0 @target=#<struct Savage::Directions::Point x=124.8046875, y=54.8828125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b6da58 @control=#<struct Savage::Directions::Point x=129.8828125, y=53.90625>, @target=#<struct Savage::Directions::Point x=130.2734375, y=50.5859375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b56150 @control=#<struct Savage::Directions::Point x=130.2734375, y=50.0>, @target=#<struct Savage::Directions::Point x=128.7109375, y=50.0>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b4eb30 @control=#<struct Savage::Directions::Point x=128.125, y=50.0>, @target=#<struct Savage::Directions::Point x=127.9296875, y=50.0>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b49ec8 @control=#<struct Savage::Directions::Point x=124.0234375, y=50.0>, @target=#<struct Savage::Directions::Point x=124.0234375, y=47.0703125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b3b968 @control=#<struct Savage::Directions::Point x=124.21875, y=43.9453125>, @target=#<struct Savage::Directions::Point x=127.9296875, y=43.75>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b39eb0 @control=#<struct Savage::Directions::Point x=133.0078125, y=44.140625>, @target=#<struct Savage::Directions::Point x=133.3984375, y=49.609375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b383f8 @control=#<struct Savage::Directions::Point x=132.6171875, y=56.4453125>, @target=#<struct Savage::Directions::Point x=125.1953125, y=56.8359375>, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002b378e0 @absolute=true>]>]>, #<Savage::Path:0x00000002b36490 @subpaths=[#<Savage::SubPath:0x00000002b35f68 @directions=[#<Savage::Directions::MoveTo:0x00000002b34be0 @target=#<struct Savage::Directions::Point x=164.0625, y=50.0>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b33650 @target=#<struct Savage::Directions::Point x=157.2265625, y=34.1796875>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b31ee0 @control=#<struct Savage::Directions::Point x=155.859375, y=31.25>, @target=#<struct Savage::Directions::Point x=153.3203125, y=31.25>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002b30ab8 @target=29.6875, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002b2f7a8 @target=165.234375, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002b2e650 @target=31.25, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b2ceb8 @control=#<struct Savage::Directions::Point x=162.5, y=31.4453125>, @target=#<struct Savage::Directions::Point x=163.671875, y=33.7890625>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b2b900 @target=#<struct Savage::Directions::Point x=167.578125, y=43.359375>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b2a640 @target=#<struct Savage::Directions::Point x=171.484375, y=34.375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b28e30 @control=#<struct Savage::Directions::Point x=170.5078125, y=31.0546875>, @target=#<struct Savage::Directions::Point x=168.359375, y=31.25>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002b27a80 @target=29.6875, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002b26a18 @target=179.6875, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002b25870 @target=31.25, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b24178 @control=#<struct Savage::Directions::Point x=176.5625, y=31.25>, @target=#<struct Savage::Directions::Point x=177.9296875, y=34.1796875>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b22c10 @target=#<struct Savage::Directions::Point x=181.640625, y=43.359375>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b218d8 @target=#<struct Savage::Directions::Point x=185.15625, y=34.765625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b20190 @control=#<struct Savage::Directions::Point x=186.328125, y=31.4453125>, @target=#<struct Savage::Directions::Point x=182.8125, y=31.25>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002b1af60 @target=29.6875, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002b19e30 @target=191.9921875, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002b18c10 @target=31.25, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b172e8 @control=#<struct Savage::Directions::Point x=188.671875, y=31.25>, @target=#<struct Savage::Directions::Point x=187.5, y=35.546875>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b15ce0 @target=#<struct Savage::Directions::Point x=181.0546875, y=50.0>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002b14b88 @target=178.3203125, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b137d8 @target=#<struct Savage::Directions::Point x=172.8515625, y=37.3046875>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002b12298 @target=#<struct Savage::Directions::Point x=166.796875, y=50.0>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002b10fb0 @target=164.0625, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002b105b0 @absolute=true>]>]>, #<Savage::Path:0x00000002b0ed28 @subpaths=[#<Savage::SubPath:0x00000002b0e6e8 @directions=[#<Savage::Directions::MoveTo:0x00000002b0d360 @target=#<struct Savage::Directions::Point x=194.140625, y=40.0390625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b07898 @control=#<struct Savage::Directions::Point x=194.921875, y=30.078125>, @target=#<struct Savage::Directions::Point x=206.640625, y=29.1015625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b05d18 @control=#<struct Savage::Directions::Point x=217.7734375, y=29.8828125>, @target=#<struct Savage::Directions::Point x=218.5546875, y=39.453125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b04080 @control=#<struct Savage::Directions::Point x=217.578125, y=49.609375>, @target=#<struct Savage::Directions::Point x=205.859375, y=50.1953125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002b02668 @control=#<struct Savage::Directions::Point x=194.7265625, y=50.0>, @target=#<struct Savage::Directions::Point x=194.140625, y=40.0390625>, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002b01948 @absolute=true>]>, #<Savage::SubPath:0x00000002b01880 @directions=[#<Savage::Directions::MoveTo:0x00000002afbb10 @target=#<struct Savage::Directions::Point x=200.78125, y=37.109375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002af9d60 @control=#<struct Savage::Directions::Point x=201.3671875, y=48.046875>, @target=#<struct Savage::Directions::Point x=207.421875, y=48.4375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002af8370 @control=#<struct Savage::Directions::Point x=211.71875, y=48.2421875>, @target=#<struct Savage::Directions::Point x=211.9140625, y=42.1875>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002aedfb0 @control=#<struct Savage::Directions::Point x=211.328125, y=32.03125>, @target=#<struct Savage::Directions::Point x=205.46875, y=31.25>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002adffa0 @control=#<struct Savage::Directions::Point x=200.78125, y=31.4453125>, @target=#<struct Savage::Directions::Point x=200.78125, y=37.109375>, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002adf280 @absolute=true>]>]>, #<Savage::Path:0x00000002addb60 @subpaths=[#<Savage::SubPath:0x00000002adcf58 @directions=[#<Savage::Directions::MoveTo:0x00000002ad36d8 @target=#<struct Savage::Directions::Point x=235.546875, y=48.4375>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002ad1b30 @target=50.0, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002ac7f90 @target=221.6796875, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002ac5fb0 @target=48.4375, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002ac4f48 @target=221.875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002ab34a0 @control=#<struct Savage::Directions::Point x=224.8046875, y=48.6328125>, @target=#<struct Savage::Directions::Point x=224.8046875, y=44.921875>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002ab2190 @target=36.71875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002aabde0 @control=#<struct Savage::Directions::Point x=224.8046875, y=33.984375>, @target=#<struct Savage::Directions::Point x=223.046875, y=33.3984375>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002aaa850 @target=#<struct Savage::Directions::Point x=221.6796875, y=32.8125>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002aa9568 @target=31.640625, @absolute=true>, #<Savage::Directions::LineTo:0x00000002aa8230 @target=#<struct Savage::Directions::Point x=229.8828125, y=28.515625>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002aa6cc8 @target=230.859375, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002aa5cd8 @target=34.1796875, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002aa4a68 @target=231.0546875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002a96f80 @control=#<struct Savage::Directions::Point x=233.3984375, y=28.7109375>, @target=#<struct Savage::Directions::Point x=235.3515625, y=29.1015625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002a94bb8 @control=#<struct Savage::Directions::Point x=235.9375, y=29.1015625>, @target=#<struct Savage::Directions::Point x=236.328125, y=29.296875>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002a8f7a8 @target=#<struct Savage::Directions::Point x=240.234375, y=30.6640625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002a8cf08 @control=#<struct Savage::Directions::Point x=239.2578125, y=33.984375>, @target=#<struct Savage::Directions::Point x=237.890625, y=35.9375>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002a7f308 @control=#<struct Savage::Directions::Point x=234.765625, y=34.9609375>, @target=#<struct Savage::Directions::Point x=233.7890625, y=34.765625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002a7d8f0 @control=#<struct Savage::Directions::Point x=232.421875, y=34.765625>, @target=#<struct Savage::Directions::Point x=230.859375, y=36.9140625>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002a7c1a8 @target=45.1171875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002a72090 @control=#<struct Savage::Directions::Point x=230.6640625, y=48.6328125>, @target=#<struct Savage::Directions::Point x=234.1796875, y=48.4375>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002a67de8 @target=235.546875, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002a67348 @absolute=true>]>]>, #<Savage::Path:0x00000002a652f0 @subpaths=[#<Savage::SubPath:0x00000002a64dc8 @directions=[#<Savage::Directions::MoveTo:0x00000002a57470 @target=#<struct Savage::Directions::Point x=250.0, y=16.6015625>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002a55968 @target=44.921875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002a4f5e0 @control=#<struct Savage::Directions::Point x=249.8046875, y=48.6328125>, @target=#<struct Savage::Directions::Point x=252.9296875, y=48.4375>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002a4e168 @target=50.0, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002a4ce80 @target=240.625, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002a37b98 @target=48.4375, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002a36950 @target=241.015625, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x0000000230fed8 @control=#<struct Savage::Directions::Point x=243.9453125, y=48.6328125>, @target=#<struct Savage::Directions::Point x=243.9453125, y=44.921875>, @absolute=true>, #<Savage::Directions::VerticalTo:0x0000000230d200 @target=24.21875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x0000000290ad38 @control=#<struct Savage::Directions::Point x=244.140625, y=21.484375>, @target=#<struct Savage::Directions::Point x=242.578125, y=21.2890625>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002907bb0 @target=#<struct Savage::Directions::Point x=240.4296875, y=20.5078125>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002905298 @target=19.140625, @absolute=true>, #<Savage::Directions::LineTo:0x000000028fb310 @target=#<struct Savage::Directions::Point x=249.0234375, y=16.6015625>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x000000028f8fe8 @target=250.0, @absolute=true>, #<Savage::Directions::ClosePath:0x000000028ef380 @absolute=true>]>]>, #<Savage::Path:0x000000028ed4e0 @subpaths=[#<Savage::SubPath:0x000000028ec630 @directions=[#<Savage::Directions::MoveTo:0x000000028e4de0 @target=#<struct Savage::Directions::Point x=272.0703125, y=50.1953125>, @absolute=true>, #<Savage::Directions::VerticalTo:0x000000028de6c0 @target=46.484375, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000028ce090 @control=#<struct Savage::Directions::Point x=267.578125, y=50.1953125>, @target=#<struct Savage::Directions::Point x=263.8671875, y=50.1953125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000028b7458 @control=#<struct Savage::Directions::Point x=256.25, y=50.0>, @target=#<struct Savage::Directions::Point x=255.859375, y=41.015625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000028aca58 @control=#<struct Savage::Directions::Point x=256.640625, y=29.6875>, @target=#<struct Savage::Directions::Point x=267.578125, y=29.1015625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000028a0dc0 @control=#<struct Savage::Directions::Point x=269.7265625, y=29.1015625>, @target=#<struct Savage::Directions::Point x=272.0703125, y=29.6875>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002898238 @target=23.2421875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002879bf8 @control=#<struct Savage::Directions::Point x=272.0703125, y=20.8984375>, @target=#<struct Savage::Directions::Point x=268.75, y=20.3125>, @absolute=true>, #<Savage::Directions::VerticalTo:0x000000028721c8 @target=19.140625, @absolute=true>, #<Savage::Directions::LineTo:0x00000002869f28 @target=#<struct Savage::Directions::Point x=276.3671875, y=16.6015625>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x000000028681f0 @target=278.125, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002849b38 @target=43.359375, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x0000000283d770 @control=#<struct Savage::Directions::Point x=277.9296875, y=47.4609375>, @target=#<struct Savage::Directions::Point x=280.078125, y=47.0703125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002829130 @control=#<struct Savage::Directions::Point x=280.6640625, y=47.265625>, @target=#<struct Savage::Directions::Point x=281.640625, y=46.875>, @absolute=true>, #<Savage::Directions::VerticalTo:0x000000028213b8 @target=48.4375, @absolute=true>, #<Savage::Directions::LineTo:0x0000000281df88 @target=#<struct Savage::Directions::Point x=273.2421875, y=50.1953125>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x000000028193e8 @target=272.0703125, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002818560 @absolute=true>]>, #<Savage::SubPath:0x000000028184e8 @directions=[#<Savage::Directions::MoveTo:0x00000002814ed8 @target=#<struct Savage::Directions::Point x=272.0703125, y=44.3359375>, @absolute=true>, #<Savage::Directions::VerticalTo:0x00000002805af0 @target=33.203125, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000028028f0 @control=#<struct Savage::Directions::Point x=269.3359375, y=31.0546875>, @target=#<struct Savage::Directions::Point x=267.1875, y=31.0546875>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000027fdd50 @control=#<struct Savage::Directions::Point x=261.9140625, y=31.4453125>, @target=#<struct Savage::Directions::Point x=261.9140625, y=38.4765625>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000027ea340 @control=#<struct Savage::Directions::Point x=262.109375, y=46.484375>, @target=#<struct Savage::Directions::Point x=267.578125, y=46.875>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000027e52c8 @control=#<struct Savage::Directions::Point x=269.7265625, y=46.875>, @target=#<struct Savage::Directions::Point x=272.0703125, y=44.3359375>, @absolute=true>, #<Savage::Directions::ClosePath:0x000000027d9b30 @absolute=true>]>]>, #<Savage::Path:0x000000027c6968 @subpaths=[#<Savage::SubPath:0x000000027c62d8 @directions=[#<Savage::Directions::MoveTo:0x000000027be8a8 @target=#<struct Savage::Directions::Point x=290.0390625, y=43.75>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000027b2968 @control=#<struct Savage::Directions::Point x=293.75, y=44.140625>, @target=#<struct Savage::Directions::Point x=294.140625, y=47.0703125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x000000027a45c0 @control=#<struct Savage::Directions::Point x=293.75, y=50.0>, @target=#<struct Savage::Directions::Point x=290.0390625, y=50.1953125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x0000000278b340 @control=#<struct Savage::Directions::Point x=286.1328125, y=50.0>, @target=#<struct Savage::Directions::Point x=285.9375, y=47.0703125>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002783cd0 @control=#<struct Savage::Directions::Point x=286.1328125, y=44.140625>, @target=#<struct Savage::Directions::Point x=290.0390625, y=43.75>, @absolute=true>, #<Savage::Directions::ClosePath:0x00000002781e80 @absolute=true>]>, #<Savage::SubPath:0x00000002781e08 @directions=[#<Savage::Directions::MoveTo:0x0000000277cf70 @target=#<struct Savage::Directions::Point x=290.8203125, y=38.8671875>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x00000002779e60 @target=289.2578125, @absolute=true>, #<Savage::Directions::LineTo:0x000000027760a8 @target=#<struct Savage::Directions::Point x=286.328125, y=20.1171875>, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x0000000276e2e0 @control=#<struct Savage::Directions::Point x=285.7421875, y=17.96875>, @target=#<struct Savage::Directions::Point x=287.6953125, y=18.1640625>, @absolute=true>, #<Savage::Directions::HorizontalTo:0x0000000276a988 @target=292.1875, @absolute=true>, #<Savage::Directions::QuadraticCurveTo:0x00000002765c80 @control=#<struct Savage::Directions::Point x=294.3359375, y=17.96875>, @target=#<struct Savage::Directions::Point x=293.75, y=20.1171875>, @absolute=true>, #<Savage::Directions::LineTo:0x00000002760938 @target=#<struct Savage::Directions::Point x=290.8203125, y=38.8671875>, @absolute=true>, #<Savage::Directions::ClosePath:0x0000000275f3a8 @absolute=true>]>]>]
data/test.rb ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative 'lib/text2path'
4
+
5
+ font = Text2Path::SvgFont.load( 'assets/fonts/fz_dabiaosong.svg' )
6
+ p Text2Path.convert( "Hello, world!", font, font_size: 50 ).to_paths