JavaShapeRasterizerpublic class JavaShapeRasterizer extends Object
Fields Summary |
---|
static final int | POINT_CAPACITY | int | edgesCount | int | edgeCur | int[] | edgesX | int[] | edgesY | int[] | edgesYS | int[] | edgesN | int[] | edgesDY | int[] | bounds | int | boundCount | boolean[] | edgesExt | int | activeCount | float[] | activeX | int[] | activeYEnd | float[] | activeXStep | int[] | activeDY | boolean[] | activeExt | int[] | crossX | int[] | crossDY | Filler | filler |
Constructors Summary |
---|
public JavaShapeRasterizer()
|
Methods Summary |
---|
void | addActiveEdge(int levelY, int start, int end, boolean back)Marks edge as active
int dy = back ? -edgesDY[end] : edgesDY[start];
if (dy <= 0) {
return;
}
int x1 = edgesX[start];
int dx = edgesX[end] - x1;
activeX[activeCount] = x1;
activeYEnd[activeCount] = edgesY[end];
activeXStep[activeCount] = dx / (float)dy;
activeDY[activeCount] = back ? -dy : dy;
activeExt[activeCount] = back ? edgesExt[end] : edgesExt[start];
activeCount++;
| void | addEdge(int x, int y, int num)Adds to the buffers new edge
edgesX = checkBufSize(edgesX, edgesCount);
edgesY = checkBufSize(edgesY, edgesCount);
edgesN = checkBufSize(edgesN, edgesCount);
edgesX[edgesCount] = x;
edgesY[edgesCount] = y;
edgesN[edgesCount] = (num << 16) | edgesCount;
edgesCount++;
| int[] | checkBufSize(int[] buf, int size)Checks buffer size and realloc if necessary
if (size == buf.length) {
int[] tmp;
tmp = new int[size + POINT_CAPACITY];
System.arraycopy(buf, 0, tmp, 0, buf.length);
buf = tmp;
}
return buf;
| int | findActiveEdges(int levelY)Find new active edges
int edgeActive = edgeCur;
while (edgeActive < edgesCount && edgesYS[edgeActive] == levelY) {
edgeActive++;
}
int activeNext = edgeActive;
while (edgeActive > edgeCur) {
edgeActive--;
int num = edgesN[edgeActive] & 0xFFFF;
addActiveEdge(levelY, num, getPrev(edgeActive), true);
addActiveEdge(levelY, num, getNext(edgeActive), false);
}
edgeCur = activeNext;
if (activeNext == edgesCount) {
return edgesY[edgesCount - 1];
}
return edgesYS[activeNext];
| int | getNext(int cur)
int n = edgesN[cur];
int bound = n >> 16;
int num = (n & 0xFFFF) + 1;
if (num == bounds[bound + 1]) {
return bounds[bound];
}
return num;
| int | getNextShape(int cur)
int bound = edgesN[cur] >> 16;
return bounds[bound + 1];
| int | getPrev(int cur)
int n = edgesN[cur];
int bound = n >> 16;
int num = (n & 0xFFFF) - 1;
if (num < bounds[bound]) {
return bounds[bound + 1] - 1;
}
return num;
| void | init()
edgesYS = new int[edgesCount];
System.arraycopy(edgesY, 0, edgesYS, 0, edgesCount);
// Create edgesDY
edgesDY = new int[edgesCount];
for(int i = 0; i < edgesCount; i++) {
int dy = edgesY[getNext(i)] - edgesY[i];
edgesDY[i] = dy;
}
// Create edgesExt
edgesExt = new boolean[edgesCount];
int prev = -1;
int i = 0;
int pos = 0;
while(i < edgesCount) {
TOP: {
do {
if (edgesDY[i] > 0) {
break TOP;
}
i = getNext(i);
} while (i != pos);
i = pos = getNextShape(i);
continue;
}
BOTTOM: {
do {
if (edgesDY[i] < 0) {
break BOTTOM;
}
if (edgesDY[i] > 0) {
prev = i;
}
i = getNext(i);
} while (i != pos);
i = pos = getNextShape(i);
continue;
}
if (prev != -1) {
edgesExt[prev] = true;
}
edgesExt[i] = true;
}
// Sort edgesY and edgesN
sort(edgesYS, edgesN, edgesCount);
edgeCur = 0;
activeCount = 0;
activeX = new float[edgesCount];
activeYEnd = new int[edgesCount];
activeXStep = new float[edgesCount];
activeDY = new int[edgesCount];
activeExt = new boolean[edgesCount];
crossX = new int[edgesCount];
crossDY = new int[edgesCount];
| void | makeBuffer(java.awt.geom.PathIterator path, double flatness)Prepare all buffers and variable to rasterize shape
edgesX = new int[POINT_CAPACITY];
edgesY = new int[POINT_CAPACITY];
edgesN = new int[POINT_CAPACITY];
bounds = new int[POINT_CAPACITY];
boundCount = 0;
edgesCount = 0;
if (path.getWindingRule() == PathIterator.WIND_EVEN_ODD) {
filler = new Filler.EvenOdd();
} else {
filler = new Filler.NonZero();
}
float[] coords = new float[2];
boolean closed = true;
while (!path.isDone()) {
switch(path.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
if (!closed) {
boundCount++;
bounds = checkBufSize(bounds, boundCount);
bounds[boundCount] = edgesCount;
}
addEdge((int)coords[0], (int)coords[1], boundCount);
closed = false;
break;
case PathIterator.SEG_LINETO:
addEdge((int)coords[0], (int)coords[1], boundCount);
break;
case PathIterator.SEG_CLOSE:
boundCount++;
bounds = checkBufSize(bounds, boundCount);
bounds[boundCount] = edgesCount;
closed = true;
break;
default:
// awt.36=Wrong segment
throw new RuntimeException(Messages.getString("awt.36")); //$NON-NLS-1$
}
path.next();
}
if (!closed) {
boundCount++;
bounds = checkBufSize(bounds, boundCount);
bounds[boundCount] = edgesCount;
}
| public org.apache.harmony.awt.gl.MultiRectArea | rasterize(java.awt.Shape shape, double flatness)Rasterizes shape with particular flatness
PathIterator path = shape.getPathIterator(null, flatness);
// Shape is empty
if (path.isDone()) {
return new MultiRectArea();
}
makeBuffer(path, flatness);
init();
int y = edgesYS[0];
int nextY = y;
int crossCount;
MultiRectArea.LineCash rect = new MultiRectArea.LineCash(edgesCount);
rect.setLine(y);
while(y <= nextY) {
crossCount = 0;
if (y == nextY) {
int i = activeCount;
while(i > 0) {
i--;
if (activeYEnd[i] == y) {
activeCount--;
int length = activeCount - i;
if (length != 0) {
int pos = i + 1;
System.arraycopy(activeX, pos, activeX, i, length);
System.arraycopy(activeYEnd, pos, activeYEnd, i, length);
System.arraycopy(activeXStep, pos, activeXStep, i, length);
System.arraycopy(activeDY, pos, activeDY, i, length);
System.arraycopy(activeExt, pos, activeExt, i, length);
}
}
}
nextY = findActiveEdges(y);
}
// Get X crossings
for(int i = 0; i < activeCount; i++) {
crossX[crossCount] = (int)Math.ceil(activeX[i]);
crossDY[crossCount] = activeDY[i];
crossCount++;
}
if (crossCount == 0) {
rect.skipLine();
} else {
// Sort X crossings
sort(crossX, crossDY, crossCount);
filler.add(rect, crossX, crossDY, crossCount, y);
}
for(int i = 0; i < activeCount; i++) {
activeX[i] += activeXStep[i];
}
y++;
}
return rect;
| void | sort(int[] master, int[] slave, int length)Sort buffers
for(int i = 0; i < length - 1; i++) {
int num = i;
int min = master[num];
for(int j = i + 1; j < length; j++) {
if (master[j] < min) {
num = j;
min = master[num];
}
}
if (num != i) {
master[num] = master[i];
master[i] = min;
min = slave[num];
slave[num] = slave[i];
slave[i] = min;
}
}
|
|