mirror of git://gcc.gnu.org/git/gcc.git
133 lines
3.2 KiB
Java
133 lines
3.2 KiB
Java
package gnu.java.awt.java2d;
|
|
|
|
/**
|
|
* Stores and handles the pixel converage for a scanline. The pixel coverage
|
|
* is stored as sorted list of buckets, each of which holds information about
|
|
* the coverage for the X and Y axis. This is utilized to compute the actual
|
|
* coverage for each pixel on the scanline and finding chunks of pixels with
|
|
* equal coverage.
|
|
*/
|
|
final class PixelCoverage
|
|
{
|
|
|
|
/**
|
|
* One bucket in the list.
|
|
*/
|
|
private static final class Bucket
|
|
{
|
|
/**
|
|
* The X coordinate on the scanline to which this bucket belongs.
|
|
*/
|
|
int xPos;
|
|
|
|
/**
|
|
* The X coverage.
|
|
*/
|
|
int xCov;
|
|
|
|
/**
|
|
* The Y coverage.
|
|
*/
|
|
int yCov;
|
|
|
|
/**
|
|
* Implements a linked list. This points to the next element of the list.
|
|
*/
|
|
Bucket next;
|
|
|
|
/**
|
|
* Implements a linked list. This points to the previous element of the
|
|
* list.
|
|
*/
|
|
Bucket prev;
|
|
}
|
|
|
|
/**
|
|
* The head of the sorted list of buckets.
|
|
*/
|
|
private Bucket head;
|
|
|
|
/**
|
|
* The current bucket. We make use of the fact that the scanline converter
|
|
* always scans the scanline (and thus this list) from left to right to
|
|
* quickly find buckets or insertion points.
|
|
*/
|
|
private Bucket current;
|
|
|
|
/**
|
|
* The bucket after the last valid bucket. Unused buckets are not thrown
|
|
* away and garbage collected. Instead, we keep them at the tail of the list
|
|
* and reuse them when necessary.
|
|
*/
|
|
private Bucket last;
|
|
|
|
/**
|
|
* Indicates the the next scan of the scanline begins and that the next
|
|
* request will be at the beginning of this list. This makes searching and
|
|
* sorting of this list very quick.
|
|
*/
|
|
void rewind()
|
|
{
|
|
current = head;
|
|
}
|
|
|
|
/**
|
|
* Clears the list. This does not throw away the old buckets but only
|
|
* resets the end-pointer of the list to the first element. All buckets are
|
|
* then unused and are reused when the list is filled again.
|
|
*/
|
|
void clear()
|
|
{
|
|
last = head;
|
|
}
|
|
|
|
/**
|
|
* This adds the specified x and y coverage to the pixel at the specified
|
|
* X position.
|
|
*
|
|
* @param x the X position
|
|
* @param xc the x coverage
|
|
* @param yc the y coverage
|
|
*/
|
|
void add(int x, int xc, int yc)
|
|
{
|
|
Bucket bucket = findOrInsert(x);
|
|
bucket.xCov += xc;
|
|
bucket.yCov += yc;
|
|
}
|
|
|
|
/**
|
|
* Finds the bucket in the list with the specified X coordinate.
|
|
* If no such bucket is found, then a new one is fetched (either a cached
|
|
* bucket from the end of the list or a newly allocated one) inserted at the
|
|
* correct position and returned.
|
|
*
|
|
* @param x the X coordinate
|
|
*
|
|
* @return a bucket to hold the coverage data
|
|
*/
|
|
private Bucket findOrInsert(int x)
|
|
{
|
|
// First search for a matching bucket.
|
|
if (head == null)
|
|
{
|
|
// Special case: the list is still empty.
|
|
head = new Bucket();
|
|
current = head;
|
|
return head;
|
|
}
|
|
|
|
// This performs a linear search, starting from the current bucket.
|
|
// This is reasonably efficient because access to this list is always done
|
|
// in a linear fashion and we are not more then 1 or 2 buckets away from
|
|
// the one we're looking for.
|
|
Bucket match = current;
|
|
while (match != null && match.xPos != x)
|
|
{
|
|
|
|
}
|
|
|
|
return match;
|
|
}
|
|
}
|