use of java.awt.geom.PathIterator in project jdk8u_jdk by JetBrains.
the class ProcessPath method doProcessPath.
private static boolean doProcessPath(ProcessHandler hnd, Path2D.Float p2df, float transXf, float transYf) {
float[] coords = new float[8];
float[] tCoords = new float[8];
float[] closeCoord = new float[] { 0.0f, 0.0f };
float[] firstCoord = new float[2];
int[] pixelInfo = new int[5];
boolean subpathStarted = false;
boolean skip = false;
float lastX, lastY;
pixelInfo[0] = 0;
/* Adjusting boundaries to the capabilities of the
* ProcessPath code
*/
hnd.dhnd.adjustBounds(LOWER_OUT_BND, LOWER_OUT_BND, UPPER_OUT_BND, UPPER_OUT_BND);
/* Adding support of the KEY_STROKE_CONTROL rendering hint.
* Now we are supporting two modes: "pixels at centers" and
* "pixels at corners".
* First one is disabled by default but could be enabled by setting
* VALUE_STROKE_PURE to the rendering hint. It means that pixel at the
* screen (x,y) has (x + 0.5, y + 0.5) float coordinates.
*
* Second one is enabled by default and means straightforward mapping
* (x,y) --> (x,y)
*/
if (hnd.dhnd.strokeControl == SunHints.INTVAL_STROKE_PURE) {
closeCoord[0] = -0.5f;
closeCoord[1] = -0.5f;
transXf -= 0.5;
transYf -= 0.5;
}
PathIterator pi = p2df.getPathIterator(null);
while (!pi.isDone()) {
switch(pi.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
/* Performing closing of the unclosed segments */
if (subpathStarted && !skip) {
if (hnd.clipMode == PH_MODE_FILL_CLIP) {
if (tCoords[0] != closeCoord[0] || tCoords[1] != closeCoord[1]) {
ProcessLine(hnd, tCoords[0], tCoords[1], closeCoord[0], closeCoord[1], pixelInfo);
}
}
hnd.processEndSubPath();
}
tCoords[0] = coords[0] + transXf;
tCoords[1] = coords[1] + transYf;
if (tCoords[0] < UPPER_BND && tCoords[0] > LOWER_BND && tCoords[1] < UPPER_BND && tCoords[1] > LOWER_BND) {
subpathStarted = true;
skip = false;
closeCoord[0] = tCoords[0];
closeCoord[1] = tCoords[1];
} else {
skip = true;
}
pixelInfo[0] = 0;
break;
case PathIterator.SEG_LINETO:
lastX = tCoords[2] = coords[0] + transXf;
lastY = tCoords[3] = coords[1] + transYf;
if (lastX < UPPER_BND && lastX > LOWER_BND && lastY < UPPER_BND && lastY > LOWER_BND) {
if (skip) {
tCoords[0] = closeCoord[0] = lastX;
tCoords[1] = closeCoord[1] = lastY;
subpathStarted = true;
skip = false;
} else {
ProcessLine(hnd, tCoords[0], tCoords[1], tCoords[2], tCoords[3], pixelInfo);
tCoords[0] = lastX;
tCoords[1] = lastY;
}
}
break;
case PathIterator.SEG_QUADTO:
tCoords[2] = coords[0] + transXf;
tCoords[3] = coords[1] + transYf;
lastX = tCoords[4] = coords[2] + transXf;
lastY = tCoords[5] = coords[3] + transYf;
if (lastX < UPPER_BND && lastX > LOWER_BND && lastY < UPPER_BND && lastY > LOWER_BND) {
if (skip) {
tCoords[0] = closeCoord[0] = lastX;
tCoords[1] = closeCoord[1] = lastY;
subpathStarted = true;
skip = false;
} else {
if (tCoords[2] < UPPER_BND && tCoords[2] > LOWER_BND && tCoords[3] < UPPER_BND && tCoords[3] > LOWER_BND) {
ProcessQuad(hnd, tCoords, pixelInfo);
} else {
ProcessLine(hnd, tCoords[0], tCoords[1], tCoords[4], tCoords[5], pixelInfo);
}
tCoords[0] = lastX;
tCoords[1] = lastY;
}
}
break;
case PathIterator.SEG_CUBICTO:
tCoords[2] = coords[0] + transXf;
tCoords[3] = coords[1] + transYf;
tCoords[4] = coords[2] + transXf;
tCoords[5] = coords[3] + transYf;
lastX = tCoords[6] = coords[4] + transXf;
lastY = tCoords[7] = coords[5] + transYf;
if (lastX < UPPER_BND && lastX > LOWER_BND && lastY < UPPER_BND && lastY > LOWER_BND) {
if (skip) {
tCoords[0] = closeCoord[0] = tCoords[6];
tCoords[1] = closeCoord[1] = tCoords[7];
subpathStarted = true;
skip = false;
} else {
if (tCoords[2] < UPPER_BND && tCoords[2] > LOWER_BND && tCoords[3] < UPPER_BND && tCoords[3] > LOWER_BND && tCoords[4] < UPPER_BND && tCoords[4] > LOWER_BND && tCoords[5] < UPPER_BND && tCoords[5] > LOWER_BND) {
ProcessCubic(hnd, tCoords, pixelInfo);
} else {
ProcessLine(hnd, tCoords[0], tCoords[1], tCoords[6], tCoords[7], pixelInfo);
}
tCoords[0] = lastX;
tCoords[1] = lastY;
}
}
break;
case PathIterator.SEG_CLOSE:
if (subpathStarted && !skip) {
skip = false;
if (tCoords[0] != closeCoord[0] || tCoords[1] != closeCoord[1]) {
ProcessLine(hnd, tCoords[0], tCoords[1], closeCoord[0], closeCoord[1], pixelInfo);
/* Storing last path's point for using in following
* segments without initial moveTo
*/
tCoords[0] = closeCoord[0];
tCoords[1] = closeCoord[1];
}
hnd.processEndSubPath();
}
break;
}
pi.next();
}
/* Performing closing of the unclosed segments */
if (subpathStarted & !skip) {
if (hnd.clipMode == PH_MODE_FILL_CLIP) {
if (tCoords[0] != closeCoord[0] || tCoords[1] != closeCoord[1]) {
ProcessLine(hnd, tCoords[0], tCoords[1], closeCoord[0], closeCoord[1], pixelInfo);
}
}
hnd.processEndSubPath();
}
return true;
}
use of java.awt.geom.PathIterator in project android_frameworks_base by crdroidandroid.
the class Path_Delegate method isEmpty.
/**
* Returns whether the path is empty (contains no lines or curves).
* @see Path#isEmpty
*/
public boolean isEmpty() {
if (!mCachedIsEmpty) {
return false;
}
float[] coords = new float[6];
mCachedIsEmpty = Boolean.TRUE;
for (PathIterator it = mPath.getPathIterator(null); !it.isDone(); it.next()) {
int type = it.currentSegment(coords);
if (type != PathIterator.SEG_MOVETO) {
// Once we know that the path is not empty, we do not need to check again unless
// Path#reset is called.
mCachedIsEmpty = false;
return false;
}
}
return true;
}
use of java.awt.geom.PathIterator in project android_frameworks_base by crdroidandroid.
the class Path_Delegate method offset.
/**
* Offset the path by (dx,dy), returning true on success
*
* @param dx The amount in the X direction to offset the entire path
* @param dy The amount in the Y direction to offset the entire path
*/
public void offset(float dx, float dy) {
GeneralPath newPath = new GeneralPath();
PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
newPath.append(iterator, false);
mPath = newPath;
}
use of java.awt.geom.PathIterator in project JMRI by JMRI.
the class PositionablePolygon method drawHandles.
@Override
public void drawHandles() {
if (_editing) {
_vertexHandles = new ArrayList<Rectangle>();
PathIterator iter = getPathIterator(null);
float[] coord = new float[6];
while (!iter.isDone()) {
iter.currentSegment(coord);
int x = Math.round(coord[0]);
int y = Math.round(coord[1]);
_vertexHandles.add(new Rectangle(x - SIZE, y - SIZE, 2 * SIZE, 2 * SIZE));
iter.next();
}
} else {
super.drawHandles();
}
}
use of java.awt.geom.PathIterator in project android by JetBrains.
the class LineChart method draw.
@Override
protected void draw(Graphics2D g2d, Dimension dim) {
if (myLinePaths.size() != myLinesConfig.size()) {
// e.g. updateData/postAnimate has not been invoked before this draw call.
return;
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform scale = AffineTransform.getScaleInstance(dim.getWidth(), dim.getHeight());
// Cache the transformed line paths for reuse below.
List<Path2D> transformedPaths = new ArrayList<>(myLinePaths.size());
for (int i = 0; i < myLinePaths.size(); ++i) {
Path2D scaledPath = new Path2D.Float(myLinePaths.get(i), scale);
scaledPath = myReducer.reduce(scaledPath, myLinePathConfigs.get(i));
transformedPaths.add(scaledPath);
if (isDrawDebugInfo()) {
int count = 0;
PathIterator it = scaledPath.getPathIterator(null);
while (!it.isDone()) {
++count;
it.next();
}
addDebugInfo("# of points drawn: %d", count);
}
}
// 1st pass - draw all the lines in the background.
drawLines(g2d, transformedPaths, myLinePathConfigs, false);
// 2nd pass - call each custom renderer instances to redraw any regions/lines as needed.
myCustomRenderers.forEach(renderer -> renderer.renderLines(this, g2d, transformedPaths, myLinePathConfigs));
}
Aggregations