diff --git a/lib/prawn/text/formatted/box.rb b/lib/prawn/text/formatted/box.rb index 16b6b3a4f..1ded7cf58 100644 --- a/lib/prawn/text/formatted/box.rb +++ b/lib/prawn/text/formatted/box.rb @@ -239,6 +239,15 @@ def render(flags = {}) end end + # Calculate the used width for the text in the box + # + def used_width + # dry run the render loop to calculate the width + render(dry_run: true) + + @max_line_width + end + # The width available at this point in the box # def available_width diff --git a/lib/prawn/text/formatted/wrap.rb b/lib/prawn/text/formatted/wrap.rb index 81b4fdac5..6910395df 100644 --- a/lib/prawn/text/formatted/wrap.rb +++ b/lib/prawn/text/formatted/wrap.rb @@ -41,12 +41,14 @@ def initialize(_array, options) # set to true until something is printed, then false # @everything_printed:: # set to false until everything printed, then true + # @max_line_width:: + # set to the maximum line width of all lines processed # # Returns any formatted text that was not printed # def wrap(array) # :nodoc: initialize_wrap(array) - + @max_line_width = 0 stop = false until stop # wrap before testing if enough height for this line because the @@ -60,6 +62,8 @@ def wrap(array) # :nodoc: disable_wrap_by_char: @disable_wrap_by_char ) + @max_line_width = [@max_line_width, @arranger.line_width].max + if enough_height_for_this_line? move_baseline_down print_line diff --git a/spec/prawn/text/formatted/box_spec.rb b/spec/prawn/text/formatted/box_spec.rb index 327a788d0..f30aed425 100644 --- a/spec/prawn/text/formatted/box_spec.rb +++ b/spec/prawn/text/formatted/box_spec.rb @@ -329,6 +329,69 @@ end end + describe 'Text::Formatted::Box#used_width' do + subject(:used_width) { text_box.used_width } + + let(:text_box) { described_class.new(array, box_options) } + let(:box_options) { base_box_options } + let(:base_box_options) { { document: pdf } } + let(:array) { [{ text: 'hello world' }] } + + context 'with basic text' do + it 'returns the max width of the text in the box' do + expect(used_width).to be_within(0.1).of(57.408) + end + end + + context 'with formatted text' do + let(:array) { [{ text: 'hello world', size: 20 }] } + + it 'returns the max width of the text in the box' do + expect(used_width).to be_within(0.1).of(95.68) + end + end + + context 'with text containing a line break' do + let(:array) { [{ text: "hello\nworld" }] } + + it 'returns the max width of the text in the box' do + expect(used_width).to be_within(0.1).of(28.728) + end + + context 'with first line being longer' do + let(:array) { [{ text: "world\nhello" }] } + + it 'returns the max width of the text in the box' do + expect(used_width).to be_within(0.1).of(28.728) + end + end + end + + context 'when the text would wrap in the box' do + let(:array) { [{text: 'hello world ' * 11}]} + + it 'returns the width of the text in the box after wrapping' do + expect(used_width).to be_within(0.1).of(604.104) + end + end + + context 'with fallback fonts and UTF-8 text' do + before do + file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf" + pdf.font_families['DejaVu Sans'] = { + normal: { file: file } + } + end + + let(:box_options) { base_box_options.merge(fallback_fonts: ['DejaVu Sans']) } + let(:array) { [{text: 'Hello ≦≧ world'}]} + + it 'returns the max width of the text in the box' do + expect(used_width).to be_within(0.1).of(82.824) + end + end + end + describe 'Text::Formatted::Box#extensions' do let(:formatted_wrap_override) do Module.new do