From b3eb3b6876e4a24d099987c7e1fa0b565d60a293 Mon Sep 17 00:00:00 2001 From: Andy Meneely Date: Tue, 12 Aug 2014 12:23:54 -0400 Subject: [PATCH] Added blending operators to png and svg Also refactored to start using save/restore more often --- lib/squib/api/image.rb | 11 ++++-- lib/squib/card.rb | 62 ++++++++++++++++-------------- lib/squib/constants.rb | 2 + lib/squib/graphics/background.rb | 7 ++-- lib/squib/graphics/image.rb | 19 +++++---- lib/squib/graphics/shapes.rb | 64 ++++++++++++++++--------------- lib/squib/graphics/text.rb | 37 +++++++++--------- samples/ball.png | Bin 0 -> 1427 bytes samples/grit.png | Bin 0 -> 13054 bytes samples/load_images.rb | 6 ++- samples/shiny-purse.png | Bin 2766 -> 3430 bytes 11 files changed, 117 insertions(+), 91 deletions(-) create mode 100644 samples/ball.png create mode 100644 samples/grit.png diff --git a/lib/squib/api/image.rb b/lib/squib/api/image.rb index 96c49aa..6b7ff05 100644 --- a/lib/squib/api/image.rb +++ b/lib/squib/api/image.rb @@ -14,13 +14,14 @@ module Squib # @option opts y [Integer] (0) the y-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} + # @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @return [nil] Returns nil # @api public def png(opts = {}) - opts = needs(opts, [:range, :files, :x, :y, :alpha, :layout]) + opts = needs(opts, [:range, :files, :x, :y, :alpha, :layout, :blend]) @progress_bar.start("Loading PNG(s)", opts[:range].size) do |bar| opts[:range].each do |i| - @cards[i].png(opts[:file][i], opts[:x][i], opts[:y][i], opts[:alpha][i]) + @cards[i].png(opts[:file][i], opts[:x][i], opts[:y][i], opts[:alpha][i], opts[:blend][i]) bar.increment end end @@ -40,14 +41,16 @@ module Squib # @option opts width [Integer] (:native) the pixel width that the image should scale to. SVG scaling is done with vectors, so the scaling should be smooth. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts height [Integer] (:native) the pixel width that the image should scale to. SVG scaling is done with vectors, so the scaling should be smooth. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} + # @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} + # @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @return [nil] Returns nil # @api public def svg(opts = {}) - p = needs(opts,[:range, :files, :svgid, :x, :y, :width, :height, :layout]) + p = needs(opts,[:range, :files, :svgid, :x, :y, :width, :height, :layout, :alpha, :blend]) @progress_bar.start("Loading SVG(s)", p[:range].size) do |bar| p[:range].each do |i| @cards[i].svg(p[:file][i], p[:id][i], p[:x][i], p[:y][i], - p[:width][i], p[:height][i]) + p[:width][i], p[:height][i], p[:alpha][i], p[:blend][i]) bar.increment end end diff --git a/lib/squib/card.rb b/lib/squib/card.rb index 8c7c3e6..ae818b7 100644 --- a/lib/squib/card.rb +++ b/lib/squib/card.rb @@ -2,35 +2,41 @@ require 'cairo' require 'squib/input_helpers' module Squib - # Back end graphics. Private. - class Card - include Squib::InputHelpers + # Back end graphics. Private. + class Card + include Squib::InputHelpers - # :nodoc: - # @api private - attr_reader :width, :height + # :nodoc: + # @api private + attr_reader :width, :height - # :nodoc: - # @api private - attr_accessor :cairo_surface, :cairo_context + # :nodoc: + # @api private + attr_accessor :cairo_surface, :cairo_context - # :nodoc: - # @api private - 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) - end + # :nodoc: + # @api private + 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) + end - ######################## - ### BACKEND GRAPHICS ### - ######################## - require 'squib/graphics/background' - require 'squib/graphics/image' - require 'squib/graphics/save_doc' - require 'squib/graphics/save_images' - require 'squib/graphics/shapes' - require 'squib/graphics/text' - - end - end \ No newline at end of file + def use_cairo(&block) + @cairo_context.save + block.yield(@cairo_context) + @cairo_context.restore + end + + ######################## + ### BACKEND GRAPHICS ### + ######################## + require 'squib/graphics/background' + require 'squib/graphics/image' + require 'squib/graphics/save_doc' + require 'squib/graphics/save_images' + require 'squib/graphics/shapes' + require 'squib/graphics/text' + + end +end \ No newline at end of file diff --git a/lib/squib/constants.rb b/lib/squib/constants.rb index 10ffa1e..5cf5ea0 100644 --- a/lib/squib/constants.rb +++ b/lib/squib/constants.rb @@ -5,6 +5,7 @@ module Squib SYSTEM_DEFAULTS = { :align => :left, :alpha => 1.0, + :blend => :none, :color => :black, :default_font => 'Arial 36', :dir => "_output", @@ -64,6 +65,7 @@ module Squib EXPANDING_PARAMS = { :align => :align, :alpha => :alpha, + :blend => :blend, :circle_radius => :radius, :color => :color, :ellipsize => :ellipsize, diff --git a/lib/squib/graphics/background.rb b/lib/squib/graphics/background.rb index d4950d2..19d816d 100644 --- a/lib/squib/graphics/background.rb +++ b/lib/squib/graphics/background.rb @@ -4,9 +4,10 @@ module Squib # :nodoc: # @api private def background(color) - cc = cairo_context - cc.set_source_color(color) - cc.paint + use_cairo do |cc| + cc.set_source_color(color) + cc.paint + end end end diff --git a/lib/squib/graphics/image.rb b/lib/squib/graphics/image.rb index 505e656..465f0e0 100644 --- a/lib/squib/graphics/image.rb +++ b/lib/squib/graphics/image.rb @@ -14,17 +14,19 @@ module Squib # :nodoc: # @api private - def png(file, x, y, alpha) + def png(file, x, y, alpha, blend) return if file.nil? or file.eql? '' - cc = cairo_context png = Squib.cache_load_image(file) - cc.set_source(png, x, y) - cc.paint(alpha) + use_cairo do |cc| + cc.set_source(png, x, y) + cc.operator = blend unless blend == :none + cc.paint(alpha) + end end # :nodoc: # @api private - def svg(file, id, x, y, width, height) + def svg(file, id, x, y, width, height, alpha, blend) return if file.nil? or file.eql? '' svg = RSVG::Handle.new_from_file(file) width = svg.width if width == :native @@ -33,8 +35,11 @@ module Squib tmp_cc = Cairo::Context.new(tmp) tmp_cc.scale(width.to_f / svg.width.to_f, height.to_f / svg.height.to_f) tmp_cc.render_rsvg_handle(svg, id) - cairo_context.set_source(tmp, x, y) - cairo_context.paint + use_cairo do |cc| + cc.set_source(tmp, x, y) + cc.operator = blend unless blend == :none + cc.paint(alpha) + end end end diff --git a/lib/squib/graphics/shapes.rb b/lib/squib/graphics/shapes.rb index 95a7753..1c42591 100644 --- a/lib/squib/graphics/shapes.rb +++ b/lib/squib/graphics/shapes.rb @@ -5,51 +5,55 @@ module Squib # @api private def rect(x, y, width, height, x_radius, y_radius, fill_color, stroke_color, stroke_width) width=@width if width==:native; height=@height if height==:native - cc = cairo_context - cc.rounded_rectangle(x, y, width, height, x_radius, y_radius) - cc.set_source_color(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.fill + use_cairo do |cc| + cc.rounded_rectangle(x, y, width, height, x_radius, y_radius) + cc.set_source_color(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.fill + end end # :nodoc: # @api private def circle(x, y, radius, fill_color, stroke_color, stroke_width) - cc = cairo_context - cc.circle(x, y, radius) - cc.set_source_color(stroke_color) - cc.set_line_width(stroke_width) - cc.stroke - cc.circle(x, y, radius) - cc.set_source_color(fill_color) - cc.fill + use_cairo do |cc| + cc.circle(x, y, radius) + cc.set_source_color(stroke_color) + cc.set_line_width(stroke_width) + cc.stroke + cc.circle(x, y, radius) + cc.set_source_color(fill_color) + cc.fill + end end # :nodoc: # @api private def triangle(x1, y1, x2, y2, x3, y3, fill_color, stroke_color, stroke_width) - cc = cairo_context - cc.triangle(x1, y1, x2, y2, x3, y3) - cc.set_source_color(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.fill + use_cairo do |cc| + cc.triangle(x1, y1, x2, y2, x3, y3) + cc.set_source_color(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.fill + end end # :nodoc: # @api private def line(x1, y1, x2, y2, stroke_color, stroke_width) - cc = cairo_context - cc.move_to(x1, y1) - cc.line_to(x2, y2) - cc.set_source_color(stroke_color) - cc.set_line_width(stroke_width) - cc.stroke + use_cairo do |cc| + cc.move_to(x1, y1) + cc.line_to(x2, y2) + cc.set_source_color(stroke_color) + cc.set_line_width(stroke_width) + cc.stroke + end end end diff --git a/lib/squib/graphics/text.rb b/lib/squib/graphics/text.rb index 6b90533..d178d1a 100644 --- a/lib/squib/graphics/text.rb +++ b/lib/squib/graphics/text.rb @@ -89,24 +89,25 @@ module Squib x, y, width, height, markup, justify, wrap, ellipsize, spacing, align, valign, hint) - Squib.logger.debug {"Placing '#{str}'' with font '#{font}' @ #{x}, #{y}, color: #{color}, etc. (TODO FILL THIS IN WITH METAPROGRAMMING)"} - cc = cairo_context - cc.set_source_color(color) - cc.move_to(x,y) - layout = cc.create_pango_layout - layout.font_description = Pango::FontDescription.new(font) - layout.text = str.to_s - layout.markup = str.to_s if markup - layout = setwh(layout, width, height) - layout = wrap(layout, wrap) - layout = ellipsize(layout, ellipsize) - layout = align(layout, align) - layout.justify = justify unless justify.nil? - layout.spacing = spacing * Pango::SCALE unless spacing.nil? - cc.update_pango_layout(layout) - valign(cc, layout, x,y, valign) - cc.update_pango_layout(layout) ; cc.show_pango_layout(layout) - draw_text_hint(x,y,layout,hint) + Squib.logger.debug {"Placing '#{str}'' with font '#{font}' @ #{x}, #{y}, color: #{color}, etc."} + use_cairo do |cc| + cc.set_source_color(color) + cc.move_to(x,y) + layout = cc.create_pango_layout + layout.font_description = Pango::FontDescription.new(font) + layout.text = str.to_s + layout.markup = str.to_s if markup + layout = setwh(layout, width, height) + layout = wrap(layout, wrap) + layout = ellipsize(layout, ellipsize) + layout = align(layout, align) + layout.justify = justify unless justify.nil? + layout.spacing = spacing * Pango::SCALE unless spacing.nil? + cc.update_pango_layout(layout) + valign(cc, layout, x,y, valign) + cc.update_pango_layout(layout) ; cc.show_pango_layout(layout) + draw_text_hint(x,y,layout,hint) + end end end diff --git a/samples/ball.png b/samples/ball.png new file mode 100644 index 0000000000000000000000000000000000000000..cf990bd108a84f103022c90ef7b4aa8b4ea982f1 GIT binary patch literal 1427 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