/* curve.coord_rect([TRAFO]) * * Return the smallest aligned rectangle that contains all nodes and * control points. With optional argument TRAFO, compute the rectangle * as if the path were transformed by the transformation TRAFO. */ static PyObject * curve_coord_rect(SKCurveObject * self, PyObject * args) { SKRectObject * rect = NULL; CurveSegment * segment; PyObject * trafo = NULL; int i; if (!PyArg_ParseTuple(args, "|O!", &SKTrafoType, &trafo)) return NULL; if (self->len == 0) { Py_INCREF(SKRect_EmptyRect); return (PyObject*)SKRect_EmptyRect; } segment = self->segments; if (!trafo) { rect = (SKRectObject*)SKRect_FromDouble(segment->x, segment->y, segment->x, segment->y); if (!rect) return NULL; segment += 1; for (i = 1; i < self->len; i++, segment++) { SKRect_AddXY(rect, segment->x, segment->y); if (segment->type == CurveBezier) { SKRect_AddXY(rect, segment->x1, segment->y1); SKRect_AddXY(rect, segment->x2, segment->y2); } } } else { SKCoord x, y; SKTrafo_TransformXY(trafo, segment->x, segment->y, &x, &y); rect = (SKRectObject*)SKRect_FromDouble(x, y, x, y); if (!rect) return NULL; segment += 1; for (i = 1; i < self->len; i++, segment++) { SKTrafo_TransformXY(trafo, segment->x, segment->y, &x, &y); SKRect_AddXY(rect, x, y); if (segment->type == CurveBezier) { SKTrafo_TransformXY(trafo, segment->x1, segment->y1, &x, &y); SKRect_AddXY(rect, x, y); SKTrafo_TransformXY(trafo, segment->x2, segment->y2, &x, &y); SKRect_AddXY(rect, x, y); } } } return (PyObject*)rect; }
int SKCurve_Transform(SKCurveObject * self, PyObject * trafo) { int i; CurveSegment * segment; segment = self->segments; for (i = 0; i < self->len; i++, segment++) { SKTrafo_TransformXY(trafo, segment->x, segment->y, &segment->x, &segment->y); if (segment->type == CurveBezier) { SKTrafo_TransformXY(trafo, segment->x1, segment->y1, &segment->x1, &segment->y1); SKTrafo_TransformXY(trafo, segment->x2, segment->y2, &segment->x2, &segment->y2); } } return 0; }
PyObject * SKAux_TransformRectangle(PyObject * self, PyObject * args) { SKRectObject * rect; PyObject * trafo; SKCoord dx, dy; int x[4], y[4]; if (!PyArg_ParseTuple(args, "O!O!", &SKTrafoType, &trafo, &SKRectType, &rect)) return NULL; SKTrafo_TransformXY(trafo, rect->left, rect->top, &dx, &dy); x[0] = ceil(dx); y[0] = ceil(dy); SKTrafo_TransformXY(trafo, rect->right, rect->top, &dx, &dy); x[1] = ceil(dx); y[1] = ceil(dy); SKTrafo_TransformXY(trafo, rect->right, rect->bottom, &dx, &dy); x[2] = ceil(dx); y[2] = ceil(dy); SKTrafo_TransformXY(trafo, rect->left, rect->bottom, &dx, &dy); x[3] = ceil(dx); y[3] = ceil(dy); if ((x[0] == x[3] && y[0] == y[1]) || (y[0] == y[3] && x[0] == x[1])) { int temp; if (x[0] > x[2]) { temp = x[0]; x[0] = x[2]; x[2] = temp; } if (y[0] > y[2]) { temp = y[0]; y[0] = y[2]; y[2] = temp; } return Py_BuildValue("iiii", x[0], y[0], x[2] - x[0], y[2] - y[0]); } return Py_BuildValue("[(ii)(ii)(ii)(ii)(ii)]", x[0], y[0], x[1], y[1], x[2], y[2], x[3], y[3], x[0], y[0]); }
int SKCurve_TestTransformed(SKCurveObject * self, PyObject * trafo, int test_x, int test_y, int closed) { CurveSegment * segment; SKCoord nx, ny, x1, y1, x2, y2, lastx, lasty, i; int x[4], y[4]; int result; int cross_count; #if DUMP_TEST fprintf(stderr, "Testing path %ld at %d, %d\n", (long)self, test_x, test_y); #endif segment = self->segments; SKTrafo_TransformXY(trafo, segment->x, segment->y, &lastx, &lasty); segment += 1; cross_count = 0; for (i = 1; i < self->len; i++, segment++) { if (segment->type == CurveBezier) { SKTrafo_TransformXY(trafo, segment->x1, segment->y1, &x1, &y1); SKTrafo_TransformXY(trafo, segment->x2, segment->y2, &x2, &y2); SKTrafo_TransformXY(trafo, segment->x, segment->y, &nx, &ny); x[0] = lastx + 0.5; y[0] = lasty + 0.5; x[1] = x1 + 0.5; y[1] = y1 + 0.5; x[2] = x2 + 0.5; y[2] = y2 + 0.5; x[3] = nx + 0.5; y[3] = ny + 0.5; result = bezier_hit_segment(x, y, test_x, test_y); } else { /* a line segment */ SKTrafo_TransformXY(trafo, segment->x, segment->y, &nx, &ny); result = bezier_hit_line(lastx + 0.5, lasty + 0.5, nx + 0.5, ny + 0.5, test_x, test_y); } lastx = nx; lasty = ny; if (result < 0) { cross_count = -1; break; } if (result > 0) cross_count += result; } if (!self->closed && closed && self->len >= 2 && cross_count >= 0) { /* an open subpath in a closed multi path berzier object */ SKTrafo_TransformXY(trafo, self->segments[0].x, self->segments[0].y, &nx, &ny); result = bezier_hit_line(lastx + 0.5, lasty + 0.5, nx + 0.5, ny + 0.5, test_x, test_y); if (result > 0) cross_count += result; } #if DUMP_TEST fprintf(stderr, "result: cross_count = %d\n", cross_count); #endif return cross_count; }