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