Subversion Repositories Kolibri OS

Rev

Rev 882 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
882 serge 1
 
2
#define CLIP_BOTTOM     2
3
#define CLIP_RIGHT      4
4
#define CLIP_LEFT       8
5
6
 
7
 
8
/*=================================
9
10
 
11
{
12
    int   flag;
1002 serge 13
882 serge 14
 
1002 serge 15
    if( x < clip->xmin ) {
16
        flag |= CLIP_LEFT;
882 serge 17
    } else if( x > clip->xmax ) {
1002 serge 18
        flag |= CLIP_RIGHT;
882 serge 19
    }
1002 serge 20
    if( y < clip->ymin ) {
21
        flag |= CLIP_TOP;
882 serge 22
    } else if( y > clip->ymax ) {
1002 serge 23
        flag |= CLIP_BOTTOM;
882 serge 24
    }
1002 serge 25
    return( flag );
26
}
882 serge 27
28
 
29
 
30
/*===========================================================================
31
32
 
33
    (x1, y1) is outside and ( x2, y2 ) is inside the viewport.
34
    NOTE : the signs of denom and ( x - *x1 ) cancel out during division
35
           so make both of them positive before rounding.   */
36
{
37
    int            numer;
1002 serge 38
    int            denom;
39
882 serge 40
 
1002 serge 41
    numer = 2L * (long)( y2 - *y1 ) * abs( x - *x1 );
42
    if( numer > 0 ) {
43
        numer += denom;                     /* round to closest pixel   */
882 serge 44
    } else {
1002 serge 45
        numer -= denom;
882 serge 46
    }
1002 serge 47
    *y1 += numer / ( denom << 1 );
48
    *x1 = x;
49
}
882 serge 50
51
 
52
 
53
/*=============================================================
54
55
 
56
    viewport using the Cohen-Sutherland clipping algorithm. Return the
57
    clipped coordinates and a decision drawing flag.    */
58
{
59
    int    flag1;
1002 serge 60
    int    flag2;
61
882 serge 62
 
1002 serge 63
    flag2 = _L1OutCode( clip, *x2, *y2 );
64
    for( ;; ) {
65
        if( flag1 & flag2 ) break;                  /* trivially outside    */
882 serge 66
        if( flag1 == flag2 ) break;                 /* completely inside    */
67
        if( flag1 == 0 ) {                          /* first point inside   */
68
            if( flag2 & CLIP_TOP ) {
1002 serge 69
                line_inter( y2, x2, *y1, *x1, clip->ymin );
70
            } else if( flag2 & CLIP_BOTTOM ) {
71
                line_inter( y2, x2, *y1, *x1, clip->ymax );
72
            } else if( flag2 & CLIP_RIGHT ) {
73
                line_inter( x2, y2, *x1, *y1, clip->xmax );
74
            } else if( flag2 & CLIP_LEFT ) {
75
                line_inter( x2, y2, *x1, *y1, clip->xmin );
76
            }
77
            flag2 = _L1OutCode( clip, *x2, *y2 );
78
        } else {                                    /* second point inside  */
882 serge 79
            if( flag1 & CLIP_TOP ) {
1002 serge 80
                line_inter( y1, x1, *y2, *x2, clip->ymin );
81
            } else if( flag1 & CLIP_BOTTOM ) {
82
                line_inter( y1, x1, *y2, *x2, clip->ymax );
83
            } else if( flag1 & CLIP_RIGHT ) {
84
                line_inter( x1, y1, *x2, *y2, clip->xmax );
85
            } else if( flag1 & CLIP_LEFT ) {
86
                line_inter( x1, y1, *x2, *y2, clip->xmin );
87
            }
88
            flag1 = _L1OutCode( clip, *x1, *y1 );
89
        }
882 serge 90
    }
1002 serge 91
    return( flag1 & flag2 );
92
}
882 serge 93
94
 
95
 
96
/*======================================================
97
98
 
99
{
100
    if( flag & CLIP_TOP ) {
1002 serge 101
        *y = clip->ymin;
882 serge 102
    } else if( flag & CLIP_BOTTOM ) {
1002 serge 103
        *y = clip->ymax;
882 serge 104
    } else if( flag & CLIP_RIGHT ) {
1002 serge 105
        *x = clip->xmax;
882 serge 106
    } else if( flag & CLIP_LEFT ) {
1002 serge 107
        *x = clip->xmin;
882 serge 108
    }
1002 serge 109
}
882 serge 110
111
 
112
 
113
/*==============================================================
114
115
 
116
    active viewport based on the Cohen-Sutherland algorithm for line
117
    clipping. Return the clipped coordinates and a decision drawing
118
    flag ( 0 draw : 1 don't draw ). */
119
{
120
    int  flag1;
1002 serge 121
    int  flag2;
122
882 serge 123
 
1002 serge 124
    flag2 = _L1OutCode( clip, *x2, *y2 );
125
    for( ;; ) {
126
        if( flag1 & flag2 ) break;                  /* trivially outside    */
882 serge 127
        if( flag1 == flag2 ) break;                 /* completely inside    */
128
        if( flag1 == 0 ) {
129
            block_inter( clip, x2, y2, flag2 );
1002 serge 130
            flag2 = _L1OutCode( clip,  *x2, *y2 );
131
        } else {
882 serge 132
            block_inter( clip, x1, y1, flag1 );
1002 serge 133
            flag1 = _L1OutCode( clip, *x1, *y1 );
134
        }
882 serge 135
    }
1002 serge 136
    return( flag1 & flag2 );
137
}
882 serge 138
139
 
140
 
141
              clip_t *src_clip,int *src_x, int *src_y,
142
              int *w, int *h)
143
{
144
    int sx0, sy0, sx1, sy1;
1002 serge 145
882 serge 146
 
1002 serge 147
    sy0 = *src_y;
148
882 serge 149
 
1002 serge 150
    sy1 = sy0 + *h - 1;
151
882 serge 152
 
153
 
1002 serge 154
    {
155
      int dx0, dy0, dx1, dy1;
156
882 serge 157
 
1002 serge 158
      dy0 = *dst_y + sy0 - *src_y;
159
882 serge 160
 
1002 serge 161
      dy1 = dy0 + sy1 - sy0;
162
882 serge 163
 
1002 serge 164
      {
165
         *w = dx1 - dx0 + 1;
166
         *h = dy1 - dy0 + 1;
167
882 serge 168
 
1002 serge 169
         *src_y += dy0 - *dst_y;
170
882 serge 171
 
1002 serge 172
         *dst_y = dy0;
173
882 serge 174
 
1002 serge 175
      };
176
    }
177
    return 1;
178
};
882 serge 179