From cf736db06700f0d88c336feaf12ac9173831f729 Mon Sep 17 00:00:00 2001 From: Andy Meneely Date: Sun, 10 Jan 2016 20:30:30 -0500 Subject: [PATCH] Maintain coordinate system when using gradients Sample: document this better spec: test this and update past tests Fixes #127 --- lib/squib/graphics/cairo_context_wrapper.rb | 8 +- samples/images | 2 +- spec/graphics/cairo_context_wrapper_spec.rb | 103 +++++++++++--------- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/lib/squib/graphics/cairo_context_wrapper.rb b/lib/squib/graphics/cairo_context_wrapper.rb index bc1d32a..590a3f1 100644 --- a/lib/squib/graphics/cairo_context_wrapper.rb +++ b/lib/squib/graphics/cairo_context_wrapper.rb @@ -37,15 +37,17 @@ module Squib 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 - linear = Cairo::RadialPattern.new(x1.to_f, y1.to_f, r1.to_f, + 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| - linear.add_color_stop(offset.to_f, color) + radial.add_color_stop(offset.to_f, color) end - @cairo_cxt.set_source(linear) + @cairo_cxt.set_source(radial) else @cairo_cxt.set_source_color(arg) end diff --git a/samples/images b/samples/images index 514af49..0714a8c 160000 --- a/samples/images +++ b/samples/images @@ -1 +1 @@ -Subproject commit 514af49430797daf7a69c31118b6056dc4abaf20 +Subproject commit 0714a8c2dee388b3f856d2a86d4efb95c5e3cde8 diff --git a/spec/graphics/cairo_context_wrapper_spec.rb b/spec/graphics/cairo_context_wrapper_spec.rb index 370885a..8ee6da7 100644 --- a/spec/graphics/cairo_context_wrapper_spec.rb +++ b/spec/graphics/cairo_context_wrapper_spec.rb @@ -28,60 +28,71 @@ describe Squib::Graphics::CairoContextWrapper do expect { subject.set_source_squibcolor(nil) }.to raise_error('nil is not a valid color') end - end - - - context 'regex variations for linear gradients' do - before(:each) do - dbl = double(Cairo::LinearPattern) - expect(Cairo::LinearPattern).to receive(:new).with(1,2,3,4).and_return(dbl) - expect(dbl).to receive(:add_color_stop).with(0.0, 'blue') - expect(dbl).to receive(:add_color_stop).with(1.0, 'red') - expect(cairo).to receive(:set_source).with(dbl) + context 'regex variations for linear gradients' do + before(:each) do + dbl = double(Cairo::LinearPattern) + mtx = double(Cairo::Matrix) + expect(Cairo::LinearPattern).to receive(:new).with(1,2,3,4).and_return(dbl) + expect(dbl).to receive(:add_color_stop).with(0.0, 'blue') + expect(dbl).to receive(:add_color_stop).with(1.0, 'red') + expect(cairo).to receive(:matrix).and_return(mtx) + expect(dbl).to receive(:matrix=).with(mtx) + expect(cairo).to receive(:set_source).with(dbl) + end + + it('handles no decimals' ) { subject.set_source_squibcolor('(1,2) (3,4) blue@0 red@1') } + it('handles decimals' ) { subject.set_source_squibcolor('(1.0,2.0) (3.0,4.0) blue@0 red@1') } + it('handles no whitespace') { subject.set_source_squibcolor('(1,2)(3,4)blue@0red@1') } + it('handles whitespace' ) { subject.set_source_squibcolor(' ( 1 , 2 ) ( 3 , 4 ) blue@0 red@1 ') } end - it('handles no decimals' ) { subject.set_source_squibcolor('(1,2) (3,4) blue@0 red@1') } - it('handles decimals' ) { subject.set_source_squibcolor('(1.0,2.0) (3.0,4.0) blue@0 red@1') } - it('handles no whitespace') { subject.set_source_squibcolor('(1,2)(3,4)blue@0red@1') } - it('handles whitespace' ) { subject.set_source_squibcolor(' ( 1 , 2 ) ( 3 , 4 ) blue@0 red@1 ') } - end - - context 'regex variations for radial gradients' do - before(:each) do - dbl = double(Cairo::RadialPattern) - expect(Cairo::RadialPattern).to receive(:new).with(1,2,5,3,4,6).and_return(dbl) - expect(dbl).to receive(:add_color_stop).with(0.0, 'blue') - expect(dbl).to receive(:add_color_stop).with(1.0, 'red') - expect(cairo).to receive(:set_source).with(dbl) + context 'regex variations for radial gradients' do + before(:each) do + dbl = double(Cairo::RadialPattern) + mtx = double(Cairo::Matrix) + expect(Cairo::RadialPattern).to receive(:new).with(1,2,5,3,4,6).and_return(dbl) + expect(dbl).to receive(:add_color_stop).with(0.0, 'blue') + expect(dbl).to receive(:add_color_stop).with(1.0, 'red') + expect(cairo).to receive(:matrix).and_return(mtx) + expect(dbl).to receive(:matrix=).with(mtx) + expect(cairo).to receive(:set_source).with(dbl) + end + + it('handles no decimals' ) { subject.set_source_squibcolor('(1,2,5) (3,4,6) blue@0 red@1') } + it('handles decimals' ) { subject.set_source_squibcolor('(1.0,2.0,5.0) (3.0,4.0,6.0) blue@0 red@1') } + it('handles no whitespace') { subject.set_source_squibcolor('(1,2,5)(3,4,6)blue@0red@1') } + it('handles whitespace' ) { subject.set_source_squibcolor(' ( 1 , 2 , 5 ) ( 3 , 4 , 6 ) blue@0 red@1 ') } end - it('handles no decimals' ) { subject.set_source_squibcolor('(1,2,5) (3,4,6) blue@0 red@1') } - it('handles decimals' ) { subject.set_source_squibcolor('(1.0,2.0,5.0) (3.0,4.0,6.0) blue@0 red@1') } - it('handles no whitespace') { subject.set_source_squibcolor('(1,2,5)(3,4,6)blue@0red@1') } - it('handles whitespace' ) { subject.set_source_squibcolor(' ( 1 , 2 , 5 ) ( 3 , 4 , 6 ) blue@0 red@1 ') } - end - - context 'regex handles hash notation' do - it 'on radial patterns' do - dbl = double(Cairo::RadialPattern) - expect(Cairo::RadialPattern).to receive(:new).with(1,2,5,3,4,6).and_return(dbl) - expect(dbl).to receive(:add_color_stop).with(0.0, '#def') - expect(dbl).to receive(:add_color_stop).with(1.0, '#112233') - expect(cairo).to receive(:set_source).with(dbl) - subject.set_source_squibcolor('(1,2,5) (3,4,6) #def@0 #112233@1') + context 'regex handles hash notation' do + it 'on radial patterns' do + dbl = double(Cairo::RadialPattern) + mtx = double(Cairo::Matrix) + expect(Cairo::RadialPattern).to receive(:new).with(1,2,5,3,4,6).and_return(dbl) + expect(dbl).to receive(:add_color_stop).with(0.0, '#def') + expect(dbl).to receive(:add_color_stop).with(1.0, '#112233') + expect(cairo).to receive(:matrix).and_return(mtx) + expect(dbl).to receive(:matrix=).with(mtx) + expect(cairo).to receive(:set_source).with(dbl) + subject.set_source_squibcolor('(1,2,5) (3,4,6) #def@0 #112233@1') + end + + it 'on linear patterns' do + dbl = double(Cairo::LinearPattern) + mtx = double(Cairo::Matrix) + expect(Cairo::LinearPattern).to receive(:new).with(1,2,3,4).and_return(dbl) + expect(dbl).to receive(:add_color_stop).with(0.0, '#def') + expect(dbl).to receive(:add_color_stop).with(1.0, '#112233') + expect(cairo).to receive(:matrix).and_return(mtx) + expect(dbl).to receive(:matrix=).with(mtx) + expect(cairo).to receive(:set_source).with(dbl) + subject.set_source_squibcolor('(1,2) (3,4) #def@0 #112233@1') + end end - it 'on linear patterns' do - dbl = double(Cairo::LinearPattern) - expect(Cairo::LinearPattern).to receive(:new).with(1,2,3,4).and_return(dbl) - expect(dbl).to receive(:add_color_stop).with(0.0, '#def') - expect(dbl).to receive(:add_color_stop).with(1.0, '#112233') - expect(cairo).to receive(:set_source).with(dbl) - subject.set_source_squibcolor('(1,2) (3,4) #def@0 #112233@1') - end end - context 'flips' do + context '#flip' do it 'in the basic case' do dbl = double(Cairo::Matrix) expect(Cairo::Matrix).to receive(:new).with(-1.0, 0.0, 0.0, -1.0, 6.0, 8.0).and_return(dbl)