extract-curves 0.1.1-mswin32

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 (135) hide show
  1. data/Changelog +21 -0
  2. data/bin/ec_rect2polar +22 -0
  3. data/bin/ec_rect2polar.rb +22 -0
  4. data/bin/ec_rev_lines +5 -0
  5. data/bin/ec_rev_lines.rb +5 -0
  6. data/bin/ec_sph_area +30 -0
  7. data/bin/ec_sph_area.rb +30 -0
  8. data/bin/extract_curves +1670 -0
  9. data/bin/extract_curves.rb +1670 -0
  10. data/ruby_ext/pav/extconf.rb +22 -0
  11. data/ruby_ext/pav/pav.dll +0 -0
  12. data/ruby_libs/pav/attr_cache.rb +211 -0
  13. data/ruby_libs/pav/attr_cache.t1.rb +32 -0
  14. data/ruby_libs/pav/cache.rb +31 -0
  15. data/ruby_libs/pav/collection/std.rb +58 -0
  16. data/ruby_libs/pav/dbg_log.rb +458 -0
  17. data/ruby_libs/pav/floatsio.rb +53 -0
  18. data/ruby_libs/pav/generator_cache.rb +165 -0
  19. data/ruby_libs/pav/graph/node.rb +602 -0
  20. data/ruby_libs/pav/graph/node_grp.rb +865 -0
  21. data/ruby_libs/pav/gtk.rb +6 -0
  22. data/ruby_libs/pav/gtk/button.rb +118 -0
  23. data/ruby_libs/pav/gtk/dialog.rb +29 -0
  24. data/ruby_libs/pav/gtk/guiobj.rb +772 -0
  25. data/ruby_libs/pav/gtk/icons.rb +124 -0
  26. data/ruby_libs/pav/gtk/rulers.rb +264 -0
  27. data/ruby_libs/pav/gtk/toolbar.rb +189 -0
  28. data/ruby_libs/pav/guiobj.rb +2 -0
  29. data/ruby_libs/pav/guiobj/info_asm.rb +41 -0
  30. data/ruby_libs/pav/guiobj/method.rb +211 -0
  31. data/ruby_libs/pav/guiobj/obj.rb +134 -0
  32. data/ruby_libs/pav/guiobj/signals.rb +9 -0
  33. data/ruby_libs/pav/heap.rb +54 -0
  34. data/ruby_libs/pav/icons/alt_handle.xpm +3832 -0
  35. data/ruby_libs/pav/icons/alt_handle_hover.xpm +3368 -0
  36. data/ruby_libs/pav/icons/alt_handle_pressed.xpm +3828 -0
  37. data/ruby_libs/pav/icons/blob.gif +0 -0
  38. data/ruby_libs/pav/icons/contour.gif +0 -0
  39. data/ruby_libs/pav/icons/contour_carpet.gif +0 -0
  40. data/ruby_libs/pav/icons/curve.gif +0 -0
  41. data/ruby_libs/pav/icons/curve_carpet.gif +0 -0
  42. data/ruby_libs/pav/icons/expand_closed.xpm +1791 -0
  43. data/ruby_libs/pav/icons/expand_closed_hover.xpm +1775 -0
  44. data/ruby_libs/pav/icons/expand_open.xpm +1788 -0
  45. data/ruby_libs/pav/icons/expand_open_hover.xpm +1752 -0
  46. data/ruby_libs/pav/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  47. data/ruby_libs/pav/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  48. data/ruby_libs/pav/icons/extract_curves/trace_mark.xpm +38 -0
  49. data/ruby_libs/pav/icons/handle.xpm +213 -0
  50. data/ruby_libs/pav/icons/loop.gif +0 -0
  51. data/ruby_libs/pav/icons/loop_carpet.gif +0 -0
  52. data/ruby_libs/pav/icons/next.xpm +29 -0
  53. data/ruby_libs/pav/icons/next_hover.xpm +315 -0
  54. data/ruby_libs/pav/icons/next_pressed.xpm +144 -0
  55. data/ruby_libs/pav/icons/prev.xpm +29 -0
  56. data/ruby_libs/pav/icons/prev_hover.xpm +315 -0
  57. data/ruby_libs/pav/icons/prev_pressed.xpm +144 -0
  58. data/ruby_libs/pav/icons/shaved-core.gif +0 -0
  59. data/ruby_libs/pav/icons/vnext.xpm +29 -0
  60. data/ruby_libs/pav/icons/vprev.xpm +29 -0
  61. data/ruby_libs/pav/numeric/ext.rb +21 -0
  62. data/ruby_libs/pav/patterns/hsep.gif +0 -0
  63. data/ruby_libs/pav/patterns/tnode.gif +0 -0
  64. data/ruby_libs/pav/patterns/tnode_w_link.gif +0 -0
  65. data/ruby_libs/pav/patterns/vlink.gif +0 -0
  66. data/ruby_libs/pav/patterns/vsep.gif +0 -0
  67. data/ruby_libs/pav/patterns/yg_hrope.xpm +492 -0
  68. data/ruby_libs/pav/patterns/yg_hrope_thick.xpm +1904 -0
  69. data/ruby_libs/pav/patterns/yg_hrope_thin.xpm +130 -0
  70. data/ruby_libs/pav/patterns/yg_tnode.xpm +180 -0
  71. data/ruby_libs/pav/patterns/yg_tnode_thick.xpm +615 -0
  72. data/ruby_libs/pav/patterns/yg_tnode_thin.xpm +55 -0
  73. data/ruby_libs/pav/patterns/yg_tnode_w_link.xpm +190 -0
  74. data/ruby_libs/pav/patterns/yg_tnode_w_link_thick.xpm +676 -0
  75. data/ruby_libs/pav/patterns/yg_tnode_w_link_thin.xpm +62 -0
  76. data/ruby_libs/pav/patterns/yg_vrope.xpm +563 -0
  77. data/ruby_libs/pav/patterns/yg_vrope_thick.xpm +2047 -0
  78. data/ruby_libs/pav/patterns/yg_vrope_thin.xpm +166 -0
  79. data/ruby_libs/pav/pav_find.rb +90 -0
  80. data/ruby_libs/pav/pix.rb +402 -0
  81. data/ruby_libs/pav/pix/aapix.rb +378 -0
  82. data/ruby_libs/pav/pix/blob.rb +678 -0
  83. data/ruby_libs/pav/pix/circle.rb +73 -0
  84. data/ruby_libs/pav/pix/contour.rb +676 -0
  85. data/ruby_libs/pav/pix/contour/calc_situations.rb +9 -0
  86. data/ruby_libs/pav/pix/contour/carp_calc.rb +212 -0
  87. data/ruby_libs/pav/pix/contour/situations.dmp +0 -0
  88. data/ruby_libs/pav/pix/contour/situations.rb +21 -0
  89. data/ruby_libs/pav/pix/curve.rb +1544 -0
  90. data/ruby_libs/pav/pix/img_obj.rb +865 -0
  91. data/ruby_libs/pav/pix/node.rb +159 -0
  92. data/ruby_libs/pav/pix/shaved_core.rb +697 -0
  93. data/ruby_libs/pav/pix/subpix.rb +212 -0
  94. data/ruby_libs/pav/rand_accessible.rb +16 -0
  95. data/ruby_libs/pav/rangeset.rb +63 -0
  96. data/ruby_libs/pav/search.rb +210 -0
  97. data/ruby_libs/pav/set.rb +130 -0
  98. data/ruby_libs/pav/string/bits.rb +523 -0
  99. data/ruby_libs/pav/string/ext.rb +58 -0
  100. data/ruby_libs/pav/string/observable.rb +155 -0
  101. data/ruby_libs/pav/string/text.rb +79 -0
  102. data/ruby_libs/pav/string/words.rb +42 -0
  103. data/ruby_libs/pav/sub_arr.rb +56 -0
  104. data/ruby_libs/pav/traced_obj.rb +79 -0
  105. data/web/index.html +280 -0
  106. data/web/media/icons/alt_handle.xpm +3832 -0
  107. data/web/media/icons/alt_handle_hover.xpm +3368 -0
  108. data/web/media/icons/alt_handle_pressed.xpm +3828 -0
  109. data/web/media/icons/blob.gif +0 -0
  110. data/web/media/icons/contour.gif +0 -0
  111. data/web/media/icons/contour_carpet.gif +0 -0
  112. data/web/media/icons/curve.gif +0 -0
  113. data/web/media/icons/curve_carpet.gif +0 -0
  114. data/web/media/icons/expand_closed.xpm +1791 -0
  115. data/web/media/icons/expand_closed_hover.xpm +1775 -0
  116. data/web/media/icons/expand_open.xpm +1788 -0
  117. data/web/media/icons/expand_open_hover.xpm +1752 -0
  118. data/web/media/icons/extract_curves/extract_curves-icon-rgb.ppm +14 -0
  119. data/web/media/icons/extract_curves/extract_curves-logo-rgb.gif +0 -0
  120. data/web/media/icons/extract_curves/trace_mark.xpm +38 -0
  121. data/web/media/icons/handle.xpm +213 -0
  122. data/web/media/icons/loop.gif +0 -0
  123. data/web/media/icons/loop_carpet.gif +0 -0
  124. data/web/media/icons/next.xpm +29 -0
  125. data/web/media/icons/next_hover.xpm +315 -0
  126. data/web/media/icons/next_pressed.xpm +144 -0
  127. data/web/media/icons/prev.xpm +29 -0
  128. data/web/media/icons/prev_hover.xpm +315 -0
  129. data/web/media/icons/prev_pressed.xpm +144 -0
  130. data/web/media/icons/shaved-core.gif +0 -0
  131. data/web/media/icons/vnext.xpm +29 -0
  132. data/web/media/icons/vprev.xpm +29 -0
  133. data/web/media/title.jpeg +0 -0
  134. data/web/stylesheets/default.css +20 -0
  135. metadata +192 -0
