File: container.rb

package info (click to toggle)
ruby-rmagick 6.0.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,232 kB
  • sloc: cpp: 19,563; ruby: 17,147; sh: 88; javascript: 36; makefile: 13
file content (130 lines) | stat: -rw-r--r-- 4,006 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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
#--
# $Id: container.rb,v 1.5 2009/02/28 23:52:13 rmagick Exp $
# Copyright (C) 2009 Timothy P. Hunter
#++
module Magick
  class RVG
    # Content is simply an Array with a deep_copy method.
    # When unit-testing, it also has a deep_equal method.
    # @private
    class Content < Array
      def deep_copy(h = {})
        me = __id__
        copy = h[me]
        unless copy
          copy = self.class.new
          each do |c|
            copy << if c.nil?
                      nil
                    elsif c.respond_to?(:deep_copy)
                      c.deep_copy(h)
                    elsif c.respond_to?(:dup)
                      begin
                        c.dup
                      rescue StandardError
                        c
                      end
                    else
                      c
                    end
          end
          copy.freeze if frozen?
          h[me] = copy
        end
        copy
      end
    end # class Content

    # Define a collection of shapes, text, etc. that can be reused.
    # Group objects are _containers_. That is, styles and transforms defined
    # on the group are used by contained objects such as shapes, text, and
    # nested groups unless overridden by a nested container or the object itself.
    # Groups can be reused with the RVG::UseConstructors#use method.
    # Create groups within
    # containers with the RVG::StructureConstructors#g method.
    #
    # Example:
    #   # All elements in the group will be translated by 50 in the
    #   # x-direction and 10 in the y-direction.
    #   rvg.g.translate(50, 10).styles(:stroke=>'red',:fill=>'none') do |grp|
    #       # The line will be red.
    #       grp.line(10,10, 20,20)
    #       # The circle will be blue.
    #       grp.circle(10, 20, 20).styles(:stroke=>'blue')
    #   end
    class Group
      include Stylable
      include Transformable
      include Embellishable
      include Describable
      include Duplicatable

      def initialize
        super
        @content = Content.new
        yield(self) if block_given?
      end

      # @private
      def add_primitives(gc)
        gc.push
        add_transform_primitives(gc)
        add_style_primitives(gc)
        @content.each { |element| element.add_primitives(gc) }
        gc.pop
      end

      # Translate container according to #use arguments
      # @private
      def ref(x, y, _width, _height)
        translate(x, y) if x != 0 || y != 0
      end

      # Append an arbitrary object to the group's content. Called
      # by #use to insert a non-container object into a group.
      # @private
      def <<(obj)
        @content << obj
      end
    end # class Group

    # A Use object allows the re-use of RVG and RVG::Group
    # objects within a container. Create a Use object with the
    # RVG::UseConstructors#use method.
    class Use
      include Stylable
      include Transformable
      include Duplicatable

      # In a container, Use objects are created indirectly via the
      # RVG::UseConstructors#use method.
      # The +x+ and +y+ arguments
      # can be used to specify an additional translation for
      # the group. The +width+ and +height+ arguments specify
      # a width and height for referenced RVG objects.
      def initialize(element, x = 0, y = 0, width = nil, height = nil)
        super()

        # If the element is not a group, defs, symbol, or rvg,
        # wrap a group around it so it can get a transform and
        # possibly a new viewport.
        if element.respond_to?(:ref)
          @element = element.deep_copy
        else
          @element = Group.new
          @element << element.deep_copy
        end
        @element.ref(x, y, width, height)
      end

      # @private
      def add_primitives(gc)
        gc.push
        add_transform_primitives(gc)
        add_style_primitives(gc)
        @element.add_primitives(gc)
        gc.pop
      end
    end # class Use
  end # class RVG
end # module Magick