File: dash.rb

package info (click to toggle)
ruby-prawn 2.5.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,528 kB
  • sloc: ruby: 17,688; sh: 43; makefile: 20
file content (123 lines) | stat: -rw-r--r-- 3,684 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
# frozen_string_literal: true

module Prawn
  module Graphics
    # Implements stroke dashing.
    module Dash
      # @group Stable API

      # Get or set stroke dash pattern.
      #
      # @overload dash()
      #   Returns the current dash pattern.
      #
      #   @return [Hash{:dash => Number, Array<Number>, :space => Number, nil, :phase => Number}]
      #
      # @overload dash(length, options ={})
      #   Sets the dash pattern for stroked lines and curves.
      #
      #   Integers or Floats may be used for length and the option values.
      #   Dash units are in PDF points (1/72 inch).
      #
      #   @param length [Number, Array<Number>]
      #     * If `length` is a Number (Integer or Float), it specifies the
      #       length of the dash and of the gap. The length of the gap can be
      #       customized by setting the `:space` option.
      #
      #       Examples:
      #
      #       length = 3
      #       : 3 on, 3 off, 3 on, 3 off, ...
      #
      #       length = 3, :space = 2
      #       : 3 on, 2 off, 3 on, 2 off, ...
      #
      #     * If `length` is an array, it specifies the lengths of alternating
      #       dashes and gaps. The numbers must be non-negative and not all
      #       zero. The `:space` option is ignored in this case.
      #
      #       Examples:
      #
      #       length = [2, 1]
      #       : 2 on, 1 off, 2 on, 1 off, ...
      #
      #       length = [3, 1, 2, 3]
      #       : 3 on, 1 off, 2 on, 3 off, 3 on, 1 off, ...
      #
      #       length = [3, 0, 1]
      #       : 3 on, 0 off, 1 on, 3 off, 0 on, 1 off, ...
      #   @param options [Hash{Symbol => any}]
      #   @option options :space [Number]
      #     The space between the dashes (only used when `length` is not an
      #     array).
      #   @option options :phase [Number] (0)
      #     The distance into the dash pattern at which to start the dash. For
      #     example, a phase of 0 starts at the beginning of the dash; whereas,
      #     if the phase is equal to the length of the dash, then stroking will
      #     begin at the beginning of the space.
      #   @return [void]
      def dash(length = nil, options = {})
        return current_dash_state if length.nil?

        length = Array(length)

        if length.all?(&:zero?)
          raise ArgumentError,
            'Zero length dashes are invalid. Call #undash to disable dashes.'
        elsif length.any?(&:negative?)
          raise ArgumentError,
            'Negative numbers are not allowed for dash lengths.'
        end

        length = length.first if length.length == 1

        self.current_dash_state = {
          dash: length,
          space: length.is_a?(Array) ? nil : options[:space] || length,
          phase: options[:phase] || 0,
        }

        write_stroke_dash
      end

      alias dash= dash

      # Stops dashing, restoring solid stroked lines and curves.
      #
      # @return [void]
      def undash
        self.current_dash_state = undashed_setting
        write_stroke_dash
      end

      # Returns `true` when stroke is dashed, `false` otherwise.
      #
      # @return [Boolean]
      def dashed?
        current_dash_state != undashed_setting
      end

      private

      def write_stroke_dash
        renderer.add_content(dash_setting)
      end

      def undashed_setting
        { dash: nil, space: nil, phase: 0 }
      end

      def current_dash_state=(dash_options)
        graphic_state.dash = dash_options
      end

      def current_dash_state
        graphic_state.dash
      end

      def dash_setting
        graphic_state.dash_setting
      end
    end
  end
end