Skip to content

Commit

Permalink
Experimental horizontal filling support
Browse files Browse the repository at this point in the history
  • Loading branch information
gettalong committed Aug 23, 2023
1 parent 7248553 commit e619567
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/hexapdf/layout/style.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,7 @@ def update(**properties)
"{type: value, value: extra_arg} : value))",
extra_args: ", extra_arg = nil"}],
[:last_line_gap, false, {valid_values: [true, false]}],
[:fill_horizontal, nil],
[:background_color, nil],
[:background_alpha, 1],
[:padding, "Quad.new(0)", {setter: "Quad.new(value)"}],
Expand Down
16 changes: 16 additions & 0 deletions lib/hexapdf/layout/text_fragment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,22 @@ def valign
:text
end

def fill_horizontal(new_width)
factor, rest = new_width.divmod(width)
items = @items * factor
rest = @items.inject(rest) do |available_width, item|
new_width = available_width - style.scaled_item_width(item)
break available_width if new_width < 0
items << item
new_width
end
# spacing needs to be correctly scaled
spacing = - (rest / (items.size - 1) / style.scaled_font_size)
items = items.each_with_object([]) {|i, result| result << i << spacing }
items.pop
dup_attributes(items)
end

# Clears all cached values.
#
# This method needs to be called if the fragment's items or attributes are changed!
Expand Down
13 changes: 13 additions & 0 deletions lib/hexapdf/layout/text_layouter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ def initialize(items, width_block)
@last_breakpoint_index = 0
@last_breakpoint_line_items_index = 0
@break_prohibited_state = false
@fill_horizontal = false

@height_calc = Line::HeightCalculator.new
@line = DummyLine.new(0, 0)
Expand Down Expand Up @@ -508,6 +509,7 @@ def add_box_item(item)
return false unless @width + item.width <= @available_width
@line_items.concat(@glue_items).push(item)
@width += item.width
@fill_horizontal ||= item.style.fill_horizontal
@glue_items.clear
true
end
Expand Down Expand Up @@ -547,6 +549,17 @@ def item_fits_on_line?(item)

# Creates a Line object from the current line items.
def create_line
if @fill_horizontal
rest_width = @available_width - @width
indices = []
@line_items.each_with_index do |item, index|
next unless item.style.fill_horizontal
indices << [index, item.style.fill_horizontal]
rest_width += item.width
end
unit_width = rest_width / indices.sum(&:last)
indices.each {|i, count| @line_items[i] = @line_items[i].fill_horizontal(unit_width * count) }
end
Line.new(@line_items)
end

Expand Down

0 comments on commit e619567

Please sign in to comment.