ruby-prawn-1.0.0~rc2.orig/ 0000755 0000000 0000000 00000000000 12114176157 014065 5 ustar root root ruby-prawn-1.0.0~rc2.orig/spec/ 0000755 0000000 0000000 00000000000 12114176157 015017 5 ustar root root ruby-prawn-1.0.0~rc2.orig/spec/outline_spec.rb 0000644 0000000 0000000 00000032153 12114176157 020041 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Outline" do
before(:each) do
@pdf = Prawn::Document.new() do
text "Page 1. This is the first Chapter. "
start_new_page
text "Page 2. More in the first Chapter. "
start_new_page
outline.define do
section 'Chapter 1', :destination => 1, :closed => true do
page :destination => 1, :title => 'Page 1'
page :destination => 2, :title => 'Page 2'
end
end
end
end
if RUBY_VERSION >= "1.9"
describe "outline encoding" do
it "should store all outline titles as UTF-16" do
render_and_find_objects
@hash.values.each do |obj|
if obj.is_a?(Hash) && obj[:Title]
title = obj[:Title].dup
title.force_encoding("UTF-16LE")
title.valid_encoding?.should == true
end
end
end
end
end
describe "#generate_outline" do
before(:each) do
render_and_find_objects
end
it "should create a root outline dictionary item" do
@outline_root.should_not be_nil
end
it "should set the first and last top items of the root outline dictionary item" do
referenced_object(@outline_root[:First]).should == @section_1
referenced_object(@outline_root[:Last]).should == @section_1
end
describe "#create_outline_item" do
it "should create outline items for each section and page" do
[@section_1, @page_1, @page_2].each {|item| item.should_not be_nil}
end
end
describe "#set_relations, #set_variables_for_block, and #reset_parent" do
it "should link sibling items" do
referenced_object(@page_1[:Next]).should == @page_2
referenced_object(@page_2[:Prev]).should == @page_1
end
it "should link child items to parent item" do
[@page_1, @page_2].each {|page| referenced_object(page[:Parent]).should == @section_1 }
end
it "should set the first and last child items for parent item" do
referenced_object(@section_1[:First]).should == @page_1
referenced_object(@section_1[:Last]).should == @page_2
end
end
describe "#increase_count" do
it "should add the count of all descendant items" do
@outline_root[:Count].should == 3
@section_1[:Count].abs.should == 2
@page_1[:Count].should == 0
@page_2[:Count].should == 0
end
end
describe "closed option" do
it "should set the item's integer count to negative" do
@section_1[:Count].should == -2
end
end
end
describe "addding a section later with outline#section" do
before(:each) do
@pdf.start_new_page
@pdf.text "Page 3. An added section "
@pdf.outline.update do
section 'Added Section', :destination => 3 do
page :destination => 3, :title => 'Page 3'
end
end
render_and_find_objects
end
it "should add new outline items to document" do
[@section_2, @page_3].each { |item| item.should_not be_nil}
end
it "should reset the last items for root outline dictionary" do
referenced_object(@outline_root[:First]).should == @section_1
referenced_object(@outline_root[:Last]).should == @section_2
end
it "should reset the next relation for the previous last top level item" do
referenced_object(@section_1[:Next]).should == @section_2
end
it "should set the previous relation of the addded to section" do
referenced_object(@section_2[:Prev]).should == @section_1
end
it "should increase the count of root outline dictionary" do
@outline_root[:Count].should == 5
end
end
describe "#outline.add_subsection_to" do
context "positioned last" do
before(:each) do
@pdf.start_new_page
@pdf.text "Page 3. An added subsection "
@pdf.outline.update do
add_subsection_to 'Chapter 1' do
section 'Added SubSection', :destination => 3 do
page :destination => 3, :title => 'Added Page 3'
end
end
end
render_and_find_objects
end
it "should add new outline items to document" do
[@subsection, @added_page_3].each { |item| item.should_not be_nil}
end
it "should reset the last item for parent item dictionary" do
referenced_object(@section_1[:First]).should == @page_1
referenced_object(@section_1[:Last]).should == @subsection
end
it "should set the prev relation for the new subsection to its parent's old last item" do
referenced_object(@subsection[:Prev]).should == @page_2
end
it "the subsection should become the next relation for its parent's old last item" do
referenced_object(@page_2[:Next]).should == @subsection
end
it "should set the first relation for the new subsection" do
referenced_object(@subsection[:First]).should == @added_page_3
end
it "should set the correct last relation of the added to section" do
referenced_object(@subsection[:Last]).should == @added_page_3
end
it "should increase the count of root outline dictionary" do
@outline_root[:Count].should == 5
end
end
context "positioned first" do
before(:each) do
@pdf.start_new_page
@pdf.text "Page 3. An added subsection "
@pdf.outline.update do
add_subsection_to 'Chapter 1', :first do
section 'Added SubSection', :destination => 3 do
page :destination => 3, :title => 'Added Page 3'
end
end
end
render_and_find_objects
end
it "should add new outline items to document" do
[@subsection, @added_page_3].each { |item| item.should_not be_nil}
end
it "should reset the first item for parent item dictionary" do
referenced_object(@section_1[:First]).should == @subsection
referenced_object(@section_1[:Last]).should == @page_2
end
it "should set the next relation for the new subsection to its parent's old first item" do
referenced_object(@subsection[:Next]).should == @page_1
end
it "the subsection should become the prev relation for its parent's old first item" do
referenced_object(@page_1[:Prev]).should == @subsection
end
it "should set the first relation for the new subsection" do
referenced_object(@subsection[:First]).should == @added_page_3
end
it "should set the correct last relation of the added to section" do
referenced_object(@subsection[:Last]).should == @added_page_3
end
it "should increase the count of root outline dictionary" do
@outline_root[:Count].should == 5
end
end
it "should require an existing title" do
lambda do
@pdf.go_to_page 1
@pdf.start_new_page
@pdf.text "Inserted Page"
@pdf.outline.update do
add_subsection_to 'Wrong page' do
page page_number, :title => "Inserted Page"
end
end
render_and_find_objects
end.should raise_error(Prawn::Errors::UnknownOutlineTitle)
end
end
describe "#outline.insert_section_after" do
describe "inserting in the middle of another section" do
before(:each) do
@pdf.go_to_page 1
@pdf.start_new_page
@pdf.text "Inserted Page"
@pdf.outline.update do
insert_section_after 'Page 1' do
page :destination => page_number, :title => "Inserted Page"
end
end
end
it "should insert new outline items to document" do
render_and_find_objects
@inserted_page.should_not be_nil
end
it "should adjust the count of all ancestors" do
render_and_find_objects
@outline_root[:Count].should == 4
@section_1[:Count].abs.should == 3
end
describe "#adjust_relations" do
it "should reset the sibling relations of adjoining items to inserted item" do
render_and_find_objects
referenced_object(@page_1[:Next]).should == @inserted_page
referenced_object(@page_2[:Prev]).should == @inserted_page
end
it "should set the sibling relation of added item to adjoining items" do
render_and_find_objects
referenced_object(@inserted_page[:Next]).should == @page_2
referenced_object(@inserted_page[:Prev]).should == @page_1
end
it "should not affect the first and last relations of parent item" do
render_and_find_objects
referenced_object(@section_1[:First]).should == @page_1
referenced_object(@section_1[:Last]).should == @page_2
end
end
context "when adding another section afterwards" do
it "should have reset the root position so that a new section is added at the end of root sections" do
@pdf.start_new_page
@pdf.text "Another Inserted Page"
@pdf.outline.update do
section 'Added Section' do
page :destination => page_number, :title => "Inserted Page"
end
end
render_and_find_objects
referenced_object(@outline_root[:Last]).should == @section_2
referenced_object(@section_1[:Next]).should == @section_2
end
end
end
describe "inserting at the end of another section" do
before(:each) do
@pdf.go_to_page 2
@pdf.start_new_page
@pdf.text "Inserted Page"
@pdf.outline.update do
insert_section_after 'Page 2' do
page :destination => page_number, :title => "Inserted Page"
end
end
render_and_find_objects
end
describe "#adjust_relations" do
it "should reset the sibling relations of adjoining item to inserted item" do
referenced_object(@page_2[:Next]).should == @inserted_page
end
it "should set the sibling relation of added item to adjoining items" do
referenced_object(@inserted_page[:Next]).should be_nil
referenced_object(@inserted_page[:Prev]).should == @page_2
end
it "should adjust the last relation of parent item" do
referenced_object(@section_1[:Last]).should == @inserted_page
end
end
end
it "should require an existing title" do
lambda do
@pdf.go_to_page 1
@pdf.start_new_page
@pdf.text "Inserted Page"
@pdf.outline.update do
insert_section_after 'Wrong page' do
page :destination => page_number, :title => "Inserted Page"
end
end
render_and_find_objects
end.should raise_error(Prawn::Errors::UnknownOutlineTitle)
end
end
describe "#page" do
it "should require a title option to be set" do
lambda do
@pdf = Prawn::Document.new() do
text "Page 1. This is the first Chapter. "
outline.define do
page :destination => 1, :title => nil
end
end
end.should raise_error(Prawn::Errors::RequiredOption)
end
end
end
describe "foreign character encoding" do
before(:each) do
pdf = Prawn::Document.new() do
outline.define do
section 'La pomme croquée', :destination => 1, :closed => true
end
end
@hash = PDF::Reader::ObjectHash.new(StringIO.new(pdf.render, 'r+'))
end
it "should handle other encodings for the title" do
object = find_by_title('La pomme croquée')
object.should_not == nil
end
end
describe "with optimize_objects option" do
before(:each) do
@pdf = Prawn::Document.new(:optimize_objects => true) do
outline.define do
section 'Chapter 1', :destination => 1, :closed => true do
page :destination => 1, :title => 'Page 1'
end
end
end
render_and_find_objects
end
it "should generate an outline" do
@section_1.should_not be_nil
@page_1.should_not be_nil
end
end
def render_and_find_objects
output = StringIO.new(@pdf.render, 'r+')
@hash = PDF::Reader::ObjectHash.new(output)
@outline_root = @hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Outlines}
@pages = @hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Pages}[:Kids]
@section_1 = find_by_title('Chapter 1')
@page_1 = find_by_title('Page 1')
@page_2 = find_by_title('Page 2')
@section_2 = find_by_title('Added Section')
@page_3 = find_by_title('Page 3')
@inserted_page = find_by_title('Inserted Page')
@subsection = find_by_title('Added SubSection')
@added_page_3 = find_by_title('Added Page 3')
end
# Outline titles are stored as UTF-16. This method accepts a UTF-8 outline title
# and returns the PDF Object that contains an outline with that name
def find_by_title(title)
@hash.values.find {|obj|
if obj.is_a?(Hash) && obj[:Title]
title_codepoints = obj[:Title].unpack("n*")
title_codepoints.shift
utf8_title = title_codepoints.pack("U*")
utf8_title == title ? obj : nil
end
}
end
def referenced_object(reference)
@hash[reference]
end
ruby-prawn-1.0.0~rc2.orig/spec/formatted_text_box_spec.rb 0000644 0000000 0000000 00000057614 12114176157 022274 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Text::Formatted::Box wrapping" do
before(:each) do
create_pdf
end
it "should not wrap between two fragments" do
texts = [
{:text => "Hello "},
{:text => "World"},
{:text => "2", :styles => [:superscript]},
]
text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
text_box.render
text_box.text.should == "Hello\nWorld2"
end
it "should_not raise_error Encoding::CompatibilityError when keeping a TTF and an " +
"AFM font together" do
ruby_19 do
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
@pdf.font_families["Kai"] = {
:normal => { :file => file, :font => "Kai" }
}
texts = [{ :text => "Hello " },
{ :text => "再见", :font => "Kai"},
{ :text => "World" }]
text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
lambda {
text_box.render
}.should_not raise_error(Encoding::CompatibilityError)
end
end
it "should wrap between two fragments when the preceding fragment ends with white space" do
texts = [
{:text => "Hello "},
{:text => "World "},
{:text => "2", :styles => [:superscript]},
]
text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
text_box.render
text_box.text.should == "Hello World\n2"
texts = [
{:text => "Hello "},
{:text => "World\n"},
{:text => "2", :styles => [:superscript]},
]
text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
text_box.render
text_box.text.should == "Hello World\n2"
end
it "should wrap between two fragments when the final fragment begins with white space" do
texts = [
{:text => "Hello "},
{:text => "World"},
{:text => " 2", :styles => [:superscript]},
]
text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
text_box.render
text_box.text.should == "Hello World\n2"
texts = [
{:text => "Hello "},
{:text => "World"},
{:text => "\n2", :styles => [:superscript]},
]
text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
text_box.render
text_box.text.should == "Hello World\n2"
end
it "should properly handle empty slices using default encoding" do
texts = [{ :text => "Noua Delineatio Geographica generalis | Apostolicarum peregrinationum | S FRANCISCI XAUERII | Indiarum & Iaponiæ Apostoli", :font => 'Courier', :size => 10 }]
text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Noua Delineatio Geographica gen"))
lambda {
text_box.render
}.should_not raise_error
text_box.text.should == "Noua Delineatio Geographica\ngeneralis | Apostolicarum\nperegrinationum | S FRANCISCI\nXAUERII | Indiarum & Iaponi\346\nApostoli"
end
describe "Unicode" do
before do
if RUBY_VERSION < '1.9'
@reset_value = $KCODE
$KCODE='u'
else
@reset_value = [Encoding.default_external, Encoding.default_internal]
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
end
end
after do
if RUBY_VERSION < '1.9'
$KCODE=@reset_value
else
Encoding.default_external = @reset_value[0]
Encoding.default_internal = @reset_value[1]
end
end
it "should properly handle empty slices using Unicode encoding" do
texts = [{ :text => "Noua Delineatio Geographica generalis | Apostolicarum peregrinationum | S FRANCISCI XAUERII | Indiarum & Iaponiæ Apostoli", :font => 'Courier', :size => 10 }]
text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Noua Delineatio Geographica gen"))
lambda {
text_box.render
}.should_not raise_error
text_box.text.should == "Noua Delineatio Geographica\ngeneralis | Apostolicarum\nperegrinationum | S FRANCISCI\nXAUERII | Indiarum & Iaponi\346\nApostoli"
end
end
end
describe "Text::Formatted::Box with :fallback_fonts option that includes" +
"a Chinese font and set of Chinese glyphs not in the current font" do
it "should change the font to the Chinese font for the Chinese glyphs" do
create_pdf
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
@pdf.font_families["Kai"] = {
:normal => { :file => file, :font => "Kai" }
}
formatted_text = [{ :text => "hello你好" },
{ :text => "再见goodbye" }]
@pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Kai"])
text = PDF::Inspector::Text.analyze(@pdf.render)
fonts_used = text.font_settings.map { |e| e[:name] }
fonts_used.length.should == 4
fonts_used[0].should == :"Helvetica"
fonts_used[1].to_s.should =~ /GBZenKai-Medium/
fonts_used[2].to_s.should =~ /GBZenKai-Medium/
fonts_used[3].should == :"Helvetica"
text.strings[0].should == "hello"
text.strings[1].should == "你好"
text.strings[2].should == "再见"
text.strings[3].should == "goodbye"
end
end
describe "Text::Formatted::Box with :fallback_fonts option that includes" +
"an AFM font and Win-Ansi glyph not in the current Chinese font" do
it "should change the font to the AFM font for the Win-Ansi glyph" do
create_pdf
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
@pdf.font_families["Kai"] = {
:normal => { :file => file, :font => "Kai" }
}
@pdf.font("Kai")
formatted_text = [{ :text => "hello你好" },
{ :text => "再见€" }]
@pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Helvetica"])
text = PDF::Inspector::Text.analyze(@pdf.render)
fonts_used = text.font_settings.map { |e| e[:name] }
fonts_used.length.should == 4
fonts_used[0].to_s.should =~ /GBZenKai-Medium/
fonts_used[1].to_s.should =~ /GBZenKai-Medium/
fonts_used[2].to_s.should =~ /GBZenKai-Medium/
fonts_used[3].should == :"Helvetica"
text.strings[0].should == "hello"
text.strings[1].should == "你好"
text.strings[2].should == "再见"
text.strings[3].should == "€"
end
end
describe "Text::Formatted::Box with :fallback_fonts option and fragment " +
"level font" do
it "should use the fragment level font except for glyphs not in that font" do
create_pdf
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
@pdf.font_families["Kai"] = {
:normal => { :file => file, :font => "Kai" }
}
formatted_text = [{ :text => "hello你好" },
{ :text => "再见goodbye", :font => "Times-Roman" }]
@pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Kai"])
text = PDF::Inspector::Text.analyze(@pdf.render)
fonts_used = text.font_settings.map { |e| e[:name] }
fonts_used.length.should == 4
fonts_used[0].should == :"Helvetica"
fonts_used[1].to_s.should =~ /GBZenKai-Medium/
fonts_used[2].to_s.should =~ /GBZenKai-Medium/
fonts_used[3].should == :"Times-Roman"
text.strings[0].should == "hello"
text.strings[1].should == "你好"
text.strings[2].should == "再见"
text.strings[3].should == "goodbye"
end
end
describe "Text::Formatted::Box" do
before(:each) do
create_pdf
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
@pdf.font_families["Kai"] = {
:normal => { :file => file, :font => "Kai" }
}
@formatted_text = [{ :text => "hello你好" }]
@pdf.fallback_fonts(["Kai"])
@pdf.fallback_fonts = ["Kai"]
end
it "#fallback_fonts should return the document-wide fallback fonts" do
@pdf.fallback_fonts.should == ["Kai"]
end
it "should be able to set text fallback_fonts document-wide" do
@pdf.formatted_text_box(@formatted_text)
text = PDF::Inspector::Text.analyze(@pdf.render)
fonts_used = text.font_settings.map { |e| e[:name] }
fonts_used.length.should == 2
fonts_used[0].should == :"Helvetica"
fonts_used[1].to_s.should =~ /GBZenKai-Medium/
end
it "should be able to override document-wide fallback_fonts" do
@pdf.formatted_text_box(@formatted_text, :fallback_fonts => ["Courier"])
text = PDF::Inspector::Text.analyze(@pdf.render)
fonts_used = text.font_settings.map { |e| e[:name] }
fonts_used.length.should == 1
fonts_used[0].should == :"Helvetica"
end
it "should omit the fallback fonts overhead when passing an empty array " +
"as the :fallback_fonts" do
box = Prawn::Text::Formatted::Box.new(@formatted_text,
:document => @pdf,
:fallback_fonts => [])
box.expects(:process_fallback_fonts).never
box.render
end
it "should be able to clear document-wide fallback_fonts" do
@pdf.fallback_fonts([])
box = Prawn::Text::Formatted::Box.new(@formatted_text,
:document => @pdf)
box.expects(:process_fallback_fonts).never
box.render
end
end
describe "Text::Formatted::Box with :fallback_fonts option " +
"with glyphs not in the primary or the fallback fonts" do
it "should use the primary font" do
create_pdf
formatted_text = [{ :text => "hello world. 世界你好。" }]
@pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Helvetica"])
text = PDF::Inspector::Text.analyze(@pdf.render)
fonts_used = text.font_settings.map { |e| e[:name] }
fonts_used.length.should == 1
fonts_used[0].should == :"Helvetica"
end
end
describe "Text::Formatted::Box#extensions" do
it "should be able to override default line wrapping" do
create_pdf
Prawn::Text::Formatted::Box.extensions << TestFormattedWrapOverride
@pdf.formatted_text_box([{ :text => "hello world" }], {})
Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == "all your base are belong to us"
end
it "overriding Text::Formatted::Box line wrapping should not affect " +
"Text::Box wrapping" do
create_pdf
Prawn::Text::Formatted::Box.extensions << TestFormattedWrapOverride
@pdf.text_box("hello world", {})
Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == "hello world"
end
it "overriding Text::Box line wrapping should override Text::Box wrapping" do
create_pdf
Prawn::Text::Box.extensions << TestFormattedWrapOverride
@pdf.text_box("hello world", {})
Prawn::Text::Box.extensions.delete(TestFormattedWrapOverride)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == "all your base are belong to us"
end
end
describe "Text::Formatted::Box#render" do
it "should handle newlines" do
create_pdf
array = [{ :text => "hello\nworld"}]
options = { :document => @pdf }
text_box = Prawn::Text::Formatted::Box.new(array, options)
text_box.render
text_box.text.should == "hello\nworld"
end
it "should omit spaces from the beginning of the line" do
create_pdf
array = [{ :text => " hello\n world"}]
options = { :document => @pdf }
text_box = Prawn::Text::Formatted::Box.new(array, options)
text_box.render
text_box.text.should == "hello\nworld"
end
it "should be okay printing a line of whitespace" do
create_pdf
array = [{ :text => "hello\n \nworld"}]
options = { :document => @pdf }
text_box = Prawn::Text::Formatted::Box.new(array, options)
text_box.render
text_box.text.should == "hello\n\nworld"
array = [{ :text => "hello" + " " * 500},
{ :text => " " * 500 },
{ :text => " " * 500 + "\n"},
{ :text => "world"}]
options = { :document => @pdf }
text_box = Prawn::Text::Formatted::Box.new(array, options)
text_box.render
text_box.text.should == "hello\n\nworld"
end
it "should enable fragment level direction setting" do
create_pdf
number_of_hellos = 18
array = [
{ :text => "hello " * number_of_hellos },
{ :text => "world", :direction => :ltr },
{ :text => ", how are you?" }
]
options = { :document => @pdf, :direction => :rtl }
text_box = Prawn::Text::Formatted::Box.new(array, options)
text_box.render
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == "era woh ,"
text.strings[1].should == "world"
text.strings[2].should == " olleh" * number_of_hellos
text.strings[3].should == "?uoy"
end
end
describe "Text::Formatted::Box#render" do
it "should be able to perform fragment callbacks" do
create_pdf
callback_object = TestFragmentCallback.new("something", 7,
:document => @pdf)
callback_object.expects(:render_behind).with(
kind_of(Prawn::Text::Formatted::Fragment))
callback_object.expects(:render_in_front).with(
kind_of(Prawn::Text::Formatted::Fragment))
array = [{ :text => "hello world " },
{ :text => "callback now",
:callback => callback_object }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
end
it "should be able to perform fragment callbacks on multiple objects" do
create_pdf
callback_object = TestFragmentCallback.new("something", 7,
:document => @pdf)
callback_object.expects(:render_behind).with(
kind_of(Prawn::Text::Formatted::Fragment))
callback_object.expects(:render_in_front).with(
kind_of(Prawn::Text::Formatted::Fragment))
callback_object2 = TestFragmentCallback.new("something else", 14,
:document => @pdf)
callback_object2.expects(:render_behind).with(
kind_of(Prawn::Text::Formatted::Fragment))
callback_object2.expects(:render_in_front).with(
kind_of(Prawn::Text::Formatted::Fragment))
array = [{ :text => "hello world " },
{ :text => "callback now",
:callback => [callback_object, callback_object2] }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
end
it "fragment callbacks should be able to define only the callback they need" do
create_pdf
behind = TestFragmentCallbackBehind.new("something", 7,
:document => @pdf)
in_front = TestFragmentCallbackInFront.new("something", 7,
:document => @pdf)
array = [{ :text => "hello world " },
{ :text => "callback now",
:callback => [behind, in_front] }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
lambda { text_box.render }.should_not raise_error(NoMethodError)
end
it "should be able to set the font" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "Times-Bold",
:styles => [:bold],
:font => "Times-Roman" },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
fonts = contents.font_settings.map { |e| e[:name] }
fonts.should == [:Helvetica, :"Times-Bold", :Helvetica]
contents.strings[0].should == "this contains "
contents.strings[1].should == "Times-Bold"
contents.strings[2].should == " text"
end
it "should be able to set bold" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "bold", :styles => [:bold] },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
fonts = contents.font_settings.map { |e| e[:name] }
fonts.should == [:Helvetica, :"Helvetica-Bold", :Helvetica]
contents.strings[0].should == "this contains "
contents.strings[1].should == "bold"
contents.strings[2].should == " text"
end
it "should be able to set italics" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "italic", :styles => [:italic] },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
fonts = contents.font_settings.map { |e| e[:name] }
fonts.should == [:Helvetica, :"Helvetica-Oblique", :Helvetica]
end
it "should be able to set subscript" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "subscript", :size => 18, :styles => [:subscript] },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.font_settings[0][:size].should == 12
contents.font_settings[1][:size].should be_within(0.0001).of(18 * 0.583)
end
it "should be able to set superscript" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "superscript", :size => 18, :styles => [:superscript] },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.font_settings[0][:size].should == 12
contents.font_settings[1][:size].should be_within(0.0001).of(18 * 0.583)
end
it "should be able to set compound bold and italic text" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "bold italic", :styles => [:bold, :italic] },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
fonts = contents.font_settings.map { |e| e[:name] }
fonts.should == [:Helvetica, :"Helvetica-BoldOblique", :Helvetica]
end
it "should be able to underline" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "underlined", :styles => [:underline] },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line_drawing.points.length.should == 2
end
it "should be able to strikethrough" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "struckthrough", :styles => [:strikethrough] },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line_drawing.points.length.should == 2
end
it "should be able to add URL links" do
create_pdf
@pdf.expects(:link_annotation).with(kind_of(Array), :Border => [0,0,0],
:A => { :Type => :Action, :S => :URI, :URI => "http://example.com" })
array = [{ :text => "click " },
{ :text => "here", :link => "http://example.com" },
{ :text => " to visit" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
end
it "should be able to add destination links" do
create_pdf
@pdf.expects(:link_annotation).with(kind_of(Array), :Border => [0,0,0],
:Dest => "ToC")
array = [{ :text => "Go to the " },
{ :text => "Table of Contents", :anchor => "ToC" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
end
it "should be able to set font size" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "sized", :size => 24 },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.font_settings[0][:size].should == 12
contents.font_settings[1][:size].should == 24
end
it "should set the baseline based on the tallest fragment on a given line" do
create_pdf
array = [{ :text => "this contains " },
{ :text => "sized", :size => 24 },
{ :text => " text" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
@pdf.font_size(24) do
text_box.height.should be_within(0.001).of(@pdf.font.ascender + @pdf.font.descender)
end
end
it "should be able to set color via an rgb hex string" do
create_pdf
array = [{ :text => "rgb",
:color => "ff0000" }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
colors.fill_color_count.should == 2
colors.stroke_color_count.should == 2
end
it "should be able to set color using a cmyk array" do
create_pdf
array = [{ :text => "cmyk",
:color => [100, 0, 0, 0] }]
text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
text_box.render
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
colors.fill_color_count.should == 2
colors.stroke_color_count.should == 2
end
end
describe "Text::Formatted::Box#render with fragment level :character_spacing option" do
it "should draw the character spacing to the document" do
create_pdf
array = [{ :text => "hello world",
:character_spacing => 7 }]
options = { :document => @pdf }
text_box = Prawn::Text::Formatted::Box.new(array, options)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.character_spacing[0].should == 7
end
it "should draw the character spacing to the document" do
create_pdf
array = [{ :text => "hello world",
:font => "Courier",
:character_spacing => 10 }]
options = { :document => @pdf,
:width => 100,
:overflow => :expand }
text_box = Prawn::Text::Formatted::Box.new(array, options)
text_box.render
text_box.text.should == "hello\nworld"
end
end
describe "Text::Formatted::Box#render with :align => :justify" do
it "should not justify the last line of a paragraph" do
create_pdf
array = [{ :text => "hello world " },
{ :text => "\n" },
{ :text => "goodbye" }]
options = { :document => @pdf, :align => :justify }
text_box = Prawn::Text::Formatted::Box.new(array, options)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.word_spacing.should be_empty
end
end
class TestFragmentCallback
def initialize(string, number, options)
@document = options[:document]
end
def render_behind(fragment)
end
def render_in_front(fragment)
end
end
class TestFragmentCallbackBehind
def initialize(string, number, options)
@document = options[:document]
end
def render_behind(fragment)
end
end
class TestFragmentCallbackInFront
def initialize(string, number, options)
@document = options[:document]
end
def render_in_front(fragment)
end
end
module TestFormattedWrapOverride
def wrap(array)
initialize_wrap([{ :text => 'all your base are belong to us' }])
line_to_print = @line_wrap.wrap_line(:document => @document,
:kerning => @kerning,
:width => 10000,
:arranger => @arranger)
fragment = @arranger.retrieve_fragment
format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
[]
end
end
ruby-prawn-1.0.0~rc2.orig/spec/formatted_text_fragment_spec.rb 0000644 0000000 0000000 00000023401 12114176157 023272 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Text::Formatted::Fragment#space_count" do
it "should return the number of spaces in the fragment" do
create_pdf
format_state = { }
fragment = Prawn::Text::Formatted::Fragment.new("hello world ",
format_state,
@pdf)
fragment.space_count.should == 2
end
it "should exclude trailing spaces from the count when " +
":exclude_trailing_white_space => true" do
create_pdf
format_state = { :exclude_trailing_white_space => true }
fragment = Prawn::Text::Formatted::Fragment.new("hello world ",
format_state,
@pdf)
fragment.space_count.should == 1
end
end
describe "Text::Formatted::Fragment#include_trailing_white_space!" do
it "should make the fragment include trailing white space" do
create_pdf
format_state = { :exclude_trailing_white_space => true }
fragment = Prawn::Text::Formatted::Fragment.new("hello world ",
format_state,
@pdf)
fragment.space_count.should == 1
fragment.include_trailing_white_space!
fragment.space_count.should == 2
end
end
describe "Text::Formatted::Fragment#text" do
it "should return the fragment text" do
create_pdf
format_state = { }
fragment = Prawn::Text::Formatted::Fragment.new("hello world ",
format_state,
@pdf)
fragment.text.should == "hello world "
end
it "should return the fragment text without trailing spaces when " +
":exclude_trailing_white_space => true" do
create_pdf
format_state = { :exclude_trailing_white_space => true }
fragment = Prawn::Text::Formatted::Fragment.new("hello world ",
format_state,
@pdf)
fragment.text.should == "hello world"
end
end
describe "Text::Formatted::Fragment#word_spacing=" do
before(:each) do
create_pdf
format_state = { :styles => [:bold, :italic],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil }
@fragment = Prawn::Text::Formatted::Fragment.new("hello world",
format_state,
@pdf)
@fragment.width = 100
@fragment.left = 50
@fragment.baseline = 200
@fragment.line_height = 27
@fragment.descender = 7
@fragment.ascender = 17
@fragment.word_spacing = 10
end
it "should account for word_spacing in #width" do
@fragment.width.should == 110
end
it "should account for word_spacing in #bounding_box" do
target_box = [50, 193, 160, 217]
@fragment.bounding_box.should == target_box
end
it "should account for word_spacing in #absolute_bounding_box" do
target_box = [50, 193, 160, 217]
target_box[0] += @pdf.bounds.absolute_left
target_box[1] += @pdf.bounds.absolute_bottom
target_box[2] += @pdf.bounds.absolute_left
target_box[3] += @pdf.bounds.absolute_bottom
@fragment.absolute_bounding_box.should == target_box
end
it "should account for word_spacing in #underline_points" do
y = 198.75
target_points = [[50, y], [160, y]]
@fragment.underline_points.should == target_points
end
it "should account for word_spacing in #strikethrough_points" do
y = 200 + @fragment.ascender * 0.3
target_points = [[50, y], [160, y]]
@fragment.strikethrough_points.should == target_points
end
end
describe "Text::Formatted::Fragment" do
before(:each) do
create_pdf
format_state = { :styles => [:bold, :italic],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil }
@fragment = Prawn::Text::Formatted::Fragment.new("hello world",
format_state,
@pdf)
@fragment.width = 100
@fragment.left = 50
@fragment.baseline = 200
@fragment.line_height = 27
@fragment.descender = 7
@fragment.ascender = 17
end
describe "#width" do
it "should return the width" do
@fragment.width.should == 100
end
end
describe "#styles" do
it "should return the styles array" do
@fragment.styles.should == [:bold, :italic]
end
it "should never return nil" do
format_state = { :styles => nil,
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil }
fragment = Prawn::Text::Formatted::Fragment.new("hello world",
format_state,
@pdf)
fragment.styles.should == []
end
end
describe "#line_height" do
it "should return the line_height" do
@fragment.line_height.should == 27
end
end
describe "#ascender" do
it "should return the ascender" do
@fragment.ascender.should == 17
end
end
describe "#descender" do
it "should return the descender" do
@fragment.descender.should == 7
end
end
describe "#y_offset" do
it "should be zero" do
@fragment.y_offset.should == 0
end
end
describe "#bounding_box" do
it "should return the bounding box surrounding the fragment" do
target_box = [50, 193, 150, 217]
@fragment.bounding_box.should == target_box
end
end
describe "#absolute_bounding_box" do
it "should return the bounding box surrounding the fragment" +
" in absolute coordinates" do
target_box = [50, 193, 150, 217]
target_box[0] += @pdf.bounds.absolute_left
target_box[1] += @pdf.bounds.absolute_bottom
target_box[2] += @pdf.bounds.absolute_left
target_box[3] += @pdf.bounds.absolute_bottom
@fragment.absolute_bounding_box.should == target_box
end
end
describe "#underline_points" do
it "should define a line under the fragment" do
y = 198.75
target_points = [[50, y], [150, y]]
@fragment.underline_points.should == target_points
end
end
describe "#strikethrough_points" do
it "should define a line through the fragment" do
y = 200 + @fragment.ascender * 0.3
target_points = [[50, y], [150, y]]
@fragment.strikethrough_points.should == target_points
end
end
end
describe "Text::Formatted::Fragment that is a subscript" do
before(:each) do
create_pdf
format_state = { :styles => [:subscript],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil }
@fragment = Prawn::Text::Formatted::Fragment.new("hello world",
format_state,
@pdf)
@fragment.line_height = 27
@fragment.descender = 7
@fragment.ascender = 17
end
describe "#subscript?" do
it "should be_true" do
@fragment.should be_subscript
end
end
describe "#y_offset" do
it "should return a negative value" do
@fragment.y_offset.should be < 0
end
end
end
describe "Text::Formatted::Fragment that is a superscript" do
before(:each) do
create_pdf
format_state = { :styles => [:superscript],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil }
@fragment = Prawn::Text::Formatted::Fragment.new("hello world",
format_state,
@pdf)
@fragment.line_height = 27
@fragment.descender = 7
@fragment.ascender = 17
end
describe "#superscript?" do
it "should be_true" do
@fragment.should be_superscript
end
end
describe "#y_offset" do
it "should return a positive value" do
@fragment.y_offset.should be > 0
end
end
end
describe "Text::Formatted::Fragment with :direction => :rtl" do
it "#text should be reversed" do
create_pdf
format_state = { :direction => :rtl }
fragment = Prawn::Text::Formatted::Fragment.new("hello world",
format_state,
@pdf)
fragment.text.should == "dlrow olleh"
end
end
describe "Text::Formatted::Fragment default_direction=" do
it "should set the direction if there is no fragment level direction " +
"specification" do
create_pdf
format_state = { }
fragment = Prawn::Text::Formatted::Fragment.new("hello world",
format_state,
@pdf)
fragment.default_direction = :rtl
fragment.direction.should == :rtl
end
it "should not set the direction if there is a fragment level direction " +
"specification" do
create_pdf
format_state = { :direction => :rtl }
fragment = Prawn::Text::Formatted::Fragment.new("hello world",
format_state,
@pdf)
fragment.default_direction = :ltr
fragment.direction.should == :rtl
end
end
ruby-prawn-1.0.0~rc2.orig/spec/annotations_spec.rb 0000644 0000000 0000000 00000004310 12114176157 020711 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
class PageAnnotations
attr_reader :pages
def self.parse(document)
receiver = new
PDF::Reader.string(document.render, receiver)
return receiver
end
def initialize
@pages = []
end
def begin_page(params)
@pages << params
end
end
describe "When creating annotations" do
before(:each) { create_pdf }
it "should append annotation to current page" do
@pdf.start_new_page
@pdf.annotate(:Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
obj = PageAnnotations.parse(@pdf)
obj.pages[0][:Annots].nil?.should == true
obj.pages[1][:Annots].length.should == 1
end
it "should force :Type to be :Annot" do
opts = @pdf.annotate(:Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
opts[:Type].should == :Annot
opts = @pdf.annotate(:Type => :Bogus, :Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
opts[:Type].should == :Annot
end
end
describe "When creating text annotations" do
before(:each) do
@rect = [0,0,10,10]
@content = "Hello, world!"
create_pdf
end
it "should build appropriate annotation" do
opts = @pdf.text_annotation(@rect, @content)
opts[:Type].should == :Annot
opts[:Subtype].should == :Text
opts[:Rect].should == @rect
opts[:Contents].should == @content
end
it "should merge extra options" do
opts = @pdf.text_annotation(@rect, @content, :Open => true, :Subtype => :Bogus)
opts[:Subtype].should == :Text
opts[:Open].should == true
end
end
describe "When creating link annotations" do
before(:each) do
@rect = [0,0,10,10]
@dest = "home"
create_pdf
end
it "should build appropriate annotation" do
opts = @pdf.link_annotation(@rect, :Dest => @dest)
opts[:Type].should == :Annot
opts[:Subtype].should == :Link
opts[:Rect].should == @rect
opts[:Dest].should == @dest
end
it "should merge extra options" do
opts = @pdf.link_annotation(@rect, :Dest => @dest, :Subtype => :Bogus)
opts[:Subtype].should == :Link
opts[:Dest].should == @dest
end
end
ruby-prawn-1.0.0~rc2.orig/spec/graphics_spec.rb 0000644 0000000 0000000 00000050735 12114176157 020170 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "When drawing a line" do
before(:each) { create_pdf }
it "should draw a line from (100,600) to (100,500)" do
@pdf.line([100,600],[100,500])
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line_drawing.points.should == [[100,600],[100,500]]
end
it "should draw two lines at (100,600) to (100,500) " +
"and (75,100) to (50,125)" do
@pdf.line(100,600,100,500)
@pdf.line(75,100,50,125)
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line_drawing.points.should ==
[[100.0, 600.0], [100.0, 500.0], [75.0, 100.0], [50.0, 125.0]]
end
it "should properly set line width via line_width=" do
@pdf.line_width = 10
line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line.widths.first.should == 10
end
it "should properly set line width via line_width(width)" do
@pdf.line_width(10)
line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line.widths.first.should == 10
end
it "should carry the current line width settings over to new pages" do
@pdf.line_width(10)
@pdf.start_new_page
line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line.widths.length.should == 2
line.widths[1].should == 10
end
describe "(Horizontally)" do
it "should draw from [x1,pdf.y],[x2,pdf.y]" do
@pdf.horizontal_line(100,150)
@line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
@line.points.should == [[100.0 + @pdf.bounds.absolute_left, @pdf.y],
[150.0 + @pdf.bounds.absolute_left, @pdf.y]]
end
it "should draw a line from (200, 250) to (300, 250)" do
@pdf.horizontal_line(200,300,:at => 250)
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line_drawing.points.should == [[200,250],[300,250]]
end
end
describe "(Vertically)" do
it "should draw a line from (350, 300) to (350, 400)" do
@pdf.vertical_line(300,400,:at => 350)
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line_drawing.points.should == [[350,300],[350,400]]
end
it "should require a y coordinate" do
lambda { @pdf.vertical_line(400,500) }.
should raise_error(ArgumentError)
end
end
end
describe "When drawing a polygon" do
before(:each) { create_pdf }
it "should draw each line passed to polygon()" do
@pdf.polygon([100,500],[100,400],[200,400])
line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
line_drawing.points.should == [[100,500],[100,400],[200,400],[100,500]]
end
end
describe "When drawing a rectangle" do
before(:each) { create_pdf }
it "should use a point, width, and height for coords" do
@pdf.rectangle [200,200], 50, 100
rectangles = PDF::Inspector::Graphics::Rectangle.
analyze(@pdf.render).rectangles
# PDF uses bottom left corner
rectangles[0][:point].should == [200,100]
rectangles[0][:width].should == 50
rectangles[0][:height].should == 100
end
end
describe "When drawing a curve" do
before(:each) { create_pdf }
it "should draw a bezier curve from 50,50 to 100,100" do
@pdf.move_to [50,50]
@pdf.curve_to [100,100],:bounds => [[20,90], [90,70]]
curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
curve.coords.should == [50.0, 50.0, 20.0, 90.0, 90.0, 70.0, 100.0, 100.0]
end
it "should draw a bezier curve from 100,100 to 50,50" do
@pdf.curve [100,100], [50,50], :bounds => [[20,90], [90,75]]
curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
curve.coords.should == [100.0, 100.0, 20.0, 90.0, 90.0, 75.0, 50.0, 50.0]
end
end
describe "When drawing a rounded rectangle" do
before(:each) do
create_pdf
@pdf.rounded_rectangle([50, 550], 50, 100, 10)
curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
curve_points = []
curve.coords.each_slice(2) {|p| curve_points << p}
@original_point = curve_points.shift
curves = []
curve_points.each_slice(3) {|c| curves << c}
line_points = PDF::Inspector::Graphics::Line.analyze(@pdf.render).points
line_points.shift
@all_coords = []
line_points.zip(curves).flatten.each_slice(2) {|p| @all_coords << p }
@all_coords.unshift @original_point
end
it "should draw a rectangle by connecting lines with rounded bezier curves" do
@all_coords.should == [[60.0, 550.0],[90.0, 550.0], [95.523, 550.0], [100.0, 545.523], [100.0, 540.0],
[100.0, 460.0], [100.0, 454.477], [95.523, 450.0], [90.0, 450.0],
[60.0, 450.0], [54.477, 450.0], [50.0, 454.477], [50.0, 460.0],
[50.0, 540.0], [50.0, 545.523], [54.477, 550.0], [60.0, 550.0]]
end
it "should start and end with the same point" do
@original_point.should == @all_coords.last
end
end
describe "When drawing an ellipse" do
before(:each) do
create_pdf
@pdf.ellipse [100,100], 25, 50
@curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
end
it "should use a Bézier approximation" do
@curve.coords.should ==
[125.0, 100.0,
125.0, 127.614,
113.807, 150,
100.0, 150.0,
86.193, 150.0,
75.0, 127.614,
75.0, 100.0,
75.0, 72.386,
86.193, 50.0,
100.0, 50.0,
113.807, 50.0,
125.0, 72.386,
125.0, 100.0,
100.0, 100.0]
end
it "should move the pointer to the center of the ellipse after drawing" do
@curve.coords[-2..-1].should == [100,100]
end
end
describe "When drawing a circle" do
before(:each) do
create_pdf
@pdf.circle [100,100], 25
@pdf.ellipse [100,100], 25, 25
@curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
end
it "should stroke the same path as the equivalent ellipse" do
middle = @curve.coords.length / 2
@curve.coords[0...middle].should == @curve.coords[middle..-1]
end
end
describe "When filling" do
before(:each) { create_pdf }
it "should default to the f operator (nonzero winding number rule)" do
@pdf.expects(:add_content).with("f")
@pdf.fill
end
it "should use f* for :fill_rule => :even_odd" do
@pdf.expects(:add_content).with("f*")
@pdf.fill(:fill_rule => :even_odd)
end
it "should use b by default for fill_and_stroke (nonzero winding number)" do
@pdf.expects(:add_content).with("b")
@pdf.fill_and_stroke
end
it "should use b* for fill_and_stroke(:fill_rule => :even_odd)" do
@pdf.expects(:add_content).with("b*")
@pdf.fill_and_stroke(:fill_rule => :even_odd)
end
end
describe "When setting colors" do
before(:each) { create_pdf }
it "should set stroke colors" do
@pdf.stroke_color "ffcccc"
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
# 100% red, 80% green, 80% blue
colors.stroke_color.should == [1.0, 0.8, 0.8]
end
it "should set fill colors" do
@pdf.fill_color "ccff00"
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
# 80% red, 100% green, 0% blue
colors.fill_color.should == [0.8,1.0,0]
end
it "should reset the colors on each new page if they have been defined" do
@pdf.fill_color "ccff00"
#colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
# colors.fill_color_count.should == 2
# colors.stroke_color_count.should == 1
@pdf.start_new_page
@pdf.stroke_color "ff00cc"
#colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
# colors.fill_color_count.should == 3
@pdf.start_new_page
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
colors.fill_color_count.should == 3
colors.stroke_color_count.should == 2
colors.fill_color.should == [0.8,1.0,0.0]
colors.stroke_color.should == [1.0,0.0,0.8]
end
it "should set the color space when setting colors on new pages to please fussy readers" do
@pdf.stroke_color "000000"
@pdf.stroke { @pdf.rectangle([10, 10], 10, 10) }
@pdf.start_new_page
@pdf.stroke_color "000000"
@pdf.stroke { @pdf.rectangle([10, 10], 10, 10) }
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
colors.stroke_color_space_count[:DeviceRGB].should == 2
end
end
describe "Patterns" do
before(:each) { create_pdf }
describe 'linear gradients' do
it "should create a /Pattern resource" do
@pdf.fill_gradient [0, @pdf.bounds.height],
[@pdf.bounds.width, @pdf.bounds.height], 'FF0000', '0000FF'
grad = PDF::Inspector::Graphics::Pattern.analyze(@pdf.render)
pattern = grad.patterns.values.first
pattern.should_not be_nil
pattern[:Shading][:ShadingType].should == 2
pattern[:Shading][:Coords].should == [0, 0, @pdf.bounds.width, 0]
pattern[:Shading][:Function][:C0].zip([1, 0, 0]).all?{ |x1, x2|
(x1-x2).abs < 0.01
}.should be_true
pattern[:Shading][:Function][:C1].zip([0, 0, 1]).all?{ |x1, x2|
(x1-x2).abs < 0.01
}.should be_true
end
it "fill_gradient should set fill color to the pattern" do
@pdf.fill_gradient [0, @pdf.bounds.height],
[@pdf.bounds.width, @pdf.bounds.height], 'FF0000', '0000FF'
str = @pdf.render
str.should =~ %r{/Pattern\s+cs\s*/SP-?\d+\s+scn}
end
it "stroke_gradient should set stroke color to the pattern" do
@pdf.stroke_gradient [0, @pdf.bounds.height],
[@pdf.bounds.width, @pdf.bounds.height], 'FF0000', '0000FF'
str = @pdf.render
str.should =~ %r{/Pattern\s+CS\s*/SP-?\d+\s+SCN}
end
end
describe 'radial gradients' do
it "should create a /Pattern resource" do
@pdf.fill_gradient [0, @pdf.bounds.height], 10,
[@pdf.bounds.width, @pdf.bounds.height], 20, 'FF0000', '0000FF'
grad = PDF::Inspector::Graphics::Pattern.analyze(@pdf.render)
pattern = grad.patterns.values.first
pattern.should_not be_nil
pattern[:Shading][:ShadingType].should == 3
pattern[:Shading][:Coords].should == [0, 0, 10, @pdf.bounds.width, 0, 20]
pattern[:Shading][:Function][:C0].zip([1, 0, 0]).all?{ |x1, x2|
(x1-x2).abs < 0.01
}.should be_true
pattern[:Shading][:Function][:C1].zip([0, 0, 1]).all?{ |x1, x2|
(x1-x2).abs < 0.01
}.should be_true
end
it "fill_gradient should set fill color to the pattern" do
@pdf.fill_gradient [0, @pdf.bounds.height], 10,
[@pdf.bounds.width, @pdf.bounds.height], 20, 'FF0000', '0000FF'
str = @pdf.render
str.should =~ %r{/Pattern\s+cs\s*/SP-?\d+\s+scn}
end
it "stroke_gradient should set stroke color to the pattern" do
@pdf.stroke_gradient [0, @pdf.bounds.height], 10,
[@pdf.bounds.width, @pdf.bounds.height], 20, 'FF0000', '0000FF'
str = @pdf.render
str.should =~ %r{/Pattern\s+CS\s*/SP-?\d+\s+SCN}
end
end
end
describe "When using painting shortcuts" do
before(:each) { create_pdf }
it "should convert stroke_some_method(args) into some_method(args); stroke" do
@pdf.expects(:line_to).with([100,100])
@pdf.expects(:stroke)
@pdf.stroke_line_to [100,100]
end
it "should convert fill_some_method(args) into some_method(args); fill" do
@pdf.expects(:line_to).with([100,100])
@pdf.expects(:fill)
@pdf.fill_line_to [100,100]
end
it "should not break method_missing" do
lambda { @pdf.i_have_a_pretty_girlfriend_named_jia }.
should raise_error(NoMethodError)
end
end
describe "When using graphics states" do
before(:each) { create_pdf }
it "should add the right content on save_graphics_state" do
@pdf.expects(:add_content).with('q')
@pdf.save_graphics_state
end
it "should add the right content on restore_graphics_state" do
@pdf.expects(:add_content).with('Q')
@pdf.restore_graphics_state
end
it "should save and restore when save_graphics_state is used with a block" do
state = sequence "state"
@pdf.expects(:add_content).with('q').in_sequence(state)
@pdf.expects(:foo).in_sequence(state)
@pdf.expects(:add_content).with('Q').in_sequence(state)
@pdf.save_graphics_state do
@pdf.foo
end
end
it "should add the previous color space when restoring to a graphic state with different color space" do
@pdf.stroke_color '000000'
@pdf.save_graphics_state
@pdf.stroke_color 0, 0, 0, 0
@pdf.restore_graphics_state
@pdf.stroke_color 0, 0, 100, 0
@pdf.graphic_state.color_space.should == {:stroke=>:DeviceCMYK}
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
colors.color_space.should == :DeviceCMYK
colors.stroke_color_space_count[:DeviceCMYK].should == 2
end
it "should use the correct dash setting after restoring and starting new page" do
@pdf.dash 5
@pdf.save_graphics_state
@pdf.dash 10
@pdf.graphic_state.dash[:dash].should == 10
@pdf.restore_graphics_state
@pdf.start_new_page
@pdf.graphic_state.dash[:dash].should == 5
end
it "the current graphic state should keep track of previous unchanged settings" do
@pdf.stroke_color '000000'
@pdf.save_graphics_state
@pdf.dash 5
@pdf.save_graphics_state
@pdf.cap_style :round
@pdf.save_graphics_state
@pdf.fill_color 0, 0, 100, 0
@pdf.save_graphics_state
@pdf.graphic_state.stroke_color.should == "000000"
@pdf.graphic_state.join_style.should == :miter
@pdf.graphic_state.fill_color.should == [0, 0, 100, 0]
@pdf.graphic_state.cap_style.should == :round
@pdf.graphic_state.color_space.should == {:fill=>:DeviceCMYK, :stroke=>:DeviceRGB}
@pdf.graphic_state.dash.should == {:space=>5, :phase=>0, :dash=>5}
@pdf.graphic_state.line_width.should == 1
end
it "should not add extra graphic space closings when rendering multiple times" do
@pdf.render
state = PDF::Inspector::Graphics::State.analyze(@pdf.render)
state.save_graphics_state_count.should == 1
state.restore_graphics_state_count.should == 1
end
it "should add extra graphic state enclosings when content is added on multiple renderings" do
@pdf.render
@pdf.text "Adding a bit more content"
state = PDF::Inspector::Graphics::State.analyze(@pdf.render)
state.save_graphics_state_count.should == 2
state.restore_graphics_state_count.should == 2
end
it "adds extra graphic state enclosings when new settings are applied on multiple renderings" do
@pdf.render
@pdf.stroke_color 0, 0, 0, 0
state = PDF::Inspector::Graphics::State.analyze(@pdf.render)
state.save_graphics_state_count.should == 2
state.restore_graphics_state_count.should == 2
end
it "should raise_error error if closing an empty graphic stack" do
lambda {
@pdf.render
@pdf.restore_graphics_state
}.should raise_error(Prawn::Errors::EmptyGraphicStateStack)
end
end
describe "When using transformation matrix" do
before(:each) { create_pdf }
# Note: The (approximate) number of significant decimal digits of precision in fractional
# part is 5 (PDF Reference, Third Edition, p. 706)
it "should send the right content on transformation_matrix" do
@pdf.expects(:add_content).with('1.00000 0.00000 0.12346 -1.00000 5.50000 20.00000 cm')
@pdf.transformation_matrix 1, 0, 0.123456789, -1.0, 5.5, 20
end
it "should use fixed digits with very small number" do
values = Array.new(6, 0.000000000001)
string = Array.new(6, "0.00000").join " "
@pdf.expects(:add_content).with("#{string} cm")
@pdf.transformation_matrix *values
end
it "should be received by the inspector" do
@pdf.transformation_matrix 1, 0, 0, -1, 5.5, 20
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
matrices.matrices.should == [[1, 0, 0, -1, 5.5, 20]]
end
it "should save the graphics state inside the given block" do
values = Array.new(6, 0.000000000001)
string = Array.new(6, "0.00000").join " "
process = sequence "process"
@pdf.expects(:save_graphics_state).with().in_sequence(process)
@pdf.expects(:add_content).with("#{string} cm").in_sequence(process)
@pdf.expects(:do_something).with().in_sequence(process)
@pdf.expects(:restore_graphics_state).with().in_sequence(process)
@pdf.transformation_matrix(*values) do
@pdf.do_something
end
end
end
describe "When using transformations shortcuts" do
before(:each) do
create_pdf
@x, @y = 12, 54.32
@angle = 12.32
@cos = Math.cos(@angle * Math::PI / 180)
@sin = Math.sin(@angle * Math::PI / 180)
@factor = 0.12
end
describe "#rotate" do
it "should rotate" do
@pdf.expects(:transformation_matrix).with(@cos, @sin, -@sin, @cos, 0, 0)
@pdf.rotate(@angle)
end
end
describe "#rotate with :origin option" do
it "should rotate around the origin" do
x_prime = @x * @cos - @y * @sin
y_prime = @x * @sin + @y * @cos
@pdf.rotate(@angle, :origin => [@x, @y]) { @pdf.text('hello world') }
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(@x - x_prime),
reduce_precision(@y - y_prime)]
matrices.matrices[1].should == [reduce_precision(@cos),
reduce_precision(@sin),
reduce_precision(-@sin),
reduce_precision(@cos), 0, 0]
end
it "should rotate around the origin in a document with a margin" do
@pdf = Prawn::Document.new
@pdf.rotate(@angle, :origin => [@x, @y]) { @pdf.text('hello world') }
x = @x + @pdf.bounds.absolute_left
y = @y + @pdf.bounds.absolute_bottom
x_prime = x * @cos - y * @sin
y_prime = x * @sin + y * @cos
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(x - x_prime),
reduce_precision(y - y_prime)]
matrices.matrices[1].should == [reduce_precision(@cos),
reduce_precision(@sin),
reduce_precision(-@sin),
reduce_precision(@cos), 0, 0]
end
it "should raise_error BlockRequired if no block is given" do
lambda {
@pdf.rotate(@angle, :origin => [@x, @y])
}.should raise_error(Prawn::Errors::BlockRequired)
end
def reduce_precision(float)
("%.5f" % float).to_f
end
end
describe "#translate" do
it "should translate" do
x, y = 12, 54.32
@pdf.expects(:transformation_matrix).with(1, 0, 0, 1, x, y)
@pdf.translate(x, y)
end
end
describe "#scale" do
it "should scale" do
@pdf.expects(:transformation_matrix).with(@factor, 0, 0, @factor, 0, 0)
@pdf.scale(@factor)
end
end
describe "#scale with :origin option" do
it "should scale from the origin" do
x_prime = @factor * @x
y_prime = @factor * @y
@pdf.scale(@factor, :origin => [@x, @y]) { @pdf.text('hello world') }
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(@x - x_prime),
reduce_precision(@y - y_prime)]
matrices.matrices[1].should == [@factor, 0, 0, @factor, 0, 0]
end
it "should scale from the origin in a document with a margin" do
@pdf = Prawn::Document.new
x = @x + @pdf.bounds.absolute_left
y = @y + @pdf.bounds.absolute_bottom
x_prime = @factor * x
y_prime = @factor * y
@pdf.scale(@factor, :origin => [@x, @y]) { @pdf.text('hello world') }
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(x - x_prime),
reduce_precision(y - y_prime)]
matrices.matrices[1].should == [@factor, 0, 0, @factor, 0, 0]
end
it "should raise_error BlockRequired if no block is given" do
lambda {
@pdf.scale(@factor, :origin => [@x, @y])
}.should raise_error(Prawn::Errors::BlockRequired)
end
def reduce_precision(float)
("%.5f" % float).to_f
end
end
# describe "skew" do
# it "should skew" do
# a, b = 30, 50.2
# @pdf.expects(:transformation_matrix).with(1, Math.tan(a * Math::PI / 180), Math.tan(b * Math::PI / 180), 1, 0, 0)
# @pdf.skew(a, b)
# end
# end
end
ruby-prawn-1.0.0~rc2.orig/spec/font_spec.rb 0000644 0000000 0000000 00000033215 12114176157 017330 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
require 'pathname'
describe "Font behavior" do
it "should default to Helvetica if no font is specified" do
@pdf = Prawn::Document.new
@pdf.font.name.should == "Helvetica"
end
end
describe "#width_of" do
it "should take character spacing into account" do
create_pdf
original_width = @pdf.width_of("hello world")
@pdf.character_spacing(7) do
@pdf.width_of("hello world").should == original_width + 11 * 7
end
end
it "should exclude newlines" do
create_pdf
# Use a TTF font that has a non-zero width for \n
@pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
@pdf.width_of("\nhello world\n").should ==
@pdf.width_of("hello world")
end
it "should take formatting into account" do
create_pdf
normal_hello = @pdf.width_of("hello")
inline_bold_hello = @pdf.width_of("hello", :inline_format => true)
@pdf.font("Helvetica", :style => :bold) {
@bold_hello = @pdf.width_of("hello")
}
inline_bold_hello.should be > normal_hello
inline_bold_hello.should == @bold_hello
end
it "should accept :style as an argument" do
create_pdf
styled_bold_hello = @pdf.width_of("hello", :style => :bold)
@pdf.font("Helvetica", :style => :bold) {
@bold_hello = @pdf.width_of("hello")
}
styled_bold_hello.should == @bold_hello
end
end
describe "#font_size" do
it "should allow setting font size in DSL style" do
create_pdf
@pdf.font_size 20
@pdf.font_size.should == 20
end
end
describe "font style support" do
before(:each) { create_pdf }
it "should complain if there is no @current_page" do
pdf_without_page = Prawn::Document.new(:skip_page_creation => true)
lambda{ pdf_without_page.font "Helvetica" }.
should raise_error(Prawn::Errors::NotOnPage)
end
it "should allow specifying font style by style name and font family" do
@pdf.font "Courier", :style => :bold
@pdf.text "In Courier bold"
@pdf.font "Courier", :style => :bold_italic
@pdf.text "In Courier bold-italic"
@pdf.font "Courier", :style => :italic
@pdf.text "In Courier italic"
@pdf.font "Courier", :style => :normal
@pdf.text "In Normal Courier"
@pdf.font "Helvetica"
@pdf.text "In Normal Helvetica"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings.map { |e| e[:name] }.should ==
[:"Courier-Bold", :"Courier-BoldOblique", :"Courier-Oblique",
:Courier, :Helvetica]
end
it "should allow font familes to be defined in a single dfont" do
file = "#{Prawn::DATADIR}/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.to_s
name = name.sub(/\w+\+/, "subset+")
name.should == "subset+ActionMan-Italic"
end
it "should accept Pathname objects for font files" do
file = Pathname.new( "#{Prawn::DATADIR}/fonts/Chalkboard.ttf" )
@pdf.font_families["Chalkboard"] = {
:normal => file
}
@pdf.font "Chalkboard"
@pdf.text "In Chalkboard"
text = PDF::Inspector::Text.analyze(@pdf.render)
name = text.font_settings.map { |e| e[:name] }.first.to_s
name = name.sub(/\w+\+/, "subset+")
name.should == "subset+Chalkboard"
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
end
it "should allow temporary setting of a new font using a transaction" do
@pdf.font "Helvetica", :size => 12
@pdf.font "Courier", :size => 16 do
@pdf.font.name.should == "Courier"
@pdf.font_size.should == 16
end
@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 fonts properly by page" do
@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"; @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)
end
def page_should_include_font(font)
page_includes_font?(font).should be_true
end
def page_should_not_include_font(font)
page_includes_font?(font).should be_false
end
end
describe "AFM fonts" do
before do
create_pdf
@times = @pdf.find_font "Times-Roman"
end
it "should calculate string width taking into account accented characters" do
input = win1252_string("\xE9")# é in win-1252
@times.compute_width_of(input, :size => 12).should == @times.compute_width_of("e", :size => 12)
end
it "should calculate string width taking into account kerning pairs" do
@times.compute_width_of(win1252_string("To"), :size => 12).should == 13.332
@times.compute_width_of(win1252_string("To"), :size => 12, :kerning => true).should == 12.372
input = win1252_string("T\xF6") # Tö in win-1252
@times.compute_width_of(input, :size => 12, :kerning => true).should == 12.372
end
it "should encode text without kerning by default" do
@times.encode_text(win1252_string("To")).should == [[0, "To"]]
input = win1252_string("T\xE9l\xE9") # Télé in win-1252
@times.encode_text(input).should == [[0, input]]
@times.encode_text(win1252_string("Technology")).should == [[0, "Technology"]]
@times.encode_text(win1252_string("Technology...")).should == [[0, "Technology..."]]
end
it "should encode text with kerning if requested" do
@times.encode_text(win1252_string("To"), :kerning => true).should == [[0, ["T", 80, "o"]]]
input = win1252_string("T\xE9l\xE9") # Télé in win-1252
output = win1252_string("\xE9l\xE9") # élé in win-1252
@times.encode_text(input, :kerning => true).should == [[0, ["T", 70, output]]]
@times.encode_text(win1252_string("Technology"), :kerning => true).should == [[0, ["T", 70, "echnology"]]]
@times.encode_text(win1252_string("Technology..."), :kerning => true).should == [[0, ["T", 70, "echnology", 65, "..."]]]
end
describe "when normalizing encoding" do
it "should not modify the original string when normalize_encoding() is used" do
original = "Foo"
normalized = @times.normalize_encoding(original)
original.equal?(normalized).should be_false
end
it "should modify the original string when normalize_encoding!() is used" do
original = "Foo"
normalized = @times.normalize_encoding!(original)
original.equal?(normalized).should be_true
end
end
it "should omit /Encoding for symbolic fonts" do
zapf = @pdf.find_font "ZapfDingbats"
font_dict = zapf.send(:register, nil)
font_dict.data[:Encoding].should == nil
end
end
describe "#glyph_present" do
before(:each) { create_pdf }
it "should return true when present in an AFM font" do
font = @pdf.find_font("Helvetica")
font.glyph_present?("H").should be_true
end
it "should return false when absent in an AFM font" do
font = @pdf.find_font("Helvetica")
font.glyph_present?("再").should be_false
end
it "should return true when present in a TTF font" do
font = @pdf.find_font("#{Prawn::DATADIR}/fonts/Activa.ttf")
font.glyph_present?("H").should be_true
end
it "should return false when absent in a TTF font" do
font = @pdf.find_font("#{Prawn::DATADIR}/fonts/Activa.ttf")
font.glyph_present?("再").should be_false
font = @pdf.find_font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
font.glyph_present?("€").should be_false
end
end
describe "TTF fonts" do
before do
create_pdf
@activa = @pdf.find_font "#{Prawn::DATADIR}/fonts/Activa.ttf"
end
it "should calculate string width taking into account accented characters" do
@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.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
@activa.encode_text("To").should == [[0, "To"]]
tele = "T\216l\216"
result = @activa.encode_text("Télé")
result.length.should == 1
result[0][0].should == 0
result[0][1].bytes.to_a.should == tele.bytes.to_a
@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
it "should use the ascender, descender, and cap height from the TTF verbatim" do
# These metrics are relative to the font's own bbox. They should not be
# scaled with font size.
ref = @pdf.ref!({})
@activa.send :embed, ref, 0
# Pull out the embedded font descriptor
descriptor = ref.data[:FontDescriptor].data
descriptor[:Ascent].should == 804
descriptor[:Descent].should == -195
descriptor[:CapHeight].should == 804
end
describe "when normalizing encoding" do
it "should not modify the original string when normalize_encoding() is used" do
original = "Foo"
normalized = @activa.normalize_encoding(original)
original.equal?(normalized).should be_false
end
it "should modify the original string when normalize_encoding!() is used" do
original = "Foo"
normalized = @activa.normalize_encoding!(original)
original.equal?(normalized).should be_true
end
end
describe "when used with snapshots or transactions" do
it "should allow TTF fonts to be used alongside document transactions" do
lambda {
Prawn::Document.new do
font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
text "Hi there"
transaction { text "Nice, thank you" }
end
}.should_not raise_error
end
it "should allow TTF fonts to be used inside transactions" do
pdf = Prawn::Document.new do
transaction do
font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
text "Hi there"
end
end
text = PDF::Inspector::Text.analyze(pdf.render)
name = text.font_settings.map { |e| e[:name] }.first.to_s
name = name.sub(/\w+\+/, "subset+")
name.should == "subset+DejaVuSans"
end
end
end
describe "DFont fonts" do
before do
create_pdf
@file = "#{Prawn::DATADIR}/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")
f2.object_id.should_not == f1.object_id
@pdf.find_font(@file, :font => "ActionMan").object_id.should == f1.object_id
@pdf.find_font(@file, :font => "ActionMan-Bold").object_id.should == f2.object_id
end
end
describe "#character_count(text)" do
it "should work on TTF fonts" do
create_pdf
@pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
@pdf.font.character_count("こんにちは世界").should == 7
@pdf.font.character_count("Hello, world!").should == 13
end
it "should work on AFM fonts" do
create_pdf
@pdf.font.character_count("Hello, world!").should == 13
end
end
ruby-prawn-1.0.0~rc2.orig/spec/span_spec.rb 0000644 0000000 0000000 00000002160 12114176157 017316 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "drawing span" do
before do
Prawn.debug = false
create_pdf
end
after do
Prawn.debug = true
end
it "should only accept :position as option in debug mode" do
Prawn.debug = true
lambda { @pdf.span(350, {:x => 3}) {} }.should raise_error(Prawn::Errors::UnknownOption)
end
it "should have raise an error if :position is invalid" do
lambda { @pdf.span(350, :position => :x) {} }.should raise_error(ArgumentError)
end
it "should restore the margin box when bounding box exits" do
margin_box = @pdf.bounds
@pdf.span(350, :position => :center) do
@pdf.text "Here's some centered text in a 350 point column. " * 100
end
@pdf.bounds.should == margin_box
end
it "should do create a margin box" do
y = @pdf.y
margin_box = @pdf.span(350, :position => :center) do
@pdf.text "Here's some centered text in a 350 point column. " * 100
end
margin_box.top.should == 792.0
margin_box.bottom.should == 0
end
end
ruby-prawn-1.0.0~rc2.orig/spec/column_box_spec.rb 0000644 0000000 0000000 00000001702 12114176157 020523 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "A column box" do
it "has sensible left and right values" do
create_pdf
@pdf.column_box [0, @pdf.cursor], :width => @pdf.bounds.width,
:height => 200, :columns => 3, :spacer => 25 do
left = @pdf.bounds.left
right = @pdf.bounds.right
@pdf.bounds.move_past_bottom # next column
@pdf.bounds.left.should be > left
@pdf.bounds.left.should be > right
@pdf.bounds.right.should be > @pdf.bounds.left
end
end
it "includes spacers between columns but not at the end" do
create_pdf
@pdf.column_box [0, @pdf.cursor], :width => 500,
:height => 200, :columns => 3, :spacer => 25 do
@pdf.bounds.width.should == 150 # (500 - (25 * 2)) / 3
@pdf.bounds.move_past_bottom
@pdf.bounds.move_past_bottom
@pdf.bounds.right.should == 500
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/soft_mask_spec.rb 0000644 0000000 0000000 00000005777 12114176157 020364 0 ustar root root require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
module SoftMaskHelper
def make_soft_mask
@pdf.save_graphics_state do
@pdf.soft_mask do
if block_given?
yield
else
@pdf.fill_color '808080'
@pdf.fill_rectangle [100, 100], 200, 200
end
end
@pdf.fill_color '000000'
@pdf.fill_rectangle [0, 0], 200, 200
end
end
end
describe "Document with soft masks" do
include SoftMaskHelper
it "should have PDF version at least 1.4" do
create_pdf
make_soft_mask
str = @pdf.render
str[0,8].should == "%PDF-1.4"
end
it "should create a new extended graphics state for each unique soft mask" do
create_pdf
make_soft_mask do
@pdf.fill_color '808080'
@pdf.fill_rectangle [100, 100], 200, 200
end
make_soft_mask do
@pdf.fill_color '808080'
@pdf.fill_rectangle [10, 10], 200, 200
end
extgstates = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates
extgstates.length.should == 2
end
it "a new extended graphics state should contain soft mask with drawing instructions" do
create_pdf
make_soft_mask do
@pdf.fill_color '808080'
@pdf.fill_rectangle [100, 100], 200, 200
end
extgstate = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates.first
extgstate[:soft_mask][:G].data.should == "q\n/DeviceRGB cs\n0.000 0.000 0.000 scn\n/DeviceRGB CS\n0.000 0.000 0.000 SCN\n1 w\n0 J\n0 j\n[ ] 0 d\n/DeviceRGB cs\n0.502 0.502 0.502 scn\n100.000 -100.000 200.000 200.000 re\nf\nQ\n"
end
it "should not create duplicate extended graphics states" do
create_pdf
make_soft_mask do
@pdf.fill_color '808080'
@pdf.fill_rectangle [100, 100], 200, 200
end
make_soft_mask do
@pdf.fill_color '808080'
@pdf.fill_rectangle [100, 100], 200, 200
end
extgstates = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates
extgstates.length.should == 1
end
it "should not have objects that are not used for extended graphic state" do
@pdf = Prawn::Document.new(:margin => 0, :optimize_objects => true)
make_soft_mask do
@pdf.fill_color '808080'
@pdf.fill_rectangle [100, 100], 200, 200
end
make_soft_mask do
@pdf.fill_color '808080'
@pdf.fill_rectangle [100, 100], 200, 200
end
reader = PDF::Reader.new(StringIO.open(@pdf.render))
groups = reader.objects.select { |obj|
o = obj[1]
o.is_a?(Hash) && o[:Type] == :Group
}
groups.length.should == 1
forms = reader.objects.select { |obj|
o = obj[1]
o.is_a?(PDF::Reader::Stream) && o.hash[:Type] == :XObject && o.hash[:Subtype] == :Form
}
forms.length.should == 1
masks = reader.objects.select { |obj|
o = obj[1]
o.is_a?(Hash) && o[:Type] == :Mask
}
masks.length.should == 1
ext_g_states = reader.objects.select { |obj|
o = obj[1]
o.is_a?(Hash) && o[:Type] == :ExtGState
}
ext_g_states.length.should == 1
end
end
ruby-prawn-1.0.0~rc2.orig/spec/table_spec.rb 0000644 0000000 0000000 00000116353 12114176157 017456 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
require 'set'
describe "Prawn::Table" do
describe "converting data to Cell objects" do
before(:each) do
@pdf = Prawn::Document.new
@table = @pdf.table([%w[R0C0 R0C1], %w[R1C0 R1C1]])
end
it "should return a Prawn::Table" do
@table.should be_a_kind_of Prawn::Table
end
it "should flatten the data into the @cells array in row-major order" do
@table.cells.map { |c| c.content }.should == %w[R0C0 R0C1 R1C0 R1C1]
end
it "should add row and column numbers to each cell" do
c = @table.cells.to_a.first
c.row.should == 0
c.column.should == 0
end
it "should allow empty fields" do
lambda {
data = [["foo","bar"],["baz",""]]
@pdf.table(data)
}.should_not raise_error
end
it "should allow a table with a header but no body" do
lambda { @pdf.table([["Header"]], :header => true) }.should_not raise_error
end
it "should accurately count columns from data" do
# First data row may contain colspan which would hide true column count
data = [["Name:", {:content => "Some very long name", :colspan => 5}]]
pdf = Prawn::Document.new
table = Prawn::Table.new data, pdf
table.column_widths.length.should == 6
end
end
describe "#initialize" do
before(:each) do
@pdf = Prawn::Document.new
end
it "should instance_eval a 0-arg block" do
initializer = mock()
initializer.expects(:kick).once
@pdf.table([["a"]]){
initializer.kick
}
end
it "should call a 1-arg block with the document as the argument" do
initializer = mock()
initializer.expects(:kick).once
@pdf.table([["a"]]){ |doc|
doc.should be_a_kind_of(Prawn::Table); initializer.kick }
end
it "should proxy cell methods to #cells" do
table = @pdf.table([["a"]], :cell_style => { :padding => 11 })
table.cells[0, 0].padding.should == [11, 11, 11, 11]
end
it "should set row and column length" do
table = @pdf.table([["a", "b", "c"], ["d", "e", "f"]])
table.row_length.should == 2
table.column_length.should == 3
end
it "should generate a text cell based on a String" do
t = @pdf.table([["foo"]])
t.cells[0,0].should be_a_kind_of(Prawn::Table::Cell::Text)
end
it "should pass through a text cell" do
c = Prawn::Table::Cell::Text.new(@pdf, [0,0], :content => "foo")
t = @pdf.table([[c]])
t.cells[0,0].should == c
end
end
describe "cell accessors" do
before(:each) do
@pdf = Prawn::Document.new
@table = @pdf.table([%w[R0C0 R0C1], %w[R1C0 R1C1]])
end
it "should select rows by number or range" do
Set.new(@table.row(0).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1])
Set.new(@table.rows(0..1).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1 R1C0 R1C1])
end
it "should select rows by array" do
Set.new(@table.rows([0, 1]).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1 R1C0 R1C1])
end
it "should allow negative row selectors" do
Set.new(@table.row(-1).map { |c| c.content }).should ==
Set.new(%w[R1C0 R1C1])
Set.new(@table.rows(-2..-1).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1 R1C0 R1C1])
Set.new(@table.rows(0..-1).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1 R1C0 R1C1])
end
it "should select columns by number or range" do
Set.new(@table.column(0).map { |c| c.content }).should ==
Set.new(%w[R0C0 R1C0])
Set.new(@table.columns(0..1).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1 R1C0 R1C1])
end
it "should select columns by array" do
Set.new(@table.columns([0, 1]).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1 R1C0 R1C1])
end
it "should allow negative column selectors" do
Set.new(@table.column(-1).map { |c| c.content }).should ==
Set.new(%w[R0C1 R1C1])
Set.new(@table.columns(-2..-1).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1 R1C0 R1C1])
Set.new(@table.columns(0..-1).map { |c| c.content }).should ==
Set.new(%w[R0C0 R0C1 R1C0 R1C1])
end
it "should allow rows and columns to be combined" do
@table.row(0).column(1).map { |c| c.content }.should == ["R0C1"]
end
it "should accept a filter block, returning a cell proxy" do
@table.cells.filter { |c| c.content =~ /R0/ }.column(1).map{ |c|
c.content }.should == ["R0C1"]
end
it "should accept the [] method, returning a Cell or nil" do
@table.cells[0, 0].content.should == "R0C0"
@table.cells[12, 12].should be_nil
end
it "should proxy unknown methods to the cells" do
@table.cells.height = 200
@table.row(1).height = 100
@table.cells[0, 0].height.should == 200
@table.cells[1, 0].height.should == 100
end
it "should ignore non-setter methods" do
lambda {
@table.cells.content_width
}.should raise_error(NoMethodError)
end
it "skips cells that don't respond to the given method" do
table = @pdf.make_table([[{:content => "R0", :colspan => 2}],
%w[R1C0 R1C1]])
lambda {
table.row(0).font_style = :bold
}.should_not raise_error
end
it "should accept the style method, proxying its calls to the cells" do
@table.cells.style(:height => 200, :width => 200)
@table.column(0).style(:width => 100)
@table.cells[0, 1].width.should == 200
@table.cells[1, 0].height.should == 200
@table.cells[1, 0].width.should == 100
end
it "style method should accept a block, passing each cell to be styled" do
@table.cells.style { |c| c.height = 200 }
@table.cells[0, 1].height.should == 200
end
it "should return the width of selected columns for #width" do
c0_width = @table.column(0).map{ |c| c.width }.max
c1_width = @table.column(1).map{ |c| c.width }.max
@table.column(0).width.should == c0_width
@table.column(1).width.should == c1_width
@table.columns(0..1).width.should == c0_width + c1_width
@table.cells.width.should == c0_width + c1_width
end
it "should return the height of selected rows for #height" do
r0_height = @table.row(0).map{ |c| c.height }.max
r1_height = @table.row(1).map{ |c| c.height }.max
@table.row(0).height.should == r0_height
@table.row(1).height.should == r1_height
@table.rows(0..1).height.should == r0_height + r1_height
@table.cells.height.should == r0_height + r1_height
end
end
describe "layout" do
before(:each) do
@pdf = Prawn::Document.new
@long_text = "The quick brown fox jumped over the lazy dogs. " * 5
end
describe "width" do
it "should raise_error an error if the given width is outside of range" do
lambda do
@pdf.table([["foo"]], :width => 1)
end.should raise_error(Prawn::Errors::CannotFit)
lambda do
@pdf.table([[@long_text]], :width => @pdf.bounds.width + 100)
end.should raise_error(Prawn::Errors::CannotFit)
end
it "should accept the natural width for small tables" do
pad = 10 # default padding
@table = @pdf.table([["a"]])
@table.width.should == @table.cells[0, 0].natural_content_width + pad
end
it "width should == sum(column_widths)" do
table = Prawn::Table.new([%w[ a b c ], %w[d e f]], @pdf) do
column(0).width = 50
column(1).width = 100
column(2).width = 150
end
table.width.should == 300
end
it "should accept Numeric for column_widths" do
table = Prawn::Table.new([%w[ a b c ], %w[d e f]], @pdf) do |t|
t.column_widths = 50
end
table.width.should == 150
end
it "should calculate unspecified column widths as "+
"(max(string_width) + 2*horizontal_padding)" do
hpad, fs = 3, 12
columns = 2
table = Prawn::Table.new( [%w[ foo b ], %w[d foobar]], @pdf,
:cell_style => { :padding => hpad, :size => fs } )
col0_width = @pdf.width_of("foo", :size => fs)
col1_width = @pdf.width_of("foobar", :size => fs)
table.width.should == col0_width + col1_width + 2*columns*hpad
end
it "should allow mixing autocalculated and preset"+
"column widths within a single table" do
hpad, fs = 10, 6
stretchy_columns = 2
col0_width = 50
col1_width = @pdf.width_of("foo", :size => fs)
col2_width = @pdf.width_of("foobar", :size => fs)
col3_width = 150
table = Prawn::Table.new( [%w[snake foo b apple],
%w[kitten d foobar banana]], @pdf,
:cell_style => { :padding => hpad, :size => fs }) do
column(0).width = col0_width
column(3).width = col3_width
end
table.width.should == col1_width + col2_width +
2*stretchy_columns*hpad +
col0_width + col3_width
end
it "should preserve all manually requested column widths" do
col0_width = 50
col1_width = 20
col3_width = 60
table = Prawn::Table.new( [["snake", "foo", "b",
"some long, long text that will wrap"],
%w[kitten d foobar banana]], @pdf,
:width => 150) do
column(0).width = col0_width
column(1).width = col1_width
column(3).width = col3_width
end
table.draw
table.column(0).width.should == col0_width
table.column(1).width.should == col1_width
table.column(3).width.should == col3_width
end
it "should_not exceed the maximum width of the margin_box" do
expected_width = @pdf.margin_box.width
data = [
['This is a column with a lot of text that should comfortably exceed '+
'the width of a normal document margin_box width', 'Some more text',
'and then some more', 'Just a bit more to be extra sure']
]
table = Prawn::Table.new(data, @pdf)
table.width.should == expected_width
end
it "should_not exceed the maximum width of the margin_box even with" +
"manual widths specified" do
expected_width = @pdf.margin_box.width
data = [
['This is a column with a lot of text that should comfortably exceed '+
'the width of a normal document margin_box width', 'Some more text',
'and then some more', 'Just a bit more to be extra sure']
]
table = Prawn::Table.new(data, @pdf) { column(1).width = 100 }
table.width.should == expected_width
end
it "scales down only the non-preset column widths when the natural width" +
"exceeds the maximum width of the margin_box" do
expected_width = @pdf.margin_box.width
data = [
['This is a column with a lot of text that should comfortably exceed '+
'the width of a normal document margin_box width', 'Some more text',
'and then some more', 'Just a bit more to be extra sure']
]
table = Prawn::Table.new(data, @pdf) { column(1).width = 100; column(3).width = 50 }
table.width.should == expected_width
table.column_widths[1].should == 100
table.column_widths[3].should == 50
end
it "should allow width to be reset even after it has been calculated" do
@table = @pdf.table([[@long_text]])
@table.width
@table.width = 100
@table.width.should == 100
end
it "should shrink columns evenly when two equal columns compete" do
@table = @pdf.table([["foo", @long_text], [@long_text, "foo"]])
@table.cells[0, 0].width.should == @table.cells[0, 1].width
end
it "should grow columns evenly when equal deficient columns compete" do
@table = @pdf.table([["foo", "foobar"], ["foobar", "foo"]], :width => 500)
@table.cells[0, 0].width.should == @table.cells[0, 1].width
end
it "should respect manual widths" do
@table = @pdf.table([%w[foo bar baz], %w[baz bar foo]], :width => 500) do
column(1).width = 60
end
@table.column(1).width.should == 60
@table.column(0).width.should == @table.column(2).width
end
it "should allow table cells to be resized in block" do
lambda do
@pdf.table([%w[1 2 3 4 5]]) do |t|
t.width = 40
t.cells.size = 8
t.cells.padding = 0
end
end.should_not raise_error(Prawn::Errors::CannotFit)
end
it "should be the width of the :width parameter" do
expected_width = 300
table = Prawn::Table.new( [%w[snake foo b apple],
%w[kitten d foobar banana]], @pdf,
:width => expected_width)
table.width.should == expected_width
end
it "should_not exceed the :width option" do
expected_width = 400
data = [
['This is a column with a lot of text that should comfortably exceed '+
'the width of a normal document margin_box width', 'Some more text',
'and then some more', 'Just a bit more to be extra sure']
]
table = Prawn::Table.new(data, @pdf, :width => expected_width)
table.width.should == expected_width
end
it "should_not exceed the :width option even with manual widths specified" do
expected_width = 400
data = [
['This is a column with a lot of text that should comfortably exceed '+
'the width of a normal document margin_box width', 'Some more text',
'and then some more', 'Just a bit more to be extra sure']
]
table = Prawn::Table.new(data, @pdf, :width => expected_width) do
column(1).width = 100
end
table.width.should == expected_width
end
it "should calculate unspecified column widths even " +
"with colspan cells declared" do
pdf = Prawn::Document.new
hpad, fs = 3, 5
columns = 3
data = [ [ { :content => 'foo', :colspan => 2 }, "foobar" ],
[ "foo", "foo", "foo" ] ]
table = Prawn::Table.new( data, pdf,
:cell_style => {
:padding_left => hpad, :padding_right => hpad,
:size => fs
})
col0_width = pdf.width_of("foo", :size => fs) # cell 1, 0
col1_width = pdf.width_of("foo", :size => fs) # cell 1, 1
col2_width = pdf.width_of("foobar", :size => fs) # cell 0, 1 (at col 2)
table.width.should == col0_width + col1_width +
col2_width + 2*columns*hpad
end
end
describe "height" do
it "should set all cells in a row to the same height" do
@table = @pdf.table([["foo", @long_text]])
@table.cells[0, 0].height.should == @table.cells[0, 1].height
end
it "should move y-position to the bottom of the table after drawing" do
old_y = @pdf.y
table = @pdf.table([["foo"]])
@pdf.y.should == old_y - table.height
end
it "should_not wrap unnecessarily" do
# Test for FP errors and glitches
t = @pdf.table([["Bender Bending Rodriguez"]])
h = @pdf.height_of("one line")
(t.height - 10).should be < h*1.5
end
it "should have a height of n rows" do
data = [["foo"],["bar"],["baaaz"]]
vpad = 4
origin = @pdf.y
@pdf.table data, :cell_style => { :padding => vpad }
table_height = origin - @pdf.y
font_height = @pdf.font.height
line_gap = @pdf.font.line_gap
num_rows = data.length
table_height.should be_within(0.001).of(
num_rows * font_height + 2*vpad*num_rows )
end
end
describe "position" do
it "should center tables with :position => :center" do
@pdf.expects(:bounding_box).with do |(x, y), opts|
expected = (@pdf.bounds.width - 500) / 2.0
(x - expected).abs < 0.001
end
@pdf.table([["foo"]], :column_widths => 500, :position => :center)
end
it "should right-align tables with :position => :right" do
@pdf.expects(:bounding_box).with do |(x, y), opts|
expected = @pdf.bounds.width - 500
(x - expected).abs < 0.001
end
@pdf.table([["foo"]], :column_widths => 500, :position => :right)
end
it "should accept a Numeric" do
@pdf.expects(:bounding_box).with do |(x, y), opts|
expected = 123
(x - expected).abs < 0.001
end
@pdf.table([["foo"]], :column_widths => 500, :position => 123)
end
it "should raise_error an ArgumentError on unknown :position" do
lambda do
@pdf.table([["foo"]], :position => :bratwurst)
end.should raise_error(ArgumentError)
end
end
end
describe "Multi-page tables" do
it "should flow to the next page when hitting the bottom of the bounds" do
Prawn::Document.new { table([["foo"]] * 30) }.page_count.should == 1
Prawn::Document.new { table([["foo"]] * 31) }.page_count.should == 2
Prawn::Document.new { table([["foo"]] * 31); table([["foo"]] * 35) }.
page_count.should == 3
end
it "should respect the containing bounds" do
Prawn::Document.new do
bounding_box([0, cursor], :width => bounds.width, :height => 72) do
table([["foo"]] * 4)
end
end.page_count.should == 2
end
it "should_not start a new page before finishing out a row" do
Prawn::Document.new do
table([[ (1..80).map{ |i| "Line #{i}" }.join("\n"), "Column 2" ]])
end.page_count.should == 1
end
it "should only start new page on long cells if it would gain us height" do
Prawn::Document.new do
text "Hello"
table([[ (1..80).map{ |i| "Line #{i}" }.join("\n"), "Column 2" ]])
end.page_count.should == 2
end
it "should_not start a new page to gain height when at the top of " +
"a bounding box, even if stretchy" do
Prawn::Document.new do
bounding_box([bounds.left, bounds.top - 20], :width => 400) do
table([[ (1..80).map{ |i| "Line #{i}" }.join("\n"), "Column 2" ]])
end
end.page_count.should == 1
end
it "should still break to the next page if in a stretchy bounding box " +
"but not at the top" do
Prawn::Document.new do
bounding_box([bounds.left, bounds.top - 20], :width => 400) do
text "Hello"
table([[ (1..80).map{ |i| "Line #{i}" }.join("\n"), "Column 2" ]])
end
end.page_count.should == 2
end
it "should only draw first-page header if the first body row fits" do
pdf = Prawn::Document.new
pdf.y = 60 # not enough room for a table row
pdf.table [["Header"], ["Body"]], :header => true
output = PDF::Inspector::Page.analyze(pdf.render)
# Ensure we only drew the header once, on the second page
output.pages[0][:strings].should be_empty
output.pages[1][:strings].should == ["Header", "Body"]
end
it "should draw background before borders, but only within pages" do
seq = sequence("drawing_order")
@pdf = Prawn::Document.new
# give enough room for only the first row
@pdf.y = @pdf.bounds.absolute_bottom + 30
t = @pdf.make_table([["A", "B"],
["C", "D"]],
:cell_style => {:background_color => 'ff0000'})
ca = t.cells[0, 0]
cb = t.cells[0, 1]
cc = t.cells[1, 0]
cd = t.cells[1, 1]
# All backgrounds should draw before any borders on page 1...
ca.expects(:draw_background).in_sequence(seq)
cb.expects(:draw_background).in_sequence(seq)
ca.expects(:draw_borders).in_sequence(seq)
cb.expects(:draw_borders).in_sequence(seq)
# ...and page 2
@pdf.expects(:start_new_page).in_sequence(seq)
cc.expects(:draw_background).in_sequence(seq)
cd.expects(:draw_background).in_sequence(seq)
cc.expects(:draw_borders).in_sequence(seq)
cd.expects(:draw_borders).in_sequence(seq)
t.draw
end
describe "before_rendering_page callback" do
before(:each) { @pdf = Prawn::Document.new }
it "is passed all cells to be rendered on that page" do
kicked = 0
@pdf.table([["foo"]] * 100) do |t|
t.before_rendering_page do |page|
page.row_count.should == ((kicked < 3) ? 30 : 10)
page.column_count.should == 1
page.row(0).first.content.should == "foo"
page.row(-1).first.content.should == "foo"
kicked += 1
end
end
kicked.should == 4
end
it "numbers cells relative to their position on page" do
@pdf.table([["foo"]] * 100) do |t|
t.before_rendering_page do |page|
page[0, 0].content.should == "foo"
end
end
end
it "changing cells in the callback affects their rendering" do
seq = sequence("render order")
t = @pdf.make_table([["foo"]] * 40) do |table|
table.before_rendering_page do |page|
page[0, 0].background_color = "ff0000"
end
end
t.cells[30, 0].stubs(:draw_background).checking do |xy|
t.cells[30, 0].background_color.should == 'ff0000'
end
t.cells[31, 0].stubs(:draw_background).checking do |xy|
t.cells[31, 0].background_color.should == nil
end
t.draw
end
it "passes headers on page 2+" do
@pdf.table([["header"]] + [["foo"]] * 100, :header => true) do |t|
t.before_rendering_page do |page|
page[0, 0].content.should == "header"
end
end
end
it "allows headers to be changed" do
seq = sequence("render order")
@pdf.expects(:draw_text!).with { |t, _| t == "hdr1"}.in_sequence(seq)
@pdf.expects(:draw_text!).with { |t, _| t == "foo"}.times(29).in_sequence(seq)
# Verify that the changed cell doesn't mutate subsequent pages
@pdf.expects(:draw_text!).with { |t, _| t == "header"}.in_sequence(seq)
@pdf.expects(:draw_text!).with { |t, _| t == "foo"}.times(11).in_sequence(seq)
set_first_page_headers = false
@pdf.table([["header"]] + [["foo"]] * 40, :header => true) do |t|
t.before_rendering_page do |page|
# only change first page header
page[0, 0].content = "hdr1" unless set_first_page_headers
set_first_page_headers = true
end
end
end
end
end
describe "#style" do
it "should send #style to its first argument, passing the style hash and" +
" block" do
stylable = stub()
stylable.expects(:style).with(:foo => :bar).once.yields
block = stub()
block.expects(:kick).once
Prawn::Document.new do
table([["x"]]) { style(stylable, :foo => :bar) { block.kick } }
end
end
it "should default to {} for the hash argument" do
stylable = stub()
stylable.expects(:style).with({}).once
Prawn::Document.new do
table([["x"]]) { style(stylable) }
end
end
end
describe "row_colors" do
it "should allow array syntax for :row_colors" do
data = [["foo"], ["bar"], ["baz"]]
pdf = Prawn::Document.new
t = pdf.table(data, :row_colors => ['cccccc', 'ffffff'])
t.cells.map{|x| x.background_color}.should == %w[cccccc ffffff cccccc]
end
it "should ignore headers" do
data = [["header"], ["foo"], ["bar"], ["baz"]]
pdf = Prawn::Document.new
t = pdf.table(data, :header => true,
:row_colors => ['cccccc', 'ffffff']) do
row(0).background_color = '333333'
end
t.cells.map{|x| x.background_color}.should ==
%w[333333 cccccc ffffff cccccc]
end
it "stripes rows consistently from page to page, skipping header rows" do
data = [["header"]] + [["foo"]] * 70
pdf = Prawn::Document.new
t = pdf.make_table(data, :header => true,
:row_colors => ['cccccc', 'ffffff']) do
cells.padding = 0
cells.size = 9
row(0).size = 11
end
# page 1: header + 67 cells (odd number -- verifies that the next
# page disrupts the even/odd coloring, since both the last data cell
# on this page and the first one on the next are colored cccccc)
Prawn::Table::Cell.expects(:draw_cells).with do |cells|
cells.map { |c, (x, y)| c.background_color } ==
[nil] + (%w[cccccc ffffff] * 33) + %w[cccccc]
end
# page 2: header and 3 data cells
Prawn::Table::Cell.expects(:draw_cells).with do |cells|
cells.map { |c, (x, y)| c.background_color } ==
[nil] + %w[cccccc ffffff cccccc]
end
t.draw
end
it "should_not override an explicit background_color" do
data = [["foo"], ["bar"], ["baz"]]
pdf = Prawn::Document.new
table = pdf.table(data, :row_colors => ['cccccc', 'ffffff']) { |t|
t.cells[0, 0].background_color = 'dddddd'
}
table.cells.map{|x| x.background_color}.should == %w[dddddd ffffff cccccc]
end
end
describe "inking" do
before(:each) do
@pdf = Prawn::Document.new
end
it "should set the x-position of each cell based on widths" do
@table = @pdf.table([["foo", "bar", "baz"]])
x = 0
(0..2).each do |col|
cell = @table.cells[0, col]
cell.x.should == x
x += cell.width
end
end
it "should set the y-position of each cell based on heights" do
y = 0
@table = @pdf.make_table([["foo"], ["bar"], ["baz"]])
(0..2).each do |row|
cell = @table.cells[row, 0]
cell.y.should be_within(0.01).of(y)
y -= cell.height
end
end
it "should output content cell by cell, row by row" do
data = [["foo","bar"],["baz","bang"]]
@pdf = Prawn::Document.new
@pdf.table(data)
output = PDF::Inspector::Text.analyze(@pdf.render)
output.strings.should == data.flatten
end
it "should_not cause an error if rendering the very first row causes a " +
"page break" do
Prawn::Document.new do |pdf|
arr = Array(1..5).collect{|i| ["cell #{i}"] }
pdf.move_down( pdf.y - (pdf.bounds.absolute_bottom + 3) )
lambda {
pdf.table(arr)
}.should_not raise_error
end
end
it "should draw all backgrounds before any borders" do
# lest backgrounds overlap borders:
# https://github.com/sandal/prawn/pull/226
seq = sequence("drawing_order")
t = @pdf.make_table([["A", "B"]],
:cell_style => {:background_color => 'ff0000'})
ca = t.cells[0, 0]
cb = t.cells[0, 1]
# XXX Not a perfectly general test, because it would still be acceptable
# if we drew B then A
ca.expects(:draw_background).in_sequence(seq)
cb.expects(:draw_background).in_sequence(seq)
ca.expects(:draw_borders).in_sequence(seq)
cb.expects(:draw_borders).in_sequence(seq)
t.draw
end
it "should allow multiple inkings of the same table" do
pdf = Prawn::Document.new
t = Prawn::Table.new([["foo"]], pdf)
pdf.expects(:bounding_box).with{|(x, y), options| y.to_i == 495}.yields
pdf.expects(:bounding_box).with{|(x, y), options| y.to_i == 395}.yields
pdf.expects(:draw_text!).with{ |text, options| text == 'foo' }.twice
pdf.move_cursor_to(500)
t.draw
pdf.move_cursor_to(400)
t.draw
end
describe "in stretchy bounding boxes" do
it "should draw all cells on a row at the same y-position" do
pdf = Prawn::Document.new
text_y = pdf.y.to_i - 5 # text starts 5pt below current y pos (padding)
pdf.bounding_box([0, pdf.cursor], :width => pdf.bounds.width) do
pdf.expects(:draw_text!).checking { |text, options|
pdf.bounds.absolute_top.should == text_y
}.times(3)
pdf.table([%w[a b c]])
end
end
end
end
describe "headers" do
it "should add headers to output when specified" do
data = [["a", "b"], ["foo","bar"],["baz","bang"]]
@pdf = Prawn::Document.new
@pdf.table(data, :header => true)
output = PDF::Inspector::Text.analyze(@pdf.render)
output.strings.should == data.flatten
end
it "should repeat headers across pages" do
data = [["foo","bar"]] * 30
headers = ["baz","foobar"]
@pdf = Prawn::Document.new
@pdf.table([headers] + data, :header => true)
output = PDF::Inspector::Text.analyze(@pdf.render)
output.strings.should == headers + data.flatten[0..-3] + headers +
data.flatten[-2..-1]
end
it "draws headers at the correct position" do
data = [["header"]] + [["foo"]] * 40
Prawn::Table::Cell.expects(:draw_cells).times(2).checking do |cells|
cells.each do |cell, pt|
if cell.content == "header"
# Assert that header text is drawn at the same location on each page
if @header_location
pt.should == @header_location
else
@header_location = pt
end
end
end
end
@pdf = Prawn::Document.new
@pdf.table(data, :header => true)
end
it "should_not draw header twice when starting new page" do
@pdf = Prawn::Document.new
@pdf.y = 0
@pdf.table([["Header"], ["Body"]], :header => true)
output = PDF::Inspector::Text.analyze(@pdf.render)
output.strings.should == ["Header", "Body"]
end
end
describe "nested tables" do
before(:each) do
@pdf = Prawn::Document.new
@subtable = Prawn::Table.new([["foo"]], @pdf)
@table = @pdf.table([[@subtable, "bar"]])
end
it "can be created from an Array" do
cell = Prawn::Table::Cell.make(@pdf, [["foo"]])
cell.should be_a_kind_of(Prawn::Table::Cell::Subtable)
cell.subtable.should be_a_kind_of(Prawn::Table)
end
it "defaults its padding to zero" do
@table.cells[0, 0].padding.should == [0, 0, 0, 0]
end
it "has a subtable accessor" do
@table.cells[0, 0].subtable.should == @subtable
end
it "determines its dimensions from the subtable" do
@table.cells[0, 0].width.should == @subtable.width
@table.cells[0, 0].height.should == @subtable.height
end
end
describe "An invalid table" do
before(:each) do
@pdf = Prawn::Document.new
@bad_data = ["Single Nested Array"]
end
it "should raise_error error when invalid table data is given" do
lambda {
@pdf.table(@bad_data)
}.should raise_error(Prawn::Errors::InvalidTableData)
end
it "should raise_error an EmptyTableError with empty table data" do
lambda {
data = []
@pdf = Prawn::Document.new
@pdf.table(data)
}.should raise_error( Prawn::Errors::EmptyTable )
end
it "should raise_error an EmptyTableError with nil table data" do
lambda {
data = nil
@pdf = Prawn::Document.new
@pdf.table(data)
}.should raise_error( Prawn::Errors::EmptyTable )
end
end
end
describe "colspan / rowspan" do
before(:each) { create_pdf }
it "doesn't raise an error" do
lambda {
@pdf.table([[{:content => "foo", :colspan => 2, :rowspan => 2}]])
}.should_not raise_error
end
it "colspan is properly counted" do
t = @pdf.make_table([[{:content => "foo", :colspan => 2}]])
t.column_length.should == 2
end
it "rowspan is properly counted" do
t = @pdf.make_table([[{:content => "foo", :rowspan => 2}]])
t.row_length.should == 2
end
it "raises if colspan or rowspan are called after layout" do
lambda {
@pdf.table([["foo"]]) { cells[0, 0].colspan = 2 }
}.should raise_error(Prawn::Errors::InvalidTableSpan)
lambda {
@pdf.table([["foo"]]) { cells[0, 0].rowspan = 2 }
}.should raise_error(Prawn::Errors::InvalidTableSpan)
end
it "raises when spans overlap" do
lambda {
@pdf.table([["foo", {:content => "bar", :rowspan => 2}],
[{:content => "baz", :colspan => 2}]])
}.should raise_error(Prawn::Errors::InvalidTableSpan)
end
it "table and cell width account for colspan" do
t = @pdf.table([["a", {:content => "b", :colspan => 2}]],
:column_widths => [100, 100, 100])
spanned = t.cells[0, 1]
spanned.colspan.should == 2
t.width.should == 300
t.cells.min_width.should == 300
t.cells.max_width.should == 300
spanned.width.should == 200
end
it "table and cell height account for rowspan" do
t = @pdf.table([["a"], [{:content => "b", :rowspan => 2}]]) do
row(0..2).height = 100
end
spanned = t.cells[1, 0]
spanned.rowspan.should == 2
t.height.should == 300
spanned.height.should == 200
end
it "provides the full content_width as drawing space" do
w = @pdf.make_table([["foo"]]).cells[0, 0].content_width
t = @pdf.make_table([[{:content => "foo", :colspan => 2}]])
t.cells[0, 0].spanned_content_width.should == w
end
it "dummy cells are not drawn" do
# make a fake master cell for the dummy cell to slave to
t = @pdf.make_table([[{:content => "foo", :colspan => 2}]])
# drawing just a dummy cell should_not ink
@pdf.expects(:stroke_line).never
@pdf.expects(:draw_text!).never
Prawn::Table::Cell.draw_cells([t.cells[0, 1]])
end
it "dummy cells do not add any height or width" do
t1 = @pdf.table([["foo"]])
t2 = @pdf.table([[{:content => "foo", :colspan => 2}]])
t2.width.should == t1.width
t3 = @pdf.table([[{:content => "foo", :rowspan => 2}]])
t3.height.should == t1.height
end
it "dummy cells ignored by #style" do
t = @pdf.table([[{:content => "blah", :colspan => 2}]],
:cell_style => { :size => 9 })
t.cells[0, 0].size.should == 9
end
context "inheriting master cell styles from dummy cell" do
# Relatively full coverage for all these attributes that should be
# inherited.
[["border_X_width", 20],
["border_X_color", "123456"],
["padding_X", 20]].each do |attribute, val|
attribute_right = attribute.sub("X", "right")
attribute_left = attribute.sub("X", "left")
attribute_bottom = attribute.sub("X", "bottom")
attribute_top = attribute.sub("X", "top")
specify "#{attribute_right} of right column is inherited" do
t = @pdf.table([[{:content => "blah", :colspan => 2}]]) do |table|
table.column(1).send("#{attribute_right}=", val)
end
t.cells[0, 0].send(attribute_right).should == val
end
specify "#{attribute_bottom} of bottom row is inherited" do
t = @pdf.table([[{:content => "blah", :rowspan => 2}]]) do |table|
table.row(1).send("#{attribute_bottom}=", val)
end
t.cells[0, 0].send(attribute_bottom).should == val
end
specify "#{attribute_left} of right column is not inherited" do
t = @pdf.table([[{:content => "blah", :colspan => 2}]]) do |table|
table.column(1).send("#{attribute_left}=", val)
end
t.cells[0, 0].send(attribute_left).should_not == val
end
specify "#{attribute_right} of interior column is not inherited" do
t = @pdf.table([[{:content => "blah", :colspan => 3}]]) do |table|
table.column(1).send("#{attribute_right}=", val)
end
t.cells[0, 0].send(attribute_right).should_not == val
end
specify "#{attribute_bottom} of interior row is not inherited" do
t = @pdf.table([[{:content => "blah", :rowspan => 3}]]) do |table|
table.row(1).send("#{attribute_bottom}=", val)
end
t.cells[0, 0].send(attribute_bottom).should_not == val
end
specify "#{attribute_top} of bottom row is not inherited" do
t = @pdf.table([[{:content => "blah", :rowspan => 2}]]) do |table|
table.row(1).send("#{attribute_top}=", val)
end
t.cells[0, 0].send(attribute_top).should_not == val
end
end
end
it "splits natural width between cols in the group" do
t = @pdf.table([[{:content => "foo", :colspan => 2}]])
widths = t.column_widths
widths[0].should == widths[1]
end
it "splits natural width between cols when width is increased" do
t = @pdf.table([[{:content => "foo", :colspan => 2}]],
:width => @pdf.bounds.width)
widths = t.column_widths
widths[0].should == widths[1]
end
it "splits min-width between cols in the group" do
# Since column_widths, when reducing column widths, reduces proportional to
# the remaining width after each column's min width, we must ensure that the
# min-width is split proportionally in order to ensure the width is still
# split evenly when the width is reduced. (See "splits natural width between
# cols when width is reduced".)
t = @pdf.table([[{:content => "foo", :colspan => 2}]],
:width => 20)
t.column(0).min_width.should == t.column(1).min_width
end
it "splits natural width between cols when width is reduced" do
t = @pdf.table([[{:content => "foo", :colspan => 2}]],
:width => 20)
widths = t.column_widths
widths[0].should == widths[1]
end
it "honors a large, explicitly set table width" do
t = @pdf.table([[{:content => "AAAAAAAAAA", :colspan => 3}],
["A", "B", "C"]],
:width => 400)
t.column_widths.inject(0) { |sum, w| sum + w }.
should be_within(0.01).of(400)
end
it "honors a small, explicitly set table width" do
t = @pdf.table([[{:content => "Lorem ipsum dolor sit amet " * 20,
:colspan => 3}],
["A", "B", "C"]],
:width => 200)
t.column_widths.inject(0) { |sum, w| sum + w }.
should be_within(0.01).of(200)
end
it "splits natural_content_height between rows in the group" do
t = @pdf.table([[{:content => "foo", :rowspan => 2}]])
heights = t.row_heights
heights[0].should == heights[1]
end
it "skips column numbers that have been col-spanned" do
t = @pdf.table([["a", "b", {:content => "c", :colspan => 3}, "d"]])
t.cells[0, 0].content.should == "a"
t.cells[0, 1].content.should == "b"
t.cells[0, 2].content.should == "c"
t.cells[0, 3].should be_a_kind_of(Prawn::Table::Cell::SpanDummy)
t.cells[0, 4].should be_a_kind_of(Prawn::Table::Cell::SpanDummy)
t.cells[0, 5].content.should == "d"
end
it "skips row/col positions that have been row-spanned" do
t = @pdf.table([["a", {:content => "b", :colspan => 2, :rowspan => 2}, "c"],
["d", "e"],
["f", "g", "h", "i"]])
t.cells[0, 0].content.should == "a"
t.cells[0, 1].content.should == "b"
t.cells[0, 2].should be_a_kind_of(Prawn::Table::Cell::SpanDummy)
t.cells[0, 3].content.should == "c"
t.cells[1, 0].content.should == "d"
t.cells[1, 1].should be_a_kind_of(Prawn::Table::Cell::SpanDummy)
t.cells[1, 2].should be_a_kind_of(Prawn::Table::Cell::SpanDummy)
t.cells[1, 3].content.should == "e"
t.cells[2, 0].content.should == "f"
t.cells[2, 1].content.should == "g"
t.cells[2, 2].content.should == "h"
t.cells[2, 3].content.should == "i"
end
end
ruby-prawn-1.0.0~rc2.orig/spec/extensions/ 0000755 0000000 0000000 00000000000 12114176157 017216 5 ustar root root ruby-prawn-1.0.0~rc2.orig/spec/extensions/encoding_helpers.rb 0000644 0000000 0000000 00000000166 12114176157 023056 0 ustar root root module EncodingHelpers
def win1252_string(str)
ruby_19 { str.force_encoding("Windows-1252") }
str
end
end
ruby-prawn-1.0.0~rc2.orig/spec/extensions/mocha.rb 0000644 0000000 0000000 00000002266 12114176157 020640 0 ustar root root # Allow speccing things when an expectation matcher runs. Similar to #with, but
# always succeeds.
#
# @pdf.expects(:stroke_line).checking do |from, to|
# @pdf.map_to_absolute(from).should == [0, 0]
# end
#
# Note that the outer expectation does *not* fail only because the inner one
# does; in the above example, the outer expectation would only fail if
# stroke_line were not called.
class ParameterChecker < Mocha::ParametersMatcher
def initialize(&matching_block)
@expected_parameters = [Mocha::ParameterMatchers::AnyParameters.new]
@matching_block = matching_block
end
def match?(actual_parameters = [])
@matching_block.call(*actual_parameters)
true # always succeed
end
end
class Mocha::Expectation
def checking(&block)
@parameters_matcher = ParameterChecker.new(&block)
self
end
end
# Equivalent to expects(method_name).at_least(0). More useful when combined
# with parameter matchers to ignore certain calls for the sake of parameter
# matching.
#
# @pdf.ignores(:stroke_color=).with("000000")
# @pdf.expects(:stroke_color=).with("ff0000")
#
module Mocha::ObjectMethods
def ignores(method_name)
expects(method_name).at_least(0)
end
end
ruby-prawn-1.0.0~rc2.orig/spec/name_tree_spec.rb 0000644 0000000 0000000 00000010301 12114176157 020310 0 ustar root root require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
def tree_dump(tree)
if tree.is_a?(Prawn::Core::NameTree::Node)
"[" + tree.children.map { |child| tree_dump(child) }.join(",") + "]"
else
"#{tree.name}=#{tree.value}"
end
end
def tree_add(tree, *args)
args.each do |(name, value)|
tree.add(name, value)
end
end
def tree_value(name, value)
Prawn::Core::NameTree::Value.new(name, value)
end
class RefExposingDocument < Prawn::Document
def object_store
state.store
end
end
describe "Name Tree" do
before(:each) { create_pdf(RefExposingDocument) }
it "should have no children when first initialized" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
node.children.length.should == 0
end
it "should have no subtrees while child limit is not reached" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3])
tree_dump(node).should == "[one=1,three=3,two=2]"
end
it "should split into subtrees when limit is exceeded" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
tree_dump(node).should == "[[four=4,one=1],[three=3,two=2]]"
end
it "should create a two new references when root is split" do
ref_count = @pdf.object_store.length
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
@pdf.object_store.length.should == ref_count+2
end
it "should create a one new reference when subtree is split" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
ref_count = @pdf.object_store.length # save when root is split
tree_add(node, ["five", 5], ["six", 6], ["seven", 7])
tree_dump(node).should == "[[five=5,four=4,one=1],[seven=7,six=6],[three=3,two=2]]"
@pdf.object_store.length.should == ref_count+1
end
it "should keep tree balanced when subtree split cascades to root" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
tree_add(node, ["five", 5], ["six", 6], ["seven", 7], ["eight", 8])
tree_dump(node).should == "[[[eight=8,five=5],[four=4,one=1]],[[seven=7,six=6],[three=3,two=2]]]"
end
it "should maintain order of already properly ordered nodes" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["eight", 8], ["five", 5], ["four", 4], ["one", 1])
tree_add(node, ['seven', 7], ['six', 6], ['three', 3], ['two', 2])
tree_dump(node).should == "[[[eight=8,five=5],[four=4,one=1]],[[seven=7,six=6],[three=3,two=2]]]"
end
it "should emit only :Names key with to_hash if root is only node" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3])
node.to_hash.should ==(
{ :Names => [tree_value("one", 1), tree_value("three", 3), tree_value("two", 2)] }
)
end
it "should emit only :Kids key with to_hash if root has children" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
node.to_hash.should ==({ :Kids => node.children.map { |child| child.ref } })
end
it "should emit :Limits and :Names keys with to_hash for leaf node" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
node.children.first.to_hash.should ==(
{ :Limits => %w(four one),
:Names => [tree_value("four", 4), tree_value("one", 1)] }
)
end
it "should emit :Limits and :Kids keys with to_hash for inner node" do
node = Prawn::Core::NameTree::Node.new(@pdf, 3)
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
tree_add(node, ["five", 5], ["six", 6], ["seven", 7], ["eight", 8])
tree_add(node, ["nine", 9], ["ten", 10], ["eleven", 11], ["twelve", 12])
tree_add(node, ["thirteen", 13], ["fourteen", 14], ["fifteen", 15], ["sixteen", 16])
node.children.first.to_hash.should ==(
{ :Limits => %w(eight one),
:Kids => node.children.first.children.map { |child| child.ref } }
)
end
end
ruby-prawn-1.0.0~rc2.orig/spec/text_box_spec.rb 0000644 0000000 0000000 00000105606 12114176157 020222 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Text::Box#nothing_printed?" do
it "should be_true when nothing printed" do
create_pdf
string = "Hello world, how are you?\nI'm fine, thank you."
text_box = Prawn::Text::Box.new(string,
:height => 2,
:document => @pdf)
text_box.render
text_box.nothing_printed?.should be_true
end
it "should be_false when something printed" do
create_pdf
string = "Hello world, how are you?\nI'm fine, thank you."
text_box = Prawn::Text::Box.new(string,
:height => 14,
:document => @pdf)
text_box.render
text_box.nothing_printed?.should be_false
end
end
describe "Text::Box#everything_printed?" do
it "should be_false when not everything printed" do
create_pdf
string = "Hello world, how are you?\nI'm fine, thank you."
text_box = Prawn::Text::Box.new(string,
:height => 14,
:document => @pdf)
text_box.render
text_box.everything_printed?.should be_false
end
it "should be_true when everything printed" do
create_pdf
string = "Hello world, how are you?\nI'm fine, thank you."
text_box = Prawn::Text::Box.new(string,
:document => @pdf)
text_box.render
text_box.everything_printed?.should be_true
end
end
describe "Text::Box#line_gap" do
it "should == the line gap of the font when using a single " +
"font and font size" do
create_pdf
string = "Hello world, how are you?\nI'm fine, thank you."
text_box = Prawn::Text::Box.new(string,
:document => @pdf)
text_box.render
text_box.line_gap.should be_within(0.0001).of(@pdf.font.line_gap)
end
end
describe "Text::Box" do
it "should be able to set text direction document-wide" do
create_pdf
@pdf.text_direction(:rtl)
@pdf.text_direction = :rtl
string = "Hello world, how are you?\nI'm fine, thank you."
text_box = Prawn::Text::Box.new(string,
:document => @pdf)
text_box.render
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == "?uoy era woh ,dlrow olleH"
text.strings[1].should == ".uoy knaht ,enif m'I"
end
it "should be able to reverse multi-byte text" do
create_pdf
@pdf.text_direction(:rtl)
@pdf.text_direction = :rtl
@pdf.text_direction = :rtl
@pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf", :size => 16) do
@pdf.text "写个小"
end
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == "小个写"
end
it "option should be able to override document-wide text direction" do
create_pdf
@pdf.text_direction = :rtl
string = "Hello world, how are you?\nI'm fine, thank you."
text_box = Prawn::Text::Box.new(string,
:document => @pdf,
:direction => :ltr)
text_box.render
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == "Hello world, how are you?"
text.strings[1].should == "I'm fine, thank you."
end
end
describe "Text::Box" do
it "should be able to set leading document-wide" do
create_pdf
@pdf.default_leading(7)
@pdf.default_leading = 7
text_box = Prawn::Text::Box.new("hello world",
:document => @pdf)
text_box.leading.should == 7
end
it "option should be able to override document-wide leading" do
create_pdf
@pdf.default_leading = 7
text_box = Prawn::Text::Box.new("hello world",
:document => @pdf,
:leading => 20)
text_box.leading.should == 20
end
it "should default to document-wide leading if no" +
"leading option is provided" do
end
end
describe "Text::Box#render with :align => :justify" do
it "should draw the word spacing to the document" do
create_pdf
string = "hello world " * 20
options = { :document => @pdf, :align => :justify }
text_box = Prawn::Text::Box.new(string, options)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.word_spacing[0].should be > 0
end
it "should not justify the last line of a paragraph" do
create_pdf
string = "hello world "
options = { :document => @pdf, :align => :justify }
text_box = Prawn::Text::Box.new(string, options)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.word_spacing.should be_empty
end
end
describe "Text::Box" do
it "should only require enough space for the descender and the ascender " +
"when determining whether a line can fit" do
create_pdf
text = "Oh hai text rect"
options = { :document => @pdf, :height => @pdf.font.ascender + @pdf.font.descender }
text_box = Prawn::Text::Box.new(text, options)
text_box.render
text_box.text.should == "Oh hai text rect"
text = "Oh hai text rect\nOh hai text rect"
options = { :document => @pdf, :height => @pdf.font.height + @pdf.font.ascender + @pdf.font.descender }
text_box = Prawn::Text::Box.new(text, options)
text_box.render
text_box.text.should == "Oh hai text rect\nOh hai text rect"
end
end
describe "Text::Box#height without leading" do
it "should == the sum of the height of each line, " +
"not including the space below the last line" do
create_pdf
text = "Oh hai text rect.\nOh hai text rect."
options = { :document => @pdf }
text_box = Prawn::Text::Box.new(text, options)
text_box.render
text_box.height.should be_within(0.001).of(@pdf.font.height * 2 - @pdf.font.line_gap)
end
end
describe "Text::Box#height with leading" do
it "should == the sum of the height of each line plus leading, " +
"but not including the space below the last line" do
create_pdf
text = "Oh hai text rect.\nOh hai text rect."
leading = 12
options = { :document => @pdf, :leading => leading }
text_box = Prawn::Text::Box.new(text, options)
text_box.render
text_box.height.should be_within(0.001).of((@pdf.font.height + leading) * 2 - @pdf.font.line_gap - leading)
end
end
describe "Text::Box with :draw_text_callback" do
before(:each) { create_pdf }
it "hits the callback whenever text is drawn" do
draw_block = stub()
draw_block.expects(:kick).with("this text is long enough to")
draw_block.expects(:kick).with("span two lines")
@pdf.text_box "this text is long enough to span two lines",
:width => 150,
:draw_text_callback => lambda { |text, _| draw_block.kick(text) }
end
it "hits the callback once per fragment for :inline_format" do
draw_block = stub()
draw_block.expects(:kick).with("this text has ")
draw_block.expects(:kick).with("fancy")
draw_block.expects(:kick).with(" formatting")
@pdf.text_box "this text has fancy formatting",
:inline_format => true, :width => 500,
:draw_text_callback => lambda { |text, _| draw_block.kick(text) }
end
it "does not call #draw_text!" do
@pdf.expects(:draw_text!).never
@pdf.text_box "some text", :width => 500,
:draw_text_callback => lambda { |_, _| }
end
end
describe "Text::Box#valid_options" do
it "should return an array" do
create_pdf
text_box = Prawn::Text::Box.new("", :document => @pdf)
text_box.valid_options.should be_a_kind_of(Array)
end
end
describe "Text::Box#render" do
it "should not fail if height is smaller than 1 line" do
create_pdf
@text = "Oh hai text rect. " * 10
@options = {
:height => @pdf.font.height * 0.5,
:document => @pdf
}
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.text.should == ""
end
it "should draw content to the page" do
create_pdf
@text = "Oh hai text rect. " * 10
@options = { :document => @pdf }
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.should_not be_empty
end
it "should not draw a transformation matrix" do
create_pdf
@text = "Oh hai text rect. " * 10
@options = { :document => @pdf }
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
matrices.matrices.length.should == 0
end
end
describe "Text::Box#render(:single_line => true)" do
it "should draw only one line to the page" do
create_pdf
@text = "Oh hai text rect. " * 10
@options = { :document => @pdf,
:single_line => true }
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.length.should == 1
end
end
describe "Text::Box#render(:dry_run => true)" do
it "should not draw any content to the page" do
create_pdf
@text = "Oh hai text rect. " * 10
@options = { :document => @pdf }
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render(:dry_run => true)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.should be_empty
end
it "subsequent calls to render should_not raise_error an ArgumentError exception" do
create_pdf
@text = "™©"
@options = { :document => @pdf }
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render(:dry_run => true)
lambda { text_box.render }.should_not raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
end
describe "Text::Box#render(:valign => :bottom)" do
it "#at should be the same from one dry run to the next" do
create_pdf
text = "this is center text " * 12
options = { :width => 162,
:valign => :bottom,
:document => @pdf }
text_box = Prawn::Text::Box.new(text, options)
text_box.render(:dry_run => true)
original_at = text_box.at.dup
text_box.render(:dry_run => true)
text_box.at.should == original_at
end
end
describe "Text::Box#render(:valign => :center)" do
it "#at should be the same from one dry run to the next" do
create_pdf
text = "this is center text " * 12
options = { :width => 162,
:valign => :center,
:document => @pdf }
text_box = Prawn::Text::Box.new(text, options)
text_box.render(:dry_run => true)
original_at = text_box.at.dup
text_box.render(:dry_run => true)
text_box.at.should == original_at
end
end
describe "Text::Box#render with :rotate option of 30)" do
before(:each) do
create_pdf
rotate = 30
@x = 300
@y = 70
@width = 100
@height = 50
@cos = Math.cos(rotate * Math::PI / 180)
@sin = Math.sin(rotate * Math::PI / 180)
@text = "Oh hai text rect. " * 10
@options = { :document => @pdf,
:rotate => rotate,
:at => [@x, @y],
:width => @width,
:height => @height }
end
context ":rotate_around option of :center" do
it "should draw content to the page rotated about the center of the text" do
@options[:rotate_around] = :center
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
x = @x + @width / 2
y = @y - @height / 2
x_prime = x * @cos - y * @sin
y_prime = x * @sin + y * @cos
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(x - x_prime),
reduce_precision(y - y_prime)]
matrices.matrices[1].should == [reduce_precision(@cos),
reduce_precision(@sin),
reduce_precision(-@sin),
reduce_precision(@cos), 0, 0]
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.should_not be_empty
end
end
context ":rotate_around option of :upper_left" do
it "should draw content to the page rotated about the upper left corner of the text" do
@options[:rotate_around] = :upper_left
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
x = @x
y = @y
x_prime = x * @cos - y * @sin
y_prime = x * @sin + y * @cos
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(x - x_prime),
reduce_precision(y - y_prime)]
matrices.matrices[1].should == [reduce_precision(@cos),
reduce_precision(@sin),
reduce_precision(-@sin),
reduce_precision(@cos), 0, 0]
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.should_not be_empty
end
end
context "default :rotate_around" do
it "should draw content to the page rotated about the upper left corner of the text" do
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
x = @x
y = @y
x_prime = x * @cos - y * @sin
y_prime = x * @sin + y * @cos
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(x - x_prime),
reduce_precision(y - y_prime)]
matrices.matrices[1].should == [reduce_precision(@cos),
reduce_precision(@sin),
reduce_precision(-@sin),
reduce_precision(@cos), 0, 0]
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.should_not be_empty
end
end
context ":rotate_around option of :upper_right" do
it "should draw content to the page rotated about the upper right corner of the text" do
@options[:rotate_around] = :upper_right
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
x = @x + @width
y = @y
x_prime = x * @cos - y * @sin
y_prime = x * @sin + y * @cos
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(x - x_prime),
reduce_precision(y - y_prime)]
matrices.matrices[1].should == [reduce_precision(@cos),
reduce_precision(@sin),
reduce_precision(-@sin),
reduce_precision(@cos), 0, 0]
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.should_not be_empty
end
end
context ":rotate_around option of :lower_right" do
it "should draw content to the page rotated about the lower right corner of the text" do
@options[:rotate_around] = :lower_right
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
x = @x + @width
y = @y - @height
x_prime = x * @cos - y * @sin
y_prime = x * @sin + y * @cos
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(x - x_prime),
reduce_precision(y - y_prime)]
matrices.matrices[1].should == [reduce_precision(@cos),
reduce_precision(@sin),
reduce_precision(-@sin),
reduce_precision(@cos), 0, 0]
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.should_not be_empty
end
end
context ":rotate_around option of :lower_left" do
it "should draw content to the page rotated about the lower left corner of the text" do
@options[:rotate_around] = :lower_left
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
x = @x
y = @y - @height
x_prime = x * @cos - y * @sin
y_prime = x * @sin + y * @cos
matrices.matrices[0].should == [1, 0, 0, 1,
reduce_precision(x - x_prime),
reduce_precision(y - y_prime)]
matrices.matrices[1].should == [reduce_precision(@cos),
reduce_precision(@sin),
reduce_precision(-@sin),
reduce_precision(@cos), 0, 0]
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.should_not be_empty
end
end
end
describe "Text::Box default height" do
before(:each) { create_pdf }
it "should be the height from the bottom bound to document.y" do
target_height = @pdf.y - @pdf.bounds.bottom
@text = "Oh hai\n" * 60
text_box = Prawn::Text::Box.new(@text, :document => @pdf)
text_box.render
text_box.height.should be_within(@pdf.font.height).of(target_height)
end
it "should use the margin-box bottom if only in a stretchy bbox" do
@pdf.bounding_box([0, @pdf.cursor], :width => @pdf.bounds.width) do
target_height = @pdf.y - @pdf.bounds.bottom
@text = "Oh hai\n" * 60
text_box = Prawn::Text::Box.new(@text, :document => @pdf)
text_box.render
text_box.height.should be_within(@pdf.font.height).of(target_height)
end
end
it "should use the parent-box bottom if in a stretchy bbox and " +
"overflow is :expand, even with an explicit height"do
@pdf.bounding_box([0, @pdf.cursor], :width => @pdf.bounds.width) do
target_height = @pdf.y - @pdf.bounds.bottom
@text = "Oh hai\n" * 60
text_box = Prawn::Text::Box.new(@text, :document => @pdf,
:height => 100, :overflow => :expand)
text_box.render
text_box.height.should be_within(@pdf.font.height).of(target_height)
end
end
it "should use the innermost non-stretchy bbox, not the margin box" do
@pdf.bounding_box([0, @pdf.cursor], :width => @pdf.bounds.width,
:height => 200) do
@pdf.bounding_box([0, @pdf.cursor], :width => @pdf.bounds.width) do
@text = "Oh hai\n" * 60
text_box = Prawn::Text::Box.new(@text, :document => @pdf)
text_box.render
text_box.height.should be_within(@pdf.font.height).of(200)
end
end
end
end
describe "Text::Box default at" do
it "should be the left corner of the bounds, and the current document.y" do
create_pdf
target_at = [@pdf.bounds.left, @pdf.y]
@text = "Oh hai text rect. " * 100
@options = { :document => @pdf }
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.at.should == target_at
end
end
describe "Text::Box with text than can fit in the box" do
before(:each) do
create_pdf
@text = "Oh hai text rect. " * 10
@options = {
:width => 162.0,
:height => 162.0,
:document => @pdf
}
end
it "printed text should match requested text, except that preceding and " +
"trailing white space will be stripped from each line, and newlines may " +
"be inserted" do
text_box = Prawn::Text::Box.new(" " + @text, @options)
text_box.render
text_box.text.gsub("\n", " ").should == @text.strip
end
it "render should return an empty string because no text remains unprinted" do
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render.should == ""
end
it "should be truncated when the leading is set high enough to prevent all the lines from being printed" do
@options[:leading] = 40
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.text.gsub("\n", " ").should_not == @text.strip
end
end
describe "Text::Box with text that fits exactly in the box" do
before(:each) do
create_pdf
@lines = 3
@interlines = @lines - 1
@text = (1..@lines).to_a.join("\n")
@options = {
:width => 162.0,
:height => @pdf.font.ascender + @pdf.font.height * @interlines + @pdf.font.descender,
:document => @pdf
}
end
it "should have the expected height" do
expected_height = @options.delete(:height)
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.height.should be_within(0.0001).of(expected_height)
end
it "should print everything" do
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.text.should == @text
end
describe "with leading" do
before(:each) do
@options[:leading] = 15
end
it "should not overflow when enough height is added" do
@options[:height] += @options[:leading] * @interlines
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.text.should == @text
end
it "should overflow when insufficient height is added" do
@options[:height] += @options[:leading] * @interlines - 1
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.text.should_not == @text
end
end
describe "with negative leading" do
before(:each) do
@options[:leading] = -4
end
it "should not overflow when enough height is removed" do
@options[:height] += @options[:leading] * @interlines
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.text.should == @text
end
it "should overflow when too much height is removed" do
@options[:height] += @options[:leading] * @interlines - 1
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.text.should_not == @text
end
end
end
describe "Text::Box printing UTF-8 string with higher bit characters" do
before(:each) do
create_pdf
@text = "©"
# not enough height to print any text, so we can directly compare against
# the input string
bounding_height = 1.0
options = {
:height => bounding_height,
:document => @pdf
}
file = "#{Prawn::DATADIR}/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" }
}
@text_box = Prawn::Text::Box.new(@text, options)
end
describe "when using a TTF font" do
it "unprinted text should be in UTF-8 encoding" do
@pdf.font("Action Man")
remaining_text = @text_box.render
remaining_text.should == @text
end
it "subsequent calls to Text::Box need not include the" +
" :skip_encoding => true option" do
@pdf.font("Action Man")
remaining_text = @text_box.render
lambda {
@pdf.text_box(remaining_text, :document => @pdf)
}.should_not raise_error(Prawn::Errors::IncompatibleStringEncoding)
end
end
describe "when using an AFM font" do
it "unprinted text should be in WinAnsi encoding" do
remaining_text = @text_box.render
remaining_text.should == @pdf.font.normalize_encoding(@text)
end
it "subsequent calls to Text::Box must include the" +
" :skip_encoding => true option" do
remaining_text = @text_box.render
lambda {
@pdf.text_box(remaining_text, :document => @pdf)
}.should raise_error(Prawn::Errors::IncompatibleStringEncoding)
lambda {
@pdf.text_box(remaining_text, :skip_encoding => true,
:document => @pdf)
}.should_not raise_error(Prawn::Errors::IncompatibleStringEncoding)
end
end
end
describe "Text::Box with more text than can fit in the box" do
before(:each) do
create_pdf
@text = "Oh hai text rect. " * 30
@bounding_height = 162.0
@options = {
:width => 162.0,
:height => @bounding_height,
:document => @pdf
}
end
context "truncated overflow" do
before(:each) do
@options[:overflow] = :truncate
@text_box = Prawn::Text::Box.new(@text, @options)
end
it "should be truncated" do
@text_box.render
@text_box.text.gsub("\n", " ").should_not == @text.strip
end
it "render should not return an empty string because some text remains unprinted" do
@text_box.render.should_not be_empty
end
it "#height should be no taller than the specified height" do
@text_box.render
@text_box.height.should be <= @bounding_height
end
it "#height should be within one font height of the specified height" do
@text_box.render
@bounding_height.should be_within(@pdf.font.height).of(@text_box.height)
end
context "with :rotate option" do
it "unrendered text should be the same as when not rotated" do
remaining_text = @text_box.render
rotate = 30
x = 300
y = 70
width = @options[:width]
height = @options[:height]
@options[:document] = @pdf
@options[:rotate] = rotate
@options[:at] = [x, y]
rotated_text_box = Prawn::Text::Box.new(@text, @options)
rotated_text_box.render.should == remaining_text
end
end
end
context "truncated with text and size taken from the manual" do
it "should return the right text" do
@text = "This is the beginning of the text. It will be cut somewhere and " +
"the rest of the text will procede to be rendered this time by " +
"calling another method." + " . " * 50
@options[:width] = 300
@options[:height] = 50
@options[:size] = 18
@text_box = Prawn::Text::Box.new(@text, @options)
remaining_text = @text_box.render
remaining_text.should == "text will procede to be rendered this time by calling another method. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
end
end
context "expand overflow" do
before(:each) do
@options[:overflow] = :expand
@text_box = Prawn::Text::Box.new(@text, @options)
end
it "height should expand to encompass all the text (but not exceed the height of the page)" do
@text_box.render
@text_box.height.should > @bounding_height
end
it "should display the entire string (as long as there was space remaining on the page to print all the text)" do
@text_box.render
@text_box.text.gsub("\n", " ").should == @text.strip
end
it "render should return an empty string because no text remains unprinted(as long as there was space remaining on the page to print all the text)" do
@text_box.render.should == ""
end
end
context "shrink_to_fit overflow" do
before(:each) do
@options[:overflow] = :shrink_to_fit
@options[:min_font_size] = 2
@text_box = Prawn::Text::Box.new(@text, @options)
end
it "should display the entire text" do
@text_box.render
@text_box.text.gsub("\n", " ").should == @text.strip
end
it "render should return an empty string because no text remains unprinted" do
@text_box.render.should == ""
end
end
context "shrink_to_fit overflow" do
it "should not drop below the minimum font size" do
@options[:overflow] = :shrink_to_fit
@options[:min_font_size] = 10.1
@text_box = Prawn::Text::Box.new(@text, @options)
@text_box.render
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 10.1
end
end
end
describe "Text::Box with enough space to fit the text but using the " +
"shrink_to_fit overflow" do
it "should not shrink the text when there is no need to" do
create_pdf
@bounding_height = 162.0
@options = {
:width => 162.0,
:height => @bounding_height,
:overflow => :shrink_to_fit,
:min_font_size => 5,
:document => @pdf
}
@text_box = Prawn::Text::Box.new("hello\nworld", @options)
@text_box.render
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 12
end
end
describe "Text::Box with a solid block of Chinese characters" do
it "printed text should match requested text, except for newlines" do
create_pdf
@text = "写中国字" * 10
@options = {
:width => 162.0,
:height => 162.0,
:document => @pdf
}
@pdf.font "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
@options[:overflow] = :truncate
text_box = Prawn::Text::Box.new(@text, @options)
text_box.render
text_box.text.gsub("\n", "").should == @text
end
end
describe "drawing bounding boxes" do
before(:each) { create_pdf }
it "should restore the margin box when bounding box exits" do
margin_box = @pdf.bounds
@pdf.text_box "Oh hai text box. " * 11, :height => @pdf.font.height * 10
@pdf.bounds.should == margin_box
end
end
describe "Text::Box#render with :character_spacing option" do
it "should draw the character spacing to the document" do
create_pdf
string = "hello world"
options = { :document => @pdf, :character_spacing => 10 }
text_box = Prawn::Text::Box.new(string, options)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.character_spacing[0].should == 10
end
it "should take character spacing into account when wrapping" do
create_pdf
@pdf.font "Courier"
text_box = Prawn::Text::Box.new("hello world",
:width => 100,
:overflow => :expand,
:character_spacing => 10,
:document => @pdf)
text_box.render
text_box.text.should == "hello\nworld"
end
end
describe "Text::Box wrapping" do
before(:each) do
create_pdf
end
it "should wrap text" do
text = "Please wrap this text about HERE. More text that should be wrapped"
expect = "Please wrap this text about\nHERE. More text that should be\nwrapped"
@pdf.font "Courier"
text_box = Prawn::Text::Box.new(text,
:width => 220,
:overflow => :expand,
:document => @pdf)
text_box.render
text_box.text.should == expect
end
# white space was being stripped after the entire line was generated, meaning
# that leading white space characters reduced the amount of space on the line
# for other characters, so wrapping "hello hello" resulted in
# "hello\n\nhello", rather than "hello\nhello"
#
it "white space at beginning of line should not be taken into account when" +
" computing line width" do
text = "hello hello"
expect = "hello\nhello"
@pdf.font "Courier"
text_box = Prawn::Text::Box.new(text,
:width => 40,
:overflow => :expand,
:document => @pdf)
text_box.render
text_box.text.should == expect
end
it "should respect end of line when wrapping text" do
text = "Please wrap only before\nTHIS word. Don't wrap this"
expect = text
@pdf.font "Courier"
text_box = Prawn::Text::Box.new(text,
:width => 220,
:overflow => :expand,
:document => @pdf)
text_box.render
text_box.text.should == expect
end
it "should respect multiple newlines when wrapping text" do
text = "Please wrap only before THIS\n\nword. Don't wrap this"
expect= "Please wrap only before\nTHIS\n\nword. Don't wrap this"
@pdf.font "Courier"
text_box = Prawn::Text::Box.new(text,
:width => 200,
:overflow => :expand,
:document => @pdf)
text_box.render
text_box.text.should == expect
end
it "should respect multiple newlines when wrapping text when those newlines coincide with a line break" do
text = "Please wrap only before\n\nTHIS word. Don't wrap this"
expect = text
@pdf.font "Courier"
text_box = Prawn::Text::Box.new(text,
:width => 220,
:overflow => :expand,
:document => @pdf)
text_box.render
text_box.text.should == expect
end
it "should respect initial newlines" do
text = "\nThis should be on line 2"
expect = text
@pdf.font "Courier"
text_box = Prawn::Text::Box.new(text,
:width => 220,
:overflow => :expand,
:document => @pdf)
text_box.render
text_box.text.should == expect
end
it "should wrap lines comprised of a single word of the bounds when wrapping text" do
text = "You_can_wrap_this_text_HERE"
expect = "You_can_wrap_this_text_HE\nRE"
@pdf.font "Courier"
text_box = Prawn::Text::Box.new(text,
:width => 180,
:overflow => :expand,
:document => @pdf)
text_box.render
text_box.text.should == expect
end
it "should wrap lines comprised of a single word of the bounds when wrapping text" do
text = "©" * 30
@pdf.font "Courier"
text_box = Prawn::Text::Box.new(text, :width => 180,
:overflow => :expand,
:document => @pdf)
text_box.render
expected = "©" * 25 + "\n" + "©" * 5
@pdf.font.normalize_encoding!(expected)
expected = expected.force_encoding("utf-8") if expected.respond_to?(:force_encoding)
text_box.text.should == expected
end
it "should wrap non-unicode strings using single-byte word-wrapping" do
text = "continúa esforzandote " * 5
text_box = Prawn::Text::Box.new(text, :width => 180,
:document => @pdf)
text_box.render
results_with_accent = text_box.text
text = "continua esforzandote " * 5
text_box = Prawn::Text::Box.new(text, :width => 180,
:document => @pdf)
text_box.render
results_without_accent = text_box.text
results_with_accent.first_line.length.should == results_without_accent.first_line.length
end
end
describe "Text::Box#render with :mode option" do
it "should alter the text rendering mode of the document" do
create_pdf
string = "hello world"
options = { :document => @pdf, :mode => :fill_stroke }
text_box = Prawn::Text::Box.new(string, options)
text_box.render
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.text_rendering_mode.should == [2,0]
end
end
def reduce_precision(float)
("%.5f" % float).to_f
end
ruby-prawn-1.0.0~rc2.orig/spec/text_spec.rb 0000644 0000000 0000000 00000034245 12114176157 017352 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Prawn::Text::NBSP" do
it "should be defined" do
Prawn::Text::NBSP.should == " "
end
end
describe "#height_of" do
before(:each) { create_pdf }
it "should return the height that would be required to print a" +
"particular string of text" do
original_y = @pdf.y
@pdf.text("Foo")
new_y = @pdf.y
@pdf.height_of("Foo").should be_within(0.0001).of(original_y - new_y)
end
it "should omit the gap below the last descender if :final_gap => false " +
"is given" do
original_y = @pdf.y
@pdf.text("Foo", :final_gap => false)
new_y = @pdf.y
@pdf.height_of("Foo", :final_gap => false).should be_within(0.0001).of(original_y - new_y)
end
it "should raise_error CannotFit if a too-small width is given" do
lambda do
@pdf.height_of("text", :width => 1)
end.should raise_error(Prawn::Errors::CannotFit)
end
it "should raise_error NotImplementedError if :indent_paragraphs option is provided" do
lambda {
@pdf.height_of("hai", :width => 300,
:indent_paragraphs => 60)
}.should raise_error(NotImplementedError)
end
it "should_not raise_error Prawn::Errors::UnknownOption if :final_gap option is provided" do
lambda {
@pdf.height_of("hai", :width => 300,
:final_gap => true)
}.should_not raise_error(Prawn::Errors::UnknownOption)
end
end
describe "#text" do
before(:each) { create_pdf }
it "should not fail when @output is nil when Prawn::Core::Text::LineWrap#finalize_line is called" do
# need a document with margins for these particulars to produce the
# condition that was throwing the error
pdf = Prawn::Document.new
lambda {
pdf.text "transparency " * 150, :size => 18
}.should_not raise_error(TypeError)
end
it "should allow drawing empty strings to the page" do
@pdf.text " "
text = PDF::Inspector::Text.analyze(@pdf.render)
# If anything is rendered to the page, it should be whitespace.
text.strings.each { |str| str.should =~ /\A\s*\z/ }
end
it "should ignore call when string is nil" do
@pdf.text(nil).should be_false
end
it "should correctly render empty paragraphs" do
@pdf.text "text\n\ntext"
text = PDF::Inspector::Text.analyze(@pdf.render)
@pdf.page_count.should == 1
text.strings.reject{ |s| s.empty? }.should == ["text", "text"]
end
it "should correctly render empty paragraphs with :indent_paragraphs" do
@pdf.text "text\n\ntext", :indent_paragraphs => 5
text = PDF::Inspector::Text.analyze(@pdf.render)
@pdf.page_count.should == 1
text.strings.reject{ |s| s.empty? }.should == ["text", "text"]
end
it "should correctly render strings ending with empty paragraphs and " +
":inline_format and :indent_paragraphs" do
@pdf.text "text\n\n", :inline_format => true, :indent_paragraphs => 5
text = PDF::Inspector::Text.analyze(@pdf.render)
@pdf.page_count.should == 1
text.strings.should == ["text"]
end
it "should default to use kerning information" do
@pdf.text "hello world"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.kerned[0].should be_true
end
it "should be able to disable kerning with an option" do
@pdf.text "hello world", :kerning => false
text = PDF::Inspector::Text.analyze(@pdf.render)
text.kerned[0].should be_false
end
it "should be able to disable kerning document-wide" do
@pdf.default_kerning(false)
@pdf.default_kerning = false
@pdf.text "hello world"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.kerned[0].should be_false
end
it "option should be able to override document-wide kerning disabling" do
@pdf.default_kerning = false
@pdf.text "hello world", :kerning => true
text = PDF::Inspector::Text.analyze(@pdf.render)
text.kerned[0].should be_true
end
it "should raise_error ArgumentError if :at option included" do
lambda { @pdf.text("hai", :at => [0, 0]) }.should raise_error(ArgumentError)
end
it "should advance down the document based on font_height" do
position = @pdf.y
@pdf.text "Foo"
@pdf.y.should be_within(0.0001).of(position - @pdf.font.height)
position = @pdf.y
@pdf.text "Foo\nBar\nBaz"
@pdf.y.should be_within(0.0001).of(position - 3*@pdf.font.height)
end
it "should advance down the document based on font_height" +
" with size option" do
position = @pdf.y
@pdf.text "Foo", :size => 15
@pdf.font_size = 15
@pdf.y.should be_within(0.0001).of(position - @pdf.font.height)
position = @pdf.y
@pdf.text "Foo\nBar\nBaz"
@pdf.y.should be_within(0.0001).of(position - 3 * @pdf.font.height)
end
it "should advance down the document based on font_height" +
" with leading option" do
position = @pdf.y
leading = 2
@pdf.text "Foo", :leading => leading
@pdf.y.should be_within(0.0001).of(position - @pdf.font.height - leading)
position = @pdf.y
@pdf.text "Foo\nBar\nBaz"
@pdf.y.should be_within(0.0001).of(position - 3*@pdf.font.height)
end
it "should advance only to the bottom of the final descender "+
"if final_gap is false" do
position = @pdf.y
@pdf.text "Foo", :final_gap => false
@pdf.y.should be_within(0.0001).of(position - @pdf.font.ascender - @pdf.font.descender)
position = @pdf.y
@pdf.text "Foo\nBar\nBaz", :final_gap => false
@pdf.y.should be_within(0.0001).of(position - 2*@pdf.font.height - @pdf.font.ascender - @pdf.font.descender)
end
it "should be able to print text starting at the last line of a page" do
@pdf.move_cursor_to(@pdf.font.height)
@pdf.text("hello world")
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.size.should == 1
end
it "should default to 12 point helvetica" do
@pdf.text "Blah"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:name].should == :Helvetica
text.font_settings[0][:size].should == 12
text.strings.first.should == "Blah"
end
it "should allow setting font size" do
@pdf.text "Blah", :size => 16
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 16
end
it "should allow setting a default font size" do
@pdf.font_size = 16
@pdf.text "Blah"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 16
end
it "should allow overriding default font for a single instance" do
@pdf.font_size = 16
@pdf.text "Blah", :size => 11
@pdf.text "Blaz"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 11
text.font_settings[1][:size].should == 16
end
it "should allow setting a font size transaction with a block" do
@pdf.font_size 16 do
@pdf.text 'Blah'
end
@pdf.text 'blah'
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 16
text.font_settings[1][:size].should == 12
end
it "should allow manual setting the font size " +
"when in a font size block" do
@pdf.font_size(16) do
@pdf.text 'Foo'
@pdf.text 'Blah', :size => 11
@pdf.text 'Blaz'
end
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 16
text.font_settings[1][:size].should == 11
text.font_settings[2][:size].should == 16
end
it "should allow registering of built-in font_settings on the fly" do
@pdf.font "Times-Roman"
@pdf.text "Blah"
@pdf.font "Courier"
@pdf.text "Blaz"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:name].should == :"Times-Roman"
text.font_settings[1][:name].should == :Courier
end
it "should utilise the same default font across multiple pages" do
@pdf.text "Blah"
@pdf.start_new_page
@pdf.text "Blaz"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings.size.should == 2
text.font_settings[0][:name].should == :Helvetica
text.font_settings[1][:name].should == :Helvetica
end
it "should raise_error an exception when an unknown font is used" do
lambda { @pdf.font "Pao bu" }.should raise_error(Prawn::Errors::UnknownFont)
end
it "should_not raise_error an exception when providing Pathname instance as font" do
lambda {
@pdf.font Pathname.new("#{Prawn::DATADIR}/fonts/comicsans.ttf")
}.should_not raise_error(Prawn::Errors::UnknownFont)
end
it "should correctly render a utf-8 string when using a built-in font" do
str = "©" # copyright symbol
@pdf.text str
# grab the text from the rendered PDF and ensure it matches
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.first.should == str
end
it "should correctly render a utf-8 string when using a TTF font" do
str = "©" # copyright symbol
@pdf.font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
@pdf.text str
# grab the text from the rendered PDF and ensure it matches
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.first.should == str
end
it "should correctly render a string with higher bit characters across" +
" a page break when using a built-in font" do
str = "©"
@pdf.move_cursor_to(@pdf.font.height)
@pdf.text(str + "\n" + str)
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.size.should == 2
pages[0][:strings].should == [str]
pages[1][:strings].should == [str]
end
it "should correctly render a string with higher bit characters across" +
" a page break when using a built-in font and :indent_paragraphs option" do
str = "©"
@pdf.move_cursor_to(@pdf.font.height)
@pdf.text(str + "\n" + str, :indent_paragraphs => 20)
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.size.should == 2
pages[0][:strings].should == [str]
pages[1][:strings].should == [str]
end
if "spec".respond_to?(:encode!)
# Handle non utf-8 string encodings in a sane way on M17N aware VMs
it "should raise_error an exception when a utf-8 incompatible string is rendered" do
str = "Blah \xDD"
str.force_encoding("ASCII-8BIT")
lambda { @pdf.text str }.should raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
it "should_not raise_error an exception when a shift-jis string is rendered" do
datafile = "#{Prawn::DATADIR}/shift_jis_text.txt"
sjis_str = File.open(datafile, "r:shift_jis") { |f| f.gets }
@pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
lambda { @pdf.text sjis_str }.should_not raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
else
# Handle non utf-8 string encodings in a sane way on non-M17N aware VMs
it "should raise_error an exception when a corrupt utf-8 string is rendered" do
str = "Blah \xDD"
lambda { @pdf.text str }.should raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
it "should raise_error an exception when a shift-jis string is rendered" do
sjis_str = File.read("#{Prawn::DATADIR}/shift_jis_text.txt")
lambda { @pdf.text sjis_str }.should raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
end
it "should call move_past_bottom when printing more text than can fit" +
" between the current document.y and bounds.bottom" do
@pdf.y = @pdf.font.height
@pdf.text "Hello"
@pdf.text "World"
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.size.should == 2
pages[0][:strings].should == ["Hello"]
pages[1][:strings].should == ["World"]
end
describe "with :indent_paragraphs option" do
it "should indent the paragraphs" do
hello = "hello " * 50
hello2 = "hello " * 50
@pdf.text(hello + "\n" + hello2, :indent_paragraphs => 60)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == ("hello " * 19).strip
text.strings[1].should == ("hello " * 21).strip
text.strings[3].should == ("hello " * 19).strip
text.strings[4].should == ("hello " * 21).strip
end
describe "when wrap to new page, and first line of new page" +
" is not the start of a new paragraph, that line should" +
" not be indented" do
it "should indent the paragraphs" do
hello = "hello " * 50
hello2 = "hello " * 50
@pdf.move_cursor_to(@pdf.font.height)
@pdf.text(hello + "\n" + hello2, :indent_paragraphs => 60)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == ("hello " * 19).strip
text.strings[1].should == ("hello " * 21).strip
text.strings[3].should == ("hello " * 19).strip
text.strings[4].should == ("hello " * 21).strip
end
end
describe "when wrap to new page, and first line of new page" +
" is the start of a new paragraph, that line should" +
" be indented" do
it "should indent the paragraphs" do
hello = "hello " * 50
hello2 = "hello " * 50
@pdf.move_cursor_to(@pdf.font.height * 3)
@pdf.text(hello + "\n" + hello2, :indent_paragraphs => 60)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings[0].should == ("hello " * 19).strip
text.strings[1].should == ("hello " * 21).strip
text.strings[3].should == ("hello " * 19).strip
text.strings[4].should == ("hello " * 21).strip
end
end
end
describe "kerning" do
it "should respect text kerning setting (document default)" do
create_pdf
@pdf.font.expects(:compute_width_of).with do |str, options|
str == "VAT" && options[:kerning] == true
end.at_least_once.returns(10)
@pdf.text "VAT"
end
it "should respect text kerning setting (kerning=true)" do
create_pdf
@pdf.font.expects(:compute_width_of).with do |str, options|
str == "VAT" && options[:kerning] == true
end.at_least_once.returns(10)
@pdf.text "VAT", :kerning => true
end
it "should respect text kerning setting (kerning=false)" do
create_pdf
@pdf.font.expects(:compute_width_of).with do |str, options|
str == "VAT" && options[:kerning] == false
end.at_least_once.returns(10)
@pdf.text "VAT", :kerning => false
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/cell_spec.rb 0000644 0000000 0000000 00000043575 12114176157 017313 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
module CellHelpers
# Build, but do not draw, a cell on @pdf.
def cell(options={})
at = options[:at] || [0, @pdf.cursor]
Prawn::Table::Cell::Text.new(@pdf, at, options)
end
end
describe "Prawn::Table::Cell" do
before(:each) do
@pdf = Prawn::Document.new
end
describe "Prawn::Document#cell" do
include CellHelpers
it "should draw the cell" do
Prawn::Table::Cell::Text.any_instance.expects(:draw).once
@pdf.cell(:content => "text")
end
it "should return a Cell" do
@pdf.cell(:content => "text").should be_a_kind_of Prawn::Table::Cell
end
it "accepts :content => nil in a hash" do
@pdf.cell(:content => nil).should be_a_kind_of(Prawn::Table::Cell::Text)
@pdf.make_cell(:content => nil).should be_a_kind_of(Prawn::Table::Cell::Text)
end
it "should convert nil, Numeric, and Date values to strings" do
[nil, 123, 123.45, Date.today].each do |value|
c = @pdf.cell(:content => value)
c.should be_a_kind_of Prawn::Table::Cell::Text
c.content.should == value.to_s
end
end
it "should allow inline styling with a hash argument" do
# used for table([[{:text => "...", :font_style => :bold, ...}, ...]])
c = Prawn::Table::Cell.make(@pdf,
{:content => 'hello', :font_style => :bold})
c.should be_a_kind_of Prawn::Table::Cell::Text
c.content.should == "hello"
c.font.name.should == 'Helvetica-Bold'
end
it "should draw text at the given point plus padding, with the given " +
"size and style" do
@pdf.expects(:bounding_box).yields
@pdf.expects(:move_down)
@pdf.expects(:draw_text!).with { |text, options| text == "hello world" }
@pdf.cell(:content => "hello world",
:at => [10, 20],
:padding => [30, 40],
:size => 7,
:font_style => :bold)
end
end
describe "Prawn::Document#make_cell" do
it "should not draw the cell" do
Prawn::Table::Cell::Text.any_instance.expects(:draw).never
@pdf.make_cell("text")
end
it "should return a Cell" do
@pdf.make_cell("text", :size => 7).should be_a_kind_of Prawn::Table::Cell
end
end
describe "#style" do
include CellHelpers
it "should set each property in turn" do
c = cell(:content => "text")
c.expects(:padding=).with(50)
c.expects(:size=).with(7)
c.style(:padding => 50, :size => 7)
end
end
describe "cell width" do
include CellHelpers
it "should be calculated for text" do
c = cell(:content => "text")
c.width.should == @pdf.width_of("text") + c.padding[1] + c.padding[3]
end
it "should be overridden by manual :width" do
c = cell(:content => "text", :width => 400)
c.width.should == 400
end
it "should incorporate padding when specified" do
c = cell(:content => "text", :padding => [1, 2, 3, 4])
c.width.should be_within(0.01).of(@pdf.width_of("text") + 6)
end
it "should allow width to be reset after it has been calculated" do
# to ensure that if we memoize width, it can still be overridden
c = cell(:content => "text")
c.width
c.width = 400
c.width.should == 400
end
it "should return proper width with size set" do
text = "text " * 4
c = cell(:content => text, :size => 7)
c.width.should ==
@pdf.width_of(text, :size => 7) + c.padding[1] + c.padding[3]
end
it "content_width should exclude padding" do
c = cell(:content => "text", :padding => 10)
c.content_width.should == @pdf.width_of("text")
end
it "content_width should exclude padding even with manual :width" do
c = cell(:content => "text", :padding => 10, :width => 400)
c.content_width.should be_within(0.01).of(380)
end
it "should have a reasonable minimum width that can fit @content" do
c = cell(:content => "text", :padding => 10)
min_content_width = c.min_width - c.padding[1] - c.padding[3]
lambda { @pdf.height_of("text", :width => min_content_width) }.
should_not raise_error(Prawn::Errors::CannotFit)
@pdf.height_of("text", :width => min_content_width).should be <
(5 * @pdf.height_of("text"))
end
it "should defer min_width's evaluation of padding" do
c = cell(:content => "text", :padding => 100)
c.padding = 0
# Make sure we use the new value of padding in calculating min_width
c.min_width.should be < 100
end
it "should defer min_width's evaluation of size" do
c = cell(:content => "text", :size => 50)
c.size = 8
c.padding = 0
c.min_width.should be < 10
end
end
describe "cell height" do
include CellHelpers
it "should be calculated for text" do
c = cell(:content => "text")
c.height.should ==
@pdf.height_of("text", :width => @pdf.width_of("text")) +
c.padding[0] + c.padding[3]
end
it "should be overridden by manual :height" do
c = cell(:content => "text", :height => 400)
c.height.should == 400
end
it "should incorporate :padding when specified" do
c = cell(:content => "text", :padding => [1, 2, 3, 4])
c.height.should be_within(0.01).of(1 + 3 +
@pdf.height_of("text", :width => @pdf.width_of("text")))
end
it "should allow height to be reset after it has been calculated" do
# to ensure that if we memoize height, it can still be overridden
c = cell(:content => "text")
c.height
c.height = 400
c.height.should == 400
end
it "should return proper height for blocks of text" do
content = "words " * 10
c = cell(:content => content, :width => 100)
c.height.should == @pdf.height_of(content, :width => 100) +
c.padding[0] + c.padding[2]
end
it "should return proper height for blocks of text with size set" do
content = "words " * 10
c = cell(:content => content, :width => 100, :size => 7)
correct_content_height = nil
@pdf.font_size(7) do
correct_content_height = @pdf.height_of(content, :width => 100)
end
c.height.should == correct_content_height + c.padding[0] + c.padding[2]
end
it "content_height should exclude padding" do
c = cell(:content => "text", :padding => 10)
c.content_height.should == @pdf.height_of("text")
end
it "content_height should exclude padding even with manual :height" do
c = cell(:content => "text", :padding => 10, :height => 400)
c.content_height.should be_within(0.01).of(380)
end
end
describe "cell padding" do
include CellHelpers
it "should default to zero" do
c = cell(:content => "text")
c.padding.should == [5, 5, 5, 5]
end
it "should accept a numeric value, setting all padding" do
c = cell(:content => "text", :padding => 10)
c.padding.should == [10, 10, 10, 10]
end
it "should accept [v,h]" do
c = cell(:content => "text", :padding => [20, 30])
c.padding.should == [20, 30, 20, 30]
end
it "should accept [t,h,b]" do
c = cell(:content => "text", :padding => [10, 20, 30])
c.padding.should == [10, 20, 30, 20]
end
it "should accept [t,l,b,r]" do
c = cell(:content => "text", :padding => [10, 20, 30, 40])
c.padding.should == [10, 20, 30, 40]
end
it "should reject other formats" do
lambda{
cell(:content => "text", :padding => [10])
}.should raise_error(ArgumentError)
end
end
describe "background_color" do
include CellHelpers
it "should fill a rectangle with the given background color" do
@pdf.stubs(:mask).yields
@pdf.expects(:mask).with(:fill_color).yields
@pdf.stubs(:fill_color)
@pdf.expects(:fill_color).with('123456')
@pdf.expects(:fill_rectangle).checking do |(x, y), w, h|
x.should be_within(0.01).of(0)
y.should be_within(0.01).of(@pdf.cursor)
w.should be_within(0.01).of(29.344)
h.should be_within(0.01).of(23.872)
end
@pdf.cell(:content => "text", :background_color => '123456')
end
it "should draw the background in the right place if cell is drawn at a " +
"different location" do
@pdf.stubs(:mask).yields
@pdf.expects(:mask).with(:fill_color).yields
@pdf.stubs(:fill_color)
@pdf.expects(:fill_color).with('123456')
@pdf.expects(:fill_rectangle).checking do |(x, y), w, h|
x.should be_within(0.01).of(12.0)
y.should be_within(0.01).of(34.0)
w.should be_within(0.01).of(29.344)
h.should be_within(0.01).of(23.872)
end
c = @pdf.make_cell(:content => "text", :background_color => '123456')
c.draw([12.0, 34.0])
end
end
describe "color" do
it "should set fill color when :text_color is provided" do
pdf = Prawn::Document.new
pdf.stubs(:fill_color)
pdf.expects(:fill_color).with('555555')
pdf.cell :content => 'foo', :text_color => '555555'
end
it "should reset the fill color to the original one" do
pdf = Prawn::Document.new
pdf.fill_color = '333333'
pdf.cell :content => 'foo', :text_color => '555555'
pdf.fill_color.should == '333333'
end
end
describe "Borders" do
it "should draw all borders by default" do
@pdf.expects(:stroke_line).times(4)
@pdf.cell(:content => "text")
end
it "should draw all borders when requested" do
@pdf.expects(:stroke_line).times(4)
@pdf.cell(:content => "text", :borders => [:top, :right, :bottom, :left])
end
# Only roughly verifying the integer coordinates so that we don't have to
# do any FP closeness arithmetic. Can plug in that math later if this goes
# wrong.
it "should draw top border when requested" do
@pdf.expects(:stroke_line).checking do |from, to|
@pdf.map_to_absolute(from).map{|x| x.round}.should == [36, 756]
@pdf.map_to_absolute(to).map{|x| x.round}.should == [65, 756]
end
@pdf.cell(:content => "text", :borders => [:top])
end
it "should draw bottom border when requested" do
@pdf.expects(:stroke_line).checking do |from, to|
@pdf.map_to_absolute(from).map{|x| x.round}.should == [36, 732]
@pdf.map_to_absolute(to).map{|x| x.round}.should == [65, 732]
end
@pdf.cell(:content => "text", :borders => [:bottom])
end
it "should draw left border when requested" do
@pdf.expects(:stroke_line).checking do |from, to|
@pdf.map_to_absolute(from).map{|x| x.round}.should == [36, 756]
@pdf.map_to_absolute(to).map{|x| x.round}.should == [36, 732]
end
@pdf.cell(:content => "text", :borders => [:left])
end
it "should draw right border when requested" do
@pdf.expects(:stroke_line).checking do |from, to|
@pdf.map_to_absolute(from).map{|x| x.round}.should == [65, 756]
@pdf.map_to_absolute(to).map{|x| x.round}.should == [65, 732]
end
@pdf.cell(:content => "text", :borders => [:right])
end
it "should draw borders at the same location when in or out of bbox" do
@pdf.expects(:stroke_line).checking do |from, to|
@pdf.map_to_absolute(from).map{|x| x.round}.should == [36, 756]
@pdf.map_to_absolute(to).map{|x| x.round}.should == [65, 756]
end
@pdf.bounding_box([0, @pdf.cursor], :width => @pdf.bounds.width) do
@pdf.cell(:content => "text", :borders => [:top])
end
end
it "should set border color with :border_..._color" do
@pdf.ignores(:stroke_color=).with("000000")
@pdf.expects(:stroke_color=).with("ff0000")
c = @pdf.cell(:content => "text", :border_top_color => "ff0000")
c.border_top_color.should == "ff0000"
c.border_colors[0].should == "ff0000"
end
it "should set border colors with :border_color" do
@pdf.ignores(:stroke_color=).with("000000")
@pdf.expects(:stroke_color=).with("ff0000")
@pdf.expects(:stroke_color=).with("00ff00")
@pdf.expects(:stroke_color=).with("0000ff")
@pdf.expects(:stroke_color=).with("ff00ff")
c = @pdf.cell(:content => "text",
:border_color => %w[ff0000 00ff00 0000ff ff00ff])
c.border_colors.should == %w[ff0000 00ff00 0000ff ff00ff]
end
it "border_..._width should return 0 if border not selected" do
c = @pdf.cell(:content => "text", :borders => [:top])
c.border_bottom_width.should == 0
end
it "should set border width with :border_..._width" do
@pdf.ignores(:line_width=).with(1)
@pdf.expects(:line_width=).with(2)
c = @pdf.cell(:content => "text", :border_bottom_width => 2)
c.border_bottom_width.should == 2
c.border_widths[2].should == 2
end
it "should set border widths with :border_width" do
@pdf.ignores(:line_width=).with(1)
@pdf.expects(:line_width=).with(2)
@pdf.expects(:line_width=).with(3)
@pdf.expects(:line_width=).with(4)
@pdf.expects(:line_width=).with(5)
c = @pdf.cell(:content => "text",
:border_width => [2, 3, 4, 5])
c.border_widths.should == [2, 3, 4, 5]
end
it "should set default border lines to :solid" do
c = @pdf.cell(:content => "text")
c.border_top_line.should == :solid
c.border_right_line.should == :solid
c.border_bottom_line.should == :solid
c.border_left_line.should == :solid
c.border_lines.should == [:solid] * 4
end
it "should set border line with :border_..._line" do
c = @pdf.cell(:content => "text", :border_bottom_line => :dotted)
c.border_bottom_line.should == :dotted
c.border_lines[2].should == :dotted
end
it "should set border lines with :border_lines" do
c = @pdf.cell(:content => "text",
:border_lines => [:solid, :dotted, :dashed, :solid])
c.border_lines.should == [:solid, :dotted, :dashed, :solid]
end
end
describe "Text cell attributes" do
include CellHelpers
it "should pass through text options like :align to Text::Box" do
c = cell(:content => "text", :align => :right)
box = Prawn::Text::Box.new("text", :document => @pdf)
Prawn::Text::Box.expects(:new).checking do |text, options|
text.should == "text"
options[:align].should == :right
end.at_least_once.returns(box)
c.draw
end
it "should use font_style for Text::Box#style" do
c = cell(:content => "text", :font_style => :bold)
box = Prawn::Text::Box.new("text", :document => @pdf)
Prawn::Text::Box.expects(:new).checking do |text, options|
text.should == "text"
options[:style].should == :bold
end.at_least_once.returns(box)
c.draw
end
it "should allow inline formatting in cells" do
c = cell(:content => "foo bar baz", :inline_format => true)
box = Prawn::Text::Formatted::Box.new([], :document => @pdf)
Prawn::Text::Formatted::Box.expects(:new).checking do |array, options|
array[0][:text].should == "foo "
array[0][:styles].should == []
array[1][:text].should == "bar"
array[1][:styles].should == [:bold]
array[2][:text].should == " baz"
array[2][:styles].should == []
end.at_least_once.returns(box)
c.draw
end
end
describe "Font handling" do
include CellHelpers
it "should allow only :font_style to be specified, defaulting to the " +
"document's font" do
c = cell(:content => "text", :font_style => :bold)
c.font.name.should == 'Helvetica-Bold'
end
it "should accept a font name for :font" do
c = cell(:content => "text", :font => 'Helvetica-Bold')
c.font.name.should == 'Helvetica-Bold'
end
it "should allow style to be changed after initialize" do
c = cell(:content => "text")
c.font_style = :bold
c.font.name.should == 'Helvetica-Bold'
end
it "should default to the document's font, if none is specified" do
c = cell(:content => "text")
c.font.should == @pdf.font
end
it "should use the metrics of the selected font (even if it is a variant " +
"of the document's font) to calculate width" do
c = cell(:content => "text", :font_style => :bold)
font = @pdf.find_font('Helvetica-Bold')
c.content_width.should == font.compute_width_of("text")
end
it "should properly calculate inline-formatted text" do
c = cell(:content => "text", :inline_format => true)
font = @pdf.find_font('Helvetica-Bold')
c.content_width.should == font.compute_width_of("text")
end
end
end
describe "Image cells" do
before(:each) do
create_pdf
end
describe "with default options" do
before(:each) do
@cell = Prawn::Table::Cell.make(@pdf,
:image => "#{Prawn::DATADIR}/images/prawn.png")
end
it "should create a Cell::Image" do
@cell.should be_a_kind_of(Prawn::Table::Cell::Image)
end
it "should pull the natural width and height from the image" do
@cell.natural_content_width.should == 141
@cell.natural_content_height.should == 142
end
end
describe "hash syntax" do
before(:each) do
@table = @pdf.make_table([[{
:image => "#{Prawn::DATADIR}/images/prawn.png",
:scale => 2,
:fit => [100, 200],
:image_width => 123,
:image_height => 456,
:position => :center,
:vposition => :center
}]])
@cell = @table.cells[0, 0]
end
it "should create a Cell::Image" do
@cell.should be_a_kind_of(Prawn::Table::Cell::Image)
end
it "should pass through image options" do
@pdf.expects(:embed_image).checking do |_, _, options|
options[:scale].should == 2
options[:fit].should == [100, 200]
options[:width].should == 123
options[:height].should == 456
options[:position].should == :center
options[:vposition].should == :center
end
@table.draw
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/text_rendering_mode_spec.rb 0000644 0000000 0000000 00000003043 12114176157 022403 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "#text_rendering_mode" do
it "should draw the text rendering mode to the document" do
create_pdf
@pdf.text_rendering_mode(:stroke) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.text_rendering_mode.first.should == 1
end
it "should not draw the text rendering mode to the document" +
" when the new mode matches the old" do
create_pdf
@pdf.text_rendering_mode(:fill) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.text_rendering_mode.should be_empty
end
it "should restore character spacing to 0" do
create_pdf
@pdf.text_rendering_mode(:stroke) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.text_rendering_mode.should == [1,0]
end
it "should function as an accessor when no parameter given" do
create_pdf
@pdf.text_rendering_mode(:fill_stroke) do
@pdf.text("hello world")
@pdf.text_rendering_mode.should == :fill_stroke
end
@pdf.text_rendering_mode.should == :fill
end
it "should raise_error an exception when passed an invalid mode" do
create_pdf
lambda { @pdf.text_rendering_mode(-1) }.should raise_error(ArgumentError)
lambda { @pdf.text_rendering_mode(8) }.should raise_error(ArgumentError)
lambda { @pdf.text_rendering_mode(:flil) }.should raise_error(ArgumentError)
end
end
ruby-prawn-1.0.0~rc2.orig/spec/grid_spec.rb 0000644 0000000 0000000 00000005703 12114176157 017310 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "A document's grid" do
before do
@pdf = Prawn::Document.new
end
it "should allow definition of a grid" do
@pdf.define_grid(:columns => 5, :rows => 8, :gutter => 0.1)
@pdf.grid.columns.should == 5
@pdf.grid.rows.should == 8
@pdf.grid.gutter.should == 0.1
end
describe "when a grid is defined" do
before do
@num_columns = 5
@num_rows = 8
@gutter = 10.0
@pdf.define_grid(
:columns => @num_columns,
:rows => @num_rows,
:gutter => @gutter
)
end
it "should compute the column width" do
(@pdf.grid.column_width * @num_columns.to_f +
@gutter * (@num_columns - 1).to_f).should == @pdf.bounds.width
end
it "should compute the row height" do
(@pdf.grid.row_height * @num_rows.to_f +
@gutter * (@num_rows - 1).to_f).should == @pdf.bounds.height
end
it "should give the edges of a grid box" do
grid_width = (@pdf.bounds.width.to_f -
(@gutter * (@num_columns - 1).to_f )) / @num_columns.to_f
grid_height = (@pdf.bounds.height.to_f -
(@gutter * (@num_rows - 1).to_f ))/ @num_rows.to_f
exp_tl_x = (grid_width + @gutter.to_f) * 4.0
exp_tl_y = @pdf.bounds.height.to_f - (grid_height + @gutter.to_f)
@pdf.grid(1,4).top_left.should == [exp_tl_x, exp_tl_y]
@pdf.grid(1,4).top_right.should == [exp_tl_x + grid_width, exp_tl_y]
@pdf.grid(1,4).bottom_left.should == [exp_tl_x, exp_tl_y - grid_height]
@pdf.grid(1,4).bottom_right.should == [exp_tl_x + grid_width, exp_tl_y - grid_height]
end
it "should give the edges of a multiple grid boxes" do
# Hand verified. Cheating a bit. Don't tell.
@pdf.grid([1,3], [2,5]).top_left.should == [330.0, 628.75]
@pdf.grid([1,3], [2,5]).top_right.should == [650.0, 628.75]
@pdf.grid([1,3], [2,5]).bottom_left.should == [330.0, 456.25]
@pdf.grid([1,3], [2,5]).bottom_right.should == [650.0, 456.25]
end
it "should draw outlines without changing global default colors to grid color" do
@pdf.grid.show_all('cccccc')
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
colors.fill_color.should_not == [0.8,0.8,0.8]
colors.stroke_color.should_not == [0.8,0.8,0.8]
# Hardcoded default color as I haven't been able to come up with a stable converter
# between fill_color without lots code.
#colors.fill_color.should == [0.0,0.0,0.0]
colors.stroke_color.should == [0.0,0.0,0.0]
end
it "should draw outlines without curent color settings" do
@pdf.fill_color "ccff00"
@pdf.stroke_color "ffcc00"
@pdf.grid.show_all
colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
colors.fill_color.should == [0.8,1.0,0.0]
colors.stroke_color.should == [1.0,0.8,0.0]
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/text_spacing_spec.rb 0000644 0000000 0000000 00000005516 12114176157 021055 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "#character_spacing" do
it "should draw the character spacing to the document" do
create_pdf
@pdf.character_spacing(10.555555) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.character_spacing.first.should == 10.556
end
it "should not draw the character spacing to the document" +
" when the new character spacing matches the old" do
create_pdf
@pdf.character_spacing(0) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.character_spacing.should be_empty
end
it "should restore character spacing to 0" do
create_pdf
@pdf.character_spacing(10.555555) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.character_spacing.last.should == 0
end
it "should function as an accessor when no parameter given" do
create_pdf
@pdf.character_spacing(10.555555) do
@pdf.text("hello world")
@pdf.character_spacing.should == 10.555555
end
@pdf.character_spacing.should == 0
end
# ensure that we properly internationalize by using the number of characters
# in a string, not the number of bytes, to insert character spaces
#
it "should calculate character spacing widths by characters, not bytes" do
create_pdf
@pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
str = "こんにちは世界"
@pdf.character_spacing(0) do
@raw_width = @pdf.width_of(str)
end
@pdf.character_spacing(10) do
# the new width should include seven 10-pt character spaces.
@pdf.width_of(str).should be_within(0.001).of(@raw_width + (10 * 7))
end
end
end
describe "#word_spacing" do
it "should draw the word spacing to the document" do
create_pdf
@pdf.word_spacing(10.555555) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.word_spacing.first.should == 10.556
end
it "should draw the word spacing to the document" +
" when the new word spacing matches the old" do
create_pdf
@pdf.word_spacing(0) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.word_spacing.should be_empty
end
it "should restore word spacing to 0" do
create_pdf
@pdf.word_spacing(10.555555) do
@pdf.text("hello world")
end
contents = PDF::Inspector::Text.analyze(@pdf.render)
contents.word_spacing.last.should == 0
end
it "should function as an accessor when no parameter given" do
create_pdf
@pdf.word_spacing(10.555555) do
@pdf.text("hello world")
@pdf.word_spacing.should == 10.555555
end
@pdf.word_spacing.should == 0
end
end
ruby-prawn-1.0.0~rc2.orig/spec/repeater_spec.rb 0000644 0000000 0000000 00000010651 12114176157 020170 0 ustar root root require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Repeaters" do
it "creates a stamp and increments Prawn::Repeater.count on initialize" do
orig_count = Prawn::Repeater.count
doc = sample_document
doc.expects(:create_stamp).with("prawn_repeater(#{orig_count})")
r = repeater(doc, :all) { :do_nothing }
Prawn::Repeater.count.should == orig_count + 1
end
it "must provide an :all filter" do
doc = sample_document
r = repeater(doc, :all) { :do_nothing }
(1..doc.page_count).all? { |i| r.match?(i) }.should be_true
end
it "must provide an :odd filter" do
doc = sample_document
r = repeater(doc, :odd) { :do_nothing }
odd, even = (1..doc.page_count).partition { |e| e % 2 == 1 }
odd.all? { |i| r.match?(i) }.should be_true
even.any? { |i| r.match?(i) }.should be_false
end
it "must be able to filter by an array of page numbers" do
doc = sample_document
r = repeater(doc, [1,2,7]) { :do_nothing }
(1..10).select { |i| r.match?(i) }.should == [1,2,7]
end
it "must be able to filter by a range of page numbers" do
doc = sample_document
r = repeater(doc, 2..4) { :do_nothing }
(1..10).select { |i| r.match?(i) }.should == [2,3,4]
end
it "must be able to filter by an arbitrary proc" do
doc = sample_document
r = repeater(doc, lambda { |x| x == 1 or x % 3 == 0 })
(1..10).select { |i| r.match?(i) }.should == [1,3,6,9]
end
it "must try to run a stamp if the page number matches" do
doc = sample_document
doc.expects(:stamp)
repeater(doc, :odd).run(3)
end
it "must not try to run a stamp unless the page number matches" do
doc = sample_document
doc.expects(:stamp).never
repeater(doc, :odd).run(2)
end
it "must not try to run a stamp if dynamic is selected" do
doc = sample_document
doc.expects(:stamp).never
(1..10).each { |p| repeater(doc, :all, true){:do_nothing}.run(p) }
end
it "must try to run a block if the page number matches" do
doc = sample_document
doc.expects(:draw_text).twice
(1..10).each { |p| repeater(doc, [1,2], true){doc.draw_text "foo"}.run(p) }
end
it "must not try to run a block unless the page number matches" do
doc = sample_document
doc.expects(:draw_text).never
repeater(doc, :odd, true){doc.draw_text "foo"}.run(2)
end
it "must treat any block as a closure" do
doc = sample_document
@page = "Page" # ensure access to ivars
doc.repeat(:all, :dynamic => true) do
doc.draw_text "#@page #{doc.page_number}", :at => [500, 0]
end
text = PDF::Inspector::Text.analyze(doc.render)
text.strings.should == (1..10).to_a.map{|p| "Page #{p}"}
end
it "must treat any block as a closure (Document.new instance_eval form)" do
doc = Prawn::Document.new(:skip_page_creation => true) do
10.times { start_new_page }
@page = "Page"
repeat(:all, :dynamic => true) do
# ensure self is accessible here
draw_text "#@page #{page_number}", :at => [500, 0]
end
end
text = PDF::Inspector::Text.analyze(doc.render)
text.strings.should == (1..10).to_a.map{|p| "Page #{p}"}
end
def sample_document
doc = Prawn::Document.new(:skip_page_creation => true)
10.times { |e| doc.start_new_page }
doc
end
def repeater(*args, &b)
Prawn::Repeater.new(*args,&b)
end
context "graphic state" do
it "should not alter the graphic state stack color space" do
create_pdf
starting_color_space = @pdf.state.page.graphic_state.color_space.dup
@pdf.repeat :all do
@pdf.text "Testing", :size => 24, :style => :bold
end
@pdf.state.page.graphic_state.color_space.should == starting_color_space
end
context "dynamic repeaters" do
it "should preserve the graphic state at creation time" do
create_pdf
@pdf.repeat :all, :dynamic => true do
@pdf.text "fill_color: #{@pdf.graphic_state.fill_color}"
@pdf.text "cap_style: #{@pdf.graphic_state.cap_style}"
end
@pdf.fill_color "666666"
@pdf.cap_style :round
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.include?("fill_color: 666666").should == false
text.strings.include?("fill_color: 000000").should == true
text.strings.include?("cap_style: round").should == false
text.strings.include?("cap_style: butt").should == true
end
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/destinations_spec.rb 0000644 0000000 0000000 00000000537 12114176157 021067 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "When creating destinations" do
before(:each) { create_pdf }
it "should add entry to Dests name tree" do
@pdf.dests.data.empty?.should == true
@pdf.add_dest "candy", "chocolate"
@pdf.dests.data.size.should == 1
end
end
ruby-prawn-1.0.0~rc2.orig/spec/transparency_spec.rb 0000644 0000000 0000000 00000005432 12114176157 021073 0 ustar root root require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
module TransparencyHelper
def make_transparent(opacity, stroke_opacity=opacity)
@pdf.transparent(opacity, stroke_opacity) do
yield if block_given?
end
end
end
describe "Document with transparency" do
include TransparencyHelper
it "the PDF version should be at least 1.4" do
create_pdf
make_transparent(0.5)
str = @pdf.render
str[0,8].should == "%PDF-1.4"
end
it "a new extended graphics state should be created for "+
"each unique transparency setting" do
create_pdf
make_transparent(0.5, 0.2) do
make_transparent(0.5, 0.75)
end
extgstates = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates
extgstates.length.should == 2
end
it "a new extended graphics state should not be created for "+
"each duplicate transparency setting" do
create_pdf
make_transparent(0.5, 0.75) do
make_transparent(0.5, 0.75)
end
extgstates = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates
extgstates.length.should == 1
end
it "setting the transparency with only one parameter sets the transparency"+
" for both the fill and the stroke" do
create_pdf
make_transparent(0.5)
extgstate = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates[0]
extgstate[:opacity].should == 0.5
extgstate[:stroke_opacity].should == 0.5
end
it "setting the transparency with a numerical parameter and "+
"a :stroke should set the fill transparency to the numerical parameter "+
"and the stroke transparency to the option" do
create_pdf
make_transparent(0.5, 0.2)
extgstate = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates[0]
extgstate[:opacity].should == 0.5
extgstate[:stroke_opacity].should == 0.2
end
it "should enforce the valid range of 0.0 to 1.0" do
create_pdf
make_transparent(-0.5, -0.2)
extgstate = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates[0]
extgstate[:opacity].should == 0.0
extgstate[:stroke_opacity].should == 0.0
create_pdf
make_transparent(2.0, 3.0)
extgstate = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates[0]
extgstate[:opacity].should == 1.0
extgstate[:stroke_opacity].should == 1.0
end
describe "with more than one page" do
include TransparencyHelper
it "the extended graphic state resource should be added to both pages" do
create_pdf
make_transparent(0.5, 0.2)
@pdf.start_new_page
make_transparent(0.5, 0.2)
extgstates = PDF::Inspector::ExtGState.analyze(@pdf.render).extgstates
extgstate = extgstates[0]
extgstates.length.should == 2
extgstate[:opacity].should == 0.5
extgstate[:stroke_opacity].should == 0.2
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/measurement_units_spec.rb 0000644 0000000 0000000 00000001161 12114176157 022124 0 ustar root root require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
require "prawn/measurement_extensions"
describe "Measurement units" do
it "should convert units to PostScriptPoints" do
1.mm.should be_within(0.000000001).of(2.834645669)
1.mm.should == (72 / 25.4)
2.mm.should == (2 * 72 / 25.4)
3.mm.should == 3 * 72 / 25.4
-3.mm.should == -3 * 72/25.4
1.cm.should == 10 * 72 / 25.4
1.dm.should == 100 * 72 / 25.4
1.m.should == 1000 * 72 / 25.4
1.in.should == 72
1.ft.should == 72 * 12
1.yd.should == 72 * 12 * 3
1.pt.should == 1
end
end
ruby-prawn-1.0.0~rc2.orig/spec/jpg_spec.rb 0000644 0000000 0000000 00000001262 12114176157 017137 0 ustar root root # encoding: utf-8
# Spec'ing the PNG class. Not complete yet - still needs to check the
# contents of palette and transparency to ensure they're correct.
# Need to find files that have these sections first.
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "When reading a JPEG file" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/pigs.jpg"
@img_data = File.open(@filename, "rb") { |f| f.read }
end
it "should read the basic attributes correctly" do
jpg = Prawn::Images::JPG.new(@img_data)
jpg.width.should == 604
jpg.height.should == 453
jpg.bits.should == 8
jpg.channels.should == 3
end
end
ruby-prawn-1.0.0~rc2.orig/spec/line_wrap_spec.rb 0000644 0000000 0000000 00000031656 12114176157 020351 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Core::Text::Formatted::LineWrap#wrap_line" do
before(:each) do
create_pdf
@arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
@line_wrap = Prawn::Core::Text::Formatted::LineWrap.new
@one_word_width = 50
end
it "should strip leading and trailing spaces" do
array = [{ :text => " hello world, " },
{ :text => "goodbye ", :style => [:bold] }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => 300,
:document => @pdf)
string.should == "hello world, goodbye"
end
it "should strip trailing spaces when a white-space-only fragment was" +
" successfully pushed onto the end of a line but no other non-white" +
" space fragment fits after it" do
array = [{ :text => "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " },
{ :text => " ", :style => [:bold] },
{ :text => " bbbbbbbbbbbbbbbbbbbbbbbbbbbb" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => 300,
:document => @pdf)
string.should == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
end
it "should raise_error CannotFit if a too-small width is given" do
array = [{ :text => " hello world, " },
{ :text => "goodbye ", :style => [:bold] }]
@arranger.format_array = array
lambda do
@line_wrap.wrap_line(:arranger => @arranger,
:width => 1,
:document => @pdf)
end.should raise_error(Prawn::Errors::CannotFit)
end
it "should break on space" do
array = [{ :text => "hello world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello"
end
it "should break on zero-width space" do
@pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
array = [{ :text => "hello#{Prawn::Text::ZWSP}world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello"
end
it "should not display zero-width space" do
@pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
array = [{ :text => "hello#{Prawn::Text::ZWSP}world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => 300,
:document => @pdf)
string.should == "helloworld"
end
it "should break on tab" do
array = [{ :text => "hello\tworld" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello"
end
it "should break on hyphens" do
array = [{ :text => "hello-world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello-"
end
it "should not break after a hyphen that follows white space and" +
"precedes a word" do
array = [{ :text => "hello -" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello -"
array = [{ :text => "hello -world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello"
end
it "should break on a soft hyphen" do
string = @pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}world")
array = [{ :text => string }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
expected = @pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}")
expected.force_encoding("utf-8") if "".respond_to?(:force_encoding)
string.should == expected
@pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
@line_wrap = Prawn::Core::Text::Formatted::LineWrap.new
string = "hello#{Prawn::Text::SHY}world"
array = [{ :text => string }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello#{Prawn::Text::SHY}"
end
it "should not display soft hyphens except at the end of a line" do
string = @pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}world")
array = [{ :text => string }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => 300,
:document => @pdf)
string.should == "helloworld"
@pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
@line_wrap = Prawn::Core::Text::Formatted::LineWrap.new
string = "hello#{Prawn::Text::SHY}world"
array = [{ :text => string }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => 300,
:document => @pdf)
string.should == "helloworld"
end
it "should not break before a hard hyphen that follows a word" do
enough_width_for_hello_world = 60
array = [{ :text => "hello world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => enough_width_for_hello_world,
:document => @pdf)
string.should == "hello world"
array = [{ :text => "hello world-" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => enough_width_for_hello_world,
:document => @pdf)
string.should == "hello"
@pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
@line_wrap = Prawn::Core::Text::Formatted::LineWrap.new
enough_width_for_hello_world = 68
array = [{ :text => "hello world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => enough_width_for_hello_world,
:document => @pdf)
string.should == "hello world"
array = [{ :text => "hello world-" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => enough_width_for_hello_world,
:document => @pdf)
string.should == "hello"
end
it "should not break after a hard hyphen that follows a soft hyphen and" +
"precedes a word" do
string = @pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}-")
array = [{ :text => string }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello-"
string = @pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}-world")
array = [{ :text => string }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
expected = @pdf.font.normalize_encoding("hello#{Prawn::Text::SHY}")
expected.force_encoding("utf-8") if "".respond_to?(:force_encoding)
string.should == expected
@pdf.font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
@line_wrap = Prawn::Core::Text::Formatted::LineWrap.new
string = "hello#{Prawn::Text::SHY}-"
array = [{ :text => string }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello-"
string = "hello#{Prawn::Text::SHY}-world"
array = [{ :text => string }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string.should == "hello#{Prawn::Text::SHY}"
end
end
describe "Core::Text::Formatted::LineWrap#space_count" do
before(:each) do
create_pdf
@arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
@line_wrap = Prawn::Core::Text::Formatted::LineWrap.new
end
it "should return the number of spaces in the last wrapped line" do
array = [{ :text => "hello world, " },
{ :text => "goodbye", :style => [:bold] }]
@arranger.format_array = array
@line_wrap.wrap_line(:arranger => @arranger,
:width => 300,
:document => @pdf)
@line_wrap.space_count.should == 2
end
it "should exclude preceding and trailing spaces from the count" do
array = [{ :text => " hello world, " },
{ :text => "goodbye ", :style => [:bold] }]
@arranger.format_array = array
@line_wrap.wrap_line(:arranger => @arranger,
:width => 300,
:document => @pdf)
@line_wrap.space_count.should == 2
end
end
describe "Core::Text::Formatted::LineWrap" do
before(:each) do
create_pdf
@arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello\nworld\n\n\nhow are you?" },
{ :text => "\n" },
{ :text => "\n" },
{ :text => "" },
{ :text => "fine, thanks. " * 4 },
{ :text => "" },
{ :text => "\n" },
{ :text => "" }]
@arranger.format_array = array
@line_wrap = Prawn::Core::Text::Formatted::LineWrap.new
end
it "should only return an empty string if nothing fit or there" +
"was nothing to wrap" do
8.times do
line = @line_wrap.wrap_line(:arranger => @arranger,
:width => 200,
:document => @pdf)
line.should_not be_empty
end
line = @line_wrap.wrap_line(:arranger => @arranger,
:width => 200,
:document => @pdf)
line.should be_empty
end
end
describe "Core::Text::Formatted::LineWrap#paragraph_finished?" do
before(:each) do
create_pdf
@arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
@line_wrap = Prawn::Core::Text::Formatted::LineWrap.new
@one_word_width = 50
end
it "should be_false when the last printed line is not the end of the paragraph" do
array = [{ :text => "hello world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
@line_wrap.paragraph_finished?.should == false
end
it "should be_true when the last printed line is the last fragment to print" do
array = [{ :text => "hello world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
@line_wrap.paragraph_finished?.should == true
end
it "should be_true when a newline exists on the current line" do
array = [{ :text => "hello\n world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
@line_wrap.paragraph_finished?.should == true
end
it "should be_true when a newline exists in the next fragment" do
array = [{ :text => "hello " },
{ :text => " \n" },
{ :text => "world" }]
@arranger.format_array = array
string = @line_wrap.wrap_line(:arranger => @arranger,
:width => @one_word_width,
:document => @pdf)
@line_wrap.paragraph_finished?.should == true
end
end
ruby-prawn-1.0.0~rc2.orig/spec/png_spec.rb 0000644 0000000 0000000 00000017156 12114176157 017154 0 ustar root root # encoding: ASCII-8BIT
# Spec'ing the PNG class. Not complete yet - still needs to check the
# contents of palette and transparency to ensure they're correct.
# Need to find files that have these sections first.
#
# see http://www.w3.org/TR/PNG/ for a detailed description of the PNG spec,
# particuarly Table 11.1 for the different color types
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "When reading a greyscale PNG file (color type 0)" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/web-links.png"
@data_filename = "#{Prawn::DATADIR}/images/web-links.dat"
@img_data = File.binread(@filename)
end
it "should read the attributes from the header chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
png.width.should == 21
png.height.should == 14
png.bits.should == 8
png.color_type.should == 0
png.compression_method.should == 0
png.filter_method.should == 0
png.interlace_method.should == 0
end
it "should read the image data chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
data = File.binread(@data_filename)
png.img_data.should == data
end
end
describe "When reading a greyscale PNG file with transparency (color type 0)" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/ruport_type0.png"
@img_data = File.binread(@filename)
end
# In a greyscale type 0 PNG image, the tRNS chunk should contain a single value
# that indicates the color that should be interpreted as transparent.
#
# http://www.w3.org/TR/PNG/#11tRNS
it "should read the tRNS chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
png.transparency[:grayscale].should == 255
end
end
describe "When reading an RGB PNG file (color type 2)" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/ruport.png"
@data_filename = "#{Prawn::DATADIR}/images/ruport_data.dat"
@img_data = File.binread(@filename)
end
it "should read the attributes from the header chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
png.width.should == 258
png.height.should == 105
png.bits.should == 8
png.color_type.should == 2
png.compression_method.should == 0
png.filter_method.should == 0
png.interlace_method.should == 0
end
it "should read the image data chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
data = File.binread(@data_filename)
png.img_data.should == data
end
end
describe "When reading an RGB PNG file with transparency (color type 2)" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/arrow2.png"
@img_data = File.binread(@filename)
end
# In a RGB type 2 PNG image, the tRNS chunk should contain a single RGB value
# that indicates the color that should be interpreted as transparent. In this
# case it's green.
#
# http://www.w3.org/TR/PNG/#11tRNS
it "should read the tRNS chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
png.transparency[:rgb].should == [0, 255, 0]
end
end
# TODO: describe "When reading an indexed color PNG file wiih transparency (color type 3)"
describe "When reading an indexed color PNG file (color type 3)" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/rails.png"
@data_filename = "#{Prawn::DATADIR}/images/rails.dat"
@img_data = File.binread(@filename)
end
it "should read the attributes from the header chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
png.width.should == 50
png.height.should == 64
png.bits.should == 8
png.color_type.should == 3
png.compression_method.should == 0
png.filter_method.should == 0
png.interlace_method.should == 0
end
it "should read the image data chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
data = File.binread(@data_filename)
png.img_data.should == data
end
end
describe "When reading a greyscale+alpha PNG file (color type 4)" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/page_white_text.png"
@data_filename = "#{Prawn::DATADIR}/images/page_white_text.dat"
@alpha_data_filename = "#{Prawn::DATADIR}/images/page_white_text.alpha"
@img_data = File.binread(@filename)
end
it "should read the attributes from the header chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
png.width.should == 16
png.height.should == 16
png.bits.should == 8
png.color_type.should == 4
png.compression_method.should == 0
png.filter_method.should == 0
png.interlace_method.should == 0
end
it "should correctly return the raw image data (with no alpha channel) from the image data chunk" do
png = Prawn::Images::PNG.new(@img_data)
png.split_alpha_channel!
data = File.binread(@data_filename)
png.img_data.should == data
end
it "should correctly extract the alpha channel data from the image data chunk" do
png = Prawn::Images::PNG.new(@img_data)
png.split_alpha_channel!
data = File.binread(@alpha_data_filename)
png.alpha_channel.should == data
end
end
describe "When reading an RGB+alpha PNG file (color type 6)" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/dice.png"
@data_filename = "#{Prawn::DATADIR}/images/dice.dat"
@alpha_data_filename = "#{Prawn::DATADIR}/images/dice.alpha"
@img_data = File.binread(@filename)
end
it "should read the attributes from the header chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
png.width.should == 320
png.height.should == 240
png.bits.should == 8
png.color_type.should == 6
png.compression_method.should == 0
png.filter_method.should == 0
png.interlace_method.should == 0
end
it "should correctly return the raw image data (with no alpha channel) from the image data chunk" do
png = Prawn::Images::PNG.new(@img_data)
png.split_alpha_channel!
data = File.binread(@data_filename)
# compare decompressed rather than compressed image data
# because JRuby's implementation of Zlib is different from MRI --
# both generate valid gzipped data, but not bit-identical to each other
Zlib::Inflate.inflate(png.img_data).should == Zlib::Inflate.inflate(data)
end
it "should correctly extract the alpha channel data from the image data chunk" do
png = Prawn::Images::PNG.new(@img_data)
png.split_alpha_channel!
data = File.binread(@alpha_data_filename)
Zlib::Inflate.inflate(png.alpha_channel).should == Zlib::Inflate.inflate(data)
end
end
describe "When reading a 16bit RGB+alpha PNG file (color type 6)" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/16bit.png"
@data_filename = "#{Prawn::DATADIR}/images/16bit.dat"
# alpha channel truncated to 8-bit
@alpha_data_filename = "#{Prawn::DATADIR}/images/16bit.alpha"
@img_data = File.binread(@filename)
end
it "should read the attributes from the header chunk correctly" do
png = Prawn::Images::PNG.new(@img_data)
png.width.should == 32
png.height.should == 32
png.bits.should == 16
png.color_type.should == 6
png.compression_method.should == 0
png.filter_method.should == 0
png.interlace_method.should == 0
end
it "should correctly return the raw image data (with no alpha channel) from the image data chunk" do
png = Prawn::Images::PNG.new(@img_data)
png.split_alpha_channel!
data = File.binread(@data_filename)
png.img_data.should == data
end
it "should correctly extract the alpha channel data from the image data chunk" do
png = Prawn::Images::PNG.new(@img_data)
png.split_alpha_channel!
data = File.binread(@alpha_data_filename)
png.alpha_channel.should == data
end
end
ruby-prawn-1.0.0~rc2.orig/spec/stamp_spec.rb 0000644 0000000 0000000 00000012013 12114176157 017477 0 ustar root root require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "create_stamp before any page is added" do
it "should work with the font class" do
@pdf = Prawn::Document.new(:skip_page_creation => true)
lambda {
@pdf.create_stamp("my_stamp") do
@pdf.font.height
end
}.should_not raise_error(Prawn::Errors::NotOnPage)
end
it "should work with setting color" do
@pdf = Prawn::Document.new(:skip_page_creation => true)
lambda {
@pdf.create_stamp("my_stamp") do
@pdf.fill_color = 'ff0000'
end
}.should_not raise_error(Prawn::Errors::NotOnPage)
end
end
describe "#stamp_at" do
it "should work" do
create_pdf
@pdf.create_stamp("MyStamp")
@pdf.stamp_at("MyStamp", [100, 200])
# I had modified PDF::Inspector::XObject to receive the
# invoke_xobject message and count the number of times it was
# called, but it was only called once, so I reverted checking the
# output with a regular expression
@pdf.render.should =~ /\/Stamp1 Do.*?/m
end
end
describe "Document with a stamp" do
it "should raise_error NameTaken error when attempt to create stamp "+
"with same name as an existing stamp" do
create_pdf
@pdf.create_stamp("MyStamp")
lambda {
@pdf.create_stamp("MyStamp")
}.should raise_error(Prawn::Errors::NameTaken)
end
it "should raise_error InvalidName error when attempt to create "+
"stamp with a blank name" do
create_pdf
lambda {
@pdf.create_stamp("")
}.should raise_error(Prawn::Errors::InvalidName)
end
it "a new XObject should be defined for each stamp created" do
create_pdf
@pdf.create_stamp("MyStamp")
@pdf.create_stamp("AnotherStamp")
@pdf.stamp("MyStamp")
@pdf.stamp("AnotherStamp")
inspector = PDF::Inspector::XObject.analyze(@pdf.render)
xobjects = inspector.page_xobjects.last
xobjects.length.should == 2
end
it "calling stamp with a name that does not match an existing stamp "+
"should raise_error UndefinedObjectName" do
create_pdf
@pdf.create_stamp("MyStamp")
lambda {
@pdf.stamp("OtherStamp")
}.should raise_error(Prawn::Errors::UndefinedObjectName)
end
it "stamp should be drawn into the document each time stamp is called" do
create_pdf
@pdf.create_stamp("MyStamp")
@pdf.stamp("MyStamp")
@pdf.stamp("MyStamp")
@pdf.stamp("MyStamp")
# I had modified PDF::Inspector::XObject to receive the
# invoke_xobject message and count the number of times it was
# called, but it was only called once, so I reverted checking the
# output with a regular expression
@pdf.render.should =~ /(\/Stamp1 Do.*?){3}/m
end
it "resources added during stamp creation should be added to the "+
"stamp XObject, not the page" do
create_pdf
@pdf.create_stamp("MyStamp") do
@pdf.transparent(0.5) { @pdf.circle([100, 100], 10)}
end
@pdf.stamp("MyStamp")
# Inspector::XObject does not give information about resources, so
# resorting to string matching
output = @pdf.render
objects = output.split("endobj")
objects.each do |object|
if object =~ /\/Type \/Page$/
object.should_not =~ /\/ExtGState/
elsif object =~ /\/Type \/XObject$/
object.should =~ /\/ExtGState/
end
end
end
it "stamp stream should be wrapped in a graphic state" do
create_pdf
@pdf.create_stamp("MyStamp") do
@pdf.text "This should have a 'q' before it and a 'Q' after it"
end
@pdf.stamp("MyStamp")
stamps = PDF::Inspector::XObject.analyze(@pdf.render)
stamps.xobject_streams[:Stamp1].data.chomp.should =~ /q(.|\s)*Q\Z/
end
it "should not add to the page graphic state stack " do
create_pdf
@pdf.state.page.stack.stack.size.should == 1
@pdf.create_stamp("MyStamp") do
@pdf.save_graphics_state
@pdf.save_graphics_state
@pdf.save_graphics_state
@pdf.text "This should have a 'q' before it and a 'Q' after it"
@pdf.restore_graphics_state
end
@pdf.state.page.stack.stack.size.should == 1
end
it "should be able to change fill and stroke colors within the stamp stream" do
create_pdf
@pdf.create_stamp("MyStamp") do
@pdf.fill_color(100, 100, 20, 0)
@pdf.stroke_color(100, 100, 20, 0)
end
@pdf.stamp("MyStamp")
stamps = PDF::Inspector::XObject.analyze(@pdf.render)
stamp_stream = stamps.xobject_streams[:Stamp1].data
stamp_stream.should include("/DeviceCMYK cs\n1.000 1.000 0.200 0.000 scn")
stamp_stream.should include("/DeviceCMYK CS\n1.000 1.000 0.200 0.000 SCN")
end
it "should save the color space even when same as current page color space" do
create_pdf
@pdf.stroke_color(100, 100, 20, 0)
@pdf.create_stamp("MyStamp") do
@pdf.stroke_color(100, 100, 20, 0)
end
@pdf.stamp("MyStamp")
stamps = PDF::Inspector::XObject.analyze(@pdf.render)
stamp_stream = stamps.xobject_streams[:Stamp1].data
stamp_stream.should include("/DeviceCMYK CS\n1.000 1.000 0.200 0.000 SCN")
end
end
ruby-prawn-1.0.0~rc2.orig/spec/template_spec.rb 0000644 0000000 0000000 00000027512 12114176157 020200 0 ustar root root require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Document built from a template" do
it "should have the same page count as the source document" do
filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
@pdf = Prawn::Document.new(:template => filename)
page_counter = PDF::Inspector::Page.analyze(@pdf.render)
page_counter.pages.size.should == 1
end
it "should not set the template page's parent to the document pages catalog (especially with nested pages)" do
filename = "#{Prawn::DATADIR}/pdfs/nested_pages.pdf"
@pdf = Prawn::Document.new(:template => filename, :skip_page_creation => true)
@pdf.state.page.dictionary.data[:Parent].should_not == @pdf.state.store.pages
end
it "should have start with the Y cursor at the top of the document" do
filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
@pdf = Prawn::Document.new(:template => filename)
(@pdf.y == nil).should == false
end
it "should respect margins set by Prawn" do
filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
@pdf = Prawn::Document.new(:template => filename, :margin => 0)
@pdf.page.margins.should == { :left => 0,
:right => 0,
:top => 0,
:bottom => 0 }
@pdf = Prawn::Document.new(:template => filename, :left_margin => 0)
@pdf.page.margins.should == { :left => 0,
:right => 36,
:top => 36,
:bottom => 36 }
@pdf.start_new_page(:right_margin => 0)
@pdf.page.margins.should == { :left => 0,
:right => 0,
:top => 36,
:bottom => 36 }
end
it "should not add an extra restore_graphics_state operator to the end of any content stream" do
filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
@pdf = Prawn::Document.new(:template => filename)
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
hash.each_value do |obj|
next unless obj.kind_of?(PDF::Reader::Stream)
data = obj.data.tr(" \n\r","")
data.include?("QQ").should == false
end
end
it "should have a single page object if importing a single page template" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
@pdf = Prawn::Document.new(:template => filename)
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
pages = hash.values.select { |obj| obj.kind_of?(Hash) && obj[:Type] == :Page }
pages.size.should == 1
end
it "should have two content streams if importing a single page template" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
@pdf = Prawn::Document.new(:template => filename)
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
streams.size.should == 2
end
it "should not die if using this PDF as a template" do
filename = "#{Prawn::DATADIR}/pdfs/complex_template.pdf"
lambda {
@pdf = Prawn::Document.new(:template => filename)
}.should_not raise_error
end
it "should have balance q/Q operators on all content streams" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
@pdf = Prawn::Document.new(:template => filename)
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
streams.each do |stream|
data = stream.unfiltered_data
data.scan("q").size.should == 1
data.scan("Q").size.should == 1
end
end
it "should allow text to be added to a single page template" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
@pdf = Prawn::Document.new(:template => filename)
@pdf.text "Adding some text"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.first.should == "Adding some text"
end
it "should allow PDFs with page resources behind an indirect object to be used as templates" do
filename = "#{Prawn::DATADIR}/pdfs/resources_as_indirect_object.pdf"
@pdf = Prawn::Document.new(:template => filename)
@pdf.text "Adding some text"
text = PDF::Inspector::Text.analyze(@pdf.render)
all_text = text.strings.join
all_text.include?("Adding some text").should == true
end
it "should copy the PDF version from the template file" do
filename = "#{Prawn::DATADIR}/pdfs/version_1_6.pdf"
@pdf = Prawn::Document.new(:template => filename)
str = @pdf.render
str[0,8].should == "%PDF-1.6"
end
it "should correctly add a TTF font to a template that has existing fonts" do
filename = "#{Prawn::DATADIR}/pdfs/contains_ttf_font.pdf"
@pdf = Prawn::Document.new(:template => filename)
@pdf.font "#{Prawn::DATADIR}/fonts/Chalkboard.ttf"
@pdf.move_down(40)
@pdf.text "Hi There"
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
page_dict = hash.values.detect{ |obj| obj.is_a?(Hash) && obj[:Type] == :Page }
resources = page_dict[:Resources]
fonts = resources[:Font]
fonts.size.should == 2
end
it "should correctly import a template file that is missing a MediaBox entry" do
filename = "#{Prawn::DATADIR}/pdfs/page_without_mediabox.pdf"
@pdf = Prawn::Document.new(:template => filename)
str = @pdf.render
str[0,4].should == "%PDF"
end
context "with the template as a stream" do
it "should correctly import a template file from a stream" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
io = StringIO.new(File.binread(filename))
@pdf = Prawn::Document.new(:template => io)
str = @pdf.render
str[0,4].should == "%PDF"
end
end
it "merges metadata info" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
info = { :Title => "Sample METADATA",
:Author => "Me",
:Subject => "Not Working",
:CreationDate => Time.now }
@pdf = Prawn::Document.new(:template => filename, :info => info)
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
info.keys.each { |k| hash[hash.trailer[:Info]].keys.include?(k).should == true }
end
end
describe "Document#start_new_page with :template option" do
filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
it "should set the imported page's parent to the document pages catalog" do
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => filename)
@pdf.state.page.dictionary.data[:Parent].should == @pdf.state.store.pages
end
it "should set start the Y cursor at the top of the page" do
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => filename)
(@pdf.y == nil).should == false
end
it "should respect margins set by Prawn" do
@pdf = Prawn::Document.new(:margin => 0)
@pdf.start_new_page(:template => filename)
@pdf.page.margins.should == { :left => 0,
:right => 0,
:top => 0,
:bottom => 0 }
@pdf = Prawn::Document.new(:left_margin => 0)
@pdf.start_new_page(:template => filename)
@pdf.page.margins.should == { :left => 0,
:right => 36,
:top => 36,
:bottom => 36 }
@pdf.start_new_page(:template => filename, :right_margin => 0)
@pdf.page.margins.should == { :left => 0,
:right => 0,
:top => 36,
:bottom => 36 }
end
it "should not add an extra restore_graphics_state operator to the end of any content stream" do
@pdf = Prawn::Document.new
@pdf.start_new_page(:template => filename)
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
hash.each_value do |obj|
next unless obj.kind_of?(PDF::Reader::Stream)
data = obj.data.tr(" \n\r","")
data.include?("QQ").should == false
end
end
it "should have two content streams if importing a single page template" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => filename)
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
pages = hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Pages}[:Kids]
template_page = hash[pages[1]]
template_page[:Contents].size.should == 2
end
it "should have balance q/Q operators on all content streams" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => filename)
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
streams.each do |stream|
data = stream.unfiltered_data
data.scan("q").size.should == 1
data.scan("Q").size.should == 1
end
end
it "should allow text to be added to a single page template" do
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => filename)
@pdf.text "Adding some text"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.first.should == "Adding some text"
end
it "should allow PDFs with page resources behind an indirect object to be used as templates" do
filename = "#{Prawn::DATADIR}/pdfs/resources_as_indirect_object.pdf"
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => filename)
@pdf.text "Adding some text"
text = PDF::Inspector::Text.analyze(@pdf.render)
all_text = text.strings.join
all_text.include?("Adding some text").should == true
end
it "should correctly add a TTF font to a template that has existing fonts" do
filename = "#{Prawn::DATADIR}/pdfs/contains_ttf_font.pdf"
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => filename)
@pdf.font "#{Prawn::DATADIR}/fonts/Chalkboard.ttf"
@pdf.move_down(40)
@pdf.text "Hi There"
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
hash = PDF::Reader::ObjectHash.new(output)
pages = hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Pages}[:Kids]
template_page = hash[pages[1]]
resources = template_page[:Resources]
fonts = resources[:Font]
fonts.size.should == 2
end
it "indexes template pages when used multiple times" do
filename = "#{Prawn::DATADIR}/pdfs/multipage_template.pdf"
@repeated_pdf = Prawn::Document.new()
3.times { @repeated_pdf.start_new_page(:template => filename) }
repeated_hash = PDF::Reader::ObjectHash.new(StringIO.new(@repeated_pdf.render))
@sequential_pdf = Prawn::Document.new()
(1..3).each { |p| @sequential_pdf.start_new_page(:template => filename, :template_page => p ) }
sequential_hash = PDF::Reader::ObjectHash.new(StringIO.new(@sequential_pdf.render))
(repeated_hash.size < sequential_hash.size).should == true
end
context "with the template as a stream" do
it "should correctly import a template file from a stream" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
io = StringIO.new(File.binread(filename))
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => io)
str = @pdf.render
str[0,4].should == "%PDF"
end
end
context "using template_page option" do
it "uses the specified page option" do
filename = "#{Prawn::DATADIR}/pdfs/multipage_template.pdf"
@pdf = Prawn::Document.new()
@pdf.start_new_page(:template => filename, :template_page => 2)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.first.should == "This is template page 2"
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/object_store_spec.rb 0000644 0000000 0000000 00000013667 12114176157 021055 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Prawn::ObjectStore" do
before(:each) do
@store = Prawn::Core::ObjectStore.new
end
it "should create required roots by default, including info passed to new" do
store = Prawn::Core::ObjectStore.new(:info => {:Test => 3})
store.size.should == 3 # 3 default roots
store.info.data[:Test].should == 3
store.pages.data[:Count].should == 0
store.root.data[:Pages].should == store.pages
end
it "should import objects from an existing PDF" do
filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.size.should == 5
end
it "should point to existing roots when importing objects from an existing PDF" do
filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.info.class.should == Prawn::Core::Reference
store.root.class.should == Prawn::Core::Reference
end
it "should initialize with pages when importing objects from an existing PDF" do
filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.pages.data[:Count].should == 1
end
it "should import all objects from a PDF that has an indirect reference in a stream dict" do
filename = "#{Prawn::DATADIR}/pdfs/indirect_reference.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.size.should == 8
end
it "should raise_error ArgumentError when given a file that doesn exist as a template" do
filename = "not_really_there.pdf"
lambda { Prawn::Core::ObjectStore.new(:template => filename) }.should raise_error(ArgumentError)
end
it "should raise_error Prawn::Errors::TemplateError when given a non PDF as a template" do
filename = "#{Prawn::DATADIR}/images/dice.png"
lambda { Prawn::Core::ObjectStore.new(:template => filename) }.should raise_error(Prawn::Errors::TemplateError)
end
it "should raise_error Prawn::Errors::TemplateError when given an encrypted PDF as a template" do
filename = "#{Prawn::DATADIR}/pdfs/encrypted.pdf"
lambda { Prawn::Core::ObjectStore.new(:template => filename) }.should raise_error(Prawn::Errors::TemplateError)
end
it "should add to its objects when ref() is called" do
count = @store.size
@store.ref("blah")
@store.size.should == count + 1
end
it "should accept push with a Prawn::Reference" do
r = Prawn::Core::Reference(123, "blah")
@store.push(r)
@store[r.identifier].should == r
end
it "should accept arbitrary data and use it to create a Prawn::Reference" do
@store.push(123, "blahblah")
@store[123].data.should == "blahblah"
end
it "should be Enumerable, yielding in order of submission" do
# higher IDs to bypass the default roots
[10, 11, 12].each do |id|
@store.push(id, "some data #{id}")
end
@store.map{|ref| ref.identifier}[-3..-1].should == [10, 11, 12]
end
end
describe "Prawn::ObjectStore#compact" do
it "should do nothing to an ObjectStore with all live refs" do
store = Prawn::Core::ObjectStore.new
store.info.data[:Blah] = store.ref(:some => "structure")
old_size = store.size
store.compact
store.size.should == old_size
end
it "should remove dead objects, renumbering live objects from 1" do
store = Prawn::Core::ObjectStore.new
store.ref(:some => "structure")
old_size = store.size
store.compact
store.size.should be < old_size
store.map{ |o| o.identifier }.should == (1..store.size).to_a
end
it "should detect and remove dead objects that were once live" do
store = Prawn::Core::ObjectStore.new
store.info.data[:Blah] = store.ref(:some => "structure")
store.info.data[:Blah] = :overwritten
old_size = store.size
store.compact
store.size.should be < old_size
store.map{ |o| o.identifier }.should == (1..store.size).to_a
end
end
describe "Prawn::ObjectStorie#object_id_for_page" do
it "should return the object ID of an imported template page" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.object_id_for_page(0).should == 4
end
it "should return the object ID of the first imported template page" do
filename = "#{Prawn::DATADIR}/pdfs/two_hexagons.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.object_id_for_page(1).should == 4
end
it "should return the object ID of the last imported template page" do
filename = "#{Prawn::DATADIR}/pdfs/two_hexagons.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.object_id_for_page(-1).should == 6
end
it "should return the object ID of the first page of a template that uses nested Pages" do
filename = "#{Prawn::DATADIR}/pdfs/nested_pages.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.object_id_for_page(1).should == 5
end
it "should return the object ID of the last page of a template that uses nested Pages" do
filename = "#{Prawn::DATADIR}/pdfs/nested_pages.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.object_id_for_page(-1).should == 8
end
it "should return nil if given an invalid page number" do
filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
store = Prawn::Core::ObjectStore.new(:template => filename)
store.object_id_for_page(10).should == nil
end
it "should return nil if given an invalid page number" do
store = Prawn::Core::ObjectStore.new
store.object_id_for_page(10).should == nil
end
it "should accept a stream instead of a filename" do
example = Prawn::Document.new()
example.text "An example doc, created in memory"
example.start_new_page
StringIO.open(example.render) do |stream|
@pdf = Prawn::Core::ObjectStore.new(:template => stream)
end
@pdf.page_count.should == 2
end
end
ruby-prawn-1.0.0~rc2.orig/spec/images_spec.rb 0000644 0000000 0000000 00000010602 12114176157 017622 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
require 'set'
require 'pathname'
describe "the image() function" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/pigs.jpg"
create_pdf
end
it "should only embed an image once, even if it's added multiple times" do
@pdf.image @filename, :at => [100,100]
@pdf.image @filename, :at => [300,300]
output = @pdf.render
images = PDF::Inspector::XObject.analyze(output)
# there should be 2 images in the page resources
images.page_xobjects.first.size.should == 2
# but only 1 image xobject
output.scan(/\/Type \/XObject/).size.should == 1
end
it "should return the image info object" do
info = @pdf.image(@filename)
info.should be_a_kind_of(Prawn::Images::JPG)
info.height.should == 453
end
it "should accept IO objects" do
file = File.open(@filename, "rb")
info = @pdf.image(file)
info.height.should == 453
end
it "rewinds IO objects to be able to embed them multiply" do
file = File.open(@filename, "rb")
@pdf.image(file)
info = @pdf.image(file)
info.height.should == 453
end
it "should accept Pathname objects" do
info = @pdf.image(Pathname.new(@filename))
info.height.should == 453
end
it "should raise_error an UnsupportedImageType if passed a BMP" do
filename = "#{Prawn::DATADIR}/images/tru256.bmp"
lambda { @pdf.image filename, :at => [100,100] }.should raise_error(Prawn::Errors::UnsupportedImageType)
end
it "should raise_error an UnsupportedImageType if passed an interlaced PNG" do
filename = "#{Prawn::DATADIR}/images/dice_interlaced.png"
lambda { @pdf.image filename, :at => [100,100] }.should raise_error(Prawn::Errors::UnsupportedImageType)
end
it "should bump PDF version to 1.5 or greater on embedding 16-bit PNGs" do
@pdf.image "#{Prawn::DATADIR}/images/16bit.png"
@pdf.state.version.should >= 1.5
end
# to support Adobe Reader, which apparently doesn't handle 16-bit alpha
# channels. Verified experimentally [BE] but not confirmed in documentation
# or anything. OS X Preview handles those files just fine.
#
it "should embed 8-bit alpha channels for 16-bit PNGs" do
@pdf.image "#{Prawn::DATADIR}/images/16bit.png"
output = @pdf.render
output.should =~ /\/BitsPerComponent 16/
output.should =~ /\/BitsPerComponent 8/
end
it "should flow an image to a new page if it will not fit on a page" do
@pdf.image @filename, :fit => [600, 600]
@pdf.image @filename, :fit => [600, 600]
output = StringIO.new(@pdf.render, 'r+')
hash = PDF::Reader::ObjectHash.new(output)
pages = hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Pages}[:Kids]
pages.size.should == 2
hash[pages[0]][:Resources][:XObject].keys.should == [:I1]
hash[pages[1]][:Resources][:XObject].keys.should == [:I2]
end
it "should not flow an image to a new page if it will fit on one page" do
@pdf.image @filename, :fit => [400, 400]
@pdf.image @filename, :fit => [400, 400]
output = StringIO.new(@pdf.render, 'r+')
hash = PDF::Reader::ObjectHash.new(output)
pages = hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Pages}[:Kids]
pages.size.should == 1
Set.new(hash[pages[0]][:Resources][:XObject].keys).should ==
Set.new([:I1, :I2])
end
it "should not start a new page just for a stretchy bounding box" do
@pdf.expects(:start_new_page).times(0)
@pdf.bounding_box([0, @pdf.cursor], :width => @pdf.bounds.width) do
@pdf.image @filename
end
end
describe ":fit option" do
it "should fit inside the defined constraints" do
info = @pdf.image @filename, :fit => [100,400]
info.scaled_width.should <= 100
info.scaled_height.should <= 400
info = @pdf.image @filename, :fit => [400,100]
info.scaled_width.should <= 400
info.scaled_height.should <= 100
info = @pdf.image @filename, :fit => [604,453]
info.scaled_width.should == 604
info.scaled_height.should == 453
end
it "should move text position" do
@y = @pdf.y
info = @pdf.image @filename, :fit => [100,400]
@pdf.y.should < @y
end
end
describe ":at option" do
it "should not move text position" do
@y = @pdf.y
info = @pdf.image @filename, :at => [100,400]
@pdf.y.should == @y
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/stroke_styles_spec.rb 0000644 0000000 0000000 00000012672 12114176157 021300 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "When stroking with default settings" do
before(:each) { create_pdf }
it "cap_style should be :butt" do
@pdf.cap_style.should == :butt
end
it "join_style should be :miter" do
@pdf.join_style.should == :miter
end
it "dashed? should be_false" do
@pdf.should_not be_dashed
end
end
describe "Cap styles" do
before(:each) { create_pdf }
it "should be able to use assignment operator" do
@pdf.cap_style = :round
@pdf.cap_style.should == :round
end
describe "#cap_style(:butt)" do
it "rendered PDF should include butt style cap" do
@pdf.cap_style(:butt)
cap_style = PDF::Inspector::Graphics::CapStyle.analyze(@pdf.render).cap_style
cap_style.should == 0
end
end
describe "#cap_style(:round)" do
it "rendered PDF should include round style cap" do
@pdf.cap_style(:round)
cap_style = PDF::Inspector::Graphics::CapStyle.analyze(@pdf.render).cap_style
cap_style.should == 1
end
end
describe "#cap_style(:projecting_square)" do
it "rendered PDF should include projecting_square style cap" do
@pdf.cap_style(:projecting_square)
cap_style = PDF::Inspector::Graphics::CapStyle.analyze(@pdf.render).cap_style
cap_style.should == 2
end
end
it "should carry the current cap style settings over to new pages" do
@pdf.cap_style(:round)
@pdf.start_new_page
cap_styles = PDF::Inspector::Graphics::CapStyle.analyze(@pdf.render)
cap_styles.cap_style_count.should == 2
cap_styles.cap_style.should == 1
end
end
describe "Join styles" do
before(:each) { create_pdf }
it "should be able to use assignment operator" do
@pdf.join_style = :round
@pdf.join_style.should == :round
end
describe "#join_style(:miter)" do
it "rendered PDF should include miter style join" do
@pdf.join_style(:miter)
join_style = PDF::Inspector::Graphics::JoinStyle.analyze(@pdf.render).join_style
join_style.should == 0
end
end
describe "#join_style(:round)" do
it "rendered PDF should include round style join" do
@pdf.join_style(:round)
join_style = PDF::Inspector::Graphics::JoinStyle.analyze(@pdf.render).join_style
join_style.should == 1
end
end
describe "#join_style(:bevel)" do
it "rendered PDF should include bevel style join" do
@pdf.join_style(:bevel)
join_style = PDF::Inspector::Graphics::JoinStyle.analyze(@pdf.render).join_style
join_style.should == 2
end
end
it "should carry the current join style settings over to new pages" do
@pdf.join_style(:round)
@pdf.start_new_page
join_styles = PDF::Inspector::Graphics::JoinStyle.analyze(@pdf.render)
join_styles.join_style_count.should == 2
join_styles.join_style.should == 1
end
end
describe "Dashes" do
before(:each) { create_pdf }
it "should be able to use assignment operator" do
@pdf.dash = 2
@pdf.should be_dashed
end
describe "setting a dash" do
it "dashed? should be_true" do
@pdf.dash(2)
@pdf.should be_dashed
end
it "rendered PDF should include a stroked dash" do
@pdf.dash(2)
dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render)
dashes.stroke_dash.should == [[2, 2], 0]
end
end
describe "setting a dash by passing a single argument" do
it "space between dashes should be the same length as the dash in the rendered PDF" do
@pdf.dash(2)
dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render)
dashes.stroke_dash.should == [[2, 2], 0]
end
end
describe "with a space option that differs from the first argument" do
it "space between dashes in the rendered PDF should be different length than the length of the dash" do
@pdf.dash(2, :space => 3)
dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render)
dashes.stroke_dash.should == [[2, 3], 0]
end
end
describe "with a non-zero phase option" do
it "rendered PDF should include a non-zero phase" do
@pdf.dash(2, :phase => 1)
dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render)
dashes.stroke_dash.should == [[2, 2], 1]
end
end
describe "clearing stroke dash" do
it "should restore solid line" do
@pdf.dash(2)
@pdf.undash
dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render)
dashes.stroke_dash.should == [[], 0]
end
end
it "should carry the current dash settings over to new pages" do
@pdf.dash(2)
@pdf.start_new_page
dashes = PDF::Inspector::Graphics::Dash.analyze(@pdf.render)
dashes.stroke_dash_count.should == 2
dashes.stroke_dash.should == [[2, 2], 0]
end
describe "#dashed?" do
it "an initial document should not be dashed" do
@pdf.dashed?.should == false
end
it "should return true if any of the currently active settings are dashed" do
@pdf.dash(2)
@pdf.save_graphics_state
@pdf.dashed?.should == true
end
it "should return false if the document was most recently undashed" do
@pdf.dash(2)
@pdf.save_graphics_state
@pdf.undash
@pdf.save_graphics_state
@pdf.dashed?.should == false
end
it "should return true when restoring to a state that was dashed" do
@pdf.dash(2)
@pdf.save_graphics_state
@pdf.undash
@pdf.restore_graphics_state
@pdf.dashed?.should == true
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/pdf_object_spec.rb 0000644 0000000 0000000 00000015557 12114176157 020472 0 ustar root root # encoding: ASCII-8BIT
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
# See PDF Reference, Sixth Edition (1.7) pp51-60 for details
describe "PDF Object Serialization" do
it "should convert Ruby's nil to PDF null" do
Prawn::Core::PdfObject(nil).should == "null"
end
it "should convert Ruby booleans to PDF booleans" do
Prawn::Core::PdfObject(true).should == "true"
Prawn::Core::PdfObject(false).should == "false"
end
it "should convert a Ruby number to PDF number" do
Prawn::Core::PdfObject(1).should == "1"
Prawn::Core::PdfObject(1.214112421).should == "1.214112421"
# scientific notation is not valid in PDF
Prawn::Core::PdfObject(0.000005).should == "0.000005"
end
it "should convert a Ruby time object to a PDF timestamp" do
t = Time.now
Prawn::Core::PdfObject(t).should == t.strftime("(D:%Y%m%d%H%M%S%z").chop.chop + "'00')"
end
it "should convert a Ruby string to PDF string when inside a content stream" do
s = "I can has a string"
PDF::Inspector.parse(Prawn::Core::PdfObject(s, true)).should == s
end
it "should convert a Ruby string to a UTF-16 PDF string when outside a content stream" do
s = "I can has a string"
s_utf16 = "\xFE\xFF" + s.unpack("U*").pack("n*")
PDF::Inspector.parse(Prawn::Core::PdfObject(s, false)).should == s_utf16
end
it "should convert a Ruby string with characters outside the BMP to its " +
"UTF-16 representation with a BOM" do
# U+10192 ROMAN SEMUNCIA SIGN
semuncia = [65938].pack("U")
Prawn::Core::PdfObject(semuncia, false).upcase.should == ""
end
it "should pass through bytes regardless of content stream status for ByteString" do
Prawn::Core::PdfObject(Prawn::Core::ByteString.new("\xDE\xAD\xBE\xEF")).upcase.
should == ""
end
it "should escape parens when converting from Ruby string to PDF" do
s = 'I )(can has a string'
PDF::Inspector.parse(Prawn::Core::PdfObject(s, true)).should == s
end
it "should handle ruby escaped parens when converting to PDF string" do
s = 'I can \\)( has string'
PDF::Inspector.parse(Prawn::Core::PdfObject(s, true)).should == s
end
it "should escape various strings correctly when converting a LiteralString" do
ls = Prawn::Core::LiteralString.new("abc")
Prawn::Core::PdfObject(ls).should == "(abc)"
ls = Prawn::Core::LiteralString.new("abc\x0Ade") # should escape \n
Prawn::Core::PdfObject(ls).should == "(abc\x5C\x0Ade)"
ls = Prawn::Core::LiteralString.new("abc\x0Dde") # should escape \r
Prawn::Core::PdfObject(ls).should == "(abc\x5C\x0Dde)"
ls = Prawn::Core::LiteralString.new("abc\x09de") # should escape \t
Prawn::Core::PdfObject(ls).should == "(abc\x5C\x09de)"
ls = Prawn::Core::LiteralString.new("abc\x08de") # should escape \b
Prawn::Core::PdfObject(ls).should == "(abc\x5C\x08de)"
ls = Prawn::Core::LiteralString.new("abc\x0Cde") # should escape \f
Prawn::Core::PdfObject(ls).should == "(abc\x5C\x0Cde)"
ls = Prawn::Core::LiteralString.new("abc(de") # should escape \(
Prawn::Core::PdfObject(ls).should == "(abc\x5C(de)"
ls = Prawn::Core::LiteralString.new("abc)de") # should escape \)
Prawn::Core::PdfObject(ls).should == "(abc\x5C)de)"
ls = Prawn::Core::LiteralString.new("abc\x5Cde") # should escape \\
Prawn::Core::PdfObject(ls).should == "(abc\x5C\x5Cde)"
Prawn::Core::PdfObject(ls).size.should == 9
end
it "should escape strings correctly when converting a LiteralString that is not utf-8" do
data = "\x43\xaf\xc9\x7f\xef\xf\xe6\xa8\xcb\x5c\xaf\xd0"
ls = Prawn::Core::LiteralString.new(data)
Prawn::Core::PdfObject(ls).should == "(\x43\xaf\xc9\x7f\xef\xf\xe6\xa8\xcb\x5c\x5c\xaf\xd0)"
end
it "should convert a Ruby symbol to PDF name" do
Prawn::Core::PdfObject(:my_symbol).should == "/my_symbol"
Prawn::Core::PdfObject(:"A;Name_With-Various***Characters?").should ==
"/A;Name_With-Various***Characters?"
end
it "should convert a whitespace or delimiter containing Ruby symbol to a PDF name" do
Prawn::Core::PdfObject(:"my symbol").should == "/my#20symbol"
Prawn::Core::PdfObject(:"my#symbol").should == "/my#23symbol"
Prawn::Core::PdfObject(:"my/symbol").should == "/my#2Fsymbol"
Prawn::Core::PdfObject(:"my(symbol").should == "/my#28symbol"
Prawn::Core::PdfObject(:"my)symbol").should == "/my#29symbol"
Prawn::Core::PdfObject(:"mysymbol").should == "/my#3Esymbol"
end
it "should convert a Ruby array to PDF Array when inside a content stream" do
Prawn::Core::PdfObject([1,2,3]).should == "[1 2 3]"
PDF::Inspector.parse(Prawn::Core::PdfObject([[1,2],:foo,"Bar"], true)).should ==
[[1,2],:foo, "Bar"]
end
it "should convert a Ruby array to PDF Array when outside a content stream" do
bar = "\xFE\xFF" + "Bar".unpack("U*").pack("n*")
Prawn::Core::PdfObject([1,2,3]).should == "[1 2 3]"
PDF::Inspector.parse(Prawn::Core::PdfObject([[1,2],:foo,"Bar"], false)).should ==
[[1,2],:foo, bar]
end
it "should convert a Ruby hash to a PDF Dictionary when inside a content stream" do
dict = Prawn::Core::PdfObject( {:foo => :bar,
"baz" => [1,2,3],
:bang => {:a => "what", :b => [:you, :say] }}, true )
res = PDF::Inspector.parse(dict)
res[:foo].should == :bar
res[:baz].should == [1,2,3]
res[:bang].should == { :a => "what", :b => [:you, :say] }
end
it "should convert a Ruby hash to a PDF Dictionary when outside a content stream" do
what = "\xFE\xFF" + "what".unpack("U*").pack("n*")
dict = Prawn::Core::PdfObject( {:foo => :bar,
"baz" => [1,2,3],
:bang => {:a => "what", :b => [:you, :say] }}, false )
res = PDF::Inspector.parse(dict)
res[:foo].should == :bar
res[:baz].should == [1,2,3]
res[:bang].should == { :a => what, :b => [:you, :say] }
end
it "should not allow keys other than strings or symbols for PDF dicts" do
lambda { Prawn::Core::PdfObject(:foo => :bar, :baz => :bang, 1 => 4) }.
should raise_error(Prawn::Errors::FailedObjectConversion)
end
it "should convert a Prawn::Reference to a PDF indirect object reference" do
ref = Prawn::Core::Reference(1,true)
Prawn::Core::PdfObject(ref).should == ref.to_s
end
it "should convert a NameTree::Node to a PDF hash" do
node = Prawn::Core::NameTree::Node.new(Prawn::Document.new, 10)
node.add "hello", 1.0
node.add "world", 2.0
data = Prawn::Core::PdfObject(node)
res = PDF::Inspector.parse(data)
res.should == {:Names => ["hello", 1.0, "world", 2.0]}
end
end
ruby-prawn-1.0.0~rc2.orig/spec/text_with_inline_formatting_spec.rb 0000644 0000000 0000000 00000002163 12114176157 024167 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "#formatted_text" do
it "should draw text" do
create_pdf
string = "hello world"
format_array = [:text => string]
@pdf.formatted_text(format_array)
# grab the text from the rendered PDF and ensure it matches
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.first.should == string
end
end
describe "#text with inline styling" do
before(:each) { create_pdf }
it "should automatically move to a new page if the tallest fragment" +
" on the next line won't fit in the available space" do
create_pdf
@pdf.move_cursor_to(@pdf.font.height)
formatted = "this contains sized text"
@pdf.text(formatted, :inline_format => true)
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.size.should == 2
end
it "should embed links as literal strings" do
@pdf.text "wiki",
:inline_format => true
@pdf.render.should =~ %r{/URI\s+\(http://wiki\.github\.com}
end
end
ruby-prawn-1.0.0~rc2.orig/spec/inline_formatted_text_parser_spec.rb 0000644 0000000 0000000 00000050073 12114176157 024326 0 ustar root root # -*- coding: utf-8 -*-
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Text::Formatted::Parser#to_array" do
it "should handle sup" do
string = "superscript"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "superscript",
:styles => [:superscript],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should handle sub" do
string = "subscript"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "subscript",
:styles => [:subscript],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should handle rgb" do
string = "red text"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "red text",
:styles => [],
:color => "ff0000",
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "# should be optional in rgb" do
string = "red text"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "red text",
:styles => [],
:color => "ff0000",
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should handle cmyk" do
string = "magenta text"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "magenta text",
:styles => [],
:color => [0, 100, 0, 0],
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should handle fonts" do
string = "Courier text"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "Courier text",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => "Courier",
:size => nil,
:character_spacing => nil }
end
it "should handle size" do
string = "14 point text"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "14 point text",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => 14,
:character_spacing => nil }
end
it "should handle character_spacing" do
string = "extra character spacing"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "extra character spacing",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => 2.5 }
end
it "should handle links" do
string = "external link"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "external link",
:styles => [],
:color => nil,
:link => "http://example.com",
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should handle anchors" do
string = "internal link"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "internal link",
:styles => [],
:color => nil,
:link => nil,
:anchor => "ToC",
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should handle higher order characters properly" do
string = "©\n©"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "©",
:styles => [:bold],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[1].should == { :text => "\n",
:styles => [:bold],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[2].should == { :text => "©",
:styles => [:bold],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should convert < >, and & to <, >, and &, respectively" do
string = "hello <, >, and &"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[1].should == { :text => "<, >, and &",
:styles => [:bold],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should handle double qoutes around tag attributes" do
string = 'some sized text'
array = Prawn::Text::Formatted::Parser.to_array(string)
array[1].should == { :text => "sized",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => 14,
:character_spacing => nil }
end
it "should handle single qoutes around tag attributes" do
string = "some sized text"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[1].should == { :text => "sized",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => 14,
:character_spacing => nil }
end
it "should construct a formatted text array from a string" do
string = "hello world\nhow are you?"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "hello ",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[1].should == { :text => "world",
:styles => [:bold],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[2].should == { :text => "\n",
:styles => [:bold],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[3].should == { :text => "how ",
:styles => [:bold],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[4].should == { :text => "are",
:styles => [:bold, :italic],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[5].should == { :text => " you?",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should accept as an alternative to " do
string = "bold not bold"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "bold",
:styles => [:bold],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[1].should == { :text => " not bold",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should accept as an alternative to " do
string = "italic not italic"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "italic",
:styles => [:italic],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[1].should == { :text => " not italic",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should accept as an alternative to " do
string = "link not a link"
array = Prawn::Text::Formatted::Parser.to_array(string)
array[0].should == { :text => "link",
:styles => [],
:color => nil,
:link => "http://example.com",
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
array[1].should == { :text => " not a link",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
end
it "should turn
,
into newline" do
array = Prawn::Text::Formatted::Parser.to_array("hello
big
world")
array.map { |frag| frag[:text] }.join.should == "hello\nbig\nworld"
end
end
describe "Text::Formatted::Parser#to_string" do
it "should handle sup" do
string = "superscript"
array = [{ :text => "superscript",
:styles => [:superscript],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }]
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should handle sub" do
string = "subscript"
array = [{ :text => "subscript",
:styles => [:subscript],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }]
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should handle rgb" do
string = "red text"
array = [{ :text => "red text",
:styles => [],
:color => "ff0000",
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }]
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should handle cmyk" do
string = "magenta text"
array = [{ :text => "magenta text",
:styles => [],
:color => [0, 100, 0, 0],
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }]
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should handle fonts" do
string = "Courier text"
array = [{ :text => "Courier text",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => "Courier",
:size => nil,
:character_spacing => nil }]
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should handle size" do
string = "14 point text"
array = [{ :text => "14 point text",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => 14,
:character_spacing => nil }]
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should handle character spacing" do
string = "2.5 extra character spacing"
array = [{ :text => "2.5 extra character spacing",
:styles => [],
:color => nil,
:link => nil,
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => 2.5 }]
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should handle links" do
array = [{ :text => "external link",
:styles => [],
:color => nil,
:link => "http://example.com",
:anchor => nil,
:font => nil,
:size => nil,
:character_spacing => nil }]
string = "external link"
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should handle anchors" do
array = [{ :text => "internal link",
:styles => [],
:color => nil,
:link => nil,
:anchor => "ToC",
:font => nil,
:size => nil,
:character_spacing => nil }]
string = "internal link"
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should convert <, >, and & to < >, and &, respectively" do
array = [{ :text => "hello ",
:styles => [],
:color => nil,
:link => nil,
:font => nil,
:size => nil,
:character_spacing => nil },
{ :text => "<, >, and &",
:styles => [:bold],
:color => nil,
:link => nil,
:font => nil,
:size => nil,
:character_spacing => nil }]
string = "hello <, >, and &"
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
it "should construct an HTML-esque string from a formatted" +
" text array" do
array = [
{ :text => "hello ",
:styles => [],
:color => nil,
:link => nil,
:font => nil,
:size => 14,
:character_spacing => nil },
{ :text => "world",
:styles => [:bold],
:color => nil,
:link => nil,
:font => nil,
:size => nil,
:character_spacing => nil },
{ :text => "\n",
:styles => [:bold],
:color => nil,
:link => nil,
:font => nil,
:size => nil,
:character_spacing => nil },
{ :text => "how ",
:styles => [:bold],
:color => nil,
:link => nil,
:font => nil,
:size => nil,
:character_spacing => nil },
{ :text => "are",
:styles => [:bold, :italic],
:color => nil,
:link => nil,
:font => nil,
:size => nil,
:character_spacing => nil },
{ :text => " you?",
:styles => [],
:color => nil,
:link => nil,
:font => nil,
:size => nil,
:character_spacing => nil }
]
string = "hello world\nhow are you?"
Prawn::Text::Formatted::Parser.to_string(array).should == string
end
end
describe "Text::Formatted::Parser#array_paragraphs" do
it "should group fragments separated by newlines" do
array = [{ :text => "\nhello\nworld" },
{ :text => "\n\n" },
{ :text => "how" },
{ :text => "are" },
{ :text => "you" }]
target = [[{ :text => "\n"}],
[{ :text => "hello" }],
[{ :text => "world" }],
[{ :text => "\n"}],
[{ :text => "how" },
{ :text => "are" },
{ :text => "you" }]]
Prawn::Text::Formatted::Parser.array_paragraphs(array).should == target
end
it "should work properly if ending in an empty paragraph" do
array = [{ :text => "\nhello\nworld\n" }]
target = [[{ :text => "\n" }],
[{ :text => "hello" }],
[{ :text => "world" }]]
Prawn::Text::Formatted::Parser.array_paragraphs(array).should == target
end
end
ruby-prawn-1.0.0~rc2.orig/spec/document_spec.rb 0000644 0000000 0000000 00000053541 12114176157 020204 0 ustar root root # encoding: utf-8
require "tempfile"
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Prawn::Document.new" do
it "should not modify its argument" do
options = {:page_layout => :landscape}
Prawn::Document.new(options)
options.should == {:page_layout => :landscape}
end
end
describe "The cursor" do
it "should == pdf.y - bounds.absolute_bottom" do
pdf = Prawn::Document.new
pdf.cursor.should == pdf.bounds.top
pdf.y = 300
pdf.cursor.should == pdf.y - pdf.bounds.absolute_bottom
end
it "should be able to move relative to the bottom margin" do
pdf = Prawn::Document.new
pdf.move_cursor_to(10)
pdf.cursor.should == 10
pdf.y.should == pdf.cursor + pdf.bounds.absolute_bottom
end
end
describe "when generating a document from a subclass" do
it "should be an instance of the subclass" do
custom_document = Class.new(Prawn::Document)
custom_document.generate(Tempfile.new("generate_test").path) do |e|
e.class.should == custom_document
e.should be_a_kind_of(Prawn::Document)
end
end
it "should retain any extensions found on Prawn::Document" do
mod1 = Module.new { attr_reader :test_extensions1 }
mod2 = Module.new { attr_reader :test_extensions2 }
Prawn::Document.extensions << mod1 << mod2
custom_document = Class.new(Prawn::Document)
custom_document.extensions.should == [mod1, mod2]
# remove the extensions we added to prawn document
Prawn::Document.extensions.delete(mod1)
Prawn::Document.extensions.delete(mod2)
Prawn::Document.new.respond_to?(:test_extensions1).should be_false
Prawn::Document.new.respond_to?(:test_extensions2).should be_false
# verify these still exist on custom class
custom_document.extensions.should == [mod1, mod2]
custom_document.new.respond_to?(:test_extensions1).should be_true
custom_document.new.respond_to?(:test_extensions2).should be_true
end
end
describe "When creating multi-page documents" do
before(:each) { create_pdf }
it "should initialize with a single page" do
page_counter = PDF::Inspector::Page.analyze(@pdf.render)
page_counter.pages.size.should == 1
@pdf.page_count.should == 1
end
it "should provide an accurate page_count" do
3.times { @pdf.start_new_page }
page_counter = PDF::Inspector::Page.analyze(@pdf.render)
page_counter.pages.size.should == 4
@pdf.page_count.should == 4
end
end
describe "When beginning each new page" do
describe "Background template feature" do
before(:each) do
@filename = "#{Prawn::DATADIR}/images/pigs.jpg"
@pdf = Prawn::Document.new(:background => @filename)
end
it "should place a background image if it is in options block" do
output = @pdf.render
images = PDF::Inspector::XObject.analyze(output)
# there should be 2 images in the page resources
images.page_xobjects.first.size.should == 1
end
it "should place a background image if it is in options block" do
@pdf.instance_variable_defined?(:@background).should == true
@pdf.instance_variable_get(:@background).should == @filename
end
end
end
describe "Prawn::Document#float" do
it "should restore the original y-position" do
create_pdf
orig_y = @pdf.y
@pdf.float { @pdf.text "Foo" }
@pdf.y.should == orig_y
end
it "should teleport across pages if necessary" do
create_pdf
@pdf.float do
@pdf.text "Foo"
@pdf.start_new_page
@pdf.text "Bar"
end
@pdf.text "Baz"
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.size.should == 2
pages[0][:strings].should == ["Foo", "Baz"]
pages[1][:strings].should == ["Bar"]
end
end
describe "The page_number method" do
it "should be 1 for a new document" do
pdf = Prawn::Document.new
pdf.page_number.should == 1
end
it "should be 0 for documents with no pages" do
pdf = Prawn::Document.new(:skip_page_creation => true)
pdf.page_number.should == 0
end
it "should be changed by go_to_page" do
pdf = Prawn::Document.new
10.times { pdf.start_new_page }
pdf.go_to_page 3
pdf.page_number.should == 3
end
end
describe "on_page_create callback" do
before do
create_pdf
end
it "should be invoked with document" do
called_with = nil
@pdf.on_page_create { |*args| called_with = args }
@pdf.start_new_page
called_with.should == [@pdf]
end
it "should be invoked for each new page" do
trigger = mock()
trigger.expects(:fire).times(5)
@pdf.on_page_create { trigger.fire }
5.times { @pdf.start_new_page }
end
it "should be replaceable" do
trigger1 = mock()
trigger1.expects(:fire).times(1)
trigger2 = mock()
trigger2.expects(:fire).times(1)
@pdf.on_page_create { trigger1.fire }
@pdf.start_new_page
@pdf.on_page_create { trigger2.fire }
@pdf.start_new_page
end
it "should be clearable by calling on_page_create without a block" do
trigger = mock()
trigger.expects(:fire).times(1)
@pdf.on_page_create { trigger.fire }
@pdf.start_new_page
@pdf.on_page_create
@pdf.start_new_page
end
end
describe "Document compression" do
it "should not compress the page content stream if compression is disabled" do
pdf = Prawn::Document.new(:compress => false)
pdf.page.content.stubs(:compress_stream).returns(true)
pdf.page.content.expects(:compress_stream).never
pdf.text "Hi There" * 20
pdf.render
end
it "should compress the page content stream if compression is enabled" do
pdf = Prawn::Document.new(:compress => true)
pdf.page.content.stubs(:compress_stream).returns(true)
pdf.page.content.expects(:compress_stream).once
pdf.text "Hi There" * 20
pdf.render
end
it "should result in a smaller file size when compressed" do
doc_uncompressed = Prawn::Document.new
doc_compressed = Prawn::Document.new(:compress => true)
[doc_compressed, doc_uncompressed].each do |pdf|
pdf.font "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
pdf.text "更可怕的是,同质化竞争对手可以按照URL中后面这个ID来遍历" * 10
end
doc_compressed.render.length.should be < doc_uncompressed.render.length
end
end
describe "Document metadata" do
it "should output strings as UTF-16 with a byte order mark" do
pdf = Prawn::Document.new(:info => {:Author => "Lóránt"})
pdf.state.store.info.object.should =~
# UTF-16: BOM L ó r á n t
%r{/Author\s*}i
end
end
describe "When reopening pages" do
it "should modify the content stream size" do
@pdf = Prawn::Document.new do |pdf|
pdf.text "Page 1"
pdf.start_new_page
pdf.text "Page 2"
pdf.go_to_page 1
pdf.text "More for page 1"
end
# MalformedPDFError raised if content stream actual length does not match
# dictionary length
lambda{ PDF::Inspector::Page.analyze(@pdf.render) }.
should_not raise_error(PDF::Reader::MalformedPDFError)
end
it "should insert pages after the current page when calling start_new_page" do
pdf = Prawn::Document.new
3.times { |i| pdf.text "Old page #{i+1}"; pdf.start_new_page }
pdf.go_to_page 1
pdf.start_new_page
pdf.text "New page 2"
pdf.page_number.should == 2
pages = PDF::Inspector::Page.analyze(pdf.render).pages
pages.size.should == 5
pages[1][:strings].should == ["New page 2"]
pages[2][:strings].should == ["Old page 2"]
end
it "should update the bounding box to the new page's margin box" do
Prawn::Document.new do
start_new_page :layout => :landscape
lsize = [bounds.width, bounds.height]
go_to_page 1
[bounds.width, bounds.height].should == lsize.reverse
end
end
end
describe "When setting page size" do
it "should default to LETTER" do
@pdf = Prawn::Document.new
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.first[:size].should == Prawn::Document::PageGeometry::SIZES["LETTER"]
end
(Prawn::Document::PageGeometry::SIZES.keys - ["LETTER"]).each do |k|
it "should provide #{k} geometry" do
@pdf = Prawn::Document.new(:page_size => k)
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.first[:size].should == Prawn::Document::PageGeometry::SIZES[k]
end
end
it "should allow custom page size" do
@pdf = Prawn::Document.new(:page_size => [1920, 1080] )
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.first[:size].should == [1920, 1080]
end
it "should retain page size by default when starting a new page" do
@pdf = Prawn::Document.new(:page_size => "LEGAL")
@pdf.start_new_page
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.each do |page|
page[:size].should == Prawn::Document::PageGeometry::SIZES["LEGAL"]
end
end
end
describe "When setting page layout" do
it "should reverse coordinates for landscape" do
@pdf = Prawn::Document.new(:page_size => "A4", :page_layout => :landscape)
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.first[:size].should == Prawn::Document::PageGeometry::SIZES["A4"].reverse
end
it "should retain page layout by default when starting a new page" do
@pdf = Prawn::Document.new(:page_layout => :landscape)
@pdf.start_new_page(:trace => true)
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.each do |page|
page[:size].should == Prawn::Document::PageGeometry::SIZES["LETTER"].reverse
end
end
it "should swap the bounds when starting a new page with different layout" do
@pdf = Prawn::Document.new
size = [@pdf.bounds.width, @pdf.bounds.height]
@pdf.start_new_page(:layout => :landscape)
[@pdf.bounds.width, @pdf.bounds.height].should == size.reverse
end
end
describe "The mask() feature" do
it "should allow transactional restoration of attributes" do
@pdf = Prawn::Document.new
y, line_width = @pdf.y, @pdf.line_width
@pdf.mask(:y, :line_width) do
@pdf.y = y + 1
@pdf.line_width = line_width + 1
@pdf.y.should_not == y
@pdf.line_width.should_not == line_width
end
@pdf.y.should == y
@pdf.line_width.should == line_width
end
end
describe "The group() feature" do
it "should return a true value if the content fits on one page" do
pdf = Prawn::Document.new do
val = group { text "Hello"; text "World" }
(!!val).should == true
end
end
it "should group a simple block on a single page" do
pdf = Prawn::Document.new do
self.y = 50
val = group do
text "Hello"
text "World"
end
# group should return a false value since a new page was started
(!!val).should == false
end
pages = PDF::Inspector::Page.analyze(pdf.render).pages
pages.size.should == 2
pages[0][:strings].should == []
pages[1][:strings].should == ["Hello", "World"]
end
it "should raise_error CannotGroup if the content is too tall" do
lambda {
Prawn::Document.new do
group do
100.times { text "Too long" }
end
end.render
}.should raise_error(Prawn::Errors::CannotGroup)
end
it "should group within individual column boxes" do
pdf = Prawn::Document.new do
# Set up columns with grouped blocks of 0..49. 0 to 49 is slightly short
# of the height of one page / column, so each column should get its own
# group (every column should start with zero).
column_box([0, bounds.top], :width => bounds.width, :columns => 7) do
10.times do
group { 50.times { |i| text(i.to_s) } }
end
end
end
# Second page should start with a 0 because it's a new group.
pages = PDF::Inspector::Page.analyze(pdf.render).pages
pages.size.should == 2
pages[1][:strings].first.should == '0'
end
end
describe "The render() feature" do
if "spec".respond_to?(:encode!)
it "should return a 8 bit encoded string on a m17n aware VM" do
@pdf = Prawn::Document.new(:page_size => "A4", :page_layout => :landscape)
@pdf.line [100,100], [200,200]
str = @pdf.render
str.encoding.to_s.should == "ASCII-8BIT"
end
end
it "should trigger before_render callbacks just before rendering" do
pdf = Prawn::Document.new
seq = sequence("callback_order")
# Verify the order: finalize -> fire callbacks -> render body
pdf.expects(:finalize_all_page_contents).in_sequence(seq)
trigger = mock()
trigger.expects(:fire).in_sequence(seq)
# Store away the render_body method to be called below
render_body = pdf.method(:render_body)
pdf.expects(:render_body).in_sequence(seq)
pdf.before_render{ trigger.fire }
# Render the body to set up object offsets
render_body.call(StringIO.new)
pdf.render
end
it "should be idempotent" do
pdf = Prawn::Document.new
contents = pdf.render
contents2 = pdf.render
contents2.should == contents
end
end
describe "The :optimize_objects option" do
before(:all) do
@wasteful_doc = lambda do |pdf|
pdf.transaction do
pdf.start_new_page
pdf.text "Hidden text"
pdf.rollback
end
pdf.text "Hello world"
end
end
it "should result in fewer objects when enabled" do
wasteful_pdf = Prawn::Document.new(&@wasteful_doc)
frugal_pdf = Prawn::Document.new(:optimize_objects => true,
&@wasteful_doc)
frugal_pdf.render.size.should be < wasteful_pdf.render.size
end
it "should default to :false" do
default_pdf = Prawn::Document.new(&@wasteful_doc)
wasteful_pdf = Prawn::Document.new(:optimize_objects => false,
&@wasteful_doc)
default_pdf.render.size.should == wasteful_pdf.render.size
end
end
describe "PDF file versions" do
it "should default to 1.3" do
@pdf = Prawn::Document.new
str = @pdf.render
str[0,8].should == "%PDF-1.3"
end
it "should allow the default to be changed" do
@pdf = Prawn::Document.new
@pdf.__send__(:min_version, 1.4)
str = @pdf.render
str[0,8].should == "%PDF-1.4"
end
end
describe "Documents that use go_to_page" do
it "should have 2 pages after calling start_new_page and go_to_page" do
@pdf = Prawn::Document.new
@pdf.text "James"
@pdf.start_new_page
@pdf.text "Anthony"
@pdf.go_to_page(1)
@pdf.text "Healy"
page_counter = PDF::Inspector::Page.analyze(@pdf.render)
page_counter.pages.size.should == 2
end
it "should correctly add text to pages" do
@pdf = Prawn::Document.new
@pdf.text "James"
@pdf.start_new_page
@pdf.text "Anthony"
@pdf.go_to_page(1)
@pdf.text "Healy"
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.size.should == 3
text.strings.include?("James").should == true
text.strings.include?("Anthony").should == true
text.strings.include?("Healy").should == true
end
end
describe "content stream characteristics" do
it "should have 1 single content stream for a single page PDF with no templates" do
@pdf = Prawn::Document.new
@pdf.text "James"
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
streams.size.should == 1
end
it "should have 1 single content stream for a single page PDF with no templates, even if go_to_page is used" do
@pdf = Prawn::Document.new
@pdf.text "James"
@pdf.go_to_page(1)
@pdf.text "Healy"
output = StringIO.new(@pdf.render)
hash = PDF::Reader::ObjectHash.new(output)
streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
streams.size.should == 1
end
end
describe "The number_pages method" do
before do
@pdf = Prawn::Document.new(:skip_page_creation => true)
end
it "replaces the '' string with the proper page number" do
@pdf.start_new_page
@pdf.expects(:text_box).with("1, test", { :height => 50 })
@pdf.number_pages ", test", {:page_filter => :all}
end
it "replaces the '' string with the total page count" do
@pdf.start_new_page
@pdf.expects(:text_box).with("test, 1", { :height => 50 })
@pdf.number_pages "test, ", {:page_filter => :all}
end
it "must print each page if given the :all page_filter" do
10.times { @pdf.start_new_page }
@pdf.expects(:text_box).times(10)
@pdf.number_pages "test", {:page_filter => :all}
end
it "must print each page if no :page_filter is specified" do
10.times { @pdf.start_new_page }
@pdf.expects(:text_box).times(10)
@pdf.number_pages "test"
end
it "must not print the page number if given a nil filter" do
10.times { @pdf.start_new_page }
@pdf.expects(:text_box).never
@pdf.number_pages "test", {:page_filter => nil}
end
context "start_count_at option" do
[1, 2].each do |startat|
context "equal to #{startat}" do
it "increments the pages" do
2.times { @pdf.start_new_page }
options = {:page_filter => :all, :start_count_at => startat}
@pdf.expects(:text_box).with("#{startat} 2", { :height => 50 })
@pdf.expects(:text_box).with("#{startat+1} 2", { :height => 50 })
@pdf.number_pages " ", options
end
end
end
[0, nil].each do |val|
context "equal to #{val}" do
it "defaults to start at page 1" do
3.times { @pdf.start_new_page }
options = {:page_filter => :all, :start_count_at => val}
@pdf.expects(:text_box).with("1 3", { :height => 50 })
@pdf.expects(:text_box).with("2 3", { :height => 50 })
@pdf.expects(:text_box).with("3 3", { :height => 50 })
@pdf.number_pages " ", options
end
end
end
end
context "total_pages option" do
it "allows the total pages count to be overridden" do
2.times { @pdf.start_new_page }
@pdf.expects(:text_box).with("1 10", { :height => 50 })
@pdf.expects(:text_box).with("2 10", { :height => 50 })
@pdf.number_pages " ", :page_filter => :all, :total_pages => 10
end
end
context "special page filter" do
context "such as :odd" do
it "increments the pages" do
3.times { @pdf.start_new_page }
@pdf.expects(:text_box).with("1 3", { :height => 50 })
@pdf.expects(:text_box).with("3 3", { :height => 50 })
@pdf.expects(:text_box).with("2 3", { :height => 50 }).never
@pdf.number_pages " ", :page_filter => :odd
end
end
context "missing" do
it "does not print any page numbers" do
3.times { @pdf.start_new_page }
@pdf.expects(:text_box).never
@pdf.number_pages " ", :page_filter => nil
end
end
end
context "given both a special page filter and a start_count_at parameter" do
context "such as :odd and 7" do
it "increments the pages" do
3.times { @pdf.start_new_page }
@pdf.expects(:text_box).with("1 3", { :height => 50 }).never
@pdf.expects(:text_box).with("5 3", { :height => 50 }) # page 1
@pdf.expects(:text_box).with("6 3", { :height => 50 }).never # page 2
@pdf.expects(:text_box).with("7 3", { :height => 50 }) # page 3
@pdf.number_pages " ", :page_filter => :odd, :start_count_at => 5
end
end
context "some crazy proc and 2" do
it "increments the pages" do
6.times { @pdf.start_new_page }
options = {:page_filter => lambda {|p| p != 2 && p != 5}, :start_count_at => 4}
@pdf.expects(:text_box).with("4 6", { :height => 50 }) # page 1
@pdf.expects(:text_box).with("5 6", { :height => 50 }).never # page 2
@pdf.expects(:text_box).with("6 6", { :height => 50 }) # page 3
@pdf.expects(:text_box).with("7 6", { :height => 50 }) # page 4
@pdf.expects(:text_box).with("8 6", { :height => 50 }).never # page 5
@pdf.expects(:text_box).with("9 6", { :height => 50 }) # page 6
@pdf.number_pages " ", options
end
end
end
context "height option" do
before do
@pdf.start_new_page
end
it "with 10 height" do
@pdf.expects(:text_box).with("1 1", { :height => 10 })
@pdf.number_pages " ", :height => 10
end
it "with nil height" do
@pdf.expects(:text_box).with("1 1", { :height => nil })
@pdf.number_pages " ", :height => nil
end
it "with no height" do
@pdf.expects(:text_box).with("1 1", { :height => 50 })
@pdf.number_pages " "
end
end
end
describe "The page_match? method" do
before do
@pdf = Prawn::Document.new(:skip_page_creation => true)
10.times {@pdf.start_new_page}
end
it "returns nil given no filter" do
@pdf.page_match?(:nil, 1).should be_false
end
it "must provide an :all filter" do
(1..@pdf.page_count).all? { |i| @pdf.page_match?(:all, i) }.should be_true
end
it "must provide an :odd filter" do
odd, even = (1..@pdf.page_count).partition { |e| e % 2 == 1 }
odd.all? { |i| @pdf.page_match?(:odd, i) }.should be_true
even.any? { |i| @pdf.page_match?(:odd, i) }.should be_false
end
it "must be able to filter by an array of page numbers" do
fltr = [1,2,7]
(1..10).select { |i| @pdf.page_match?(fltr, i) }.should == [1,2,7]
end
it "must be able to filter by a range of page numbers" do
fltr = 2..4
(1..10).select { |i| @pdf.page_match?(fltr, i) }.should == [2,3,4]
end
it "must be able to filter by an arbitrary proc" do
fltr = lambda { |x| x == 1 or x % 3 == 0 }
(1..10).select { |i| @pdf.page_match?(fltr, i) }.should == [1,3,6,9]
end
end
ruby-prawn-1.0.0~rc2.orig/spec/text_at_spec.rb 0000644 0000000 0000000 00000011343 12114176157 020030 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "#draw_text" do
before(:each) { create_pdf }
it "should raise_error ArgumentError if :at option omitted" do
lambda { @pdf.draw_text("hai", { }) }.should raise_error(ArgumentError)
end
it "should raise_error ArgumentError if :align option included" do
lambda { @pdf.draw_text("hai", :at => [0, 0], :align => :center) }.should raise_error(ArgumentError)
end
it "should allow drawing empty strings to the page" do
@pdf.draw_text(" ", :at => [100,100])
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.first.should == " "
end
it "should default to 12 point helvetica" do
@pdf.draw_text("Blah", :at => [100,100])
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:name].should == :Helvetica
text.font_settings[0][:size].should == 12
text.strings.first.should == "Blah"
end
it "should allow setting font size" do
@pdf.draw_text("Blah", :at => [100,100], :size => 16)
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 16
end
it "should allow setting a default font size" do
@pdf.font_size = 16
@pdf.draw_text("Blah", :at => [0, 0])
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 16
end
it "should allow overriding default font for a single instance" do
@pdf.font_size = 16
@pdf.draw_text("Blah", :size => 11, :at => [0, 0])
@pdf.draw_text("Blaz", :at => [0, 0])
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 11
text.font_settings[1][:size].should == 16
end
it "should allow setting a font size transaction with a block" do
@pdf.font_size 16 do
@pdf.draw_text('Blah', :at => [0, 0])
end
@pdf.draw_text('blah', :at => [0, 0])
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 16
text.font_settings[1][:size].should == 12
end
it "should allow manual setting the font size " +
"when in a font size block" do
@pdf.font_size(16) do
@pdf.draw_text('Foo', :at => [0, 0])
@pdf.draw_text('Blah', :size => 11, :at => [0, 0])
@pdf.draw_text('Blaz', :at => [0, 0])
end
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:size].should == 16
text.font_settings[1][:size].should == 11
text.font_settings[2][:size].should == 16
end
it "should allow registering of built-in font_settings on the fly" do
@pdf.font "Times-Roman"
@pdf.draw_text("Blah", :at => [100,100], :at => [0, 0])
@pdf.font "Courier"
@pdf.draw_text("Blaz", :at => [150,150], :at => [0, 0])
text = PDF::Inspector::Text.analyze(@pdf.render)
text.font_settings[0][:name].should == :"Times-Roman"
text.font_settings[1][:name].should == :Courier
end
it "should raise_error an exception when an unknown font is used" do
lambda { @pdf.font "Pao bu" }.should raise_error(Prawn::Errors::UnknownFont)
end
it "should correctly render a utf-8 string when using a built-in font" do
str = "©" # copyright symbol
@pdf.draw_text(str, :at => [0, 0])
# grab the text from the rendered PDF and ensure it matches
text = PDF::Inspector::Text.analyze(@pdf.render)
text.strings.first.should == str
end
if "spec".respond_to?(:encode!)
# Handle non utf-8 string encodings in a sane way on M17N aware VMs
it "should raise_error an exception when a utf-8 incompatible string is rendered" do
str = "Blah \xDD"
str.force_encoding("ASCII-8BIT")
lambda { @pdf.draw_text(str, :at => [0, 0]) }.should raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
it "should_not raise_error an exception when a shift-jis string is rendered" do
datafile = "#{Prawn::DATADIR}/shift_jis_text.txt"
sjis_str = File.open(datafile, "r:shift_jis") { |f| f.gets }
@pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
lambda { @pdf.draw_text(sjis_str, :at => [0, 0]) }.should_not raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
else
# Handle non utf-8 string encodings in a sane way on non-M17N aware VMs
it "should raise_error an exception when a corrupt utf-8 string is rendered" do
str = "Blah \xDD"
lambda { @pdf.draw_text(str, :at => [0, 0]) }.should raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
it "should raise_error an exception when a shift-jis string is rendered" do
sjis_str = File.read("#{Prawn::DATADIR}/shift_jis_text.txt")
lambda { @pdf.draw_text(sjis_str, :at => [0, 0]) }.should raise_error(
Prawn::Errors::IncompatibleStringEncoding)
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/formatted_text_arranger_spec.rb 0000644 0000000 0000000 00000035742 12114176157 023303 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Core::Text::Formatted::Arranger#format_array" do
it "should populate unconsumed array" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you?" }]
arranger.format_array = array
arranger.unconsumed[0].should == { :text => "hello " }
arranger.unconsumed[1].should == { :text => "world how ",
:styles => [:bold] }
arranger.unconsumed[2].should == { :text => "are",
:styles => [:bold, :italic] }
arranger.unconsumed[3].should == { :text => " you?" }
end
it "should split newlines into their own elements" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "\nhello\nworld" }]
arranger.format_array = array
arranger.unconsumed[0].should == { :text => "\n" }
arranger.unconsumed[1].should == { :text => "hello" }
arranger.unconsumed[2].should == { :text => "\n" }
arranger.unconsumed[3].should == { :text => "world" }
end
end
describe "Core::Text::Formatted::Arranger#preview_next_string" do
it "should not populate the consumed array" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello" }]
arranger.format_array = array
arranger.preview_next_string
arranger.consumed.should == []
end
it "should not consumed array" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello" }]
arranger.format_array = array
arranger.preview_next_string.should == "hello"
end
end
describe "Core::Text::Formatted::Arranger#next_string" do
before(:each) do
create_pdf
@arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you?" }]
@arranger.format_array = array
end
it "should raise_error an error if called after a line was finalized and" +
" before a new line was initialized" do
@arranger.finalize_line
lambda do
@arranger.next_string
end.should raise_error(RuntimeError)
end
it "should populate consumed array" do
while string = @arranger.next_string
end
@arranger.consumed[0].should == { :text => "hello " }
@arranger.consumed[1].should == { :text => "world how ",
:styles => [:bold] }
@arranger.consumed[2].should == { :text => "are",
:styles => [:bold, :italic] }
@arranger.consumed[3].should == { :text => " you?" }
end
it "should populate current_format_state array" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you?" }]
arranger.format_array = array
counter = 0
while string = arranger.next_string
case counter
when 0
arranger.current_format_state.should == { }
when 1
arranger.current_format_state.should == { :styles => [:bold] }
when 2
arranger.current_format_state.should == { :styles => [:bold, :italic] }
when 3
arranger.current_format_state.should == { }
end
counter += 1
end
end
end
describe "Core::Text::Formatted::Arranger#retrieve_fragment" do
it "should raise_error an error if called before finalize_line was called" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you?" }]
arranger.format_array = array
while string = arranger.next_string
end
lambda do
arranger.retrieve_fragment
end.should raise_error(RuntimeError)
end
it "should return the consumed fragments in order of consumption" +
" and update" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you?" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.finalize_line
arranger.retrieve_fragment.text.should == "hello "
arranger.retrieve_fragment.text.should == "world how "
arranger.retrieve_fragment.text.should == "are"
arranger.retrieve_fragment.text.should == " you?"
end
it "should never return a fragment whose text is an empty string" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello\nworld\n\n\nhow are you?" },
{ :text => "\n" },
{ :text => "\n" },
{ :text => "\n" },
{ :text => "" },
{ :text => "fine, thanks." },
{ :text => "" },
{ :text => "\n" },
{ :text => "" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.finalize_line
while fragment = arranger.retrieve_fragment
fragment.text.should_not be_empty
end
end
it "should not alter the current font style" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you?" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.finalize_line
arranger.retrieve_fragment
arranger.current_format_state[:styles].should be_nil
end
end
describe "Core::Text::Formatted::Arranger#update_last_string" do
it "should update the last retrieved string with what actually fit on" +
"the line and the list of unconsumed with what did not" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?", :styles => [:bold, :italic] }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.update_last_string(" you", " now?", nil)
arranger.consumed[3].should == { :text => " you",
:styles => [:bold, :italic] }
arranger.unconsumed.should == [{ :text => " now?",
:styles => [:bold, :italic] }]
end
it "should set the format state to the previously processed fragment" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?" }]
arranger.format_array = array
3.times { arranger.next_string }
arranger.current_format_state.should == { :styles => [:bold, :italic] }
arranger.update_last_string("", "are", "-")
arranger.current_format_state.should == { :styles => [:bold] }
end
context "when the entire string was used" do
it "should not push empty string onto unconsumed" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.update_last_string(" you now?", "", nil)
arranger.unconsumed.should == []
end
end
end
describe "Core::Text::Formatted::Arranger#space_count" do
before(:each) do
create_pdf
@arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you?" }]
@arranger.format_array = array
while string = @arranger.next_string
end
end
it "should raise_error an error if called before finalize_line was called" do
lambda do
@arranger.space_count
end.should raise_error(RuntimeError)
end
it "should return the total number of spaces in all fragments" do
@arranger.finalize_line
@arranger.space_count.should == 4
end
end
describe "Core::Text::Formatted::Arranger#finalize_line" do
it "should make it so that all trailing white space fragments " +
"exclude trailing white space" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => " ", :styles => [:bold, :italic] }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.finalize_line
arranger.fragments.length.should == 3
fragment = arranger.retrieve_fragment
fragment.text.should == "hello "
fragment = arranger.retrieve_fragment
fragment.text.should == "world how"
fragment = arranger.retrieve_fragment
fragment.text.should == ""
end
end
describe "Core::Text::Formatted::Arranger#line_width" do
before(:each) do
create_pdf
@arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world", :styles => [:bold] }]
@arranger.format_array = array
while string = @arranger.next_string
end
end
it "should raise_error an error if called before finalize_line was called" do
lambda do
@arranger.line_width
end.should raise_error(RuntimeError)
end
it "should return the width of the complete line" do
@arranger.finalize_line
@arranger.line_width.should be > 0
end
end
describe "Core::Text::Formatted::Arranger#line_width with character_spacing > 0" do
it "should return a width greater than a line without a character_spacing" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world", :styles => [:bold] }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.finalize_line
base_line_width = arranger.line_width
array = [{ :text => "hello " },
{ :text => "world", :styles => [:bold],
:character_spacing => 7}]
arranger.format_array = array
while string = arranger.next_string
end
arranger.finalize_line
arranger.line_width.should be > base_line_width
end
end
describe "Core::Text::Formatted::Arranger#line" do
before(:each) do
create_pdf
@arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world", :styles => [:bold] }]
@arranger.format_array = array
while string = @arranger.next_string
end
end
it "should raise_error an error if called before finalize_line was called" do
lambda do
@arranger.line
end.should raise_error(RuntimeError)
end
it "should return the complete line" do
@arranger.finalize_line
@arranger.line.should == "hello world"
end
end
describe "Core::Text::Formatted::Arranger#unconsumed" do
it "should return the original array if nothing was consumed" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?" }]
arranger.format_array = array
arranger.unconsumed.should == array
end
it "should return an empty array if everything was consumed" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.unconsumed.should == []
end
end
describe "Core::Text::Formatted::Arranger#finished" do
it "should be_false if anything was not printed" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.update_last_string(" you", "now?", nil)
arranger.should_not be_finished
end
it "should be_false if everything was printed" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.should be_finished
end
end
describe "Core::Text::Formatted::Arranger.max_line_height" do
it "should be the height of the maximum consumed fragment" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic],
:size => 28 },
{ :text => " you now?" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.finalize_line
arranger.max_line_height.should be_within(0.0001).of(33.32)
end
end
describe "Core::Text::Formatted::Arranger#repack_unretrieved" do
it "should restore part of the original string" do
create_pdf
arranger = Prawn::Core::Text::Formatted::Arranger.new(@pdf)
array = [{ :text => "hello " },
{ :text => "world how ", :styles => [:bold] },
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?" }]
arranger.format_array = array
while string = arranger.next_string
end
arranger.finalize_line
arranger.retrieve_fragment
arranger.retrieve_fragment
arranger.repack_unretrieved
arranger.unconsumed.should == [
{ :text => "are", :styles => [:bold, :italic] },
{ :text => " you now?" }]
end
end
ruby-prawn-1.0.0~rc2.orig/spec/data/ 0000755 0000000 0000000 00000000000 12114176157 015730 5 ustar root root ruby-prawn-1.0.0~rc2.orig/spec/data/curves.pdf 0000644 0000000 0000000 00000001675 12114176157 017743 0 ustar root root %PDF-1.3
%
1 0 obj
<< /Creator (Prawn)
/Producer (Prawn)
>>
endobj
2 0 obj
<< /Type /Pages
/Count 1
/Kids [5 0 R]
>>
endobj
3 0 obj
<< /Type /Catalog
/Pages 2 0 R
>>
endobj
4 0 obj
<< /Length 380
>>
stream
/DeviceRGB cs
0.000 0.000 0.000 scn
/DeviceRGB CS
0.000 0.000 0.000 SCN
q
136.000 136.000 m
96.000 126.000 96.000 126.000 86.000 86.000 c
S
246.000 236.000 m
246.000 241.523 241.523 246.000 236.000 246.000 c
230.477 246.000 226.000 241.523 226.000 236.000 c
226.000 230.477 230.477 226.000 236.000 226.000 c
241.523 226.000 246.000 230.477 246.000 236.000 c
236.000 236.000 m
f
Q
endstream
endobj
5 0 obj
<< /Type /Page
/Parent 2 0 R
/MediaBox [0 0 612.0 792.0]
/Contents 4 0 R
/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
>>
>>
endobj
xref
0 6
0000000000 65535 f
0000000015 00000 n
0000000071 00000 n
0000000128 00000 n
0000000177 00000 n
0000000608 00000 n
trailer
<< /Size 6
/Root 3 0 R
/Info 1 0 R
>>
startxref
762
%%EOF
ruby-prawn-1.0.0~rc2.orig/spec/reference_spec.rb 0000644 0000000 0000000 00000006152 12114176157 020320 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "A Reference object" do
it "should produce a PDF reference on #to_s call" do
ref = Prawn::Core::Reference(1,true)
ref.to_s.should == "1 0 R"
end
it "should allow changing generation number" do
ref = Prawn::Core::Reference(1,true)
ref.gen = 1
ref.to_s.should == "1 1 R"
end
it "should generate a valid PDF object for the referenced data" do
ref = Prawn::Core::Reference(2,[1,"foo"])
ref.object.should == "2 0 obj\n#{Prawn::Core::PdfObject([1,"foo"])}\nendobj\n"
end
it "should automatically open a stream when #<< is used" do
ref = Prawn::Core::Reference(1, :Length => 41)
ref << "BT\n/F1 12 Tf\n72 712 Td\n( A stream ) Tj\nET"
ref.object.should == "1 0 obj\n<< /Length 41\n>>\nstream"+
"\nBT\n/F1 12 Tf\n72 712 Td\n( A stream ) Tj\nET" +
"\nendstream\nendobj\n"
end
it "should compress a stream upon request" do
ref = Prawn::Core::Reference(2,{})
ref << "Hi There " * 20
cref = Prawn::Core::Reference(2,{})
cref << "Hi There " * 20
cref.compress_stream
cref.stream.size.should be < ref.stream.size,
"compressed stream expected to be smaller than source but wasn't"
cref.data[:Filter].should == :FlateDecode
end
it "should copy the data and stream from another ref on #replace" do
from = Prawn::Core::Reference(3, {:foo => 'bar'})
from << "has a stream too"
to = Prawn::Core::Reference(4, {:foo => 'baz'})
to.replace from
# should preserve identifier but copy data and stream
to.identifier.should == 4
to.data.should == from.data
to.stream.should == from.stream
end
it "should copy a compressed stream from a compressed ref on #replace" do
from = Prawn::Core::Reference(5, {:foo => 'bar'})
from << "has a stream too " * 20
from.compress_stream
to = Prawn::Core::Reference(6, {:foo => 'baz'})
to.replace from
to.identifier.should == 6
to.data.should == from.data
to.stream.should == from.stream
to.compressed?.should == true
end
it "should have Length if stream present" do
ref = Prawn::Core::Reference(7, {})
ref << "Hello"
ref.data[:Length].should == 5
end
it "should update Length when stream is updated" do
ref = Prawn::Core::Reference(7, {})
ref << "Hello"
ref.data[:Length].should == 5
ref << " world"
ref.data[:Length].should == 11
end
describe "generated via Prawn::Document" do
it "should return a proper reference on ref!" do
pdf = Prawn::Document.new
pdf.ref!({}).is_a?(Prawn::Core::Reference).should == true
end
it "should return an identifier on ref" do
pdf = Prawn::Document.new
r = pdf.ref({})
r.is_a?(Integer).should == true
end
it "should have :Length of stream if it has one when compression disabled" do
pdf = Prawn::Document.new :compress => false
ref = pdf.ref!({})
ref << 'Hello'
ref.data[:Length].should == 5
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/spec_helper.rb 0000644 0000000 0000000 00000001432 12114176157 017635 0 ustar root root # encoding: utf-8
puts "Prawn specs: Running on Ruby Version: #{RUBY_VERSION}"
require "bundler"
Bundler.setup
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
require "prawn"
Prawn.debug = true
#require "test/spec"
require "rspec"
require "mocha/api"
require "pdf/reader"
require "pdf/inspector"
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/extensions/ and its subdirectories.
Dir[File.dirname(__FILE__) + "/extensions/**/*.rb"].each {|f| require f }
RSpec.configure do |config|
config.mock_framework = :mocha
config.include EncodingHelpers
end
def create_pdf(klass=Prawn::Document)
@pdf = klass.new(:margin => 0)
end
# Make some methods public to assist in testing
module Prawn::Graphics
public :map_to_absolute
end
ruby-prawn-1.0.0~rc2.orig/spec/bounding_box_spec.rb 0000644 0000000 0000000 00000034222 12114176157 021036 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "A bounding box" do
before(:each) do
@x = 100
@y = 125
@width = 50
@height = 75
@box = Prawn::Document::BoundingBox.new(nil, nil, [@x,@y],
:width => @width, :height => @height )
end
it "should have an anchor at (x, y - height)" do
@box.anchor.should == [@x,@y-@height]
end
it "should have a left boundary of 0" do
@box.left.should == 0
end
it "should have a right boundary equal to the width" do
@box.right.should == @width
end
it "should have a top boundary of height" do
@box.top.should == @height
end
it "should have a bottom boundary of 0" do
@box.bottom.should == 0
end
it "should have a top-left of [0,height]" do
@box.top_left.should == [0,@height]
end
it "should have a top-right of [width,height]" do
@box.top_right.should == [@width,@height]
end
it "should have a bottom-left of [0,0]" do
@box.bottom_left.should == [0,0]
end
it "should have a bottom-right of [width,0]" do
@box.bottom_right.should == [@width,0]
end
it "should have an absolute left boundary of x" do
@box.absolute_left.should == @x
end
it "should have an absolute right boundary of x + width" do
@box.absolute_right.should == @x + @width
end
it "should have an absolute top boundary of y" do
@box.absolute_top.should == @y
end
it "should have an absolute bottom boundary of y - height" do
@box.absolute_bottom.should == @y - @height
end
it "should have an absolute bottom-left of [x,y-height]" do
@box.absolute_bottom_left.should == [@x, @y - @height]
end
it "should have an absolute bottom-right of [x+width,y-height]" do
@box.absolute_bottom_right.should == [@x + @width , @y - @height]
end
it "should have an absolute top-left of [x,y]" do
@box.absolute_top_left.should == [@x, @y]
end
it "should have an absolute top-right of [x+width,y]" do
@box.absolute_top_right.should == [@x + @width, @y]
end
it "should require width to be set" do
lambda do
Prawn::Document::BoundingBox.new(nil, nil, [100,100])
end.should raise_error(ArgumentError)
end
it "should raise_error an ArgumentError if a block is not passed" do
pdf = Prawn::Document.new
lambda do
pdf.bounding_box([0, 0], :width => 200)
end.should raise_error(ArgumentError)
end
end
describe "drawing bounding boxes" do
before(:each) { create_pdf }
it "should not stomp on the arguments to bounding_box" do
pdf = Prawn::Document.new
x = [100, 500]
pdf.bounding_box x, :width => 100 do
pdf.text "bork-bork-bork"
end
x.should == [100, 500]
end
it "should restore the margin box when bounding box exits" do
margin_box = @pdf.bounds
@pdf.bounding_box [100,500], :width => 100 do
#nothing
end
@pdf.bounds.should == margin_box
end
it "should restore the parent bounding box when calls are nested" do
@pdf.bounding_box [100,500], :width => 300, :height => 300 do
@pdf.bounds.absolute_top.should == 500 + @pdf.margin_box.absolute_bottom
@pdf.bounds.absolute_left.should == 100 + @pdf.margin_box.absolute_left
parent_box = @pdf.bounds
@pdf.bounding_box [50,200], :width => 100, :height => 100 do
@pdf.bounds.absolute_top.should == 200 + parent_box.absolute_bottom
@pdf.bounds.absolute_left.should == 50 + parent_box.absolute_left
end
@pdf.bounds.absolute_top.should == 500 + @pdf.margin_box.absolute_bottom
@pdf.bounds.absolute_left.should == 100 + @pdf.margin_box.absolute_left
end
end
it "should calculate a height if none is specified" do
@pdf.bounding_box([100, 500], :width => 100) do
@pdf.text "The rain in Spain falls mainly on the plains."
end
@pdf.y.should be_within(0.001).of(458.384)
end
it "should keep track of the max height the box was stretched to" do
box = @pdf.bounding_box(@pdf.bounds.top_left, :width => 100) do
@pdf.move_down 100
@pdf.move_up 15
end
box.height.should == 100
end
it "should advance the y-position by bbox.height by default" do
orig_y = @pdf.y
@pdf.bounding_box [0, @pdf.cursor], :width => @pdf.bounds.width,
:height => 30 do
@pdf.text "hello"
end
@pdf.y.should be_within(0.001).of(orig_y - 30)
end
it "should not advance y-position if passed :hold_position => true" do
orig_y = @pdf.y
@pdf.bounding_box [0, @pdf.cursor], :width => @pdf.bounds.width,
:hold_position => true do
@pdf.text "hello"
end
# y only advances by height of one line ("hello")
@pdf.y.should be_within(0.001).of(orig_y - @pdf.height_of("hello"))
end
it "should not advance y-position of a stretchy bbox if it would stretch " +
"the bbox further" do
bottom = @pdf.y = @pdf.margin_box.absolute_bottom
@pdf.bounding_box [0, @pdf.margin_box.top], :width => @pdf.bounds.width do
@pdf.y = bottom
@pdf.text "hello" # starts a new page
end
@pdf.page_count.should == 2
# Restoring the position (to the absolute bottom) would stretch the bbox to
# the bottom of the page, which we don't want. This should be equivalent to
# a bbox with :hold_position => true, where we only advance by the amount
# that was actually drawn.
@pdf.y.should be_within(0.001).of(
@pdf.margin_box.absolute_top - @pdf.height_of("hello")
)
end
end
describe "Indentation" do
before(:each) { create_pdf }
it "should temporarily shift the x coordinate and width" do
@pdf.bounding_box([100,100], :width => 200) do
@pdf.indent(20) do
@pdf.bounds.absolute_left.should == 120
@pdf.bounds.width.should == 180
end
end
end
it "should restore the x coordinate and width after block exits" do
@pdf.bounding_box([100,100], :width => 200) do
@pdf.indent(20) do
# no-op
end
@pdf.bounds.absolute_left.should == 100
@pdf.bounds.width.should == 200
end
end
it "should restore the x coordinate and width on error" do
@pdf.bounding_box([100,100], :width => 200) do
begin
@pdf.indent(20) { raise }
rescue
@pdf.bounds.absolute_left.should == 100
@pdf.bounds.width.should == 200
end
end
end
it "should maintain left indentation across a page break" do
original_left = @pdf.bounds.absolute_left
@pdf.indent(20) do
@pdf.bounds.absolute_left.should == original_left + 20
@pdf.start_new_page
@pdf.bounds.absolute_left.should == original_left + 20
end
@pdf.bounds.absolute_left.should == original_left
end
it "should maintain right indentation across a page break" do
original_width = @pdf.bounds.width
@pdf.indent(0, 20) do
@pdf.bounds.width.should == original_width - 20
@pdf.start_new_page
@pdf.bounds.width.should == original_width - 20
end
@pdf.bounds.width.should == original_width
end
it "optionally allows adjustment of the right bound as well" do
@pdf.bounding_box([100,100], :width => 200) do
@pdf.indent(20, 30) do
@pdf.bounds.absolute_left.should == 120
@pdf.bounds.width.should == 150
end
@pdf.bounds.absolute_left.should == 100
@pdf.bounds.width.should == 200
end
end
describe "in a ColumnBox" do
it "should subtract the given indentation from the available width" do
@pdf.column_box([0, @pdf.cursor], :width => @pdf.bounds.width,
:height => 200, :columns => 2, :spacer => 20) do
width = @pdf.bounds.width
@pdf.indent(20) do
@pdf.bounds.width.should be_within(0.01).of(width - 20)
end
end
end
it "should subtract right padding from the available width" do
@pdf.column_box([0, @pdf.cursor], :width => @pdf.bounds.width,
:height => 200, :columns => 2, :spacer => 20) do
width = @pdf.bounds.width
@pdf.indent(20, 30) do
@pdf.bounds.width.should be_within(0.01).of(width - 50)
end
end
end
it "should maintain the same left indentation across column breaks" do
@pdf.column_box([0, @pdf.cursor], :width => @pdf.bounds.width, :columns => 3, :spacer => 15) do
3.times do |column|
x = @pdf.bounds.left_side
@pdf.indent(20) do
@pdf.bounds.left_side.should == x+20
end
@pdf.bounds.move_past_bottom
end
end
end
it "should not change the right margin if only left indentation is requested" do
@pdf.column_box([0, @pdf.cursor], :width => @pdf.bounds.width, :columns => 3, :spacer => 15) do
3.times do |column|
x = @pdf.bounds.right_side
@pdf.indent(20) do
@pdf.bounds.right_side.should == x
end
@pdf.bounds.move_past_bottom
end
end
end
it "should maintain the same right indentation across columns" do
@pdf.column_box([0, @pdf.cursor], :width => @pdf.bounds.width, :columns => 3, :spacer => 15) do
3.times do |column|
x = @pdf.bounds.right_side
@pdf.indent(20, 10) do
@pdf.bounds.right_side.should == x-10
end
@pdf.bounds.move_past_bottom
end
end
end
it "should keep the right indentation after nesting indents" do
@pdf.column_box([0, @pdf.cursor], :width => @pdf.bounds.width, :columns => 3, :spacer => 15) do
3.times do |column|
# I am giving a right indent of 10...
@pdf.indent(20, 10) do
x = @pdf.bounds.right_side
# ...and no right indent here...
@pdf.indent(20) do
# right indent is inherited from the parent!
@pdf.bounds.right_side.should == x
end
end
@pdf.bounds.move_past_bottom
end
end
end
it "should revert the right indentation if negative indent is given in nested indent" do
@pdf.column_box([0, @pdf.cursor], :width => @pdf.bounds.width, :columns => 3, :spacer => 15) do
3.times do |column|
x = @pdf.bounds.right_side
@pdf.indent(20, 10) do
# requesting a negative right-indent of equivalent size...
@pdf.indent(20, -10) do
# ...resets the right margin to that of the column!
@pdf.bounds.right_side.should == x
end
end
@pdf.bounds.move_past_bottom
end
end
end
it "should reduce the available column width by the sum of all nested indents" do
@pdf.column_box([0, @pdf.cursor], :width => @pdf.bounds.width, :columns => 3, :spacer => 15) do
3.times do |column|
w = @pdf.bounds.width
@pdf.indent(20, 10) do
@pdf.indent(20, 10) do
@pdf.bounds.width.should == w - 60
end
end
@pdf.bounds.move_past_bottom
end
end
end
end
end
describe "A canvas" do
before(:each) { create_pdf }
it "should use whatever the last set y position is" do
@pdf.canvas do
@pdf.bounding_box([100,500],:width => 200) { @pdf.move_down 50 }
end
@pdf.y.should == 450
end
end
describe "Deep-copying" do
it "should create a new object that does not copy @document" do
Prawn::Document.new do |pdf|
orig = pdf.bounds
copy = orig.deep_copy
copy.should_not == pdf.bounds
copy.document.should be_nil
end
end
it "should deep-copy parent bounds" do
Prawn::Document.new do |pdf|
outside = pdf.bounds
pdf.bounding_box [100, 100], :width => 100 do
copy = pdf.bounds.deep_copy
# the parent bounds should have the same parameters
copy.parent.width.should == outside.width
copy.parent.height.should == outside.height
# but should not be the same object
copy.parent.should_not == outside
end
end
end
end
describe "Prawn::Document#reference_bounds" do
before(:each) { create_pdf }
it "should return self for non-stretchy bounds" do
@pdf.bounding_box([0, @pdf.cursor], :width => 100, :height => 100) do
@pdf.reference_bounds.should == @pdf.bounds
end
end
it "should return the parent bounds if in a stretchy box" do
@pdf.bounding_box([0, @pdf.cursor], :width => 100, :height => 100) do
correct_bounds = @pdf.bounds
@pdf.bounding_box([0, @pdf.cursor], :width => 100) do
@pdf.reference_bounds.should == correct_bounds
end
end
end
it "should find the non-stretchy box through 2 levels" do
@pdf.bounding_box([0, @pdf.cursor], :width => 100, :height => 100) do
correct_bounds = @pdf.bounds
@pdf.bounding_box([0, @pdf.cursor], :width => 100) do
@pdf.bounding_box([0, @pdf.cursor], :width => 100) do
@pdf.reference_bounds.should == correct_bounds
end
end
end
end
it "should return the margin box if there's no explicit bbox" do
@pdf.reference_bounds.should == @pdf.margin_box
@pdf.bounding_box([0, @pdf.cursor], :width => 100) do
@pdf.reference_bounds.should == @pdf.margin_box
end
end
it "should return the canvas box if we're in a canvas" do
@pdf.canvas do
canvas_box = @pdf.bounds
@pdf.reference_bounds.should == canvas_box
@pdf.bounding_box([0, @pdf.cursor], :width => 100) do
@pdf.reference_bounds.should == canvas_box
end
end
end
end
describe "BoundingBox#move_past_bottom" do
before(:each) { create_pdf }
it "should ordinarily start a new page" do
@pdf.bounds.move_past_bottom
@pdf.text "Foo"
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.size.should == 2
pages[0][:strings].should == []
pages[1][:strings].should == ["Foo"]
end
it "should move to the top of the next page if it exists already" do
# save away the y-position at the top of a page
top_y = @pdf.y
# create a blank page but go to the page before it
@pdf.start_new_page
@pdf.go_to_page 1
@pdf.text "Foo"
@pdf.bounds.move_past_bottom
@pdf.y.should be_within(0.001).of(top_y)
@pdf.text "Bar"
pages = PDF::Inspector::Page.analyze(@pdf.render).pages
pages.size.should == 2
pages[0][:strings].should == ["Foo"]
pages[1][:strings].should == ["Bar"]
end
end
ruby-prawn-1.0.0~rc2.orig/spec/security_spec.rb 0000644 0000000 0000000 00000007633 12114176157 020236 0 ustar root root # encoding: utf-8
require "tempfile"
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Document encryption" do
describe "Password padding" do
include Prawn::Document::Security
it "should truncate long passwords" do
pw = "Long long string" * 30
padded = pad_password(pw)
padded.length.should == 32
padded.should == pw[0, 32]
end
it "should pad short passwords" do
pw = "abcd"
padded = pad_password(pw)
padded.length.should == 32
padded.should == pw + Prawn::Document::Security::PasswordPadding[0, 28]
end
it "should fully pad null passwords" do
pw = ""
padded = pad_password(pw)
padded.length.should == 32
padded.should == Prawn::Document::Security::PasswordPadding
end
end
describe "Setting permissions" do
def doc_with_permissions(permissions)
pdf = Prawn::Document.new
class << pdf
# Make things easier to test
public :permissions_value
end
pdf.encrypt_document(:permissions => permissions)
pdf
end
it "should default to full permissions" do
doc_with_permissions({}).permissions_value.should == 0xFFFFFFFF
doc_with_permissions(:print_document => true,
:modify_contents => true,
:copy_contents => true,
:modify_annotations => true).permissions_value.
should == 0xFFFFFFFF
end
it "should clear the appropriate bits for each permission flag" do
doc_with_permissions(:print_document => false).permissions_value.
should == 0b1111_1111_1111_1111_1111_1111_1111_1011
doc_with_permissions(:modify_contents => false).permissions_value.
should == 0b1111_1111_1111_1111_1111_1111_1111_0111
doc_with_permissions(:copy_contents => false).permissions_value.
should == 0b1111_1111_1111_1111_1111_1111_1110_1111
doc_with_permissions(:modify_annotations => false).permissions_value.
should == 0b1111_1111_1111_1111_1111_1111_1101_1111
end
it "should raise_error ArgumentError if invalid option is provided" do
lambda {
doc_with_permissions(:modify_document => false)
}.should raise_error(ArgumentError)
end
end
describe "Encryption keys" do
# Since PDF::Reader doesn't read encrypted PDF files, we just take the
# roundabout method of verifying each step of the encryption. This works
# fine because the encryption method is deterministic.
before(:each) do
@pdf = Prawn::Document.new
class << @pdf
public :owner_password_hash, :user_password_hash, :user_encryption_key
end
@pdf.encrypt_document :user_password => 'foo', :owner_password => 'bar',
:permissions => { :print_document => false }
end
it "should calculate the correct owner hash" do
@pdf.owner_password_hash.unpack("H*").first.should match(/^61CA855012/i)
end
it "should calculate the correct user hash" do
@pdf.user_password_hash.unpack("H*").first.should =~ /^6BC8C51031/i
end
it "should calculate the correct user_encryption_key" do
@pdf.user_encryption_key.unpack("H*").first.upcase.should == "B100AB6429"
end
end
describe "EncryptedPdfObject" do
it "should delegate to PdfObject for simple types" do
Prawn::Core::EncryptedPdfObject(true, nil, nil, nil).should == "true"
Prawn::Core::EncryptedPdfObject(42, nil, nil, nil).should == "42"
end
it "should encrypt strings properly" do
Prawn::Core::EncryptedPdfObject("foo", "12345", 123, 0).should == "<4ad6e3>"
end
it "should properly handle compound types" do
Prawn::Core::EncryptedPdfObject({:Bar => "foo"}, "12345", 123, 0).should ==
"<< /Bar <4ad6e3>\n>>"
Prawn::Core::EncryptedPdfObject(["foo", "bar"], "12345", 123, 0).should ==
"[<4ad6e3> <4ed8fe>]"
end
end
end
ruby-prawn-1.0.0~rc2.orig/spec/snapshot_spec.rb 0000644 0000000 0000000 00000011412 12114176157 020214 0 ustar root root # encoding: utf-8
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
describe "Prawn::Document#transaction" do
it "should properly commit if no error is raised" do
pdf = Prawn::Document.new do
transaction do
text "This is shown"
end
end
text = PDF::Inspector::Text.analyze(pdf.render)
text.strings.should == ["This is shown"]
end
it "should not display text if transaction is rolled back" do
pdf = Prawn::Document.new do
transaction do
text "This is not shown"
rollback
end
end
text = PDF::Inspector::Text.analyze(pdf.render)
text.strings.should == []
end
it "should return true/false value indicating success of the transaction" do
Prawn::Document.new do
success = transaction { }
success.should == true
success = transaction { rollback }
success.should == false
end
end
it "should support nested transactions" do
pdf = Prawn::Document.new do
transaction do
text "This is shown"
transaction do
text "and this is not"
rollback
end
text "and this is"
end
end
text = PDF::Inspector::Text.analyze(pdf.render)
text.strings.should == ["This is shown", "and this is"]
end
it "should allow rollback of multiple pages" do
pdf = Prawn::Document.new do
transaction do
5.times { start_new_page }
text "way out there and will never be shown"
rollback
end
text "This is the real text, only one page"
end
pages = PDF::Inspector::Page.analyze(pdf.render).pages
pages.size.should == 1
end
it "should not propagate a RollbackTransaction outside its bounds" do
def add_lines(pdf)
100.times { |i| pdf.text "Line #{i}" }
end
Prawn::Document.new do |pdf|
lambda do
begin
pdf.group { add_lines(pdf) }
rescue Prawn::Errors::CannotGroup
add_lines(pdf)
end
end.should_not raise_error#(Prawn::Document::Snapshot::RollbackTransaction)
end
end
# Because the Pages object, when restored, points to the snapshotted pages
# by identifier, we have to restore the snapshot into the same page objects,
# or else old pages will appear in the post-rollback document.
it "should restore the pages into the same objects" do
Prawn::Document.new do
old_page_object_id = state.page.dictionary.identifier
old_page_content_id = state.page.content.identifier
transaction do
start_new_page
rollback
end
state.page.dictionary.identifier.should == old_page_object_id
state.page.content.identifier.should == old_page_content_id
end
end
it "page object should refer to the page_content object after restore" do
Prawn::Document.new do
transaction do
start_new_page
rollback
end
# should be the exact same object, not a clone
state.page.dictionary.data[:Contents].should == state.page.content
end
end
it "should restore bounds on rollback" do
Prawn::Document.new(:page_layout => :landscape) do
size = [bounds.width, bounds.height]
transaction do
start_new_page :layout => :portrait
rollback
end
[bounds.width, bounds.height].should == size
end
end
it "should set new bounding box on start_new_page with different layout" do
Prawn::Document.new(:page_layout => :landscape) do
size = [bounds.width, bounds.height]
transaction do
start_new_page
rollback
end
start_new_page :layout => :portrait
[bounds.width, bounds.height].should == size.reverse
end
end
it "should work with dests" do
Prawn::Document.new do |pdf|
pdf.add_dest("dest", pdf.dest_fit_horizontally(pdf.cursor, pdf.page))
pdf.text("Hello world")
lambda { pdf.transaction{} }.should_not raise_error
end
end
describe "with a stamp dictionary present" do
it "should properly commit if no error is raised" do
pdf = Prawn::Document.new do
create_stamp("test_stamp") { draw_text "This is shown", :at => [0,0] }
transaction do
stamp("test_stamp")
end
end
pdf.render.should =~ /\/Stamp1 Do/
end
it "should properly rollback when #rollback is called" do
pdf = Prawn::Document.new do
create_stamp("test_stamp") { draw_text "This is not shown", :at => [0,0] }
transaction do
stamp("test_stamp")
rollback
end
end
pdf.render.should_not =~ /\/Stamp1 Do/
end
end
it "should restore page_number on rollback" do
Prawn::Document.new do
transaction do
5.times { start_new_page }
rollback
end
page_number.should == 1
end
end
end
ruby-prawn-1.0.0~rc2.orig/bugs/ 0000755 0000000 0000000 00000000000 12114176157 015025 5 ustar root root ruby-prawn-1.0.0~rc2.orig/bugs/resolved/ 0000755 0000000 0000000 00000000000 12114176157 016650 5 ustar root root ruby-prawn-1.0.0~rc2.orig/bugs/resolved/stamp_color_issues.rb 0000644 0000000 0000000 00000001343 12114176157 023113 0 ustar root root # encoding: utf-8
#
#
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require 'rubygems'
require 'prawn'
##
# This bug was reported in comments in issue #200
# When the bug is fixed the stamp text and shape color should be set to a blue CMYK color
pdf = Prawn::Document.generate("stamp_color_issues.pdf", :margin => [40, 45, 50, 45]) do
text "Page text starts out with RGB black color"
create_stamp("logo") do
fill_color(100, 100, 20, 0)
stroke_color(100, 100, 20, 0)
move_down 50
text "But in a stamp I can create CMYK colored text and shapes"
fill_and_stroke_rounded_rectangle([200, 550], 50, 100, 10)
end
stamp('logo')
draw_text "And non stamped text is not affected", :at => [10, 400]
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/transaction_page_number_issue_79.rb 0000644 0000000 0000000 00000000705 12114176157 025617 0 ustar root root # As of 2010.01.12, we have confirmed that page_number is not properly set on
# transaction rollback, resulting in an error from the code sample below.
#
# Resolved in 7c62bbf.
#
$LOAD_PATH << File.join(File.dirname(__FILE__), '..','lib')
require "prawn/core"
Prawn::Document.generate("transaction_rollback_pagenumber.pdf") do
text "Hello world"
transaction do
text "hello " * 1000
rollback
end
start_new_page
text "hi there"
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/ttf_fails_in_transactions.rb 0000644 0000000 0000000 00000001555 12114176157 024434 0 ustar root root # http://github.com/sandal/prawn/issues#issue/56
#
# As of f952055d03f9b21b78ec2844bd873cf62005d00a
# Transactions fail when using TTF fonts.
#
# This is because we use an on_encode Proc that gets included in the
# @current_page object, which breaks snapshots. We can surely write
# around this to either split out the Proc into non-marshalled data
# or set up some sort of callback that is indicated by something that
# can be safely marshalled.
#
# But whoever tackles this patch should take care to ensure we
# don't break TTF subsetting support, adding specs if necessary.
#
# Resolved in 36ef89c2bc21e504df623f61d918c5bfdc1fdab1.
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', '..','lib')
require 'prawn/core'
Prawn::Document.generate("err.pdf") do
font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
text "Hi there"
transaction { text "Nice, thank you" }
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/multiple_rendering.rb 0000644 0000000 0000000 00000000553 12114176157 023070 0 ustar root root # encoding: utf-8
#
#
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require 'rubygems'
require 'prawn'
pdf = Prawn::Document.new(:page_layout => :landscape) do
text "here is the first rendering"
end
pdf.render_file("multiple_rendering.pdf")
pdf.move_down 10
pdf.text "here is another rendering"
pdf.render_file("multiple_rendering_2.pdf")
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/looks_blank.rb 0000644 0000000 0000000 00000000575 12114176157 021502 0 ustar root root $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require 'rubygems'
require 'bundler'
require 'prawn'
Bundler.require
##
# When this is fixed then Testing should appear with normal default black color in Acrobat reader
Prawn::Document.generate("looks_blank.pdf") do
repeat :all do
text "Testing", :size => 24, :style => :bold
end
fill_color '662255'
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/save_graphics_state.rb 0000644 0000000 0000000 00000001364 12114176157 023217 0 ustar root root # encoding: utf-8
#
#
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require 'rubygems'
require 'prawn'
##
# This bug is taken from issue #102 including the comments.
# When the bug is fixed then the third rectangle should be yellow and not green.
pdf = Prawn::Document.generate("graphics_state.pdf", :page_layout => :landscape) do
fill_color '000000' # Prawn thinks color space is RGB
fill { rectangle([10, bounds.top], 10, 10) }
save_graphics_state
fill_color 0, 0, 0, 0 # Prawn thinks color space is CMYK
fill { rectangle([20, bounds.top], 10, 10) }
restore_graphics_state # Oops, now PDF thinks color space is RGB again
fill_color 0, 0, 100, 0 # This won't work!
fill { rectangle([ 30, bounds.top ], 10, 10) }
end ruby-prawn-1.0.0~rc2.orig/bugs/resolved/dash_stamp_issue.rb 0000644 0000000 0000000 00000000762 12114176157 022535 0 ustar root root # encoding: utf-8
#
#
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require 'rubygems'
require 'prawn'
##
# When resolved the second page circle should not be dashed
pdf = Prawn::Document.generate("stamp_dash_issues.pdf", :margin => [40, 45, 50, 45]) do
text "The stamped circle might be dashed"
create_stamp("stamp_circle") do
dash(5)
stroke_circle [0, 0], 10
end
stamp("stamp_circle")
text "but the nonstamped circle should not"
stroke_circle [10, 10], 10
end ruby-prawn-1.0.0~rc2.orig/bugs/resolved/color_space_issues.rb 0000644 0000000 0000000 00000000777 12114176157 023074 0 ustar root root # encoding: utf-8
#
#
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require 'rubygems'
require 'prawn'
##
# This bug is simplification of issue #183.
# When the bug is fixed then a rectangle should show on both pages in Acrobat Reader.
pdf = Prawn::Document.generate("color_space_issues.pdf", :page_layout => :landscape) do
stroke_color "000000"
stroke { rectangle([10, bounds.top], 10, 10) }
start_new_page
stroke_color "000000"
stroke { rectangle([10, bounds.top], 10, 10) }
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/png_barcode_issue.rb 0000644 0000000 0000000 00000000511 12114176157 022645 0 ustar root root # encoding: utf-8
#
# As of 200fc36455fa3bee0e1e3bb25d1b5bf73dbf3b52,
# the following code does not correctly render a PNG image
#
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', '..','lib')
require "prawn/core"
Prawn::Document.generate('png_barcode_issue.pdf') do
image "#{Prawn::DATADIR}/images/barcode_issue.png"
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/layout/ 0000755 0000000 0000000 00000000000 12114176157 020165 5 ustar root root ruby-prawn-1.0.0~rc2.orig/bugs/resolved/layout/table_header_overrun.rb 0000644 0000000 0000000 00000001752 12114176157 024676 0 ustar root root # Text was overflowing into following cells because of some issues with
# floating point numbers in naive wrap.
#
# Resolved in: 9c357bc488d26e7bbc2e442606106106d349e232
#
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
require "rubygems"
require "prawn"
require "prawn/layout"
@prawn_document_options = {
:page_layout => :landscape,
:left_margin => 36,
:right_margin => 36,
:top_margin => 36,
:bottom_margin => 36}
Prawn::Document.generate("table_header_overrun.pdf", @prawn_document_options) do
headers = [ "Customer", "Grand\nHijynx", "Kh", "Red\nCorvette", "Rushmore", "bPnr", "lGh", "retail\nPantaloons", "sRsm", "Total\nBoxes"]
data = [[1,0,1,0,1,0,1,0,1,0], [0,1,0,1,0,1,0,1,0,1]]
table(data,
:headers => headers,
:font_size => 16,
:horizontal_padding => 5,
:vertical_padding => 3,
:border => 2,
:position => :center)
start_new_page
table [['MyString']], :headers=>['Field1']
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/layout/cell_width_miscalculation.rb 0000644 0000000 0000000 00000001333 12114176157 025717 0 ustar root root # encoding: utf-8
#
# As of 40c7bde9690e5174b6a958a5df6b2aabc6b8b041 this code produces an extra
# empty line of text in row 2.
#
# Simple rounding of string_width floats seems to fix this issue, see the patch
# in 09c837466c31bb715f1276118c606e20477577df.
#
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
require "rubygems"
require "prawn"
require "prawn/layout"
Prawn::Document.generate("broken_table.pdf") do
font "#{Prawn::DATADIR}/fonts/comicsans.ttf"
table [["foo", "baaar", "1" ],
["This is","a sample", "2" ],
["Table", "dont\ncha\nknow?", "3" ]],
:font_size => 30,
:padding => 10,
:border => 2,
:position => :center
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/layout/table_ignores_align_headers.rb 0000644 0000000 0000000 00000001723 12114176157 026177 0 ustar root root # As of fadb65c303ff129d0b25a929d3b9d1f915b2f98d,
# Prawn ignores :align_headers property in tables
# when :border_style => :grid is present (Lighthouse issue #119).
#
# NOTES:
#
# * This issue can only be reproduced when :border_style => :grid is used
#
# Resolved as of 47297900dcf3f16c4765ca817f17c53fb0a5a079
# I think a bad merge created issues in edge, and this code fixes previous
# problems that are present in stable.
#
$DEBUG = true
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
require "rubygems"
require "prawn"
require "prawn/layout"
Prawn::Document.generate("table_ignores_align_headers.pdf") do
left = "Left justified"
left2 = "left"
center = "centered"
table [[left, left], [left2, left2]], :headers => [center, center],
:align => :left,
:align_headers => :center,
:border_style => :grid
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/layout/table_suppress_newline.rb 0000644 0000000 0000000 00000001036 12114176157 025266 0 ustar root root # As of bbe1df6530455dff41768bcc329bdc7cfdfaded1 (and earlier),
# Prawn does not properly display cells with newlines in tables.
#
# Fixed in e28cf53b5d05e6cb343e8dd5265c57d5f24ef4da [#76]
#
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
require "rubygems"
require "prawn"
require "prawn/layout"
Prawn::Document.generate("table_supresses_newlines.pdf") do
table [["test\n\naaaa","test\n\nbbbb"],
["test\n\ncccc", "test\n\ndddd"]], :border_style => :grid
cell [100,100], :text => "test\n\naaaa"
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/layout/table_in_bounding_box_without_height.rb 0000644 0000000 0000000 00000001410 12114176157 030133 0 ustar root root # encoding: utf-8
#
# Issue with tables within stretchy bounding boxes. Changes to the way
# bounding boxes work caused tables to not properly render within stretchy
# bounding boxes.
#
# A fix in 200fc36455fa3bee0e1e3bb25d1b5bf73dbf3b52 makes it so the bottom
# of the margin_box will be used as the page boundary in stretchy bounding
# boxes. Ideally, this would instead use the nesting bounding box dimensions
# [#80] , but this works for now.
#
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
require "rubygems"
require "prawn"
require "prawn/layout"
Prawn::Document.generate("table_in_bounding_box_without_height.pdf") do
bounding_box bounds.top_left, :width => 200 do
table [%w(These should all be), %w(on the same page)]
end
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/layout/table_row_background_color_issue.rb 0000644 0000000 0000000 00000004502 12114176157 027276 0 ustar root root # As of 96f660660345c7c22923ba51d0124022a3a189ab, table is currently not taking
# in account border widths when filling in rows with background coloring. This
# means the larger the border, the larger the visible gap between rows.
#
# This problem was fixed in 97d9bf083fd9423d17fd1efca36ea675ff34a6d7, but
# there remains a very minor issue when the border size is 1 for the headers.
# Because this almost appears to be a feature display-wise, we will leave it
# alone for now.
#
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
require "rubygems"
require "prawn"
require "prawn/layout"
Prawn::Document.generate("table_with_background_color_problems.pdf") do
font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
table [["ὕαλον ϕαγεῖν", "baaar", "1" ],
["This is","a sample", "2" ],
["Table", "dont\ncha\nknow?", "3" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules\nwith an iron fist", "x" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ],
[ "It", "Rules", "4" ]],
:font_size => 10,
:horizontal_padding => 10,
:vertical_padding => 3,
:border => 1,
:position => :center,
:headers => ["Column A","Column B","#"],
:row_colors => ["cccccc"]
pad(20) do
text "This should appear in the original font size"
end
table [[ "Wide", "columns", "streeetch"],
["are","mighty fine", "streeeeeeeech"]],
:column_widths => { 0 => 200, 1 => 250 }, :position => 5
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/layout/fill_color.rb 0000644 0000000 0000000 00000000557 12114176157 022645 0 ustar root root # encoding: utf-8
#
# As of 9e48a6 (2009.01.03), this code fails to recognize fill_color in tables.
# Resolved in 664760 (2009.01.05)
#
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..','lib')
require "prawn/core"
require "prawn/layout"
Prawn::Document.generate("fill_color.pdf") do
fill_color "ff0000"
table [%w[1 2 3],%w[4 5 6],%w[7 8 9]],
end
ruby-prawn-1.0.0~rc2.orig/bugs/resolved/canvas_sets_y_to_0.rb 0000644 0000000 0000000 00000000774 12114176157 022767 0 ustar root root # As of 7e94d25828021732f7872934cb91430ef798cd86, Document#canvas
# sets pdf.y to 0 after executing a block, which is probably not useful for
# anyone. It should retain the y position present at the end of the block.
#
# This was resolved in 998a5c3fad40c9e0a79e1468e3a83815ed948a74 [#88]
#
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', '..','lib')
require "prawn/core"
Prawn::Document.generate("canvas_sets_y_to_0.pdf") do
canvas { text "blah" }
text "Here's my sentence. by satoko"
end
ruby-prawn-1.0.0~rc2.orig/bugs/indentation_across_pagebreaks.rb 0000644 0000000 0000000 00000000513 12114176157 023423 0 ustar root root # As of 2009.02.13, indentation does not work across page breaks. [#86]
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require "prawn/core"
Prawn::Document.generate("indent_page_breaks.pdf") do
text "heading", :size => 14, :style => :bold
indent(20) do
100.times do
text "test"
end
end
end
ruby-prawn-1.0.0~rc2.orig/bugs/png_alpha_channel_filter.rb 0000644 0000000 0000000 00000000536 12114176157 022344 0 ustar root root $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require 'prawn'
image_file = File.expand_path('../../data/images/prawn.png', __FILE__)
pdf = Prawn::Document.new
pdf.image image_file
pdf.render_file("works.pdf")
require 'mathn' # Re-defines '/' operation !
pdf = Prawn::Document.new
pdf.image image_file
pdf.render_file("broken.pdf")
ruby-prawn-1.0.0~rc2.orig/.gitignore 0000644 0000000 0000000 00000000132 12114176157 016051 0 ustar root root .*.sw?
nbproject
pkg
.rvmrc
.bundle
Gemfile.lock
drop_to_console.rb
manual.pdf
/doc
/bin
ruby-prawn-1.0.0~rc2.orig/Rakefile 0000644 0000000 0000000 00000002170 12114176157 015532 0 ustar root root require "bundler"
Bundler.setup
require 'rake'
require 'rspec/core/rake_task'
require 'rdoc/task'
require 'rubygems/package_task'
task :default => [:spec]
desc "Run all rspec files"
RSpec::Core::RakeTask.new("spec")
desc "Show library's code statistics"
task :stats do
require 'code_statistics'
CodeStatistics::TEST_TYPES << "Specs"
CodeStatistics.new( ["Prawn", "lib"],
["Specs", "spec"] ).to_s
end
desc "genrates documentation"
RDoc::Task.new do |rdoc|
rdoc.rdoc_files.include( "README",
"COPYING",
"LICENSE",
"HACKING", "lib/" )
rdoc.main = "README"
rdoc.rdoc_dir = "doc/html"
rdoc.title = "Prawn Documentation"
end
desc "Generate the 'Prawn by Example' manual"
task :manual do
puts "Building manual..."
require File.expand_path(File.join(File.dirname(__FILE__),
%w[manual manual manual]))
puts "The Prawn manual is available at manual.pdf. Happy Prawning!"
end
spec = Gem::Specification.load "prawn.gemspec"
Gem::PackageTask.new(spec) do |pkg|
pkg.need_zip = true
pkg.need_tar = true
end
ruby-prawn-1.0.0~rc2.orig/prawn.gemspec 0000644 0000000 0000000 00000003364 12114176157 016567 0 ustar root root Gem::Specification.new do |spec|
spec.name = "prawn"
spec.version = File.read(File.expand_path('VERSION', File.dirname(__FILE__))).strip
spec.platform = Gem::Platform::RUBY
spec.summary = "A fast and nimble PDF generator for Ruby"
spec.files = Dir.glob("{examples,lib,spec,data,manual}/**/**/*") +
["Rakefile", "prawn.gemspec", "COPYING", "LICENSE", "GPLv2", "GPLv3",
"Gemfile"]
spec.require_path = "lib"
spec.required_ruby_version = '>= 1.8.7'
spec.required_rubygems_version = ">= 1.3.6"
spec.test_files = Dir[ "spec/*_spec.rb" ]
spec.extra_rdoc_files = %w{README.md LICENSE COPYING GPLv2 GPLv3}
spec.rdoc_options << '--title' << 'Prawn Documentation' <<
'--main' << 'README.md' << '-q'
spec.authors = ["Gregory Brown","Brad Ediger","Daniel Nelson","Jonathan Greenberg","James Healy"]
spec.email = ["gregory.t.brown@gmail.com","brad@bradediger.com","dnelson@bluejade.com","greenberg@entryway.net","jimmy@deefa.com"]
spec.rubyforge_project = "prawn"
spec.add_dependency('pdf-reader', '>=0.9.0', '<2.0')
spec.add_dependency('ttfunk', '~>1.0.3')
spec.add_dependency('ruby-rc4')
spec.add_dependency('afm')
spec.add_development_dependency('pdf-inspector', '~> 1.0.1')
spec.add_development_dependency('coderay', '~> 1.0.7')
spec.add_development_dependency('rdoc')
spec.homepage = "http://prawn.majesticseacreature.com"
spec.description = <