Pathpublic class Path extends Object implements org.w3c.dom.svg.SVGPath
Fields Summary |
---|
public static final int | WIND_EVEN_ODDThe event-odd winding rule. | public static final int | WIND_NON_ZEROThe non-zero winding rule. | static final int | INITIAL_COMMAND_CAPACITYThe default initial number of commands. | static final int | INITIAL_DATA_CAPACITYThe default initial number of data entries. | public static final byte | MOVE_TO_IMPLThe internal value for moveTo commands. | public static final byte | LINE_TO_IMPLThe internal value for lineTo commands | public static final byte | QUAD_TO_IMPLThe internal value for quadTo commands | public static final byte | CURVE_TO_IMPLThe internal value for curveTo commands. | public static final int | CLOSE_IMPLThe internal value for close commands. | public static final int[] | COMMAND_OFFSETDelta offset for each command type.
2 for moveto and lineto.
4 for quadto.
6 for curveto.
0 for close. | protected byte[] | commandsAn array storing the path command types. One of MOVE_TO_IMPL,
LINE_TO_IMPL, QUAD_TO_IMPL, CURVE_TO_IMPL. | protected float[] | dataAn array storing the path data. The array is a list of even
length made of consecutive x/y coordinate pairs. | protected int | nSegmentsThe current number of segments. | protected int | nDataThe number of used entries in the data array. | protected int | lastCmdIndexKeeps track of the last requested command index. | protected int | lastOffsetThe offset in the data array for the last requested command.
This is used to minimize the computation of the offset
in getSegmentParam. |
Constructors Summary |
---|
public Path()Default constructor. The initial capacity is defined by
the INITIAL_COMMAND_CAPACITY and INITIAL_DATA_CAPACITY
static variables.
this(INITIAL_COMMAND_CAPACITY, INITIAL_DATA_CAPACITY);
| public Path(int commandCapacity, int dataCapacity)Initial constructor. The initial capacity is defined by
the capacity parameters.
commands = new byte[commandCapacity];
data = new float[dataCapacity];
| public Path(Path model)Copy constructor.
if (model != null) {
// Copy path data.
this.data = new float[model.data.length];
System.arraycopy(model.data, 0, data, 0, model.data.length);
// Copy command data
this.commands = new byte[model.commands.length];
System.arraycopy(model.commands, 0, commands, 0, model.commands.length);
this.nData = model.nData;
this.nSegments = model.nSegments;
} // else, use default values
|
Methods Summary |
---|
final int | checkOffset(int cmdIndex)Implementation helper. Sets the lastCmdIndex to the requested index
after computing the offset corresponding to that index.
if (cmdIndex == lastCmdIndex) {
return lastOffset;
}
if (cmdIndex > lastCmdIndex) {
// The new index is _after_ the previous one. Add offsets for all
// commands between the two indices.
for (int ci = lastCmdIndex; ci < cmdIndex; ci++) {
lastOffset += COMMAND_OFFSET[commands[ci]];
}
} else {
// The next index is _before_ the previous one. Remove offsets for
// all commands, between the two indices.
for (int ci = lastCmdIndex - 1; ci >= cmdIndex; ci--) {
lastOffset -= COMMAND_OFFSET[commands[ci]];
}
}
lastCmdIndex = cmdIndex;
return lastOffset;
| public void | close()
newCommand(0);
commands[nSegments] = CLOSE_IMPL;
nSegments++;
| public void | curveTo(float x1, float y1, float x2, float y2, float x3, float y3)
newCommand(3);
commands[nSegments] = CURVE_TO_IMPL;
data[nData] = x1;
data[nData + 1] = y1;
data[nData + 2] = x2;
data[nData + 3] = y2;
data[nData + 4] = x3;
data[nData + 5] = y3;
nSegments++;
nData += 6;
| public boolean | equals(java.lang.Object obj)
if (obj == this) {
return true;
}
if (obj == null || !(obj instanceof Path)) {
return false;
}
Path p = (Path) obj;
if (nSegments != p.nSegments || nData != nData) {
return false;
}
// Compare each command type and offset
for (int ci = 0; ci < nSegments; ci++) {
// Check we are dealing with the same command type
if (commands[ci] != p.commands[ci]) {
return false;
}
}
// Now, compare each command data
for (int di = 0; di < nData; di++) {
if (data[di] != p.data[di]) {
return false;
}
}
return true;
| public Box | getBounds()Compute the path's bounds.
float x1, y1, x2, y2;
int i = nData - 2;
if (nData > 0) {
x1 = x2 = data[i];
y1 = y2 = data[i + 1];
i -= 2;
while (i >= 0) {
float x = data[i];
float y = data[i + 1];
i -= 2;
if (x < x1) x1 = x;
if (y < y1) y1 = y;
if (x > x2) x2 = x;
if (y > y2) y2 = y;
}
} else {
x1 = y1 = x2 = y2 = 0.0f;
}
return new Box(x1, y1, x2 - x1, y2 - y1);
| public byte[] | getCommands()
return commands;
| public float[] | getData()
return data;
| public int | getNumberOfSegments()
return nSegments;
| public short | getSegment(int cmdIndex)
if (cmdIndex >= nSegments || cmdIndex < 0) {
throw new DOMException(DOMException.INDEX_SIZE_ERR, "");
}
return toSVGPathCommand(commands[cmdIndex]);
| public float | getSegmentParam(int cmdIndex, int paramIndex)
if (cmdIndex >= nSegments || cmdIndex < 0 || paramIndex < 0) {
throw new DOMException(DOMException.INDEX_SIZE_ERR, "");
}
switch (commands[cmdIndex]) {
case CLOSE_IMPL:
throw new DOMException(DOMException.INDEX_SIZE_ERR, "");
case LINE_TO_IMPL:
case MOVE_TO_IMPL:
if (paramIndex > 1) {
throw new DOMException(DOMException.INDEX_SIZE_ERR, "");
}
break;
case QUAD_TO_IMPL:
if (paramIndex > 3) {
throw new DOMException(DOMException.INDEX_SIZE_ERR, "");
}
break;
case CURVE_TO_IMPL:
if (paramIndex > 5) {
throw new DOMException(DOMException.INDEX_SIZE_ERR, "");
}
break;
default:
throw new DOMException(DOMException.INDEX_SIZE_ERR, "");
}
return data[checkOffset(cmdIndex) + paramIndex];
| public Box | getTransformedBounds(Transform t)Compute the path's bounds in the transformed coordinate system.
float x1, y1, x2, y2;
int i = nData - 2;
float x0, y0, x, y;
if (nData > 0) {
x0 = data[i];
y0 = data[i + 1];
x1 = x2 = x0 * t.m0 + y0 * t.m2 + t.m4;
y1 = y2 = x0 * t.m1 + y0 * t.m3 + t.m5;
i -= 2;
while (i >= 0) {
x0 = data[i];
y0 = data[i + 1];
i -= 2;
x = x0 * t.m0 + y0 * t.m2 + t.m4;
y = x0 * t.m1 + y0 * t.m3 + t.m5;
if (x < x1) x1 = x;
if (y < y1) y1 = y;
if (x > x2) x2 = x;
if (y > y2) y2 = y;
}
} else {
x1 = y1 = x2 = y2 = 0.0f;
}
return new Box(x1, y1, x2 - x1, y2 - y1);
| public void | lineTo(float x, float y)
newCommand(1);
commands[nSegments] = LINE_TO_IMPL;
data[nData] = x;
data[nData + 1] = y;
nSegments++;
nData += 2;
| public void | moveTo(float x, float y)
newCommand(1);
commands[nSegments] = MOVE_TO_IMPL;
data[nData] = x;
data[nData + 1] = y;
nSegments++;
nData += 2;
| void | newCommand(int nPoints)Adjust the internal arrays for the requested number of points.
// Adjust the length of the command array if needed.
if (nSegments == commands.length) {
byte[] tmpCommands = new byte[commands.length * 2 + 1];
System.arraycopy(commands, 0, tmpCommands, 0, commands.length);
commands = tmpCommands;
}
// Adjust the length of the data array if needed.
if (nData + nPoints * 2 > data.length) {
float[] tmpData = new float[(nData + nPoints * 2) * 2];
System.arraycopy(data, 0, tmpData, 0, data.length);
data = tmpData;
}
| public void | quadTo(float x1, float y1, float x2, float y2)
newCommand(2);
commands[nSegments] = QUAD_TO_IMPL;
data[nData] = x1;
data[nData + 1] = y1;
data[nData + 2] = x2;
data[nData + 3] = y2;
nSegments++;
nData += 4;
| public void | setData(float[] newData)
if (nData == 0) {
return;
}
this.data = newData;
| public java.lang.String | toPointsString()
return toPointsString(data);
| public java.lang.String | toPointsString(float[] d)
StringBuffer sb = new StringBuffer();
int curSegment = 0;
int off = 0, cmd = 0;
while (curSegment < nSegments) {
switch(commands[curSegment]) {
case Path.MOVE_TO_IMPL:
if (curSegment > 0) {
throw new IllegalArgumentException();
}
sb.append(d[off]);
sb.append(',");
sb.append(d[off + 1]);
sb.append(' ");
off += 2;
break;
case Path.LINE_TO_IMPL:
sb.append(d[off]);
sb.append(',");
sb.append(d[off + 1]);
sb.append(' ");
off += 2;
break;
case Path.CLOSE_IMPL:
break;
default:
case Path.QUAD_TO_IMPL:
case Path.CURVE_TO_IMPL:
throw new IllegalArgumentException();
}
curSegment++;
}
return sb.toString().trim();
| static short | toSVGPathCommand(int command)
switch (command) {
case MOVE_TO_IMPL:
return SVGPath.MOVE_TO;
case LINE_TO_IMPL:
return SVGPath.LINE_TO;
case QUAD_TO_IMPL:
return SVGPath.QUAD_TO;
case CURVE_TO_IMPL:
return SVGPath.CURVE_TO;
case CLOSE_IMPL:
default:
return SVGPath.CLOSE;
}
| public java.lang.String | toString()
return toString(data);
| public java.lang.String | toString(float[] d)
StringBuffer sb = new StringBuffer();
int offset = 0;
for (int i = 0; i < nSegments; i++) {
switch (commands[i]) {
case Path.MOVE_TO_IMPL:
sb.append('M");
sb.append(d[offset]);
sb.append(',");
sb.append(d[offset + 1]);
offset += 2;
break;
case Path.LINE_TO_IMPL:
sb.append('L");
sb.append(d[offset]);
sb.append(',");
sb.append(d[offset + 1]);
offset += 2;
break;
case Path.QUAD_TO_IMPL:
sb.append('Q");
sb.append(d[offset]);
sb.append(',");
sb.append(d[offset + 1]);
sb.append(',");
sb.append(d[offset + 2]);
sb.append(',");
sb.append(d[offset + 3]);
offset += 4;
break;
case Path.CURVE_TO_IMPL:
sb.append('C");
sb.append(d[offset]);
sb.append(',");
sb.append(d[offset + 1]);
sb.append(',");
sb.append(d[offset + 2]);
sb.append(',");
sb.append(d[offset + 3]);
sb.append(',");
sb.append(d[offset + 4]);
sb.append(',");
sb.append(d[offset + 5]);
offset += 6;
break;
case Path.CLOSE_IMPL:
sb.append('Z");
break;
default:
throw new Error();
}
}
return sb.toString();
|
|