5
* Created by fred on Wed Jul 23 2003.
18
#include <glib/gmem.h>
20
BitLigne::BitLigne(int ist,int ien,float iScale)
26
if ( en <= st ) en=st+1;
27
stBit=(int)floor(((float)st)*invScale); // round to pixel boundaries in the canvas
28
enBit=(int)ceil(((float)en)*invScale);
29
int nbBit=enBit-stBit;
36
fullB=(uint32_t*)g_malloc(nbInt*sizeof(uint32_t));
37
partB=(uint32_t*)g_malloc(nbInt*sizeof(uint32_t));
42
BitLigne::~BitLigne(void)
48
void BitLigne::Reset(void)
52
memset(fullB,0,nbInt*sizeof(uint32_t));
53
memset(partB,0,nbInt*sizeof(uint32_t));
55
int BitLigne::AddBord(float spos,float epos,bool full)
57
if ( spos >= epos ) return 0;
59
// separation of full and not entirely full bits is a bit useless
60
// the goal is to obtain a set of bits that are "on the edges" of the polygon, so that their coverage
61
// will be 1/2 on the average. in practice it's useless for anything but the even-odd fill rule
62
int ffBit,lfBit; // first and last bit of the portion of the line that is entirely covered
63
ffBit=(int)(ceil(invScale*spos));
64
lfBit=(int)(floor(invScale*epos));
65
int fpBit,lpBit; // first and last bit of the portion of the line that is not entirely but partially covered
66
fpBit=(int)(floor(invScale*spos));
67
lpBit=(int)(ceil(invScale*epos));
69
// update curMin and curMax to reflect the start and end pixel that need to be updated on the canvas
70
if ( floor(spos) < curMin ) curMin=(int)floor(spos);
71
if ( ceil(epos) > curMax ) curMax=(int)ceil(epos);
74
if ( ffBit < stBit ) ffBit=stBit;
75
if ( ffBit > enBit ) ffBit=enBit;
76
if ( lfBit < stBit ) lfBit=stBit;
77
if ( lfBit > enBit ) lfBit=enBit;
78
if ( fpBit < stBit ) fpBit=stBit;
79
if ( fpBit > enBit ) fpBit=enBit;
80
if ( lpBit < stBit ) lpBit=stBit;
81
if ( lpBit > enBit ) lpBit=enBit;
83
// offset to get actual bit position in the array
89
// get the end and start indices of the elements of fullB and partB that will receives coverage
94
// get bit numbers in the last and first changed elements of the fullB and partB arrays
100
// note that the "full" bits are always a subset of the "not empty" bits, ie of the partial bits
101
// the function is a bit lame: since there is at most one bit that is partial but not full, or no full bit,
102
// it does 2 times the optimal amount of work when the coverage is full. but i'm too lazy to change that...
103
if ( fpPos == lpPos ) { // only one element of the arrays is modified
104
// compute the vector of changed bits in the element
105
uint32_t add=0xFFFFFFFF;
106
if ( lpRem < 32 ) {add>>=32-lpRem;add<<=32-lpRem; }
107
if ( lpRem <= 0 ) add=0;
108
if ( fpRem > 0) {add<<=fpRem;add>>=fpRem;}
109
// and put it in the line
110
fullB[fpPos]&=~(add); // partial is exclusive from full, so partial bits are removed from fullB
111
partB[fpPos]|=add; // and added to partB
112
if ( full ) { // if the coverage is full, add the vector of full bits
113
if ( ffBit <= lfBit ) {
115
if ( lfRem < 32 ) {add>>=32-lfRem;add<<=32-lfRem;}
116
if ( lfRem <= 0 ) add=0;
117
if ( ffRem > 0 ) {add<<=ffRem;add>>=ffRem;}
119
partB[ffPos]&=~(add);
123
// first and last elements are differents, so add what appropriate to each
124
uint32_t add=0xFFFFFFFF;
125
if ( fpRem > 0 ) {add<<=fpRem;add>>=fpRem;}
126
fullB[fpPos]&=~(add);
130
if ( lpRem < 32 ) {add>>=32-lpRem;add<<=32-lpRem;}
131
if ( lpRem <= 0 ) add=0;
132
fullB[lpPos]&=~(add);
135
// and fill what's in between with partial bits
136
if ( lpPos > fpPos+1 ) memset(fullB+(fpPos+1),0x00,(lpPos-fpPos-1)*sizeof(uint32_t));
137
if ( lpPos > fpPos+1 ) memset(partB+(fpPos+1),0xFF,(lpPos-fpPos-1)*sizeof(uint32_t));
139
if ( full ) { // is the coverage is full, do your magic
140
if ( ffBit <= lfBit ) {
141
if ( ffPos == lfPos ) {
143
if ( lfRem < 32 ) {add>>=32-lfRem;add<<=32-lfRem;}
144
if ( lfRem <= 0 ) add=0;
145
if ( ffRem > 0 ) {add<<=ffRem;add>>=ffRem;}
147
partB[ffPos]&=~(add);
150
if ( ffRem > 0 ) {add<<=ffRem;add>>=ffRem;}
155
if ( lfRem < 32 ) {add>>=32-lfRem;add<<=32-lfRem;}
156
if ( lfRem <= 0 ) add=0;
160
if ( lfPos > ffPos+1 ) memset(fullB+(ffPos+1),0xFF,(lfPos-ffPos-1)*sizeof(uint32_t));
161
if ( lfPos > ffPos+1 ) memset(partB+(ffPos+1),0x00,(lfPos-ffPos-1)*sizeof(uint32_t));
170
void BitLigne::Affiche(void)
172
for (int i=0;i<nbInt;i++) printf(" %.8x",fullB[i]);
174
for (int i=0;i<nbInt;i++) printf(" %.8x",partB[i]);