dyi 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +22 -16
- data/lib/dyi.rb +7 -3
- data/lib/dyi/canvas.rb +118 -21
- data/lib/dyi/chart/array_reader.rb +12 -2
- data/lib/dyi/chart/base.rb +0 -3
- data/lib/dyi/chart/csv_reader.rb +49 -6
- data/lib/dyi/element.rb +53 -19
- data/lib/dyi/event.rb +0 -2
- data/lib/dyi/formatter/svg_formatter.rb +68 -4
- data/lib/dyi/script/ecmascript.rb +64 -3
- data/lib/dyi/script/simple_script.rb +0 -1
- data/lib/dyi/shape/base.rb +152 -35
- data/lib/dyi/stylesheet.rb +0 -1
- data/lib/ironruby.rb +18 -17
- data/lib/util.rb +16 -0
- metadata +6 -6
data/lib/dyi/element.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: UTF-8 -*-
|
2
2
|
|
3
|
-
# Copyright (c) 2009-
|
3
|
+
# Copyright (c) 2009-2012 Sound-F Co., Ltd. All rights reserved.
|
4
4
|
#
|
5
5
|
# Author:: Mamoru Yuo
|
6
6
|
#
|
@@ -18,20 +18,26 @@
|
|
18
18
|
#
|
19
19
|
# You should have received a copy of the GNU General Public License
|
20
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
21
|
|
29
|
-
module DYI
|
22
|
+
module DYI
|
30
23
|
|
24
|
+
# Abstract class that represents a element contained in the image.
|
25
|
+
# @abstract
|
26
|
+
# @since 1.0.0
|
31
27
|
class Element
|
32
28
|
extend AttributeCreator
|
33
29
|
ID_REGEXP = /\A[:A-Z_a-z][\-\.0-9:A-Z_a-z]*\z/
|
34
30
|
|
31
|
+
# Returns a title of the element.
|
32
|
+
# @return [String] a title of the element
|
33
|
+
# @since 1.1.1
|
34
|
+
attr_accessor :title
|
35
|
+
|
36
|
+
# Returns a description of the element.
|
37
|
+
# @return [String] a description of the element
|
38
|
+
# @since 1.1.1
|
39
|
+
attr_accessor :description
|
40
|
+
|
35
41
|
# Returns id for the element. If the element has no id yet, makes id and
|
36
42
|
# returns it.
|
37
43
|
# @return [String] id for the element
|
@@ -58,7 +64,7 @@ module DYI #:nodoc:
|
|
58
64
|
@id = value.to_s
|
59
65
|
end
|
60
66
|
|
61
|
-
# Returns the canvas where the shape is drawn
|
67
|
+
# Returns the canvas where the shape is drawn.
|
62
68
|
# @return [Canvas] the canvas where the shape is drawn
|
63
69
|
def canvas
|
64
70
|
current_node = self
|
@@ -68,24 +74,41 @@ module DYI #:nodoc:
|
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
77
|
+
# Returns an array of child elements.
|
78
|
+
# @return [Array<Element>] an empty array
|
71
79
|
def child_elements
|
72
80
|
[]
|
73
81
|
end
|
74
82
|
|
83
|
+
# Returns whether the element has reference of external file.
|
84
|
+
# @return [Boolean] always false
|
75
85
|
def include_external_file?
|
76
86
|
false
|
77
87
|
end
|
78
88
|
|
79
|
-
#
|
89
|
+
# Returns whether the element has URI reference.
|
90
|
+
# @return [Boolean] always false
|
80
91
|
def has_uri_reference?
|
81
92
|
false
|
82
93
|
end
|
83
94
|
end
|
84
95
|
|
96
|
+
# Abstract class that represents a graphic element.
|
97
|
+
# @abstract
|
98
|
+
# @since 1.0.0
|
85
99
|
class GraphicalElement < Element
|
100
|
+
|
101
|
+
# Returns a CSS class attribute of the element.
|
102
|
+
# @return [String] a class name or set of class names. If the elements has
|
103
|
+
# multiple class names, class names are separated by white space
|
86
104
|
attr_reader :css_class
|
105
|
+
|
87
106
|
CLASS_REGEXP = /\A[A-Z_a-z][\-0-9A-Z_a-z]*\z/
|
88
107
|
|
108
|
+
# Sets a CSS class attribute.
|
109
|
+
# @param [String] css_class a CSS class attribute
|
110
|
+
# @see {#css_class}
|
111
|
+
# @raise [ArgumentError] parameter `css_class' is illegal class name
|
89
112
|
def css_class=(css_class)
|
90
113
|
return @css_class = nil if css_class.nil?
|
91
114
|
classes = css_class.to_s.split(/\s+/)
|
@@ -97,10 +120,17 @@ module DYI #:nodoc:
|
|
97
120
|
@css_class = classes.join(' ')
|
98
121
|
end
|
99
122
|
|
123
|
+
# Returns an array of CSS class names.
|
124
|
+
# @return [Array<String>] an array of CSS class names
|
100
125
|
def css_classes
|
101
126
|
css_class.to_s.split(/\s+/)
|
102
127
|
end
|
103
128
|
|
129
|
+
# Adds a CSS class.
|
130
|
+
# @param [String] css_class a CSS class name
|
131
|
+
# @return [String, nil] value of parameter `css_class' if successes to add
|
132
|
+
# a class, nil if failures
|
133
|
+
# @raise [ArgumentError] parameter `css_class' is illegal class name
|
104
134
|
def add_css_class(css_class)
|
105
135
|
if css_class.to_s !~ CLASS_REGEXP
|
106
136
|
raise ArgumentError, "`#{css_class}' is a illegal class-name"
|
@@ -112,6 +142,10 @@ module DYI #:nodoc:
|
|
112
142
|
css_class
|
113
143
|
end
|
114
144
|
|
145
|
+
# Remove a CSS class.
|
146
|
+
# @param [String] css_class a CSS class name that will be removed
|
147
|
+
# @return [String, nil] value of parameter `css_class' if successes to
|
148
|
+
# remove a class, nil if failures
|
115
149
|
def remove_css_class(css_class)
|
116
150
|
classes = css_classes
|
117
151
|
if classes.delete(css_class.to_s)
|
@@ -122,29 +156,30 @@ module DYI #:nodoc:
|
|
122
156
|
end
|
123
157
|
end
|
124
158
|
|
125
|
-
# Returns event listeners that is associated with the element
|
159
|
+
# Returns event listeners that is associated with the element.
|
160
|
+
# @return [Hash] hash of event listeners
|
126
161
|
def event_listeners
|
127
162
|
@event_listeners ||= {}
|
128
163
|
end
|
129
164
|
|
130
|
-
# Adds a animation of painting to the element
|
131
|
-
# @param [Event] an event that is set to the element
|
132
|
-
# @return [
|
165
|
+
# Adds a animation of painting to the element.
|
166
|
+
# @param [Event] event an event that is set to the element
|
167
|
+
# @return [String] id for this element
|
133
168
|
def set_event(event)
|
134
169
|
@events ||= []
|
135
170
|
@events << event
|
136
171
|
publish_id
|
137
172
|
end
|
138
173
|
|
139
|
-
#
|
174
|
+
# Returns whether an event is set to the element.
|
175
|
+
# @return [Boolean] true if an event is set to the element, false otherwise
|
140
176
|
def event_target?
|
141
177
|
!(@events.nil? || @events.empty?)
|
142
178
|
end
|
143
179
|
|
144
|
-
# Associates the element with a event listener
|
180
|
+
# Associates the element with a event listener.
|
145
181
|
# @param [Symbol] event_name a event name
|
146
182
|
# @param [Script::SimpleScript] event_listener a event listener
|
147
|
-
# @return [void]
|
148
183
|
def add_event_listener(event_name, event_listener)
|
149
184
|
event_listener.related_to(DYI::Event.new(event_name, self))
|
150
185
|
if event_listeners.key?(event_name)
|
@@ -161,7 +196,6 @@ module DYI #:nodoc:
|
|
161
196
|
# Removes asociation with given event listener
|
162
197
|
# @param [Symbol] event_name a event name
|
163
198
|
# @param [Script::SimpleScript] event_listener a event listener
|
164
|
-
# @return [void]
|
165
199
|
def remove_event_listener(event_name, event_listener)
|
166
200
|
if event_listeners.key?(event_name)
|
167
201
|
event_listeners[event_name].delete(event_listener)
|
data/lib/dyi/event.rb
CHANGED
@@ -60,7 +60,6 @@ module DYI
|
|
60
60
|
# Sets a event listener.
|
61
61
|
# @param [Script::EcmaScript::EventListener] event_listener a script to be
|
62
62
|
# called when the event occurs
|
63
|
-
# @return [void]
|
64
63
|
def set_listener(event_listener)
|
65
64
|
target.add_event_listener(event_name, event_listener)
|
66
65
|
event_listener.related_to(self)
|
@@ -69,7 +68,6 @@ module DYI
|
|
69
68
|
# Removes a event listener.
|
70
69
|
# @param [Script::EcmaScript::EventListener] event_listener a script that
|
71
70
|
# is removed
|
72
|
-
# @return [void]
|
73
71
|
def remove_listener(event_listener)
|
74
72
|
target.remove_event_listener(event_name, event_listener)
|
75
73
|
event_listener.unrelated_to(self)
|
@@ -27,7 +27,7 @@ module DYI #:nodoc:
|
|
27
27
|
class SvgFormatter < XmlFormatter
|
28
28
|
|
29
29
|
def initialize(canvas, options={})
|
30
|
-
super
|
30
|
+
super
|
31
31
|
version = options[:version] || '1.1'
|
32
32
|
unless ['1.0', '1.1'].include?(@version = version.to_s)
|
33
33
|
raise ArgumentError, "version `#{version}' is unknown version"
|
@@ -79,6 +79,15 @@ module DYI #:nodoc:
|
|
79
79
|
end
|
80
80
|
sio = StringIO.new
|
81
81
|
create_node(sio, 'svg', attrs) {
|
82
|
+
create_leaf_node(sio, 'title', canvas.title) if canvas.title
|
83
|
+
create_leaf_node(sio, 'desc', canvas.description) if canvas.description
|
84
|
+
if canvas.metadata
|
85
|
+
create_cdata_node(sio, 'metadata'){
|
86
|
+
puts_line(sio) {
|
87
|
+
write_metadata(canvas.metadata, sio)
|
88
|
+
}
|
89
|
+
}
|
90
|
+
end
|
82
91
|
@root_info = [sio.pos, @level]
|
83
92
|
i = 0
|
84
93
|
length = canvas.scripts.size
|
@@ -433,8 +442,10 @@ module DYI #:nodoc:
|
|
433
442
|
|
434
443
|
# @since 1.0.0
|
435
444
|
def write_shape_node(shape, io, attrs, tag_name, &create_child_node)
|
436
|
-
if shape.animate? || block_given?
|
445
|
+
if shape.title || shape.description || shape.animate? || block_given?
|
437
446
|
create_node(io, tag_name, attrs) {
|
447
|
+
create_leaf_node(io, 'title', shape.title) if shape.title
|
448
|
+
create_leaf_node(io, 'desc', shape.description) if shape.description
|
438
449
|
yield if block_given?
|
439
450
|
write_animations(shape, io)
|
440
451
|
}
|
@@ -452,6 +463,61 @@ module DYI #:nodoc:
|
|
452
463
|
end
|
453
464
|
end
|
454
465
|
|
466
|
+
# @since 1.1.1
|
467
|
+
def write_metadata(metadata, io)
|
468
|
+
case metadata
|
469
|
+
when String, Symbol
|
470
|
+
io << '"'
|
471
|
+
metadata.to_s.unpack('U*').each do |c|
|
472
|
+
case c
|
473
|
+
when 0x08 then io << '\\b' # backspace
|
474
|
+
when 0x09 then io << '\\t' # horizontal tab
|
475
|
+
when 0x0a then io << '\\n' # line feed
|
476
|
+
when 0x0c then io << '\\f' # form feed
|
477
|
+
when 0x0d then io << '\\r' # carriage return
|
478
|
+
when 0x22 then io << '\\"' # double quote
|
479
|
+
when 0x5c then io << '\\\\' # backslash
|
480
|
+
when (0x20..0x7e) then io << c.chr
|
481
|
+
else io << '\\u' << ('%04X' % c)
|
482
|
+
end
|
483
|
+
end
|
484
|
+
io << '"'
|
485
|
+
when Integer, TrueClass, FalseClass
|
486
|
+
io << metadata.inspect
|
487
|
+
when NilClass
|
488
|
+
io << 'null'
|
489
|
+
when Numeric
|
490
|
+
io << metadata.to_f.to_s
|
491
|
+
when Hash
|
492
|
+
io << '{'
|
493
|
+
metadata.keys.each_with_index do |key, i|
|
494
|
+
io << ',' unless i == 0
|
495
|
+
write_metadata(key.to_s, io)
|
496
|
+
io << ':'
|
497
|
+
write_metadata(metadata[key], io)
|
498
|
+
end
|
499
|
+
io << '}'
|
500
|
+
when Struct
|
501
|
+
io << '{'
|
502
|
+
metadata.members.each_with_index do |key, i|
|
503
|
+
io << ',' unless i == 0
|
504
|
+
write_metadata(key.to_s, io)
|
505
|
+
io << ':'
|
506
|
+
write_metadata(metadata.__send__(key), io)
|
507
|
+
end
|
508
|
+
io << '}'
|
509
|
+
when Enumerable
|
510
|
+
io << '['
|
511
|
+
metadata.each_with_index do |value, i|
|
512
|
+
io << ',' unless i == 0
|
513
|
+
write_metadata(value, io)
|
514
|
+
end
|
515
|
+
io << ']'
|
516
|
+
else
|
517
|
+
write_metadata(metadata.to_s, io)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
455
521
|
# @since 1.0.0
|
456
522
|
def create_border_node(shape, io)
|
457
523
|
if shape.attributes[:show_border]
|
@@ -467,7 +533,6 @@ module DYI #:nodoc:
|
|
467
533
|
|
468
534
|
# Examines the descendant elements of the canvas to collect the
|
469
535
|
# information of the elements.
|
470
|
-
# @return [void]
|
471
536
|
# @since 1.0.0
|
472
537
|
def pre_write
|
473
538
|
if @canvas.scripts.any?{|script| script.has_uri_reference?}
|
@@ -526,7 +591,6 @@ module DYI #:nodoc:
|
|
526
591
|
[amin_event(shape, event), anim_duration(offset)].compact.join('+')
|
527
592
|
end
|
528
593
|
|
529
|
-
# @return [void]
|
530
594
|
# @since 1.0.0
|
531
595
|
def merge_anim_attributes(anim, shape, attrs) #:nodoc:
|
532
596
|
attrs[:dur] = anim_duration(anim.duration) if anim.duration && anim.duration != 0
|
@@ -35,6 +35,42 @@ module DYI
|
|
35
35
|
# This Module includes helper methods for generating a client-script.
|
36
36
|
# These methods generate a script that conforms to DOM Level 2 (W3C
|
37
37
|
# Recommendation).
|
38
|
+
#
|
39
|
+
# All the methods defined by the module are `module functions', which are
|
40
|
+
# called as private instance methods and are also called as public class
|
41
|
+
# methods (they are methods of Math Module like).
|
42
|
+
# In the following example, +get_element+ method is called as a
|
43
|
+
# private instance method.
|
44
|
+
# class Foo
|
45
|
+
# include DYI::Script::EcmaScript::DomLevel2
|
46
|
+
# def bar
|
47
|
+
# puts get_element('el_id') # => "document.getElementById(\"el_id\")"
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
# At the toplevel, it is able to include the module.
|
51
|
+
# include DYI::Script::EcmaScript::DomLevel2
|
52
|
+
# puts get_element('el_id') # => "document.getElementById(\"el_id\")"
|
53
|
+
# In the Next example, +get_element+ method is called as a public class
|
54
|
+
# method.
|
55
|
+
# puts DYI::Script::EcmaScript::DomLevel2.get_element('el_id')
|
56
|
+
# # => "document.getElementById(\"el_id\")"
|
57
|
+
#
|
58
|
+
#= Module Function List
|
59
|
+
#
|
60
|
+
# {#add_event_listener}, {#draw_text_border}, {#form_legend_labels},
|
61
|
+
# {#get_attribute}, {#get_element}, {#metadata_parse_json},
|
62
|
+
# {#rewrite_text}, {#set_attribute}, {#to_ecmascript_string}
|
63
|
+
#
|
64
|
+
# {render:#add_event_listener}
|
65
|
+
# {render:#dispatch_evnet}
|
66
|
+
# {render:#draw_text_border}
|
67
|
+
# {render:#form_legend_labels}
|
68
|
+
# {render:#get_attribute}
|
69
|
+
# {render:#get_element}
|
70
|
+
# {render:#metadata_parse_json}
|
71
|
+
# {render:#rewrite_text}
|
72
|
+
# {render:#set_attribute}
|
73
|
+
# {render:#to_ecmascript_string}
|
38
74
|
module DomLevel2
|
39
75
|
|
40
76
|
private
|
@@ -62,6 +98,33 @@ module DYI
|
|
62
98
|
parts.join
|
63
99
|
end
|
64
100
|
|
101
|
+
# Returns an ECMAScript value of a metadata that this image has.
|
102
|
+
# @return [String] a string that means
|
103
|
+
# @since 1.1.1
|
104
|
+
# @api function
|
105
|
+
def metadata_parse_json
|
106
|
+
=begin
|
107
|
+
script =<<-EOS
|
108
|
+
(function() {
|
109
|
+
var metadata_element = document.getElementsByTagName("metadata").item(0);
|
110
|
+
if(metadata_element == null)
|
111
|
+
return null;
|
112
|
+
var metadata_contents = [];
|
113
|
+
for(var i=0, length=metadata_element.childNodes.length; i<length; i++) {
|
114
|
+
var child = metadata_element.childNodes.item(i);
|
115
|
+
if(child.nodeType!=3&&child.nodeType!=4)
|
116
|
+
return null;
|
117
|
+
metadata_contents.push(child.data);
|
118
|
+
}
|
119
|
+
if(metadata_contents.length == 0)
|
120
|
+
return null;
|
121
|
+
return JSON.parse(metadata_contents.join(""));
|
122
|
+
})()
|
123
|
+
EOS
|
124
|
+
=end
|
125
|
+
'(function(){var a=document.getElementsByTagName("metadata").item(0);if(a==null)return null;var b=[];for(var c=0,d=a.childNodes.length;c<d;c++){var e=a.childNodes.item(c);if(e.nodeType!=3&&e.nodeType!=4)return null;b.push(e.data);}if(b.length==0)return null;return JSON.parse(b.join(""));})()'
|
126
|
+
end
|
127
|
+
|
65
128
|
# Returns an ECMAScript value of attribute of the element.
|
66
129
|
# @param [Element|String] element the target element or id of the target
|
67
130
|
# element
|
@@ -70,7 +133,7 @@ module DYI
|
|
70
133
|
# @example
|
71
134
|
# rect = pen.draw_rectange(canvas, [0, 0], 20, 30, :id => "rect1")
|
72
135
|
# get_attribute(rect, "width")
|
73
|
-
# # => "document.getElementById(\"rect1\").getAttribute(\"
|
136
|
+
# # => "document.getElementById(\"rect1\").getAttribute(\"width\")"
|
74
137
|
# @since 1.1.0
|
75
138
|
def get_attribute(element, attribute_name)
|
76
139
|
"#{get_element(element)}.getAttribute(\"#{attribute_name}\")"
|
@@ -325,7 +388,6 @@ EOS
|
|
325
388
|
|
326
389
|
# Relates this object to an event.
|
327
390
|
# @param [Event] event an event that is related to
|
328
|
-
# @return [void]
|
329
391
|
def related_to(event)
|
330
392
|
unless @events.include?(event)
|
331
393
|
@events << event
|
@@ -334,7 +396,6 @@ EOS
|
|
334
396
|
|
335
397
|
# Removes the relation to an event.
|
336
398
|
# @param [Event] event an event that is removed the relation to
|
337
|
-
# @return [void]
|
338
399
|
def unrelated_to(event)
|
339
400
|
@events.delete(event)
|
340
401
|
end
|
data/lib/dyi/shape/base.rb
CHANGED
@@ -21,22 +21,50 @@
|
|
21
21
|
|
22
22
|
require 'enumerator'
|
23
23
|
|
24
|
-
module DYI
|
25
|
-
module Shape
|
24
|
+
module DYI
|
25
|
+
module Shape
|
26
26
|
|
27
|
+
# Base class of all graphical shapes.
|
28
|
+
# @abstract
|
29
|
+
# @since 0.0.0
|
27
30
|
class Base < GraphicalElement
|
31
|
+
|
32
|
+
# Returns painting status of the shape.
|
33
|
+
# @attribute painting
|
34
|
+
# @return [Painting] painting status
|
28
35
|
attr_painting :painting
|
36
|
+
|
37
|
+
# Returns font status of the shape.
|
38
|
+
# @attribute font
|
39
|
+
# @return [Font] font status
|
29
40
|
attr_font :font
|
30
|
-
|
41
|
+
|
42
|
+
# Returns optional attributes of the shape.
|
43
|
+
# @return [Hash] optional attributes
|
44
|
+
attr_reader :attributes
|
45
|
+
|
46
|
+
# Returns clipping status of the shape.
|
47
|
+
# @return [Drawing::Clipping] clipping status
|
48
|
+
attr_reader :clipping
|
49
|
+
|
50
|
+
# Returns a parent element of the shape.
|
51
|
+
# @return [GraphicalElement] a parent element
|
31
52
|
attr_reader :parent
|
53
|
+
|
54
|
+
# Returns a location of a reference of a source anchor for the link.
|
55
|
+
# @return [String] a location of a reference
|
32
56
|
attr_accessor :anchor_href
|
33
|
-
attr_accessor :anchor_target
|
34
57
|
|
35
|
-
|
58
|
+
# Returns a relevant presentation context when the link is activated.
|
59
|
+
# @return [String] a relevant presentation context
|
60
|
+
attr_accessor :anchor_target
|
36
61
|
|
37
62
|
# Draws the shape on a parent element.
|
38
|
-
# @param [Element] parent a element
|
39
|
-
# @return [Shape::Base]
|
63
|
+
# @param [Element] parent a container element on which the shape is drawn
|
64
|
+
# @return [Shape::Base] itself
|
65
|
+
# @raise [ArgumentError] parent is nil
|
66
|
+
# @raise [RuntimeError] this shape already has a parent, or descendants of
|
67
|
+
# this shape include itself
|
40
68
|
def draw_on(parent)
|
41
69
|
raise ArgumentError, "parent is nil" if parent.nil?
|
42
70
|
return self if @parent == parent
|
@@ -53,8 +81,7 @@ module DYI #:nodoc:
|
|
53
81
|
self
|
54
82
|
end
|
55
83
|
|
56
|
-
#
|
57
|
-
# @deprecated
|
84
|
+
# @deprecated Use {#root_element?} instead.
|
58
85
|
def root_node?
|
59
86
|
msg = [__FILE__, __LINE__, ' waring']
|
60
87
|
msg << ' DYI::Shape::Base#root_node? is depricated; use DYI::Shape::Base#root_element?'
|
@@ -62,15 +89,22 @@ module DYI #:nodoc:
|
|
62
89
|
false
|
63
90
|
end
|
64
91
|
|
92
|
+
# Returns whether this instance is root element of the shape.
|
93
|
+
# @return [Boolean] always false.
|
65
94
|
# @since 1.0.0
|
66
95
|
def root_element?
|
67
96
|
false
|
68
97
|
end
|
69
98
|
|
99
|
+
# Returns transform list.
|
100
|
+
# @return [Array] transform list.
|
70
101
|
def transform
|
71
102
|
@transform ||= []
|
72
103
|
end
|
73
104
|
|
105
|
+
# Translates the shape.
|
106
|
+
# @param [Numeric] x translated value along x-axis
|
107
|
+
# @param [Numeric] y translated value along y-axis
|
74
108
|
def translate(x, y=0)
|
75
109
|
x = Length.new(x)
|
76
110
|
y = Length.new(y)
|
@@ -85,6 +119,11 @@ module DYI #:nodoc:
|
|
85
119
|
end
|
86
120
|
end
|
87
121
|
|
122
|
+
# Scales up (or down) this shape.
|
123
|
+
# @param [Numeric] x scaled ratio along x-axis
|
124
|
+
# @param [Numeric] y scaled ratio along y-axis. If this parameter is nil,
|
125
|
+
# uses value that equals to parameter `x' value
|
126
|
+
# @param [Coordinate] base_point based coordinate of scaling up (or down)
|
88
127
|
def scale(x, y=nil, base_point=Coordinate::ZERO)
|
89
128
|
y ||= x
|
90
129
|
return if x == 1 && y == 1
|
@@ -101,6 +140,9 @@ module DYI #:nodoc:
|
|
101
140
|
translate(- base_point.x, - base_point.y) if base_point.nonzero?
|
102
141
|
end
|
103
142
|
|
143
|
+
# Rotates this shape.
|
144
|
+
# @param [Numeric] angle rotation angle. specifies degree
|
145
|
+
# @param [Coordinate] base_point based coordinate of rotetion
|
104
146
|
def rotate(angle, base_point=Coordinate::ZERO)
|
105
147
|
angle %= 360
|
106
148
|
return if angle == 0
|
@@ -116,6 +158,9 @@ module DYI #:nodoc:
|
|
116
158
|
translate(- base_point.x, - base_point.y) if base_point.nonzero?
|
117
159
|
end
|
118
160
|
|
161
|
+
# Skews this shape along x-axis.
|
162
|
+
# @param [Numeric] angle skew angle. specifies degree
|
163
|
+
# @param [Coordinate] base_point based coordinate of skew
|
119
164
|
def skew_x(angle, base_point=Coordinate::ZERO)
|
120
165
|
angle %= 180
|
121
166
|
return if angle == 0
|
@@ -125,6 +170,9 @@ module DYI #:nodoc:
|
|
125
170
|
translate(- base_point.x, - base_point.y) if base_point.nonzero?
|
126
171
|
end
|
127
172
|
|
173
|
+
# Skews this shape along y-axis.
|
174
|
+
# @param [Numeric] angle skew angle. specifies degree
|
175
|
+
# @param [Coordinate] base_point based coordinate of skew
|
128
176
|
def skew_y(angle, base_point=Coordinate::ZERO)
|
129
177
|
angle %= 180
|
130
178
|
return if angle == 0
|
@@ -135,96 +183,102 @@ module DYI #:nodoc:
|
|
135
183
|
translate(- base_point.x, - base_point.y) if base_point.nonzero?
|
136
184
|
end
|
137
185
|
|
186
|
+
# Restricts the region to which paint can be applied.
|
187
|
+
# @param [Drawing::Clipping] clipping a clipping object
|
138
188
|
def set_clipping(clipping)
|
139
189
|
clipping.set_canvas(canvas)
|
140
190
|
@clipping = clipping
|
141
191
|
end
|
142
192
|
|
193
|
+
# Crears clipping settings.
|
143
194
|
def clear_clipping
|
144
195
|
@clipping = nil
|
145
196
|
end
|
146
197
|
|
198
|
+
# Sets shapes that is used to estrict the region to which paint can be
|
199
|
+
# applied.
|
200
|
+
# @param [Base] shapes a shape that is used to clip
|
147
201
|
def set_clipping_shapes(*shapes)
|
148
202
|
set_clipping(Drawing::Clipping.new(*shapes))
|
149
203
|
end
|
150
204
|
|
205
|
+
# Returns registed animations.
|
206
|
+
# @return [Array<Animation::Base>] amination list.
|
151
207
|
# since 1.0.0
|
152
208
|
def animations
|
153
209
|
@animations ||= []
|
154
210
|
end
|
155
211
|
|
156
|
-
#
|
212
|
+
# Returns whether the shape is animated.
|
213
|
+
# @return [Boolean] true if the shape is animated, false otherwise
|
157
214
|
# @since 1.0.0
|
158
215
|
def animate?
|
159
216
|
!(@animations.nil? || @animations.empty?)
|
160
217
|
end
|
161
218
|
|
162
|
-
#
|
219
|
+
# Adds animation to the shape
|
163
220
|
# @param [Animation::Base] animation a animation that the shape is run
|
164
|
-
# @return [void]
|
165
221
|
# @since 1.0.0
|
166
222
|
def add_animation(animation)
|
167
223
|
animations << animation
|
168
224
|
end
|
169
225
|
|
170
|
-
#
|
171
|
-
# @param [Hash] options
|
226
|
+
# Adds animation of painting to the shape
|
172
227
|
# @option options [Painting] :from the starting painting of the animation
|
173
228
|
# @option options [Painting] :to the ending painting of the animation
|
174
229
|
# @option options [Number] :duration a simple duration in seconds
|
175
230
|
# @option options [Number] :begin_offset a offset that determine the
|
176
|
-
#
|
231
|
+
# animation begin, in seconds
|
177
232
|
# @option options [Event] :begin_event an event that determine the
|
178
|
-
#
|
233
|
+
# animation begin
|
179
234
|
# @option options [Number] :end_offset a offset that determine the
|
180
|
-
#
|
181
|
-
# @option options [Event] :end_event an event that determine the
|
182
|
-
#
|
235
|
+
# animation end, in seconds
|
236
|
+
# @option options [Event] :end_event an event that determine the animation
|
237
|
+
# end
|
183
238
|
# @option options [String] :fill `freeze' or `remove'
|
184
|
-
# @return [void]
|
185
239
|
# @since 1.0.0
|
186
240
|
def add_painting_animation(options)
|
187
241
|
add_animation(Animation::PaintingAnimation.new(self, options))
|
188
242
|
end
|
189
243
|
|
190
|
-
#
|
191
|
-
#
|
244
|
+
# Adds animation of transform to the shape
|
192
245
|
# @param [Symbol] type a type of transformation which is to have values
|
193
|
-
# @
|
194
|
-
#
|
195
|
-
# @option options [Number
|
246
|
+
# @option options [Number, Array] :from the starting transform of the
|
247
|
+
# animation
|
248
|
+
# @option options [Number, Array] :to the ending transform of the animation
|
196
249
|
# @option options [Number] :duration a simple duration in seconds
|
197
250
|
# @option options [Number] :begin_offset a offset that determine the
|
198
|
-
#
|
251
|
+
# animation begin, in seconds
|
199
252
|
# @option options [Event] :begin_event an event that determine the
|
200
|
-
#
|
253
|
+
# animation begin
|
201
254
|
# @option options [Number] :end_offset a offset that determine the
|
202
|
-
#
|
203
|
-
# @option options [Event] :end_event an event that determine the
|
204
|
-
#
|
255
|
+
# animation end, in seconds
|
256
|
+
# @option options [Event] :end_event an event that determine the animation
|
257
|
+
# end
|
205
258
|
# @option options [String] :fill `freeze' or `remove'
|
206
|
-
# @return [void]
|
207
259
|
# @since 1.0.0
|
208
260
|
def add_transform_animation(type, options)
|
209
261
|
add_animation(Animation::TransformAnimation.new(self, type, options))
|
210
262
|
end
|
211
263
|
|
212
|
-
#
|
264
|
+
# Adds animation of painting to the shape
|
213
265
|
# @param [Event] an event that is set to the shape
|
214
|
-
# @return [void]
|
215
266
|
# @since 1.0.0
|
216
267
|
def set_event(event)
|
217
268
|
super
|
218
269
|
canvas.set_event(event)
|
219
270
|
end
|
220
271
|
|
272
|
+
# Sets a location of a reference of a source anchor for the link.
|
273
|
+
# @param [String] href a location of a reference
|
221
274
|
# @since 1.0.0
|
222
275
|
def anchor_href=(href)
|
223
276
|
anchor_href = href.strip
|
224
277
|
@anchor_href = anchor_href.empty? ? nil : anchor_href
|
225
278
|
end
|
226
279
|
|
227
|
-
#
|
280
|
+
# Returns whether the element has URI reference.
|
281
|
+
# @return [Boolean] true if the element has URI reference, false otherwise
|
228
282
|
# @since 1.0.0
|
229
283
|
def has_uri_reference?
|
230
284
|
@anchor_href ? true : false
|
@@ -244,9 +298,28 @@ module DYI #:nodoc:
|
|
244
298
|
end
|
245
299
|
end
|
246
300
|
|
301
|
+
# The rectangle in the vector image
|
302
|
+
# @since 0.0.0
|
247
303
|
class Rectangle < Base
|
248
|
-
attr_length :width, :height
|
249
304
|
|
305
|
+
# Returns width of the rectangle.
|
306
|
+
# @attribute width
|
307
|
+
# @return [Length] width of the rectangle
|
308
|
+
attr_length :width
|
309
|
+
|
310
|
+
# Returns heigth of the rectangle.
|
311
|
+
# @attribute height
|
312
|
+
# @return [Length] heigth of the rectangle
|
313
|
+
attr_length :height
|
314
|
+
|
315
|
+
# @param [Coordinate] left_top a coordinate of a corner of the rectangle
|
316
|
+
# @param [Length] width width of the rectangle
|
317
|
+
# @param [Length] heigth heigth of the rectangle
|
318
|
+
# @option options [Painting] :painting painting status of the rectangle
|
319
|
+
# @option options [Length] :rx the x-axis radius of the ellipse for
|
320
|
+
# rounded the rectangle
|
321
|
+
# @option options [Length] :ry the y-axis radius of the ellipse for
|
322
|
+
# rounded the rectangle
|
250
323
|
def initialize(left_top, width, height, options={})
|
251
324
|
width = Length.new(width)
|
252
325
|
height = Length.new(height)
|
@@ -258,26 +331,39 @@ module DYI #:nodoc:
|
|
258
331
|
@attributes = init_attributes(options)
|
259
332
|
end
|
260
333
|
|
334
|
+
# Returns a x-axis coordinate of the left side of the rectangle.
|
335
|
+
# @return [Length] the x-axis coordinate of the left side
|
261
336
|
def left
|
262
337
|
@lt_pt.x
|
263
338
|
end
|
264
339
|
|
340
|
+
# Returns a x-axis coordinate of the right side of the rectangle.
|
341
|
+
# @return [Length] the x-axis coordinate of the right side
|
265
342
|
def right
|
266
343
|
@lt_pt.x + width
|
267
344
|
end
|
268
345
|
|
346
|
+
# Returns a y-axis coordinate of the top of the rectangle.
|
347
|
+
# @return [Length] a y-axis coordinate of the top
|
269
348
|
def top
|
270
349
|
@lt_pt.y
|
271
350
|
end
|
272
351
|
|
352
|
+
# Returns a y-axis coordinate of the bottom of the rectangle.
|
353
|
+
# @return [Length] a y-axis coordinate of the bottom
|
273
354
|
def bottom
|
274
355
|
@lt_pt.y + height
|
275
356
|
end
|
276
357
|
|
358
|
+
# Returns a coordinate of the center of the rectangle.
|
359
|
+
# @return [Coordinate] a coordinate of the center
|
277
360
|
def center
|
278
361
|
@lt_pt + Coordinate.new(width.quo(2), height.quo(2))
|
279
362
|
end
|
280
363
|
|
364
|
+
# Writes the shape on io object.
|
365
|
+
# @param [Formatter::Base] formatter an object that defines the image format
|
366
|
+
# @param [IO] io an io to be written
|
281
367
|
def write_as(formatter, io=$>)
|
282
368
|
formatter.write_rectangle(self, io, &(block_given? ? Proc.new : nil))
|
283
369
|
end
|
@@ -286,10 +372,31 @@ module DYI #:nodoc:
|
|
286
372
|
|
287
373
|
public
|
288
374
|
|
375
|
+
# Create a new instance of Rectangle.
|
376
|
+
# @param [Coordinate] left_top a coordinate of a corner of the rectangle
|
377
|
+
# @param [Length] width width of the rectangle
|
378
|
+
# @param [Length] heigth heigth of the rectangle
|
379
|
+
# @option options [Painting] :painting painting status of the rectangle
|
380
|
+
# @option options [Length] :rx the x-axis radius of the ellipse for
|
381
|
+
# rounded the rectangle
|
382
|
+
# @option options [Length] :ry the y-axis radius of the ellipse for
|
383
|
+
# rounded the rectangle
|
384
|
+
# @return [Rectangle] a new instance of Rectangle
|
289
385
|
def create_on_width_height(left_top, width, height, options={})
|
290
386
|
new(left_top, width, height, options)
|
291
387
|
end
|
292
388
|
|
389
|
+
# Create a new instance of Rectangle.
|
390
|
+
# @param [Length] top a y-axis coordinate of the top
|
391
|
+
# @param [Length] right a x-axis coordinate of the right side
|
392
|
+
# @param [Length] bottom a y-axis coordinate of the bottom
|
393
|
+
# @param [Length] left a x-axis coordinate of the left side
|
394
|
+
# @option options [Painting] :painting painting status of the rectangle
|
395
|
+
# @option options [Length] :rx the x-axis radius of the ellipse for
|
396
|
+
# rounded the rectangle
|
397
|
+
# @option options [Length] :ry the y-axis radius of the ellipse for
|
398
|
+
# rounded the rectangle
|
399
|
+
# @return [Rectangle] a new instance of Rectangle
|
293
400
|
def create_on_corner(top, right, bottom, left, options={})
|
294
401
|
left_top = Coordinate.new([left, right].min, [top, bottom].min)
|
295
402
|
width = (Length.new(right) - Length.new(left)).abs
|
@@ -299,8 +406,18 @@ module DYI #:nodoc:
|
|
299
406
|
end
|
300
407
|
end
|
301
408
|
|
409
|
+
# The circle in the vector image
|
410
|
+
# @since 0.0.0
|
302
411
|
class Circle < Base
|
412
|
+
|
413
|
+
# Returns a center coordinate of the circle.
|
414
|
+
# @attribute center
|
415
|
+
# @return [Coordinate] a center coordinate of the circle
|
303
416
|
attr_coordinate :center
|
417
|
+
|
418
|
+
# Returns a radius of the circle.
|
419
|
+
# @attribute radius
|
420
|
+
# @return [Length] a radius of the circle
|
304
421
|
attr_length :radius
|
305
422
|
|
306
423
|
def initialize(center, radius, options={})
|