diff --git a/ChangeLog b/ChangeLog
index f54539d..7f361b7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
= PDF::Writer Change Log
+== PDF::Writer 1.3.0: August 16, 2013
+* Ruby 2.0 compatibility.
+ o ImageInfo fixes encoding issue
+ o Writer fixes enumeration of String
+ o Fixed computation of font-width calculations
+
== PDF::Writer 1.2.1: May 13, 2009
* Ruby 1.9 compatibility.
diff --git a/README b/README
index e3f61a9..9a26cbb 100644
--- a/README
+++ b/README
@@ -12,6 +12,14 @@ This software is based on Adobe's PDF Reference, Fifth Edition, version 1.6.
This and earlier editions are available from Adobe's PDF developer
website[http://partners.adobe.com/public/developer/pdf/index_reference.html].
+== Ruby 2.0 Compatibility
+This gem version has been updated to work with Ruby 2.0. This is a maintenance
+effort only to support moving existing projects from Ruby 1.8 to 2.0. New project
+development should use Prawn[1] over PDF-Writer as it is actively maintained and
+is also the successor/rewrite of this library.
+
+[1] http://prawn.majesticseacreature.com/
+
== LICENCE NOTES
Please read the file LICENCE for licensing restrictions on this library, as
well as important patent considerations.
diff --git a/lib/pdf/writer.rb b/lib/pdf/writer.rb
index e25338a..5c96f11 100644
--- a/lib/pdf/writer.rb
+++ b/lib/pdf/writer.rb
@@ -1,3 +1,4 @@
+#encoding: ISO-8859-1
#--
# PDF::Writer for Ruby.
# http://rubyforge.org/projects/ruby-pdf/
@@ -6,13 +7,12 @@
# Licensed under a MIT-style licence. See LICENCE in the main distribution
# for full licensing information.
#
-# $Id$
+# $Id: writer.rb 202 2008-03-16 23:30:11Z sandal $
#++
require 'thread'
require 'open-uri'
require 'transaction/simple'
-require 'pdf/core_ext/mutex'
require 'color'
# A class to provide the core functionality to create a PDF document
@@ -20,7 +20,7 @@
module PDF
class Writer
# The version of PDF::Writer.
- VERSION = '1.2.0'
+ VERSION = '1.3.0'
# Escape the text so that it's safe for insertion into the PDF
# document.
@@ -710,14 +710,22 @@ def render(debug = false)
xref = []
- content = "%PDF-#{@version}\n%\303\242\303\243\303\217\303\223\n"
+ content = "%PDF-#{@version}\n%âãÏÓ\n"
pos = content.size
objects.each do |oo|
- cont = oo.to_s
- content << cont
- xref << pos
- pos += cont.size
+ begin
+ cont = oo.to_s.force_encoding("ISO-8859-1")
+ content << cont
+ xref << pos
+ pos += cont.size
+ rescue
+ # puts '*' * 80
+ # puts cont.inspect
+ # puts cont.encoding.name
+ # puts '*' * 80
+ raise
+ end
end
# pos += 1 # Newline character before XREF
@@ -741,6 +749,10 @@ def render(debug = false)
end
alias :to_s :render
+ def render_to_file(filename)
+ IO.binwrite(filename, render)
+ end
+
# Loads the font metrics. This is now thread-safe.
def load_font_metrics(font)
metrics = PDF::Writer::FontMetrics.open(font)
@@ -1371,9 +1383,9 @@ def add_text(x, y, text, size = nil, angle = 0, word_space_adjust = 0)
end
select_font("Helvetica") if @fonts.empty?
-
+
text = text.to_s
-
+
# If there are any open callbacks, then they should be called, to show
# the start of the line
@callbacks.reverse_each do |ii|
@@ -1467,11 +1479,11 @@ def add_text(x, y, text, size = nil, angle = 0, word_space_adjust = 0)
end
def char_width(font, char)
- if RUBY_VERSION >= '1.9'
- char = char.bytes.to_a.first unless @fonts[font].c[char]
- else
- char = char[0] unless @fonts[font].c[char]
- end
+ if RUBY_VERSION >= '1.9'
+ char = char.ord unless @fonts[font].c[char]
+ else
+ char = char[0] unless @fonts[font].c[char]
+ end
if @fonts[font].differences and @fonts[font].c[char].nil?
name = @fonts[font].differences[char] || 'M'
diff --git a/lib/pdf/writer/fontmetrics.rb b/lib/pdf/writer/fontmetrics.rb
index a071783..77c7304 100644
--- a/lib/pdf/writer/fontmetrics.rb
+++ b/lib/pdf/writer/fontmetrics.rb
@@ -6,7 +6,7 @@
# Licensed under a MIT-style licence. See LICENCE in the main distribution
# for full licensing information.
#
-# $Id$
+# $Id: fontmetrics.rb 168 2007-11-08 19:04:08Z sandal $
#++
class PDF::Writer::FontMetrics
@@ -78,7 +78,7 @@ def self.open(font_name)
font = PDF::Writer::FontMetrics.new
# An AFM file contains key names followed by valuees.
- file.each_line do |line|
+ file.each do |line|
line.chomp!
line.strip!
key, *values = line.split
@@ -152,7 +152,7 @@ def self.open(font_name)
# C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ;
bits = line.chomp.strip.split(/;/).collect { |r| r.strip }
dtmp = {}
-
+
bits.each do |bit|
b = bit.split
if b.size > 2
diff --git a/lib/pdf/writer/graphics.rb b/lib/pdf/writer/graphics.rb
index 289f071..dd7df78 100644
--- a/lib/pdf/writer/graphics.rb
+++ b/lib/pdf/writer/graphics.rb
@@ -1,3 +1,4 @@
+#encoding: ISO-8859-1
#--
# PDF::Writer for Ruby.
# http://rubyforge.org/projects/ruby-pdf/
@@ -6,7 +7,7 @@
# Licensed under a MIT-style licence. See LICENCE in the main distribution
# for full licensing information.
#
-# $Id$
+# $Id: graphics.rb 166 2007-11-08 18:22:05Z sandal $
#++
# Points for use in the drawing of polygons.
class PDF::Writer::PolygonPoint
@@ -543,11 +544,7 @@ def add_image_from_file(image, x, y, width = nil, height = nil, link = nil)
if image.respond_to?(:read)
data = image.read
else
- if RUBY_VERSION >= '1.9'
- open(image,'rb:binary') { |ff| data = ff.read }
- else
- open(image,'rb') { |ff| data = ff.read }
- end
+ open(image, 'r:ISO-8859-1:ISO-8859-1') { |ff| data = ff.read }
end
add_image(data, x, y, width, height, nil, link)
@@ -664,7 +661,7 @@ def image(image, options = {})
if image.respond_to?(:read)
image_data = image.read
else
- image_data = open(image, "rb") { |file| file.read }
+ image_data = open(image, "r:ISO-8859-1:ISO-8859-1") { |file| file.read }
end
info = PDF::Writer::Graphics::ImageInfo.new(image_data)
end
diff --git a/lib/pdf/writer/graphics/imageinfo.rb b/lib/pdf/writer/graphics/imageinfo.rb
index 0ace52f..b4d5ca7 100644
--- a/lib/pdf/writer/graphics/imageinfo.rb
+++ b/lib/pdf/writer/graphics/imageinfo.rb
@@ -1,3 +1,4 @@
+#encoding: ISO-8859-1
#--
# PDF::Writer for Ruby.
# http://rubyforge.org/projects/ruby-pdf/
@@ -9,7 +10,7 @@
# This file is also licensed under standard Ruby licensing provisions: the
# Ruby licence and the GNU General Public Licence, version 2 or later.
#
-# $Id$
+# $Id: imageinfo.rb 173 2007-11-15 17:58:43Z sandal $
#++
require 'pdf/writer/oreader'
@@ -47,8 +48,8 @@ def formats
alias :type_list :formats
end
- JPEG_SOF_BLOCKS = %W(\xc0 \xc1 \xc2 \xc3 \xc5 \xc6 \xc7 \xc9 \xca \xcb \xcd \xce \xcf)
- JPEG_APP_BLOCKS = %W(\xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef)
+ JPEG_SOF_BLOCKS = %W(\xc0 \xc1 \xc2 \xc3 \xc5 \xc6 \xc7 \xc9 \xca \xcb \xcd \xce \xcf).map{|m| m.force_encoding("ISO-8859-1")}
+ JPEG_APP_BLOCKS = %W(\xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef).map{|m| m.force_encoding("ISO-8859-1")}
# Receive image & make size. argument is image String or IO
def initialize(data, format = nil)
@@ -98,7 +99,7 @@ def @data.read_o(length = 1, offset = nil)
attr_reader :channels
attr_reader :info
-
+
def discover_format
if @top =~ %r{^GIF8[79]a}
Formats::GIF
@@ -173,8 +174,12 @@ def measure_JPEG
@data.read_o(2) # Skip the first two bytes of JPEG identifier.
loop do
marker, code, length = @data.read_o(4).unpack('aan')
+
+ marker.force_encoding("ISO-8859-1")
+ code.force_encoding("ISO-8859-1")
+
raise "JPEG marker not found!" if marker != c_marker
-
+
if JPEG_SOF_BLOCKS.include?(code)
@bits, @height, @width, @channels = @data.read_o(6).unpack("CnnC")
break
@@ -351,7 +356,7 @@ def measure_TIFF
Dir.glob("*").each do |file|
print "#{file} (string)\n"
- open(file, "rb") do |fh|
+ open(file, "r:ISO-8859-1:ISO-8859-1") do |fh|
image = PDF::Writer::Graphics::ImageInfo.new(fh.read)
print <<-EOF
Format : #{image.format}
diff --git a/test/test_image_read.rb b/test/test_image_read.rb
new file mode 100644
index 0000000..ab2a9ac
--- /dev/null
+++ b/test/test_image_read.rb
@@ -0,0 +1,70 @@
+#encoding: UTF-8
+$LOAD_PATH.unshift(File.dirname(__FILE__) + "/../lib")
+require "pdf/writer"
+
+MAIN_TEXT_WIDTH = 330
+MAIN_TEXT_LINE_SPACING = 16
+PADDING_BOTTOM = 20
+
+def write_text(pdf, text, options = {})
+ y = options[:y] if options[:y]
+ left = options[:left] if options[:left]
+ width = options[:width] if options[:width]
+ size = options[:font_size] || 0
+ height = options[:leading]
+
+ # Filled with the text that would flow onto the next page
+ next_page_text = nil
+
+ text.each_line do |line|
+ start = true
+ loop do
+ break if (line.nil? or line.empty?) and not start
+
+ start = false
+
+ y -= height
+
+ if y < (pdf.absolute_bottom_margin + PADDING_BOTTOM)
+ if options[:no_newpage]
+ # Collect remaining text so it can be returned
+ next_page_text = "" if next_page_text.nil?
+ next_page_text += line
+ line = nil
+ else
+ pdf.start_new_page
+ y = options[:new_page_y] || multi_page_top_y(pdf)
+ end
+ end
+
+ if next_page_text.nil?
+ line = pdf.add_text_wrap(left, y, width, line, size)
+ end
+ end
+ end
+
+ if options[:no_newpage]
+ {:leftover_text => next_page_text, :next_line_y => y}
+ else
+ y
+ end
+end
+
+
+pdf = PDF::Writer.new
+top_logo_file = '/Users/mwlang/projects/clients/taftlaw/taft_site/website/public/images/hr_taft_logo.jpg'
+pdf.image(top_logo_file, {:width => 85, :justification => :right, :pad => 0 })
+
+body = "\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\r\n\r\n\r\nCHARLES R. \"ROCKY\" SAXBE is Partner-in-Charge of the Columbus office. He maintains an active litigation practice representing clients in all aspects of civil litigation. Over the course of his illustrious career, he has acted as principal litigation counsel in numerous complex litigation cases, including serving as principal outside Ohio special counsel for the State of Ohio in the national tobacco litigation. He has appeared in numerous jury trials and has appeared before the Ohio Supreme Court, Ohio Courts of Appeals, and the Sixth Circuit U.S. Court of Appeals. According to Chambers USA, who interviews clients for feedback, Rocky is held in high regard \"for his political acumen, especially in election law-related and complex civil litigation.\" Rocky has a long affiliation with the political scene in Ohio, having served four terms in the Ohio House of Representatives. He provides counsel to elected officials, political party organizations and candidates on election, campaign finance and public ethics law.\r\n\r\nRepresentative Experience\r\n\r\n\r\n\tServed as principal outside Ohio special counsel for the State of Ohio in the \"national tobacco litigation,\" contributing significantly to the record setting $10 billion settlement for the State of Ohio.\r\n\tHas been the principal litigation counsel in numerous complex litigations, including numerous jury trials and has appeared before Ohio Supreme Court, Ohio Courts of Appeals, and the Sixth Circuit U.S. Court of Appeals.\r\n\tProvided counsel to elected officials, political party organizations and candidates on election, campaign finance and public ethics law.\r\n\tFrequent mediator assigned by the Federal Court for the Southern District of Ohio, providing expert testimony in the areas of attorneys' fees and malpractice.\r\n\tServes as legislative counsel for the Ohio Association of Municipal and County Judges.\r\n\r\n\r\nAchievements and Awards\r\n\r\n\r\n\tRecipient of the Ohio State Bar Association Distinguished Service Award\r\n\tAV Peer Review (Preeminent) Rated by Martindale-Hubbell\r\n\tBest Lawyers in America, Commercial Litigation, Government Relations Law & Bet-the-Company Litigation\r\n\tListed for inclusion in Ohio Super Lawyers, General Litigation (2004 - 2013)\r\n\tChambers USA, Litigation\r\n\r\n\r\nProfessional Memberships and Community Service\r\n\r\n\r\n\tColumbus Bar Association\r\n\tOhio State Bar Association\r\n\tAmerican Bar Associations\r\n\tChampaign County Bar Association\r\n\tGreater Columbus Arts Council, Past Chairman\r\n\tBexley Library Board, Past President\r\n\tColumbus College of Art and Design, Past Chairman\r\n\tCentral State University, Past Trustee\r\n\tMechanicsburg Lodge #113 F&AM, Past Master\r\n\tAncient and Accepted Scottish Rite, 33°\r\n\tVietnam Veterans of America\r\n\tAmerican Legion\r\n\tScioto Valley Rugby Football Club (SVRFC Hall of Fame)\r\n\r\n\r\nOther Professional Experience\r\n\r\n\r\n\tU.S. Marine Corps, infantry platoon commander with the First Marine Division in the Republic of Vietnam and was discharged with the rank of Captain\r\n\tElected to the Ohio House of Representatives in 1974 where he served four terms\r\n\tRepublican nominee for Ohio Attorney General in 1982\r\n\r\n"
+write_text(pdf,
+ body,
+ {
+ :no_newpage => true,
+ :y => pdf.absolute_top_margin - 140,
+ :left => pdf.absolute_left_margin,
+ :leading => MAIN_TEXT_LINE_SPACING,
+ :width => MAIN_TEXT_WIDTH
+ }
+)
+
+pdf.render
\ No newline at end of file