summaryrefslogtreecommitdiffstats
path: root/art_vpath_bpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'art_vpath_bpath.c')
-rw-r--r--art_vpath_bpath.c119
1 files changed, 58 insertions, 61 deletions
diff --git a/art_vpath_bpath.c b/art_vpath_bpath.c
index 3f9afe7..2459f23 100644
--- a/art_vpath_bpath.c
+++ b/art_vpath_bpath.c
@@ -123,18 +123,6 @@ art_vpath_render_bez (ArtVpath **p_vpath, int *pn, int *pn_max,
double x3, double y3,
double flatness)
{
- double x3_0, y3_0;
- double z3_0_dot;
- double z1_dot, z2_dot;
- double z1_perp, z2_perp;
- double max_perp_sq;
-
- double x_m, y_m;
- double xa1, ya1;
- double xa2, ya2;
- double xb1, yb1;
- double xb2, yb2;
-
/* It's possible to optimize this routine a fair amount.
First, once the _dot conditions are met, they will also be met in
@@ -157,70 +145,79 @@ art_vpath_render_bez (ArtVpath **p_vpath, int *pn, int *pn_max,
just that I have this undying quest for more speed...
*/
-
- x3_0 = x3 - x0;
- y3_0 = y3 - y0;
-
- /* z3_0_dot is dist z0-z3 squared */
- z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0;
-
- if (z3_0_dot < 0.001)
+ do
{
- /* if start and end point are almost identical, the flatness tests
- * don't work properly, so fall back on testing whether both of
- * the other two control points are the same as the start point,
- * too.
- */
- if (hypot(x1 - x0, y1 - y0) < 0.001
- && hypot(x2 - x0, y2 - y0) < 0.001)
- goto nosubdivide;
- else
- goto subdivide;
- }
+ /* don't subdivide inside this */
+ double x3_0, y3_0;
+ double z3_0_dot;
+ double z1_dot, z2_dot;
+ double z1_perp, z2_perp;
+ double max_perp_sq;
- /* we can avoid subdivision if:
+ x3_0 = x3 - x0;
+ y3_0 = y3 - y0;
- z1 has distance no more than flatness from the z0-z3 line
+ /* z3_0_dot is dist z0-z3 squared */
+ z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0;
- z1 is no more z0'ward than flatness past z0-z3
+ if (z3_0_dot > 0.001)
+ {
+ /* we can avoid subdivision if:
- z1 is more z0'ward than z3'ward on the line traversing z0-z3
+ z1 has distance no more than flatness from the z0-z3 line
- and correspondingly for z2 */
+ z1 is no more z0'ward than flatness past z0-z3
- /* perp is distance from line, multiplied by dist z0-z3 */
- max_perp_sq = flatness * flatness * z3_0_dot;
+ z1 is more z0'ward than z3'ward on the line traversing z0-z3
- z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0;
- if (z1_perp * z1_perp > max_perp_sq)
- goto subdivide;
+ and correspondingly for z2 */
- z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0;
- if (z2_perp * z2_perp > max_perp_sq)
- goto subdivide;
+ /* perp is distance from line, multiplied by dist z0-z3 */
+ max_perp_sq = flatness * flatness * z3_0_dot;
- z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0;
- if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq)
- goto subdivide;
+ z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0;
+ if (z1_perp * z1_perp > max_perp_sq)
+ break;
- z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0;
- if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq)
- goto subdivide;
+ z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0;
+ if (z2_perp * z2_perp > max_perp_sq)
+ break;
- if (z1_dot + z1_dot > z3_0_dot)
- goto subdivide;
+ z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0;
+ if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq)
+ break;
- if (z2_dot + z2_dot > z3_0_dot)
- goto subdivide;
+ if (z1_dot + z1_dot > z3_0_dot)
+ break;
-
- nosubdivide:
- /* don't subdivide */
- art_vpath_add_point (p_vpath, pn, pn_max,
- ART_LINETO, x3, y3);
- return;
+ z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0;
+ if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq)
+ break;
- subdivide:
+ if (z2_dot + z2_dot > z3_0_dot)
+ break;
+ }
+ else
+ {
+ /* if start and end point are almost identical, the flatness tests
+ * don't work properly, so fall back on testing whether both of
+ * the other two control points are the same as the start point,
+ * too.
+ */
+ if (hypot(x1 - x0, y1 - y0) > 0.001
+ || hypot(x2 - x0, y2 - y0) > 0.001)
+ break;
+ }
+
+ art_vpath_add_point (p_vpath, pn, pn_max,
+ ART_LINETO, x3, y3);
+ return;
+ } while (0);
+ double x_m, y_m;
+ double xa1, ya1;
+ double xa2, ya2;
+ double xb1, yb1;
+ double xb2, yb2;
xa1 = (x0 + x1) * 0.5;
ya1 = (y0 + y1) * 0.5;