tagen 1.1.7 → 2.0.0

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.
Files changed (92) hide show
  1. data/.gitignore +4 -1
  2. data/.travis.yml +5 -0
  3. data/CHANGELOG +6 -0
  4. data/Gemfile +2 -3
  5. data/Gemfile.lock +13 -15
  6. data/README.md +20 -39
  7. data/Rakefile +2 -1
  8. data/benchmark/a.rb +14 -0
  9. data/lib/tagen/core.rb +17 -22
  10. data/lib/tagen/core/array.rb +5 -109
  11. data/lib/tagen/core/array/append.rb +3 -0
  12. data/lib/tagen/core/array/delete_values.rb +43 -0
  13. data/lib/tagen/core/array/extract_options.rb +35 -94
  14. data/lib/tagen/core/class.rb +1 -0
  15. data/lib/tagen/core/enumerable.rb +15 -18
  16. data/lib/tagen/core/enumerator.rb +22 -12
  17. data/lib/tagen/core/exception.rb +5 -3
  18. data/lib/tagen/core/file.rb +1 -0
  19. data/lib/tagen/core/hash.rb +4 -39
  20. data/lib/tagen/core/integer.rb +2 -0
  21. data/lib/tagen/core/io.rb +59 -26
  22. data/lib/tagen/core/kernel.rb +5 -64
  23. data/lib/tagen/core/kernel/deprecate.rb +5 -0
  24. data/lib/tagen/core/kernel/platform.rb +46 -0
  25. data/lib/tagen/core/kernel/shell.rb +45 -0
  26. data/lib/tagen/core/module.rb +9 -11
  27. data/lib/tagen/core/numeric.rb +4 -2
  28. data/lib/tagen/core/object.rb +6 -21
  29. data/lib/tagen/core/process.rb +6 -4
  30. data/lib/tagen/core/re.rb +2 -2
  31. data/lib/tagen/core/string.rb +12 -47
  32. data/lib/tagen/core/time.rb +30 -38
  33. data/lib/tagen/erb.rb +10 -8
  34. data/lib/tagen/net/http.rb +33 -29
  35. data/lib/tagen/pathname.rb +1 -5
  36. data/lib/tagen/rbconfig.rb +8 -0
  37. data/lib/tagen/socket.rb +8 -2
  38. data/lib/tagen/uri.rb +9 -0
  39. data/lib/tagen/version.rb +1 -1
  40. data/lib/tagen/vim.rb +8 -8
  41. data/lib/tagen/xmpp4r.rb +23 -23
  42. data/spec/spec_helper.rb +23 -17
  43. data/spec/tagen/core/array/delete_values_spec.rb +19 -0
  44. data/spec/tagen/core/array/extract_options_spec.rb +9 -29
  45. data/spec/tagen/core/enumerable_spec.rb +9 -0
  46. data/spec/tagen/core/enumerator_spec.rb +10 -12
  47. data/spec/tagen/core/exception_spec.rb +14 -9
  48. data/spec/tagen/core/io_spec.rb +20 -0
  49. data/spec/tagen/core/kernel/platform_spec.rb +92 -0
  50. data/spec/tagen/core/kernel/shell_spec.rb +27 -0
  51. data/spec/tagen/core/numeric_spec.rb +10 -0
  52. data/spec/tagen/core/process_spec.rb +14 -0
  53. data/spec/tagen/core/re_spec.rb +9 -0
  54. data/spec/tagen/core/string_spec.rb +9 -0
  55. data/spec/tagen/core/time_spec.rb +6 -51
  56. data/spec/tagen/erb_spec.rb +3 -10
  57. data/spec/tagen/pathname_spec.rb +11 -0
  58. data/spec/tagen/rbconfig_spec.rb +11 -0
  59. data/spec/tagen/socket_spec.rb +7 -5
  60. data/spec/tagen/uri_spec.rb +13 -0
  61. data/tagen.gemspec +3 -4
  62. metadata +45 -51
  63. data/TODO +0 -1
  64. data/docs/Architecture.md +0 -17
  65. data/docs/CoreExtensions.md +0 -40
  66. data/docs/ExtraExtensions.md +0 -20
  67. data/lib/tagen/RMagick.rb +0 -12
  68. data/lib/tagen/audioinfo.rb +0 -22
  69. data/lib/tagen/cairo.rb +0 -811
  70. data/lib/tagen/core/extend_hash.rb +0 -46
  71. data/lib/tagen/core/marshal.rb +0 -34
  72. data/lib/tagen/core/open_option.rb +0 -161
  73. data/lib/tagen/core/string/pyformat.rb +0 -336
  74. data/lib/tagen/core/symbol.rb +0 -8
  75. data/lib/tagen/date.rb +0 -80
  76. data/lib/tagen/gdk_pixbuf2.rb +0 -26
  77. data/lib/tagen/gtk2.rb +0 -122
  78. data/lib/tagen/ncurses.rb +0 -246
  79. data/lib/tagen/poppler.rb +0 -48
  80. data/lib/tagen/tree.rb +0 -77
  81. data/lib/tagen/xmpp4r/roster.rb +0 -20
  82. data/lib/tagen/yaml.rb +0 -38
  83. data/spec/tagen/cairo_spec.rb +0 -137
  84. data/spec/tagen/core/array_spec.rb +0 -42
  85. data/spec/tagen/core/extend_hash_spec.rb +0 -54
  86. data/spec/tagen/core/hash_spec.rb +0 -10
  87. data/spec/tagen/core/module_spec.rb +0 -14
  88. data/spec/tagen/core/open_option_spec.rb +0 -83
  89. data/spec/tagen/core/string/pyformat_spec.rb +0 -98
  90. data/spec/tagen/core/symbol_spec.rb +0 -15
  91. data/spec/tagen/core_spec.rb +0 -6
  92. data/spec/tagen/date_spec.rb +0 -146
