module Prawn::SVG::Pathable
Constants
- Close
- Curve
- Line
- Move
Public Instance Methods
bounding_box()
click to toggle source
# File lib/prawn/svg/pathable.rb, line 7 def bounding_box points = commands.map { |command| translate(command.destination) } x1, x2 = points.map(&:first).minmax y2, y1 = points.map(&:last).minmax [x1, y1, x2, y2] end
Protected Instance Methods
angles()
click to toggle source
# File lib/prawn/svg/pathable.rb, line 51 def angles return @angles if @angles last_point = nil destination_angles = commands.map do |command| angles = case command when Move [nil, nil] when Close, Line angle = Math.atan2(command.destination[1] - last_point[1], command.destination[0] - last_point[0]) * 180.0 / Math::PI [angle, angle] when Curve point = select_non_equal_point(last_point, command.point1, command.point2, command.destination) start = Math.atan2(point[1] - last_point[1], point[0] - last_point[0]) * 180.0 / Math::PI point = select_non_equal_point(command.destination, command.point2, command.point1, last_point) stop = Math.atan2(command.destination[1] - point[1], command.destination[0] - point[0]) * 180.0 / Math::PI [start, stop] else raise NotImplementedError, 'Unknown path command type' end last_point = command.destination angles end angles = destination_angles.each_cons(2).map do |first_angles, second_angles| if first_angles.first.nil? second_angles.first || 0 elsif second_angles.first.nil? first_angles.last else first = first_angles.last second = second_angles.last bisect = (first + second) / 2.0 if (first - second).abs > 180 bisect >= 0 ? bisect - 180 : bisect + 180 else bisect end end end if commands.last.is_a?(Close) first = destination_angles.last.last || 0 second = angles.first bisect = (first + second) / 2.0 angles << if (first - second).abs > 180 bisect >= 0 ? bisect - 180 : bisect + 180 else bisect end else angles << destination_angles.last.last end @angles = angles end
apply_commands()
click to toggle source
# File lib/prawn/svg/pathable.rb, line 17 def apply_commands commands.each do |command| case command when Move add_call 'move_to', translate(command.destination) when Close add_call 'close_path' when Line add_call 'line_to', translate(command.destination) when Curve add_call 'curve_to', translate(command.destination), bounds: [translate(command.point1), translate(command.point2)] else raise NotImplementedError, 'Unknown path command type' end end end
apply_markers()
click to toggle source
# File lib/prawn/svg/pathable.rb, line 35 def apply_markers if (marker = extract_element_from_url_id_reference(properties.marker_start, 'marker')) marker.apply_marker(self, point: commands.first.destination, angle: angles.first) end if (marker = extract_element_from_url_id_reference(properties.marker_mid, 'marker')) (1..commands.length - 2).each do |index| marker.apply_marker(self, point: commands[index].destination, angle: angles[index]) end end if (marker = extract_element_from_url_id_reference(properties.marker_end, 'marker')) marker.apply_marker(self, point: commands.last.destination, angle: angles.last) end end
parse_points(points_string)
click to toggle source
# File lib/prawn/svg/pathable.rb, line 117 def parse_points(points_string) values = points_string .to_s .strip .gsub(/(\d)-(\d)/, '\1 -\2') .split(Prawn::SVG::Elements::COMMA_WSP_REGEXP) .map(&:to_f) if values.length.odd? document.warnings << 'points attribute has an odd number of points; ignoring the last one' values.pop end raise Prawn::SVG::Elements::Base::SkipElementQuietly if values.empty? values.each_slice(2).to_a end
translate(point)
click to toggle source
# File lib/prawn/svg/pathable.rb, line 135 def translate(point) [point[0].to_f, document.sizing.output_height - point[1].to_f] end
Private Instance Methods
select_non_equal_point(base, point_a, point_b, point_c)
click to toggle source
# File lib/prawn/svg/pathable.rb, line 141 def select_non_equal_point(base, point_a, point_b, point_c) if point_a != base point_a elsif point_b != base point_b else point_c end end