Skip to content

Commit

Permalink
Merge branch 'encoding_compatibility_cleanup' of git://github.com/ale…
Browse files Browse the repository at this point in the history
…xdowad/prawn

Conflicts:
	spec/font_spec.rb
  • Loading branch information
bradediger committed Aug 21, 2012
2 parents 5b34840 + a5a7fc1 commit 121dba0
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 59 deletions.
11 changes: 5 additions & 6 deletions bench/table_bench.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,15 @@ def benchmark_table_generation(columns,rows,string_size,options={})
end
end

# Slowest case: styled table, which is very squeezed horizontally,
# so text has to be wrapped
benchmark_table_generation(26,50,10, :row_colors => ['FFFFFF','F0F0FF'], :header => true, :cell_style => {:inline_format=>true})

# Try building and rendering tables of different sizes
benchmark_table_generation(10,450,5)
benchmark_table_generation(10,300,5)
benchmark_table_generation(10,400,5)
benchmark_table_generation(10,200,5)
benchmark_table_generation(10,100,5)

# Try different optional arguments to Prawn::Document#table
benchmark_table_generation(10,450,5, :cell_style => {:inline_format=>true})
benchmark_table_generation(10,450,5, :row_colors => ['FFFFFF','F0F0FF'], :header => true, :cell_style => {:inline_format=>true})

# Try different "aspect ratios", with same total number of cells
benchmark_table_generation(20,100,5)
benchmark_table_generation(25,80,5)
56 changes: 46 additions & 10 deletions lib/prawn/compatibility.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,60 @@
# coding: utf-8
#
# Why would we ever use Ruby 1.8.7 when we can backport with something
# as simple as this?
#
# Compatibility layer to smooth over differences between Ruby implementations
# The oldest version of Ruby which is supported is MRI 1.8.7
# Ideally, all version-specific or implementation-specific code should be
# kept in this file (but that ideal has not been attained yet)

class String #:nodoc:
def first_line
self.each_line { |line| return line }
end
unless "".respond_to?(:lines)
alias_method :lines, :to_a

unless "".respond_to?(:codepoints)
def codepoints(&block)
if block_given?
unpack("U*").each(&block)
else
unpack("U*")
end
end
end
unless "".respond_to?(:each_char)
def each_char #:nodoc:
# copied from jcode

if "".respond_to?(:encode)
def normalize_to_utf8
begin
encode(Encoding::UTF_8)
rescue
raise Prawn::Errors::IncompatibleStringEncoding, "Encoding " +
"#{text.encoding} can not be transparently converted to UTF-8. " +
"Please ensure the encoding of the string you are attempting " +
"to use is set correctly"
end
end
alias :unicode_characters :each_char
alias :unicode_length :length

else
def normalize_to_utf8
begin
# use unpack as a hackish way to verify the string is valid utf-8
unpack("U*")
return dup
rescue
raise Prawn::Errors::IncompatibleStringEncoding, "The string you " +
"are attempting to render is not encoded in valid UTF-8."
end
end
def unicode_characters
if block_given?
scan(/./m) { |x| yield x }
unpack("U*").each { |c| yield [c].pack("U") }
else
scan(/./m)
unpack("U*").map { |c| [c].pack("U") }
end
end
def unicode_length
unpack("U*").length
end
end
end

Expand Down
6 changes: 1 addition & 5 deletions lib/prawn/core/object_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,7 @@ def import_page(input, page_num)
io = if input.respond_to?(:seek) && input.respond_to?(:read)
input
elsif File.file?(input.to_s)
if File.respond_to?(:binread)
StringIO.new(File.binread(input.to_s))
else
StringIO.new(File.read(input.to_s))
end
StringIO.new(File.binread(input.to_s))
else
raise ArgumentError, "input must be an IO-like object or a filename"
end
Expand Down
2 changes: 1 addition & 1 deletion lib/prawn/core/pdf_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def string_to_hex(str)
def utf8_to_utf16(str)
utf16 = "\xFE\xFF"

