class Prawn::Text::Formatted::Arranger
D data structure for 2-stage processing of lines of formatted text. @private
Attributes
The following present only for testing purposes
Public Class Methods
Source
# File lib/prawn/text/formatted/arranger.rb, line 45 def initialize(document, options = {}) @document = document @fragments = [] @unconsumed = [] @kerning = options[:kerning] end
Public Instance Methods
Source
# File lib/prawn/text/formatted/arranger.rb, line 191 def apply_color_and_font_settings(fragment, &block) if fragment.color original_fill_color = @document.fill_color original_stroke_color = @document.stroke_color @document.fill_color(*fragment.color) @document.stroke_color(*fragment.color) apply_font_settings(fragment, &block) @document.stroke_color = original_stroke_color @document.fill_color = original_fill_color else apply_font_settings(fragment, &block) end end
Apply color and font settings.
@param fragment [Prawn::Text::Formatted::Fragment] @yield @return [void]
Source
# File lib/prawn/text/formatted/arranger.rb, line 210 def apply_font_settings(fragment = nil, &block) if fragment.nil? font = current_format_state[:font] size = current_format_state[:size] character_spacing = current_format_state[:character_spacing] || @document.character_spacing styles = current_format_state[:styles] else font = fragment.font size = fragment.size character_spacing = fragment.character_spacing styles = fragment.styles end font_style = font_style(styles) @document.character_spacing(character_spacing) do if font || font_style != :normal raise BadFontFamily unless @document.font.family @document.font( font || @document.font.family, style: font_style, ) do apply_font_size(size, styles, &block) end else apply_font_size(size, styles, &block) end end end
Apply font settings.
@param fragment [Prawn::Text::Formatted::Fragment] @yield @return [void]
Source
# File lib/prawn/text/formatted/arranger.rb, line 101 def finalize_line @finalized = true omit_trailing_whitespace_from_line_width @fragments = [] @consumed.each do |hash| text = hash[:text] format_state = hash.dup format_state.delete(:text) fragment = Prawn::Text::Formatted::Fragment.new( text, format_state, @document, ) @fragments << fragment self.fragment_measurements = fragment self.line_measurement_maximums = fragment end end
Finish laying out current line.
@return [void]
Source
# File lib/prawn/text/formatted/arranger.rb, line 151 def finished? @unconsumed.empty? end
Were all fragments processed?
@return [Boolean]
Source
# File lib/prawn/text/formatted/arranger.rb, line 295 def font_style(styles) styles = Array(styles) if styles.include?(:bold) && styles.include?(:italic) :bold_italic elsif styles.include?(:bold) :bold elsif styles.include?(:italic) :italic else :normal end end
Get font variant from fragment styles.
@param styles [Array<Symbol>] @return [Symbol]
Source
# File lib/prawn/text/formatted/arranger.rb, line 125 def format_array=(array) initialize_line @unconsumed = [] array.each do |hash| hash[:text].scan(/[^\n]+|\n/) do |line| @unconsumed << hash.merge(text: line) end end end
Set new fragment array.
@param array [Array<Hash>] @return [void]
Source
# File lib/prawn/text/formatted/arranger.rb, line 138 def initialize_line @finalized = false @max_line_height = 0 @max_descender = 0 @max_ascender = 0 @consumed = [] @fragments = [] end
Prepare for new line layout.
@return [void]
Source
# File lib/prawn/text/formatted/arranger.rb, line 84 def line unless finalized raise NotFinalized.new(method: 'line') end @fragments.map { |fragment| begin fragment.text.dup.encode(::Encoding::UTF_8) rescue ::Encoding::InvalidByteSequenceError, ::Encoding::UndefinedConversionError fragment.text.dup.force_encoding(::Encoding::UTF_8) end }.join end
Line text.
@return [String] @raise [NotFinalized]
Source
# File lib/prawn/text/formatted/arranger.rb, line 70 def line_width unless finalized raise raise NotFinalized.new(method: 'line_width') end @fragments.reduce(0) do |sum, fragment| sum + fragment.width end end
Line width.
@return [Number] @raise [NotFinalized]
Source
# File lib/prawn/text/formatted/arranger.rb, line 159 def next_string if finalized raise NotFinalized.new(method: 'next_string') end next_unconsumed_hash = @unconsumed.shift if next_unconsumed_hash @consumed << next_unconsumed_hash.dup @current_format_state = next_unconsumed_hash.dup @current_format_state.delete(:text) next_unconsumed_hash[:text] end end
Get the next unprocessed string.
@return [String, nil] @raise [NotFinalized]
Source
# File lib/prawn/text/formatted/arranger.rb, line 178 def preview_next_string next_unconsumed_hash = @unconsumed.first if next_unconsumed_hash next_unconsumed_hash[:text] end end
Get the next unprocessed string keeping it in the queue.
@return [String, nil]
Source
# File lib/prawn/text/formatted/arranger.rb, line 280 def repack_unretrieved new_unconsumed = [] # rubocop: disable Lint/AssignmentInCondition while fragment = retrieve_fragment # rubocop: enable Lint/AssignmentInCondition fragment.include_trailing_white_space! new_unconsumed << fragment.format_state.merge(text: fragment.text) end @unconsumed = new_unconsumed.concat(@unconsumed) end
Repack remaining fragments.
@return [void]
Source
# File lib/prawn/text/formatted/arranger.rb, line 269 def retrieve_fragment unless finalized raise NotFinalized, 'Lines must be finalized before fragments can be retrieved' end @fragments.shift end
Get the next fragment.
@return [Prawn::Text::Formatted::Fragment] @raise [NotFinalized]
Source
# File lib/prawn/text/formatted/arranger.rb, line 56 def space_count unless finalized raise NotFinalized.new(method: 'space_count') end @fragments.reduce(0) do |sum, fragment| sum + fragment.space_count end end
Number of spaces in the text.
@return [Integer] @raise [NotFinalized]
Source
# File lib/prawn/text/formatted/arranger.rb, line 246 def update_last_string(printed, unprinted, normalized_soft_hyphen = nil) return if printed.nil? if printed.empty? @consumed.pop else @consumed.last[:text] = printed if normalized_soft_hyphen @consumed.last[:normalized_soft_hyphen] = normalized_soft_hyphen end end unless unprinted.empty? @unconsumed.unshift(@current_format_state.merge(text: unprinted)) end load_previous_format_state if printed.empty? end
Update last fragment’s text.
@param printed [String] @param unprinted [String] @param normalized_soft_hyphen [Boolean] @return [void]