module Rabbit::Element::TextRenderer

Attributes

first_line_height[R]
first_line_width[R]
indent[W]
layout[R]
original_height[R]
original_width[R]
wrap_mode[W]

Public Class Methods

new(*args, &block) click to toggle source
Calls superclass method Rabbit::Element::Base::new
# File lib/rabbit/element/text-renderer.rb, line 14
def initialize(*args, &block)
  super
  text_clear_theme
end

Public Instance Methods

align=(new_value) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 23
def align=(new_value)
  if new_value.is_a?(String)
    new_value = Pango::Alignment.const_get(new_value.to_s.upcase)
  end
  dirty! if @align != new_value
  @align = new_value
end
as_large_as_possible(proc_name=nil, &compute_max_size) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 167
def as_large_as_possible(proc_name=nil, &compute_max_size)
  proc_name ||= "as-large-as-possible"
  make_params = Proc.new do |canvas, x, y, w, h,
                             initial_width, initial_height,
                             max_width, max_height|
    if (max_width and initial_width > max_width) or
        (max_height and initial_height > max_height)
      scale = 0.95
      compare = Proc.new do |_width, _height|
        (max_width.nil? or _width < max_width) and
          (max_height.nil? or _height < max_height)
      end
    else
      scale = 1.05
      compare = Proc.new do |_width, _height|
        (max_width and _width > max_width) or
          (max_height and _height > max_height)
      end
    end
    [scale, compare]
  end
  dynamic_font_size_computation(proc_name, compute_max_size, &make_params)
end
clear_theme() click to toggle source
Calls superclass method Rabbit::Element::Base#clear_theme
# File lib/rabbit/element/text-renderer.rb, line 92
def clear_theme
  super
  text_clear_theme
end
compile(canvas, x, y, w, h) click to toggle source
Calls superclass method Rabbit::Element::Base#compile
# File lib/rabbit/element/text-renderer.rb, line 58
def compile(canvas, x, y, w, h)
  super
  text_compile(canvas, x, y, w, h)
end
dirty!() click to toggle source
Calls superclass method Rabbit::Element::Base#dirty!
# File lib/rabbit/element/text-renderer.rb, line 106
def dirty!
  super
  @layout = nil
end
dirty?() click to toggle source
Calls superclass method Rabbit::Element::Base#dirty?
# File lib/rabbit/element/text-renderer.rb, line 111
def dirty?
  super or text_dirty?
end
do_horizontal_centering(canvas, x, y, w, h) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 80
def do_horizontal_centering(canvas, x, y, w, h)
  self.align = Pango::Alignment::CENTER
end
do_horizontal_centering?() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 76
def do_horizontal_centering?
  @horizontal_centering
end
font_size() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 127
def font_size
  text_props["size"]
end
have_numerical_font_size?() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 140
def have_numerical_font_size?
  font_size.is_a?(Numeric)
end
height() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 50
def height
  if @height
    @height + @padding_top + @padding_bottom
  else
    nil
  end
end
justify=(new_value) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 31
def justify=(new_value)
  new_value = true if new_value
  dirty! if @justify != new_value
  @justify = new_value
end
keep_in_size(proc_name=nil, &compute_max_size) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 144
def keep_in_size(proc_name=nil, &compute_max_size)
  proc_name ||= "keep-in-size"
  make_params = Proc.new do |canvas, x, y, w, h,
                             initial_width, initial_height,
                             max_width, max_height|
    if (max_width and initial_width > max_width) or
        (max_height and initial_height > max_height)
      scale = lambda do |_width, _height|
        candidates = [0.95]
        candidates << (max_width.to_f) / _width if max_width
        candidates << (max_height.to_f) / _height if max_height
        candidates.min
      end
      compare = Proc.new do |_width, _height|
        (max_width.nil? or _width < max_width) and
          (max_height.nil? or _height < max_height)
      end
      [scale, compare]
    end
  end
  dynamic_font_size_computation(proc_name, compute_max_size, &make_params)
end
markuped_text() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 88
def markuped_text
  markup(text)
end
pixel_font_size() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 131
def pixel_font_size
  _font_size = font_size
  if _font_size
    _font_size / Pango::SCALE
  else
    original_height
  end
end
reset_horizontal_centering(canvas, x, y, w, h) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 84
def reset_horizontal_centering(canvas, x, y, w, h)
  self.align = default_align if @align == Pango::Alignment::CENTER
end
spacing=(new_spacing) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 37
def spacing=(new_spacing)
  dirty! if @spacing != new_spacing
  @spacing = new_spacing
end
text_clear_theme() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 97
def text_clear_theme
  @layout = nil
  @indent = 0
  @spacing = 0
  @wrap_mode = default_wrap_mode
  @align = default_align
  @justify = default_justify
end
text_compile(canvas, x, y, w, h) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 63
def text_compile(canvas, x, y, w, h)
  if (@width and @width > @w) or (@height and @height > @h)
    dirty!
  end
  if_dirty do
    setup_draw_info(markuped_text, canvas, w)
  end
end
text_dirty?() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 115
def text_dirty?
  @layout.nil?
end
text_props() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 119
def text_props
  props = {}
  @prop.each do |name, formatter|
    props[name] = formatter.value
  end
  props
end
text_renderer?() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 19
def text_renderer?
  true
end
text_to_html(generator) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 72
def text_to_html(generator)
  markup_as_html(text)
