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