dyi 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/dyi/color.rb CHANGED
@@ -23,7 +23,7 @@ module DYI #:nodoc:
23
23
 
24
24
  class Color
25
25
  @@named_colors = {'aliceblue'=>[240,248,255],'antiquewhite'=>[250,235,215],'aqua'=>[0,255,255],'aquamarine'=>[127,255,212],'azure'=>[240,255,255],'beige'=>[245,245,220],'bisque'=>[255,228,196],'black'=>[0,0,0],'blanchedalmond'=>[255,235,205],'blue'=>[0,0,255],'blueviolet'=>[138,43,226],'brown'=>[165,42,42],'burlywood'=>[222,184,135],'cadetblue'=>[95,158,160],'chartreuse'=>[127,255,0],'chocolate'=>[210,105,30],'coral'=>[255,127,80],'cornflowerblue'=>[100,149,237],'cornsilk'=>[255,248,220],'crimson'=>[220,20,60],'cyan'=>[0,255,255],'darkblue'=>[0,0,139],'darkcyan'=>[0,139,139],'darkgoldenrod'=>[184,134,11],'darkgray'=>[169,169,169],'darkgreen'=>[0,100,0],'darkgrey'=>[169,169,169],'darkkhaki'=>[189,183,107],'darkmagenta'=>[139,0,139],'darkolivegreen'=>[85,107,47],'darkorange'=>[255,140,0],'darkorchid'=>[153,50,204],'darkred'=>[139,0,0],'darksalmon'=>[233,150,122],'darkseagreen'=>[143,188,143],'darkslateblue'=>[72,61,139],'darkslategray'=>[47,79,79],'darkslategrey'=>[47,79,79],'darkturquoise'=>[0,206,209],'darkviolet'=>[148,0,211],'deeppink'=>[255,20,147],'deepskyblue'=>[0,191,255],'dimgray'=>[105,105,105],'dimgrey'=>[105,105,105],'dodgerblue'=>[30,144,255],'firebrick'=>[178,34,34],'floralwhite'=>[255,250,240],'forestgreen'=>[34,139,34],'fuchsia'=>[255,0,255],'gainsboro'=>[220,220,220],'ghostwhite'=>[248,248,255],'gold'=>[255,215,0],'goldenrod'=>[218,165,32],'gray'=>[128,128,128],'grey'=>[128,128,128],'green'=>[0,128,0],'greenyellow'=>[173,255,47],'honeydew'=>[240,255,240],'hotpink'=>[255,105,180],'indianred'=>[205,92,92],'indigo'=>[75,0,130],'ivory'=>[255,255,240],'khaki'=>[240,230,140],'lavender'=>[230,230,250],'lavenderblush'=>[255,240,245],'lawngreen'=>[124,252,0],'lemonchiffon'=>[255,250,205],'lightblue'=>[173,216,230],'lightcoral'=>[240,128,128],'lightcyan'=>[224,255,255],'lightgoldenrodyellow'=>[250,250,210],'lightgray'=>[211,211,211],'lightgreen'=>[144,238,144],'lightgrey'=>[211,211,211],'lightpink'=>[255,182,193],'lightsalmon'=>[255,160,122],'lightseagreen'=>[32,178,170],'lightskyblue'=>[135,206,250],'lightslategray'=>[119,136,153],'lightslategrey'=>[119,136,153],'lightsteelblue'=>[176,196,222],'lightyellow'=>[255,255,224],'lime'=>[0,255,0],'limegreen'=>[50,205,50],'linen'=>[250,240,230],'magenta'=>[255,0,255],'maroon'=>[128,0,0],'mediumaquamarine'=>[102,205,170],'mediumblue'=>[0,0,205],'mediumorchid'=>[186,85,211],'mediumpurple'=>[147,112,219],'mediumseagreen'=>[60,179,113],'mediumslateblue'=>[123,104,238],'mediumspringgreen'=>[0,250,154],'mediumturquoise'=>[72,209,204],'mediumvioletred'=>[199,21,133],'midnightblue'=>[25,25,112],'mintcream'=>[245,255,250],'mistyrose'=>[255,228,225],'moccasin'=>[255,228,181],'navajowhite'=>[255,222,173],'navy'=>[0,0,128],'oldlace'=>[253,245,230],'olive'=>[128,128,0],'olivedrab'=>[107,142,35],'orange'=>[255,165,0],'orangered'=>[255,69,0],'orchid'=>[218,112,214],'palegoldenrod'=>[238,232,170],'palegreen'=>[152,251,152],'paleturquoise'=>[175,238,238],'palevioletred'=>[219,112,147],'papayawhip'=>[255,239,213],'peachpuff'=>[255,218,185],'peru'=>[205,133,63],'pink'=>[255,192,203],'plum'=>[221,160,221],'powderblue'=>[176,224,230],'purple'=>[128,0,128],'red'=>[255,0,0],'rosybrown'=>[188,143,143],'royalblue'=>[65,105,225],'saddlebrown'=>[139,69,19],'salmon'=>[250,128,114],'sandybrown'=>[244,164,96],'seagreen'=>[46,139,87],'seashell'=>[255,245,238],'sienna'=>[160,82,45],'silver'=>[192,192,192],'skyblue'=>[135,206,235],'slateblue'=>[106,90,205],'slategray'=>[112,128,144],'slategrey'=>[112,128,144],'snow'=>[255,250,250],'springgreen'=>[0,255,127],'steelblue'=>[70,130,180],'tan'=>[210,180,140],'teal'=>[0,128,128],'thistle'=>[216,191,216],'tomato'=>[255,99,71],'turquoise'=>[64,224,208],'violet'=>[238,130,238],'wheat'=>[245,222,179],'white'=>[255,255,255],'whitesmoke'=>[245,245,245],'yellow'=>[255,255,0],'yellowgreen'=>[154,205,50]}
