summaryrefslogtreecommitdiff
path: root/src/plot
diff options
context:
space:
mode:
Diffstat (limited to 'src/plot')
-rw-r--r--src/plot/api.c8
-rw-r--r--src/plot/generic.c205
2 files changed, 139 insertions, 74 deletions
diff --git a/src/plot/api.c b/src/plot/api.c
index 95644cc..f5c16f3 100644
--- a/src/plot/api.c
+++ b/src/plot/api.c
@@ -158,14 +158,14 @@ bool nsfb_plot_readrect(nsfb_t *nsfb, nsfb_bbox_t *rect, nsfb_colour_t *buffer)
}
-bool nsfb_plot_cubic_bezier(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_point_t *ctrlb, nsfb_colour_t c)
+bool nsfb_plot_cubic_bezier(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_point_t *ctrlb, nsfb_plot_pen_t *pen)
{
- return nsfb->plotter_fns->cubic(nsfb, curve, ctrla, ctrlb, c);
+ return nsfb->plotter_fns->cubic(nsfb, curve, ctrla, ctrlb, pen);
}
-bool nsfb_plot_quadratic_bezier(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_colour_t c)
+bool nsfb_plot_quadratic_bezier(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_plot_pen_t *pen)
{
- return nsfb->plotter_fns->quadratic(nsfb, curve, ctrla, c);
+ return nsfb->plotter_fns->quadratic(nsfb, curve, ctrla, pen);
}
bool nsfb_plot_path(nsfb_t *nsfb, int pathc, nsfb_plot_pathop_t *pathop, nsfb_plot_pen_t *pen)
diff --git a/src/plot/generic.c b/src/plot/generic.c
index 287c2c0..2c3cdbb 100644
--- a/src/plot/generic.c
+++ b/src/plot/generic.c
@@ -516,11 +516,12 @@ static bool arc(nsfb_t *nsfb, int x, int y, int radius, int angle1, int angle2,
#define N_SEG 30
static bool
-cubic(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_point_t *ctrlb, nsfb_colour_t cl)
+cubic_points(unsigned int pointc,
+ nsfb_point_t *point,
+ nsfb_bbox_t *curve,
+ nsfb_point_t *ctrla,
+ nsfb_point_t *ctrlb)
{
- nsfb_bbox_t line;
- nsfb_plot_pen_t pen;
-
unsigned int seg_loop;
double t;
double one_minus_t;
@@ -531,13 +532,13 @@ cubic(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_point_t *ctrlb
double x;
double y;
- pen.stroke_colour = cl;
-
- x = curve->x0;
- y = curve->y0;
+ point->x = curve->x0;
+ point->y = curve->y0;
+ point++;
+ pointc--;
- for (seg_loop = 1; seg_loop <= N_SEG; ++seg_loop) {
- t = (double)seg_loop / (double)N_SEG;
+ for (seg_loop = 1; seg_loop < pointc; ++seg_loop) {
+ t = (double)seg_loop / (double)pointc;
one_minus_t = 1.0 - t;
@@ -546,26 +547,45 @@ cubic(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_point_t *ctrlb
c = 3.0 * t * t * one_minus_t;
d = t * t * t;
- line.x0 = x;
- line.y0 = y;
-
x = a * curve->x0 + b * ctrla->x + c * ctrlb->x + d * curve->x1;
y = a * curve->y0 + b * ctrla->y + c * ctrlb->y + d * curve->y1;
- line.x1 = x;
- line.y1 = y;
-
- nsfb->plotter_fns->line(nsfb, 1, &line, &pen);
+ point->x = x;
+ point->y = y;
+ point++;
}
+ point->x = curve->x1;
+ point->y = curve->y1;
+
return true;
}
-static bool quadratic(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsfb_colour_t cl)
+static bool
+polylines(nsfb_t *nsfb,
+ int pointc,
+ const nsfb_point_t *points,
+ nsfb_plot_pen_t *pen)
{
+ int point_loop;
nsfb_bbox_t line;
- nsfb_plot_pen_t pen;
+ if (pen->stroke_type != NFSB_PLOT_OPTYPE_NONE) {
+ for (point_loop = 0; point_loop < (pointc - 1); point_loop++) {
+ line = *(nsfb_bbox_t *)&points[point_loop];
+ nsfb->plotter_fns->line(nsfb, 1, &line, pen);
+ }
+ }
+ return true;
+}
+
+
+static bool
+quadratic_points(unsigned int pointc,
+ nsfb_point_t *point,
+ nsfb_bbox_t *curve,
+ nsfb_point_t *ctrla)
+{
unsigned int seg_loop;
double t;
double one_minus_t;
@@ -575,13 +595,12 @@ static bool quadratic(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsf
double x;
double y;
- pen.stroke_colour = cl;
-
- x = curve->x0;
- y = curve->y0;
-
- for (seg_loop = 1; seg_loop <= N_SEG; ++seg_loop) {
- t = (double)seg_loop / (double)N_SEG;
+ point->x = curve->x0;
+ point->y = curve->y0;
+ point++;
+ pointc--;
+ for (seg_loop = 1; seg_loop < pointc; ++seg_loop) {
+ t = (double)seg_loop / (double)pointc;
one_minus_t = 1.0 - t;
@@ -589,36 +608,54 @@ static bool quadratic(nsfb_t *nsfb, nsfb_bbox_t *curve, nsfb_point_t *ctrla, nsf
b = 2.0 * t * one_minus_t;
c = t * t;
- line.x0 = x;
- line.y0 = y;
-
x = a * curve->x0 + b * ctrla->x + c * curve->x1;
y = a * curve->y0 + b * ctrla->y + c * curve->y1;
- line.x1 = x;
- line.y1 = y;
-
- nsfb->plotter_fns->line(nsfb, 1, &line, &pen);
+ point->x = x;
+ point->y = y;
+ point++;
}
+ point->x = curve->x1;
+ point->y = curve->y1;
+
return true;
}
+static bool
+quadratic(nsfb_t *nsfb,
+ nsfb_bbox_t *curve,
+ nsfb_point_t *ctrla,
+ nsfb_plot_pen_t *pen)
+{
+ nsfb_point_t points[N_SEG];
+
+ if (pen->stroke_type == NFSB_PLOT_OPTYPE_NONE)
+ return false;
+
+ quadratic_points(N_SEG, points, curve, ctrla);
-static bool polylines(nsfb_t *nsfb, int pointc, const nsfb_point_t *points, nsfb_plot_pen_t *pen)
+ return polylines(nsfb, N_SEG, points, pen);
+}
+
+static bool
+cubic(nsfb_t *nsfb,
+ nsfb_bbox_t *curve,
+ nsfb_point_t *ctrla,
+ nsfb_point_t *ctrlb,
+ nsfb_plot_pen_t *pen)
{
- int point_loop;
- nsfb_bbox_t line;
+ nsfb_point_t points[N_SEG];
- if (pen->stroke_type != NFSB_PLOT_OPTYPE_NONE) {
- for (point_loop = 0; point_loop < (pointc - 1); point_loop++) {
- line = *(nsfb_bbox_t *)&points[point_loop];
- nsfb->plotter_fns->line(nsfb, 1, &line, pen);
- }
- }
- return true;
+ if (pen->stroke_type == NFSB_PLOT_OPTYPE_NONE)
+ return false;
+
+ cubic_points(N_SEG, points, curve, ctrla,ctrlb);
+
+ return polylines(nsfb, N_SEG, points, pen);
}
+
static bool
path(nsfb_t *nsfb, int pathc, nsfb_plot_pathop_t *pathop, nsfb_plot_pen_t *pen)
{
@@ -626,40 +663,68 @@ path(nsfb_t *nsfb, int pathc, nsfb_plot_pathop_t *pathop, nsfb_plot_pen_t *pen)
nsfb_point_t *pts;
nsfb_point_t *curpt;
int ptc = 0;
+ nsfb_bbox_t curve;
+ nsfb_point_t ctrla;
+ nsfb_point_t ctrlb;
+ int added_count = 0;
+
+ /* count the verticies in the path and add N_SEG extra for curves */
+ for (path_loop = 0; path_loop < pathc; path_loop++) {
+ ptc++;
+ if ((pathop[path_loop].operation == NFSB_PLOT_PATHOP_QUAD) ||
+ (pathop[path_loop].operation == NFSB_PLOT_PATHOP_CUBIC))
+ ptc += N_SEG;
+ }
- /* count the verticies in the path and add N_SEG extra for curves */
- for (path_loop = 0; path_loop < pathc; path_loop++) {
- ptc++;
- if ((pathop[path_loop].operation == NFSB_PLOT_PATHOP_QUAD) ||
- (pathop[path_loop].operation == NFSB_PLOT_PATHOP_QUAD))
- ptc += N_SEG;
- }
-
- /* allocate storage for the vertexes */
- curpt = pts = malloc(ptc * sizeof(nsfb_point_t));
-
- for (path_loop = 0; path_loop < pathc; path_loop++) {
- switch (pathop[path_loop].operation) {
- case NFSB_PLOT_PATHOP_QUAD:
- curpt-=1;
- break;
-
- case NFSB_PLOT_PATHOP_CUBIC:
- curpt-=2;
- break;
-
- default:
- *curpt = pathop[path_loop].point;
- curpt++;
- }
+ /* allocate storage for the vertexes */
+ curpt = pts = malloc(ptc * sizeof(nsfb_point_t));
+
+ for (path_loop = 0; path_loop < pathc; path_loop++) {
+ switch (pathop[path_loop].operation) {
+ case NFSB_PLOT_PATHOP_QUAD:
+ curpt-=2;
+ added_count -= 2;
+ curve.x0 = pathop[path_loop - 2].point.x;
+ curve.y0 = pathop[path_loop - 2].point.y;
+ ctrla.x = pathop[path_loop - 1].point.x;
+ ctrla.y = pathop[path_loop - 1].point.y;
+ curve.x1 = pathop[path_loop].point.x;
+ curve.y1 = pathop[path_loop].point.y;
+ quadratic_points(N_SEG, curpt, &curve, &ctrla);
+ curpt+=N_SEG;
+ added_count += N_SEG;
+ break;
+
+ case NFSB_PLOT_PATHOP_CUBIC:
+ curpt-=3;
+ added_count -=3;
+ curve.x0 = pathop[path_loop - 3].point.x;
+ curve.y0 = pathop[path_loop - 3].point.y;
+ ctrla.x = pathop[path_loop - 2].point.x;
+ ctrla.y = pathop[path_loop - 2].point.y;
+ ctrlb.x = pathop[path_loop - 1].point.x;
+ ctrlb.y = pathop[path_loop - 1].point.y;
+ curve.x1 = pathop[path_loop].point.x;
+ curve.y1 = pathop[path_loop].point.y;
+ cubic_points(N_SEG, curpt, &curve, &ctrla, &ctrlb);
+ curpt += N_SEG;
+ added_count += N_SEG;
+ break;
+
+ default:
+ *curpt = pathop[path_loop].point;
+ curpt++;
+ added_count ++;
+ break;
}
+ }
if (pen->fill_type != NFSB_PLOT_OPTYPE_NONE) {
- polygon(nsfb, (int *)pts, path_loop, pen->fill_colour);
+ polygon(nsfb, (int *)pts, added_count, pen->fill_colour);
}
if (pen->stroke_type != NFSB_PLOT_OPTYPE_NONE) {
- polylines(nsfb, path_loop, pts, pen);
+ polylines(nsfb, added_count, pts, pen);
}
free(pts);