@@ -0,0 +1,166 @@
1
+ /* XPM */
2
+ static char * yg_vrope_thin_xpm[] = {
3
+ "5 41 122 2",
4
+ " c None",
5
+ ". c #6EB880",
6
+ "+ c #4FD7BB",
7
+ "@ c #487C5F",
8
+ "# c #808C50",
9
+ "$ c #41C29E",
10
+ "% c #4BA086",
11
+ "& c #B49E5A",
12
+ "* c #54A576",
13
+ "= c #41A889",
14
+ "- c #F7E9A5",
15
+ "; c #C3B276",
16
+ "> c #5A8F6E",
17
+ ", c #6DC59B",
18
+ "' c #EEE7BA",
19
+ ") c #B7AC79",
20
+ "! c #289D7B",
21
+ "~ c #6E975E",
22
+ "{ c #F0E6B8",
23
+ "] c #657057",
24
+ "^ c #35B69A",
25
+ "/ c #2E764F",
26
+ "( c #E8DFAB",
27
+ "_ c #6D7157",
28
+ ": c #71EFDE",
29
+ "< c #289B7E",
30
+ "[ c #A0B284",
31
+ "} c #67E7D1",
32
+ "| c #3F977B",
33
+ "1 c #A8A55D",
34
+ "2 c #3CA579",
35
+ "3 c #5FD5BF",
36
+ "4 c #C6B067",
37
+ "5 c #548653",
38
+ "6 c #6DE2CE",
39
+ "7 c #C6B474",
40
+ "8 c #58AC8C",
41
+ "9 c #F2EAC0",
42
+ "0 c #A1A57E",
43
+ "a c #30AF8F",
44
+ "b c #719458",
45
+ "c c #E1D8B0",
46
+ "d c #32B297",
47
+ "e c #378658",
48
+ "f c #E5DDAF",
49
+ "g c #78F0E1",
50
+ "h c #2DAA8B",
51
+ "i c #BCC69E",
52
+ "j c #61E9D2",
53
+ "k c #579E80",
54
+ "l c #B4B870",
55
+ "m c #48CAAB",
56
+ "n c #67C7B0",
57
+ "o c #B4A85D",
58
+ "p c #399D71",
59
+ "q c #8BE4D2",
60
+ "r c #E6CD65",
61
+ "s c #7BA16B",
62
+ "t c #84D6C5",
63
+ "u c #E2D988",
64
+ "v c #EADA91",
65
+ "w c #6D9474",
66
+ "x c #48BD95",
67
+ "y c #D7CF95",
68
+ "z c #C5C2A0",
69
+ "A c #37B495",
70
+ "B c #749B5E",
71
+ "C c #E1DBB8",
72
+ "D c #62E3CF",
73
+ "E c #509865",
74
+ "F c #D7D3B0",
75
+ "G c #6EEED9",
76
+ "H c #49CEB2",
77
+ "I c #92A37C",
78
+ "J c #91C886",
79
+ "K c #68E6D0",
80
+ "L c #62AC91",
81
+ "M c #B2B368",
82
+ "N c #3DB491",
83
+ "O c #88D7C2",
84
+ "P c #D9CA7E",
85
+ "Q c #3DA174",
86
+ "R c #76D3BB",
87
+ "S c #F8EEBF",
88
+ "T c #BBCFA1",
89
+ "U c #6AB697",
90
+ "V c #C5E0B2",
91
+ "W c #F4EBC1",
92
+ "X c #869470",
93
+ "Y c #46BA91",
94
+ "Z c #C0BC79",
95
+ "` c #BCBB92",
96
+ " . c #3EBD9E",
97
+ ".. c #80A768",
98
+ "+. c #DBD6AE",
99
+ "@. c #6BEBD5",
100
+ "#. c #62C6A0",
101
+ "$. c #D1D1AF",
102
+ "%. c #68D4A8",
103
+ "&. c #7CEFDB",
104
+ "*. c #679879",
105
+ "=. c #BCC776",
106
+ "-. c #36AA88",
107
+ ";. c #6EC5AB",
108
+ ">. c #E0D47B",
109
+ ",. c #35895E",
110
+ "'. c #4CB397",
111
+ "). c #FAF2C6",
112
+ "!. c #ABC38E",
113
+ "~. c #4FB08E",
114
+ "{. c #D5DBA3",
115
+ "]. c #FBF4D0",
116
+ "^. c #AFB68C",
117
+ "/. c #5FD8B7",
118
+ "(. c #C9C388",
119
+ "_. c #E5DEB7",
120
+ ":. c #6EE4CF",
121
+ "<. c #5A975E",
122
+ "[. c #E0D7A8",
123
+ "}. c #8BF2E1",
124
+ "|. c #4CC19D",
125
+ "1. c #BCC08E",
126
+ " . + @ ",
127
+ " # $ % ",
128
+ " & * = ",
129
+ " - ; > ",
130
+ " , ' ) ",
131
+ " ! ~ { ] ",
132
+ " ^ / ( _ ",
133
+ " : < [ ",
134
+ " } | ",
135
+ " 1 2 3 ",
136
+ " 4 5 6 ",
137
+ " 7 8 ",
138
+ " 9 0 ",
139
+ " a b c ",
140
+ " d e f ",
141
+ " g h i ",
142
+ " j k ",
143
+ " l m n ",
144
+ " o p q ",
145
+ " r s t ",
146
+ " u v w ",
147
+ " x y z ",
148
+ " A B C ",
149
+ " D E F ",
150
+ " G H I ",
151
+ " J K L ",
152
+ " M N O ",
153
+ " P Q R ",
154
+ " S T U ",
155
+ " V W X ",
156
+ " Y Z ` ",
157
+ " ...+. ",
158
+ " @.#.$. ",
159
+ " %.&.*. ",
160
+ " =.-.;. ",
161
+ " >.,.'. ",
162
+ " ).!.~. ",
163
+ " {.].^. ",
164
+ " /.(._. ",
165
+ " :.<.[. ",
166
+ " }.|.1. "};
@@ -0,0 +1,90 @@
1
+ # From Ruby's Find module:
2
+ module PavFind
3
+ def self.pfind_follow_symlinks(paths)
4
+ paths = paths.collect{|d| d.dup}
5
+ while file = paths.shift
6
+ catch(:prune) do
7
+ next unless File.exist? file
8
+ yield file.dup.taint
9
+ begin
10
+ if File.directory?(file) then
11
+ d = Dir.open(file)
12
+ begin
13
+ for f in d
14
+ next if f == "." or f == ".."
15
+ if File::ALT_SEPARATOR and
16
+ file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/ then
17
+ f = file + f
18
+ elsif file == "/" then
19
+ f = "/" + f
20
+ else
21
+ f = File.join(file, f)
22
+ end
23
+ paths.unshift f.untaint
24
+ end
25
+ ensure
26
+ d.close
27
+ end
28
+ end
29
+ rescue Errno::ENOENT, Errno::EACCES
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.pfind_no_follow_symlinks(paths)
36
+ paths = paths.collect{|d| d.dup}
37
+ while file = paths.shift
38
+ catch(:prune) do
39
+ next unless File.exist? file
40
+ yield file.dup.taint
41
+ begin
42
+ if File.lstat(file).directory? then
43
+ d = Dir.open(file)
44
+ begin
45
+ for f in d
46
+ next if f == "." or f == ".."
47
+ if File::ALT_SEPARATOR and
48
+ file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/ then
49
+ f = file + f
50
+ elsif file == "/" then
51
+ f = "/" + f
52
+ else
53
+ f = File.join(file, f)
54
+ end
55
+ paths.unshift f.untaint
56
+ end
57
+ ensure
58
+ d.close
59
+ end
60
+ end
61
+ rescue Errno::ENOENT, Errno::EACCES
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def self.pfind(paths, follow_symlinks=true, entry_visit_once=true, &block)
68
+ if follow_symlinks
69
+ if entry_visit_once
70
+ visited = {}
71
+ self.pfind_follow_symlinks(paths) { |path|
72
+ if visited.include?(path)
73
+ self.prune
74
+ else
75
+ yield(path)
76
+ visited[path] = true
77
+ end
78
+ }
79
+ else
80
+ self.pfind_follow_symlinks(paths, &block)
81
+ end
82
+ else
83
+ self.pfind_no_follow_symlinks(paths, &block)
84
+ end
85
+ end
86
+
87
+ def self.prune
88
+ throw :prune
89
+ end
90
+ end
@@ -0,0 +1,402 @@
1
+ require 'gtk2'
2
+ require 'sync'
3
+ require 'observer'
4
+ require 'pav/sub_arr'
5
+ require 'pav/attr_cache'
6
+ require 'pav/string/ext'
7
+
8
+ begin
9
+ require 'pav/pav'
10
+ rescue LoadError
11
+
12
+ module PPix
13
+
14
+ class Xy
15
+ attr_accessor :x, :y
16
+
17
+ def initialize(x, y)
18
+ @x = x
19
+ @y = y
20
+ end
21
+
22
+ def coords_to_s
23
+ "(#{@x}, #{@y})"
24
+ end
25
+ end
26
+
27
+ class Xy
28
+ ADJACENT4 = [Xy.new(1, 0), Xy.new(0, 1), Xy.new(-1, 0), Xy.new(0, -1)]
29
+ ADJACENT8 = ADJACENT4 + [Xy.new(1,1), Xy.new(-1,1),
30
+ Xy.new(-1,-1), Xy.new(1, -1)]
31
+ end
32
+
33
+ class PixbufPix < Xy
34
+ include AttrCache
35
+
36
+ attr_reader :pixbuf, :x, :y, :color_id, :yx
37
+
38
+ def self.rgb_to_hsv(r, g, b)
39
+ # From the colorsys module of Python 2.4:
40
+ maxc = [r, g, b].max
41
+ minc = [r, g, b].min
42
+ v = maxc
43
+ return [0.0, 0.0, v] if minc == maxc
44
+ s = (maxc-minc) / maxc
45
+ rc = (maxc-r) / (maxc-minc)
46
+ gc = (maxc-g) / (maxc-minc)
47
+ bc = (maxc-b) / (maxc-minc)
48
+ if r == maxc then h = bc-gc
49
+ elsif g == maxc then h = 2.0+rc-bc
50
+ else h = 4.0+gc-rc; end
51
+ h = (h/6.0) % 1.0
52
+ [h, s, v]
53
+ end
54
+
55
+ def initialize(pixbuf, x, y)
56
+ @pixbuf = pixbuf
57
+ @x = x
58
+ @y = y
59
+ @yx = [y, x]
60
+ #@pixbuf.add_observer(PixbufObserver.new(self))
61
+ end
62
+
63
+ def color_id
64
+ #$PDbgLog.sig_call(self); c =
65
+ @pixbuf.pixels[@pixbuf.ofs0 + @y*@pixbuf.rowstride +
66
+ @x*@pixbuf.pix_length, @pixbuf.pix_length]
67
+ #$PDbgLog.sig_return("#{self.coords_to_s}: #{c.unpack("H*")}")
68
+ #c
69
+ end
70
+
71
+ def color_rgb
72
+ #$PDbgLog.sig_call(self)
73
+ cid = self.color_id; clen = @pixbuf.sample_length
74
+ #res =
75
+ [cid[0,clen].bits_to_i, cid[clen, clen].bits_to_i,
76
+ cid[2*clen, clen].bits_to_i]
77
+ #$PDbgLog.sig_return("color_id=#{cid.inspect}: #{res.inspect}")
78
+ #res
79
+ end
80
+
81
+ def color_hsv
82
+ r, g, b = *self.color_rgb
83
+ c_max = Float((1 << @pixbuf.bits_per_sample) - 1)
84
+ PixbufPix.rgb_to_hsv(r/c_max, g/c_max, b/c_max)
85
+ end
86
+
87
+ def virtual?
88
+ @x < 0 || @x >= @pixbuf.picture_width || @y < 0 ||
89
+ @y >= @pixbuf.picture_height
90
+ end
91
+
92
+ def border?(adjacents = ADJACENT8)
93
+ clr = self.color_id
94
+ for adj in adjacents
95
+ x, y = @x + adj.x, @y + adj.y
96
+ return true if x < 0 || x >= @pixbuf.picture_width ||
97
+ y < 0 || y >= @pixbuf.picture_height
98
+ return true if @pixbuf.get_pix(x, y).color_id != clr
99
+ end
100
+ false
101
+ end
102
+
103
+ def border8?
104
+ self.border?
105
+ end
106
+
107
+ def border4?
108
+ self.border?(ADJACENT4)
109
+ end
110
+
111
+ def adj(adjacents = ADJACENT8)
112
+ res = []
113
+ for adj in adjacents
114
+ if (x=@x+adj.x) >= 0 && x < @pixbuf.picture_width &&
115
+ (y=@y+adj.y) >= 0 && y < @pixbuf.picture_height
116
+ res << @pixbuf[y][x]
117
+ end
118
+ end
119
+ res
120
+ end
121
+
122
+ def adj8
123
+ self.adj
124
+ end
125
+
126
+ def adj4
127
+ self.adj(ADJACENT4)
128
+ end
129
+
130
+ def adj_cocolor(adjacents = ADJACENT8)
131
+ clr = self.color_id
132
+ res = []
133
+ adjacents.each { |adj| x, y = @x + adj.x, @y + adj.y
134
+ if x >= 0 && x < @pixbuf.picture_width && y >= 0 &&
135
+ y < @pixbuf.picture_height
136
+ pix = @pixbuf.get_pix(x, y)
137
+ res << pix if pix.color_id == clr
138
+ end
139
+ }
140
+ res
141
+ end
142
+
143
+ def adj_cocolor8
144
+ self.adj_cocolor
145
+ end
146
+
147
+ def adj_cocolor4
148
+ self.adj_cocolor(ADJACENT4)
149
+ end
150
+
151
+ def adj_fuzzy_rgb_cocolor(adjacents=ADJACENT8, r_toler=10, g_toler=10,
152
+ b_toler=10)
153
+ r, g, b = *self.color_rgb
154
+ w = @pixbuf.picture_width; h = @pixbuf.picture_height
155
+ res = []
156
+ adjacents.each { |adj| x = @x + adj.x; y = @y + adj.y
157
+ if x >= 0 && x < w && y >= 0 && y < h
158
+ ra, ga, ba = *(apix = @pixbuf.get_pix(x,y)).color_rgb
159
+ res << apix if (ra - r).abs <= r_toler &&
160
+ (ga - g).abs <= g_toler &&
161
+ (ba - b).abs <= b_toler
162
+ end
163
+ }
164
+ res
165
+ end
166
+
167
+ def adj_fuzzy_hsv_cocolor(adjacents=ADJACENT8, h_toler=0.1, s_toler=0.1,
168
+ v_toler=0.1)
169
+ h, s, v = *self.color_hsv
170
+ w = @pixbuf.picture_width; hgt = @pixbuf.picture_height
171
+ res = []
172
+ adjacents.each { |adj| x = @x + adj.x; y = @y + adj.y
173
+ if x >= 0 && x < w && y >= 0 && y < hgt
174
+ ha, sa, va = *(apix = @pixbuf.get_pix(x,y)).color_hsv
175
+ res << apix if (ha - h).abs <= h_toler &&
176
+ (sa - s).abs <= s_toler &&
177
+ (va - v).abs <= v_toler
178
+ end
179
+ }
180
+ res
181
+ end
182
+
183
+ #cache_attr! :color_id, :color_rgb
184
+ #freeze_cache_attr! :border8?, :border4?, :adj8, :adj4, :adj_cocolor8,
185
+ # :adj_cocolor4, :adj_border_cocolor8_4, :color_hsv
186
+
187
+ def color_id=(val)
188
+ @pixbuf.set_pix(@x, @y, val)
189
+ end
190
+
191
+ def hash
192
+ #@x.hash + @y.hash + @pixbuf.hash
193
+ #self.yx.hash
194
+ @y * @pixbuf.width + @x
195
+ end
196
+ end
197
+
198
+ class Pixbuf #< Gdk::Pixbuf
199
+ #include Sync_m
200
+
201
+ attr_accessor :border_width, :ofs0, :picture_width, :picture_height
202
+ attr_reader :pix_length, :sample_length
203
+
204
+ def initialize(*args)
205
+ unless args.length==1 && (@under=args[0]).kind_of?(Gdk::Pixbuf)
206
+ @under = Gdk::Pixbuf.new(*args)
207
+ end
208
+ @virtual_pix = {}
209
+ @sample_length = self.bits_per_sample / 8
210
+ @pix_length = self.n_channels * @sample_length
211
+ @picture_width = self.width
212
+ @picture_height = self.height
213
+ @border_width = 0
214
+ @ofs0 = 0
215
+ end
216
+
217
+ def method_missing(id, *args, &block)
218
+ @under.send(id, *args, &block)
219
+ end
220
+
221
+ def get_pix(x, y)
222
+ if x < 0 || y < 0 || x >= @picture_width || y >= @picture_height
223
+ tmp = @virtual_pix[[y, x]]
224
+ return tmp if tmp
225
+ return (@virtual_pix[[y, x]] = PixbufPix.new(self,x,y))
226
+ end
227
+ end
228
+
229
+ def set_pix(x, y, clr)
230
+ if x < 0
231
+ if x < -self.width
232
+ return nil
233
+ else x = self.width+x end
234
+ else
235
+ if x >= self.width
236
+ return nil
237
+ end
238
+ end
239
+ if y < 0
240
+ if y < -self.height
241
+ return nil
242
+ else y = self.height+y end
243
+ else
244
+ if y >= self.height
245
+ return nil
246
+ end
247
+ end
248
+ ofs = y*@rowstride + x*@pix_length
249
+ self.synchronize {
250
+ self.changed( c = (@pixels[ofs,@pix_length]==
251
+ (@pixels[ofs,@pix_length]=clr)) )
252
+ if c
253
+ self.notify_observers(self, "set_pix",[x,y,clr],nil)
254
+ pix.update(self, "set_pix",[x,y,clr],nil) if
255
+ @scanlines[y] && (pix = @scanlines[y].pixels[x])
256
+ end
257
+ }
258
+ end
259
+
260
+ def dup
261
+ Pixbuf.new(@pixels.dup, @width, @height, @n_channels,
262
+ @rowstride)
263
+ end
264
+
265
+ def add_border(width)
266
+ res_pb = Gdk::Pixbuf.new(self.colorspace, self.has_alpha?,
267
+ self.bits_per_sample, self.width+2*width,
268
+ self.height+2*width)
269
+ res_pb.scale!(@under, width, width,
270
+ self.width+width, self.height+width, width, width,
271
+ 1, 1, Gdk::Pixbuf::INTERP_NEAREST)
272
+ res_pb = Pixbuf.new(res_pb)
273
+ res_pb.picture_width = self.picture_width
274
+ res_pb.picture_height = self.picture_height
275
+ res_pb.border_width = self.border_width + width
276
+ res_pb
277
+ end
278
+
279
+ def scaled(kx, ky, x, y, width, height)
280
+ res_pb = Gdk::Pixbuf.new(self.colorspace, self.has_alpha?,
281
+ self.bits_per_sample, width, height)
282
+ res_pb.scale!(@under, 0, 0, width, height, -x, -y, kx, ky,
283
+ Gdk::Pixbuf::INTERP_NEAREST)
284
+ res_pb
285
+ end
286
+
287
+ def dup
288
+ res = Pixbuf.new(@under.dup)
289
+ res.picture_width = self.picture_width
290
+ res.picture_height = self.picture_height
291
+ res.ofs0 = self.ofs0
292
+ res.border_width = self.border_width
293
+ res
294
+ end
295
+
296
+ def <=>(other)
297
+ return leg if (leg = @width <=> other.width) != 0
298
+ return leg if (leg = @height <=> other.height) != 0
299
+ return leg if (leg = @pix_length <=> other.pix_length) != 0
300
+ self.object_id <=> other.object_id
301
+ #@pixels <=> other.pixels
302
+ end
303
+
304
+ #cache_attr! :pixels
305
+ end
306
+
307
+ end # module PPix
308
+
309
+ end # require 'pav/pav'
310
+
311
+ module PPix
312
+
313
+ class Xy
314
+ include Comparable
315
+
316
+ ADJ8_CCW_ORDER = [Xy.new(1,-1), Xy.new(0,-1), Xy.new(-1,-1),
317
+ Xy.new(-1,0), Xy.new(-1,1), Xy.new(0,1), Xy.new(1,1), Xy.new(1,0)]
318
+
319
+ ADJ4_CCW_ORDER = (0...4).collect {|i| ADJ8_CCW_ORDER[2*i+1] }
320
+
321
+ def neighb8?(pix)
322
+ dx = (self.x - pix.x).abs; dy = (self.y - pix.y).abs
323
+ dx < 2 && dy < 2
324
+ end
325
+
326
+ def neighb4?(pix)
327
+ dx = (self.x - pix.x).abs; dy = (self.y - pix.y).abs
328
+ (dx < 2 && dy == 0) || (dy < 2 && dx == 0)
329
+ end
330
+
331
+ def self.path_to_s(path)
332
+ path.collect { |xy| xy.coords_to_s }.join(' ')
333
+ end
334
+
335
+ def <=>(other)
336
+ self.yx <=> other.yx
337
+ end
338
+
339
+ def hash
340
+ self.yx.hash
341
+ end
342
+
343
+ def eql?(xy)
344
+ self.yx == xy.yx
345
+ end
346
+ end
347
+
348
+ module MPixbufPix
349
+ def adj_border_cocolor(adjacents = ADJACENT8, border_adj = ADJACENT4)
350
+ self.adj(adjacents).find_all { |pix| pix.border?(border_adj) }
351
+ end
352
+
353
+ def adj_border_cocolor8_4
354
+ self.adj_border_cocolor
355
+ end
356
+
357
+ def adj_border_cocolor4_8
358
+ self.adj_border_cocolor(ADJACENT4, ADJACENT8)
359
+ end
360
+
361
+ def end_pt_excl_yx_set?(excl_set)
362
+ self.adj8.find_all { |pix| !excl_set.include?(pix.yx) }.length<2
363
+ end
364
+
365
+ def end_pt_incl_set?(incl_set)
366
+ self.adj8.find_all { |pix| incl_set.include?(pix) }.length < 2
367
+ end
368
+
369
+ #def to_s
370
+ # self.class.name + self.coords_to_s
371
+ #end
372
+ end
373
+
374
+ class Xy
375
+ def adj8_get_i(adj)
376
+ x = adj.x - self.x; y = adj.y - self.y
377
+ Xy::ADJ8_CCW_ORDER.each_with_index{ |a,i|
378
+ return i if a.y == y && a.x == x }
379
+ nil
380
+ end
381
+
382
+ def self.adj8_xy_id(dx, dy)
383
+ ((dy + 1) << 2) | (dx + 1)
384
+ end
385
+
386
+ tmp1 = []
387
+ ADJ8_CCW_ORDER.each_with_index { |a,i| tmp1[self.adj8_xy_id(a.x,a.y)] =
388
+ [a, i, 1<<i] }
389
+ tmp1[self.adj8_xy_id(0,0)] = [nil, 8, 0]
390
+ ADJ8_ID2SPEC = tmp1
391
+
392
+ def adj8_situation_id(neighbs)
393
+ res = 0
394
+ for ngb in neighbs
395
+ res |= Xy::ADJ8_ID2SPEC.at(PixbufPix.adj8_xy_id(
396
+ ngb.x - self.x, ngb.y - self.y)).at(2)
397
+ end
398
+ res
399
+ end
400
+ end
401
+
402
+ end