26
- @@default_format = ['rgb(%d,%d,%d)', false]
26
+ @@default_format = ['#%02X%02X%02X', false]
27
27
  attr_reader :name
28
28
 
29
29
  # :call-seq:
data/lib/dyi/drawing.rb CHANGED
@@ -21,7 +21,6 @@
21
21
 
22
22
  %w(
23
23
 
24
- canvas
25
24
  pen
26
25
  pen_3d
27
26
  clipping
@@ -30,3 +29,11 @@ color_effect
30
29
  ).each do |file_name|
31
30
  require File.join(File.dirname(__FILE__), 'drawing', file_name)
32
31
  end
32
+
33
+ module DYI
34
+ module Drawing
35
+ # DYI::Drawing::Canvas is depricated; use DYI::Canvas
36
+ # @deprecated
37
+ Canvas = DYI::Canvas
38
+ end
39
+ end
@@ -22,15 +22,28 @@
22
22
  module DYI #:nodoc:
23
23
  module Drawing #:nodoc:
24
24
 
25
- class Clipping
25
+ class Clipping < Element
26
26
  RULES = ['nonzero', 'evenodd']
27
27
  attr_reader :rule, :shapes
28
+ attr_reader :canvas
28
29
 
29
30
  def initialize(*shapes)
30
31
  @shapes = shapes
31
32
  @rules = Array.new(shapes.size)
32
33
  end
33
34
 
35
+ def child_elements
36
+ @shapes
37
+ end
38
+
39
+ def set_canvas(canvas)
40
+ if @canvas.nil?
41
+ @canvas = canvas
42
+ elsif @canvas != canvas
43
+ raise Arguments, "the clipping is registered to another canvas"
44
+ end
45
+ end
46
+
34
47
  def add_shape(shape, rule=nil)
35
48
  raise ArgumentError, "\"#{rule}\" is invalid rule" if rule && !RULES.include?(rule)
36
49
  unless @shapes.include?(shape)
@@ -104,6 +104,16 @@ module DYI #:nodoc:
104
104
  Shape::Ellipse.create_on_center_radius(center_point, radius_x, radius_y, merge_option(options)).draw_on(canvas)
105
105
  end
106
106
 
107
+ # @since 1.0.0
108
+ def draw_image(canvas, left_top_point, width, height, file_path, options={})
109
+ Shape::Image.new(left_top_point, width, height, file_path, merge_option(options)).draw_on(canvas)
110
+ end
111
+
112
+ # @since 1.0.0
113
+ def import_image(canvas, left_top_point, width, height, image_uri, options={})
114
+ Shape::ImageReference.new(left_top_point, width, height, image_uri, merge_option(options)).draw_on(canvas)
115
+ end
116
+
107
117
  def draw_sector(canvas, center_point, radius_x, radius_y, start_angle, center_angle, options={})
108
118
  raise ArgumentError, "center_angle is out of range: #{center_angle}" if center_angle.abs > 360
109
119
  center_point = Coordinate.new(center_point)
@@ -142,7 +152,7 @@ module DYI #:nodoc:
142
152
  #:stopdoc:
143
153
  ALIAS_ATTRIBUTES =
144
154
  Painting::IMPLEMENT_ATTRIBUTES.inject({}) do |hash, key|
