File: gradient.rb

package info (click to toggle)
ruby-prawn 1.0.0~rc1%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,248 kB
  • sloc: ruby: 17,499; sh: 44; makefile: 17
file content (84 lines) | stat: -rw-r--r-- 2,611 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# encoding: utf-8

# gradient.rb : Implements axial gradient
#
# Contributed by Wojciech Piekutowski. November, 2009
#
# This is free software. Please see the LICENSE and COPYING files for details.
#
module Prawn
  module Graphics
    module Gradient
      # Sets the fill gradient from color1 to color2.
      #
      # It accepts CMYK and RGB colors, like #fill_color. Both colors must be
      # of the same type.
      #
      # point, width and height define a bounding box in which the gradient
      # will be rendered. For example, if you want to have page full of text
      # with gradually changing color:
      #
      #   pdf.fill_gradient [0, pdf.bounds.height], pdf.bounds.width,
      #     pdf.bounds.height, 'FF0000', '0000FF'
      #   pdf.text 'lots of text'*1000
      #
      # <tt>:stroke_bounds</tt> - draw gradient bounds
      def fill_gradient(point, width, height, color1, color2, options = {})
        set_gradient(:fill, point, width, height, color1, color2, options)
      end

      # Sets the stroke gradient from color1 to color2.
      #
      # See #fill_gradient for details.
      def stroke_gradient(point, width, height, color1, color2, options = {})
        set_gradient(:stroke, point, width, height, color1, color2, options)
      end

      private

      def set_gradient(type, point, width, height, color1, color2, options)
        if options[:stroke_bounds]
          stroke_color 0, 0, 0, 100
          stroke_rectangle point, width, height
        end

        if color_type(color1) != color_type(color2)
          raise ArgumentError, 'both colors must be of the same type: RGB or CMYK'
        end

        process_color color1
        process_color color2

        shader = ref!({
          :FunctionType => 2,
          :Domain => [0.0, 1.0],
          :C0 => normalize_color(color1),
          :C1 => normalize_color(color2),
          :N => 1,
        })

        shading = ref!({
          :ShadingType => 2, # axial shading
          :ColorSpace => color_type(color1) == :RGB ? :DeviceRGB : :DeviceCMYK,
          :Coords => [0.0, 0.0, 1.0, 0.0],
          :Function => shader,
          :Extend => [true, true],
        })

        x, y = *point
        shading_pattern = ref!({
          :PatternType => 2, # shading pattern
          :Shading => shading,
          :Matrix => [0,-height, -width, 0, x, y],
        })

        patterns = page.resources[:Pattern] ||= {}
        id = patterns.empty? ? 'SP1' : patterns.keys.sort.last.succ
        patterns[id] = shading_pattern

        set_color type, id, :pattern => true
      end
    end
  end
end