diff --git a/lib/rbpdf.rb b/lib/rbpdf.rb index 91c84cd1..be433d5c 100755 --- a/lib/rbpdf.rb +++ b/lib/rbpdf.rb @@ -14769,6 +14769,14 @@ def openHTMLTagHandler(dom, key, cell) else align = 'B' end + + # store original margin values + l_margin = @l_margin + r_margin = @r_margin + + SetLeftMargin(@l_margin + @c_margin) + SetRightMargin(@r_margin + @c_margin) + prevy = @y xpos = @x # eliminate marker spaces @@ -14806,8 +14814,7 @@ def openHTMLTagHandler(dom, key, cell) iw = 0 if tag['width'] # Calculate available width for percentage-based widths - available_width = @rtl ? (@x - @l_margin) : (@w - @r_margin - @x) - available_width -= 2 * @c_margin if available_width > 0 + available_width = @w - @l_margin - @r_margin iw = getHTMLUnitToUnits(tag['width'], available_width, 'px', false) end ih = 0 @@ -14817,13 +14824,6 @@ def openHTMLTagHandler(dom, key, cell) ih = getHTMLUnitToUnits(tag['height'], available_height, 'px', false) end - # store original margin values - l_margin = @l_margin - r_margin = @r_margin - - SetLeftMargin(@l_margin + @c_margin) - SetRightMargin(@r_margin + @c_margin) - result_img = proc_image_file(tag['attribute']['src']) do |img_file| Image(img_file, xpos, @y, iw, ih, '', imglink, align, false, 300, '', false, false, border, false, false, true) diff --git a/test/rbpdf_html_test.rb b/test/rbpdf_html_test.rb index de6dce19..594cd48e 100644 --- a/test/rbpdf_html_test.rb +++ b/test/rbpdf_html_test.rb @@ -1,7 +1,7 @@ # coding: ASCII-8BIT # frozen_string_literal: true # -# Copyright (c) 2011-2017 NAITOH Jun +# Copyright (c) 2011-2025 NAITOH Jun # Released under the MIT license # http://www.opensource.org/licenses/MIT @@ -636,6 +636,104 @@ def get_html_text(page) assert_equal ' 1.text A2.text B', pdf_text # A space is placed before the img tag. end + IMG_PATH = File.join(File.dirname(__FILE__), '..', 'logo_example.png') + + htmls = { + 'rtl:false, width=100%' => {html: "", percentage: 100, rtl: false}, + 'rtl:true, width=100%' => {html: "", percentage: 100, rtl: true}, + 'rtl:false, width=10%' => {html: "", percentage: 10, rtl: false}, + 'rtl:true, width=10%' => {html: "", percentage: 10, rtl: true}, + 'rtl:false, width=100% string' => {html: "test", percentage: 100, rtl: false}, + 'rtl:true, width=100% string' => {html: "test", percentage: 100, rtl: true}, + } + + data(htmls) + test "write_html_cell image style percentage width" do |data| + pdf = RBPDF.new + pdf.set_rtl(data[:rtl], true) + pdf.add_page() + + margins = pdf.get_margins + l_margin = margins['left'] + r_margin = margins['right'] + c_margin = margins['cell'] + w = pdf.get_page_width + x0 = pdf.get_x + assert_equal l_margin, x0 + + pdf.write_html(data[:html]) + no = pdf.get_num_pages + assert_equal 1, no + + width = w - l_margin - r_margin - c_margin * 2 + img_rb_x = pdf.get_image_rbx + + if data[:rtl] == false + # NOTE: rtl=false + # +- x0 -+ c_margin +- width -+ + # +----------------------------------- @w ----------------------------------------------+ + # +- @l_margin -+- @c_margin -+- available_width -+- @c_margin -+- @r_margin -+ + # | + # @img_rb_x + # +- @l_margin -+- @c_margin -+- available_width * 0.8 -+ + # | + # @img_rb_x + assert_in_delta(x0 + c_margin + width * (data[:percentage] / 100.0), img_rb_x, 0.1) + else + # NOTE: rtl=true + # +- x0 -+ c_margin +- width -+ + # +----------------------------------- @w ----------------------------------------------+ + # +- @l_margin -+- @c_margin -+- available_width -+- @c_margin -+- @r_margin -+ + # | + # @img_rb_x + # +- available_width * 0.8 -+- @c_margin -+- @r_margin -+ + # | + # @img_rb_x + assert_in_delta(w - r_margin - c_margin - width * (data[:percentage] / 100.0), img_rb_x, 0.1) + end + end + + htmls = { + 'height=100%' => {html: "", percentage: 100, pno: 1}, + 'height=10%' => {html: "", percentage: 10, pno: 1}, + 'height=100% string' => {html: "test
", percentage: 100, pno: 3}, + } + + data(htmls) + test "write_html_cell image style percentage height" do |data| + pdf = RBPDF.new + pdf.add_page('L') + + margins = pdf.get_margins + t_margin = margins['top'] + b_margin = margins['bottom'] + + w = pdf.get_page_width + h = pdf.get_page_height + + y0 = pdf.get_y + assert_equal t_margin, y0 + + pdf.write_html(data[:html], false) + no = pdf.get_num_pages + assert_equal data[:pno], no + + height = h - t_margin - b_margin + img_rb_y = pdf.get_image_rby + + # NOTE: + # + + + # | @t_margin + # | +------------------+---------------+ y0 + # | | | | + # @h available_hight height available_hight * 0.8 + # | | | +- @img_rb_y + # | +------------------+- @img_rb_y + # | @b_margin + # + + + assert_in_delta(y0 + height * (data[:percentage] / 100.0), img_rb_y, 0.1) + end + test "write_html Character Entities test" do pdf = MYPDF.new pdf.set_print_header(false) diff --git a/test/rbpdf_htmlcell_test.rb b/test/rbpdf_htmlcell_test.rb index 3625dc7b..39f232ff 100644 --- a/test/rbpdf_htmlcell_test.rb +++ b/test/rbpdf_htmlcell_test.rb @@ -77,68 +77,4 @@ class RbpdfTest < Test::Unit::TestCase no = pdf.get_num_pages assert_equal 1, no end - - test "write_html_cell with image percentage width" do - # Test that images with percentage-based width styles are actually embedded - pdf = RBPDF.new - pdf.add_page() - - # Test image path - using the logo_example.png from the repo - img_path = File.join(File.dirname(__FILE__), '..', 'logo_example.png') - - # Create PDF with image using percentage width - html_with_percentage = "

