Skip to content

Commit

Permalink
move width_of to Document
Browse files Browse the repository at this point in the history
This will make it easier for extensions libs to extend the
width_of calculation (*cough* prawn-format *cough*).
  • Loading branch information
jamis committed Jan 28, 2009
1 parent 788fed2 commit 78df46f
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 26 deletions.
4 changes: 2 additions & 2 deletions examples/m17n/win_ansi_charset.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/prawn/document/text.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/prawn/document/text/wrapping.rb
Expand Up @@ -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")}"
Expand Down
36 changes: 23 additions & 13 deletions lib/prawn/font.rb
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion lib/prawn/font/afm.rb
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion lib/prawn/font/ttf.rb
Expand Up @@ -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|
Expand Down
14 changes: 7 additions & 7 deletions spec/font_spec.rb
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 78df46f

Please sign in to comment.