class Graph
Public Class Methods
new(e_list, metrics, symmetrize, color, leafstyle, multibyte, font, font_size)
click to toggle source
# File lib/rsyntaxtree/graph.rb, line 21 def initialize(e_list, metrics, symmetrize, color, leafstyle, multibyte, font, font_size) # Set class-specific parameters beforehand in subclass # Store parameters @e_list = e_list @m = metrics @multibyte = multibyte @leafstyle = leafstyle @symmetrize = symmetrize # Calculate image dimensions @e_height = font_size + @m[:e_padd] * 2 h = @e_list.get_level_height w = calc_level_width(0) @width = w + @m[:b_side] * 2 @height = h * @e_height + (h-1) * (@m[:v_space] + font_size) + @m[:b_topbot] * 2 # Initialize the image and colors @col_bg = "none" @col_fg = "black" @col_line = "black" if color @col_node = "blue" @col_leaf = "green" @col_trace = "red" else @col_node = "black" @col_leaf = "black" @col_trace = "black" end @main_height = img_get_txt_height("l", font, font_size) @sub_size = (font_size * SUBSCRIPT_CONST) @sub_space_width = img_get_txt_width("l", font, @sub_size) end
Public Instance Methods
calc_children_width(id)
click to toggle source
# File lib/rsyntaxtree/graph.rb, line 120 def calc_children_width(id) left = 0 right = 0 c_list = @e_list.get_children(id) return nil if c_list.empty? c_list.each do |c| left = c.indent if indent == 0 or left > c.indent end c_list.each do |c| right = c.indent + e.width if c.indent + c.width > right end return [left, right] end
calc_element_width(e)
click to toggle source
Calculate the width of the element. If the element is a node, the calculation will be performed recursively for all child elements.
# File lib/rsyntaxtree/graph.rb, line 83 def calc_element_width(e) w = 0 children = @e_list.get_children(e.id) if(children.length == 0) w = img_get_txt_width(e.content, @font, @font_size) + @font_size else children.each do |child| child_e = @e_list.get_id(child) w += calc_element_width(child_e) end tw = img_get_txt_width(e.content, @font, @font_size) + @font_size if(tw > w) fix_child_size(e.id, w, tw) w = tw end end @e_list.set_element_width(e.id, w) return w end
calc_level_width(level)
click to toggle source
Calculate the width of all elements in a certain level
# File lib/rsyntaxtree/graph.rb, line 108 def calc_level_width(level) w = 0 e = @e_list.get_first while e if(e.level == level) w += calc_element_width(e) end e = @e_list.get_next end return w end
get_children_indent(id)
click to toggle source
# File lib/rsyntaxtree/graph.rb, line 135 def get_children_indent(id) calc_children_width(id)[0] end
get_children_width(id)
click to toggle source
# File lib/rsyntaxtree/graph.rb, line 139 def get_children_width(id) calc_children_width(id)[1] - get_children_indent(id) end
get_txt_only(text)
click to toggle source
# File lib/rsyntaxtree/graph.rb, line 287 def get_txt_only(text) text = text.strip if /\A([\+\-\=\*]+).+/ =~ text prefix = $1 prefix_l = Regexp.escape(prefix) prefix_r = Regexp.escape(prefix.reverse) if /\A#{prefix_l}(.+)#{prefix_r}\z/ =~ text return $1 end end return text end
img_get_txt_height(text, font, font_size, multiline = false)
click to toggle source
# File lib/rsyntaxtree/graph.rb, line 300 def img_get_txt_height(text, font, font_size, multiline = false) metrics = img_get_txt_metrics(text, font, font_size, multiline) y = metrics.height return y end
img_get_txt_metrics(text, font, font_size, multiline)
click to toggle source
# File lib/rsyntaxtree/graph.rb, line 59 def img_get_txt_metrics(text, font, font_size, multiline) background = Image.new(500, 250) gc = Draw.new gc.annotate(background, 0, 0, 0, 0, text) do |gc| gc.font = font gc.pointsize = font_size gc.gravity = CenterGravity gc.stroke = 'none' end if multiline metrics = gc.get_multiline_type_metrics(background, text) else metrics = gc.get_type_metrics(background, text) end return metrics end
parse_list()
click to toggle source
Parse the elements in the list top to bottom and
draw the elements into the image. As we it iterate through the levels, the element indentation is calculated.
# File lib/rsyntaxtree/graph.rb, line 147 def parse_list # Calc element list recursively.... e_arr = @e_list.get_elements h = @e_list.get_level_height h.times do |i| x = 0 e_arr.each do |j| if (j.level == i) cw = @e_list.get_element_width(j.id) parent_indent = @e_list.get_indent(j.parent) if (x < parent_indent) x = parent_indent end @e_list.set_indent(j.id, x) if !@symmetrize draw_element(x, i, cw, j.content, j.type) if(j.parent != 0 ) words = j.content.split(" ") unless @leafstyle == "nothing" && ETYPE_LEAF == j.type if (@leafstyle == "triangle" && ETYPE_LEAF == j.type && x == parent_indent && words.length > 0) txt_width = img_get_txt_width(j.content, @font, @font_size) triangle_to_parent(x, i, cw, txt_width, @symmetrize) elsif (@leafstyle == "auto" && ETYPE_LEAF == j.type && x == parent_indent) if words.length > 1 || j.triangle txt_width = img_get_txt_width(j.content, @font, @font_size) triangle_to_parent(x, i, cw, txt_width, @symmetrize) else line_to_parent(x, i, cw, @e_list.get_indent(j.parent), @e_list.get_element_width(j.parent)) end else line_to_parent(x, i, cw, @e_list.get_indent(j.parent), @e_list.get_element_width(j.parent)) end end end end x += cw end end end return true if !@symmetrize h.times do |i| curlevel = h - i - 1 indent = 0 e_arr.each_with_index do |j, idx| if (j.level == curlevel) # Draw a line to the parent element children = @e_list.get_children(j.id) tw = img_get_txt_width(j.content, @font, @font_size) if children.length > 1 left, right = -1, -1 children.each do |child| k = @e_list.get_id(child) kw = img_get_txt_width(k.content, @font, @font_size) left = k.indent + kw / 2 if k.indent + kw / 2 < left or left == -1 right = k.indent + kw / 2 if k.indent + kw / 2 > right end draw_element(left, curlevel, right - left, j.content, j.type) @e_list.set_indent(j.id, left + (right - left) / 2 - tw / 2) children.each do |child| k = @e_list.get_id(child) words = k.content.split(" ") dw = img_get_txt_width(k.content, @font, @font_size) unless @leafstyle == "nothing" && ETYPE_LEAF == k.type if (@leafstyle == "triangle" && ETYPE_LEAF == k.type && k.indent == j.indent && words.length > 0) txt_width = img_get_txt_width(k.content, @font, @font_size) triangle_to_parent(k.indent, curlevel + 1, dw, txt_width) elsif (@leafstyle == "auto" && ETYPE_LEAF == k.type && k.indent == j.indent) if words.length > 1 || k.triangle txt_width = img_get_txt_width(k.content, @font, @font_size) triangle_to_parent(k.indent, curlevel + 1, dw, txt_width) else line_to_parent(k.indent, curlevel + 1, dw, j.indent, tw) end else line_to_parent(k.indent, curlevel + 1, dw, j.indent, tw) end end end else unless children.empty? k = @e_list.get_id(children[0]) kw = img_get_txt_width(k.content, @font, @font_size) left = k.indent right = k.indent + kw draw_element(left, curlevel, right - left, j.content, j.type) @e_list.set_indent(j.id, left + (right - left) / 2 - tw / 2) else parent = @e_list.get_id(j.parent) pw = img_get_txt_width(parent.content, @font, @font_size) pleft = parent.indent pright = pleft + pw left = j.indent right = left + tw if pw > tw left = pleft right = pright end draw_element(left, curlevel, right - left, j.content, j.type) @e_list.set_indent(j.id, left + (right - left) / 2 - tw / 2) end unless children.empty? k = @e_list.get_id(children[0]) words = k.content.split(" ") dw = img_get_txt_width(k.content, @font, @font_size) unless @leafstyle == "nothing" && ETYPE_LEAF == k.type if (@leafstyle == "triangle" && ETYPE_LEAF == k.type && words.length > 0) txt_width = img_get_txt_width(k.content, @font, @font_size) triangle_to_parent(k.indent, curlevel + 1, dw, txt_width) elsif (@leafstyle == "auto" && ETYPE_LEAF == k.type) if words.length > 1 || k.triangle txt_width = img_get_txt_width(k.content, @font, @font_size) triangle_to_parent(k.indent, curlevel + 1, dw, txt_width) else line_to_parent(k.indent, curlevel + 1, dw, j.indent, tw) end else line_to_parent(k.indent, curlevel + 1, dw, j.indent, tw) end end end end end end end end
row2px(row)
click to toggle source
Calculate top position from row (level)
# File lib/rsyntaxtree/graph.rb, line 283 def row2px(row) @m[:b_topbot] + @e_height * row + (@m[:v_space] + @font_size) * row end