Skip to content

Commit

Permalink
resolves asciidoctor#2012 don't advance image that's first child of b…
Browse files Browse the repository at this point in the history
…lock at top of page if image is taller than page
  • Loading branch information
mojavelinux committed Dec 3, 2023
1 parent 32d4694 commit e291c42
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Bug Fixes::
* decouple tests from path of PWD (#2444)
* consider inherited styles when analyzing glyphs for fallback font support (#2463)
* add fallback character for placeholder character when using AFM font (#2453)
* don't advance image that's first child of block at top of page if image is taller than page (#2012)

== 2.3.9 (2023-06-28) - @mojavelinux

Expand Down
4 changes: 2 additions & 2 deletions lib/asciidoctor/pdf/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1819,7 +1819,7 @@ def convert_image node, opts = {}
end
# NOTE: shrink image so it fits within available space; group image & caption
if (rendered_h = svg_size.output_height) > (available_h = cursor - caption_h)
unless pinned || at_page_top?
unless pinned || at_page_top? || (node.first_child? && (node.parent.attr? 'pdf-at-top'))
advance_page
available_h = cursor - caption_h
end
Expand Down Expand Up @@ -1860,7 +1860,7 @@ def convert_image node, opts = {}
rendered_w, rendered_h = image_info.calc_image_dimensions width: (width || [available_w, actual_w].min)
# NOTE: shrink image so it fits within available space; group image & caption
if rendered_h > (available_h = cursor - caption_h)
unless pinned || at_page_top?
unless pinned || at_page_top? || (node.first_child? && (node.parent.attr? 'pdf-at-top'))
advance_page
available_h = cursor - caption_h
end
Expand Down
4 changes: 4 additions & 0 deletions lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ def last_child
blocks[-1]
end

def first_child?
self == parent.blocks[0]
end

def last_child?
self == parent.blocks[-1]
end
Expand Down
10 changes: 10 additions & 0 deletions lib/asciidoctor/pdf/ext/prawn/extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -990,16 +990,26 @@ def with_dry_run &block
# start_new_page. Using start_new_page can mangle the calculation of content block's extent.
#
def arrange_block node, &block
if at_page_top?
at_top = ''
else
at_top = '' if node.first_child? && (node.parent.attr? 'pdf-at-top')
keep_together = true if node.option? 'unbreakable'
end
node.set_attr 'pdf-at-top', at_top if at_top
keep_together = (node.option? 'unbreakable') && !at_page_top?
doc = node.document
block_for_scratch = proc do
node.set_attr 'pdf-at-top', (at_top = '') if at_page_top?
push_scratch doc
instance_exec(&block)
ensure
pop_scratch doc
end
extent = dry_run keep_together: keep_together, onto: [self, keep_together], &block_for_scratch
scratch? ? block_for_scratch.call : (yield extent)
ensure
node.remove_attr 'pdf-at-top' if at_top
end

# This method installs an on_page_create_callback that stops processing if the first page is
Expand Down
26 changes: 10 additions & 16 deletions spec/arrange_block_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -929,8 +929,7 @@ def content
(expect image[:y]).to eql 742.0
end

# NOTE: this scenario renders an example block that starts with an empty page
it 'should split block across pages that contains image taller than page at start of block', negative: true do
it 'should split block across pages that contains image taller than page at start of block' do
input = <<~'END'
====
image::tall-spacer.png[]
Expand All @@ -939,18 +938,16 @@ def content
pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
images = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images
pages = pdf.pages
(expect pages).to have_size 2
(expect pages).to have_size 1
page_width, page_height = (get_page_size pdf, 1).map(&:to_f)
page_margin = pdf_theme[:page_margin].to_f
(expect images).to have_size 1
image = images[0]
(expect image[:page_number]).to be 2
(expect image[:y]).to eql (page_height - page_margin)
(expect image[:height]).to eql (page_height - page_margin * 2)
(expect image[:page_number]).to be 1
(expect image[:y]).to eql (page_height - page_margin - 12)
(expect image[:height]).to eql (page_height - 12 - page_margin * 2)
p1_gs = (pdf.extract_graphic_states pages[0][:raw_content])[0]
(expect p1_gs).to have_background color: 'FFFFCC', top_left: [page_margin, page_height - page_margin], bottom_right: [page_width - page_margin, page_margin]
p2_gs = (pdf.extract_graphic_states pages[1][:raw_content])[0]
(expect p2_gs).to have_background color: 'FFFFCC', top_left: [page_margin, page_height - page_margin], bottom_right: [page_width - page_margin, page_margin]
end

it 'should split block across pages that contains image taller than page that follows text' do
Expand Down Expand Up @@ -1350,8 +1347,7 @@ def content
(expect image[:y]).to eql 711.009
end

# NOTE: this scenario renders an example block that starts with an empty page
it 'should split block across pages that contains image taller than page at start of block', negative: true do
it 'should split block across pages that contains image taller than page at start of block' do
input = <<~'END'
before block
Expand All @@ -1362,19 +1358,17 @@ def content
pdf = to_pdf input, pdf_theme: pdf_theme, analyze: true
images = (to_pdf input, pdf_theme: pdf_theme, analyze: :image).images
pages = pdf.pages
(expect pages).to have_size 3
(expect pages).to have_size 2
page_width, page_height = (get_page_size pdf, 1).map(&:to_f)
page_margin = pdf_theme[:page_margin].to_f
(expect images).to have_size 1
image = images[0]
(expect image[:page_number]).to be 3
(expect image[:y]).to eql (page_height - page_margin)
(expect image[:height]).to eql (page_height - page_margin * 2)
(expect image[:page_number]).to be 2
(expect image[:y]).to eql (page_height - page_margin - 12)
(expect image[:height]).to eql (page_height - 12 - page_margin * 2)
(expect (pdf.extract_graphic_states pages[0][:raw_content])).to be_empty
p2_gs = (pdf.extract_graphic_states pages[1][:raw_content])[0]
(expect p2_gs).to have_background color: 'FFFFCC', top_left: [page_margin, page_height - page_margin], bottom_right: [page_width - page_margin, page_margin]
p3_gs = (pdf.extract_graphic_states pages[2][:raw_content])[0]
(expect p3_gs).to have_background color: 'FFFFCC', top_left: [page_margin, page_height - page_margin], bottom_right: [page_width - page_margin, page_margin]
end

# FIXME: this fails when block is unbreakable
Expand Down

0 comments on commit e291c42

Please sign in to comment.