File: graphics_state.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 (136 lines) | stat: -rw-r--r-- 3,545 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
131
132
133
134
135
136
# encoding: utf-8
#
# graphics_state.rb: Implements graphics state saving and restoring
#
# Copyright January 2010, Michael Witrant. All Rights Reserved.
#
# This is free software. Please see the LICENSE and COPYING files for details.
#

module Prawn
  class GraphicStateStack
    attr_accessor :stack
    
    def initialize(previous_state = nil)
      self.stack = [GraphicState.new(previous_state)]
    end
    
    def save_graphic_state(graphic_state = nil)
      stack.push(GraphicState.new(graphic_state || current_state))
    end
    
    def restore_graphic_state
      if stack.empty?
        raise Prawn::Errors::EmptyGraphicStateStack, 
          "\n You have reached the end of the graphic state stack" 
      end
      stack.pop
    end
    
    def current_state
      stack.last
    end
    
    def present?
      stack.size > 0
    end

    def empty?
      stack.empty?
    end
      
  end
  
  class GraphicState
    attr_accessor :color_space, :dash, :cap_style, :join_style, :line_width, :fill_color, :stroke_color
    
    def initialize(previous_state = nil)
      @color_space = previous_state ? previous_state.color_space.dup : {}
      @fill_color = previous_state ? previous_state.fill_color : "000000"
      @stroke_color = previous_state ? previous_state.stroke_color : "000000"
      @dash = previous_state ? previous_state.dash : { :dash => nil, :space => nil, :phase => 0 }
      @cap_style = previous_state ? previous_state.cap_style : :butt
      @join_style = previous_state ? previous_state.join_style : :miter
      @line_width = previous_state ? previous_state.line_width : 1
    end
    
    def dash_setting
      "[#{@dash[:dash]} #{@dash[:space]}] #{@dash[:phase]} d"
    end
  end
  
  module Core
    class Page
      module GraphicsState
      
        def graphic_state
          stack.current_state
        end
    
      end
    end
  end
  
  class Document
    module GraphicsState

      # Pushes the current graphics state on to the graphics state stack so we
      # can restore it when finished with a change we want to isolate (such as
      # modifying the transformation matrix). Used in pairs with
      # restore_graphics_state or passed a block
      #
      # Example without a block:
      #
      #   save_graphics_state
      #   rotate 30
      #   text "rotated text"
      #   restore_graphics_state
      #
      # Example with a block:
      #
      #   save_graphics_state do
      #     rotate 30
      #     text "rotated text"
      #   end
      #
      
      def open_graphics_state
        add_content "q"
      end
      
      def close_graphics_state
        add_content "Q"
      end
        
      def save_graphics_state(graphic_state = nil)
        graphic_stack.save_graphic_state(graphic_state)
        open_graphics_state
        if block_given?
          yield
          restore_graphics_state
        end
      end

      # Pops the last saved graphics state off the graphics state stack and
      # restores the state to those values
      def restore_graphics_state
        if graphic_stack.empty?
          raise Prawn::Errors::EmptyGraphicStateStack, 
            "\n You have reached the end of the graphic state stack" 
        end
        close_graphics_state 
        graphic_stack.restore_graphic_state
      end
      
      def graphic_stack
        state.page.stack
      end
      
      def graphic_state
        save_graphics_state unless graphic_stack.current_state
        graphic_stack.current_state 
      end
      
    end
  end
end