145
- hash[$'.empty? ? :color : $'.to_sym] = key if key.to_s =~ /^(stroke_|stroke$)/
155
+ hash[$'.empty? ? :color : $'.to_sym] = key if key.to_s =~ /^(stroke_|stroke$)/ && key != :stroke_opacity
146
156
  hash
147
157
  end
148
158
  #:startdoc:
@@ -193,7 +203,7 @@ module DYI #:nodoc:
193
203
  #:stopdoc:
194
204
  ALIAS_ATTRIBUTES =
195
205
  Painting::IMPLEMENT_ATTRIBUTES.inject({}) do |hash, key|
196
- hash[$'.empty? ? :color : $'.to_sym] = key if key.to_s =~ /^(fill_|fill$)/
206
+ hash[$'.empty? ? :color : $'.to_sym] = key if key.to_s =~ /^(fill_|fill$)/ && key != :fill_opacity
197
207
  hash
198
208
  end
199
209
  #:startdoc:
@@ -0,0 +1,167 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ # Copyright (c) 2009-2011 Sound-F Co., Ltd. All rights reserved.
4
+ #
5
+ # Author:: Mamoru Yuo
6
+ #
7
+ # This file is part of DYI.
8
+ #
9
+ # DYI is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # DYI is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with DYI. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+ # == Overview
23
+ #
24
+ # This file provides the DYI::Element class, which is abstract base class of
25
+ # DYI::Canvas and DYI::Shape::Base.
26
+ #
27
+ # @since 1.0.0
28
+
29
+ module DYI #:nodoc:
30
+
31
+ class Element
32
+ extend AttributeCreator
33
+ ID_REGEXP = /\A[:A-Z_a-z][\-\.0-9:A-Z_a-z]*\z/
34
+
35
+ # Returns id for the element. If the element has no id yet, makes id and
36
+ # returns it.
37
+ # @return [String] id for the element
38
+ def id
39
+ @id ||= canvas && canvas.publish_shape_id
40
+ end
41
+
42
+ alias publish_id id
43
+
44
+ # Returns id of the element. If the element has no id yet, returns nil.
45
+ # @return [String] id for the element if it has id, nil if not
46
+ def inner_id
47
+ @id
48
+ end
49
+
50
+ # Sets id for the element.
51
+ # @param [String] value id for the element
52
+ # @return [String] id that is given
53
+ # @raise [ArgumentError] value is empty or illegal format
54
+ def id=(value)
55
+ # TODO: veryfy that the id is unique.
56
+ raise ArgumentError, "`#{value}' is empty" if value.to_s.size == 0
57
+ raise ArgumentError, "`#{value}' is a illegal id" if value.to_s !~ ID_REGEXP
58
+ @id = value.to_s
59
+ end
60
+
61
+ # Returns the canvas where the shape is drawn
62
+ # @return [Canvas] the canvas where the shape is drawn
63
+ def canvas
64
+ current_node = self
65
+ loop do
66
+ return current_node if current_node.nil? || current_node.root_element?
67
+ current_node = current_node.parent
68
+ end
69
+ end
70
+
71
+ def child_elements
72
+ []
73
+ end
74
+
75
+ def include_external_file?
76
+ false
77
+ end
78
+
79
+ # @return [Boolean] whether the element has a URI reference
80
+ def has_uri_reference?
81
+ false
82
+ end
83
+ end
84
+
85
+ class GraphicalElement < Element
86
+ attr_reader :css_class
87
+ CLASS_REGEXP = /\A[A-Z_a-z][\-0-9A-Z_a-z]*\z/
88
+
89
+ def css_class=(css_class)
90
+ classes = css_class.to_s.split(/\s+/)
91
+ classes.each do |c|
92
+ if c.to_s !~ CLASS_REGEXP
93
+ raise ArgumentError, "`#{c}' is a illegal class-name"
94
+ end
95
+ end
96
+ @css_class = classes.join(' ')
97
+ end
98
+
99
+ def css_classes
100
+ css_class.split(/\s+/)
101
+ end
102
+
103
+ def add_css_class(css_class)
104
+ if css_class.to_s !~ CLASS_REGEXP
105
+ raise ArgumentError, "`#{css_class}' is a illegal class-name"
106
+ end
107
+ unless css_classes.include?(css_class.to_s)
108
+ @css_class += " #{css_class}"
109
+ css_class
110
+ end
111
+ nil
112
+ end
113
+
114
+ def remove_css_class(css_class)
115
+ classes = css_classes
116
+ if classes.delete(css_class.to_s)
117
+ @css_class = classes.join(' ')
118
+ css_class
119
+ else
120
+ nil
121
+ end
122
+ end
123
+
124
+ # Returns event listeners that is associated with the element
125
+ def event_listeners
126
+ @event_listeners ||= {}
127
+ end
128
+
129
+ # Adds a animation of painting to the element
130
+ # @param [Event] an event that is set to the element
131
+ # @return [void]
132
+ def set_event(event)
133
+ @events ||= []
134
+ @events << event
135
+ publish_id
136
+ end
137
+
138
+ # @return [Boolean] whether event is set to the element
139
+ def event_target?
140
+ !(@events.nil? || @events.empty?)
141
+ end
142
+
143
+ # Associates the element with a event listener
144
+ # @param [Symbol] event_name a event name
145
+ # @param [Script::SimpleScript|String] event_listener a event listener
146
+ # @return [void]
147
+ def add_event_listener(event_name, event_listener)
148
+ if event_listeners.key?(event_name)
149
+ unless event_listeners[event_name].include?(event_listener)
150
+ event_listeners[event_name] << event_listener
151
+ end
152
+ else
153
+ event_listeners[event_name] = [event_listener]
154
+ end
155
+ end
156
+
157
+ # Removes asociation with given event listener
158
+ # @param [Symbol] event_name a event name
159
+ # @param [Script::SimpleScript|String] event_listener a event listener
160
+ # @return [void]
161
+ def remove_event_listener(event_name, event_listener)
162
+ if event_listeners.key?(event_name)
163
+ event_listeners[event_name].delete(event_listener)
164
+ end
165
+ end
166
+ end
167
+ end
data/lib/dyi/event.rb ADDED
@@ -0,0 +1,148 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ # Copyright (c) 2009-2011 Sound-F Co., Ltd. All rights reserved.
4
+ #
5
+ # Author:: Mamoru Yuo
6
+ #
7
+ # This file is part of DYI.
8
+ #
9
+ # DYI is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # DYI is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with DYI. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+ # == Overview
23
+ #
24
+ # This file provides the DYI::Event class, which provides event supports for
25
+ # DYI. The event becomes effective only when it is output by SVG format.
26
+ #
27
+ # See the documentation to the DYI::Length class for more details and
28
+ # examples of usage.
29
+ #
30
+ # @since 1.0.0
31
+
32
+ module DYI
33
+
34
+ # Class representing a event. The event becomes effective only when it is
35
+ # output by SVG format.
36
+ class Event
37
+ IMPLEMENT_EVENTS = [:focusin,:focusout,:click,:mousedown,:mouseup,
38
+ :mouseover,:mousemove,:mouseout,:load]
39
+
40
+ # @return [Symbol] event name
41
+ attr_reader :event_name
42
+
43
+ # @return [GraphicalElement] an element to which the event applied
44
+ attr_reader :target
45
+
46
+ # @return [Array] a list of event listener
47
+ attr_reader :listeners
48
+
49
+ # @param [Symbol] event_name event name, one of followings: focusin,
50
+ # focusout, click, mousedown, mouseup, mouseover,
51
+ # mousemove, mouseout, load
52
+ # @param [GraphicalElement] target a element to which the event applied
53
+ # @raise [ArgumentError] unknown event name is given
54
+ def initialize(event_name, target)
55
+ event_name = event_name.to_sym
56
+ unless IMPLEMENT_EVENTS.include?(event_name)
57
+ raise ArgumentError, "`#{event_name}' is unknown event"
58
+ end
59
+ @event_name = event_name
60
+ @listeners = []
61
+ (@target = target).set_event(self)
62
+ end
63
+
64
+ # Sets a event listener.
65
+ # @param [Script::EcmaScript::EventListener] event_listener a script to be
66
+ # called when the event occurs
67
+ # @return [void]
68
+ def set_listener(event_listener)
69
+ target.add_event_listener(event_name, event_listener)
70
+ event_listener.related_to(self)
71
+ end
72
+
73
+ # Removes a event listener.
74
+ # @param [Script::EcmaScript::EventListener] event_listener a script that
75
+ # is removed
76
+ # @return [void]
77
+ def remove_listener(event_listener)
78
+ target.remove_event_listener(event_name, event_listener)
79
+ event_listener.unrelated_to(self)
80
+ end
81
+
82
+ class << self
83
+
84
+ # Creates a new focus-in event.
85
+ # @param target (see Event#initialize)
86
+ # @return [Event] a new focus-in event
87
+ def focusin(target)
88
+ new(:focusin, target)
89
+ end
90
+
91
+ # Creates a new focus-out event.
92
+ # @param target (see Event#initialize)
93
+ # @return [Event] a new focus-out event
94
+ def focusout(target)
95
+ new(:focusout, target)
96
+ end
97
+
98
+ # Creates a new click event.
99
+ # @param target (see Event#initialize)
100
+ # @return [Event] a new click event
101
+ def click(target)
102
+ new(:click, target)
103
+ end
104
+
105
+ # Creates a new mouse-down event.
106
+ # @param target (see Event#initialize)
107
+ # @return [Event] a new mouse-down event
108
+ def mousedown(target)
109
+ new(:mousedown, target)
110
+ end
111
+
112
+ # Creates a new mouse-up event.
113
+ # @param target (see Event#initialize)
114
+ # @return [Event] a new mouse-up event
115
+ def mouseup(target)
116
+ new(:mouseup, target)
117
+ end
118
+
119
+ # Creates a new mouse-over event.
120
+ # @param target (see Event#initialize)
121
+ # @return [Event] a new mouse-over event
122
+ def mouseover(target)
123
+ new(:mouseover, target)
124
+ end
125
+
126
+ # Creates a new mouse-move event.
127
+ # @param target (see Event#initialize)
128
+ # @return [Event] a new mouse-move event
129
+ def mousemove(target)
130
+ new(:mousemove, target)
131
+ end
132
+
133
+ # Creates a new mouse-out event.
134
+ # @param target (see Event#initialize)
135
+ # @return [Event] a new mouse-out event
136
+ def mouseout(target)
137
+ new(:mouseout, target)
138
+ end
139
+
140
+ # Creates a new load event.
141
+ # @param target (see Event#initialize)
142
+ # @return [Event] a new load event
143
+ def load(target)
144
+ new(:load, target)
145
+ end
146
+ end
147
+ end
148
+ end
@@ -75,6 +75,10 @@ module DYI #:nodoc:
75
75
  raise NotImplementedError
