protected int convertPathData(Shape s, AffineTransform at) { PathIterator pi = s.getPathIterator(at); double[] coords = new double[6]; double currX = 0; double currY = 0; while (!pi.isDone()) { int curOp = pi.currentSegment(coords); int pointIndex; switch (curOp) { case PathIterator.SEG_MOVETO: ops.addByte(CAIRO_PATH_OP_MOVE_TO); pointIndex = points.getNextIndex(); points.setX(pointIndex, DoubleToCairoFixed(coords[0])); points.setY(pointIndex, DoubleToCairoFixed(coords[1])); currX = coords[0]; currY = coords[1]; break; case PathIterator.SEG_LINETO: ops.addByte(CAIRO_PATH_OP_LINE_TO); pointIndex = points.getNextIndex(); points.setX(pointIndex, DoubleToCairoFixed(coords[0])); points.setY(pointIndex, DoubleToCairoFixed(coords[1])); currX = coords[0]; currY = coords[1]; break; /** q0 = p0 q1 = (p0+2*p1)/3 q2 = (p2+2*p1)/3 q3 = p2 */ case PathIterator.SEG_QUADTO: double x1 = coords[0]; double y1 = coords[1]; double x2, y2; double x3 = coords[2]; double y3 = coords[3]; x2 = x1 + (x3 - x1) / 3; y2 = y1 + (y3 - y1) / 3; x1 = currX + 2 * (x1 - currX) / 3; y1 = currY + 2 * (y1 - currY) / 3; ops.addByte(CAIRO_PATH_OP_CURVE_TO); pointIndex = points.getNextIndex(); points.setX(pointIndex, DoubleToCairoFixed(x1)); points.setY(pointIndex, DoubleToCairoFixed(y1)); pointIndex = points.getNextIndex(); points.setX(pointIndex, DoubleToCairoFixed(x2)); points.setY(pointIndex, DoubleToCairoFixed(y2)); pointIndex = points.getNextIndex(); points.setX(pointIndex, DoubleToCairoFixed(x3)); points.setY(pointIndex, DoubleToCairoFixed(y3)); currX = x3; currY = y3; break; case PathIterator.SEG_CUBICTO: ops.addByte(CAIRO_PATH_OP_CURVE_TO); pointIndex = points.getNextIndex(); points.setX(pointIndex, DoubleToCairoFixed(coords[0])); points.setY(pointIndex, DoubleToCairoFixed(coords[1])); pointIndex = points.getNextIndex(); points.setX(pointIndex, DoubleToCairoFixed(coords[2])); points.setY(pointIndex, DoubleToCairoFixed(coords[3])); pointIndex = points.getNextIndex(); points.setX(pointIndex, DoubleToCairoFixed(coords[4])); points.setY(pointIndex, DoubleToCairoFixed(coords[5])); currX = coords[4]; currY = coords[5]; break; case PathIterator.SEG_CLOSE: ops.addByte(CAIRO_PATH_OP_CLOSE_PATH); break; } pi.next(); } return pi.getWindingRule(); }