# encoding: utf-8
#
# transparency.rb : Implements transparency
#
# Copyright October 2009, Daniel Nelson. All Rights Reserved.
#
# This is free software. Please see the LICENSE and COPYING files for details.
#
module Prawn
module Graphics
# The Prawn::Transparency module is used to place transparent
# content on the page. It has the capacity for separate
# transparency values for stroked content and all other content.
#
# Example:
# # both the fill and stroke will be at 50% opacity
# pdf.transparent(0.5) do
# pdf.text("hello world")
# pdf.fill_and_stroke_circle([x, y], 25)
# end
#
# # the fill will be at 50% opacity, but the stroke will
# # be at 75% opacity
# pdf.transparent(0.5, 0.75) do
# pdf.text("hello world")
# pdf.fill_and_stroke_circle([x, y], 25)
# end
#
module Transparency
# @group Stable API
# Sets the opacity and stroke_opacity for all
# the content within the block
# If stroke_opacity is not provided, then it takes on
# the same value as opacity
#
# Valid ranges for both paramters are 0.0 to 1.0
#
# Example:
# # both the fill and stroke will be at 50% opacity
# pdf.transparent(0.5) do
# pdf.text("hello world")
# pdf.fill_and_stroke_circle([x, y], 25)
# end
#
# # the fill will be at 50% opacity, but the stroke will
# # be at 75% opacity
# pdf.transparent(0.5, 0.75) do
# pdf.text("hello world")
# pdf.fill_and_stroke_circle([x, y], 25)
# end
#
def transparent(opacity, stroke_opacity = opacity, &block)
renderer.min_version(1.4)
opacity = [[opacity, 0.0].max, 1.0].min
stroke_opacity = [[stroke_opacity, 0.0].max, 1.0].min
save_graphics_state
renderer.add_content "/#{opacity_dictionary_name(opacity, stroke_opacity)} gs"
yield
restore_graphics_state
end
private
def opacity_dictionary_registry
@opacity_dictionary_registry ||= {}
end
def next_opacity_dictionary_id
opacity_dictionary_registry.length + 1
end
def opacity_dictionary_name(opacity, stroke_opacity)
key = "#{opacity}_#{stroke_opacity}"
if opacity_dictionary_registry[key]
dictionary = opacity_dictionary_registry[key][:obj]
dictionary_name = opacity_dictionary_registry[key][:name]
else
dictionary = ref!(
:Type => :ExtGState,
:CA => stroke_opacity,
:ca => opacity
)
dictionary_name = "Tr#{next_opacity_dictionary_id}"
opacity_dictionary_registry[key] = { :name => dictionary_name,
:obj => dictionary }
end
page.ext_gstates.merge!(dictionary_name => dictionary)
dictionary_name
end
end
end
end