Image with percentage width:

" - pdf.write_html_cell(0, 0, '', '', html_with_percentage) - - # Check if the image was embedded - images = pdf.instance_variable_get('@images') - assert_equal 1, images.length, "Expected 1 image to be embedded in cache" - - # More importantly, check that the PDF actually contains image data - # by verifying the PDF size is much larger than an empty PDF - output = pdf.output('', 'S') - - # Create a reference PDF without any image - pdf_no_img = RBPDF.new - pdf_no_img.add_page() - pdf_no_img.write_html_cell(0, 0, '', '', '

Image with percentage width:

') - output_no_img = pdf_no_img.output('', 'S') - - # PDF with image should be significantly larger (image data embedded) - assert output.length > output_no_img.length + 10000, - "Expected PDF with image (#{output.length} bytes) to be much larger than PDF without image (#{output_no_img.length} bytes). Image may not have been embedded." - end - - test "write_html_cell with image percentage width generates output" do - pdf = RBPDF.new - pdf.add_page() - - img_path = File.join(File.dirname(__FILE__), '..', 'logo_example.png') - - # Test both plain and percentage width styles - html = <<-HTML -

Test: Image rendering with percentage width

-

Image without style (should work):

- -

Image with width=50 attribute (should work):

- -

Image with style width percentage (should work):

