Module: Compass::Magick::Functions::Drawing

Included in:
Compass::Magick::Functions
Defined in:
lib/magick/functions/drawing.rb

Overview

Methods for drawing on a Canvas.

Instance Method Summary collapse

Instance Method Details

#magick_border(type, radius = nil, width = nil, top_left = nil, top_right = nil, bottom_right = nil, bottom_left = nil) ⇒ Command

Draws a (rounded) border around the Canvas with the given width and fill Type.

When width is not given, the border fills the entire image.

Parameters:

  • type (Object)

    The type of fill to apply. Supported:

  • radius (Sass::Script::Number) (defaults to: nil)

    The border radius.

  • will (Sass::Script::Number)

    The border width, defaults to filling the entire image.

  • top_left (Sass::Script::Bool) (defaults to: nil)

    Controls the top-left border radius effect (default true)

  • top_right (Sass::Script::Bool) (defaults to: nil)

    Controls the top-right border radius effect (default true)

  • bottom_right (Sass::Script::Bool) (defaults to: nil)

    Controls the bottom-right border radius effect (default true)

  • bottom_left (Sass::Script::Bool) (defaults to: nil)

    Controls the bottom-left border radius effect (default true)

Returns:

  • (Command)

    A command(-set) which composes the border on the canvas.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/magick/functions/drawing.rb', line 103

def magick_border(type, radius = nil, width = nil, top_left = nil, top_right = nil, bottom_right = nil, bottom_left = nil)
  Compass::Magick::Utils.assert_type 'radius',       radius,       Sass::Script::Number
  Compass::Magick::Utils.assert_type 'width',        width,        Sass::Script::Number
  Compass::Magick::Utils.assert_type 'top_left',     top_left,     Sass::Script::Bool
  Compass::Magick::Utils.assert_type 'top_right',    top_right,    Sass::Script::Bool
  Compass::Magick::Utils.assert_type 'bottom_left',  bottom_left,  Sass::Script::Bool
  Compass::Magick::Utils.assert_type 'bottom_right', bottom_right, Sass::Script::Bool
  Command.new do |canvas|
    max = [canvas.width, canvas.height].max
    min = [canvas.width, canvas.height].min
    border_width  = Compass::Magick::Utils.value_of(width,  max, max)
    border_radius = Compass::Magick::Utils.value_of(radius, min, 10)
    border_top_left     = (top_left.nil?     || top_left.value)
    border_top_right    = (top_right.nil?    || top_right.value)
    border_bottom_right = (bottom_right.nil? || bottom_right.value)
    border_bottom_left  = (bottom_left.nil?  || bottom_left.value)
    right_x  = canvas.width  - border_radius
    bottom_y = canvas.height - border_radius
    mask = ChunkyPNG::Canvas.new(canvas.width, canvas.height, ChunkyPNG::Color.rgba(0, 0, 0, 0))
    for y in 0...canvas.height
      for x in 0...canvas.width
        unless (border_top_left     && (y < border_radius && x < border_radius)) ||
               (border_top_right    && (y < border_radius && x > right_x))       ||
               (border_bottom_right && (y > bottom_y && x > right_x))            ||
               (border_bottom_left  && (y > bottom_y && x < border_radius))
          if y < border_width || y >= canvas.height - border_width ||
             x < border_width || x >= canvas.width - border_width
            mask.set_pixel(x, y, ChunkyPNG::Color::WHITE)
          end
        end
      end
    end
    if border_radius > 0
      radius_mask = Compass::Magick::Shapes.circle(border_radius * 2, border_width)
      if border_top_left
        mask.compose!(radius_mask.crop(0, 0, border_radius, border_radius), 0, 0)
      end
      if border_top_right
        mask.compose!(radius_mask.crop(border_radius, 0, border_radius, border_radius), mask.width - border_radius, 0)
      end
      if border_bottom_right
        mask.compose!(radius_mask.crop(border_radius, border_radius, border_radius, border_radius), mask.width - border_radius, mask.height - border_radius)
      end
      if border_bottom_left
        mask.compose!(radius_mask.crop(0, border_radius, border_radius, border_radius), 0, mask.height - border_radius)
      end
    end
    overlay = Compass::Magick::Utils.to_canvas(type, Sass::Script::Number.new(canvas.width), Sass::Script::Number.new(canvas.height))
    Compass::Magick::Canvas.new(canvas, magick_compose(Compass::Magick::Canvas.new(overlay, magick_mask(mask))))
  end