@@ -1,6 +1,5 @@
1
1
  require "spec_helper"
2
2
  require "tagen/erb"
3
- require "tagen/core"
4
3
 
5
4
  describe ERB do
6
5
  describe "#result" do
@@ -10,21 +9,15 @@ describe ERB do
10
9
 
11
10
  it "runs ok" do
12
11
  a = 1
13
- @erb.result(binding).should == "1"
12
+ expect(@erb.result(binding)).to eq("1")
14
13
  end
15
14
 
16
15
  it "runs ok with local " do
17
- @erb.result(nil, a: 2).should == "2"
16
+ expect(@erb.result(nil, a: 2)).to eq("2")
18
17
  end
19
18
 
20
19
  it "support string as key in locals" do
21
- @erb.result(nil, "a" => 2).should == "2"
20
+ expect(@erb.result(nil, "a" => 2)).to eq("2")
22
21
  end
23
-
24
- #it "support OpenOption" do
25
- #o = OpenOption.new(a: 1)
26
- #@erb.result(nil, o).should == '1'
27
- #end
28
-
29
22
  end
30
23
  end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+ require "tagen/pathname"
3
+
4
+ describe Pathname do
5
+ describe "#path" do
6
+ it do
7
+ expect(Pathname.new("hello").path).to eq("hello")
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+ require "tagen/rbconfig"
3
+
4
+ describe RbConfig do
5
+ describe ".method_missing" do
6
+ it do
7
+ expect(RbConfig["host_os"]).to eq(RbConfig::CONFIG["host_os"])
8
+ end
9
+ end
10
+ end
11
+
@@ -2,16 +2,17 @@ require "spec_helper"
2
2
  require "tagen/socket"
3
3
 
4
4
  describe BasicSocket do
5
- describe "#send2 and #recv2" do
6
- it "works" do
5
+ describe "#send2, recv2" do
6
+ it do
7
7
  s = TCPServer.open("127.0.0.1", 0)
8
8
  af, port, host, addr = s.addr
9
9
  c = TCPSocket.open(host, port)
10
10
  s = s.accept
11
11
  c.send2("guten")
12
12
  c.send2("tag")
13
- s.recv2.should == "guten"
14
- s.recv2.should == "tag"
13
+
14
+ expect(s.recv2).to eq("guten")
15
+ expect(s.recv2).to eq("tag")
15
16
  end
16
17
  end
17
18
 
@@ -22,7 +23,8 @@ describe BasicSocket do
22
23
  c = TCPSocket.open(host, port)
23
24
  s = s.accept
24
25
  c.send_obj([1,2])
25
- s.recv_obj.should == [1,2]
26
+
27
+ expect(s.recv_obj).to eq([1,2])
26
28
  end
27
29
  end
28
30
  end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+ require "tagen/uri"
3
+
4
+ describe URI::Generic do
5
+ describe "#to_hash" do
6
+ it do
7
+ a = URI("http://example.com").to_hash
8
+ b = { scheme: "http", userinfo: nil, host: "example.com", port: 80, path: "", query: nil, fragment: nil }
9
+
10
+ expect(a).to eq(b)
11
+ end
12
+ end
13
+ end
@@ -3,9 +3,9 @@ Kernel.load File.expand_path("../lib/tagen/version.rb", __FILE__)
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "tagen"
5
5
  s.version = Tagen::VERSION
6
- s.summary = "a core and extra extension to ruby library"
6
+ s.summary = "a lightweight core and extra extensions for Ruby."
7
7
  s.description = <<-EOF
8
- a core and extra extension to ruby library.
8
+ a lightweight core and extra extensions for Ruby.
9
9
  EOF
10
10
 
11
11
  s.author = "Guten"
@@ -15,7 +15,6 @@ a core and extra extension to ruby library.
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
17
17
 
18
- s.add_dependency "activesupport", "~>3.1.0"
19
- s.add_dependency "i18n"
20
18
  s.add_dependency "pd"
19
+ s.add_dependency "activesupport", "~>3.2.8"
21
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tagen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 2.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,42 +9,41 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-29 00:00:00.000000000 Z
12
+ date: 2012-08-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: activesupport
16
- requirement: &9557280 !ruby/object:Gem::Requirement
15
+ name: pd
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 3.1.0
21
+ version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *9557280
25
- - !ruby/object:Gem::Dependency
26
- name: i18n
27
- requirement: &9591460 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
28
25
  none: false
29
26
  requirements:
30
27
  - - ! '>='
31
28
  - !ruby/object:Gem::Version
32
29
  version: '0'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: *9591460
36
30
  - !ruby/object:Gem::Dependency
37
- name: pd
38
- requirement: &9590200 !ruby/object:Gem::Requirement
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
39
33
  none: false
40
34
  requirements:
41
- - - ! '>='
35
+ - - ~>
42
36
  - !ruby/object:Gem::Version
43
- version: '0'
37
+ version: 3.2.8
44
38
  type: :runtime
45
39
  prerelease: false
46
- version_requirements: *9590200
47
- description: ! "a core and extra extension to ruby library. \n"
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 3.2.8
46
+ description: ! "a lightweight core and extra extensions for Ruby. \n"
48
47
  email: ywzhaifei@gmail.com
49
48
  executables: []
50
49
  extensions: []
@@ -52,71 +51,66 @@ extra_rdoc_files: []
52
51
  files:
53
52
  - .gitignore
54
53
  - .rspec
54
+ - .travis.yml
55
55
  - .yardopts
56
+ - CHANGELOG
56
57
  - Gemfile
57
58
  - Gemfile.lock
