class Phantom::SVG::Parser::SVGWriter

SVG writer.

Public Instance Methods

write(path, object) click to toggle source

Write svg file from object to path. Return write size.

# File lib/phantom/parser/svg_writer.rb, line 13
def write(path, object)
  return 0 if path.nil? || path.empty? || object.nil?

  reset

  # Parse object.
  return 0 unless write_proc(object)

  # Add svg version.
  @root.elements['svg'].add_attribute('version', '1.1')

  # Write to file.
  File.open(path, 'w') { |file| @root.write(file, 2) }
end

Private Instance Methods

convert_id_to_unique(root_node, prefix) click to toggle source

Convert id.

# File lib/phantom/parser/svg_writer.rb, line 193
def convert_id_to_unique(root_node, prefix)
  id_array = []
  overwrite_id(root_node, prefix, id_array)
  overwrite_relative_id(root_node, prefix, id_array)
end
overwrite_id(parent_node, prefix, out_id_array) click to toggle source

Overwrite id in surfaces.

# File lib/phantom/parser/svg_writer.rb, line 200
def overwrite_id(parent_node, prefix, out_id_array)
  parent_node.elements.each do |child|
    old_id = child.attributes['id']
    unless old_id.nil?
      out_id_array << old_id
      child.add_attribute('id', "#{prefix}#{old_id}")
    end
    overwrite_id(child, prefix, out_id_array)
  end
end
overwrite_relative_id(parent_node, prefix, id_array) click to toggle source

Overwrite relative id in surfaces.

# File lib/phantom/parser/svg_writer.rb, line 212
def overwrite_relative_id(parent_node, prefix, id_array)
  parent_node.elements.each do |child|
    child.attributes.each do |_, val|
      id_array.each do |id|
        val.gsub!("##{id}", "##{prefix}#{id}")
      end
    end
    overwrite_relative_id(child, prefix, id_array)
  end
end
reset() click to toggle source

Reset SVGWriter object.

# File lib/phantom/parser/svg_writer.rb, line 31
def reset
  @root = REXML::Document.new
  @root.context[:attribute_quote] = :quote
  @root << Phantom::SVG::Parser::PhantomXMLDecl.new('1.0', 'UTF-8')
  @root << REXML::Comment.new(' Generated by phantom_svg. ')
end
skip_frame_and_no_animation?(base) click to toggle source

If base has skip frame and no animation, return true.

# File lib/phantom/parser/svg_writer.rb, line 224
def skip_frame_and_no_animation?(base)
  base.skip_first == true && base.frames.size == 2
end
write_animation(base, parent_node) click to toggle source

Write animation.

# File lib/phantom/parser/svg_writer.rb, line 121
def write_animation(base, parent_node)
  return if skip_frame_and_no_animation?(base)

  REXML::Comment.new(' Animation. ', parent_node)
  symbol = parent_node.add_element('symbol', 'id' => 'animation')

  begin_text = "0s;frame#{base.frames.length - 1}_anim.end"
  base.frames.each_with_index do |frame, i|
    next if i == 0 && base.skip_first

    write_animation_frame(frame, "frame#{i}", begin_text, symbol)

    begin_text = "frame#{i}_anim.end"
  end
end
write_animation_frame(frame, id, begin_text, parent) click to toggle source
# File lib/phantom/parser/svg_writer.rb, line 137
def write_animation_frame(frame, id, begin_text, parent)
  use = parent.add_element('use', 'xlink:href' => "##{id}",
                                  'visibility' => 'hidden')

  use.add_element('set',  'id' => "#{id}_anim",
                          'attributeName' => 'visibility',
                          'to' => 'visible',
                          'begin' => begin_text,
                          'dur' => "#{frame.duration}s")
end
write_animation_svg(base) click to toggle source

Write animation svg.

# File lib/phantom/parser/svg_writer.rb, line 58
def write_animation_svg(base)
  svg = @root.add_element('svg', 'id' => 'phantom_svg')
  defs = svg.add_element('defs')

  # Header.
  write_size(base, svg)
  svg.add_namespace('http://www.w3.org/2000/svg')
  svg.add_namespace('xlink', 'http://www.w3.org/1999/xlink')

  # Images.
  write_images(base.frames, defs)

  # Animation.
  write_animation(base, defs)

  # Show control.
  write_show_control(base, svg)
end
write_image(frame, parent_node, id = nil) click to toggle source

Write image.