- -

Image with style width pixels (should work):

- - HTML - - pdf.write_html_cell(0, 0, '', '', html) - - # Generate PDF output to verify it doesn't crash - output = pdf.output('', 'S') - assert_not_nil output - assert output.length > 0 - - # Optionally write to file for manual inspection - if ENV['OUTPUT'] - File.write('test_image_percentage_width.pdf', output) - puts "Generated test_image_percentage_width.pdf for manual inspection" - end - end end diff --git a/test/rbpdf_image_rmagick_test.rb b/test/rbpdf_image_rmagick_test.rb index 97014e52..f6bbd1d7 100644 --- a/test/rbpdf_image_rmagick_test.rb +++ b/test/rbpdf_image_rmagick_test.rb @@ -1,6 +1,6 @@ # coding: ASCII-8BIT # frozen_string_literal: true -# Copyright (c) 2011-2023 NAITOH Jun +# Copyright (c) 2011-2025 NAITOH Jun # Released under the MIT license # http://www.opensource.org/licenses/MIT @@ -177,40 +177,37 @@ class RbpdfTest < Test::Unit::TestCase assert_equal "#{data[:file]} #{data[:info]}", "#{data[:file]} #{info}" end + images = { + 'png_test_alpha.png' => {file: 'png_test_alpha.png', x: 188, y: 34.8}, + 'png_test_msk_alpha.png' => {file: 'png_test_msk_alpha.png', x: 188, y: 34.8}, + 'png_test_non_alpha.png' => {file: 'png_test_non_alpha.png', x: 188, y: 34.8}, + 'webp_test_alpha.webp' => {file: 'webp_test_alpha.webp', x: 188, y: 34.8}, + 'logo_rbpdf_8bit.png' => {file: 'logo_rbpdf_8bit.png', x: 84.7, y: 31.4}, + 'logo_rbpdf_8bit.webp' => {file: 'logo_rbpdf_8bit.webp', x: 84.7, y: 31.4}, + 'logo_rbpdf_8bit.gif' => {file: 'logo_rbpdf_8bit.gif', x: 84.7, y: 31.4}, + 'logo_rbpdf_8bit_alpha.gif' => {file: 'logo_rbpdf_8bit_alpha.gif', x: 84.7, y: 31.4}, + 'logo_rbpdf_8bit.jpg' => {file: 'logo_rbpdf_8bit.jpg', x: 84.7, y: 31.4}, + 'logo_rbpdf_mono_gray.jpg' => {file: 'logo_rbpdf_mono_gray.jpg', x: 84.7, y: 31.4}, + 'logo_rbpdf_mono_gray.png' => {file: 'logo_rbpdf_mono_gray.png', x: 84.7, y: 31.4}, + 'logo_rbpdf_mono_rgb.jpg' => {file: 'logo_rbpdf_mono_rgb.jpg', x: 84.7, y: 31.4}, + 'logo_rbpdf_mono_rgb.png' => {file: 'logo_rbpdf_mono_rgb.png', x: 84.7, y: 31.4}, + } + + data(images) test "HTML Image test" do return unless Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick) - images = { - 'png_test_alpha.png' => 40.11, - 'png_test_msk_alpha.png' => 40.11, - 'png_test_non_alpha.png' => 40.11, - 'webp_test_alpha.webp' => 40.11, - 'logo_rbpdf_8bit.png' => 36.58, - 'logo_rbpdf_8bit.webp' => 36.58, - 'logo_rbpdf_8bit.gif' => 36.58, - 'logo_rbpdf_8bit_alpha.gif' => 36.58, - 'logo_rbpdf_8bit.jpg' => 36.58, - 'logo_rbpdf_mono_gray.jpg' => 36.58, - 'logo_rbpdf_mono_gray.png' => 36.58, - 'logo_rbpdf_mono_rgb.jpg' => 36.58, - 'logo_rbpdf_mono_rgb.png' => 36.58, - 'ng.png' => 9.42 - } - pdf = RBPDF.new - images.each {|image, h| - pdf.add_page - img_file = File.join(File.dirname(__FILE__), image) - htmlcontent = '' - - x_org = pdf.get_x - y_org = pdf.get_y - pdf.write_html(htmlcontent, true, 0, true, 0) - x = pdf.get_x - y = pdf.get_y - - assert_equal '[' + image + ']:' + x_org.to_s, '[' + image + ']:' + x.to_s - assert_equal '[' + image + ']:' + (y_org + h).round(2).to_s, '[' + image + ']:' + y.round(2).to_s - } + pdf.add_page + c_margin = pdf.get_margins['cell'] + + x_org = pdf.get_x + y_org = pdf.get_y + pdf.write_html("") + x = pdf.get_image_rbx + y = pdf.get_image_rby + + assert_in_delta data[:x], x - x_org - c_margin, 0.1 + assert_in_delta data[:y], y - y_org, 0.1 end end diff --git a/test/rbpdf_image_test.rb b/test/rbpdf_image_test.rb index bb1cc0b9..6522b49f 100644 --- a/test/rbpdf_image_test.rb +++ b/test/rbpdf_image_test.rb @@ -1,6 +1,6 @@ # coding: ASCII-8BIT # frozen_string_literal: true -# Copyright (c) 2011-2017 NAITOH Jun +# Copyright (c) 2011-2025 NAITOH Jun # Released under the MIT license # http://www.opensource.org/licenses/MIT @@ -183,82 +183,72 @@ class RbpdfTest < Test::Unit::TestCase end end + images = { + 'png_test_msk_alpha.png' => {file: 'png_test_msk_alpha.png', x: 188, y: 34.8}, + 'png_test_non_alpha.png' => {file: 'png_test_non_alpha.png', x: 188, y: 34.8}, + 'logo_rbpdf_8bit.png' => {file: 'logo_rbpdf_8bit.png', x: 84.7, y: 31.4}, + 'logo_rbpdf_8bit+ .png' => {file: 'logo_rbpdf_8bit+ .png', x: 84.7, y: 31.4}, + } + + data(images) test "HTML Image test without RMagick or MiniMagick" do return if Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick) - # no use - # utf8_japanese_aiueo_str = "\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a" - - images = { - 'png_test_msk_alpha.png' => 40.11, - 'png_test_non_alpha.png' => 40.11, - 'logo_rbpdf_8bit.png' => 36.58, - 'logo_rbpdf_8bit .png' => 36.58, - 'logo_rbpdf_8bit+ .png' => 36.58, - # no use - #'logo_rbpdf_8bit_' + utf8_japanese_aiueo_str + '.png' => 36.58, - 'ng.png' => 9.42 - } - - images.each {|image, h| - pdf = RBPDF.new - pdf.add_page - img_file = File.join(File.dirname(__FILE__), image) - htmlcontent = '' + pdf = RBPDF.new + pdf.add_page + c_margin = pdf.get_margins['cell'] - x_org = pdf.get_x - y_org = pdf.get_y - pdf.write_html(htmlcontent, true, 0, true, 0) - x = pdf.get_x - y = pdf.get_y + x_org = pdf.get_x + y_org = pdf.get_y + pdf.write_html("") + x = pdf.get_image_rbx + y = pdf.get_image_rby - assert_equal '[' + image + ']:' + x_org.to_s, '[' + image + ']:' + x.to_s - assert_equal '[' + image + ']:' + (y_org + h).round(2).to_s, '[' + image + ']:' + y.round(2).to_s - } + assert_in_delta data[:x], x - x_org - c_margin, 0.1 + assert_in_delta data[:y], y - y_org, 0.1 end + image_sizes = { + # writeHTML() : not !@rtl and (@x + imgw > @w - @r_margin - @c_margin) case + w10_h20_cell0_over0: {width: 10, height: 20, cell: false, over: false}, + w100_h100_cell0_over0: {width: 100, height: 100, cell: false, over: false}, + w100_h100_cell1_over0: {width: 100, height: 100, cell: true, over: false}, + w500_h100_cell0_over0: {width: 500, height: 100, cell: false, over: false}, + # writeHTML() : !@rtl and (@x + imgw > @w - @r_margin - @c_margin) case + w600_h10_cell0_over1: {width: 600, height: 10, cell: false, over: true}, + w600_h10_cell1_over1: {width: 600, height: 10, cell: true, over: true}, + w600_h13_cell0_over1: {width: 600, height: 13, cell: false, over: true}, + } + + data(image_sizes) test "HTML Image vertically align image in line test without RMagick or MiniMagick" do return if Object.const_defined?(:Magick) or Object.const_defined?(:MiniMagick) - image_sizes = [ - # writeHTML() : not !@rtl and (@x + imgw > @w - @r_margin - @c_margin) case - {'width' => 10, 'height' => 20, 'cell' => false}, - {'width' => 100, 'height' => 100, 'cell' => false}, - {'width' => 100, 'height' => 100, 'cell' => true}, - {'width' => 500, 'height' => 100, 'cell' => false}, - # writeHTML() : !@rtl and (@x + imgw > @w - @r_margin - @c_margin) case - {'width' => 600, 'height' => 10, 'cell' => false}, - {'width' => 600, 'height' => 10, 'cell' => true}, - {'width' => 600, 'height' => 13, 'cell' => false}, - ] - img_file = File.join(File.dirname(__FILE__), 'logo_rbpdf_8bit.png') - image_sizes.each {|size| - pdf = RBPDF.new - pdf.add_page - htmlcontent = "" - - x_org = pdf.get_x - y_org = pdf.get_y - - imgw = pdf.getHTMLUnitToUnits(size['width']) - imgh = pdf.getHTMLUnitToUnits(size['height']) - pdf.write_html(htmlcontent, true, 0, true, size['cell']) - x = pdf.get_x - y = pdf.get_y - w = pdf.get_page_width - r_margin = pdf.instance_variable_get("@r_margin") - lasth = pdf.get_font_size * pdf.get_cell_height_ratio - if x + imgw > w - r_margin - result = lasth * 2 - else - result = lasth + imgh - pdf.get_font_size_pt / pdf.get_scale_factor - end + pdf = RBPDF.new + pdf.add_page + htmlcontent = "" - test_name = "[ width: #{size['width']} height: #{size['height']} cell: #{size['cell']}]:" - assert_equal test_name + x_org.to_s, test_name + x.to_s - assert_equal test_name + (y_org + result).round(2).to_s, test_name + y.round(2).to_s - } + x_org = pdf.get_x + y_org = pdf.get_y + + imgw = pdf.getHTMLUnitToUnits(data[:width]) + imgh = pdf.getHTMLUnitToUnits(data[:height]) + pdf.write_html(htmlcontent, true, 0, true, data[:cell]) + x = pdf.get_image_rbx + y = pdf.get_image_rby + w = pdf.get_page_width + r_margin = pdf.get_margins['right'] + c_margin = pdf.get_margins['cell'] + + unless data[:over] == true + assert_in_delta imgw, x - (x_org + c_margin), 0.1 + assert_in_delta imgh, y - y_org, 0.1 + else + assert_in_delta w - r_margin - (x_org + c_margin), x - x_org, 0.1 + ratio_wh = imgw / imgh + assert_in_delta (w - r_margin - x_org)/ ratio_wh, y - y_org, 0.1 + end end test "HTML Image vertically align image in line and shift the annotations and links test without RMagick or MiniMagick" do