58
59
  - README.md
59
60
  - Rakefile
60
- - TODO
61
- - docs/Architecture.md
62
- - docs/CoreExtensions.md
63
- - docs/ExtraExtensions.md
64
- - lib/tagen/RMagick.rb
65
- - lib/tagen/audioinfo.rb
66
- - lib/tagen/cairo.rb
61
+ - benchmark/a.rb
67
62
  - lib/tagen/core.rb
68
63
  - lib/tagen/core/array.rb
64
+ - lib/tagen/core/array/append.rb
65
+ - lib/tagen/core/array/delete_values.rb
69
66
  - lib/tagen/core/array/extract_options.rb
67
+ - lib/tagen/core/class.rb
70
68
  - lib/tagen/core/enumerable.rb
71
69
  - lib/tagen/core/enumerator.rb
72
70
  - lib/tagen/core/exception.rb
73
- - lib/tagen/core/extend_hash.rb
71
+ - lib/tagen/core/file.rb
74
72
  - lib/tagen/core/hash.rb
73
+ - lib/tagen/core/integer.rb
75
74
  - lib/tagen/core/io.rb
76
75
  - lib/tagen/core/kernel.rb
77
- - lib/tagen/core/marshal.rb
76
+ - lib/tagen/core/kernel/deprecate.rb
77
+ - lib/tagen/core/kernel/platform.rb
78
+ - lib/tagen/core/kernel/shell.rb
78
79
  - lib/tagen/core/module.rb
79
80
  - lib/tagen/core/numeric.rb
80
81
  - lib/tagen/core/object.rb
81
- - lib/tagen/core/open_option.rb
82
82
  - lib/tagen/core/process.rb
83
83
  - lib/tagen/core/re.rb
84
84
  - lib/tagen/core/string.rb
85
- - lib/tagen/core/string/pyformat.rb
86
- - lib/tagen/core/symbol.rb
87
85
  - lib/tagen/core/time.rb
88
- - lib/tagen/date.rb
89
86
  - lib/tagen/erb.rb
90
- - lib/tagen/gdk_pixbuf2.rb
91
- - lib/tagen/gtk2.rb
92
- - lib/tagen/ncurses.rb
93
87
  - lib/tagen/net/http.rb
94
88
  - lib/tagen/pathname.rb
95
- - lib/tagen/poppler.rb
89
+ - lib/tagen/rbconfig.rb
96
90
  - lib/tagen/socket.rb
97
- - lib/tagen/tree.rb
91
+ - lib/tagen/uri.rb
98
92
  - lib/tagen/version.rb
99
93
  - lib/tagen/vim.rb
100
94
  - lib/tagen/xmpp4r.rb
101
- - lib/tagen/xmpp4r/roster.rb
102
- - lib/tagen/yaml.rb
103
95
  - spec/spec_helper.rb
104
- - spec/tagen/cairo_spec.rb
96
+ - spec/tagen/core/array/delete_values_spec.rb
105
97
  - spec/tagen/core/array/extract_options_spec.rb
106
- - spec/tagen/core/array_spec.rb
98
+ - spec/tagen/core/enumerable_spec.rb
107
99
  - spec/tagen/core/enumerator_spec.rb
108
100
  - spec/tagen/core/exception_spec.rb
109
- - spec/tagen/core/extend_hash_spec.rb
110
- - spec/tagen/core/hash_spec.rb
111
- - spec/tagen/core/module_spec.rb
112
- - spec/tagen/core/open_option_spec.rb
113
- - spec/tagen/core/string/pyformat_spec.rb
114
- - spec/tagen/core/symbol_spec.rb
101
+ - spec/tagen/core/io_spec.rb
102
+ - spec/tagen/core/kernel/platform_spec.rb
103
+ - spec/tagen/core/kernel/shell_spec.rb
104
+ - spec/tagen/core/numeric_spec.rb
105
+ - spec/tagen/core/process_spec.rb
106
+ - spec/tagen/core/re_spec.rb
107
+ - spec/tagen/core/string_spec.rb
115
108
  - spec/tagen/core/time_spec.rb
116
- - spec/tagen/core_spec.rb
117
- - spec/tagen/date_spec.rb
118
109
  - spec/tagen/erb_spec.rb
110
+ - spec/tagen/pathname_spec.rb
111
+ - spec/tagen/rbconfig_spec.rb
119
112
  - spec/tagen/socket_spec.rb
113
+ - spec/tagen/uri_spec.rb
120
114
  - tagen.gemspec
121
115
  - tagen.watchr
122
116
  homepage: http://github.com/GutenYe/tagen
@@ -139,9 +133,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
133
  version: '0'
140
134
  requirements: []
141
135
  rubyforge_project: xx
142
- rubygems_version: 1.8.11
136
+ rubygems_version: 1.8.24
143
137
  signing_key:
144
138
  specification_version: 3
145
- summary: a core and extra extension to ruby library
139
+ summary: a lightweight core and extra extensions for Ruby.
146
140
  test_files: []
147
141
  has_rdoc:
