From 27d8677e3655cd8664e0f101a18d77703f4be6b8 Mon Sep 17 00:00:00 2001 From: Gregory Brown Date: Sun, 5 Oct 2014 08:56:17 -0400 Subject: [PATCH 1/6] Round to 4 decimal places in dash_setting --- lib/pdf/core/graphics_state.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/pdf/core/graphics_state.rb b/lib/pdf/core/graphics_state.rb index 3fcb1c3..3818808 100644 --- a/lib/pdf/core/graphics_state.rb +++ b/lib/pdf/core/graphics_state.rb @@ -64,10 +64,14 @@ def initialize(previous_state = nil) def dash_setting if @dash[:dash].kind_of?(Array) - "[#{@dash[:dash].join(' ')}] #{@dash[:phase]} d" + array = @dash[:dash].map { |e| e.round(4) } else - "[#{@dash[:dash]} #{@dash[:space]}] #{@dash[:phase]} d" + array = [@dash[:dash].round(4), @dash[:space].round(4)] end + + phase = @dash[:phase].round(4) + + "[#{array.join(' ')}] #{phase} d" end private From 5cbaf7780a5f92278964975b4ad617e7700b98ff Mon Sep 17 00:00:00 2001 From: Gregory Brown Date: Sun, 5 Oct 2014 11:07:00 -0400 Subject: [PATCH 2/6] Update dash code --- lib/pdf/core/graphics_state.rb | 9 +++++---- lib/pdf/core/pdf_object.rb | 18 ++++++++++++------ spec/pdf_object_spec.rb | 8 ++++---- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/pdf/core/graphics_state.rb b/lib/pdf/core/graphics_state.rb index 3818808..7aba7d3 100644 --- a/lib/pdf/core/graphics_state.rb +++ b/lib/pdf/core/graphics_state.rb @@ -63,15 +63,16 @@ def initialize(previous_state = nil) end def dash_setting + return "[] 0 d" unless @dash[:dash] + if @dash[:dash].kind_of?(Array) - array = @dash[:dash].map { |e| e.round(4) } + array = @dash[:dash] else - array = [@dash[:dash].round(4), @dash[:space].round(4)] + array = [@dash[:dash], @dash[:space]] end - phase = @dash[:phase].round(4) - "[#{array.join(' ')}] #{phase} d" + "[#{PDF::Core.real_array(array).join(' ')}] #{PDF::Core.real(phase)} d" end private diff --git a/lib/pdf/core/pdf_object.rb b/lib/pdf/core/pdf_object.rb index 1c34291..78254be 100644 --- a/lib/pdf/core/pdf_object.rb +++ b/lib/pdf/core/pdf_object.rb @@ -12,6 +12,14 @@ module PDF module Core module_function + def real(num) + num.to_f.round(4) + end + + def real_array(array) + array.map { |num| real(num) } + end + def utf8_to_utf16(str) "\xFE\xFF".force_encoding(::Encoding::UTF_16BE) + str.encode(::Encoding::UTF_16BE) end @@ -43,12 +51,10 @@ def PdfObject(obj, in_content_stream = false) when TrueClass then "true" when FalseClass then "false" when Numeric - if (str = String(obj)) =~ /e/i - # scientific notation is not supported in PDF - sprintf("%.16f", obj).gsub(/\.?0+\z/, "") - else - str - end + obj = real(obj) unless obj.kind_of?(Integer) + + String(obj) # NOTE: this can fail on huge floating point numbers, + # but it seems unlikely to ever happen in practice. when Array "[" << obj.map { |e| PdfObject(e, in_content_stream) }.join(' ') << "]" when PDF::Core::LiteralString diff --git a/spec/pdf_object_spec.rb b/spec/pdf_object_spec.rb index 39e0f65..2ff925a 100644 --- a/spec/pdf_object_spec.rb +++ b/spec/pdf_object_spec.rb @@ -14,10 +14,10 @@ end it "should convert a Ruby number to PDF number" do - PDF::Core::PdfObject(1).should == "1" - PDF::Core::PdfObject(1.214112421).should == "1.214112421" - # scientific notation is not valid in PDF - PDF::Core::PdfObject(0.000005).should == "0.000005" + PDF::Core::PdfObject(42).should == "42" + + # numbers are rounded to four decimal places + PDF::Core::PdfObject(1.214112421).should == "1.2141" end it "should convert a Ruby time object to a PDF timestamp" do From b3ea88b43f1f88c14567826f966cc52a2f8e0829 Mon Sep 17 00:00:00 2001 From: Gregory Brown Date: Sun, 5 Oct 2014 11:13:57 -0400 Subject: [PATCH 3/6] Temporary fix --- lib/pdf/core/graphics_state.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pdf/core/graphics_state.rb b/lib/pdf/core/graphics_state.rb index 7aba7d3..bb2282c 100644 --- a/lib/pdf/core/graphics_state.rb +++ b/lib/pdf/core/graphics_state.rb @@ -72,7 +72,8 @@ def dash_setting end - "[#{PDF::Core.real_array(array).join(' ')}] #{PDF::Core.real(phase)} d" + "[#{PDF::Core.real_array(array).join(' ')}] "+ + "#{PDF::Core.real(@dash[:phase])} d" end private From c2de7723a08bad0d4b9005e08117822808939a72 Mon Sep 17 00:00:00 2001 From: Gregory Brown Date: Mon, 6 Oct 2014 17:20:19 -0400 Subject: [PATCH 4/6] At this point we should have fairly comprehensive rounding --- example/lines.rb | 4 ++-- lib/pdf/core/graphics_state.rb | 2 +- lib/pdf/core/pdf_object.rb | 4 ++-- lib/pdf/core/renderer.rb | 5 +++-- lib/pdf/core/text.rb | 11 ++++++----- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/example/lines.rb b/example/lines.rb index 3014a85..e74d757 100644 --- a/example/lines.rb +++ b/example/lines.rb @@ -3,8 +3,8 @@ pdf = PDF::Core::Renderer.new(PDF::Core::DocumentState.new({})) pdf.start_new_page -pdf.add_content("%.3f %.3f m" % [100, 500]) -pdf.add_content("%.3f %.3f l" % [300, 550]) +pdf.add_content("#{PDF::Core.real_params([100,500])} m") +pdf.add_content("#{PDF::Core.real_params([300,550])} l") pdf.add_content("S") pdf.render_file("x.pdf") diff --git a/lib/pdf/core/graphics_state.rb b/lib/pdf/core/graphics_state.rb index bb2282c..1b44438 100644 --- a/lib/pdf/core/graphics_state.rb +++ b/lib/pdf/core/graphics_state.rb @@ -72,7 +72,7 @@ def dash_setting end - "[#{PDF::Core.real_array(array).join(' ')}] "+ + "[#{PDF::Core.real_params(array)}] "+ "#{PDF::Core.real(@dash[:phase])} d" end diff --git a/lib/pdf/core/pdf_object.rb b/lib/pdf/core/pdf_object.rb index 78254be..3b67b40 100644 --- a/lib/pdf/core/pdf_object.rb +++ b/lib/pdf/core/pdf_object.rb @@ -16,8 +16,8 @@ def real(num) num.to_f.round(4) end - def real_array(array) - array.map { |num| real(num) } + def real_params(array) + real_array(array).join(" ") end def utf8_to_utf16(str) diff --git a/lib/pdf/core/renderer.rb b/lib/pdf/core/renderer.rb index c5fcc24..2b88311 100644 --- a/lib/pdf/core/renderer.rb +++ b/lib/pdf/core/renderer.rb @@ -47,8 +47,9 @@ def deref(obj) # # # Raw line drawing example: # x1,y1,x2,y2 = 100,500,300,550 - # pdf.add_content("%.3f %.3f m" % [ x1, y1 ]) # move - # pdf.add_content("%.3f %.3f l" % [ x2, y2 ]) # draw path + # + # pdf.add_content("#{PDF::Core.real_params([x1, y1])} m") # move + # pdf.add_content("#{PDF::Core.real_params([ x2, y2 ])} l") # draw path # pdf.add_content("S") # stroke # def add_content(str) diff --git a/lib/pdf/core/text.rb b/lib/pdf/core/text.rb index 9f29866..b92a92a 100644 --- a/lib/pdf/core/text.rb +++ b/lib/pdf/core/text.rb @@ -204,9 +204,9 @@ def character_spacing(amount=nil) yield else @character_spacing = amount - add_content "\n%.3f Tc" % amount + add_content "\n#{PDF::Core.real(amount)} Tc" yield - add_content "\n%.3f Tc" % original_character_spacing + add_content "\n#{PDF::Core.real(original_character_spacing)} Tc" @character_spacing = original_character_spacing end end @@ -222,9 +222,10 @@ def word_spacing(amount=nil) yield else @word_spacing = amount - add_content "\n%.3f Tw" % amount + add_content "\n#{PDF::Core.real(amount)} Tw" yield - add_content "\n%.3f Tw" % original_word_spacing + add_content "\n#{PDF::Core.real(original_word_spacing)} Tw" + @word_spacing = original_word_spacing end end @@ -237,7 +238,7 @@ def add_text_content(text, x, y, options) if options[:rotate] rad = options[:rotate].to_f * Math::PI / 180 arr = [ Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), x, y ] - add_content "%.3f %.3f %.3f %.3f %.3f %.3f Tm" % arr + add_content "#{PDF::Core.real_params(array)} Tm" else add_content "#{x} #{y} Td" end From 3f5e991c2ad4036844e3609d6ecf23db3de20305 Mon Sep 17 00:00:00 2001 From: Gregory Brown Date: Mon, 6 Oct 2014 17:26:39 -0400 Subject: [PATCH 5/6] Fix broken real_params method --- lib/pdf/core/pdf_object.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pdf/core/pdf_object.rb b/lib/pdf/core/pdf_object.rb index 3b67b40..e3fade6 100644 --- a/lib/pdf/core/pdf_object.rb +++ b/lib/pdf/core/pdf_object.rb @@ -17,7 +17,7 @@ def real(num) end def real_params(array) - real_array(array).join(" ") + array.map { |e| real(e) }.join(" ") end def utf8_to_utf16(str) From 337f5e41472a09aeda5a14f7bd2015ef3b6779e3 Mon Sep 17 00:00:00 2001 From: Gregory Brown Date: Fri, 10 Oct 2014 08:02:10 -0400 Subject: [PATCH 6/6] Add very basic tests for real and real_params --- spec/decimal_rounding_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 spec/decimal_rounding_spec.rb diff --git a/spec/decimal_rounding_spec.rb b/spec/decimal_rounding_spec.rb new file mode 100644 index 0000000..6055719 --- /dev/null +++ b/spec/decimal_rounding_spec.rb @@ -0,0 +1,12 @@ +# encoding: binary +require_relative "spec_helper" + +describe "Decimal rounding" do + it "should round floating point numbers to four decimal places" do + PDF::Core.real(1.23456789).should == 1.2346 + end + + it "should be able to create a PDF parameter list of rounded decimals" do + PDF::Core.real_params([1,2.34567,Math::PI]).should == "1.0 2.3457 3.1416" + end +end