You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
3.8 KiB
113 lines
3.8 KiB
require 'forwardable' |
|
require_relative 'gradient_regex' |
|
|
|
module Squib |
|
module Graphics |
|
# Wrapper class for the Cairo context. Private. |
|
# @api private |
|
class CairoContextWrapper |
|
extend Forwardable |
|
|
|
# :nodoc: |
|
# @api private |
|
attr_accessor :cairo_cxt |
|
|
|
# :nodoc: |
|
# @api private |
|
def initialize(cairo_cxt) |
|
@cairo_cxt = cairo_cxt |
|
end |
|
|
|
def_delegators :cairo_cxt, :save, :set_source_color, :paint, :restore, |
|
:translate, :rotate, :move_to, :update_pango_layout, :width, :height, |
|
:show_pango_layout, :rounded_rectangle, :set_line_width, :stroke, :fill, |
|
:set_source, :scale, :render_rsvg_handle, :circle, :triangle, :line_to, |
|
:operator=, :show_page, :clip, :transform, :mask, :create_pango_layout, |
|
:antialias=, :curve_to, :matrix, :matrix=, :identity_matrix, :pango_layout_path, |
|
:stroke_preserve, :target, :new_path, :fill_preserve, :close_path, |
|
:set_line_join, :set_line_cap, :set_dash |
|
|
|
# :nodoc: |
|
# @api private |
|
def set_source_squibcolor(arg) |
|
raise 'nil is not a valid color' if arg.nil? |
|
if match = arg.match(LINEAR_GRADIENT) |
|
x1, y1, x2, y2 = match.captures |
|
linear = Cairo::LinearPattern.new(x1.to_f, y1.to_f, x2.to_f, y2.to_f) |
|
arg.scan(STOPS).each do |color, offset| |
|
linear.add_color_stop(offset.to_f, color) |
|
end |
|
linear.matrix = matrix # match the coordinate systems - see bug 127 |
|
@cairo_cxt.set_source(linear) |
|
elsif match = arg.match(RADIAL_GRADIENT) |
|
x1, y1, r1, x2, y2, r2 = match.captures |
|
radial = Cairo::RadialPattern.new(x1.to_f, y1.to_f, r1.to_f, |
|
x2.to_f, y2.to_f, r2.to_f) |
|
radial.matrix = matrix # match the coordinate systems - see bug 127 |
|
arg.scan(STOPS).each do |color, offset| |
|
radial.add_color_stop(offset.to_f, color) |
|
end |
|
@cairo_cxt.set_source(radial) |
|
else |
|
@cairo_cxt.set_source_color(arg) |
|
end |
|
end |
|
|
|
# Convenience method for a common task |
|
# @api private |
|
def fill_n_stroke(draw) |
|
return stroke_n_fill(draw) if draw.stroke_strategy == :stroke_first |
|
set_source_squibcolor draw.fill_color |
|
fill_preserve |
|
set_source_squibcolor draw.stroke_color |
|
set_line_width draw.stroke_width |
|
set_line_join draw.join |
|
set_line_cap draw.cap |
|
set_dash draw.dash |
|
stroke |
|
end |
|
|
|
def stroke_n_fill(draw) |
|
return fill_n_stroke(draw) if draw.stroke_strategy == :fill_first |
|
set_source_squibcolor draw.stroke_color |
|
set_line_width draw.stroke_width |
|
set_line_join draw.join |
|
set_line_cap draw.cap |
|
set_dash draw.dash |
|
stroke_preserve |
|
set_source_squibcolor draw.fill_color |
|
fill |
|
end |
|
|
|
# Convenience method for a common task |
|
# @api private |
|
def fancy_stroke(draw) |
|
set_source_squibcolor draw.stroke_color |
|
set_line_width draw.stroke_width |
|
set_line_join draw.join |
|
set_line_cap draw.cap |
|
set_dash draw.dash |
|
stroke |
|
end |
|
|
|
def rotate_about(x, y, angle) |
|
translate(x, y) |
|
rotate(angle) |
|
translate(-x, -y) |
|
end |
|
|
|
# Flip either vertical or horizontal depending |
|
# From the cairo website: http://cairographics.org/matrix_transform/ |
|
# cairo.Matrix(fx, 0, 0, |
|
# fy, cx*(1-fx), cy*(fy-1)) |
|
# fx/fy = 1 means 'no flip', fx/fy = -1 are used for horizontal/vertical flip |
|
def flip(vertical, horizontal, x, y) |
|
v = vertical ? -1.0 : 1.0 |
|
h = horizontal ? -1.0 : 1.0 |
|
transform Cairo::Matrix.new(v, 0.0, 0.0, |
|
h, x*(1-v), y*(1-h)) |
|
end |
|
|
|
end |
|
end |
|
end
|
|
|