agg_scanline_boolean_algebra.h

来自「这是VCF框架的代码」· C头文件 代码 · 共 1,568 行 · 第 1/4 页

H
1,568
字号
//----------------------------------------------------------------------------// Anti-Grain Geometry - Version 2.4// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)//// Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied// warranty, and with no claim as to its suitability for any purpose.////----------------------------------------------------------------------------// Contact: mcseem@antigrain.com//          mcseemagg@yahoo.com//          http://www.antigrain.com//----------------------------------------------------------------------------#ifndef AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED#define AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED#include <stdlib.h>#include <math.h>#include "agg_basics.h"namespace agg{    //-----------------------------------------------sbool_combine_spans_bin    // Functor.    // Combine two binary encoded spans, i.e., when we don't have any    // anti-aliasing information, but only X and Length. The function    // is compatible with any type of scanlines.    //----------------    template<class Scanline1,              class Scanline2,              class Scanline>     struct sbool_combine_spans_bin    {        void operator () (const typename Scanline1::const_iterator&,                           const typename Scanline2::const_iterator&,                           int x, unsigned len,                           Scanline& sl) const        {            sl.add_span(x, len, cover_full);        }    };    //---------------------------------------------sbool_combine_spans_empty    // Functor.    // Combine two spans as empty ones. The functor does nothing    // and is used to XOR binary spans.    //----------------    template<class Scanline1,              class Scanline2,              class Scanline>     struct sbool_combine_spans_empty    {        void operator () (const typename Scanline1::const_iterator&,                           const typename Scanline2::const_iterator&,                           int, unsigned,                           Scanline&) const        {}    };    //--------------------------------------------------sbool_add_span_empty    // Functor.    // Add nothing. Used in conbine_shapes_sub    //----------------    template<class Scanline1,              class Scanline>     struct sbool_add_span_empty    {        void operator () (const typename Scanline1::const_iterator&,                           int, unsigned,                           Scanline&) const        {}    };    //----------------------------------------------------sbool_add_span_bin    // Functor.    // Add a binary span    //----------------    template<class Scanline1,              class Scanline>     struct sbool_add_span_bin    {        void operator () (const typename Scanline1::const_iterator&,                           int x, unsigned len,                           Scanline& sl) const        {            sl.add_span(x, len, cover_full);        }    };        //-----------------------------------------------------sbool_add_span_aa    // Functor.    // Add an anti-aliased span    // anti-aliasing information, but only X and Length. The function    // is compatible with any type of scanlines.    //----------------    template<class Scanline1,              class Scanline>     struct sbool_add_span_aa    {        void operator () (const typename Scanline1::const_iterator& span,                           int x, unsigned len,                           Scanline& sl) const        {            if(span->len < 0)            {                sl.add_span(x, len, *span->covers);            }            else            if(span->len > 0)            {                const typename Scanline1::cover_type* covers = span->covers;                if(span->x < x) covers += x - span->x;                sl.add_cells(x, len, covers);            }        }    };    //----------------------------------------------sbool_intersect_spans_aa    // Functor.    // Intersect two spans preserving the anti-aliasing information.    // The result is added to the "sl" scanline.    //------------------    template<class Scanline1,              class Scanline2,              class Scanline,              unsigned CoverShift = cover_shift>     struct sbool_intersect_spans_aa    {        enum cover_scale_e        {            cover_shift = CoverShift,            cover_size  = 1 << cover_shift,            cover_mask  = cover_size - 1,            cover_full  = cover_mask        };                void operator () (const typename Scanline1::const_iterator& span1,                           const typename Scanline2::const_iterator& span2,                           int x, unsigned len,                           Scanline& sl) const        {            unsigned cover;            const typename Scanline1::cover_type* covers1;            const typename Scanline2::cover_type* covers2;            // Calculate the operation code and choose the             // proper combination algorithm.            // 0 = Both spans are of AA type            // 1 = span1 is solid, span2 is AA            // 2 = span1 is AA, span2 is solid            // 3 = Both spans are of solid type            //-----------------            switch((span1->len < 0) | ((span2->len < 0) << 1))            {            case 0:      // Both are AA spans                covers1 = span1->covers;                covers2 = span2->covers;                if(span1->x < x) covers1 += x - span1->x;                if(span2->x < x) covers2 += x - span2->x;                do                {                    cover = *covers1++ * *covers2++;                    sl.add_cell(x++,                                 (cover == cover_full * cover_full) ?                                cover_full :                                 (cover >> cover_shift));                }                while(--len);                break;            case 1:      // span1 is solid, span2 is AA                covers2 = span2->covers;                if(span2->x < x) covers2 += x - span2->x;                if(*(span1->covers) == cover_full)                {                    sl.add_cells(x, len, covers2);                }                else                {                    do                    {                        cover = *(span1->covers) * *covers2++;                        sl.add_cell(x++,                                     (cover == cover_full * cover_full) ?                                    cover_full :                                     (cover >> cover_shift));                    }                    while(--len);                }                break;            case 2:      // span1 is AA, span2 is solid                covers1 = span1->covers;                if(span1->x < x) covers1 += x - span1->x;                if(*(span2->covers) == cover_full)                {                    sl.add_cells(x, len, covers1);                }                else                {                    do                    {                        cover = *covers1++ * *(span2->covers);                        sl.add_cell(x++,                                     (cover == cover_full * cover_full) ?                                    cover_full :                                     (cover >> cover_shift));                    }                    while(--len);                }                break;            case 3:      // Both are solid spans                cover = *(span1->covers) * *(span2->covers);                sl.add_span(x, len,                             (cover == cover_full * cover_full) ?                            cover_full :                             (cover >> cover_shift));                break;            }        }    };    //--------------------------------------------------sbool_unite_spans_aa    // Functor.    // Unite two spans preserving the anti-aliasing information.    // The result is added to the "sl" scanline.    //------------------    template<class Scanline1,              class Scanline2,              class Scanline,              unsigned CoverShift = cover_shift>     struct sbool_unite_spans_aa    {        enum cover_scale_e        {            cover_shift = CoverShift,            cover_size  = 1 << cover_shift,            cover_mask  = cover_size - 1,            cover_full  = cover_mask        };                void operator () (const typename Scanline1::const_iterator& span1,                           const typename Scanline2::const_iterator& span2,                           int x, unsigned len,                           Scanline& sl) const        {            unsigned cover;            const typename Scanline1::cover_type* covers1;            const typename Scanline2::cover_type* covers2;            // Calculate the operation code and choose the             // proper combination algorithm.            // 0 = Both spans are of AA type            // 1 = span1 is solid, span2 is AA            // 2 = span1 is AA, span2 is solid            // 3 = Both spans are of solid type            //-----------------            switch((span1->len < 0) | ((span2->len < 0) << 1))            {            case 0:      // Both are AA spans                covers1 = span1->covers;                covers2 = span2->covers;                if(span1->x < x) covers1 += x - span1->x;                if(span2->x < x) covers2 += x - span2->x;                do                {                    cover = cover_mask * cover_mask -                                 (cover_mask - *covers1++) *                                 (cover_mask - *covers2++);                    sl.add_cell(x++,                                 (cover == cover_full * cover_full) ?                                cover_full :                                 (cover >> cover_shift));                }                while(--len);                break;            case 1:      // span1 is solid, span2 is AA                covers2 = span2->covers;                if(span2->x < x) covers2 += x - span2->x;                if(*(span1->covers) == cover_full)                {                    sl.add_span(x, len, cover_full);                }                else                {                    do                    {                        cover = cover_mask * cover_mask -                                     (cover_mask - *(span1->covers)) *                                     (cover_mask - *covers2++);                        sl.add_cell(x++,                                     (cover == cover_full * cover_full) ?                                    cover_full :                                     (cover >> cover_shift));                    }                    while(--len);                }                break;            case 2:      // span1 is AA, span2 is solid                covers1 = span1->covers;                if(span1->x < x) covers1 += x - span1->x;                if(*(span2->covers) == cover_full)                {                    sl.add_span(x, len, cover_full);                }                else                {                    do                    {                        cover = cover_mask * cover_mask -                                     (cover_mask - *covers1++) *                                     (cover_mask - *(span2->covers));                        sl.add_cell(x++,                                     (cover == cover_full * cover_full) ?                                    cover_full :                                     (cover >> cover_shift));                    }                    while(--len);                }                break;            case 3:      // Both are solid spans                cover = cover_mask * cover_mask -                             (cover_mask - *(span1->covers)) *                             (cover_mask - *(span2->covers));                sl.add_span(x, len,                             (cover == cover_full * cover_full) ?                            cover_full :                             (cover >> cover_shift));                break;            }        }    };    //---------------------------------------------sbool_xor_formula_linear    template<unsigned CoverShift = cover_shift>     struct sbool_xor_formula_linear    {        enum cover_scale_e        {            cover_shift = CoverShift,            cover_size  = 1 << cover_shift,            cover_mask  = cover_size - 1        };        static AGG_INLINE unsigned calculate(unsigned a, unsigned b)        {            unsigned cover = a + b;            if(cover > cover_mask) cover = cover_mask + cover_mask - cover;            return cover;        }    };    //---------------------------------------------sbool_xor_formula_saddle    template<unsigned CoverShift = cover_shift>     struct sbool_xor_formula_saddle    {        enum cover_scale_e        {            cover_shift = CoverShift,            cover_size  = 1 << cover_shift,            cover_mask  = cover_size - 1        };        static AGG_INLINE unsigned calculate(unsigned a, unsigned b)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?