diff --git a/examples/m17n/win_ansi_charset.rb b/examples/m17n/win_ansi_charset.rb index f7da2d7a9..ffde37566 100644 --- a/examples/m17n/win_ansi_charset.rb +++ b/examples/m17n/win_ansi_charset.rb @@ -31,14 +31,14 @@ code = "%d." % index char = index.chr - width = 1000 * font.width_of(char, :size => FONT_SIZE) / FONT_SIZE + width = 1000 * width_of(char, :size => FONT_SIZE) / FONT_SIZE size = "%d" % width data = [code, nil, char, size, nil, name] dx = x fields.zip(data).each do |(total_width, align), field| if field - width = font.width_of(field, :size => FONT_SIZE) + width = width_of(field, :size => FONT_SIZE) case align when :left then offset = 0 diff --git a/lib/prawn/document/text.rb b/lib/prawn/document/text.rb index 3952b1757..b01a4f8cd 100644 --- a/lib/prawn/document/text.rb +++ b/lib/prawn/document/text.rb @@ -138,7 +138,7 @@ def wrapped_text(text,options) lines.each_with_index do |e,i| move_text_position(font.ascender) - line_width = font.width_of(e, :kerning => options[:kerning]) + line_width = width_of(e, :kerning => options[:kerning]) case(options[:align]) when :left x = @bounding_box.absolute_left diff --git a/lib/prawn/document/text/wrapping.rb b/lib/prawn/document/text/wrapping.rb index 42aa38dd2..b0dc05aa1 100644 --- a/lib/prawn/document/text/wrapping.rb +++ b/lib/prawn/document/text/wrapping.rb @@ -32,7 +32,7 @@ def naive_wrap(string, line_width, font_size, options = {}) segments = line.scan(scan_pattern) segments.each do |segment| - segment_width = font.width_of(segment, :size => font_size, :kerning => options[:kerning]) + segment_width = width_of(segment, :size => font_size, :kerning => options[:kerning]) if (accumulated_width + segment_width).round > line_width.round output = "#{output.sub(/[ \t]*\n?(\n*)\z/, "\n\\1")}" diff --git a/lib/prawn/font.rb b/lib/prawn/font.rb index af1eda3bd..17b099538 100644 --- a/lib/prawn/font.rb +++ b/lib/prawn/font.rb @@ -169,6 +169,29 @@ def font_families :normal => "Helvetica" } }) end + + # Returns the width of the given string using the given font. If :size is not + # specified as one of the options, the string is measured using the current + # font size. You can also pass :kerning as an option to indicate whether + # kerning should be used when measuring the width (defaults to +false+). + # + # Note that the string _must_ be encoded properly for the font being used. + # For AFM fonts, this is WinAnsi. For TTF, make sure the font is encoded as + # UTF-8. You can use the Font#normalize_encoding method to make sure strings + # are in an encoding appropriate for the current font. + #-- + # For the record, this method used to be a method of Font (and still delegates + # to width computations on Font). However, having the primary interface for + # calculating string widths exist on Font made it tricky to write extensions + # for Prawn in which widths are computed differently (e.g., taking formatting + # tags into account, or the like). + # + # By putting width_of here, on Document itself, extensions may easily override + # it and redefine the width calculation behavior. + #++ + def width_of(string, options={}) + font.compute_width_of(string, options) + end end # Provides font information and helper functions. @@ -226,19 +249,6 @@ def inspect "#{self.class.name}< #{name}: #{size} >" end - # Returns the width of the given string using the given font. If :size is not - # specified as one of the options, the string is measured using the current - # font size. You can also pass :kerning as an option to indicate whether - # kerning should be used when measuring the width (defaults to +false+). - # - # Note that the string _must_ be encoded properly for the font being used. - # For AFM fonts, this is WinAnsi. For TTF, make sure the font is encoded as - # UTF-8. You can use the #normalize_encoding method to make sure strings - # are in an encoding appropriate for the font. - def width_of(string, options={}) - raise NotImplementedError, "subclasses of Prawn::Font must implement #width_of" - end - # Normalizes the encoding of the string to an encoding supported by the font. # The string is expected to be UTF-8 going in, and will be reencoded in-place # (the argument will be modified directly). The return value is not defined. diff --git a/lib/prawn/font/afm.rb b/lib/prawn/font/afm.rb index a278c90af..af593f4e5 100644 --- a/lib/prawn/font/afm.rb +++ b/lib/prawn/font/afm.rb @@ -53,7 +53,7 @@ def bbox # # String *must* be encoded as WinAnsi # - def width_of(string, options={}) + def compute_width_of(string, options={}) scale = (options[:size] || size) / 1000.0 if options[:kerning] diff --git a/lib/prawn/font/ttf.rb b/lib/prawn/font/ttf.rb index 34b76ae65..6f7022546 100644 --- a/lib/prawn/font/ttf.rb +++ b/lib/prawn/font/ttf.rb @@ -23,7 +23,7 @@ def initialize(document, name, options={}) end # +string+ must be UTF8-encoded. - def width_of(string, options={}) + def compute_width_of(string, options={}) scale = (options[:size] || size) / 1000.0 if options[:kerning] kern(string).inject(0) do |s,r| diff --git a/spec/font_spec.rb b/spec/font_spec.rb index 2333c25ed..9661357c4 100644 --- a/spec/font_spec.rb +++ b/spec/font_spec.rb @@ -135,13 +135,13 @@ def page_should_not_include_font(font) end it "should calculate string width taking into account accented characters" do - @times.width_of(@iconv.iconv("é"), :size => 12).should == @times.width_of("e", :size => 12) + @times.compute_width_of(@iconv.iconv("é"), :size => 12).should == @times.compute_width_of("e", :size => 12) end it "should calculate string width taking into account kerning pairs" do - @times.width_of(@iconv.iconv("To"), :size => 12).should == 13.332 - @times.width_of(@iconv.iconv("To"), :size => 12, :kerning => true).should == 12.372 - @times.width_of(@iconv.iconv("Tö"), :size => 12, :kerning => true).should == 12.372 + @times.compute_width_of(@iconv.iconv("To"), :size => 12).should == 13.332 + @times.compute_width_of(@iconv.iconv("To"), :size => 12, :kerning => true).should == 12.372 + @times.compute_width_of(@iconv.iconv("Tö"), :size => 12, :kerning => true).should == 12.372 end it "should encode text without kerning by default" do @@ -168,12 +168,12 @@ def page_should_not_include_font(font) end it "should calculate string width taking into account accented characters" do - @activa.width_of("é", :size => 12).should == @activa.width_of("e", :size => 12) + @activa.compute_width_of("é", :size => 12).should == @activa.compute_width_of("e", :size => 12) end it "should calculate string width taking into account kerning pairs" do - @activa.width_of("To", :size => 12).should == 15.228 - @activa.width_of("To", :size => 12, :kerning => true).should == 12.996 + @activa.compute_width_of("To", :size => 12).should == 15.228 + @activa.compute_width_of("To", :size => 12, :kerning => true).should == 12.996 end it "should encode text without kerning by default" do