# File lib/phantom/parser/svg_writer.rb, line 103
def write_image(frame, parent_node, id = nil)
  svg = parent_node.add_element('svg')
  svg.add_attribute('id', id) unless id.nil?
  write_size(frame, svg) if parent_node == @root
  write_viewbox(frame, svg)
  svg.add_attribute('preserveAspectRatio', 'none')
  write_namespaces(frame, svg)
  write_surfaces(frame.surfaces, svg)
  convert_id_to_unique(svg, "#{id}_") unless id.nil?
end
write_images(frames, parent_node) click to toggle source

Write images.

# File lib/phantom/parser/svg_writer.rb, line 115
def write_images(frames, parent_node)
  REXML::Comment.new(' Images. ', parent_node)
  frames.each_with_index { |frame, i| write_image(frame, parent_node, "frame#{i}") }
end
write_namespaces(src, dest) click to toggle source

Write namespaces from src to dest.

# File lib/phantom/parser/svg_writer.rb, line 89
def write_namespaces(src, dest)
  src.namespaces.each do |key, val|
    if key == 'xmlns' then  dest.add_namespace(val)
    else                    dest.add_namespace(key, val)
    end
  end
end
write_proc(object) click to toggle source

Write procedure.

# File lib/phantom/parser/svg_writer.rb, line 39
def write_proc(object)
  if object.is_a?(Base)
    if object.frames.size == 1    then  write_svg(object.frames[0])
    elsif object.frames.size > 1  then  write_animation_svg(object)
    else                                return false
    end
  elsif object.is_a?(Frame)       then  write_svg(object)
  else                                  return false
  end

  true
end
write_show_control(base, parent_node) click to toggle source

Write show control.

# File lib/phantom/parser/svg_writer.rb, line 149
def write_show_control(base, parent_node)
  REXML::Comment.new(' Main control. ', parent_node)

  if skip_frame_and_no_animation?(base)
    write_show_control_main_2(parent_node)
  else
    write_show_control_header(base, parent_node)
    write_show_control_main(base, parent_node)
  end
end
write_show_control_header(base, parent_node) click to toggle source

Write show control header.

# File lib/phantom/parser/svg_writer.rb, line 161
def write_show_control_header(base, parent_node)
  repeat_count = base.loops.to_i == 0 ? 'indefinite' : base.loops.to_i.to_s

  parent_node.add_element('animate',  'id' => 'controller',
                                      'begin' => '0s',
                                      'dur' => "#{base.total_duration}s",
                                      'repeatCount' => repeat_count)
end
write_show_control_main(base, parent_node) click to toggle source

Write show control main.

# File lib/phantom/parser/svg_writer.rb, line 171
def write_show_control_main(base, parent_node)
  use = parent_node.add_element('use', 'xlink:href' => '#frame0')

  use.add_element('set',  'attributeName' => 'xlink:href',
                          'to' => '#animation',
                          'begin' => 'controller.begin')

  use.add_element('set',  'attributeName' => 'xlink:href',
                          'to' => "#frame#{base.frames.length - 1}",
                          'begin' => 'controller.end')
end
write_show_control_main_2(parent_node) click to toggle source

Write show control main.

# File lib/phantom/parser/svg_writer.rb, line 184
def write_show_control_main_2(parent_node)
  use = parent_node.add_element('use', 'xlink:href' => '#frame0')

  use.add_element('set',  'attributeName' => 'xlink:href',
                          'to' => '#frame1',
                          'begin' => '0s')
end
write_size(s, d) click to toggle source

Write image size.

# File lib/phantom/parser/svg_writer.rb, line 78
def write_size(s, d)
  d.add_attribute('width', s.width.is_a?(String) ? s.width : "#{s.width.to_i}px")
  d.add_attribute('height', s.height.is_a?(String) ? s.height : "#{s.height.to_i}px")
end
write_surfaces(surfaces, dest) click to toggle source

Write surfaces to dest.

# File lib/phantom/parser/svg_writer.rb, line 98
def write_surfaces(surfaces, dest)
  surfaces.each { |surface| dest.add_element(Marshal.load(Marshal.dump(surface))) }
end
write_svg(frame) click to toggle source

Write no animation svg.

# File lib/phantom/parser/svg_writer.rb, line 53
def write_svg(frame)
  write_image(frame, @root)
end
write_viewbox(s, d) click to toggle source

Write viewbox.

# File lib/phantom/parser/svg_writer.rb, line 84
def write_viewbox(s, d)
  d.add_attribute('viewBox', s.viewbox.to_s) if s.instance_variable_defined?(:@viewbox)
end