end

#magick_circle(type, radius, compose_x, compose_y, feather = nil) ⇒ Command

Draws a circle on the Canvas with the given fill Type.

The X and Y coordinates are not the center of the circle, but rather the coordinates at which the circle is composed on top of the Canvas. E.g., 100%, 100% would put the circle at the bottom-right corner of the Canvas.

Parameters:

  • type (Object)

    The type of fill to apply. Supported:

  • radius (Sass::Script::Number)

    The radius of the circle.

  • x (Sass::Script::Number)

    The composite X coordinate of the circle.

  • y (Sass::Script::Number)

    The composite Y coordinate of the circle.

  • feather (Sass::Script::Number) (defaults to: nil)

    The feater value determines the anti-aliasing the circle will get, defaults to 1.

Returns:

  • (Command)

    A command(-set) which composes a circle on the canvas.



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/magick/functions/drawing.rb', line 68

def magick_circle(type, radius, compose_x, compose_y, feather = nil)
  Compass::Magick::Utils.assert_type 'radius',   radius,   Sass::Script::Number
  Compass::Magick::Utils.assert_type 'feather',  feather,  Sass::Script::Number
  Command.new do |canvas|
    circle_radius  = Compass::Magick::Utils.value_of(radius,  [canvas.width, canvas.height].min, 1)
    circle_feather = Compass::Magick::Utils.value_of(feather, [canvas.width, canvas.height].min, 1).to_f
    mask    = Compass::Magick::Shapes.circle(circle_radius, circle_radius, circle_feather)
    overlay = Compass::Magick::Utils.to_canvas(type, Sass::Script::Number.new(circle_radius), Sass::Script::Number.new(circle_radius))
    Compass::Magick::Canvas.new(canvas, magick_compose(Compass::Magick::Canvas.new(overlay, magick_mask(mask)), compose_x, compose_y))
  end
end

#magick_fill(type, x1 = nil, y1 = nil, x2 = nil, y2 = nil) ⇒ Command

Fills the Canvas region with the given Type.

Parameters:

  • type (Object)

    The type of fill to apply. Supported:

  • x1 (Sass::Script::Number) (defaults to: nil)

    The left coordinate of the fill.

  • y1 (Sass::Script::Number) (defaults to: nil)

    The top coordinate of the fill.

  • x2 (Sass::Script::Number) (defaults to: nil)

    The right coordinate of the fill.

  • y2 (Sass::Script::Number) (defaults to: nil)

    The bottom coordinate of the fill.

Returns:

  • (Command)

    A command which applies the fill on the canvas.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/magick/functions/drawing.rb', line 17

def magick_fill(type, x1 = nil, y1 = nil, x2 = nil, y2 = nil)
  Compass::Magick::Utils.assert_type 'x1', x1, Sass::Script::Number
  Compass::Magick::Utils.assert_type 'y1', y1, Sass::Script::Number
  Compass::Magick::Utils.assert_type 'x2', x2, Sass::Script::Number
  Compass::Magick::Utils.assert_type 'y2', y2, Sass::Script::Number
  Command.new do |canvas|
    canvas_x1 = Compass::Magick::Utils.value_of(x1, canvas.width,  0)
    canvas_y1 = Compass::Magick::Utils.value_of(y1, canvas.height, 0)
    canvas_x2 = Compass::Magick::Utils.value_of(x2, canvas.width,  canvas.width)
    canvas_y2 = Compass::Magick::Utils.value_of(y2, canvas.height, canvas.height)
    canvas_x1, canvas_x2 = canvas_x2, canvas_x1 if canvas_x1 > canvas_x2
    canvas_y1, canvas_y2 = canvas_y2, canvas_y1 if canvas_y1 > canvas_y2
    width     = Sass::Script::Number.new(canvas_x2 - canvas_x1)
    height    = Sass::Script::Number.new(canvas_y2 - canvas_y1)
    top       = type
    tail      = []
    if top.kind_of?(Sass::Script::List)
      tail = top.value
      top  = tail.shift
    end
    overlay = Compass::Magick::Utils.to_canvas(top, width, height)
    tail.each do |mask_type|
      mask_canvas = Compass::Magick::Utils.to_canvas(mask_type, width, height)
      overlay     = Compass::Magick::Canvas.new(overlay, magick_mask(mask_canvas))
    end
    canvas.compose(overlay, canvas_x1, canvas_y1)
  end
end