summaryrefslogtreecommitdiff
path: root/agg/inc/agg_line_aa_basics.h
blob: ab8e94715019391ae3a2ae79904ba74e5396897e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// 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_LINE_AA_BASICS_INCLUDED
#define AGG_LINE_AA_BASICS_INCLUDED

#include <stdlib.h>
#include "agg_basics.h"

namespace agg
{

    // See Implementation agg_line_aa_basics.cpp

    //-------------------------------------------------------------------------
    enum
    {
        line_subpixel_shift = 8,                        //----line_subpixel_shift
        line_subpixel_size  = 1 << line_subpixel_shift, //----line_subpixel_size
        line_subpixel_mask  = line_subpixel_size - 1    //----line_subpixel_mask
    };

    //-------------------------------------------------------------------------
    enum
    {
        line_mr_subpixel_shift = 4,                           //----line_mr_subpixel_shift
        line_mr_subpixel_size  = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_size
        line_mr_subpixel_mask  = line_mr_subpixel_size - 1    //----line_mr_subpixel_mask
    };

    //------------------------------------------------------------------line_mr
    inline int line_mr(int x)
    {
        return x >> ((int)line_subpixel_shift - (int)line_mr_subpixel_shift);
    }

    //-------------------------------------------------------------------line_hr
    inline int line_hr(int x)
    {
        return x << ((int)line_subpixel_shift - (int)line_mr_subpixel_shift);
    }

    //---------------------------------------------------------------line_dbl_hr
    inline int line_dbl_hr(int x)
    {
        return x << line_subpixel_shift;
    }

    //---------------------------------------------------------------line_coord
    inline int line_coord(double x)
    {
        return int(x * line_subpixel_size);
    }

    //==========================================================line_parameters
    struct line_parameters
    {
        //---------------------------------------------------------------------
        line_parameters() {}
        line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) :
            x1(x1_), y1(y1_), x2(x2_), y2(y2_),
            dx(abs(x2_ - x1_)),
            dy(abs(y2_ - y1_)),
            sx((x2_ > x1_) ? 1 : -1),
            sy((y2_ > y1_) ? 1 : -1),
            vertical(dy >= dx),
            inc(vertical ? sy : sx),
            len(len_),
            octant((sy & 4) | (sx & 2) | int(vertical))
        {
        }

        //---------------------------------------------------------------------
        unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; }
        unsigned diagonal_quadrant()   const { return s_diagonal_quadrant[octant];   }

        //---------------------------------------------------------------------
        bool same_orthogonal_quadrant(const line_parameters& lp) const
        {
            return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant];
        }

        //---------------------------------------------------------------------
        bool same_diagonal_quadrant(const line_parameters& lp) const
        {
            return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
        }

        //---------------------------------------------------------------------
        int x1, y1, x2, y2, dx, dy, sx, sy;
        bool vertical;
        int inc;
        int len;
        int octant;

        //---------------------------------------------------------------------
        static int8u s_orthogonal_quadrant[8];
        static int8u s_diagonal_quadrant[8];
    };



    // See Implementation agg_line_aa_basics.cpp

    //----------------------------------------------------------------bisectrix
    void bisectrix(const line_parameters& l1,
                   const line_parameters& l2,
                   int* x, int* y);


    //-------------------------------------------fix_degenerate_bisectrix_start
    void inline fix_degenerate_bisectrix_start(const line_parameters& lp,
                                               int* x, int* y)
    {
        int d = int((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
                     double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
        if(d < line_subpixel_size)
        {
            *x = lp.x1 + (lp.y2 - lp.y1);
            *y = lp.y1 - (lp.x2 - lp.x1);
        }
    }


    //---------------------------------------------fix_degenerate_bisectrix_end
    void inline fix_degenerate_bisectrix_end(const line_parameters& lp,
                                             int* x, int* y)
    {
        int d = int((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
                     double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
        if(d < line_subpixel_size)
        {
            *x = lp.x2 + (lp.y2 - lp.y1);
            *y = lp.y2 - (lp.x2 - lp.x1);
        }
    }


}

#endif