summaryrefslogtreecommitdiff
path: root/src/plot/generic.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@netsurf-browser.org>2010-01-22 23:51:49 +0000
committerVincent Sanders <vince@netsurf-browser.org>2010-01-22 23:51:49 +0000
commit951f02ddbd4f0987d151461eec877808b5f125f8 (patch)
treebee0ea292be20230661b63244f6ab24275d07a92 /src/plot/generic.c
parentf6c7cb873e7998ff0641131bba57c0f83e53b938 (diff)
downloadlibnsfb-951f02ddbd4f0987d151461eec877808b5f125f8.tar.gz
libnsfb-951f02ddbd4f0987d151461eec877808b5f125f8.tar.bz2
Ensure the bezier curve routines do not generate duplicate points unecissarily.
svn path=/trunk/libnsfb/; revision=9866
Diffstat (limited to 'src/plot/generic.c')
-rw-r--r--src/plot/generic.c127
1 files changed, 73 insertions, 54 deletions
diff --git a/src/plot/generic.c b/src/plot/generic.c
index 2c3cdbb..041fd8f 100644
--- a/src/plot/generic.c
+++ b/src/plot/generic.c
@@ -515,10 +515,10 @@ static bool arc(nsfb_t *nsfb, int x, int y, int radius, int angle1, int angle2,
#define N_SEG 30
-static bool
+static int
cubic_points(unsigned int pointc,
- nsfb_point_t *point,
- nsfb_bbox_t *curve,
+ nsfb_point_t *point,
+ nsfb_bbox_t *curve,
nsfb_point_t *ctrla,
nsfb_point_t *ctrlb)
{
@@ -531,10 +531,11 @@ cubic_points(unsigned int pointc,
double d;
double x;
double y;
+ int cur_point;
- point->x = curve->x0;
- point->y = curve->y0;
- point++;
+ point[0].x = curve->x0;
+ point[0].y = curve->y0;
+ cur_point = 1;
pointc--;
for (seg_loop = 1; seg_loop < pointc; ++seg_loop) {
@@ -549,38 +550,32 @@ cubic_points(unsigned int pointc,
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;
-
- point->x = x;
- point->y = y;
- point++;
+
+ point[cur_point].x = x;
+ point[cur_point].y = y;
+ if ((point[cur_point].x != point[cur_point - 1].x) ||
+ (point[cur_point].y != point[cur_point - 1].y))
+ cur_point++;
}
- point->x = curve->x1;
- point->y = curve->y1;
+ point[cur_point].x = curve->x1;
+ point[cur_point].y = curve->y1;
+ if ((point[cur_point].x != point[cur_point - 1].x) ||
+ (point[cur_point].y != point[cur_point - 1].y))
+ cur_point++;
- return true;
+ return cur_point;
}
-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;
-
- 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
+/* calculate a series of points which describe a quadratic bezier spline.
+ *
+ * fills an array of points with values describing a quadratic curve. Both the
+ * start and end points are included as the first and last points
+ * respectively. Only if the next point on the curve is different from its
+ * predecessor is the point added which ensures points for the same position
+ * are not repeated.
+ */
+static int
quadratic_points(unsigned int pointc,
nsfb_point_t *point,
nsfb_bbox_t *curve,
@@ -594,11 +589,13 @@ quadratic_points(unsigned int pointc,
double c;
double x;
double y;
+ int cur_point;
+
+ point[0].x = curve->x0;
+ point[0].y = curve->y0;
+ cur_point = 1;
+ pointc--; /* we have added the start point, one less point in the curve */
- 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;
@@ -611,17 +608,42 @@ quadratic_points(unsigned int pointc,
x = a * curve->x0 + b * ctrla->x + c * curve->x1;
y = a * curve->y0 + b * ctrla->y + c * curve->y1;
- point->x = x;
- point->y = y;
- point++;
+ point[cur_point].x = x;
+ point[cur_point].y = y;
+ if ((point[cur_point].x != point[cur_point - 1].x) ||
+ (point[cur_point].y != point[cur_point - 1].y))
+ cur_point++;
}
- point->x = curve->x1;
- point->y = curve->y1;
+ point[cur_point].x = curve->x1;
+ point[cur_point].y = curve->y1;
+ if ((point[cur_point].x != point[cur_point - 1].x) ||
+ (point[cur_point].y != point[cur_point - 1].y))
+ cur_point++;
+ return cur_point;
+}
+
+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;
+
+ 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(nsfb_t *nsfb,
nsfb_bbox_t *curve,
@@ -633,9 +655,7 @@ quadratic(nsfb_t *nsfb,
if (pen->stroke_type == NFSB_PLOT_OPTYPE_NONE)
return false;
- quadratic_points(N_SEG, points, curve, ctrla);
-
- return polylines(nsfb, N_SEG, points, pen);
+ return polylines(nsfb, quadratic_points(N_SEG, points, curve, ctrla), points, pen);
}
static bool
@@ -650,9 +670,7 @@ cubic(nsfb_t *nsfb,
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);
+ return polylines(nsfb, cubic_points(N_SEG, points, curve, ctrla,ctrlb), points, pen);
}
@@ -667,6 +685,7 @@ path(nsfb_t *nsfb, int pathc, nsfb_plot_pathop_t *pathop, nsfb_plot_pen_t *pen)
nsfb_point_t ctrla;
nsfb_point_t ctrlb;
int added_count = 0;
+ int bpts;
/* count the verticies in the path and add N_SEG extra for curves */
for (path_loop = 0; path_loop < pathc; path_loop++) {
@@ -690,9 +709,9 @@ path(nsfb_t *nsfb, int pathc, nsfb_plot_pathop_t *pathop, nsfb_plot_pen_t *pen)
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;
+ bpts = quadratic_points(N_SEG, curpt, &curve, &ctrla);
+ curpt += bpts;
+ added_count += bpts;
break;
case NFSB_PLOT_PATHOP_CUBIC:
@@ -706,9 +725,9 @@ path(nsfb_t *nsfb, int pathc, nsfb_plot_pathop_t *pathop, nsfb_plot_pen_t *pen)
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;
+ bpts = cubic_points(N_SEG, curpt, &curve, &ctrla, &ctrlb);
+ curpt += bpts;
+ added_count += bpts;
break;
default: