Added support for linear and radial gradients

Closes #29
This commit is contained in:
Andy Meneely
2015-01-26 22:22:09 -05:00
parent bde7fe018e
commit bfbf7a7eba
30 changed files with 1361 additions and 1064 deletions
+2 -1
View File
@@ -1,5 +1,6 @@
require 'cairo'
require 'squib/input_helpers'
require 'squib/graphics/cairo_context_wrapper'
module Squib
# Back end graphics. Private.
@@ -19,7 +20,7 @@ module Squib
def initialize(deck, width, height)
@deck=deck; @width=width; @height=height
@cairo_surface = Cairo::ImageSurface.new(width,height)
@cairo_context = Cairo::Context.new(@cairo_surface)
@cairo_context = Squib::Graphics::CairoContextWrapper.new(Cairo::Context.new(@cairo_surface))
end
# A save/restore wrapper for using Cairo
+1 -1
View File
@@ -5,7 +5,7 @@ module Squib
# @api private
def background(color)
use_cairo do |cc|
cc.set_source_color(color)
cc.set_source_squibcolor(color)
cc.paint
end
end
@@ -0,0 +1,42 @@
require 'forwardable'
require 'squib/graphics/gradient_regex'
module Squib
module Graphics
class CairoContextWrapper
extend Forwardable
attr_accessor :cairo_cxt
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
def set_source_squibcolor(arg)
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
@cairo_cxt.set_source(linear)
elsif match = arg.match(RADIAL_GRADIENT)
x1, y1, r1, x2, y2, r2 = match.captures
linear = Cairo::RadialPattern.new(x1.to_f, y1.to_f, r1.to_f,
x2.to_f, y2.to_f, r2.to_f)
arg.scan(STOPS).each do |color, offset|
linear.add_color_stop(offset.to_f, color)
end
@cairo_cxt.set_source(linear)
else
@cairo_cxt.set_source_color(arg)
end
end
end
end
end
+46
View File
@@ -0,0 +1,46 @@
module Squib
module Graphics
STOPS = / # used to capture the stops
\s* # leading whitespace is ok
(\#?[\w]+) # color
@ # no spaces here
(\d+\.?\d*) # offset number
/x
LINEAR_GRADIENT = /
\( \s* # coordinate 1
(\d+\.?\d*) \s* # x1 number
,\s* # whitespace after comma is ok
(\d+\.?\d*) \s* # y1 number
\)
\s* # space between coordinates is ok
\( \s* # coordinate 2
(\d+\.?\d*) \s* # x2 number
,\s* # whitespace after comma is ok
(\d+\.?\d*) \s* # y2 number
\)
(#{STOPS})+ # stops
\s* # trailing whitespace is ok
/x
RADIAL_GRADIENT = /
\( \s* # coordinate 1
(\d+\.?\d*) \s* # x1 number
,\s* # whitespace after comma is ok
(\d+\.?\d*) \s* # y1 number
,\s* # whitespace after comma is ok
(\d+\.?\d*) \s* # r1 number
\)
\s* # space between coordinates is ok
\( \s* # coordinate 2
(\d+\.?\d*) \s* # x2 number
,\s* # whitespace after comma is ok
(\d+\.?\d*) \s* # y2 number
,\s* # whitespace after comma is ok
(\d+\.?\d*) \s* # r2 number
\)
(#{STOPS})+ # stops
\s* # trailing whitespace is ok
/x
end
end
+7 -7
View File
@@ -8,11 +8,11 @@ module Squib
height = @height if height == :native
use_cairo do |cc|
cc.rounded_rectangle(x, y, width, height, x_radius, y_radius)
cc.set_source_color(stroke_color)
cc.set_source_squibcolor(stroke_color)
cc.set_line_width(stroke_width)
cc.stroke
cc.rounded_rectangle(x, y, width, height, x_radius, y_radius)
cc.set_source_color(fill_color)
cc.set_source_squibcolor(fill_color)
cc.fill
end
end
@@ -22,11 +22,11 @@ module Squib
def circle(x, y, radius, fill_color, stroke_color, stroke_width)
use_cairo do |cc|
cc.circle(x, y, radius)
cc.set_source_color(stroke_color)
cc.set_source_squibcolor(stroke_color)
cc.set_line_width(stroke_width)
cc.stroke
cc.circle(x, y, radius)
cc.set_source_color(fill_color)
cc.set_source_squibcolor(fill_color)
cc.fill
end
end
@@ -36,11 +36,11 @@ module Squib
def triangle(x1, y1, x2, y2, x3, y3, fill_color, stroke_color, stroke_width)
use_cairo do |cc|
cc.triangle(x1, y1, x2, y2, x3, y3)
cc.set_source_color(stroke_color)
cc.set_source_squibcolor(stroke_color)
cc.set_line_width(stroke_width)
cc.stroke
cc.triangle(x1, y1, x2, y2, x3, y3)
cc.set_source_color(fill_color)
cc.set_source_squibcolor(fill_color)
cc.fill
end
end
@@ -51,7 +51,7 @@ module Squib
use_cairo do |cc|
cc.move_to(x1, y1)
cc.line_to(x2, y2)
cc.set_source_color(stroke_color)
cc.set_source_squibcolor(stroke_color)
cc.set_line_width(stroke_width)
cc.stroke
end
+1 -1
View File
@@ -91,7 +91,7 @@ module Squib
Squib.logger.debug {"Placing '#{str}'' with font '#{font}' @ #{x}, #{y}, color: #{color}, angle: #{angle} etc."}
extents = nil
use_cairo do |cc|
cc.set_source_color(color)
cc.set_source_squibcolor(color)
cc.translate(x,y)
cc.rotate(angle)
cc.translate(-1*x,-1*y)
+1 -1
View File
@@ -132,7 +132,7 @@ module Squib
if @custom_colors.key? color.to_s
color = @custom_colors[color.to_s]
end
opts[key][i] = Cairo::Color.parse(color)
opts[key][i] = color
end
end
Squib.logger.debug {"After colorify: #{opts}"}