class Krill::TextBox

Attributes

ascender[R]

The height of the ascender of the last line printed

at[R]

The upper left corner of the text box

descender[R]

The height of the descender of the last line printed

leading[R]

The leading used during printing

line_height[R]

The line height of the last line printed

printed_lines[R]
text[R]

The text that was successfully printed (or, if dry_run was used, the text that would have been successfully printed)

Public Class Methods

new(formatted_text, options={}) click to toggle source
# File lib/krill/text_box.rb, line 9
def initialize(formatted_text, options={})
  @original_array       = formatted_text
  @text                 = nil
  @at                   = [0, 720.0] # was [ @document.bounds.left, @document.bounds.top ]
  @width                = options.fetch(:width)
  @height               = options.fetch(:height, @at[1])
  @direction            = options.fetch(:direction, :ltr)
  @align                = options.fetch(:align, @direction == :rtl ? :right : :left)
  @leading              = options.fetch(:leading, 0)
  @kerning              = options.fetch(:kerning, true)
  @disable_wrap_by_char = options[:disable_wrap_by_char]
  @line_wrap            = Krill::LineWrap.new
  @arranger             = Krill::Arranger.new(kerning: @kerning)
end

Public Instance Methods

everything_printed?() click to toggle source

True if everything printed (or, if dry_run was used, everything would have been successfully printed)

# File lib/krill/text_box.rb, line 40
def everything_printed?
  @everything_printed
end
height() click to toggle source

The height actually used during the previous render

# File lib/krill/text_box.rb, line 64
def height
  return 0 if @baseline_y.nil? || @descender.nil?
  (@baseline_y - @descender).abs
end
line_gap() click to toggle source
# File lib/krill/text_box.rb, line 59
def line_gap
  line_height - (ascender + descender)
end
nothing_printed?() click to toggle source

True if nothing printed (or, if dry_run was used, nothing would have been successfully printed)

# File lib/krill/text_box.rb, line 34
def nothing_printed?
  @nothing_printed
end
render() click to toggle source
# File lib/krill/text_box.rb, line 24
def render
  wrap(normalize_encoding(original_text))
end

Private Instance Methods

available_width() click to toggle source

The width available at this point in the box

# File lib/krill/text_box.rb, line 72
def available_width
  @width
end
draw_fragment(fragment, accumulated_width=0, line_width=0, word_spacing=0) click to toggle source

fragment is a Krill::Fragment object

# File lib/krill/text_box.rb, line 77
def draw_fragment(fragment, accumulated_width=0, line_width=0, word_spacing=0)
  case @align
  when :left
    x = @at[0]
  when :center
    x = @at[0] + @width * 0.5 - line_width * 0.5
  when :right
    x = @at[0] + @width - line_width
  when :justify
    x = if @direction == :ltr
          @at[0]
        else
          @at[0] + @width - line_width
        end
  end

  x += accumulated_width

  y = @at[1] + @baseline_y

  y += fragment.y_offset

  fragment.left = x
  fragment.baseline = y
end
enough_height_for_this_line?() click to toggle source
# File lib/krill/text_box.rb, line 206
def enough_height_for_this_line?
  @line_height = @arranger.max_line_height
  @descender = @arranger.max_descender
  @ascender = @arranger.max_ascender
  diff = if @baseline_y.zero?
           @ascender + @descender
         else
           @descender + @line_height + @leading
         end
  require_relatived_total_height = @baseline_y.abs + diff
  if require_relatived_total_height > @height + 0.0001
    # no room for the full height of this line
    @arranger.repack_unretrieved
    false
  else
    true
  end
end
format_and_draw_fragment(fragment, accumulated_width, line_width, word_spacing) click to toggle source
# File lib/krill/text_box.rb, line 240
def format_and_draw_fragment(fragment, accumulated_width, line_width, word_spacing)
  draw_fragment(fragment, accumulated_width, line_width, word_spacing)
end
initialize_wrap(array) click to toggle source
# File lib/krill/text_box.rb, line 225
def initialize_wrap(array)
  @text = nil
  @arranger.format_array = array

  # these values will depend on the maximum value within a given line
  @line_height = 0
  @descender = 0
  @ascender = 0
  @baseline_y = 0

  @printed_lines = []
  @nothing_printed = true
  @everything_printed = false
end
move_baseline_down() click to toggle source
# File lib/krill/text_box.rb, line 113
def move_baseline_down
  if @baseline_y.zero?
    @baseline_y = -@ascender
  else
    @baseline_y -= (@line_height + @leading)
  end
end
normalize_encoding(text) click to toggle source
# File lib/krill/text_box.rb, line 107
def normalize_encoding(text)
  text.each do |hash|
    hash[:text] = hash.fetch(:font).normalize_encoding(hash.fetch(:text))
  end
end
original_text() click to toggle source
# File lib/krill/text_box.rb, line 103
def original_text
  @original_array.collect(&:dup)
end
print_line() click to toggle source
word_spacing_for_this_line() click to toggle source
# File lib/krill/text_box.rb, line 198
def word_spacing_for_this_line
  if @align == :justify && @line_wrap.space_count > 0 && !@line_wrap.paragraph_finished?
    (available_width - @line_wrap.width) / @line_wrap.space_count
  else
    0
  end
end
wrap(array) click to toggle source

See the developer documentation for PDF::Core::Text#wrap

Formatted#wrap should set the following variables:

<tt>@line_height</tt>::
     the height of the tallest fragment in the last printed line
<tt>@descender</tt>::
     the descender height of the tallest fragment in the last
     printed line
<tt>@ascender</tt>::
     the ascender heigth of the tallest fragment in the last
     printed line
<tt>@baseline_y</tt>::
    the baseline of the current line
<tt>@nothing_printed</tt>::
    set to true until something is printed, then false
<tt>@everything_printed</tt>::
    set to false until everything printed, then true

Returns any formatted text that was not printed

# File lib/krill/text_box.rb, line 141
def wrap(array)
  initialize_wrap(array)

  stop = false
  until stop
    # wrap before testing if enough height for this line because the
    # height of the highest fragment on this line will be used to
    # determine the line height
    @line_wrap.wrap_line(
      kerning: @kerning,
      width: available_width,
      arranger: @arranger,
      disable_wrap_by_char: @disable_wrap_by_char)

    if enough_height_for_this_line?
      move_baseline_down
      print_line
    else
      stop = true
    end

    stop ||= @arranger.finished?
  end
  @text = @printed_lines.join("\n")
  @everything_printed = @arranger.finished?
  @arranger.unconsumed
end