alpha_available?()
click to toggle source
def alpha_available?
true
end
background_image=(pixbuf)
click to toggle source
def background_image=(pixbuf)
surface = ::Cairo::ImageSurface.new(::Cairo::FORMAT_A1, 1, 1)
context = ::Cairo::Context.new(surface)
context.set_source_pixbuf(pixbuf)
@background_image = context.source
@background_image.extend = ::Cairo::EXTEND_REPEAT
pixbuf
end
create_pango_context()
click to toggle source
def create_pango_context
context = Pango::CairoFontMap.default.create_context
set_font_resolution(context)
context
end
draw_arc(filled, x, y, w, h, a1, a2, color=nil, params={})
click to toggle source
def draw_arc(filled, x, y, w, h, a1, a2, color=nil, params={})
r = w * 0.5
draw_arc_by_radius(filled, x + w * 0.5, y + h * 0.5,
r, a1, a2, color, params)
end
draw_arc_by_radius(filled, x, y, r, a1, a2, color=nil, params={})
click to toggle source
def draw_arc_by_radius(filled, x, y, r, a1, a2, color=nil, params={})
x, y = from_screen(x, y)
a1, a2 = convert_angle(a1, a2)
@context.save do
set_source(color, params)
set_line_options(params)
args = [x, y, r, a1, a2]
action, = cairo_action(filled, params)
@context.move_to(x, y) unless action == :stroke
@context.arc(*args)
@context.close_path unless action == :stroke
apply_cairo_action(filled, params)
end
end
draw_background(slide)
click to toggle source
def draw_background(slide)
super
if @background_image
@context.save do
@context.set_source(@background_image)
@context.paint
end
end
end
draw_layout(layout, x, y, color=nil, params={})
click to toggle source
def draw_layout(layout, x, y, color=nil, params={})
x, y = from_screen(x, y)
@context.save do
set_source(color, params)
set_line_options(params)
@context.move_to(x, y)
@context.show_pango_layout(layout)
end
end
draw_line(x1, y1, x2, y2, color=nil, params={})
click to toggle source
def draw_line(x1, y1, x2, y2, color=nil, params={})
x1, y1 = from_screen(x1, y1)
x2, y2 = from_screen(x2, y2)
@context.save do
set_source(color, params)
set_line_options(params)
@context.new_path
@context.move_to(x1, y1)
@context.line_to(x2, y2)
apply_cairo_action(false, params)
end
end
draw_lines(points, color=nil, params={})
click to toggle source
def draw_lines(points, color=nil, params={})
draw_polygon(false, points, color, params.merge({:opened => true}))
end
draw_pixbuf(pixbuf, x, y, params={})
click to toggle source
def draw_pixbuf(pixbuf, x, y, params={})
x, y = from_screen(x, y)
@context.save do
@context.translate(x, y)
set_source_pixbuf(pixbuf, params)
@context.paint(params[:alpha])
end
_draw_reflected_pixbuf(pixbuf, x, y, params)
end
draw_polygon(filled, points, color=nil, params={})
click to toggle source
def draw_polygon(filled, points, color=nil, params={})
return if points.empty?
@context.save do
set_source(color, params)
set_line_options(params)
@context.move_to(*from_screen(*points.first))
points[1..-1].each do |x, y|
@context.line_to(*from_screen(x, y))
end
@context.line_to(*from_screen(*points.first)) unless params[:opened]
apply_cairo_action(filled, params)
end
end
draw_poppler_page(page, x, y, params={})
click to toggle source
def draw_poppler_page(page, x, y, params={})
x, y = from_screen(x, y)
w, h = page.size
width = (params[:width] || w).to_f
height = (params[:height] || h).to_f
@context.save do
@context.translate(x, y)
@context.scale(width / w, height / h)
@context.render_poppler_page(page)
end
end
draw_rectangle(filled, x, y, w, h, color=nil, params={})
click to toggle source
def draw_rectangle(filled, x, y, w, h, color=nil, params={})
x, y = from_screen(x, y)
@context.save do
set_source(color, params)
set_line_options(params)
@context.rectangle(x, y, w, h)
apply_cairo_action(filled, params)
end
end
draw_rounded_rectangle(filled, x, y, w, h, radius, color=nil, params={})
click to toggle source
def draw_rounded_rectangle(filled, x, y, w, h, radius,
color=nil, params={})
x, y = from_screen(x, y)
x_radius = params[:x_radius] || radius
y_radius = params[:y_radius] || radius
@context.save do
set_source(color, params)
set_line_options(params)
@context.new_path
@context.rounded_rectangle(x, y, w, h, x_radius, y_radius)
apply_cairo_action(filled, params)
end
end
draw_rsvg_handle(handle, x, y, params={})
click to toggle source
def draw_rsvg_handle(handle, x, y, params={})
x, y = from_screen(x, y)
dim = handle.dimensions
width = (params[:width] || dim.width).to_f
height = (params[:height] || dim.height).to_f
@context.save do
@context.translate(x, y)
@context.scale(width / dim.width, height / dim.height)
@context.render_rsvg_handle(handle)
end
_draw_reflected_rsvg_handle(handle, x, y, width, height,
params)
end
finish_context()
click to toggle source
def finish_context
@contexts.pop
@context.destroy if @context.respond_to?(:destroy)
@context = @contexts.last
end
finish_renderer()
click to toggle source
def finish_renderer
finish_context
end
init_context(context)
click to toggle source
def init_context(context)
@context = context
@contexts ||= []
@contexts.push(@context)
set_line_width(1)
@context.line_cap = ::Cairo::LINE_CAP_ROUND
@context.line_join = ::Cairo::LINE_JOIN_ROUND
end
init_renderer(drawable)
click to toggle source
def init_renderer(drawable)
init_context(drawable.create_cairo_context)
end
make_layout(text)
click to toggle source
def make_layout(text)
attrs, text = Pango.parse_markup(text)
layout = @context.create_pango_layout
layout.text = text
layout.set_attributes(attrs)
set_font_resolution(layout.context)
@context.update_pango_layout(layout)
layout
end
poppler_available?()
click to toggle source
def poppler_available?
if @@poppler_available.nil?
@@poppler_available = Poppler.cairo_available?
end
@@poppler_available
end
prepare_renderer(drawable)
click to toggle source
def prepare_renderer(drawable)
end
reflect_context(base, params={})
click to toggle source
def reflect_context(base, params={})
case base
when :y
matrix = make_matrix(-1, 0, 0,
0, 1, 0)
else
matrix = make_matrix(1, 0, 0,
0, -1, 0)
end
@context.transform(matrix)
end
restore_context()
click to toggle source
def restore_context
@context.restore
end
rotate_context(angle, params={})
click to toggle source
def rotate_context(angle, params={})
@context.rotate(convert_angle(angle, 0)[0])
end
rsvg_available?()
click to toggle source
def rsvg_available?
if @@rsvg_available.nil?
@@rsvg_available = RSVG.cairo_available?
end
@@rsvg_available
end
save_context()
click to toggle source
def save_context
@context.save
super
end
scale_context(x, y, params={})
click to toggle source
def scale_context(x, y, params={})
@context.scale(x, y)
end
set_font_resolution(context)
click to toggle source
def set_font_resolution(context)
context.resolution = @canvas.font_resolution
end
set_source_pixbuf(pixbuf, params)
click to toggle source
def set_source_pixbuf(pixbuf, params)
draw_scaled_pixbuf = params[:draw_scaled_pixbuf]
draw_scaled_pixbuf = @draw_scaled_image if draw_scaled_pixbuf.nil?
width = (params[:width] || pixbuf.width).to_f
height = (params[:height] || pixbuf.height).to_f
if [width, height] == [pixbuf.width, pixbuf.height]
@context.set_source_pixbuf(pixbuf, 0, 0)
return
end
case draw_scaled_pixbuf
when true
scaled_pixbuf = pixbuf.scale(width, height)
@context.set_source_pixbuf(scaled_pixbuf, 0, 0)
when false
@context.set_source_pixbuf(pixbuf, 0, 0)
matrix = ::Cairo::Matrix.scale(pixbuf.width / width,
pixbuf.height / height)
@context.source.matrix = matrix
else
scales = [4, 3, 2]
scales.each do |scale|
if width * scale < pixbuf.width and height * scale < pixbuf.height
scaled_pixbuf = pixbuf.scale(width * scale, height * scale)
@context.set_source_pixbuf(scaled_pixbuf)
matrix = ::Cairo::Matrix.scale(scale, scale)
@context.source.matrix = matrix
return
end
end
@context.set_source_pixbuf(pixbuf, 0, 0)
matrix = ::Cairo::Matrix.scale(pixbuf.width / width,
pixbuf.height / height)
@context.source.matrix = matrix
end
end
shear_context(x, y, params={})
click to toggle source
def shear_context(x, y, params={})
@context.transform(make_matrix(1, x, 0,
y, 1, 0))
end
to_gdk_rgb(color)
click to toggle source
def to_gdk_rgb(color)
make_color(color).to_gdk_rgb
end
translate_context(x, y, params={})
click to toggle source
def translate_context(x, y, params={})
@context.translate(x, y)
end
_draw_reflected_pixbuf(pixbuf, x, y, params)
click to toggle source
def _draw_reflected_pixbuf(pixbuf, x, y, params)
reflect_params = params[:reflect]
return unless reflect_params
reflect_params = {} if reflect_params == true
ratio = reflect_params[:ratio] || 0.3
start_alpha = reflect_params[:start_alpha] || 0.3
@context.save do
width = (params[:width] || pixbuf.width).to_f
height = (params[:height] || pixbuf.height).to_f
@context.translate(x, y + height * 2)
reflect_context(:x)
set_source_pixbuf(pixbuf, params)
pattern = ::Cairo::LinearPattern.new(width * 0.5, 0,
width * 0.5, height)
pattern.add_color_stop_rgba(0, 0, 0, 0, 0)
pattern.add_color_stop_rgba(1 - ratio, 0, 0, 0, 0)
pattern.add_color_stop_rgba(1, 0, 0, 0, start_alpha)
@context.mask(pattern)
end
end
_draw_reflected_rsvg_handle(handle, x, y, width, height, params)
click to toggle source
def _draw_reflected_rsvg_handle(handle, x, y, width, height, params)
return unless params
dim = handle.dimensions
surface = ::Cairo::ImageSurface.new(:argb32, width, height)
context = ::Cairo::Context.new(surface)
context.scale(width / dim.width, height / dim.height)
context.render_rsvg_handle(handle)
png = Tempfile.new("rabbit-cairo-svg-renderer")
context.target.write_to_png(png.path)
context.target.finish
pixbuf = Gdk::Pixbuf.new(png.path)
_draw_reflected_pixbuf(pixbuf, x, y, params)
end
apply_cairo_action(filled, params={})
click to toggle source
def apply_cairo_action(filled, params={})
action, *other_info = cairo_action(filled, params)
@context.send(action)
case action
when :clip
block, = other_info
block.call if block
end
end
cairo_action(filled, params={})
click to toggle source
def cairo_action(filled, params={})
if params[:clip]
[:clip, params[:clip]]
elsif filled
:fill
else
:stroke
end
end
convert_angle(a1, a2)
click to toggle source
def convert_angle(a1, a2)
a2 += a1
[a2, a1].collect {|a| (360 - a) * (Math::PI / 180.0)}
end
from_screen(x, y)
click to toggle source
def from_screen(x, y)
[x.ceil, y.ceil]
end
init_engine_color()
click to toggle source
def init_engine_color
@foreground = make_color("black")
@background = make_color(@background_color)
end
make_matrix(xx, xy, x0, yx, yy, y0)
click to toggle source
def make_matrix(xx, xy, x0, yx, yy, y0)
::Cairo::Matrix.new(xx, yx, xy, yy, x0, y0)
end
set_color(color)
click to toggle source
def set_color(color)
@context.set_source_rgba(make_color(color).to_a)
end
set_line_options(params)
click to toggle source
def set_line_options(params)
set_line_width(get_line_width(params))
[:line_cap, :line_join].each do |key|
value = params[key]
@context.send("#{key}=", value) if value
end
end
set_line_width(line_width)
click to toggle source
def set_line_width(line_width)
if line_width
@context.set_line_width(line_width)
end
end
set_pattern(info)
click to toggle source
def set_pattern(info)
pattern = nil
case info[:type]
when :radial
cx0, cy0, radius0, cx1, cy1, radius1 = info[:base]
cx0, cy0 = from_screen(cx0, cy0)
cx1, cy1 = from_screen(cx1, cy1)
pattern = ::Cairo::RadialPattern.new(cx0, cy0, radius0,
cx1, cy1, radius1)
info[:color_stops].each do |offset, r, g, b, a|
pattern.add_color_stop_rgba(offset, r, g, b, a)
end
when :linear
x, y, w, h = info[:base]
x, y = from_screen(x, y)
pattern = ::Cairo::LinearPattern.new(x, y, w, h)
info[:color_stops].each do |offset, r, g, b, a|
pattern.add_color_stop_rgba(offset, r, g, b, a)
end
when :pixbuf
@context.set_source_pixbuf(info[:pixbuf])
pattern = @context.source
end
if pattern
set_pattern_common_options(pattern, info)
@context.set_source(pattern)
end
!pattern.nil?
end
set_pattern_common_options(pattern, info)
click to toggle source
def set_pattern_common_options(pattern, info)
extend = info[:extend]
pattern.extend = extend if extend
transformations = info[:transformations]
if transformations
matrix = ::Cairo::Matrix.identity
transformations.each do |operation, *args|
matrix.send("#{operation}!", *args)
end
pattern.matrix = matrix
end
end
set_source(color, params={})
click to toggle source
def set_source(color, params={})
pattern = params[:pattern]
set = false
if pattern
set = set_pattern(pattern)
color ||= Color.parse("#fff0") unless set
end
set_color(make_color(color)) unless set
end