lib/prawn/document/text.rb in prawn-0.1.1 vs lib/prawn/document/text.rb in prawn-0.1.2

- old
+ new

@@ -35,30 +35,46 @@ # # If your font contains kerning pairs data that Prawn can parse, the # text will be kerned by default. You can disable this feature by passing # <tt>:kerning => false</tt>. # + # == Encoding + # # Note that strings passed to this function should be encoded as UTF-8. - # If you get unexpected characters appearing in your rendered - # document, check this. + # If you get unexpected characters appearing in your rendered document, + # check this. # + # If the current font is a built-in one, although the string must be + # encoded as UTF-8, only characters that are available in ISO-8859-1 + # are allowed. + # # If an empty box is rendered to your PDF instead of the character you # wanted it usually means the current font doesn't include that character. # def text(text,options={}) + # ensure a valid font is selected + font "Helvetica" unless fonts[@font] + + # we'll be messing with the strings encoding, don't change the users + # original string + text = text.dup + # check the string is encoded sanely - normalize_encoding(text) + # - UTF-8 for TTF fonts + # - ISO-8859-1 for Built-In fonts + if using_builtin_font? + normalize_builtin_encoding(text) + else + normalize_ttf_encoding(text) + end if options.key?(:kerning) options[:kerning] = false unless font_metrics.has_kerning_data? else options[:kerning] = true if font_metrics.has_kerning_data? end - # ensure a valid font is selected - font "Helvetica" unless fonts[@font] - return wrapped_text(text,options) unless options[:at] x,y = translate(options[:at]) font_size(options[:size] || current_font_size) do font_name = font_registry[fonts[@font]] @@ -149,11 +165,12 @@ end alias_method :font_size=, :font_size! private - + + # The current font_size being used in the document. # def current_font_size @font_size || DEFAULT_FONT_SIZE end @@ -279,15 +296,29 @@ :Encoding => :"Identity-H", :ToUnicode => to_unicode) return basename end - def normalize_encoding(text) + # built-in fonts only work with latin encoding, so translate the string + def normalize_builtin_encoding(text) + if text.respond_to?(:encode!) + text.encode!("ISO-8859-1") + else + require 'iconv' + text.replace Iconv.conv('ISO-8859-1', 'utf-8', text) + end + rescue + raise Prawn::Errors::IncompatibleStringEncoding, "When using a " + + "builtin font, only characters that exist in " + + "WinAnsi/ISO-8859-1 are allowed." + end + + def normalize_ttf_encoding(text) # TODO: if the current font is a built in one, we can't use the utf-8 # string provided by the user. We should convert it to WinAnsi or # MacRoman or some such. - if text.respond_to?(:"encode!") + 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 @@ -314,11 +345,11 @@ raise Prawn::Errors::UnknownFont, "#{name} is not a known font." end fonts[name] ||= ref(:Type => :Font, :Subtype => :Type1, :BaseFont => name.to_sym, - :Encoding => :MacRomanEncoding) + :Encoding => :WinAnsiEncoding) return name end def set_current_font #:nodoc: return if @font.nil? @@ -339,8 +370,11 @@ def fonts #:nodoc: @fonts ||= {} end + def using_builtin_font? + fonts[@font].data[:Subtype] == :Type1 + end end end end