1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 //
16 // Adaptation for 32-bit screen coordinates has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
18 //
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
21 //
22 //----------------------------------------------------------------------------
23
24
25 #ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
26 #define AGG_SCANLINE_STORAGE_BIN_INCLUDED
27
28 #include <cstdlib>
29 #include <limits>
30 #include "agg_array.h"
31
32
33 namespace agg
34 {
35
36 //-----------------------------------------------scanline_storage_bin
37 class scanline_storage_bin
38 {
39 public:
40 //---------------------------------------------------------------
41 struct span_data
42 {
43 int32 x;
__construct()44 int32 len;
45 };
46
47 //---------------------------------------------------------------
48 struct scanline_data
49 {
50 int y;
_connect($argDSN, $argUsername, $argPassword, $argDatabasename)51 unsigned num_spans;
52 unsigned start_span;
53 };
54
55
56 //---------------------------------------------------------------
57 class embedded_scanline
58 {
59 public:
60
61 //-----------------------------------------------------------
62 class const_iterator
63 {
64 public:
65 const_iterator() : m_storage(0) {}
66 const_iterator(const embedded_scanline* sl) :
67 m_storage(sl->m_storage),
68 m_span_idx(sl->m_scanline.start_span)
69 {
70 m_span = m_storage->span_by_index(m_span_idx);
71 }
_pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)72
73 const span_data& operator*() const { return m_span; }
74 const span_data* operator->() const { return &m_span; }
75
76 void operator ++ ()
77 {
78 ++m_span_idx;
79 m_span = m_storage->span_by_index(m_span_idx);
80 }
81
82 private:
83 const scanline_storage_bin* m_storage;
84 unsigned m_span_idx;
85 span_data m_span;
86 };
87
88 friend class const_iterator;
89
90
91 //-----------------------------------------------------------
92 embedded_scanline(scanline_storage_bin& storage) :
ServerInfo()93 m_storage(&storage)
94 {
95 setup(0);
96 }
97
98 //-----------------------------------------------------------
99 void reset(int, int) {}
100 unsigned num_spans() const { return m_scanline.num_spans; }
101 int y() const { return m_scanline.y; }
102 const_iterator begin() const { return const_iterator(this); }
103
104 //-----------------------------------------------------------
105 void setup(unsigned scanline_idx)
106 {
107 m_scanline_idx = scanline_idx;
108 m_scanline = m_storage->scanline_by_index(m_scanline_idx);
109 }
110
111 private:
112 scanline_storage_bin* m_storage;
113 scanline_data m_scanline;
114 unsigned m_scanline_idx;
115 };
116
117
118 //---------------------------------------------------------------
119 scanline_storage_bin() :
120 m_spans(256-2), // Block increment size
121 m_scanlines(),
122 m_min_x(std::numeric_limits<int>::max()),
CreateSequence($seqname = 'adodbseq', $start = 1)123 m_min_y(std::numeric_limits<int>::max()),
124 m_max_x(std::numeric_limits<int>::min()),
125 m_max_y(std::numeric_limits<int>::min()),
126 m_cur_scanline(0)
127 {
128 m_fake_scanline.y = 0;
129 m_fake_scanline.num_spans = 0;
130 m_fake_scanline.start_span = 0;
131 m_fake_span.x = 0;
132 m_fake_span.len = 0;
133 }
134
135 // Renderer Interface
136 //---------------------------------------------------------------
137 void prepare()
138 {
139 m_scanlines.remove_all();
140 m_spans.remove_all();
141 m_min_x = std::numeric_limits<int>::max();
142 m_min_y = std::numeric_limits<int>::max();
143 m_max_x = std::numeric_limits<int>::min();
144 m_max_y = std::numeric_limits<int>::min();
GenID($seq = 'adodbseq', $start = 1)145 m_cur_scanline = 0;
146 }
147
148 //---------------------------------------------------------------
149 template<class Scanline> void render(const Scanline& sl)
150 {
151 scanline_data sl_this;
152
153 int y = sl.y();
154 if(y < m_min_y) m_min_y = y;
155 if(y > m_max_y) m_max_y = y;
156
157 sl_this.y = y;
158 sl_this.num_spans = sl.num_spans();
159 sl_this.start_span = m_spans.size();
160 typename Scanline::const_iterator span_iterator = sl.begin();
161
162 unsigned num_spans = sl_this.num_spans;
163 for(;;)
164 {
165 span_data sp;
166 sp.x = span_iterator->x;
167 sp.len = (int32)std::abs((int)(span_iterator->len));
168 m_spans.add(sp);
169 int x1 = sp.x;
170 int x2 = sp.x + sp.len - 1;
171 if(x1 < m_min_x) m_min_x = x1;
172 if(x2 > m_max_x) m_max_x = x2;
173 if(--num_spans == 0) break;
174 ++span_iterator;
175 }
176 m_scanlines.add(sl_this);
177 }
178
179
180 //---------------------------------------------------------------
ErrorMsg()181 // Iterate scanlines interface
182 int min_x() const { return m_min_x; }
183 int min_y() const { return m_min_y; }
184 int max_x() const { return m_max_x; }
185 int max_y() const { return m_max_y; }
186
187 //---------------------------------------------------------------
188 bool rewind_scanlines()
189 {
ErrorNo()190 m_cur_scanline = 0;
191 return m_scanlines.size() > 0;
192 }
193
194
195 //---------------------------------------------------------------
196 template<class Scanline> bool sweep_scanline(Scanline& sl)
197 {
198 sl.reset_spans();
199 for(;;)
200 {
201 if(m_cur_scanline >= m_scanlines.size()) return false;
202 const scanline_data& sl_this = m_scanlines[m_cur_scanline];
203
204 unsigned num_spans = sl_this.num_spans;
205 unsigned span_idx = sl_this.start_span;
206 do
207 {
208 const span_data& sp = m_spans[span_idx++];
209 sl.add_span(sp.x, sp.len, cover_full);
210 }
BeginTrans()211 while(--num_spans);
212
213 ++m_cur_scanline;
214 if(sl.num_spans())
215 {
216 sl.finalize(sl_this.y);
217 break;
218 }
219 }
CommitTrans($ok = true)220 return true;
221 }
222
223
224 //---------------------------------------------------------------
225 // Specialization for embedded_scanline
226 bool sweep_scanline(embedded_scanline& sl)
227 {
228 do
229 {
230 if(m_cur_scanline >= m_scanlines.size()) return false;
RollbackTrans()231 sl.setup(m_cur_scanline);
232 ++m_cur_scanline;
233 }
234 while(sl.num_spans() == 0);
235 return true;
236 }
237
238
239 //---------------------------------------------------------------
240 unsigned byte_size() const
MetaPrimaryKeys($table, $owner = false)241 {
242 unsigned i;
243 unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
244
245 for(i = 0; i < m_scanlines.size(); ++i)
246 {
247 size += sizeof(int32) * 2 + // Y, num_spans
248 unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len
249 }
250 return size;
251 }
252
253
254 //---------------------------------------------------------------
255 static void write_int32(int8u* dst, int32 val)
256 {
257 dst[0] = ((const int8u*)&val)[0];
258 dst[1] = ((const int8u*)&val)[1];
259 dst[2] = ((const int8u*)&val)[2];
260 dst[3] = ((const int8u*)&val)[3];
261 }
262
263
264 //---------------------------------------------------------------
265 void serialize(int8u* data) const
266 {
267 unsigned i;
268
269 write_int32(data, min_x()); // min_x
270 data += sizeof(int32);
271 write_int32(data, min_y()); // min_y
272 data += sizeof(int32);
273 write_int32(data, max_x()); // max_x
274 data += sizeof(int32);
MetaTables($ttype = false, $showSchema = false, $mask = false)275 write_int32(data, max_y()); // max_y
276 data += sizeof(int32);
277
278 for(i = 0; i < m_scanlines.size(); ++i)
279 {
280 const scanline_data& sl_this = m_scanlines[i];
281
282 write_int32(data, sl_this.y); // Y
283 data += sizeof(int32);
284
285 write_int32(data, sl_this.num_spans); // num_spans
286 data += sizeof(int32);
287
288 unsigned num_spans = sl_this.num_spans;
289 unsigned span_idx = sl_this.start_span;
290 do
291 {
292 const span_data& sp = m_spans[span_idx++];
293
294 write_int32(data, sp.x); // X
295 data += sizeof(int32);
296
297 write_int32(data, sp.len); // len
298 data += sizeof(int32);
299 }
300 while(--num_spans);
301 }
302 }
303
304
305 //---------------------------------------------------------------
306 const scanline_data& scanline_by_index(unsigned i) const
307 {
308 return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
309 }
310
311 //---------------------------------------------------------------
312 const span_data& span_by_index(unsigned i) const
313 {
314 return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
315 }
316
317
318 private:
319 pod_bvector<span_data, 10> m_spans;
320 pod_bvector<scanline_data, 8> m_scanlines;
321 span_data m_fake_span;
322 scanline_data m_fake_scanline;
323 int m_min_x;
324 int m_min_y;
325 int m_max_x;
326 int m_max_y;
327 unsigned m_cur_scanline;
328 };
329
330
331
332
333
334
335
336
337
338
339
340
ODBCTypes($t)341
342 //---------------------------------------serialized_scanlines_adaptor_bin
343 class serialized_scanlines_adaptor_bin
344 {
345 public:
346 typedef bool cover_type;
347
348 //--------------------------------------------------------------------
349 class embedded_scanline
350 {
351 public:
352
353 //----------------------------------------------------------------
354 class const_iterator
355 {
356 public:
357 struct span
358 {
359 int32 x;
360 int32 len;
361 };
362
363 const_iterator() : m_ptr(0) {}
364 const_iterator(const embedded_scanline* sl) :
365 m_ptr(sl->m_ptr),
366 m_dx(sl->m_dx)
367 {
368 m_span.x = read_int32() + m_dx;
369 m_span.len = read_int32();
370 }
371
372 const span& operator*() const { return m_span; }
373 const span* operator->() const { return &m_span; }
374
375 void operator ++ ()
376 {
377 m_span.x = read_int32() + m_dx;
378 m_span.len = read_int32();
379 }
380
381 private:
382 int read_int32()
383 {
384 int32 val;
385 ((int8u*)&val)[0] = *m_ptr++;
386 ((int8u*)&val)[1] = *m_ptr++;
387 ((int8u*)&val)[2] = *m_ptr++;
388 ((int8u*)&val)[3] = *m_ptr++;
389 return val;
390 }
391
392 const int8u* m_ptr;
393 span m_span;
394 int m_dx;
395 };
396
397 friend class const_iterator;
398
399
400 //----------------------------------------------------------------
401 embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
402
403 //----------------------------------------------------------------
404 void reset(int, int) {}
405 unsigned num_spans() const { return m_num_spans; }
406 int y() const { return m_y; }
407 const_iterator begin() const { return const_iterator(this); }
408
409
410 private:
411 //----------------------------------------------------------------
412 int read_int32()
413 {
414 int32 val;
415 ((int8u*)&val)[0] = *m_ptr++;
416 ((int8u*)&val)[1] = *m_ptr++;
417 ((int8u*)&val)[2] = *m_ptr++;
418 ((int8u*)&val)[3] = *m_ptr++;
419 return val;
420 }
421
422 public:
423 //----------------------------------------------------------------
424 void init(const int8u* ptr, int dx, int dy)
425 {
426 m_ptr = ptr;
427 m_y = read_int32() + dy;
428 m_num_spans = unsigned(read_int32());
429 m_dx = dx;
430 }
431
432 private:
433 const int8u* m_ptr;
434 int m_y;
435 unsigned m_num_spans;
436 int m_dx;
437 };
438
439
440
441 public:
442 //--------------------------------------------------------------------
443 serialized_scanlines_adaptor_bin() :
444 m_data(0),
445 m_end(0),
446 m_ptr(0),
447 m_dx(0),
448 m_dy(0),
449 m_min_x(std::numeric_limits<int>::max()),
450 m_min_y(std::numeric_limits<int>::max()),
451 m_max_x(std::numeric_limits<int>::min()),
452 m_max_y(std::numeric_limits<int>::min())
453 {}
454
455 //--------------------------------------------------------------------
456 serialized_scanlines_adaptor_bin(const int8u* data, unsigned size,
457 double dx, double dy) :
458 m_data(data),
459 m_end(data + size),
460 m_ptr(data),
461 m_dx(iround(dx)),
462 m_dy(iround(dy)),
463 m_min_x(std::numeric_limits<int>::max()),
464 m_min_y(std::numeric_limits<int>::max()),
465 m_max_x(std::numeric_limits<int>::min()),
466 m_max_y(std::numeric_limits<int>::min())
467 {}
468
469 //--------------------------------------------------------------------
470 void init(const int8u* data, unsigned size, double dx, double dy)
471 {
472 m_data = data;
473 m_end = data + size;
474 m_ptr = data;
475 m_dx = iround(dx);
476 m_dy = iround(dy);
477 m_min_x = std::numeric_limits<int>::max();
478 m_min_y = std::numeric_limits<int>::max();
479 m_max_x = std::numeric_limits<int>::min();
480 m_max_y = std::numeric_limits<int>::min();
481 }
482
483 private:
484 //--------------------------------------------------------------------
485 int read_int32()
486 {
487 int32 val;
488 ((int8u*)&val)[0] = *m_ptr++;
489 ((int8u*)&val)[1] = *m_ptr++;
490 ((int8u*)&val)[2] = *m_ptr++;
491 ((int8u*)&val)[3] = *m_ptr++;
492 return val;
493 }
494
495 public:
496 // Iterate scanlines interface
497 //--------------------------------------------------------------------
498 bool rewind_scanlines()
499 {
500 m_ptr = m_data;
501 if(m_ptr < m_end)
502 {
503 m_min_x = read_int32() + m_dx;
504 m_min_y = read_int32() + m_dy;
505 m_max_x = read_int32() + m_dx;
506 m_max_y = read_int32() + m_dy;
507 }
508 return m_ptr < m_end;
509 }
510
511 //--------------------------------------------------------------------
512 int min_x() const { return m_min_x; }
513 int min_y() const { return m_min_y; }
514 int max_x() const { return m_max_x; }
515 int max_y() const { return m_max_y; }
516
517 //--------------------------------------------------------------------
518 template<class Scanline> bool sweep_scanline(Scanline& sl)
519 {
520 sl.reset_spans();
521 for(;;)
522 {
523 if(m_ptr >= m_end) return false;
524
525 int y = read_int32() + m_dy;
526 unsigned num_spans = read_int32();
527
528 do
529 {
530 int x = read_int32() + m_dx;
531 int len = read_int32();
532
533 if(len < 0) len = -len;
534 sl.add_span(x, unsigned(len), cover_full);
535 }
536 while(--num_spans);
537
538 if(sl.num_spans())
539 {
540 sl.finalize(y);
541 break;
542 }
543 }
544 return true;
545 }
546
547
548 //--------------------------------------------------------------------
549 // Specialization for embedded_scanline
550 bool sweep_scanline(embedded_scanline& sl)
551 {
552 do
553 {
554 if(m_ptr >= m_end) return false;
555
556 sl.init(m_ptr, m_dx, m_dy);
557
558 // Jump to the next scanline
559 //--------------------------
560 read_int32(); // Y
561 int num_spans = read_int32(); // num_spans
562 m_ptr += num_spans * sizeof(int32) * 2;
563 }
564 while(sl.num_spans() == 0);
565 return true;
566 }
567
568 private:
569 const int8u* m_data;
570 const int8u* m_end;
571 const int8u* m_ptr;
572 int m_dx;
573 int m_dy;
574 int m_min_x;
575 int m_min_y;
576 int m_max_x;
577 int m_max_y;
578 };
579
580
581
_close()582 }
583
584 #endif
585
586