str.unpack("U*").each do |cp|
str.codepoints do |cp|
if cp < 0x10000 # Basic Multilingual Plane
utf16 << [cp].pack("n")
else
Expand Down
7 changes: 5 additions & 2 deletions lib/prawn/core/text/formatted/line_wrap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,12 @@ def end_of_the_line_reached(segment)
end

def wrap_by_char(segment)
# this conditional is only necessary for Ruby 1.8 compatibility
# String#unicode_characters is a helper which iterates over UTF-8 characters
# under Ruby 1.9, it is implemented simply by aliasing #each_char
if @document.font.unicode?
segment.unpack("U*").each do |char_int|
break unless append_char([char_int].pack("U"))
segment.unicode_characters do |char|
break unless append_char(char)
end
else
segment.each_char do |char|
Expand Down
4 changes: 2 additions & 2 deletions lib/prawn/font/afm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def kern(string)

kern_pairs = latin_kern_pairs_table

string.unpack("C*").each do |byte|
string.bytes do |byte|
if k = last_byte && kern_pairs[[last_byte, byte]]
kerned << -k << [byte]
else
Expand Down Expand Up @@ -236,7 +236,7 @@ def latin_glyphs_table
def unscaled_width_of(string)
glyph_table = latin_glyphs_table

string.unpack("C*").inject(0) do |s,r|
string.bytes.inject(0) do |s,r|
s + glyph_table[r]
end
end
Expand Down
36 changes: 5 additions & 31 deletions lib/prawn/font/ttf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def compute_width_of(string, options={}) #:nodoc:
end
end * scale
else
string.unpack("U*").inject(0) do |s,r|
string.codepoints.inject(0) do |s,r|
s + character_width_by_code(r)
end * scale
end
Expand Down Expand Up @@ -160,44 +160,18 @@ def pdf_flags
end

def normalize_encoding(text)
if text.respond_to?(:encode)
# if we're running under a M17n aware VM, ensure the string provided is
# UTF-8 (by converting it if necessary)
begin
text.encode("UTF-8")
rescue
raise Prawn::Errors::IncompatibleStringEncoding, "Encoding " +
"#{text.encoding} can not be transparently converted to UTF-8. " +
"Please ensure the encoding of the string you are attempting " +
"to use is set correctly"
end
else
# on a non M17N aware VM, use unpack as a hackish way to verify the
# string is valid utf-8. I thought it was better than loading iconv
# though.
begin
text.unpack("U*")
return text.dup
rescue
raise Prawn::Errors::IncompatibleStringEncoding, "The string you " +
"are attempting to render is not encoded in valid UTF-8."
end
end
text.normalize_to_utf8
end

def glyph_present?(char)
code = char.unpack("U*").first
code = char.codepoints.first
cmap[code] > 0
end

# Returns the number of characters in +str+ (a UTF-8-encoded string).
#
def character_count(str)
if str.respond_to?(:encode)
str.length
else
str.unpack("U*").length
end
str.unicode_length
end

private
Expand All @@ -214,7 +188,7 @@ def cmap
def kern(string)
a = []

string.unpack("U*").each do |r|
string.codepoints do |r|
if a.empty?
a << [r]
elsif (kern = kern_pairs_table[[cmap[a.last.last], cmap[r]]])
Expand Down
3 changes: 1 addition & 2 deletions lib/prawn/text/formatted/box.rb
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,7 @@ def analyze_glyphs_for_fallback_font_support(hash)
# all fonts
fallback_fonts << fragment_font

hash[:text].unpack("U*").each do |char_int|
char = [char_int].pack("U")
hash[:text].unicode_characters do |char|
@document.font(fragment_font)
font_glyph_pairs << [find_font_for_this_glyph(char,
@document.font.family,
Expand Down

0 comments on commit 121dba0

Please sign in to comment.