/* Copyright (C) 2012-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3bezcu.ctr */ /** @file dk3bezcu.c The dk3bezcu module. */ #line 62 "dk3bezcu.ctr" #include "dk3all.h" #include "dk3bb.h" #include "dk3bezcu.h" #line 70 "dk3bezcu.ctr" #if !(defined(isgreaterequal)) #if DK3_HAVE_ISFINITE /** Test whether a is greater than or equal to b. */ #define isgreaterequal(a,b) ((isfinite(a)) && (isfinite(b)) && (a >= b)) #else #if DK3_HAVE__FINITE /** Test whether a is greater than or equal to b. */ #define isgreaterequal(a,b) ((_finite(a)) && (_finite(b)) && (a >= b)) #else /** Test whether a is greater than or equal to b. */ #define isgreaterequal(a,b) (a >= b) #endif #endif #endif #if !(defined(islessequal)) #if DK3_HAVE_ISFINITE /** Test whether a is less than or equal to b. */ #define islessequal(a,b) ((isfinite(a)) && (isfinite(b)) && (a <= b)) #else #if DK3_HAVE__FINITE /** Test whether a is less than or equal to b. */ #define islessequal(a,b) ((_finite(a)) && (_finite(b)) && (a <= b)) #else /** Test whether a is less than or equal to b. */ #define islessequal(a,b) (a <= b) #endif #endif #endif double dk3bezier_value( double x0, double xp, double xm, double x1, double t, int *ec ) { int mec = 0; double back; #line 115 "dk3bezcu.ctr" back = dk3ma_d_add_ok( x0, dk3ma_d_mul_ok( t, dk3ma_d_add_ok( dk3ma_d_sub_ok( dk3ma_d_mul_ok(3.0, xp, &mec), dk3ma_d_mul_ok(3.0, x0, &mec), &mec ), dk3ma_d_mul_ok( t, dk3ma_d_add_ok( dk3ma_d_add_ok( dk3ma_d_sub_ok( dk3ma_d_mul_ok(3.0, xm, &mec), dk3ma_d_mul_ok(6.0, xp, &mec), &mec ), dk3ma_d_mul_ok(3.0, x0, &mec), &mec ), dk3ma_d_mul_ok( t, dk3ma_d_add_ok( dk3ma_d_sub_ok( dk3ma_d_mul_ok(3.0, xp, &mec), dk3ma_d_mul_ok(3.0, xm, &mec), &mec ), dk3ma_d_sub_ok(x1, x0, &mec), &mec ), &mec ), &mec ), &mec ), &mec ), &mec ), &mec ); #line 160 "dk3bezcu.ctr" if(mec) { if(ec) { *ec = mec; } } #line 164 "dk3bezcu.ctr" return back; } /** Apply one t value to a bounding box. @param bb Bounding box to modify. @param x0 Start value. @param xp Control value for start. @param xm Control value for end. @param x1 End value. @param ra Point radius (half line width). @param tv The t value. @param isy Flag: Y direction. @param ec Pointer to error code variable, may be NULL. @return 1 on success, 0 on error. */ static int dk3bezier_t_dimension( dk3_bb_t *bb, double x0, double xp, double xm, double x1, double ra, double tv, int isy, int *ec ) { double val; int back = 1; int mec = 0; #line 199 "dk3bezcu.ctr" if(tv > 0.0) { if(tv < 1.0) { val = dk3bezier_value(x0, xp, xm, x1, tv, &mec); #line 202 "dk3bezcu.ctr" if(isy) { if(!dk3bb_add_y_width(bb, val, ra)) { back = 0; } } else { if(!dk3bb_add_x_width(bb, val, ra)) { back = 0; } } } } if(mec) { #line 210 "dk3bezcu.ctr" back = 0; if(ec) { *ec = mec; } } #line 213 "dk3bezcu.ctr" return back; } #if VERSION_BEFORE_20121218 /** Apply one dimension to a bounding box. @param bb Bounding box to modify. @param x0 Start value. @param xp Control value for start. @param xm Control value for end. @param x1 End value. @param ra Point radius (half line width). @param isy Flag: Y direction. @param ec Pointer to error code variable, may be NULL. @return 1 on success, 0 on error. */ static int dk3bezier_bb_dimension( dk3_bb_t *bb, double x0, double xp, double xm, double x1, double ra, int isy, int *ec ) { double n; double z1; double z2; double t; int back = 1; int mec = 0; #line 250 "dk3bezcu.ctr" n = dk3ma_d_add_ok( dk3ma_d_sub_ok(x1, x0, &mec), dk3ma_d_mul_ok(3.0, dk3ma_d_sub_ok(xp, xm, &mec), &mec), &mec ); #line 255 "dk3bezcu.ctr" z1 = dk3ma_d_sub_ok( dk3ma_d_sub_ok(dk3ma_d_mul_ok(2.0, xp, &mec), xm, &mec), x0, &mec ); #line 260 "dk3bezcu.ctr" z2 = dk3ma_d_add_ok( dk3ma_d_sub_ok( xm, dk3ma_d_mul_ok(2.0, xp, &mec), &mec ), x0, &mec ); #line 269 "dk3bezcu.ctr" z2 = dk3ma_d_mul_ok(z2, z2, &mec); z2 = dk3ma_d_sub_ok( z2, dk3ma_d_mul_ok( dk3ma_d_sub_ok(xp, x0, &mec), n, &mec ), &mec ); #line 279 "dk3bezcu.ctr" if(z2 >= 0.0) { z2 = sqrt(z2); #line 281 "dk3bezcu.ctr" t = dk3ma_d_div_ok( dk3ma_d_add_ok(z1, z2, &mec), n, &mec ); #line 286 "dk3bezcu.ctr" if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) { back = 0; } #line 289 "dk3bezcu.ctr" t = dk3ma_d_div_ok( dk3ma_d_sub_ok(z1, z2, &mec), n, &mec ); #line 294 "dk3bezcu.ctr" if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) { back = 0; } #line 297 "dk3bezcu.ctr" } if(mec) { #line 299 "dk3bezcu.ctr" back = 0; if(ec) { *ec = mec; } } #line 302 "dk3bezcu.ctr" return back; } #else #if VERSION_BEFORE_20170609 /** Apply one dimension to a bounding box. @param bb Bounding box to modify. @param x0 Start value. @param xp Control value for start. @param xm Control value for end. @param x1 End value. @param ra Point radius (half line width). @param isy Flag: Y direction. @param ec Pointer to error code variable, may be NULL. @return 1 on success, 0 on error. */ static int dk3bezier_bb_dimension( dk3_bb_t *bb, double x0, double xp, double xm, double x1, double ra, int isy, int *ec ) { double n; double z1; double z2; double t; int back = 1; int mec = 0; int testmec; #line 338 "dk3bezcu.ctr" n = dk3ma_d_add_ok( dk3ma_d_sub_ok(x1, x0, &mec), dk3ma_d_mul_ok(3.0, dk3ma_d_sub_ok(xp, xm, &mec), &mec), &mec ); #line 343 "dk3bezcu.ctr" z1 = dk3ma_d_sub_ok( dk3ma_d_sub_ok(dk3ma_d_mul_ok(2.0, xp, &mec), xm, &mec), x0, &mec ); #line 348 "dk3bezcu.ctr" z2 = dk3ma_d_add_ok( dk3ma_d_sub_ok( xm, dk3ma_d_mul_ok(2.0, xp, &mec), &mec ), x0, &mec ); #line 357 "dk3bezcu.ctr" z2 = dk3ma_d_mul_ok(z2, z2, &mec); z2 = dk3ma_d_sub_ok( z2, dk3ma_d_mul_ok( dk3ma_d_sub_ok(xp, x0, &mec), n, &mec ), &mec ); #line 367 "dk3bezcu.ctr" if(z2 >= 0.0) { z2 = sqrt(z2); #line 369 "dk3bezcu.ctr" testmec = 0; t = dk3ma_d_div_ok( dk3ma_d_add_ok(z1, z2, &mec), n, &testmec ); #line 375 "dk3bezcu.ctr" if(0 == testmec) { if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) { back = 0; } #line 379 "dk3bezcu.ctr" } testmec = 0; t = dk3ma_d_div_ok( dk3ma_d_sub_ok(z1, z2, &mec), n, &testmec ); #line 386 "dk3bezcu.ctr" if(0 == testmec) { if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) { back = 0; } #line 390 "dk3bezcu.ctr" } } if(mec) { #line 393 "dk3bezcu.ctr" back = 0; if(ec) { *ec = mec; } } #line 396 "dk3bezcu.ctr" return back; } #else /** Apply one dimension to a bounding box. @param bb Bounding box to modify. @param x0 Start value. @param xp Control value for start. @param xm Control value for end. @param x1 End value. @param ra Point radius (half line width). @param isy Flag: Y direction. @param ec Pointer to error code variable, may be NULL. @return 1 on success, 0 on error. */ static int dk3bezier_bb_dimension( dk3_bb_t *bb, double x0, double xp, double xm, double x1, double ra, int isy, int *ec ) { double a; double b; double c; double t1; double t2; double sqop; double sqv; double denom; int back = 1; int mec = 0; #line 434 "dk3bezcu.ctr" a = x1 - 3.0 * xm + 3.0 * xp - x0; b = 3.0 * x0 - 6.0 * xp + 3.0 * xm; c = 3.0 * (xp - x0); sqop = b * b - 3.0 * a * c; sqv = sqrt(sqop); denom = 3.0 * a; t1 = (0.0 - b + sqv) / (denom); t2 = (0.0 - b - sqv) / (denom); #if DK3_HAVE_ISFINITE if ((isfinite(t1)) && (isfinite(t2))) #else #if DK3_HAVE__FINITE if ((_finite(t1)) && (_finite(t2))) #else #error "Neither isfinite() nor _finite() available!" if (1) #endif #endif { #line 453 "dk3bezcu.ctr" if ((isgreaterequal(t1, 0.0)) && (islessequal(t1, 1.0))) { if(!dk3bezier_t_dimension( bb, x0, xp, xm, x1, ra, t1, isy, &mec ) ) { back = 0; } #line 460 "dk3bezcu.ctr" } if ((isgreaterequal(t2, 0.0)) && (islessequal(t2, 1.0))) { if(!dk3bezier_t_dimension( bb, x0, xp, xm, x1, ra, t2, isy, &mec ) ) { back = 0; } #line 468 "dk3bezcu.ctr" } } else { #line 471 "dk3bezcu.ctr" t1 = (0.0 - c) / (2.0 * b); #if DK3_HAVE_ISFINITE if (isfinite(t1)) #else #if DK3_HAVE__FINITE if (_finite(t1)) #else #error "Neither isfinite() nor _finite() available!" if (1) #endif #endif { if ((isgreaterequal(t1,0.0)) && (islessequal(t1,1.0))) { if(!dk3bezier_t_dimension( bb, x0, xp, xm, x1, ra, t1, isy, &mec ) ) { back = 0; } #line 490 "dk3bezcu.ctr" } } #if TRACE_DEBUG else { #line 494 "dk3bezcu.ctr" } #endif } if (0 != mec) { if (NULL != ec) { *ec = mec; } back = 0; } #line 501 "dk3bezcu.ctr" return back; } #endif #endif int dk3bezier_bb( dk3_bb_t *bb, double x0, double y0, double xp, double yp, double xm, double ym, double x1, double y1, double ra, int *ec ) { int back = 0; int mec = 0; #line 525 "dk3bezcu.ctr" if(bb) { back = 1; if(!dk3bb_point_width(bb, x0, y0, ra)) { back = 0; } if(!dk3bb_point_width(bb, x1, y1, ra)) { back = 0; } if(!dk3bezier_bb_dimension(bb, x0, xp, xm, x1, ra, 0, &mec)) { back = 0; } if(!dk3bezier_bb_dimension(bb, y0, yp, ym, y1, ra, 1, &mec)) { back = 0; } if(mec) { back = 0; if(ec) { *ec = mec; } } } else { if(ec) { *ec = DK3_ERROR_INVALID_ARGS; } } #line 546 "dk3bezcu.ctr" return back; }