# frozen_string_literal: true
require 'spec_helper'
describe Prawn::Stamp do
describe 'create_stamp before any page is added' do
let(:pdf) { Prawn::Document.new(skip_page_creation: true) }
it 'works with the font class' do
# If anything goes wrong, Prawn::Errors::NotOnPage will be raised
pdf.create_stamp('my_stamp') do
pdf.font.height
end
end
it 'works with setting color' do
# If anything goes wrong, Prawn::Errors::NotOnPage will be raised
pdf.create_stamp('my_stamp') do
pdf.fill_color = 'ff0000'
end
end
end
describe '#stamp_at' do
let(:pdf) { create_pdf }
it 'works' do
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
expect(pdf.render).to match(%r{/Stamp1 Do.*?}m)
end
end
describe 'Document with a stamp' do
let(:pdf) { create_pdf }
it 'raises NameTaken error when attempt to create stamp with '\
'same name as an existing stamp' do
pdf.create_stamp('MyStamp')
expect do
pdf.create_stamp('MyStamp')
end.to raise_error(Prawn::Errors::NameTaken)
end
it 'raises InvalidName error when attempt to create stamp with '\
'a blank name' do
expect do
pdf.create_stamp('')
end.to raise_error(Prawn::Errors::InvalidName)
end
it 'a new XObject should be defined for each stamp created' do
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
expect(xobjects.length).to eq(2)
end
it 'calling stamp with a name that does not match an existing stamp ' \
'should raise_error UndefinedObjectName' do
pdf.create_stamp('MyStamp')
expect do
pdf.stamp('OtherStamp')
end.to raise_error(Prawn::Errors::UndefinedObjectName)
end
it 'stamp should be drawn into the document each time stamp is called' do
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
expect(pdf.render).to match(%r{(/Stamp1 Do.*?){3}}m)
end
it 'stamp should render clickable links' do
pdf.create_stamp 'bar' do
pdf.text 'Prawn GitHub',
inline_format: true
end
pdf.stamp 'bar'
output = pdf.render
objects = output.split('endobj')
objects.each do |obj|
next unless %r{/Type /Page$}.match?(obj)
# The page object must contain the annotation reference
# to render a clickable link
expect(obj).to match(%r{^/Annots \[\d \d .\]$})
end
end
it 'resources added during stamp creation should be added to the ' \
'stamp XObject, not the page' do
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|
case object
when %r{/Type /Page$}
expect(object).to_not match(%r{/ExtGState})
when %r{/Type /XObject$}
expect(object).to match(%r{/ExtGState})
end
end
end
it 'stamp stream should be wrapped in a graphic state' do
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)
expect(stamps.xobject_streams[:Stamp1].data.chomp).to match(/q(.|\s)*Q\Z/)
end
it 'does not add to the page graphic state stack' do
expect(pdf.state.page.stack.stack.size).to eq(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
expect(pdf.state.page.stack.stack.size).to eq(1)
end
it 'is able to change fill and stroke colors within the stamp stream' do
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
expect(stamp_stream).to include("/DeviceCMYK cs\n1.0 1.0 0.2 0.0 scn")
expect(stamp_stream).to include("/DeviceCMYK CS\n1.0 1.0 0.2 0.0 SCN")
end
it 'saves the color space even when same as current page color space' do
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
expect(stamp_stream).to include("/DeviceCMYK CS\n1.0 1.0 0.2 0.0 SCN")
end
end
end