in batik-awt-util/src/main/java/org/apache/batik/ext/awt/MultipleGradientPaintContext.java [1039:1313]
private final int getAntiAlias(float p1, boolean p1_up,
float p2, boolean p2_up,
float sz, float weight) {
// Until the last set of ops these are 28.4 fixed point values.
int ach=0, rch=0, gch=0, bch=0;
if (isSimpleLookup) {
p1 *= fastGradientArraySize;
p2 *= fastGradientArraySize;
int idx1 = (int)p1;
int idx2 = (int)p2;
int i, pix;
if (p1_up && !p2_up && (idx1 <= idx2)) {
if (idx1 == idx2)
return gradient[idx1];
// Sum between idx1 and idx2.
for (i=idx1+1; i<idx2; i++) {
pix = gradient[i];
ach += ((pix>>>20)&0xFF0);
rch += ((pix>>>12)&0xFF0);
gch += ((pix>>> 4)&0xFF0);
bch += ((pix<< 4)&0xFF0);
}
} else {
// Do the bulk of the work, all the whole gradient entries
// for idx1 and idx2.
int iStart;
int iEnd;
if (p1_up) {
iStart = idx1+1;
iEnd = fastGradientArraySize;
} else {
iStart = 0;
iEnd = idx1;
}
for ( i = iStart; i < iEnd; i++) {
pix = gradient[i];
ach += ((pix>>>20)&0xFF0);
rch += ((pix>>>12)&0xFF0);
gch += ((pix>>> 4)&0xFF0);
bch += ((pix<< 4)&0xFF0);
}
if (p2_up) {
iStart = idx2 + 1;
iEnd = fastGradientArraySize;
} else {
iStart = 0;
iEnd = idx2;
}
for (i= iStart; i < iEnd; i++) {
pix = gradient[i];
ach += ((pix>>>20)&0xFF0);
rch += ((pix>>>12)&0xFF0);
gch += ((pix>>> 4)&0xFF0);
bch += ((pix<< 4)&0xFF0);
}
}
int norm, isz;
// Normalize the summation so far...
isz = (int)((1<<16)/(sz*fastGradientArraySize));
ach = (ach*isz)>>16;
rch = (rch*isz)>>16;
gch = (gch*isz)>>16;
bch = (bch*isz)>>16;
// Clean up with the partial buckets at each end.
if (p1_up) norm = (int)((1-(p1-idx1))*isz);
else norm = (int)( (p1-idx1) *isz);
pix = gradient[idx1];
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
if (p2_up) norm = (int)((1-(p2-idx2))*isz);
else norm = (int)( (p2-idx2) *isz);
pix = gradient[idx2];
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
// Round and drop the 4bits frac.
ach = (ach+0x08)>>4;
rch = (rch+0x08)>>4;
gch = (gch+0x08)>>4;
bch = (bch+0x08)>>4;
} else {
int idx1=0, idx2=0;
int i1=-1, i2=-1;
float f1=0, f2=0;
// Find which gradient interval our points fall into.
for (int i = 0; i < gradientsLength; i++) {
if ((p1 < fractions[i+1]) && (i1 == -1)) {
//this is the array we want
i1 = i;
f1 = p1 - fractions[i];
f1 = ((f1/normalizedIntervals[i])
*GRADIENT_SIZE_INDEX);
//this is the interval we want.
idx1 = (int)f1;
if (i2 != -1) break;
}
if ((p2 < fractions[i+1]) && (i2 == -1)) {
//this is the array we want
i2 = i;
f2 = p2 - fractions[i];
f2 = ((f2/normalizedIntervals[i])
*GRADIENT_SIZE_INDEX);
//this is the interval we want.
idx2 = (int)f2;
if (i1 != -1) break;
}
}
if (i1 == -1) {
i1 = gradients.length - 1;
f1 = idx1 = GRADIENT_SIZE_INDEX;
}
if (i2 == -1) {
i2 = gradients.length - 1;
f2 = idx2 = GRADIENT_SIZE_INDEX;
}
if (DEBUG) System.out.println("I1: " + i1 + " Idx1: " + idx1 +
" I2: " + i2 + " Idx2: " + idx2);
// Simple case within one gradient array (so the average
// of the two idx gives us the true average of colors).
if ((i1 == i2) && (idx1 <= idx2) && p1_up && !p2_up)
return gradients[i1][(idx1+idx2+1)>>1];
// i1 != i2
int pix, norm;
int base = (int)((1<<16)/sz);
if ((i1 < i2) && p1_up && !p2_up) {
norm = (int)((base
*normalizedIntervals[i1]
*(GRADIENT_SIZE_INDEX-f1))
/GRADIENT_SIZE_INDEX);
pix = gradients[i1][(idx1+GRADIENT_SIZE)>>1];
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
for (int i=i1+1; i<i2; i++) {
norm = (int)(base*normalizedIntervals[i]);
pix = gradients[i][GRADIENT_SIZE>>1];
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
}
norm = (int)((base*normalizedIntervals[i2]*f2)
/GRADIENT_SIZE_INDEX);
pix = gradients[i2][(idx2+1)>>1];
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
} else {
if (p1_up) {
norm = (int)((base
*normalizedIntervals[i1]
*(GRADIENT_SIZE_INDEX-f1))
/GRADIENT_SIZE_INDEX);
pix = gradients[i1][(idx1+GRADIENT_SIZE)>>1];
} else {
norm = (int)((base*normalizedIntervals[i1]*f1)
/GRADIENT_SIZE_INDEX);
pix = gradients[i1][(idx1+1)>>1];
}
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
if (p2_up) {
norm = (int)((base
*normalizedIntervals[i2]
*(GRADIENT_SIZE_INDEX-f2))
/GRADIENT_SIZE_INDEX);
pix = gradients[i2][(idx2+GRADIENT_SIZE)>>1];
} else {
norm = (int)((base*normalizedIntervals[i2]*f2)
/GRADIENT_SIZE_INDEX);
pix = gradients[i2][(idx2+1)>>1];
}
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
// p1_up and p2_up are just used to set the loop-boundarys,
// then we loop from iStart to iEnd
int iStart;
int iEnd;
if (p1_up) {
iStart = i1+1;
iEnd = gradientsLength;
} else {
iStart = 0;
iEnd = i1;
}
for (int i=iStart; i < iEnd ; i++) {
norm = (int)(base*normalizedIntervals[i]);
pix = gradients[i][GRADIENT_SIZE>>1];
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
}
if (p2_up) {
iStart = i2+1;
iEnd = gradientsLength;
} else {
iStart = 0;
iEnd = i2;
}
for (int i=iStart; i < iEnd ; i++) {
norm = (int)(base*normalizedIntervals[i]);
pix = gradients[i][GRADIENT_SIZE>>1];
ach += (((pix>>>20)&0xFF0) *norm)>>16;
rch += (((pix>>>12)&0xFF0) *norm)>>16;
gch += (((pix>>> 4)&0xFF0) *norm)>>16;
bch += (((pix<< 4)&0xFF0) *norm)>>16;
}
}
ach = (ach+0x08)>>4;
rch = (rch+0x08)>>4;
gch = (gch+0x08)>>4;
bch = (bch+0x08)>>4;
if (DEBUG) System.out.println("Pix: [" + ach + ", " + rch +
", " + gch + ", " + bch + ']' );
}
if (weight != 1) {
// System.out.println("ave: " + gradientAverage);
int aveW = (int)((1<<16)*(1-weight));
int aveA = ((gradientAverage>>>24) & 0xFF)*aveW;
int aveR = ((gradientAverage>> 16) & 0xFF)*aveW;
int aveG = ((gradientAverage>> 8) & 0xFF)*aveW;
int aveB = ((gradientAverage ) & 0xFF)*aveW;
int iw = (int)(weight*(1<<16));
ach = ((ach*iw)+aveA)>>16;
rch = ((rch*iw)+aveR)>>16;
gch = ((gch*iw)+aveG)>>16;
bch = ((bch*iw)+aveB)>>16;
}
return ((ach<<24) | (rch<<16) | (gch<<8) | bch);
}