end
width() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 42
def width
  if @width
    @width + @padding_left + @padding_right
  else
    nil
  end
end

Protected Instance Methods

compute_next_font_size(previous_size, scale) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 345
def compute_next_font_size(previous_size, scale)
  if previous_size
    (previous_size * scale).ceil
  else
    nil
  end
end
initial_font_size_for_compute_font_size() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 341
def initial_font_size_for_compute_font_size
  font_size
end
set_computed_font_size(new_size) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 353
def set_computed_font_size(new_size)
  if new_size
    font :size => new_size
    dirty!
  end
  dirty?
end

Private Instance Methods

compute_font_size(canvas, x, y, w, h, max_width, max_height, make_params) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 304
def compute_font_size(canvas, x, y, w, h, max_width, max_height,
                      make_params)
  compile(canvas, x, y, w, h) if dirty?
  initial_width, initial_height = @layout.pixel_size
  scale, compare = make_params.call(canvas, x, y, w, h,
                                    initial_width, initial_height,
                                    max_width, max_height)

  return if scale.nil? or compare.nil?

  if scale.respond_to?(:call)
    compute_scale = scale
    scale = nil
  end

  size = new_size = initial_font_size_for_compute_font_size
  current_layout_size = @layout.pixel_size
  unless compare.call(*@layout.pixel_size)
    loop do
      scale = compute_scale.call(*@layout.pixel_size) if compute_scale
      new_size = compute_next_font_size(size, scale)
      break if new_size == size
      set_computed_font_size(new_size)
      compile(canvas, x, y, w, h)
      break if !@wrap_mode and @layout.wrapped?
      break if compare.call(*@layout.pixel_size)
      size = new_size
    end
  end
  if scale > 1
    set_computed_font_size(size)
  else
    set_computed_font_size(new_size)
  end
end
default_align() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 248
def default_align
  Pango::Alignment::LEFT
end
default_justify() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 252
def default_justify
  false
end
default_wrap_mode() click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 244
def default_wrap_mode
  Pango::WrapMode::WORD_CHAR
end
draw_layout(canvas, x, y) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 256
def draw_layout(canvas, x, y)
  shadow_color = prop_value("shadow-color")
  if shadow_color
    shadow_foreground = Format::Foreground.new(shadow_color)
    shadow_text = markup(shadow_foreground.format(text))
    shadow_layout = canvas.make_layout(shadow_text)
    setup_layout(shadow_layout, @layout.width / Pango::SCALE)
    line_height = shadow_layout.pixel_size[1] / shadow_layout.line_count
    shadow_x = prop_value("shadow-x") || (line_height * 0.03)
    shadow_y = prop_value("shadow-y") || (line_height * 0.02)
    canvas.draw_layout(shadow_layout, x + shadow_x, y + shadow_y,
                       shadow_color)
  end

  color = prop_get("foreground")
  color = color.value if color
  canvas.draw_layout(@layout, x, y, color)
end
dynamic_font_size_computation(proc_name, compute_max_size, &make_params) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 275
def dynamic_font_size_computation(proc_name, compute_max_size,
                                  &make_params)
  return if text.empty?
  computed = false
  min_width = nil
  add_pre_draw_proc(proc_name) do |canvas, x, y, w, h, simulation|
    if simulation and !computed and have_numerical_font_size?
      max_width = max_height = nil
      if compute_max_size
        max_width, max_height = compute_max_size.call(self, canvas,
                                                      x, y, w, h)
      else
        max_width = (pw || w) - padding_left - padding_right
        max_height = (ph || h) - padding_top - padding_bottom
        max_width = nil if max_width <= 0
        max_height = nil if max_height <= 0
      end

      computed = true

      if max_width and max_height
        compute_font_size(canvas, x, y, w, h, max_width, max_height,
                          make_params)
      end
    end
    [x, y, w, h]
  end
end
markup(str) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 224
def markup(str)
  t = str
  @prop.each do |name, formatter|
    if formatter.text_formatter?
      t = formatter.format(t)
    end
  end
  t
end
markup_as_html(str) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 234
def markup_as_html(str)
  t = str
  @prop.each do |name, formatter|
    if formatter.html_formatter?
      t = formatter.html_format(t)
    end
  end
  t
end
setup_draw_info(str, canvas, w) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 192
def setup_draw_info(str, canvas, w)
  layout = canvas.make_layout(str)
  @original_width, @original_height = layout.pixel_size
  @first_line_width = @original_width / layout.line_count
  @first_line_height = @original_height / layout.line_count
  setup_layout(layout, w)
  width, height = layout.pixel_size
  if layout.width != -1 and
      (layout.alignment == Pango::Alignment::CENTER or
       layout.alignment == Pango::Alignment::RIGHT)
    width = layout.width / Pango::SCALE
  end
  @width, @height = width, height
  @layout = layout
end
setup_layout(layout, w) click to toggle source
# File lib/rabbit/element/text-renderer.rb, line 208
def setup_layout(layout, w)
  layout.set_wrap(@wrap_mode) if @wrap_mode
  layout.set_alignment(@align)
  if @wrap_mode or layout.alignment != Pango::Alignment::LEFT
    layout.set_width((w * Pango::SCALE).ceil)
  else
    layout.set_width(-1)
  end
  indent = @indent
  indent = indent.value if indent.respond_to?(:value)
  layout.set_indent(indent)
  layout.set_spacing(@spacing * Pango::SCALE)
  layout.justify = @justify
  layout.context_changed
end