contrek 1.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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +84 -0
- data/LICENSE.md +9 -0
- data/README.md +118 -0
- data/Rakefile +19 -0
- data/contrek.gemspec +23 -0
- data/contrek.png +0 -0
- data/ext/cpp_polygon_finder/PolygonFinder/.cproject +136 -0
- data/ext/cpp_polygon_finder/PolygonFinder/.project +27 -0
- data/ext/cpp_polygon_finder/PolygonFinder/.settings/org.eclipse.ltk.core.refactoring.prefs +2 -0
- data/ext/cpp_polygon_finder/PolygonFinder/images/labyrinth.png +0 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/Main.cpp +41 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +69 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +19 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.cpp +52 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.h +32 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp +656 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h +42 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp +48 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.h +32 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp +30 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h +26 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/X_picopng.cpp +576 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.cpp +120 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.h +40 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.cpp +36 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.h +30 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +111 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +80 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +325 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +59 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +206 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +69 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/optionparser.h +2858 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.cpp +23 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.h +23 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.cpp +20 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.h +23 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp +20 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.h +23 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp +20 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.h +21 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +40 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +23 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +19 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +25 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +30 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +21 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +50 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +121 -0
- data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +260 -0
- data/ext/cpp_polygon_finder/extconf.rb +2 -0
- data/lib/contrek/bitmaps/bitmap.rb +21 -0
- data/lib/contrek/bitmaps/chunky_bitmap.rb +33 -0
- data/lib/contrek/bitmaps/painting.rb +40 -0
- data/lib/contrek/bitmaps/png_bitmap.rb +62 -0
- data/lib/contrek/bitmaps/rgb_color.rb +25 -0
- data/lib/contrek/finder/list.rb +132 -0
- data/lib/contrek/finder/list_entry.rb +11 -0
- data/lib/contrek/finder/listable.rb +8 -0
- data/lib/contrek/finder/lists.rb +25 -0
- data/lib/contrek/finder/node.rb +126 -0
- data/lib/contrek/finder/node_cluster.rb +294 -0
- data/lib/contrek/finder/polygon_finder.rb +121 -0
- data/lib/contrek/map/mercator_projection.rb +76 -0
- data/lib/contrek/matchers/matcher.rb +20 -0
- data/lib/contrek/matchers/matcher_hsb.rb +24 -0
- data/lib/contrek/matchers/value_not_matcher.rb +9 -0
- data/lib/contrek/reducers/linear_reducer.rb +25 -0
- data/lib/contrek/reducers/reducer.rb +14 -0
- data/lib/contrek/reducers/uniq_reducer.rb +9 -0
- data/lib/contrek/reducers/visvalingam_reducer.rb +139 -0
- data/lib/contrek/version.rb +3 -0
- data/lib/contrek.rb +58 -0
- metadata +175 -0
@@ -0,0 +1,260 @@
|
|
1
|
+
/*
|
2
|
+
* cpp_polygon_finder.cpp
|
3
|
+
*
|
4
|
+
* Created on: 25 apr 2025
|
5
|
+
* Author: ema
|
6
|
+
* Copyright 2025 Emanuele Cesaroni
|
7
|
+
*/
|
8
|
+
// https://github.com/mapnik/Ruby-Mapnik/blob/master/ext/ruby_mapnik/_mapnik_map.rb.cpp
|
9
|
+
|
10
|
+
#include <iostream>
|
11
|
+
#include <list>
|
12
|
+
#include <rice/rice.hpp>
|
13
|
+
#include <rice/stl.hpp>
|
14
|
+
#include <vector>
|
15
|
+
#include <map>
|
16
|
+
#include <string>
|
17
|
+
|
18
|
+
#include "PolygonFinder/src/polygon/finder/PolygonFinder.h"
|
19
|
+
#include "PolygonFinder/src/polygon/finder/PolygonFinder.cpp"
|
20
|
+
#include "PolygonFinder/src/polygon/finder/NodeCluster.cpp"
|
21
|
+
#include "PolygonFinder/src/polygon/finder/NodeCluster.h"
|
22
|
+
#include "PolygonFinder/src/polygon/finder/Node.cpp"
|
23
|
+
#include "PolygonFinder/src/polygon/finder/Node.h"
|
24
|
+
#include "PolygonFinder/src/polygon/finder/List.cpp"
|
25
|
+
#include "PolygonFinder/src/polygon/finder/List.h"
|
26
|
+
#include "PolygonFinder/src/polygon/finder/Lists.cpp"
|
27
|
+
#include "PolygonFinder/src/polygon/finder/Lists.h"
|
28
|
+
#include "PolygonFinder/src/polygon/bitmaps/Bitmap.h"
|
29
|
+
#include "PolygonFinder/src/polygon/bitmaps/Bitmap.cpp"
|
30
|
+
#include "PolygonFinder/src/polygon/bitmaps/PngBitmap.h"
|
31
|
+
#include "PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp"
|
32
|
+
#include "PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h"
|
33
|
+
#include "PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp"
|
34
|
+
#include "PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h"
|
35
|
+
#include "PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp"
|
36
|
+
#include "PolygonFinder/src/polygon/matchers/Matcher.h"
|
37
|
+
#include "PolygonFinder/src/polygon/matchers/Matcher.cpp"
|
38
|
+
#include "PolygonFinder/src/polygon/matchers/ValueNotMatcher.h"
|
39
|
+
#include "PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp"
|
40
|
+
#include "PolygonFinder/src/polygon/matchers/RGBMatcher.h"
|
41
|
+
#include "PolygonFinder/src/polygon/matchers/RGBMatcher.cpp"
|
42
|
+
#include "PolygonFinder/src/polygon/matchers/RGBNotMatcher.h"
|
43
|
+
#include "PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp"
|
44
|
+
#include "PolygonFinder/src/polygon/reducers/Reducer.cpp"
|
45
|
+
#include "PolygonFinder/src/polygon/reducers/Reducer.h"
|
46
|
+
#include "PolygonFinder/src/polygon/reducers/UniqReducer.cpp"
|
47
|
+
#include "PolygonFinder/src/polygon/reducers/UniqReducer.h"
|
48
|
+
#include "PolygonFinder/src/polygon/reducers/LinearReducer.cpp"
|
49
|
+
#include "PolygonFinder/src/polygon/reducers/LinearReducer.h"
|
50
|
+
#include "PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp"
|
51
|
+
#include "PolygonFinder/src/polygon/reducers/VisvalingamReducer.h"
|
52
|
+
#include "png++/png.hpp"
|
53
|
+
|
54
|
+
using namespace Rice;
|
55
|
+
|
56
|
+
namespace Rice::detail
|
57
|
+
{ template<>
|
58
|
+
class To_Ruby<std::list<Point*> >
|
59
|
+
{ public:
|
60
|
+
VALUE convert(std::list<Point*> const & x)
|
61
|
+
{ return Rice::Array(x.begin(), x.end());
|
62
|
+
}
|
63
|
+
};
|
64
|
+
|
65
|
+
template<>
|
66
|
+
class To_Ruby<std::list<std::list<Point*>>>
|
67
|
+
{ public:
|
68
|
+
VALUE convert(std::list<std::list<Point*>> const & x)
|
69
|
+
{ return Rice::Array(x.begin(), x.end());
|
70
|
+
}
|
71
|
+
};
|
72
|
+
|
73
|
+
template<>
|
74
|
+
class To_Ruby<std::list<Point*>*>
|
75
|
+
{ public:
|
76
|
+
VALUE convert(std::list<Point*>* const & x)
|
77
|
+
{ return Rice::Array(x->begin(), x->end());
|
78
|
+
}
|
79
|
+
};
|
80
|
+
|
81
|
+
template<>
|
82
|
+
class To_Ruby<std::list<std::list<Point*>*>>
|
83
|
+
{ public:
|
84
|
+
VALUE convert(std::list<std::list<Point*>*> const & x)
|
85
|
+
{ return Rice::Array(x.begin(), x.end());
|
86
|
+
}
|
87
|
+
};
|
88
|
+
|
89
|
+
template<>
|
90
|
+
class To_Ruby<Point*>
|
91
|
+
{ public:
|
92
|
+
VALUE convert(Point* const & x)
|
93
|
+
{ Rice::Hash h = Rice::Hash();
|
94
|
+
h[Symbol("x")] = x->x;
|
95
|
+
h[Symbol("y")] = x->y;
|
96
|
+
return(h);
|
97
|
+
}
|
98
|
+
};
|
99
|
+
|
100
|
+
template<>
|
101
|
+
class To_Ruby<std::map<std::string, double>*>
|
102
|
+
{ public:
|
103
|
+
VALUE convert(std::map<std::string, double>* const & x)
|
104
|
+
{ Rice::Hash return_me = Rice::Hash();
|
105
|
+
std::map<std::string, double>::iterator it;
|
106
|
+
for ( it = x->begin(); it != x->end(); it++ )
|
107
|
+
{ return_me[String(it->first)] = it->second;
|
108
|
+
}
|
109
|
+
return return_me;
|
110
|
+
}
|
111
|
+
};
|
112
|
+
|
113
|
+
template<>
|
114
|
+
class From_Ruby<std::vector<std::string>*>
|
115
|
+
{ public:
|
116
|
+
Convertible is_convertible(VALUE value)
|
117
|
+
{ switch (rb_type(value))
|
118
|
+
{ case RUBY_T_HASH:
|
119
|
+
return Convertible::Cast;
|
120
|
+
break;
|
121
|
+
default:
|
122
|
+
return Convertible::None;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
std::vector<std::string>* convert(VALUE value)
|
126
|
+
{ std::vector<std::string> *arguments = new std::vector<std::string>();
|
127
|
+
if (rb_type(value) == RUBY_T_NIL) return(arguments);
|
128
|
+
Rice::Hash hash = (Rice::Hash) value;
|
129
|
+
for (Rice::Hash::iterator it = hash.begin(); it != hash.end(); ++it) {
|
130
|
+
Rice::String keyString = it->key.to_s();
|
131
|
+
Rice::Object value = it->value;
|
132
|
+
switch (value.rb_type()) {
|
133
|
+
case T_STRING:
|
134
|
+
arguments->push_back("--" + keyString.str()+"="+((Rice::String) value).str());
|
135
|
+
break;
|
136
|
+
case T_SYMBOL:
|
137
|
+
arguments->push_back("--" + keyString.str()+"="+((Rice::Symbol) value).str());
|
138
|
+
break;
|
139
|
+
case T_FLOAT:
|
140
|
+
arguments->push_back("--" + keyString.str()+"="+std::to_string(NUM2DBL(value.value())));
|
141
|
+
break;
|
142
|
+
case T_FIXNUM:
|
143
|
+
arguments->push_back("--" + keyString.str()+"="+std::to_string(NUM2INT(value.value())));
|
144
|
+
break;
|
145
|
+
case T_TRUE:
|
146
|
+
arguments->push_back("--" + keyString.str()+"=true");
|
147
|
+
break;
|
148
|
+
case T_FALSE:
|
149
|
+
arguments->push_back("--" + keyString.str()+"=false");
|
150
|
+
break;
|
151
|
+
case T_HASH:
|
152
|
+
std::vector<std::string>* iv = From_Ruby<std::vector<std::string>*>::convert(value);
|
153
|
+
for (std::vector<std::string>::iterator it_iv = iv->begin() ; it_iv != iv->end(); ++it_iv)
|
154
|
+
{ (*it_iv).replace(0, 2, "_");
|
155
|
+
arguments->push_back("--" + keyString.str() + *it_iv);
|
156
|
+
}
|
157
|
+
break;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
return arguments;
|
161
|
+
}
|
162
|
+
};
|
163
|
+
|
164
|
+
template<>
|
165
|
+
struct Type<ProcessResult>
|
166
|
+
{ static bool verify()
|
167
|
+
{ return true;
|
168
|
+
}
|
169
|
+
};
|
170
|
+
|
171
|
+
template<>
|
172
|
+
class To_Ruby<ProcessResult*>
|
173
|
+
{ public:
|
174
|
+
VALUE convert(ProcessResult* const & pr)
|
175
|
+
{ Rice::Hash return_me = Rice::Hash();
|
176
|
+
return_me[Symbol("benchmarks")] = &pr->benchmarks;
|
177
|
+
return_me[Symbol("groups")] = pr->groups;
|
178
|
+
return_me[Symbol("named_sequence")] = pr->named_sequence;
|
179
|
+
Rice::Array out;
|
180
|
+
for (std::list<std::map<std::string, std::list<std::list<Point*>*>>>::iterator x = pr->polygons.begin(); x != pr->polygons.end(); ++x)
|
181
|
+
{ Rice::Hash h = Rice::Hash();
|
182
|
+
h[Symbol("outer")] = (*x)["outer"].front();
|
183
|
+
h[Symbol("inner")] = (*x)["inner"];
|
184
|
+
out.push(h);
|
185
|
+
}
|
186
|
+
return_me[Symbol("polygons")] = out;
|
187
|
+
Rice::Array tmapout;
|
188
|
+
for (std::list<int*>::iterator tm = pr->treemap.begin(); tm != pr->treemap.end(); ++tm)
|
189
|
+
{ Rice::Array tmentry;
|
190
|
+
tmentry.push((*tm)[0]);
|
191
|
+
tmentry.push((*tm)[1]);
|
192
|
+
tmapout.push(tmentry);
|
193
|
+
}
|
194
|
+
return_me[Symbol("treemap")] = tmapout;
|
195
|
+
return(return_me);
|
196
|
+
}
|
197
|
+
};
|
198
|
+
} // namespace Rice::detail
|
199
|
+
|
200
|
+
extern "C"
|
201
|
+
void Init_cpp_polygon_finder() {
|
202
|
+
Data_Type<Bitmap> rb_cBitmap =
|
203
|
+
define_class<Bitmap>("CPPBitMap")
|
204
|
+
.define_constructor(Constructor<Bitmap, std::string, int>())
|
205
|
+
.define_method("value_set", &Bitmap::value_set)
|
206
|
+
.define_method("value_at", &Bitmap::value_at)
|
207
|
+
.define_method("w", &Bitmap::w)
|
208
|
+
.define_method("h", &Bitmap::h)
|
209
|
+
.define_method("error", &Bitmap::error)
|
210
|
+
.define_method("clear", &Bitmap::clear)
|
211
|
+
.define_method("print", &Bitmap::print);
|
212
|
+
|
213
|
+
Data_Type<RemoteFastPngBitmap> rb_cRemotePngBitmap =
|
214
|
+
define_class<RemoteFastPngBitmap, Bitmap>("CPPRemotePngBitMap")
|
215
|
+
.define_constructor(Constructor<RemoteFastPngBitmap, std::string*>(), Arg("url"))
|
216
|
+
.define_method("value_set", &FastPngBitmap::value_set)
|
217
|
+
.define_method("value_at", &FastPngBitmap::value_at)
|
218
|
+
.define_method("rgb_value_at", &FastPngBitmap::rgb_value_at)
|
219
|
+
.define_method("w", &FastPngBitmap::w)
|
220
|
+
.define_method("h", &FastPngBitmap::h)
|
221
|
+
.define_method("error", &FastPngBitmap::error)
|
222
|
+
.define_method("print", &FastPngBitmap::print);
|
223
|
+
|
224
|
+
Data_Type<FastPngBitmap> rb_cPngBitmap =
|
225
|
+
define_class<FastPngBitmap, Bitmap>("CPPPngBitMap")
|
226
|
+
.define_constructor(Constructor<FastPngBitmap, std::string>(), Arg("filename"))
|
227
|
+
.define_method("value_set", &FastPngBitmap::value_set)
|
228
|
+
.define_method("value_at", &FastPngBitmap::value_at)
|
229
|
+
.define_method("rgb_value_at", &FastPngBitmap::rgb_value_at)
|
230
|
+
.define_method("w", &FastPngBitmap::w)
|
231
|
+
.define_method("h", &FastPngBitmap::h)
|
232
|
+
.define_method("error", &FastPngBitmap::error)
|
233
|
+
.define_method("print", &FastPngBitmap::print);
|
234
|
+
|
235
|
+
Data_Type<Matcher> rb_cMatcher =
|
236
|
+
define_class<Matcher>("CPPMatcher")
|
237
|
+
.define_constructor(Constructor<Matcher, char>())
|
238
|
+
.define_method("match", &Matcher::match);
|
239
|
+
|
240
|
+
Data_Type<ValueNotMatcher> rb_cValueNotMatcher =
|
241
|
+
define_class<ValueNotMatcher, Matcher>("CPPValueNotMatcher")
|
242
|
+
.define_constructor(Constructor<ValueNotMatcher, char>())
|
243
|
+
.define_method("match", &ValueNotMatcher::match);
|
244
|
+
|
245
|
+
Data_Type<RGBMatcher> rb_cRGBMatcher =
|
246
|
+
define_class<RGBMatcher, Matcher>("CPPRGBMatcher")
|
247
|
+
.define_constructor(Constructor<RGBMatcher, unsigned int>())
|
248
|
+
.define_method("match", &RGBMatcher::match);
|
249
|
+
|
250
|
+
Data_Type<RGBNotMatcher> rb_cRGBNotMatcher =
|
251
|
+
define_class<RGBNotMatcher, Matcher>("CPPRGBNotMatcher")
|
252
|
+
.define_constructor(Constructor<RGBNotMatcher, int>())
|
253
|
+
.define_method("match", &RGBNotMatcher::match);
|
254
|
+
|
255
|
+
Data_Type<PolygonFinder> rb_cPolygonFinder =
|
256
|
+
define_class<PolygonFinder>("CPPPolygonFinder")
|
257
|
+
.define_constructor(Constructor<PolygonFinder, Bitmap*, Matcher*, Bitmap*, std::vector<std::string>*>(), Arg("bitmap"), Arg("matcher"), Arg("test_bitmap") = nullptr, Arg("options") = nullptr)
|
258
|
+
.define_method("get_shapelines", &PolygonFinder::get_shapelines)
|
259
|
+
.define_method("process_info", &PolygonFinder::process_info);
|
260
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Contrek
|
2
|
+
module Bitmaps
|
3
|
+
class ChunkyBitmap < Bitmap
|
4
|
+
def initialize(data, mod)
|
5
|
+
@raw = data.dup
|
6
|
+
@module = mod
|
7
|
+
end
|
8
|
+
|
9
|
+
def clear(val = "0")
|
10
|
+
@raw = val * @module * h
|
11
|
+
end
|
12
|
+
|
13
|
+
def w
|
14
|
+
@module
|
15
|
+
end
|
16
|
+
|
17
|
+
def h
|
18
|
+
@raw.size / @module
|
19
|
+
end
|
20
|
+
|
21
|
+
def value_at(x, y)
|
22
|
+
@raw[y * @module + x]
|
23
|
+
end
|
24
|
+
|
25
|
+
def value_set(x, y, value)
|
26
|
+
return if y >= h
|
27
|
+
return if x >= w
|
28
|
+
|
29
|
+
@raw[y * @module + x] = value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Contrek
|
2
|
+
module Bitmaps
|
3
|
+
module Painting
|
4
|
+
def draw_line(start_x, start_y, end_x, end_y, value)
|
5
|
+
raise NoMethodError
|
6
|
+
end
|
7
|
+
|
8
|
+
def bitmap_colors(step: 1, max: 0)
|
9
|
+
colors = {}
|
10
|
+
step = 1 if step <= 0
|
11
|
+
0.step(h - 1, step) do |h|
|
12
|
+
0.step(w - 1, step) do |w|
|
13
|
+
color = value_at(w, h)
|
14
|
+
colors[color] ||= 0
|
15
|
+
colors[color] += 1
|
16
|
+
break if colors.size == max
|
17
|
+
end
|
18
|
+
end
|
19
|
+
colors.sort_by { |color, count| -color }
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.direct_draw_polygons(polygons, png_image)
|
23
|
+
polygons.compact.each do |poly|
|
24
|
+
color = ChunkyPNG::Color("red @ 1.0")
|
25
|
+
poly[:outer].each_cons(2) do |coords|
|
26
|
+
png_image.draw_line(coords[0][:x], coords[0][:y], coords[1][:x], coords[1][:y], color)
|
27
|
+
end
|
28
|
+
png_image.draw_line(poly[:outer][0][:x], poly[:outer][0][:y], poly[:outer][-1][:x], poly[:outer][-1][:y], color)
|
29
|
+
color = ChunkyPNG::Color("green @ 1.0")
|
30
|
+
poly[:inner].each do |sequence|
|
31
|
+
sequence.each_cons(2) do |coords|
|
32
|
+
png_image.draw_line(coords[0][:x], coords[0][:y], coords[1][:x], coords[1][:y], color)
|
33
|
+
end
|
34
|
+
png_image.draw_line(sequence[0][:x], sequence[0][:y], sequence[-1][:x], sequence[-1][:y], color)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "chunky_png"
|
2
|
+
|
3
|
+
module Contrek
|
4
|
+
module Bitmaps
|
5
|
+
class PngBitmap < Bitmap
|
6
|
+
def initialize(file_path)
|
7
|
+
@image = ChunkyPNG::Image.from_file(file_path)
|
8
|
+
end
|
9
|
+
|
10
|
+
def w
|
11
|
+
@image.dimension.width
|
12
|
+
end
|
13
|
+
|
14
|
+
def h
|
15
|
+
@image.dimension.height
|
16
|
+
end
|
17
|
+
|
18
|
+
def draw_line(start_x, start_y, end_x, end_y, value)
|
19
|
+
@image.line_xiaolin_wu(start_x, start_y, end_x, end_y, value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def value_at(x, y)
|
23
|
+
@image[x, y]
|
24
|
+
end
|
25
|
+
|
26
|
+
def rgb_value_at(x, y)
|
27
|
+
value_at(x, y)
|
28
|
+
end
|
29
|
+
|
30
|
+
def hsv_at(x, y)
|
31
|
+
@image.get_pixel(x, y).to_hsv
|
32
|
+
end
|
33
|
+
|
34
|
+
def value_set(x, y, value)
|
35
|
+
@image[x, y] = value
|
36
|
+
end
|
37
|
+
|
38
|
+
def save(filename)
|
39
|
+
@image.save(filename, interlace: true, compression: Zlib::NO_COMPRESSION)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_tmp_file
|
43
|
+
tmp_png_file = Tempfile.new
|
44
|
+
tmp_png_file.binmode
|
45
|
+
tmp_png_file.write(@image.to_blob)
|
46
|
+
tmp_png_file
|
47
|
+
end
|
48
|
+
|
49
|
+
def resize_h(new_h)
|
50
|
+
old_w = w
|
51
|
+
old_h = h
|
52
|
+
|
53
|
+
new_w = (old_w * new_h) / old_h
|
54
|
+
@image = @image.resize(new_w, new_h)
|
55
|
+
end
|
56
|
+
|
57
|
+
def inspect
|
58
|
+
"PngBitMap"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Contrek
|
2
|
+
module Bitmaps
|
3
|
+
class RgbColor
|
4
|
+
attr_reader :raw
|
5
|
+
def initialize(r:, g:, b:, a: 255)
|
6
|
+
@r = r
|
7
|
+
@g = g
|
8
|
+
@b = b
|
9
|
+
@a = a
|
10
|
+
@raw = (r << 24) + (g << 16) + (b << 8) + a
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_rgb_raw
|
14
|
+
@raw >> 8
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.reverse_raw(raw)
|
18
|
+
[:a, :b, :g, :r].each_with_object({}) do |c, h|
|
19
|
+
h[c] = raw & 0xFF
|
20
|
+
raw >>= 8
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module Contrek
|
2
|
+
module Finder
|
3
|
+
class List
|
4
|
+
attr_reader :start, :end, :size, :idd
|
5
|
+
def initialize(id)
|
6
|
+
@start = nil
|
7
|
+
@end = nil
|
8
|
+
@size = 0
|
9
|
+
@idd = id
|
10
|
+
end
|
11
|
+
|
12
|
+
def first
|
13
|
+
@start
|
14
|
+
end
|
15
|
+
|
16
|
+
def find
|
17
|
+
each { |e| return e if yield(e) }
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def contains(entry)
|
22
|
+
entry.data_pointer[@idd].inside
|
23
|
+
end
|
24
|
+
|
25
|
+
def grab(source_list)
|
26
|
+
return if source_list.size == 0
|
27
|
+
|
28
|
+
source_list_idd = source_list.idd
|
29
|
+
source_list_start_entry = source_list.start
|
30
|
+
|
31
|
+
act = source_list.end
|
32
|
+
loop do
|
33
|
+
break if (act = act.data_pointer[source_list_idd].prev).nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
source_entry = source_list.start
|
37
|
+
loop do
|
38
|
+
source_entry.data_pointer[@idd] = source_entry.data_pointer[source_list_idd]
|
39
|
+
next_entry = source_entry.data_pointer[source_list_idd].next
|
40
|
+
source_entry.data_pointer[source_list_idd] = Contrek::Finder::Lists::Link.new(nil, nil, false)
|
41
|
+
break if next_entry.nil?
|
42
|
+
source_entry = next_entry
|
43
|
+
end
|
44
|
+
|
45
|
+
source_list_start_entry.data_pointer[@idd].prev = @end
|
46
|
+
@end.data_pointer[@idd].next = source_list_start_entry unless @end.nil?
|
47
|
+
|
48
|
+
@end = source_list.end
|
49
|
+
@start = source_list.start if @start.nil?
|
50
|
+
@size += source_list.size
|
51
|
+
|
52
|
+
source_list.reset
|
53
|
+
end
|
54
|
+
|
55
|
+
def reset
|
56
|
+
@end = nil
|
57
|
+
@start = nil
|
58
|
+
@size = 0
|
59
|
+
end
|
60
|
+
|
61
|
+
def <<(entry)
|
62
|
+
return if entry.data_pointer[@idd].inside == true
|
63
|
+
|
64
|
+
if @size > 0
|
65
|
+
@end.data_pointer[@idd].next = entry
|
66
|
+
entry.data_pointer[@idd].prev = @end
|
67
|
+
else
|
68
|
+
@start = entry
|
69
|
+
end
|
70
|
+
@end = entry
|
71
|
+
entry.data_pointer[@idd].inside = true
|
72
|
+
@size += 1
|
73
|
+
end
|
74
|
+
|
75
|
+
def shift
|
76
|
+
return nil if @size == 0
|
77
|
+
retme = @start
|
78
|
+
next_of_retme = retme.data_pointer[@idd].next
|
79
|
+
@start = next_of_retme
|
80
|
+
|
81
|
+
@end = nil if retme == @end
|
82
|
+
|
83
|
+
next_of_retme.data_pointer[@idd].prev = nil unless next_of_retme.nil?
|
84
|
+
@size -= 1
|
85
|
+
|
86
|
+
retme.data_pointer[@idd].next = nil
|
87
|
+
retme.data_pointer[@idd].prev = nil
|
88
|
+
retme.data_pointer[@idd].inside = false
|
89
|
+
retme
|
90
|
+
end
|
91
|
+
|
92
|
+
def each
|
93
|
+
return if @size == 0
|
94
|
+
act = @start
|
95
|
+
loop do
|
96
|
+
yield act
|
97
|
+
break if (act = act.data_pointer[@idd].next).nil?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def map
|
102
|
+
ary = []
|
103
|
+
each { |e| ary << yield(e) }
|
104
|
+
ary
|
105
|
+
end
|
106
|
+
|
107
|
+
def delete(entry)
|
108
|
+
return if @size == 0
|
109
|
+
return if entry.data_pointer[@idd].inside == false
|
110
|
+
|
111
|
+
next_of_entry = entry.data_pointer[@idd].next
|
112
|
+
prev_of_entry = entry.data_pointer[@idd].prev
|
113
|
+
|
114
|
+
case entry
|
115
|
+
when @start
|
116
|
+
@start = next_of_entry
|
117
|
+
when @end
|
118
|
+
@end = prev_of_entry
|
119
|
+
end
|
120
|
+
|
121
|
+
next_of_entry.data_pointer[@idd].prev = prev_of_entry unless next_of_entry.nil?
|
122
|
+
prev_of_entry.data_pointer[@idd].next = next_of_entry unless prev_of_entry.nil?
|
123
|
+
|
124
|
+
entry.data_pointer[@idd].next = nil
|
125
|
+
entry.data_pointer[@idd].prev = nil
|
126
|
+
|
127
|
+
@size -= 1
|
128
|
+
entry.data_pointer[@idd].inside = false
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Contrek
|
2
|
+
module Finder
|
3
|
+
class Lists
|
4
|
+
Link = Struct.new(:next, :prev, :inside)
|
5
|
+
def initialize
|
6
|
+
@lists = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_data_pointer
|
10
|
+
data_pointer = Array.new(@lists.size) { [] }
|
11
|
+
@lists.size.times do |n|
|
12
|
+
data_pointer[n] = Link.new(nil, nil, false)
|
13
|
+
end
|
14
|
+
|
15
|
+
data_pointer
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_list
|
19
|
+
list = Contrek::Finder::List.new(@lists.size)
|
20
|
+
@lists << list
|
21
|
+
list
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|