data/TODO DELETED
@@ -1 +0,0 @@
1
- * Pa support home path. e.g. '~/.vimrc'
@@ -1,17 +0,0 @@
1
- Architecture
2
- ============
3
-
4
- **source file layout**:
5
-
6
- lib/tagen/
7
- core.rb
8
- core/
9
- array/extract_options.rb
10
- ...
11
- pathname.rb # extra lib
12
- ...
13
-
14
-
15
-
16
-
17
-
@@ -1,40 +0,0 @@
1
- Core extensions
2
- ==============
3
-
4
- Usage
5
- -----
6
-
7
- require "tagen/core"
8
- # or
9
- require "tagen/core/string"
10
-
11
-
12
- From Tagen
13
- ----------
14
- * {Object#deepdup}
15
-
16
- * {Kernel}
17
- * `#linux? win32?`
18
- * `sh`
19
- * `blk2method`
20
-
21
- * {Numeric#div2}
22
-
23
- * {String}.hexdigits octdigits letters uppercase lowercase
24
-
25
- * {Array}
26
- * `#extract_extend_options! extract_options!`
27
- * `#append`
28
- * `#delete(*values) delete_at` _support delete more than one values_
29
-
30
- * {Hash#delete}
31
-
32
- * {IO#fd}
33
-
34
- * {Time.time}
35
-
36
- * {Process.exists?}(pid)
37
-
38
- * {MatchData#to_hash}
39
-
40
- * {PyFormat} _a string format libraray_
@@ -1,20 +0,0 @@
1
- A list of extra extensions
2
- ==========================
3
-
4
- From stdlib
5
- -----------
6
- * "pathname"
7
- * "socket"
8
- * "net/http"
9
-
10
- From Gems
11
- ---------
12
- * "audioinfo"
13
- * "cairo"
14
- * "gtk2"
15
- * "magick"
16
- * "ncurses"
17
- * "poppler"
18
- * "tree"
19
- * "vim"
20
- * "xmpp4r
@@ -1,12 +0,0 @@
1
- require "RMagick"
2
-
3
- module Magick
4
- class Image
5
- # get columns, rows
6
- #
7
- # @return [Array] [width, height]
8
- def cr
9
- [columns, rows]
10
- end
11
- end
12
- end
@@ -1,22 +0,0 @@
1
- require "audioinfo"
2
- =begin
3
- * **gem**: ruby-audioinfo
4
- =end
5
- class AudioInfo
6
- class << self
7
-
8
- # check if it is a audio file?
9
- #
10
- # @param [String] path
11
- # @return [Boolean]
12
- def file? path
13
- SUPPORTED_EXTENSIONS.include? File.extname(path)
14
- end
15
-
16
- # get a file's type
17
- #
18
- # @param [String] path
19
- # @return [String]
20
- def type path; File.extname(path) end
21
- end
22
- end
@@ -1,811 +0,0 @@
1
- require "cairo"
2
-
3
- # gdk_pixbuf2 for
4
- # Context#set_source
5
- # set_source_pixbuf
6
- begin
7
- require "gdk_pixbuf2"
8
- require_relative "gdk_pixbuf2"
9
- rescue
10
- end
11
-
12
- # confict. Gtk::PrintContext use Cairo. but not use Context#initialize method
13
- # because inherit probleam
14
- # FF1. only change Cairo::Context -> Cairo::Contexg
15
- # FF2. Gtk::PrintContext config with cairo. so change Gtk::PrintContext
16
-
17
- =begin
18
- * **Install**: gem(cairo)
19
-
20
- a wrap to Cairo.
21
-
22
- this library is deprecated, please don't use it.
23
-
24
- =end
25
- module Cairo
26
-
27
- # compute width height by rotate and scale
28
- #
29
- # @param [Numeric] w
30
- # @param [Numeric] h
31
- # @param [Numeric] rotate 0<=x<=1
32
- # @param [Numeric] scale 0<=x<=1
33
- # @return [Array<Numeric>] \[length1, length2]
34
- def self.compute_wh(w, h, rotate=0,scale=1)
35
- # selection=[x,y,w,h]
36
- w,h=1,1 if w<=0 or h<=0
37
- w,h = w*scale.to_f, h*scale.to_f
38
-
39
- radius = 0
40
-
41
- rotate = rotate*180/Math::PI if String===rotate
42
- rotate %= 360
43
-
44
- unless rotate.zero?
45
- radius = rotate / 180.0 * Math::PI
46
- if (90 < rotate and rotate < 180) or (270 < rotate and rotate < 360)
47
- radius -= Math::PI / 2
48
- end
49
- end
50
- inner_angle1 = Math.atan(w/h)
51
- inner_angle2 = Math.atan(h/w)
52
- diagonal = Math.sqrt(w**2 + h**2)
53
-
54
- angle1 = radius + inner_angle1
55
- angle2 = radius + inner_angle2
56
-
57
- bottom1 = diagonal * Math.cos(angle1)
58
- length1 = (bottom1 * Math.tan(angle1)).abs.to_up
59
- bottom2 = diagonal * Math.cos(angle2)
60
- length2 = (bottom2 * Math.tan(angle2)).abs.to_up
61
-
62
- if (0 <= rotate and rotate <= 90) or (180 <= rotate and rotate <= 270)
63
- [length1, length2]
64
- else
65
- [length2, length1]
66
- end
67
- end # def self.compute_wh
68
- end
69
-
70
- module Cairo
71
- # class FontExtents and TextExtents
72
- class FontExtents
73
-
74
- # @return [Array] \[ascent, descent, height, max_x_advance, max_y_advance\]
75
- def to_a
76
- [ascent,descent,height,max_x_advance,max_y_advance]
77
- end
78
- end
79
-
80
- # === Additional Method List
81
- # * #w: _alias from width_
82
- # * #h: _alias from h_
83
- class TextExtents
84
- alias w width
85
- alias h height
86
-
87
- # @return [Array] \[width, height]
88
- def wh; [width, height] end
89
-
90
- # @return [Array] \[x_advance, y_advance]
91
- def xy_advance; [x_advance, y_advance] end
92
-
93
- # @return [Array] \[x_bearing, y_bearing]
94
- def xy_bearing; [x_bearing, y_bearing] end
95
-
96
- # @return [Array] \[x_bearing, y_bearing, width, height, x_advance, y_advance\]
97
- def to_a
98
- [x_bearing, y_bearing, width, height, x_advance, y_advance]
99
- end
100
- end
101
-
102
- class PDFSurface
103
- alias initialize_ initialize
104
- def initialize(filename, width, height)
105
- initialize_(filename, width, height)
106
- @wh=[width.to_f, height.to_f]
107
- end
108
-
109
- # get width, height
110
- def wh; @wh end
111
- # get width
112
- def w; @wh[0] end
113
- # get height
114
- def h; @wh[1] end
115
- end # class PDFSurface
116
-
117
- class ImageSurface
118
- alias initialize_ initialize
119
-
120
- # get width, height
121
- def wh; [width.to_f, height.to_f] end
122
- # get width
123
- def w; self.wh[0] end
124
- # get height
125
- def h; self.wh[1] end
126
-
127
- end # class ImageSurface
128
-
129
- class Context
130
- private
131
- # utils
132
- def __rpos(*args)
133
- # 10 user_relative_distance
134
- # "10" device_relative_distance
135
- x_,y_ = xy
136
- args.split(2,[]) do |(x,y),i,memo|
137
- x = String===x ? tdu(x.to_f) : x
138
- y = String===y ? tdu(nil, y.to_f) : y
139
- memo.push(x+x_, y+y_)
140
- end
141
- end
142
- def __tpos(*args)
143
- # 7 device_relative_distance
144
- x_, y_ = xy
145
- args.split(2, []) do |(x,y), i, memo|
146
- x,y = tdu(x, y)
147
- memo.push(x+x_, y+y_)
148
- end
149
- end
150
-
151
- def __dpos(*args)
152
- # 10 device_pos
153
- # "10" device_relative_distance
154
- x_,y_ = xy
155
- args.split(2, []) do |(x,y),i,memo|
156
- x = String===x ? tdu(x.to_f)+x_ : du(x)
157
- y = String===y ? tdu(nil,y.to_f)+y_ : du(nil,y)
158
- memo.push(x,y)
159
- end
160
- end
161
-
162
- def __pos(*args)
163
- # 7 user_pos
164
- # "7" user_relative_distance
165
- # :d7 device_pos
166
- # :r7 device_relative_distance
167
- x_,y_ = xy
168
- args.split(2, []) do |(x,y),i,memo|
169
- x = case x
170
- when /^d/
171
- du(x[1..-1].to_f)
172
- when /^r/
173
- tdu(x[1..-1].to_f) + x_
174
- when String
175
- x.to_f + x_
176
- else
177
- x
178
- end
179
-
180
- #p x,y,y_
181
- y = case y
182
- when /^d/
183
- du(nil, y[1..-1].to_f)
184
- when /^r/
185
- tdu(nil, y[1..-1].to_f) + y_
186
- when String
187
- y.to_f + y_
188
- else
189
- y
190
- end
191
-
192
- memo.push(x,y)
193
- end
194
- end # def __pos
195
-
196
- def __angle(*args)
197
- rst = args.split(2, []) do |(a1,a2),i,memo|
198
- a1 = a1.to_f*Math::PI/180.0 unless String === a1
199
- a2 = a2.to_f*Math::PI/180.0 unless String === a2
200
- memo.push(a1,a2)
201
- end
202
-
203
- rst.gach!(&:to_f)
204
- args.size==1 ? rst[0] : rst
205
- end
206
-
207
- def __du(x,y)
208
- # 7
209
- # "7" device_to_user
210
- x = device_to_user(x.to_f,1)[0] if String === x
211
- y = device_to_user(1,y.to_f)[1] if String === y
212
- [x,y]
213
- end
214
-
215
- def __tdu(tx,ty)
216
- # 7
217
- # "7" device_to_user_distance
218
- tx = device_to_user_distance(tx.to_f,1)[0] if String === tx
219
- ty = device_to_user_distance(1,ty.to_f)[1] if String === ty
220
- [tx,ty]
221
- end
222
-
223
- public
224
- alias initialize_ initialize
225
- def initialize(surface)
226
- initialize_(surface)
227
- move_to(0,0)
228
-
229
- self.dsize = 13
230
- self.dborder = 1
231
-
232
- @line_cap =line_cap_
233
- @line_join =line_join_
234
- @line_dash =line_dash_
235
- @font_matrix =font_matrix_
236
- @font_options =font_options_
237
- @font_face =font_face_
238
- @operator =operator_
239
- @antialias =antialias_
240
- end # def initialize
241
-
242
- attr_reader :size, :dsize, :border, :line_cap, :line_join, :line_dash,
243
- :font_matrix, :font_options, :font_face, :operator, :antialias
244
-
245
- alias showglyphs show_glyphs
246
- alias line_cap_ line_cap
247
- alias line_join_ line_join
248
- alias line_dash_ dash
249
- alias font_matrix_ font_matrix
250
- alias font_options_ font_options
251
- alias font_face_ font_face
252
- alias operator_ operator
253
- alias antialias_ antialias
254
- alias showpage show_page
255
- alias copypage copy_page
256
- alias surface target
257
-
258
- alias textpath text_path
259
- alias glyphpath glyph_path
260
-
261
- def font_face family, slant=:normal, weight=:normal
262
- slant = Cairo.const_get("font_slant_#{slant}".upcase)
263
- weight = Cairo.const_get("font_weight_#{weight}".upcase)
264
- select_font_face family, slant, weight
265
- end
266
-
267
- alias size_= font_size=
268
- def size=(size)
269
- if String === size
270
- self.dsize = size.to_f
271
- else
272
- @dsize = ud(size)
273
- @size = size
274
- self.font_size = @size
275
- end
276
- end
277
- def dsize=(size)
278
- @dsize = size
279
- @size = tdu(size)
280
- self.font_size = @size
281
- end
282
-
283
- def font_matrix=(matrix)
284
- @font_matrix=matrix
285
- set_font_matrix(@font_matrix)
286
- @font_matrix
287
- end
288
-
289
- def font_options=(options)
290
- set_font_options( @font_options=options )
291
- @font_options
292
- end
293
-
294
- def font_face=(face)
295
- set_font_face( @font_face=face )
296
- @font_face
297
- end
298
-
299
- def text_scale_min
300
- min = tud(1,1).min
301
- bak(:scale) do
302
- dscale min, min
303
- yield
304
- end
305
- end
306
-
307
- def showtext(text, newline=false)
308
- text_scale_min do
309
- ascent, descent = font_extents.to_a
310
- mvxy('0', ascent.to_s)
311
- show_text(text.to_s)
312
- mvxy('0', (-ascent).to_s)
313
- mvxy(0, (ascent+descent).to_s) if newline
314
- end
315
- end
316
-
317
- def newline_height
318
- out = nil; prev=nil
319
- text_scale_min do
320
- ascent, descent = font_extents.to_a
321
- out = ascent+descent
322
- prev = tud(nil, 1)
323
- end
324
-
325
- cur = tud(nil, 1)
326
- out = prev/cur*out
327
- out
328
- end
329
-
330
- def newline
331
- mvxy(0, newline_height.to_s)
332
- end
333
-
334
- def sep(width, border="1")
335
- mvxy(0, "0")
336
- line("0","0", width, "0")
337
- bak(:border) do
338
- self.border = border
339
- stroke
340
- end
341
- end
342
-
343
- def centertext(text)
344
- advanced_x = nil
345
- advanced_x = text_extents(text.to_s).to_a[-2]
346
- mvxy( ((1-advanced_x)/2.0).to_s , '0')
347
- showtext(text, true)
348
- end
349
-
350
- def instroke?(x,y); in_stroke?(x,y) end
351
- def infill?(x,y); in_fill?(x,y) end
352
-
353
- alias set_source_ set_source
354
- def set_source(source)
355
- # [r,g,b,a=1.0] Pattern Surface
356
- # "#rgb[a]", "name" (set_source_color)
357
- # Pixbuf (set_source_pixbuf)
358
- case
359
- when String===source
360
- set_source_color(source)
361
- when Array===source, source.kind_of?(Pattern), source.kind_of?(Surface)
362
- set_source_(source)
363
- else
364
- set_source_pixbuf(*args)
365
- end
366
- end
367
-
368
- def operator=(operator)
369
- @operator = Cairo.const_get("operator_#{operator}".upcase)
370
- set_operator(@operator)
371
- @operator
372
- end
373
-
374
- def antialias=(antialias)
375
- @antialias = Cairo.const_get("antianias_#{antialias}".upcase)
376
- set_antialias(@antialias)
377
- @antialias
378
- end
379
-
380
- alias fill_ fill
381
- def fill(keep=true)
382
- if keep
383
- xy = current_point
384
- fill_()
385
- move_to(*xy)
386
- else
387
- fill_()
388
- end
389
- end
390
-
391
- def mask(*args)
392
- if args[0].class == Pattern
393
- mask(args[0])
394
- elsif args[0].class == Surface
395
- mask_surface(*args)
396
- end
397
- end
398
-
399
- alias push_group_ push_group
400
- def push_group(context=false)
401
- if context
402
- push_group_widht_context(context)
403
- else
404
- push_group_
405
- end
406
- end
407
-
408
- alias pop_group_ pop_group
409
- def pop_group(to_source=false)
410
- group = pop_group_
411
- set_source(group) if to_source
412
- group
413
- end
414
-
415
- #alias xy_ move_to
416
- #def xy_(*xy) xy.empty? ? current_point : move_to(*xy) end
417
- def mvxy(*xy) xy.empty? ? current_point : move_to(*__pos(*xy)) end
418
- def dmvxy(*xy) xy.empty? ? ud(*current_point) : move_to(*__dpos(*xy)) end
419
- def rmvxy(x,y) move_to(*__rpos(x,y)) end
420
- def rdmvxy(x,y) move_to(*__tpos(x,y)) end
421
-
422
- #def dpos; ud(*pos) end
423
-
424
- def mvx(x=nil); x ? mvxy(x, "0") : current_point[0] end
425
- def dmvx(x=nil); x ? dmvxy(x, "0") : ud(*current_point)[0] end
426
- def rmvx x; rmvxy(x, 0) end
427
- def rdmvx x; rdmvxy(x, 0) end
428
-
429
- def mvy(y=nil) y ? mvxy("0", y ) : current_point[1] end
430
- def dmvy(y=nil) y ? dmvxy("0", y) : ud(*current_point)[1] end
431
- def rmvy y; rmvxy(0, y) end
432
- def rmvdy y; rdmvxy(0, y) end
433
-
434
- alias lineto_ line_to
435
- def lineto(x,y) line_to(*__pos(x,y) ) end
436
- def rlineto(x,y) line_to(*__rpos(x,y)) end
437
- def lineno(x,y) bak(:xy){lineto(x,y)} end
438
- def rlineno(x,y) bak(:xy){rlineto(x,y)} end
439
- def line(x,y, x1,y1) bak(:xy){mvxy(x,y); lineto(x1,y1) } end
440
- def rline(x,y, x1,y1) bak(:xy){rmvxy(x,y); rlineto(x1,y1)} end
441
-
442
- def circle(x,y,r); arc(x,y,r,0,360) end
443
- alias arc_ arc
444
- def arc(x,y,r, a1,a2)
445
- x,y=__pos(x,y)
446
- a1,a2=__angle(a1,a2)
447
- new_path # need new_path to clear prior-path
448
- arc_(x,y,r,a1,a2)
449
- end
450
-
451
- alias arc_neg_ arc_negative
452
- def arg_neg(x,y,r, a1,a2)
453
- x,y=__pos(x,y)
454
- a1,a2=__angle(a1,a2)
455
- new_path
456
- arc_negative(x,y,r, a1,a2)
457
- end
458
-
459
-
460
- alias curveto_ curve_to
461
- def curveto(x1,y1, x2,y2, x3,y3)
462
- x1,y1,x2,y2,x3,y3=__pos(x1,y1,x2,y2,x3,y3)
463
- curve_to(x1,y1, x2,y2, x3,y3)
464
- end
465
- alias rcurveto_ rel_curve_to
466
- alias rcurveto rel_curve_to
467
-
468
- alias new_subpath new_sub_path
469
- alias copy_path_ copy_path
470
- def copy_path(flat=false) flat ? copy_path_flat : copy_path_ end
471
-
472
- alias stroke_ stroke
473
- def stroke(preverse=false, &blk)
474
- bak(:xy) {
475
- stroke_(preverse, &blk)
476
- }
477
- end
478
-
479
- # border line_cap _join _dash
480
- alias border_= line_width=
481
- def border=(border)
482
- if String === border
483
- self.dborder = border.to_f
484
- else
485
- @dborder = ud(border)
486
- @border = border
487
- self.line_width = @border
488
- end
489
- end
490
-
491
- def dborder=(border)
492
- @dborder = border
493
- @border = tdu(border)
494
- self.line_width = @border
495
- end
496
-
497
- def line_cap=(cap)
498
- @line_cap = Cairo.const_get("line_cap_#{cap}".upcase)
499
- set_line_cap(@line_cap)
500
- @line_cap
501
- end
502
-
503
- def line_join=(join)
504
- @line_join = Cairo.const_get("line_join_#{join}".upcase)
505
- set_line_join(@line_join)
506
- @line_join
507
- end
508
-
509
- def line_dash=(arg, offset=0)
510
- @line_dash ||=arg
511
- set_line_dash(arg, offset)
512
- @line_dash
513
- end
514
-
515
- def has_pos?; has_current_point? ? true : false end
516
-
517
- # push pos
518
- def push
519
- @xy_stack ||=[]
520
- @xy_stack.push(current_point)
521
- end
522
- def pop
523
- @xy_stack.pop
524
- end
525
-
526
-
527
- alias rotate_ rotate
528
- def rotate(angle); rotate_(__angle(angle)) end
529
-
530
- alias scale_ scale
531
- # args@ tx,ty,keep=true
532
- # keep size border
533
- def scale(*args)
534
- if args.empty?
535
- tdu 1,1
536
- else
537
- tx, ty, keep = args
538
- keep ||= true
539
- tx,ty = __tdu(tx,ty)
540
- scale_(tx,ty)
541
- if keep
542
- self.dsize=@dsize
543
- self.dborder=@dborder
544
- end
545
- end
546
- end
547
- def dscale tx=1,ty=1, keep=true; scale tx.to_s, ty.to_s, keep end
548
-
549
- alias translate_ translate
550
- def translate(*txy)
551
- if txy.empty?
552
- ud 0,0
553
- else
554
- txy_ = xy
555
- translate_(*__du(*txy))
556
- mvxy(*txy_)
557
- end
558
- end
559
-
560
- def btranslate tx=0,ty=0; translate tx.to_s, ty.to_s end
561
-
562
- # ud tud du tdu
563
- alias ud_ user_to_device
564
- alias tud_ user_to_device_distance
565
- # user_to_device
566
- # (x,nil) (nil,y) (x,y)
567
- def ud(x,y=nil)
568
- if y==nil
569
- user_to_device(x,0)[0]
570
- elsif x==nil
571
- user_to_device(0,y)[1]
572
- else
573
- user_to_device(x,y)
574
- end
575
- end
576
-
577
- # user_to_device_sitance
578
- # (x,nil) (nil,y) (x,y)
579
- def tud(x,y=nil)
580
- if y==nil
581
- user_to_device_distance(x, 0)[0]
582
- elsif x==nil
583
- user_to_device_distance(0, y)[1]
584
- else
585
- user_to_device_distance(x,y)
586
- end
587
- end
588
-
589
- alias du_ device_to_user
590
- alias tdu_ device_to_user_distance
591
- # device to user
592
- # (x,nil) (nil,y) (x,y)
593
- def du(x,y=nil)
594
- if y==nil
595
- device_to_user(x,0)[0]
596
- elsif x==nil
597
- device_to_user(0,y)[1]
598
- else
599
- device_to_user(x,y)
600
- end
601
- end
602
-
603
- # device to user distance
604
- # (x,nil) (nil,y) (x,y)
605
- def tdu(x,y=nil)
606
- if y==nil
607
- device_to_user_distance(x, 0)[0]
608
- elsif x==nil
609
- device_to_user_distance(0, y)[1]
610
- else
611
- device_to_user_distance(x,y)
612
- end
613
- end
614
-
615
- # options: xy x y translate scale matrix
616
- # state size
617
- def bak(name, *args)
618
- case name.to_sym
619
- # :xy x y
620
- when :xy
621
- x_, y_ = user_to_device(*current_point)
622
- yield
623
- move_to( *device_to_user(x_, y_))
624
- when :x
625
- x_, y_ = user_to_device(*current_point)
626
- yield
627
- x = device_to_user(x_, y_)[0]
628
- y = current_point[1]
629
- move_to(x,y)
630
- when :y
631
- x_, y_ = user_to_device(*current_point)
632
- yield
633
- x = current_point[0]
634
- y = device_to_user(x_, y_)[1]
635
- move_to(x,y)
636
-
637
- # :translate scale matrix
638
- when :translate
639
- xy_d = ud(0,0)
640
- yield
641
- a = xy_d.gach(&:to_s)
642
- translate(*a)
643
- when :scale
644
- txy_d = tud(1,1)
645
- yield
646
- scale(*txy_d.gach(&:to_s))
647
- when :matrix # combine translate and scale
648
- xy_d = ud(0,0)
649
- txy_d = tud(1,1)
650
- yield
651
- scale(*txy_d.gach(&:to_s))
652
- translate(*xy_d.gach(&:to_s))
653
-
654
- # state
655
- when :state
656
- save
657
- yield
658
- restore
659
-
660
- # size
661
- when :size
662
- size_ = @dsize
663
- yield
664
- self.dsize = size_
665
- when :border
666
- border_ = @dborder
667
- yield
668
- self.dborder = border_
669
-
670
- # all: save xy size
671
- when :all
672
- x_, y_ = user_to_device(*current_point)
673
- size_ = @dsize
674
- save
675
- yield
676
- restore
677
- move_to( *device_to_user(x_, y_))
678
- self.dsize = size_
679
- else
680
- raise ArgumentError, "bak(:#{name})"
681
- end
682
- end # def bak
683
- # selection=[x|y=nil, w|h=nil]
684
- def paint_img(img, selection=nil, rotate=0, scale=1)
685
- # handle arg selection
686
- selection ||= []
687
- select_x,select_y,select_w,select_h = selection
688
- select_x ||= 0; select_y ||= 0
689
- select_w ||= img.w-select_x; select_h ||= img.h-select_y
690
- select_w,select_h=1,1 if select_w<=0 or select_h<=0
691
-
692
- select_w,select_h = select_w*scale.to_f, select_h*scale.to_f
693
- select_x,select_y = select_x*scale.to_f, select_y*scale.to_f
694
-
695
- bak(:state) do
696
-
697
- # rotate
698
- translate(surface.w/2, surface.h/2)
699
- rotate(rotate)
700
- translate(-select_w/2, -select_h/2)
701
-
702
- # selection [x,y,w,h]
703
- rectangle(0,0,select_w,select_h)
704
- clip
705
- translate(-select_x,-select_y)
706
-
707
- # scale
708
- scale(scale, scale)
709
-
710
- # paint
711
- set_source(img)
712
- paint
713
- end
714
- end # def paint_img
715
-
716
- # base on scale(*wh)
717
- # datas: \[ \[..\], \]
718
- def table(datas, oph={})
719
-
720
- # width height
721
- # row_nrs col_nrs
722
- cols = oph[:pos]
723
- spacing = oph[:spacing] || [4,1]
724
- spacing = tdu(*spacing)
725
-
726
- # ==>datas row_nrs and col_nrs
727
- datas = [datas] if not Array===datas[0]
728
- row_nrs = datas.size
729
- col_nrs = datas[0].size
730
-
731
- # ==> cell_height 0.05 height
732
- cell_height = newline_height + spacing[1]*2
733
- height = cell_height * datas.size
734
-
735
- ## ==>cols [0, 0.5, 1.0]
736
- # cell_widths [text_extents..]
737
- if oph[:pos] == "<" || oph[:pos] == ">"
738
- cell_widths = [0]
739
- cell_widths += datas.transpose.gach do |cols|
740
- cols.gach{|v| text_extents(v.to_s).to_a[-2]}.max
741
- end
742
- end
743
-
744
- case oph[:pos]
745
- when "<"
746
- if oph[:border]
747
- pos = cell_widths[0]+spacing[0]*2
748
- cols = [0, pos, pos+cell_widths[1]+spacing[0] ]
749
- else
750
- pos = cell_widths[0]+spacing[0]
751
- cols = [0, pos, pos+cell_widths[1]+spacing[0] ]
752
- end
753
- when ">"
754
- if oph[:border]
755
- pos = 1-(cell_widths[0]+cell_widths[1]+spacing[0]*4)
756
- cols = [ pos, pos+cell_widths[0]+spacing[0]*2, 1 ]
757
- else
758
- pos = 1-(cell_widths[0]+cell_widths[1]+spacing[0]*3)
759
- cols = [ pos, pos+cell_widths[0]+spacing[0], 1 ]
760
- end
761
- else
762
- cols ||= (0..col_nrs).map{|v| v/col_nrs.to_f}
763
- end
764
- width = cols[-1]
765
-
766
-
767
- # draw border
768
- if oph[:border]
769
- rectangle cols[0], "0", cols[-1], height
770
-
771
- # draw rows
772
- bak(:xy) {
773
- row_nrs.each do
774
- ry cell_height; rlineno cols[-1], 0
775
- end
776
- }
777
-
778
- # draw cols
779
- bak(:xy) {
780
- cols.gach do |v|
781
- x v; rlineno 0, height
782
- end
783
- }
784
-
785
- stroke
786
- end
787
-
788
- # draw text
789
- datas.gach do |rows|
790
- bak(:xy) {
791
- rxy 0, spacing[1]
792
- rows.gach do |row, i|
793
- xy cols[i], "0"
794
- rx spacing[0]
795
- showtext row
796
- end
797
- }
798
- ry cell_height
799
- end
800
-
801
- [width, height]
802
- end # def table
803
-
804
- # rectangle with rounded support
805
- alias rectangle_ rectangle
806
- def rectangle(x,y,w,h) rectangle_(*__pos(x,y), *__du(w,h) ) end
807
- def rrectangle(x,y,w,h) rectangle_(*__rpos(x,y), *__du(w,h) ) end
808
-
809
- end # class Context
810
-
811
- end # module Cairo