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#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED
25#define AGG_SCANLINE_STORAGE_AA_INCLUDED
26
27#include <string.h>
28#include <stdlib.h>
29#include <math.h>
30#include "agg_array.h"
31
32
33namespace agg
34{
35
36    //----------------------------------------------scanline_cell_storage
37    template<class T> class scanline_cell_storage
38    {
39        struct extra_span
40        {
41            unsigned len;
42            T*       ptr;
43        };
44
45    public:
46        typedef T value_type;
47
48        //---------------------------------------------------------------
49        ~scanline_cell_storage()
50        {
51            remove_all();
52        }
53
54        //---------------------------------------------------------------
55        scanline_cell_storage() :
56            m_cells(128-2),
57            m_extra_storage()
58        {}
59
60
61        // Copying
62        //---------------------------------------------------------------
63        scanline_cell_storage(const scanline_cell_storage<T>& v) :
64            m_cells(v.m_cells),
65            m_extra_storage()
66        {
67            copy_extra_storage(v);
68        }
69
70        //---------------------------------------------------------------
71        const scanline_cell_storage<T>&
72        operator = (const scanline_cell_storage<T>& v)
73        {
74            remove_all();
75            m_cells = v.m_cells;
76            copy_extra_storage(v);
77            return *this;
78        }
79
80        //---------------------------------------------------------------
81        void remove_all()
82        {
83            int i;
84            for(i = m_extra_storage.size()-1; i >= 0; --i)
85            {
86                pod_allocator<T>::deallocate(m_extra_storage[i].ptr,
87                                             m_extra_storage[i].len);
88            }
89            m_extra_storage.remove_all();
90            m_cells.remove_all();
91        }
92
93        //---------------------------------------------------------------
94        int add_cells(const T* cells, unsigned num_cells)
95        {
96            int idx = m_cells.allocate_continuous_block(num_cells);
97            if(idx >= 0)
98            {
99                T* ptr = &m_cells[idx];
100                memcpy(ptr, cells, sizeof(T) * num_cells);
101                return idx;
102            }
103            extra_span s;
104            s.len = num_cells;
105            s.ptr = pod_allocator<T>::allocate(num_cells);
106            memcpy(s.ptr, cells, sizeof(T) * num_cells);
107            m_extra_storage.add(s);
108            return -int(m_extra_storage.size());
109        }
110
111        //---------------------------------------------------------------
112        const T* operator [] (int idx) const
113        {
114            if(idx >= 0)
115            {
116                if((unsigned)idx >= m_cells.size()) return 0;
117                return &m_cells[(unsigned)idx];
118            }
119            unsigned i = unsigned(-idx - 1);
120            if(i >= m_extra_storage.size()) return 0;
121            return m_extra_storage[i].ptr;
122        }
123
124        //---------------------------------------------------------------
125        T* operator [] (int idx)
126        {
127            if(idx >= 0)
128            {
129                if((unsigned)idx >= m_cells.size()) return 0;
130                return &m_cells[(unsigned)idx];
131            }
132            unsigned i = unsigned(-idx - 1);
133            if(i >= m_extra_storage.size()) return 0;
134            return m_extra_storage[i].ptr;
135        }
136
137    private:
138        void copy_extra_storage(const scanline_cell_storage<T>& v)
139        {
140            unsigned i;
141            for(i = 0; i < v.m_extra_storage.size(); ++i)
142            {
143                const extra_span& src = v.m_extra_storage[i];
144                extra_span dst;
145                dst.len = src.len;
146                dst.ptr = pod_allocator<T>::allocate(dst.len);
147                memcpy(dst.ptr, src.ptr, dst.len * sizeof(T));
148                m_extra_storage.add(dst);
149            }
150        }
151
152        pod_bvector<T, 12>         m_cells;
153        pod_bvector<extra_span, 6> m_extra_storage;
154    };
155
156
157
158
159
160
161    //-----------------------------------------------scanline_storage_aa
162    template<class T> class scanline_storage_aa
163    {
164    public:
165        typedef T cover_type;
166
167        //---------------------------------------------------------------
168        struct span_data
169        {
170            int32 x;
171            int32 len;       // If negative, it's a solid span, covers is valid
172            int   covers_id; // The index of the cells in the scanline_cell_storage
173        };
174
175        //---------------------------------------------------------------
176        struct scanline_data
177        {
178            int      y;
179            unsigned num_spans;
180            unsigned start_span;
181        };
182
183
184        //---------------------------------------------------------------
185        class embedded_scanline
186        {
187        public:
188
189            //-----------------------------------------------------------
190            class const_iterator
191            {
192            public:
193                struct span
194                {
195                    int32    x;
196                    int32    len; // If negative, it's a solid span, covers is valid
197                    const T* covers;
198                };
199
200                const_iterator() : m_storage(0) {}
201                const_iterator(const embedded_scanline& sl) :
202                    m_storage(sl.m_storage),
203                    m_span_idx(sl.m_scanline.start_span)
204                {
205                    init_span();
206                }
207
208                const span& operator*()  const { return m_span;  }
209                const span* operator->() const { return &m_span; }
210
211                void operator ++ ()
212                {
213                    ++m_span_idx;
214                    init_span();
215                }
216
217            private:
218                void init_span()
219                {
220                    const span_data& s = m_storage->span_by_index(m_span_idx);
221                    m_span.x      = s.x;
222                    m_span.len    = s.len;
223                    m_span.covers = m_storage->covers_by_index(s.covers_id);
224                }
225
226                const scanline_storage_aa* m_storage;
227                unsigned                   m_span_idx;
228                span                       m_span;
229            };
230
231            friend class const_iterator;
232
233
234            //-----------------------------------------------------------
235            embedded_scanline(const scanline_storage_aa& storage) :
236                m_storage(&storage)
237            {
238                init(0);
239            }
240
241            //-----------------------------------------------------------
242            void     reset(int, int)     {}
243            unsigned num_spans()   const { return m_scanline.num_spans;  }
244            int      y()           const { return m_scanline.y;          }
245            const_iterator begin() const { return const_iterator(*this); }
246
247            //-----------------------------------------------------------
248            void init(unsigned scanline_idx)
249            {
250                m_scanline_idx = scanline_idx;
251                m_scanline = m_storage->scanline_by_index(m_scanline_idx);
252            }
253
254        private:
255            const scanline_storage_aa* m_storage;
256            scanline_data              m_scanline;
257            unsigned                   m_scanline_idx;
258        };
259
260
261        //---------------------------------------------------------------
262        scanline_storage_aa() :
263            m_covers(),
264            m_spans(256-2),         // Block increment size
265            m_scanlines(),
266            m_min_x( 0x7FFFFFFF),
267            m_min_y( 0x7FFFFFFF),
268            m_max_x(-0x7FFFFFFF),
269            m_max_y(-0x7FFFFFFF),
270            m_cur_scanline(0)
271        {
272            m_fake_scanline.y = 0;
273            m_fake_scanline.num_spans = 0;
274            m_fake_scanline.start_span = 0;
275            m_fake_span.x = 0;
276            m_fake_span.len = 0;
277            m_fake_span.covers_id = 0;
278        }
279
280        // Renderer Interface
281        //---------------------------------------------------------------
282        void prepare()
283        {
284            m_covers.remove_all();
285            m_scanlines.remove_all();
286            m_spans.remove_all();
287            m_min_x =  0x7FFFFFFF;
288            m_min_y =  0x7FFFFFFF;
289            m_max_x = -0x7FFFFFFF;
290            m_max_y = -0x7FFFFFFF;
291            m_cur_scanline = 0;
292        }
293
294        //---------------------------------------------------------------
295        template<class Scanline> void render(const Scanline& sl)
296        {
297            scanline_data sl_this;
298
299            int y = sl.y();
300            if(y < m_min_y) m_min_y = y;
301            if(y > m_max_y) m_max_y = y;
302
303            sl_this.y = y;
304            sl_this.num_spans = sl.num_spans();
305            sl_this.start_span = m_spans.size();
306            typename Scanline::const_iterator span_iterator = sl.begin();
307
308            unsigned num_spans = sl_this.num_spans;
309            for(;;)
310            {
311                span_data sp;
312
313                sp.x         = span_iterator->x;
314                sp.len       = span_iterator->len;
315                int len      = abs(int(sp.len));
316                sp.covers_id =
317                    m_covers.add_cells(span_iterator->covers,
318                                       unsigned(len));
319                m_spans.add(sp);
320                int x1 = sp.x;
321                int x2 = sp.x + len - 1;
322                if(x1 < m_min_x) m_min_x = x1;
323                if(x2 > m_max_x) m_max_x = x2;
324                if(--num_spans == 0) break;
325                ++span_iterator;
326            }
327            m_scanlines.add(sl_this);
328        }
329
330
331        //---------------------------------------------------------------
332        // Iterate scanlines interface
333        int min_x() const { return m_min_x; }
334        int min_y() const { return m_min_y; }
335        int max_x() const { return m_max_x; }
336        int max_y() const { return m_max_y; }
337
338        //---------------------------------------------------------------
339        bool rewind_scanlines()
340        {
341            m_cur_scanline = 0;
342            return m_scanlines.size() > 0;
343        }
344
345
346        //---------------------------------------------------------------
347        template<class Scanline> bool sweep_scanline(Scanline& sl)
348        {
349            sl.reset_spans();
350            for(;;)
351            {
352                if(m_cur_scanline >= m_scanlines.size()) return false;
353                const scanline_data& sl_this = m_scanlines[m_cur_scanline];
354
355                unsigned num_spans = sl_this.num_spans;
356                unsigned span_idx  = sl_this.start_span;
357                do
358                {
359                    const span_data& sp = m_spans[span_idx++];
360                    const T* covers = covers_by_index(sp.covers_id);
361                    if(sp.len < 0)
362                    {
363                        sl.add_span(sp.x, unsigned(-sp.len), *covers);
364                    }
365                    else
366                    {
367                        sl.add_cells(sp.x, sp.len, covers);
368                    }
369                }
370                while(--num_spans);
371                ++m_cur_scanline;
372                if(sl.num_spans())
373                {
374                    sl.finalize(sl_this.y);
375                    break;
376                }
377            }
378            return true;
379        }
380
381
382        //---------------------------------------------------------------
383        // Specialization for embedded_scanline
384        bool sweep_scanline(embedded_scanline& sl)
385        {
386            do
387            {
388                if(m_cur_scanline >= m_scanlines.size()) return false;
389                sl.init(m_cur_scanline);
390                ++m_cur_scanline;
391            }
392            while(sl.num_spans() == 0);
393            return true;
394        }
395
396        //---------------------------------------------------------------
397        unsigned byte_size() const
398        {
399            unsigned i;
400            unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
401
402            for(i = 0; i < m_scanlines.size(); ++i)
403            {
404                size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans
405
406                const scanline_data& sl_this = m_scanlines[i];
407
408                unsigned num_spans = sl_this.num_spans;
409                unsigned span_idx  = sl_this.start_span;
410                do
411                {
412                    const span_data& sp = m_spans[span_idx++];
413
414                    size += sizeof(int32) * 2;                // X, span_len
415                    if(sp.len < 0)
416                    {
417                        size += sizeof(T);                    // cover
418                    }
419                    else
420                    {
421                        size += sizeof(T) * unsigned(sp.len); // covers
422                    }
423                }
424                while(--num_spans);
425            }
426            return size;
427        }
428
429
430        //---------------------------------------------------------------
431        static void write_int32(int8u* dst, int32 val)
432        {
433            dst[0] = ((const int8u*)&val)[0];
434            dst[1] = ((const int8u*)&val)[1];
435            dst[2] = ((const int8u*)&val)[2];
436            dst[3] = ((const int8u*)&val)[3];
437        }
438
439
440        //---------------------------------------------------------------
441        void serialize(int8u* data) const
442        {
443            unsigned i;
444
445            write_int32(data, min_x()); // min_x
446            data += sizeof(int32);
447            write_int32(data, min_y()); // min_y
448            data += sizeof(int32);
449            write_int32(data, max_x()); // max_x
450            data += sizeof(int32);
451            write_int32(data, max_y()); // max_y
452            data += sizeof(int32);
453
454            for(i = 0; i < m_scanlines.size(); ++i)
455            {
456                const scanline_data& sl_this = m_scanlines[i];
457
458                int8u* size_ptr = data;
459                data += sizeof(int32);  // Reserve space for scanline size in bytes
460
461                write_int32(data, sl_this.y);            // Y
462                data += sizeof(int32);
463
464                write_int32(data, sl_this.num_spans);    // num_spans
465                data += sizeof(int32);
466
467                unsigned num_spans = sl_this.num_spans;
468                unsigned span_idx  = sl_this.start_span;
469                do
470                {
471                    const span_data& sp = m_spans[span_idx++];
472                    const T* covers = covers_by_index(sp.covers_id);
473
474                    write_int32(data, sp.x);            // X
475                    data += sizeof(int32);
476
477                    write_int32(data, sp.len);          // span_len
478                    data += sizeof(int32);
479
480                    if(sp.len < 0)
481                    {
482                        memcpy(data, covers, sizeof(T));
483                        data += sizeof(T);
484                    }
485                    else
486                    {
487                        memcpy(data, covers, unsigned(sp.len) * sizeof(T));
488                        data += sizeof(T) * unsigned(sp.len);
489                    }
490                }
491                while(--num_spans);
492                write_int32(size_ptr, int32(unsigned(data - size_ptr)));
493            }
494        }
495
496
497        //---------------------------------------------------------------
498        const scanline_data& scanline_by_index(unsigned i) const
499        {
500            return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
501        }
502
503        //---------------------------------------------------------------
504        const span_data& span_by_index(unsigned i) const
505        {
506            return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
507        }
508
509        //---------------------------------------------------------------
510        const T* covers_by_index(int i) const
511        {
512            return m_covers[i];
513        }
514
515    private:
516        scanline_cell_storage<T>      m_covers;
517        pod_bvector<span_data, 10>    m_spans;
518        pod_bvector<scanline_data, 8> m_scanlines;
519        span_data     m_fake_span;
520        scanline_data m_fake_scanline;
521        int           m_min_x;
522        int           m_min_y;
523        int           m_max_x;
524        int           m_max_y;
525        unsigned      m_cur_scanline;
526    };
527
528
529    typedef scanline_storage_aa<int8u>  scanline_storage_aa8;  //--------scanline_storage_aa8
530    typedef scanline_storage_aa<int16u> scanline_storage_aa16; //--------scanline_storage_aa16
531    typedef scanline_storage_aa<int32u> scanline_storage_aa32; //--------scanline_storage_aa32
532
533
534
535
536    //------------------------------------------serialized_scanlines_adaptor_aa
537    template<class T> class serialized_scanlines_adaptor_aa
538    {
539    public:
540        typedef T cover_type;
541
542        //---------------------------------------------------------------------
543        class embedded_scanline
544        {
545        public:
546            typedef T cover_type;
547
548            //-----------------------------------------------------------------
549            class const_iterator
550            {
551            public:
552                struct span
553                {
554                    int32    x;
555                    int32    len; // If negative, it's a solid span, "covers" is valid
556                    const T* covers;
557                };
558
559                const_iterator() : m_ptr(0) {}
560                const_iterator(const embedded_scanline& sl) :
561                    m_ptr(sl.m_ptr),
562                    m_dx(sl.m_dx)
563                {
564                    init_span();
565                }
566
567                const span& operator*()  const { return m_span;  }
568                const span* operator->() const { return &m_span; }
569
570                void operator ++ ()
571                {
572                    if(m_span.len < 0)
573                    {
574                        m_ptr += sizeof(T);
575                    }
576                    else
577                    {
578                        m_ptr += m_span.len * sizeof(T);
579                    }
580                    init_span();
581                }
582
583            private:
584                int read_int32()
585                {
586                    int32 val;
587                    ((int8u*)&val)[0] = *m_ptr++;
588                    ((int8u*)&val)[1] = *m_ptr++;
589                    ((int8u*)&val)[2] = *m_ptr++;
590                    ((int8u*)&val)[3] = *m_ptr++;
591                    return val;
592                }
593
594                void init_span()
595                {
596                    m_span.x      = read_int32() + m_dx;
597                    m_span.len    = read_int32();
598                    m_span.covers = m_ptr;
599                }
600
601                const int8u* m_ptr;
602                span         m_span;
603                int          m_dx;
604            };
605
606            friend class const_iterator;
607
608
609            //-----------------------------------------------------------------
610            embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
611
612            //-----------------------------------------------------------------
613            void     reset(int, int)     {}
614            unsigned num_spans()   const { return m_num_spans;  }
615            int      y()           const { return m_y;          }
616            const_iterator begin() const { return const_iterator(*this); }
617
618
619        private:
620            //-----------------------------------------------------------------
621            int read_int32()
622            {
623                int32 val;
624                ((int8u*)&val)[0] = *m_ptr++;
625                ((int8u*)&val)[1] = *m_ptr++;
626                ((int8u*)&val)[2] = *m_ptr++;
627                ((int8u*)&val)[3] = *m_ptr++;
628                return val;
629            }
630
631        public:
632            //-----------------------------------------------------------------
633            void init(const int8u* ptr, int dx, int dy)
634            {
635                m_ptr       = ptr;
636                m_y         = read_int32() + dy;
637                m_num_spans = unsigned(read_int32());
638                m_dx        = dx;
639            }
640
641        private:
642            const int8u* m_ptr;
643            int          m_y;
644            unsigned     m_num_spans;
645            int          m_dx;
646        };
647
648
649
650    public:
651        //--------------------------------------------------------------------
652        serialized_scanlines_adaptor_aa() :
653            m_data(0),
654            m_end(0),
655            m_ptr(0),
656            m_dx(0),
657            m_dy(0),
658            m_min_x(0x7FFFFFFF),
659            m_min_y(0x7FFFFFFF),
660            m_max_x(-0x7FFFFFFF),
661            m_max_y(-0x7FFFFFFF)
662        {}
663
664        //--------------------------------------------------------------------
665        serialized_scanlines_adaptor_aa(const int8u* data, unsigned size,
666                                        double dx, double dy) :
667            m_data(data),
668            m_end(data + size),
669            m_ptr(data),
670            m_dx(iround(dx)),
671            m_dy(iround(dy)),
672            m_min_x(0x7FFFFFFF),
673            m_min_y(0x7FFFFFFF),
674            m_max_x(-0x7FFFFFFF),
675            m_max_y(-0x7FFFFFFF)
676        {}
677
678        //--------------------------------------------------------------------
679        void init(const int8u* data, unsigned size, double dx, double dy)
680        {
681            m_data  = data;
682            m_end   = data + size;
683            m_ptr   = data;
684            m_dx    = iround(dx);
685            m_dy    = iround(dy);
686            m_min_x = 0x7FFFFFFF;
687            m_min_y = 0x7FFFFFFF;
688            m_max_x = -0x7FFFFFFF;
689            m_max_y = -0x7FFFFFFF;
690        }
691
692    private:
693        //--------------------------------------------------------------------
694        int read_int32()
695        {
696            int32 val;
697            ((int8u*)&val)[0] = *m_ptr++;
698            ((int8u*)&val)[1] = *m_ptr++;
699            ((int8u*)&val)[2] = *m_ptr++;
700            ((int8u*)&val)[3] = *m_ptr++;
701            return val;
702        }
703
704        //--------------------------------------------------------------------
705        unsigned read_int32u()
706        {
707            int32u val;
708            ((int8u*)&val)[0] = *m_ptr++;
709            ((int8u*)&val)[1] = *m_ptr++;
710            ((int8u*)&val)[2] = *m_ptr++;
711            ((int8u*)&val)[3] = *m_ptr++;
712            return val;
713        }
714
715    public:
716        // Iterate scanlines interface
717        //--------------------------------------------------------------------
718        bool rewind_scanlines()
719        {
720            m_ptr = m_data;
721            if(m_ptr < m_end)
722            {
723                m_min_x = read_int32() + m_dx;
724                m_min_y = read_int32() + m_dy;
725                m_max_x = read_int32() + m_dx;
726                m_max_y = read_int32() + m_dy;
727            }
728            return m_ptr < m_end;
729        }
730
731        //--------------------------------------------------------------------
732        int min_x() const { return m_min_x; }
733        int min_y() const { return m_min_y; }
734        int max_x() const { return m_max_x; }
735        int max_y() const { return m_max_y; }
736
737        //--------------------------------------------------------------------
738        template<class Scanline> bool sweep_scanline(Scanline& sl)
739        {
740            sl.reset_spans();
741            for(;;)
742            {
743                if(m_ptr >= m_end) return false;
744
745                read_int32();      // Skip scanline size in bytes
746                int y = read_int32() + m_dy;
747                unsigned num_spans = read_int32();
748
749                do
750                {
751                    int x = read_int32() + m_dx;
752                    int len = read_int32();
753
754                    if(len < 0)
755                    {
756                        sl.add_span(x, unsigned(-len), *m_ptr);
757                        m_ptr += sizeof(T);
758                    }
759                    else
760                    {
761                        sl.add_cells(x, len, m_ptr);
762                        m_ptr += len * sizeof(T);
763                    }
764                }
765                while(--num_spans);
766
767                if(sl.num_spans())
768                {
769                    sl.finalize(y);
770                    break;
771                }
772            }
773            return true;
774        }
775
776
777        //--------------------------------------------------------------------
778        // Specialization for embedded_scanline
779        bool sweep_scanline(embedded_scanline& sl)
780        {
781            do
782            {
783                if(m_ptr >= m_end) return false;
784
785                unsigned byte_size = read_int32u();
786                sl.init(m_ptr, m_dx, m_dy);
787                m_ptr += byte_size - sizeof(int32);
788            }
789            while(sl.num_spans() == 0);
790            return true;
791        }
792
793    private:
794        const int8u* m_data;
795        const int8u* m_end;
796        const int8u* m_ptr;
797        int          m_dx;
798        int          m_dy;
799        int          m_min_x;
800        int          m_min_y;
801        int          m_max_x;
802        int          m_max_y;
803    };
804
805
806
807    typedef serialized_scanlines_adaptor_aa<int8u>  serialized_scanlines_adaptor_aa8;  //----serialized_scanlines_adaptor_aa8
808    typedef serialized_scanlines_adaptor_aa<int16u> serialized_scanlines_adaptor_aa16; //----serialized_scanlines_adaptor_aa16
809    typedef serialized_scanlines_adaptor_aa<int32u> serialized_scanlines_adaptor_aa32; //----serialized_scanlines_adaptor_aa32
810
811}
812
813
814#endif
815
816