76
76
  end
77
77
 
78
+ # @since 1.0.0
79
+ def write_image(shape, io)
80
+ end
81
+
78
82
  def write_text(shape, io)
79
83
  raise NotImplementedError
80
84
  end
@@ -170,10 +174,28 @@ module DYI #:nodoc:
170
174
  @level = level
171
175
  end
172
176
 
173
- def instruction
177
+ def xml_instruction
174
178
  %Q{<?xml version="1.0" encoding="UTF-8"?>}
175
179
  end
176
180
 
181
+ def stylesheet_instruction(stylesheet)
182
+ styles = []
183
+ styles << '<?xml-stylesheet href="'
184
+ styles << stylesheet.href
185
+ styles << '" type="'
186
+ styles << stylesheet.content_type
187
+ if stylesheet.title
188
+ styles << '" title="'
189
+ styles << stylesheet.title
190
+ end
191
+ if stylesheet.media
192
+ styles << '" media="'
193
+ styles << stylesheet.media
194
+ end
195
+ styles << '"?>'
196
+ styles.join
197
+ end
198
+
177
199
  def generator_comment
178
200
  %Q{<!-- Create with DYI #{DYI::VERSION} (#{DYI::URL}) -->}
179
201
  end
@@ -183,8 +205,13 @@ module DYI #:nodoc:
183
205
  end
184
206
 
185
207
  def puts(io=$>)
186
- if @canvas.root_node?
187
- puts_line(io) {io << instruction}
208
+ if @canvas.root_element?
209
+ puts_line(io) {io << xml_instruction}
210
+ @canvas.stylesheets.each do |stylesheet|
211
+ if stylesheet.include_external_file?
212
+ puts_line(io) {io << stylesheet_instruction(stylesheet)}
213
+ end
214
+ end
188
215
  puts_line(io) {io << generator_comment}
189
216
  declaration.each_line do |dec|
190
217
  puts_line(io) {io << dec}
@@ -240,6 +267,19 @@ module DYI #:nodoc:
240
267
  ensure
241
268
  @level -= 1
242
269
  end
270
+
271
+ # @since 1.0.0
272
+ def create_cdata_node(io, tag_name, attributes={}, &block) #:nodoc:
273
+ puts_line(io) {
274
+ io << '<' << tag_name
275
+ attributes.each do |key, value|
276
+ io << ' ' << key << '="' << attr_escape(value) << '"'
277
+ end
278
+ io << '><![CDATA['
279
+ }
280
+ yield
281
+ puts_line(io) {io << ']]></' << tag_name << '>'}
282
+ end
243
283
  end
244
284
  end
245
285
  end