spec/font_spec.rb in prawn-0.3.0 vs spec/font_spec.rb in prawn-0.4.0

- old
+ new

@@ -1,48 +1,17 @@ # encoding: utf-8 require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper") +require 'iconv' -describe "Font Metrics" do +describe "Font behavior" do it "should default to Helvetica if no font is specified" do @pdf = Prawn::Document.new - @pdf.font.metrics.should == Prawn::Font::Metrics["Helvetica"] + @pdf.font.name.should == "Helvetica" end - it "should use the currently set font for font_metrics" do - @pdf = Prawn::Document.new - @pdf.font "Courier" - @pdf.font.metrics.should == Prawn::Font::Metrics["Courier"] - - comicsans = "#{Prawn::BASEDIR}/data/fonts/comicsans.ttf" - @pdf.font(comicsans) - @pdf.font.metrics.should == Prawn::Font::Metrics[comicsans] - end - - it "should wrap text" do - @pdf = Prawn::Document.new - @pdf.font "Courier" - @pdf.font.metrics.naive_wrap("Please wrap this text about HERE. More text that should be wrapped", 220, @pdf.font.size).should == - "Please wrap this text about\nHERE. More text that should be\nwrapped" - end - - it "should respect end of line when wrapping text" do - @pdf = Prawn::Document.new - @pdf.font "Courier" - text = "Please wrap only before\nTHIS word. Don't wrap this" - @pdf.font.metrics.naive_wrap(text, 220, @pdf.font.size).should == text - end - - it "should respect end of line when wrapping text and mode is set to 'character'" do - @pdf = Prawn::Document.new - @pdf.font "Courier" - opts = {:mode => :character} - @pdf.font.metrics.naive_wrap("You can wrap this text HERE", 180, @pdf.font.size, opts).should == - "You can wrap this text HE\nRE" - end - end describe "font style support" do before(:each) { create_pdf } @@ -64,64 +33,85 @@ text = PDF::Inspector::Text.analyze(@pdf.render) text.font_settings.map { |e| e[:name] }.should == [:"Courier-Bold", :"Courier-BoldOblique", :"Courier-Oblique", :Courier, :Helvetica] - end - + end + + it "should allow font familes to be defined in a single dfont" do + file = "#{Prawn::BASEDIR}/data/fonts/Action Man.dfont" + @pdf.font_families["Action Man"] = { + :normal => { :file => file, :font => "ActionMan" }, + :italic => { :file => file, :font => "ActionMan-Italic" }, + :bold => { :file => file, :font => "ActionMan-Bold" }, + :bold_italic => { :file => file, :font => "ActionMan-BoldItalic" } + } + + @pdf.font "Action Man", :style => :italic + @pdf.text "In ActionMan-Italic" + + text = PDF::Inspector::Text.analyze(@pdf.render) + name = text.font_settings.map { |e| e[:name] }.first + name = name.unpack("n*")[2..-1].pack("U*") + name = name.sub(/\w+\+/, "subset+") + name.should == "subset+ActionMan-Italic" + end end describe "Transactional font handling" do before(:each) { create_pdf } it "should allow setting of size directly when font is created" do @pdf.font "Courier", :size => 16 - @pdf.font.size.should == 16 + @pdf.font_size.should == 16 end it "should allow temporary setting of a new font using a transaction" do - original = @pdf.font + @pdf.font "Helvetica", :size => 12 @pdf.font "Courier", :size => 16 do @pdf.font.name.should == "Courier" - @pdf.font.size.should == 16 + @pdf.font_size.should == 16 end - @pdf.font.should == original + @pdf.font.name.should == "Helvetica" + @pdf.font_size.should == 12 end + + it "should mask font size when using a transacation" do + @pdf.font "Courier", :size => 16 do + @pdf.font_size.should == 16 + end + + @pdf.font "Times-Roman" + @pdf.font "Courier" + + @pdf.font_size.should == 12 + end end - describe "Document#page_fonts" do before(:each) { create_pdf } - it "should register the current font when changing pages" do - @pdf.font "Courier" - page_should_include_font("Courier") - @pdf.start_new_page - page_should_include_font("Courier") - end - it "should register fonts properly by page" do - @pdf.font "Courier" - @pdf.font "Helvetica" - @pdf.font "Times-Roman" + @pdf.font "Courier"; @pdf.text("hello") + @pdf.font "Helvetica"; @pdf.text("hello") + @pdf.font "Times-Roman"; @pdf.text("hello") ["Courier","Helvetica","Times-Roman"].each { |f| page_should_include_font(f) } @pdf.start_new_page - @pdf.font "Helvetica" - ["Times-Roman","Helvetica"].each { |f| - page_should_include_font(f) - } - page_should_not_include_font("Courier") + @pdf.font "Helvetica"; @pdf.text("hello") + page_should_include_font("Helvetica") + page_should_not_include_font("Courier") + page_should_not_include_font("Times-Roman") end - def page_includes_font?(font) - @pdf.page_fonts.values.map { |e| e.data[:BaseFont] }.include?(font.to_sym) + def page_includes_font?(font) + @pdf.page_fonts.values.map { |e| e.data[:BaseFont] }.include?(font.to_sym) end def page_should_include_font(font) assert_block("Expected page to include font: #{font}") do page_includes_font?(font) @@ -134,8 +124,111 @@ end end end - - - \ No newline at end of file +describe "AFM fonts" do + + setup do + create_pdf + @times = @pdf.find_font "Times-Roman" + @iconv = ::Iconv.new('Windows-1252', 'utf-8') + 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) + 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 + end + + it "should encode text without kerning by default" do + @times.encode_text(@iconv.iconv("To")).should == [[0, "To"]] + @times.encode_text(@iconv.iconv("Télé")).should == [[0, @iconv.iconv("Télé")]] + @times.encode_text(@iconv.iconv("Technology")).should == [[0, "Technology"]] + @times.encode_text(@iconv.iconv("Technology...")).should == [[0, "Technology..."]] + end + + it "should encode text with kerning if requested" do + @times.encode_text(@iconv.iconv("To"), :kerning => true).should == [[0, ["T", 80, "o"]]] + @times.encode_text(@iconv.iconv("Télé"), :kerning => true).should == [[0, ["T", 70, @iconv.iconv("élé")]]] + @times.encode_text(@iconv.iconv("Technology"), :kerning => true).should == [[0, ["T", 70, "echnology"]]] + @times.encode_text(@iconv.iconv("Technology..."), :kerning => true).should == [[0, ["T", 70, "echnology", 65, "..."]]] + end + +end + +describe "TTF fonts" do + + setup do + create_pdf + @activa = @pdf.find_font "#{Prawn::BASEDIR}/data/fonts/Activa.ttf" + end + + it "should calculate string width taking into account accented characters" do + @activa.width_of("é", :size => 12).should == @activa.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 + end + + it "should encode text without kerning by default" do + @activa.encode_text("To").should == [[0, "To"]] + @activa.encode_text("Télé").should == [[0, "T\216l\216"]] + @activa.encode_text("Technology").should == [[0, "Technology"]] + @activa.encode_text("Technology...").should == [[0, "Technology..."]] + @activa.encode_text("Teχnology...").should == [[0, "Te"], [1, "!"], [0, "nology..."]] + end + + it "should encode text with kerning if requested" do + @activa.encode_text("To", :kerning => true).should == [[0, ["T", 186.0, "o"]]] + @activa.encode_text("To", :kerning => true).should == [[0, ["T", 186.0, "o"]]] + @activa.encode_text("Technology", :kerning => true).should == [[0, ["T", 186.0, "echnology"]]] + @activa.encode_text("Technology...", :kerning => true).should == [[0, ["T", 186.0, "echnology", 88.0, "..."]]] + @activa.encode_text("Teχnology...", :kerning => true).should == [[0, ["T", 186.0, "e"]], [1, "!"], [0, ["nology", 88.0, "..."]]] + end + +end + +describe "DFont fonts" do + setup do + create_pdf + @file = "#{Prawn::BASEDIR}/data/fonts/Action Man.dfont" + end + + it "should list all named fonts" do + list = Prawn::Font::DFont.named_fonts(@file) + list.sort.should == %w(ActionMan ActionMan-Italic ActionMan-Bold ActionMan-BoldItalic).sort + end + + it "should count the number of fonts in the file" do + Prawn::Font::DFont.font_count(@file).should == 4 + end + + it "should default selected font to the first one if not specified" do + font = @pdf.find_font(@file) + font.basename.should == "ActionMan" + end + + it "should allow font to be selected by index" do + font = @pdf.find_font(@file, :font => 2) + font.basename.should == "ActionMan-Italic" + end + + it "should allow font to be selected by name" do + font = @pdf.find_font(@file, :font => "ActionMan-BoldItalic") + font.basename.should == "ActionMan-BoldItalic" + end + + it "should cache font object based on selected font" do + f1 = @pdf.find_font(@file, :font => "ActionMan") + f2 = @pdf.find_font(@file, :font => "ActionMan-Bold") + assert_not_equal f1.object_id, f2.object_id + assert_equal f1.object_id, @pdf.find_font(@file, :font => "ActionMan").object_id + assert_equal f2.object_id, @pdf.find_font(@file, :font => "ActionMan-Bold").object_id + end +end