diff --git a/Gemfile b/Gemfile index d65e2a66..8a54fa54 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,7 @@ source 'http://rubygems.org' gemspec + +group :example do + gem 'pdf-inspector' +end diff --git a/lib/thinreports/core.rb b/lib/thinreports/core.rb index bb07d767..b5b34c72 100644 --- a/lib/thinreports/core.rb +++ b/lib/thinreports/core.rb @@ -1,17 +1,16 @@ # coding: utf-8 module ThinReports - + ROOTDIR = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')) - + module Core end - + end require 'thinreports/core/ext' require 'thinreports/core/utils' -require 'thinreports/core/ordered_hash' require 'thinreports/core/errors' require 'thinreports/core/events' diff --git a/lib/thinreports/generator/pdf.rb b/lib/thinreports/generator/pdf.rb index f06b9e1f..0e874fb8 100644 --- a/lib/thinreports/generator/pdf.rb +++ b/lib/thinreports/generator/pdf.rb @@ -1,11 +1,11 @@ # coding: utf-8 begin - gem 'prawn', '0.12.0' + gem 'prawn', '1.3.0' require 'prawn' rescue LoadError - puts 'ThinReports requires Prawn = 0.12.0. ' + - 'Please `gem install prawn -v 0.12.0` and try again.' + puts 'ThinReports requires Prawn = 1.3.0. ' + + 'Please `gem install prawn -v 1.3.0` and try again.' end module ThinReports diff --git a/lib/thinreports/generator/pdf/document/graphics/image.rb b/lib/thinreports/generator/pdf/document/graphics/image.rb index 175ca2d5..3a80dfae 100644 --- a/lib/thinreports/generator/pdf/document/graphics/image.rb +++ b/lib/thinreports/generator/pdf/document/graphics/image.rb @@ -5,7 +5,7 @@ module ThinReports module Generator - + module PDF::Graphics # @param [String] filename # @param [Numeric, Strng] x @@ -16,7 +16,7 @@ def image(filename, x, y, w, h) w, h = s2f(w, h) pdf.image(filename, at: pos(x, y), width: w, height: h) end - + # @param [String] base64 # @param [Numeric, Strng] x # @param [Numeric, Strng] y @@ -26,7 +26,7 @@ def base64image(base64, x, y, w, h) image = create_temp_imagefile(base64) image(image.path, x, y, w, h) end - + # @param file (see Prawn#image) # @param [Numeric, Strng] x # @param [Numeric, Strng] y @@ -43,17 +43,17 @@ def image_box(file, x, y, w, h, options = {}) auto_fit: [w, h]) end end - + private - + def clean_temp_images temp_image_registry.each {|tmp| tmp.unlink } end - + def temp_image_registry @temp_image_registry ||= [] end - + # @param [String] base64 # @return [Tempfile] def create_temp_imagefile(base64) @@ -64,8 +64,8 @@ def create_temp_imagefile(base64) file ensure file.close - end + end end - + end end diff --git a/lib/thinreports/generator/pdf/document/graphics/text.rb b/lib/thinreports/generator/pdf/document/graphics/text.rb index a4baa185..704e1eb7 100644 --- a/lib/thinreports/generator/pdf/document/graphics/text.rb +++ b/lib/thinreports/generator/pdf/document/graphics/text.rb @@ -34,7 +34,7 @@ def text_box(contents, x, y, w, h, attrs = {}) with_text_styles(attrs) do |built_attrs, font_styles| contents = if inline_format - parsed_contents = ::Prawn::Text::Formatted::Parser.to_array(contents) + parsed_contents = ::Prawn::Text::Formatted::Parser.format(contents) parsed_contents.each {|c| c[:styles] |= font_styles } else [{ text: contents, styles: font_styles }] diff --git a/lib/thinreports/generator/pdf/document/page.rb b/lib/thinreports/generator/pdf/document/page.rb index d0c92a6c..cfa61f20 100644 --- a/lib/thinreports/generator/pdf/document/page.rb +++ b/lib/thinreports/generator/pdf/document/page.rb @@ -2,21 +2,21 @@ module ThinReports module Generator - + # @private module PDF::Page # Add JIS-B4,B5 page geometry - Prawn::Document::PageGeometry::SIZES.update( + ::PDF::Core::PageGeometry::SIZES.update( 'B4_JIS' => [728.5, 1031.8], 'B5_JIS' => [515.9, 728.5] ) - + # @param [ThinReports::Layout::Format] format def start_new_page(format) format_id = if change_page_format?(format) pdf.start_new_page(new_basic_page_options(format)) @current_page_format = format - + unless format_stamp_registry.include?(format.identifier) create_format_stamp(format) end @@ -25,16 +25,16 @@ def start_new_page(format) pdf.start_new_page(new_basic_page_options(current_page_format)) current_page_format.identifier end - + stamp(format_id.to_s) end - + def add_blank_page pdf.start_new_page(pdf.page_count.zero? ? {size: 'A4'} : {}) end - + private - + # @return [ThinReports::Layout::Format] attr_reader :current_page_format @@ -44,7 +44,7 @@ def change_page_format?(new_format) !current_page_format || current_page_format.identifier != new_format.identifier end - + # @param [ThinReports::Layout::Format] format def create_format_stamp(format) create_stamp(format.identifier.to_s) do @@ -52,12 +52,12 @@ def create_format_stamp(format) end format_stamp_registry << format.identifier end - + # @return [Array] def format_stamp_registry @format_stamp_registry ||= [] end - + # @param [ThinReports::Layout::Format] format # @return [Hash] def new_basic_page_options(format) @@ -80,6 +80,6 @@ def new_basic_page_options(format) options end end - + end end diff --git a/lib/thinreports/generator/pdf/prawn_ext.rb b/lib/thinreports/generator/pdf/prawn_ext.rb index 5cdc8c1d..f7b27313 100644 --- a/lib/thinreports/generator/pdf/prawn_ext.rb +++ b/lib/thinreports/generator/pdf/prawn_ext.rb @@ -3,46 +3,29 @@ # @private module Prawn class Document - # Create around alias. alias_method :original_width_of, :width_of - + def width_of(string, options={}) font.compute_width_of(string, options) + (character_spacing * (font.character_count(string) - 1)) end - - private - # Create around alias. + end + + class Images::Image alias_method :original_calc_image_dimensions, :calc_image_dimensions - - def calc_image_dimensions(info, options) + + def calc_image_dimensions(options) if options[:auto_fit] - w, h = info.width, info.height - sw, sh = options.delete(:auto_fit) - - if w > sw || h > sh - options[:fit] = [sw, sh] - end - end - original_calc_image_dimensions(info, options) - end - end + w = options[:width] || width + h = options[:height] || height - # Patch: https://github.com/prawnpdf/prawn/commit/34039d13b7886692debca11e85b9a572a20d57ee - module Core - class Reference - def <<(data) - (@stream ||= "") << data - @data[:Length] = @stream.length - @stream - end - - def compress_stream - @stream = Zlib::Deflate.deflate(@stream) - @data[:Filter] = :FlateDecode - @data[:Length] = @stream.length - @compressed = true + box_width, box_height = options.delete(:auto_fit) + + if w > box_width || h > box_height + options[:fit] = [box_width, box_height] + end end + original_calc_image_dimensions(options) end end end diff --git a/test/unit/generator/pdf/document/graphics/test_text.rb b/test/unit/generator/pdf/document/graphics/test_text.rb index b60fd22a..27cc1943 100644 --- a/test/unit/generator/pdf/document/graphics/test_text.rb +++ b/test/unit/generator/pdf/document/graphics/test_text.rb @@ -4,19 +4,19 @@ class ThinReports::Generator::PDF::Graphics::TestText < Minitest::Test include ThinReports::TestHelper - + def setup @pdf = ThinReports::Generator::PDF::Document.new @pdf.internal.start_new_page end - + def exec_with_font_styles(attrs = nil, font = nil, &block) attrs ||= {styles: [:bold]} font ||= {name: 'IPAMincho', size: 18, color: 'ff0000'} - + @pdf.send(:with_font_styles, attrs, font, &block) end - + def exec_with_text_styles(attrs = {}, &block) default_attrs = {font: 'Helvetica', color: 'ff0000', @@ -29,7 +29,7 @@ def test_with_text_styles_should_not_operate_when_color_is_none flunk end end - + def test_with_text_styles_should_set_leading_via_line_height_attribute exec_with_text_styles(line_height: 30) do |attrs, styles| expected = @pdf.send(:text_line_leading, @@ -38,86 +38,86 @@ def test_with_text_styles_should_set_leading_via_line_height_attribute assert_equal attrs[:leading], expected end end - + def test_with_text_styles_should_not_set_leading_when_line_height_is_not_specified exec_with_text_styles do |attrs, styles| refute_includes attrs.keys, :leading end end - + def test_with_text_styles_should_set_character_spacing_via_letter_spacing_attribute exec_with_text_styles(letter_spacing: 5) do |attrs, styles| assert_equal attrs[:character_spacing], @pdf.send(:s2f, 5) end end - + def test_with_text_styles_should_not_set_character_spacing_when_letter_spacing_is_not_specified exec_with_text_styles do |attrs, styles| refute_includes attrs.keys, :character_spacing end end - + def test_with_text_styles_should_parse_color exec_with_text_styles(color: '#ff0000') do |attrs, styles| assert_equal @pdf.internal.fill_color, 'ff0000' end end - + def test_with_font_styles_should_set_fill_color_using_color_of_font exec_with_font_styles do |attrs, styles| assert_equal @pdf.internal.fill_color, 'ff0000' end end - + def test_with_font_styles_should_perform_manual_style_when_bold_style_cannot_be_applied exec_with_font_styles do |attrs, styles| assert_empty styles end end - + def test_with_font_styles_should_perform_manual_style_when_italic_style_cannot_be_applied exec_with_font_styles do |attrs, styles| assert_empty styles end end - + def test_with_font_styles_should_set_stroke_color_using_color_of_font_when_bold_style_cannot_be_applied exec_with_font_styles do |attrs, styles| assert_equal @pdf.internal.stroke_color, 'ff0000' end end - + def test_with_font_styles_should_set_line_width_calculated_from_font_size_when_bold_style_cannot_be_applied exec_with_font_styles do |attrs, styles| assert_equal @pdf.internal.line_width, 18 * 0.025 end end - + def test_with_font_styles_should_set_mode_to_fill_stroke_when_bold_style_cannot_be_applied exec_with_font_styles do |attrs, styles| assert_equal attrs[:mode], :fill_stroke end end - + def test_with_font_styles_should_not_perform_a_manual_style_when_bold_style_can_be_applied exec_with_font_styles(nil, name: 'Helvetica', size: 12, color: '0000ff') do |attrs, styles| assert_includes styles, :bold end end - + def test_with_font_styles_should_not_perform_a_manual_style_when_italic_style_can_be_applied exec_with_font_styles({styles: [:italic]}, name: 'Helvetica', size: 12, color: 'ff0000') do |attrs, styles| assert_includes styles, :italic end end - + def test_text_line_leading_should_return_a_specified_leading_value_minus_the_font_height font = {name: 'IPAMincho', size: 36} font_height = @pdf.internal.font(font[:name], size: font[:size]).height - + assert_equal @pdf.send(:text_line_leading, 100, font), 100 - font_height end - + def test_text_without_line_wrap_should_replace_the_spaces_NBSP assert_equal @pdf.send(:text_without_line_wrap, ' ' * 2), Prawn::Text::NBSP * 2 end @@ -125,14 +125,14 @@ def test_text_without_line_wrap_should_replace_the_spaces_NBSP def test_text_box_with_inline_format contents = 'ThinReports official site is here.' - flexmock(::Prawn::Text::Formatted::Parser).should_receive(:to_array).with(contents).and_return([]).once + flexmock(::Prawn::Text::Formatted::Parser).should_receive(:format).with(contents).and_return([]).once @pdf.text_box(contents, 1, 1, 200, 100, inline_format: true, font: 'IPAMincho', size: 18, color: '000000') end def test_text_box_without_inline_format contents = 'ThinReports official site is here.' - flexmock(::Prawn::Text::Formatted::Parser).should_receive(:to_array).times(0) + flexmock(::Prawn::Text::Formatted::Parser).should_receive(:format).times(0) @pdf.text_box(contents, 1, 1, 200, 100, inline_format: false, font: 'IPAMincho', size: 18, color: '000000') end @@ -143,34 +143,34 @@ def test_text_box_should_not_raise_PrawnCannotFitError rescue Prawn::Errors::CannotFit flunk('Raise Prawn::Errors::CannotFit.') end - + def test_text_box_attrs_should_return_a_Hash_containing_a_at_and_width_options attrs = @pdf.send(:text_box_attrs, 0, 0, 50, 100) - + assert_equal attrs.values_at(:at, :width), [@pdf.send(:pos, 0, 0), @pdf.send(:s2f, 50)] end - + def test_text_box_attrs_should_return_a_Hash_which_doesnt_contain_the_single_line_option_when_single_is_true_but_overflow_is_expand attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 100, single: true, overflow: :expand) refute attrs.key?(:single_line) end - + def test_text_box_attrs_should_return_a_Hash_containing_a_single_line_option_when_single_is_true_and_overflow_isnot_expand attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 100, single: true, overflow: :truncate) assert_equal attrs[:single_line], true end - + def test_text_box_attrs_should_return_a_Hash_which_does_not_contain_a_height_option_when_single_is_true attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 100, single: true) refute attrs.key?(:height) end - + def test_text_box_attrs_should_return_a_Hash_which_does_not_contain_a_single_line_option_when_single_is_not_specified attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 100) refute attrs.key?(:single_line) end - + def test_text_box_attrs_should_return_a_Hash_containing_a_height_optin_when_single_is_not_specified attrs = @pdf.send(:text_box_attrs, 0, 0, 100, 200) assert_equal attrs[:height], 200 diff --git a/test/unit/generator/pdf/document/test_page.rb b/test/unit/generator/pdf/document/test_page.rb index 87adf4fe..b20584bf 100644 --- a/test/unit/generator/pdf/document/test_page.rb +++ b/test/unit/generator/pdf/document/test_page.rb @@ -4,13 +4,13 @@ class ThinReports::Generator::PDF::Document::TestPage < Minitest::Test include ThinReports::TestHelper - + def create_pdf @pdf = ThinReports::Generator::PDF::Document.new end def test_page_geometry - page_geometry = Prawn::Document::PageGeometry::SIZES + page_geometry = ::PDF::Core::PageGeometry::SIZES assert_equal page_geometry['B4_JIS'], [728.5, 1031.8] assert_equal page_geometry['B5_JIS'], [515.9, 728.5] end @@ -38,68 +38,68 @@ def test_B4_ISO_paper_size_should_be_converted_to_B4 def test_change_page_format_should_return_true_at_first_time create_pdf format = create_basic_layout_format('basic_layout1.tlf') - + assert_equal @pdf.send(:change_page_format?, format), true end - + def test_change_page_format_should_return_false_when_given_the_same_format create_pdf format = create_basic_layout_format('basic_layout1.tlf') - + @pdf.instance_variable_set(:@current_page_format, format) assert_equal @pdf.send(:change_page_format?, format), false end - + def test_change_page_format_should_return_true_when_given_the_other_format create_pdf format1 = create_basic_layout_format('basic_layout1.tlf') format2 = create_basic_layout_format('basic_layout2.tlf') - + @pdf.instance_variable_set(:@current_page_format, format1) assert_equal @pdf.send(:change_page_format?, format2), true end - + def test_new_basic_page_options format = create_basic_layout_format('basic_layout1.tlf') options = create_pdf.send(:new_basic_page_options, format) - + assert_equal options[:layout], format.page_orientation.to_sym assert_equal options[:size], format.page_paper_type end - + def test_new_basic_page_options_when_the_layout_has_customize_size format = flexmock('format'). should_receive(:user_paper_type? => true, page_width: 100, page_height: 100, page_orientation: 'portrait').mock - + options = create_pdf.send(:new_basic_page_options, format) assert_equal options[:size], [100, 100] end - + def test_start_new_page_should_create_stamp create_pdf format = create_basic_layout_format('basic_layout1.tlf') @pdf.start_new_page(format) - + assert_includes @pdf.send(:format_stamp_registry), format.identifier end - + def test_start_new_page_should_not_create_stamp create_pdf format = create_basic_layout_format('basic_layout1.tlf') @pdf.start_new_page(format) @pdf.start_new_page(format) - + assert_equal @pdf.send(:format_stamp_registry).size, 1 end - + def test_start_new_page_should_stamp_constantly create_pdf format = create_basic_layout_format('basic_layout1.tlf') flexmock(@pdf).should_receive(:stamp).with(format.identifier.to_s).times(2) - + @pdf.start_new_page(format) @pdf.start_new_page(format) end @@ -107,15 +107,15 @@ def test_start_new_page_should_stamp_constantly def test_add_blank_page_should_create_an_A4_size_page_in_first_page create_pdf flexmock(@pdf.internal).should_receive(:start_new_page).with(size: 'A4').once - + @pdf.add_blank_page end - + def test_add_blank_page_should_call_with_no_arguments_since_second_page create_pdf @pdf.start_new_page(create_basic_layout_format('basic_layout1.tlf')) flexmock(@pdf.internal).should_receive(:start_new_page).with(Hash.new).once - + @pdf.add_blank_page end end diff --git a/thinreports.gemspec b/thinreports.gemspec index af45c5a5..882e3913 100644 --- a/thinreports.gemspec +++ b/thinreports.gemspec @@ -23,7 +23,7 @@ Gem::Specification.new do |s| s.test_files = s.files.grep %r{^test/} s.require_paths = ['lib'] - s.add_dependency 'prawn', '0.12.0' + s.add_dependency 'prawn', '1.3.0' s.add_development_dependency 'bundler', ['>= 1.0.0'] s.add_development_dependency 'minitest', ['>= 5.0.0']