void fz_lineto(fz_context *ctx, fz_path *path, float x, float y) { float x0, y0; if (path->last < 0) { fz_warn(ctx, "lineto with no current point"); return; } if (path->items[path->last].k == FZ_CLOSE_PATH) { x0 = path->items[path->last-2].v; y0 = path->items[path->last-1].v; } else { x0 = path->items[path->len-2].v; y0 = path->items[path->len-1].v; } /* Anything other than MoveTo followed by LineTo the same place is a nop */ if (path->items[path->last].k != FZ_MOVETO && x0 == x && y0 == y) return; grow_path(ctx, path, 3); path->items[path->len++].k = FZ_LINETO; path->items[path->len++].v = x; path->items[path->len++].v = y; }
void fz_curveto(fz_context *ctx, fz_path *path, float x1, float y1, float x2, float y2, float x3, float y3) { float x0, y0; if (path->last < 0) { fz_warn(ctx, "curveto with no current point"); return; } if (path->items[path->last].k == FZ_CLOSE_PATH) { x0 = path->items[path->last-2].v; y0 = path->items[path->last-1].v; } else { x0 = path->items[path->len-2].v; y0 = path->items[path->len-1].v; } /* Check for degenerate cases: */ if (x0 == x1 && y0 == y1) { if (x2 == x3 && y2 == y3) { /* If (x1,y1)==(x2,y2) and prev wasn't a moveto, then skip */ if (x1 == x2 && y1 == y2 && path->items[path->last].k != FZ_MOVETO) return; /* Otherwise a line will suffice */ fz_lineto(ctx, path, x3, y3); return; } if (x1 == x2 && y1 == y2) { /* A line will suffice */ fz_lineto(ctx, path, x3, y3); return; } } else if (x1 == x2 && y1 == y2 && x2 == x3 && y2 == y3) { /* A line will suffice */ fz_lineto(ctx, path, x3, y3); return; } grow_path(ctx, path, 7); path->items[path->len++].k = FZ_CURVETO; path->items[path->len++].v = x1; path->items[path->len++].v = y1; path->items[path->len++].v = x2; path->items[path->len++].v = y2; path->items[path->len++].v = x3; path->items[path->len++].v = y3; }
void fz_moveto(fz_path *path, float x, float y) { grow_path(path, 3); path->items[path->len++].k = FZ_MOVETO; path->items[path->len++].v = x; path->items[path->len++].v = y; }
void fz_closepath(fz_path *path) { if (path->len == 0) { fz_warn("closepath with no current point"); return; } grow_path(path, 1); path->items[path->len++].k = FZ_CLOSE_PATH; }
void fz_moveto(fz_context *ctx, fz_path *path, float x, float y) { if (path->last >= 0 && path->items[path->last].k == FZ_MOVETO) { /* No point in having MOVETO then MOVETO */ path->len = path->last; } grow_path(ctx, path, 3); path->items[path->len++].k = FZ_MOVETO; path->items[path->len++].v = x; path->items[path->len++].v = y; }
void fz_lineto(fz_path *path, float x, float y) { if (path->len == 0) { fz_warn("lineto with no current point"); return; } grow_path(path, 3); path->items[path->len++].k = FZ_LINETO; path->items[path->len++].v = x; path->items[path->len++].v = y; }
void fz_closepath(fz_context *ctx, fz_path *path) { if (path->last < 0) { fz_warn(ctx, "closepath with no current point"); return; } /* CLOSE following a CLOSE is a NOP */ if (path->items[path->last].k == FZ_CLOSE_PATH) return; grow_path(ctx, path, 1); path->items[path->len++].k = FZ_CLOSE_PATH; }
void fz_curveto(fz_path *path, float x1, float y1, float x2, float y2, float x3, float y3) { if (path->len == 0) { fz_warn("curveto with no current point"); return; } grow_path(path, 7); path->items[path->len++].k = FZ_CURVETO; path->items[path->len++].v = x1; path->items[path->len++].v = y1; path->items[path->len++].v = x2; path->items[path->len++].v = y2; path->items[path->len++].v = x3; path->items[path->len++].v = y3; }