From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- support/dktools/dk3figpr.ctr | 1259 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1259 insertions(+) create mode 100644 support/dktools/dk3figpr.ctr (limited to 'support/dktools/dk3figpr.ctr') diff --git a/support/dktools/dk3figpr.ctr b/support/dktools/dk3figpr.ctr new file mode 100644 index 0000000000..36669133d5 --- /dev/null +++ b/support/dktools/dk3figpr.ctr @@ -0,0 +1,1259 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2012-xxxx +license = bsd + + + +%% header + +#ifdef __cplusplus +extern "C" { +#endif + +/** Prepare drawing for printing. + This includes (1) allocating memory for arrowhead Fig objects, + (2) attaching arrowhead Fig objects for arrowheads, (3) shortening + the paths for arrowheads, and (4) finding + object and drawing bounding boxes. + @param drw Drawing to prepare. + @return 1 on success, 0 on error. +*/ +int +dk3fig_prepare(dk3_fig_drawing_t *drw); + +/** Add object bounding box to bounding box structure. + @param dbb Destination bounding box. + @param drw Drawing structure. + @param obj Object to add. + @param primobj Flag: Primary object (1=object, 0=arrowhead). + @return 1 on success, 0 on error. +*/ +int +dk3fig_prepare_obj_bb( + dk3_bb_t *dbb, + dk3_fig_drawing_t *drw, + dk3_fig_obj_t const *obj, + int primobj +); + +#ifdef __cplusplus +} +#endif + + + +%% module + +#include "dk3all.h" +#include "dk3fig.h" +#include "dk3figto.h" +#include "dk3figpr.h" +#include "dk3figbb.h" +#include "dk3figah.h" +#include "fig2lat.h" + +$!trace-include + + + +/** If the first object is a background rectangle check + whether it was created by jFig or XFig. + @param drw Drawing. + @param obj Object to check. + @param objno Object number. +*/ +static +void +dk3fig_prepare_check_bgrect( + dk3_fig_drawing_t *drw, + dk3_fig_obj_t *obj, + unsigned long objno +) +{ + $? "+ dk3fig_prepare_check_bgrect" + if(dk3fig_tool_is_bgrect(obj, objno)) { + if(DK3_FIG_SRCTYPE_UNKNOWN == drw->srctype) { + switch(obj->pc) { + case 7: { $? ". jFig file" + drw->srctype = DK3_FIG_SRCTYPE_JFIG; + } break; + default: { $? ". XFig file" + drw->srctype = DK3_FIG_SRCTYPE_XFIG; + } break; + } + } + } $? "- dk3fig_prepare_check_bgrect" +} + + + +#if TRACE_DEBUG +/** Calculate distance of 2 points, used to verify the correct + radius calculation for args. + @param x1 Point 1 x. + @param x2 Point 2 x. + @param y1 Point 1 y. + @param y2 Point 2 y. + @return Distance between points. +*/ +static +double +dk3fig_prepare_point_distance( + double x1, double x2, double y1, double y2 +) +{ + double back; + back = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); + return back; +} +#endif + + + +/** Initialize arc object (calculate center and radius). + @param drw Drawing. + @param obj Object. + @param objno Object number (0 for first object). + @param primobj Flag: Primary object (1=object, 0=arrowhead). + @return 1 on success, 0 on error. +*/ +static +int +dk3fig_prepare_initialize_arc( + dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj +) +{ + dk3_fig_poly_point_t *points; + dk3_fig_det_arc_t *arc; + double tm; /* The t parameter of the M point. */ + double n; /* Denominator in tm calculation. */ + double xa; + double ya; + double xc; + double yc; + double r; + double eps = DK3_FIG_EPSILON; + int back = 1; + int ec = 0; + int divec = 0; + $? "+ dk3fig_prepare_initialize_arc" + arc = &((obj->dt).arc); + n = dk3ma_d_sub_ok( + dk3ma_d_mul_ok( + dk3ma_d_sub_ok(arc->y2, arc->y1, &ec), + dk3ma_d_sub_ok(arc->x2, arc->x3, &ec), + &ec + ), + dk3ma_d_mul_ok( + dk3ma_d_sub_ok(arc->y3, arc->y2, &ec), + dk3ma_d_sub_ok(arc->x1, arc->x2, &ec), + &ec + ), + &ec + ); + tm = 0.5 * dk3ma_d_div_ok( + dk3ma_d_sub_ok( + dk3ma_d_mul_ok( + dk3ma_d_sub_ok(arc->x2, arc->x3, &ec), + dk3ma_d_sub_ok(arc->x3, arc->x1, &ec), + &ec + ), + dk3ma_d_mul_ok( + dk3ma_d_sub_ok(arc->y3, arc->y2, &ec), + dk3ma_d_sub_ok(arc->y3, arc->y1, &ec), + &ec + ), + &ec + ), + n, + &divec + ); + if(0 == divec) { + arc->xc = dk3ma_d_add_ok( + (0.5 * dk3ma_d_add_ok(arc->x1, arc->x2, &ec)), + dk3ma_d_mul_ok( + tm, + dk3ma_d_sub_ok(arc->y2, arc->y1, &ec), + &ec + ), + &ec + ); + arc->yc = dk3ma_d_add_ok( + (0.5 * dk3ma_d_add_ok(arc->y1, arc->y2, &ec)), + dk3ma_d_mul_ok( + tm, + dk3ma_d_sub_ok(arc->x1, arc->x2, &ec), + &ec + ), + &ec + ); + arc->ra = sqrt( + dk3ma_d_add_ok( + dk3ma_d_mul_ok( + dk3ma_d_sub_ok(arc->xc, arc->x1, &ec), + dk3ma_d_sub_ok(arc->xc, arc->x1, &ec), + &ec + ), + dk3ma_d_mul_ok( + dk3ma_d_sub_ok(arc->yc, arc->y1, &ec), + dk3ma_d_sub_ok(arc->yc, arc->y1, &ec), + &ec + ), + &ec + ) + ); + arc->as = dk3ma_d_atan2( + dk3ma_d_sub_ok(arc->y1, arc->yc, &ec), + dk3ma_d_sub_ok(arc->x1, arc->xc, &ec) + ); + arc->ae = dk3ma_d_atan2( + dk3ma_d_sub_ok(arc->y3, arc->yc, &ec), + dk3ma_d_sub_ok(arc->x3, arc->xc, &ec) + ); + if(n >= 0.0) { + arc->di = 0x01; + while(arc->ae < arc->as) { + arc->ae = arc->ae + (2.0 * M_PI); + } + } else { + arc->di = 0x00; + while(arc->as < arc->ae) { + arc->as = arc->as + (2.0 * M_PI); + } + } + $? ". point 1:\t%lg\t%lg", arc->x1, arc->y1 + $? ". point 2:\t%lg\t%lg", arc->x2, arc->y2 + $? ". point 3:\t%lg\t%lg", arc->x3, arc->y3 + $? ". point M:\t%lg\t%lg", arc->xc, arc->yc + $? ". radius: \t%lg", arc->ra + $? ". r 1 : \t%lg", dk3fig_prepare_point_distance(arc->x1, arc->xc, arc->y1, arc->yc) + $? ". r 1 : \t%lg", dk3fig_prepare_point_distance(arc->x2, arc->xc, arc->y2, arc->yc) + $? ". r 1 : \t%lg", dk3fig_prepare_point_distance(arc->x3, arc->xc, arc->y3, arc->yc) + $? ". alphas: \t%lg", (180.0 * arc->as) / M_PI + $? ". alphae: \t%lg", (180.0 * arc->ae) / M_PI + $? ". dir: \t%!8s", ((arc->di) ? "pos" : "neg") + } else { + /* line */ + back = 0; + xa = arc->x1; + ya = arc->y1; + xc = arc->x3; + yc = arc->y3; + if(dk3ma_d_equal(xa, xc, eps) && dk3ma_d_equal(ya, yc, eps)) { + r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec); + switch(obj->cs) { + case DK3_FIG_LC_ROUND: { + back = 1; + dk3mem_res( + (void *)(&((obj->dt))), + sizeof(dk3_fig_obj_det_t) + ); + obj->ot = DK3_FIG_OBJ_ELLIPSE; + obj->st = 3; /* Circle defined by radius */ + obj->lw = 0; + obj->fc = obj->pc; + obj->fi = 20; /* Full saturation of color. */ + obj->cs = DK3_FIG_LC_BUTT; + obj->js = DK3_FIG_LJ_MITER; + obj->ls = DK3_FIG_LS_SOLID; + obj->cl = 1; + (obj->dt).ell.an = 0.0; + (obj->dt).ell.cx = xa; + (obj->dt).ell.cy = ya; + (obj->dt).ell.rx = (obj->dt).ell.ry = r; + } break; + default: { + points = dk3_new_app(dk3_fig_poly_point_t,4,drw->app); + if(points) { + back = 1; + points[0].x = points[3].x = dk3ma_d_sub_ok(xa, r, &ec); + points[1].x = points[2].x = dk3ma_d_add_ok(xa, r, &ec); + points[0].y = points[1].y = dk3ma_d_sub_ok(ya, r, &ec); + points[2].y = points[3].y = dk3ma_d_add_ok(ya, r, &ec); + dk3mem_res( + (void *)(&((obj->dt))), + sizeof(dk3_fig_obj_det_t) + ); + obj->ot = DK3_FIG_OBJ_POLYLINE; + obj->st = 3; /* Polygon */ + obj->lw = 0; + obj->fc = obj->pc; + obj->fi = 20; /* Full saturation of color. */ + obj->cs = DK3_FIG_LC_BUTT; + obj->js = DK3_FIG_LJ_MITER; + obj->ls = DK3_FIG_LS_SOLID; + obj->cl = 1; + (obj->dt).pol.fn = NULL; + (obj->dt).pol.po = points; + (obj->dt).pol.ra = 0.0; + (obj->dt).pol.xs = 0.0; + (obj->dt).pol.ys = 0.0; + (obj->dt).pol.xe = 0.0; + (obj->dt).pol.ye = 0.0; + (obj->dt).pol.np = 4; + (obj->dt).pol.flf = 0; + } else { + back = 0; + dk3fig_set_ec(drw, DK3_ERROR_MEMORY); + } + } break; + } + } else { + points = dk3_new_app(dk3_fig_poly_point_t,2,drw->app); + if(points) { + back = 1; + points[0].x = xa; + points[0].y = ya; + points[1].x = xc; + points[1].y = yc; + (obj->dt).pol.fn = NULL; + (obj->dt).pol.po = points; + (obj->dt).pol.ra = 0.0; + (obj->dt).pol.xs = xa; + (obj->dt).pol.ys = ya; + (obj->dt).pol.xe = xc; + (obj->dt).pol.ye = yc; + (obj->dt).pol.np = 2; + (obj->dt).pol.flf = 0; + obj->ot = DK3_FIG_OBJ_POLYLINE; + obj->st = 1; + } else { + dk3fig_set_ec(drw, DK3_ERROR_MEMORY); + /* memory allocation failed, reported by back == 0. */ + } + } + } + if(ec) { $? "! math problem in arc" + back = 0; + /* ERROR: Mathematical problem with arc! */ + dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW); + dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 3); + } + $? "- dk3fig_prepare_initialize_arc %d", back + return back; +} + + + +/** Convert polyline to circle or squara if necessary. + @param drw Drawing. + @param obj Object. + @param objno Object number (0 for first object). + @param primobj Flag: Primary object (1=object, 0=arrowhead). + @return 1 on success, 0 on error. +*/ +static +int +dk3fig_prepare_initialize_polyline( + dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj +) +{ + dk3_fig_poly_point_t *newpoints; + double cx; + double cy; + double r; + double x1; + double x2; + double y1; + double y2; + double eps = DK3_FIG_EPSILON; + int back = 1; + int mc = 0; + int ec = 0; + $? "+ dk3fig_prepare_initialize_polyline" + if(1 == (obj->dt).pol.np) { + mc = 1; + } else { + if(2 == (obj->dt).pol.np) { + if(dk3ma_d_equal(((obj->dt).pol.po)[0].x, ((obj->dt).pol.po)[1].x, eps)) { + if(dk3ma_d_equal(((obj->dt).pol.po)[0].y, ((obj->dt).pol.po)[1].y, eps)) { + mc = 1; + } + } + } + } + if(mc) { + switch(obj->cs) { + case DK3_FIG_LC_ROUND: { $? ". convert polyline dot to circle" + cx = ((obj->dt).pol.po)[0].x; + cy = ((obj->dt).pol.po)[0].y; + r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec); + dk3_release((obj->dt).pol.fn); + dk3_release((obj->dt).pol.po); + dk3mem_res( + (void *)(&((obj->dt))), + sizeof(dk3_fig_obj_det_t) + ); + obj->ot = DK3_FIG_OBJ_ELLIPSE; + obj->st = 3; /* Circle defined by radius */ + obj->lw = 0; + obj->fc = obj->pc; + obj->fi = 20; /* Full saturation of color. */ + obj->cs = DK3_FIG_LC_BUTT; + obj->js = DK3_FIG_LJ_MITER; + obj->ls = DK3_FIG_LS_SOLID; + obj->cl = 1; + (obj->dt).ell.an = 0.0; + (obj->dt).ell.cx = cx; + (obj->dt).ell.cy = cy; + (obj->dt).ell.rx = (obj->dt).ell.ry = r; + } break; + default: { $? ". convert polyline dot to square" + cx = ((obj->dt).pol.po)[0].x; + cy = ((obj->dt).pol.po)[0].y; + r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec); + x1 = dk3ma_d_sub_ok(cx, r, &ec); + x2 = dk3ma_d_add_ok(cx, r, &ec); + y1 = dk3ma_d_sub_ok(cy, r, &ec); + y2 = dk3ma_d_add_ok(cy, r, &ec); + newpoints = dk3_new_app(dk3_fig_poly_point_t,4,drw->app); + if(newpoints) { + newpoints[0].x = x1; newpoints[0].y = y1; + newpoints[1].x = x2; newpoints[1].y = y1; + newpoints[2].x = x2; newpoints[2].y = y2; + newpoints[3].x = x1; newpoints[3].y = y2; + dk3_release((obj->dt).pol.fn); + dk3_release((obj->dt).pol.po); + dk3mem_res( + (void *)(&((obj->dt))), + sizeof(dk3_fig_obj_det_t) + ); + obj->ot = DK3_FIG_OBJ_POLYLINE; + obj->st = 3; /* Polygon */ + obj->lw = 0; + obj->fc = obj->pc; + obj->fi = 20; /* Full saturation of color. */ + obj->cs = DK3_FIG_LC_BUTT; + obj->js = DK3_FIG_LJ_MITER; + obj->ls = DK3_FIG_LS_SOLID; + obj->cl = 1; + (obj->dt).pol.fn = NULL; + (obj->dt).pol.po = newpoints; + (obj->dt).pol.ra = 0.0; + (obj->dt).pol.xs = 0.0; + (obj->dt).pol.ys = 0.0; + (obj->dt).pol.xe = 0.0; + (obj->dt).pol.ye = 0.0; + (obj->dt).pol.np = 4; + (obj->dt).pol.flf = 0; + } else { + back = 0; + dk3fig_set_ec(drw, DK3_ERROR_MEMORY); + } + } break; + } + } + if(ec) { $? "! math error" + /* ERROR: Math */ + dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW); + back = 0; + dk3app_log_i1(drw->app, DK3_LL_ERROR, 260); + } $? "- dk3fig_prepare_initialize_polyline %d", back + return back; +} + + + +#if 0 +/* + Only polylines are allowed to have one point, not splines. +*/ +/** Convert spline to circle or squara if necessary. + @param drw Drawing. + @param obj Object. + @param objno Object number (0 for first object). + @param primobj Flag: Primary object (1=object, 0=arrowhead). + @return 1 on success, 0 on error. +*/ +static +int +dk3fig_prepare_initialize_spline( + dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj +) +{ + dk3_fig_poly_point_t *newpoints; + double cx; + double cy; + double r; + double x1; + double x2; + double y1; + double y2; + double eps = DK3_FIG_EPSILON; + int back = 1; + int mc = 0; + int ec = 0; + $? "+ dk3fig_prepare_initialize_spline" + if(1 == (obj->dt).spl.np) { + mc = 1; + } else { + if(2 == (obj->dt).spl.np) { + if(dk3ma_d_equal(((obj->dt).spl.po)[0].x, ((obj->dt).spl.po)[1].x, eps)) { + if(dk3ma_d_equal(((obj->dt).spl.po)[0].y, ((obj->dt).spl.po)[1].y, eps)) { + mc = 1; + } + } + } + } + if(mc) { + switch(obj->cs) { + case DK3_FIG_LC_ROUND: { $? ". convert spline dot to circle" + cx = ((obj->dt).spl.po)[0].x; + cy = ((obj->dt).spl.po)[0].y; + r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec); + dk3_release((obj->dt).spl.po); + dk3mem_res( + (void *)(&((obj->dt))), + sizeof(dk3_fig_obj_det_t) + ); + obj->ot = DK3_FIG_OBJ_ELLIPSE; + obj->st = 3; /* Circle defined by radius */ + obj->lw = 0; + obj->fc = obj->pc; + obj->fi = 20; /* Full saturation of color. */ + obj->cs = DK3_FIG_LC_BUTT; + obj->js = DK3_FIG_LJ_MITER; + obj->ls = DK3_FIG_LS_SOLID; + obj->cl = 1; + (obj->dt).ell.an = 0.0; + (obj->dt).ell.cx = cx; + (obj->dt).ell.cy = cy; + (obj->dt).ell.rx = (obj->dt).ell.ry = r; + } break; + default: { $? ". convert spline dot to square" + cx = ((obj->dt).spl.po)[0].x; + cy = ((obj->dt).spl.po)[0].y; + r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec); + x1 = dk3ma_d_sub_ok(cx, r, &ec); + x2 = dk3ma_d_add_ok(cx, r, &ec); + y1 = dk3ma_d_sub_ok(cy, r, &ec); + y2 = dk3ma_d_add_ok(cy, r, &ec); + newpoints = dk3_new_app(dk3_fig_poly_point_t,4,drw->app); + if(newpoints) { + newpoints[0].x = x1; newpoints[0].y = y1; + newpoints[1].x = x2; newpoints[1].y = y1; + newpoints[2].x = x2; newpoints[2].y = y2; + newpoints[3].x = x1; newpoints[3].y = y2; + dk3_release((obj->dt).spl.po); + dk3mem_res( + (void *)(&((obj->dt))), + sizeof(dk3_fig_obj_det_t) + ); + obj->ot = DK3_FIG_OBJ_POLYLINE; + obj->st = 3; /* Polygon */ + obj->lw = 0; + obj->fc = obj->pc; + obj->fi = 20; /* Full saturation of color. */ + obj->cs = DK3_FIG_LC_BUTT; + obj->js = DK3_FIG_LJ_MITER; + obj->ls = DK3_FIG_LS_SOLID; + obj->cl = 1; + (obj->dt).pol.fn = NULL; + (obj->dt).pol.po = newpoints; + (obj->dt).pol.ra = 0.0; + (obj->dt).pol.xs = 0.0; + (obj->dt).pol.ys = 0.0; + (obj->dt).pol.xe = 0.0; + (obj->dt).pol.ye = 0.0; + (obj->dt).pol.np = 4; + (obj->dt).pol.flf = 0; + } else { + back = 0; + } + } break; + } + } + if(ec) { $? "! math error" + dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW); + /* ERROR: Math */ + dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38); + } $? "- dk3fig_prepare_initialize_spline %d", back + return back; +} +#endif + + + + +/** Object type specific initialization. + @param drw Drawing. + @param obj Object. + @param objno Object number (0 for first object). + @param primobj Flag: Primary object (1=object, 0=arrowhead). + @return 1 on success, 0 on error. +*/ +static +int +dk3fig_prepare_initialize_object( + dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj +) +{ + int back = 1; + $? "+ dk3fig_prepare_initialize_object" + switch(obj->ot) { + case DK3_FIG_OBJ_POLYLINE: { + back = dk3fig_prepare_initialize_polyline(drw, obj, objno, primobj); + } break; +#if 0 + /* + Only polylines are allowed to have one point, not splines. + */ + case DK3_FIG_OBJ_SPLINE: { + back = dk3fig_prepare_initialize_spline(drw, obj, objno, primobj); + } break; +#endif + case DK3_FIG_OBJ_ARC: { + back = dk3fig_prepare_initialize_arc(drw, obj, objno, primobj); + } break; + } $? "- dk3fig_prepare_initialize_object %d", back + return back; +} + + + +/** Add object to drawing bounding box. + @param drw Drawing to calculate the bounding box for. + @param obj Object to add to bounding box. + @param primobj Flag: Primary object (1=object, 0=arrowhead). + @return 1 on success, 0 on error. +*/ +static +int +dk3fig_prepare_add_to_bb( + dk3_fig_drawing_t *drw, + dk3_fig_obj_t const *obj, + int primobj +); + + + +/** Add objects for one arrowhead to bounding box. + @param drw + @param obj + @param ah + @return 1 on success, 0 on error. +*/ +static +int +dk3fig_prepare_arrowhead_object( + dk3_fig_drawing_t *drw, + dk3_fig_obj_t const *obj, + dk3_fig_ah_t const *ah +) +{ + int back = 1; + $? "+ dk3fig_prepare_arrowhead_object" + if(ah) { + if(ah->o1) { + if(!dk3fig_prepare_add_to_bb(drw, (dk3_fig_obj_t *)(ah->o1), 0)) { + back = 0; + } + } + if(ah->o2) { + if(!dk3fig_prepare_add_to_bb(drw, (dk3_fig_obj_t *)(ah->o2), 0)) { + back = 0; + } + } + if(!(back)) { + dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW); + /* ERROR: Math overflow */ + } + } $? "- dk3fig_prepare_arrowhead_object %d", back + return back; +} + + + +int +dk3fig_prepare_obj_bb( + dk3_bb_t *dbb, + dk3_fig_drawing_t *drw, + dk3_fig_obj_t const *obj, + int primobj +) +{ + int back = 0; + int notfound = 0; + switch(obj->ot) { + case DK3_FIG_OBJ_ELLIPSE: { $? ". ellipse" + back = dk3fig_bb_add_ellipse( + dbb, &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + case DK3_FIG_OBJ_POLYLINE: { $? ". polyline %d lw=%d", obj->la, obj->lw + back = dk3fig_bb_add_polyline( + dbb, &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + case DK3_FIG_OBJ_SPLINE: { $? ". spline" + back = dk3fig_bb_add_spline( + drw, + dbb, &((obj->dt).spl), + (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj, + ((obj->cl) ? 1 : 0) + ); + } break; + case DK3_FIG_OBJ_TEXT: { $? ". text" + back = dk3fig_bb_add_text( + dbb, &((obj->dt).txt), drw->res, drw->bbts + ); + } break; + case DK3_FIG_OBJ_ARC: { $? ". arc" + back = dk3fig_bb_add_arc( + dbb, &((obj->dt).arc), + ((1 != obj->st) ? 1 : 0), + (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + default: { $? "! unknown object" + dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); + /* ERROR: Unknown object type! */ + dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 8); + notfound = 1; + } break; + } + if(!(back)) { + if(!(notfound)) { + dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW); + /* ERROR: Math overflow */ + } + } + return back; +} + + + +static +int +dk3fig_prepare_add_to_bb( + dk3_fig_drawing_t *drw, + dk3_fig_obj_t const *obj, + int primobj +) +{ +#if TEST_SHOW_EACH_BB + int back = 0; + dk3_bb_t mybb; + $? "+ dk3fig_prepare_add_to_bb" + dk3bb_reset(&mybb); + switch(obj->ot) { + case DK3_FIG_OBJ_ELLIPSE: { $? ". ellipse" + back = dk3fig_bb_add_ellipse( + &mybb, &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + case DK3_FIG_OBJ_POLYLINE: { $? ". polyline %d lw=%d", obj->la, obj->lw + back = dk3fig_bb_add_polyline( + &mybb, &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + case DK3_FIG_OBJ_SPLINE: { $? ". spline" + back = dk3fig_bb_add_spline( + drw, + &mybb, &((obj->dt).spl), + (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj, + ((obj->cl) ? 1 : 0) + ); + } break; + case DK3_FIG_OBJ_TEXT: { $? ". text" + back = dk3fig_bb_add_text( + &mybb, &((obj->dt).txt), drw->res, drw->bbts + ); + } break; + case DK3_FIG_OBJ_ARC: { $? ". arc" + back = dk3fig_bb_add_arc( + &mybb, &((obj->dt).arc), + ((1 != obj->st) ? 1 : 0), + (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: { + back = dk3fig_bb_add_hci( + &mybb, &(obj->dt).hci, (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + default: { $? "! unknown object" + } break; + } $? ". bb x = %lg %lg y = %lg %lg",mybb.xmin,mybb.xmax,mybb.ymin,mybb.ymax + dk3bb_merge(&(drw->bb), &mybb); + if(primobj) { + if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->af)) { back = 0; } + if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->ab)) { back = 0; } + } + if(!(back)) { + /* ERROR: Math overflow */ + dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW); + dk3app_log_i1(drw->app, DK3_LL_ERROR, 260); + } + $? "- dk3fig_prepare_add_to_bb %d", back + return back; +#else + int back = 0; + $? "+ dk3fig_prepare_add_to_bb" + switch(obj->ot) { + case DK3_FIG_OBJ_ELLIPSE: { $? ". ellipse" + back = dk3fig_bb_add_ellipse( + &(drw->bb), &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + case DK3_FIG_OBJ_POLYLINE: { $? ". polyline %d lw=%d", obj->la, obj->lw + back = dk3fig_bb_add_polyline( + &(drw->bb), &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + case DK3_FIG_OBJ_SPLINE: { $? ". spline" + back = dk3fig_bb_add_spline( + drw, + &(drw->bb), &((obj->dt).spl), + (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj, + ((obj->cl) ? 1 : 0) + ); + } break; + case DK3_FIG_OBJ_TEXT: { $? ". text" + back = dk3fig_bb_add_text( + &(drw->bb), &((obj->dt).txt), drw->res, drw->bbts + ); + } break; + case DK3_FIG_OBJ_ARC: { $? ". arc" + back = dk3fig_bb_add_arc( + &(drw->bb), &((obj->dt).arc), + ((1 != obj->st) ? 1 : 0), + (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: { + back = dk3fig_bb_add_hci( + &(drw->bb), &((obj->dt).hci), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)) + ); + } break; + default: { $? "! unknown object" + } break; + } + if(primobj) { + if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->af)) { back = 0; } + if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->ab)) { back = 0; } + } + if(!(back)) { + /* ERROR: Math overflow */ + dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW); + dk3app_log_i1(drw->app, DK3_LL_ERROR, 260); + } + $? "- dk3fig_prepare_add_to_bb %d", back + return back; +#endif +} + + + +#if TRACE_DEBUG +/** Report object to trace file. + @param obj Object to report. + @param primobj Flag: Primary object (1=object, 0=arrowhead). +*/ +static +void +dk3fig_prepare_report_object(dk3_fig_obj_t *obj, int primobj); + +/** Report one arrowhead to trace file. + @param ah Arrowhead to report. +*/ +static +void +dk3fig_prepare_report_ah(dk3_fig_ah_t *ah) +{ + if(ah) { + $? "+ dk3fig_prepare_report_ah" + if(ah->o1) { + dk3fig_prepare_report_object((dk3_fig_obj_t *)(ah->o1), 0); + } + if(ah->o2) { + dk3fig_prepare_report_object((dk3_fig_obj_t *)(ah->o2), 0); + } + $? "- dk3fig_prepare_report_ah" + } +} + + + +static +void +dk3fig_prepare_report_object(dk3_fig_obj_t *obj, int primobj) +{ + FILE *fipo; + dk3_fig_poly_point_t *pp; + dk3_fig_spline_point_t *sp; + size_t i; + $? "+ dk3fig_prepare_report_object primary=%d", primobj + fipo = dktrace_file(); + if(fipo) { + switch(obj->ot) { + case DK3_FIG_OBJ_ELLIPSE: { + fputs("Ellipse\n", fipo); + switch(obj->st) { + case 1: { + fputs("Ellipse by radii\n", fipo); + } break; + case 2: { + fputs("Ellipse by diameter\n", fipo); + } break; + case 3: { + fputs("Circle by radius\n", fipo); + } break; + case 4: { + fputs("Circle by diameter\n", fipo); + } break; + default: { + fputs("UNKNOWN SUB-TYPE\n", fipo); + } break; + } + } break; + case DK3_FIG_OBJ_POLYLINE: { + fputs("Polyline\n", fipo); + switch(obj->st) { + case 1: { + fputs("Polyline\n", fipo); + } break; + case 2: { + fputs("Box\n", fipo); + } break; + case 3: { + fputs("Polygon\n", fipo); + } break; + case 4: { + fputs("Arc-box\n", fipo); + } break; + case 5: { + fputs("Imported image\n", fipo); + } break; + default: { + fputs("UNKNOWN SUBTYPE\n", fipo); + } break; + } + } break; + case DK3_FIG_OBJ_SPLINE: { + fputs("Spline\n", fipo); + switch(obj->st) { + case 0: { + fputs("Open approximated\n", fipo); + } break; + case 1: { + fputs("Closed approximated\n", fipo); + } break; + case 2: { + fputs("Open interpolated\n", fipo); + } break; + case 3: { + fputs("Closed interpolated\n", fipo); + } break; + case 4: { + fputs("Open X-spline\n", fipo); + } break; + case 5: { + fputs("Closed X-spline\n", fipo); + } break; + default: { + fputs("UNKNOWN SUBTYPE\n", fipo); + } break; + } + } break; + case DK3_FIG_OBJ_TEXT: { + fputs("Text\n", fipo); + switch(obj->st) { + case 0: { + fputs("Left-aligned\n", fipo); + } break; + case 1: { + fputs("Centered\n", fipo); + } break; + case 2: { + fputs("Right-aligned\n", fipo); + } break; + default: { + fputs("UNKNOWN SUB-TYPE\n", fipo); + } break; + } + } break; + case DK3_FIG_OBJ_ARC: { + fputs("Arc\n", fipo); + switch(obj->st) { + case 1: { + fputs("Open arc\n", fipo); + } break; + case 2: { + fputs("Closed arc\n", fipo); + } break; + default: { + fputs("UNKNOWN SUB-TYPE\n", fipo); + } break; + } + } break; + case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: { + fputs("Half-circle\n", fipo); + if(obj->st) { + fputs("Closed filled half-circle\n", fipo); + } else { + fputs("Open half-circle\n", fipo); + } + } break; + default: { + fputs("UNKNOWN OBJECT TYPE\n", fipo); + } break; + } + fprintf(fipo, "Layer: %d\n", obj->la); + fprintf(fipo, "Line number: %lu\n", obj->li); + fprintf(fipo, "Closed: %d\n", obj->cl); + fprintf(fipo, "Line width: %d\n", obj->lw); + fprintf(fipo, "Pen color: %d\n", obj->pc); + fprintf(fipo, "Fill color: %d\n", obj->fc); + fprintf(fipo, "Fill type: %d\n", obj->fi); + fprintf(fipo, "Line cap: %d\n", obj->cs); + fprintf(fipo, "Line join: %d\n", obj->js); + fprintf(fipo, "Line style: %d\n", obj->ls); + fprintf(fipo, "Style value: %g\n", obj->sv); + switch(obj->ot) { + case DK3_FIG_OBJ_ELLIPSE: { + fprintf(fipo, "Center x: %g\n", (obj->dt).ell.cx); + fprintf(fipo, "Center y: %g\n", (obj->dt).ell.cy); + fprintf(fipo, "Radius x: %g\n", (obj->dt).ell.rx); + fprintf(fipo, "Radius y: %g\n", (obj->dt).ell.ry); + fprintf(fipo, "Angle: %g\n", (180.0 * (obj->dt).ell.an / M_PI)); + } break; + case DK3_FIG_OBJ_POLYLINE: { + fprintf(fipo, "Radius: %g\n", (obj->dt).pol.ra); + fprintf(fipo, "Start x: %g\n", (obj->dt).pol.xs); + fprintf(fipo, "Start y: %g\n", (obj->dt).pol.ys); + fprintf(fipo, "End x: %g\n", (obj->dt).pol.xe); + fprintf(fipo, "End y: %g\n", (obj->dt).pol.ye); + if(5 == obj->st) { + fprintf(fipo, "Flip: %d\n", (obj->dt).pol.flf); + fprintf(fipo, "Image: \"%s\"", TR_8STR((obj->dt).pol.fn)); + } + fprintf(fipo, "Points: %lu\n", (unsigned long)((obj->dt).pol.np)); + if((obj->dt).pol.po) { + pp = (obj->dt).pol.po; i = (obj->dt).pol.np; + while(i--) { + fprintf(fipo, "%g %g\n", pp->x, pp->y); + pp++; + } + } else { + fprintf(fipo, "ERROR: NO POINTS!\n"); + } + } break; + case DK3_FIG_OBJ_SPLINE: { + fprintf(fipo, "Start t: %g\n", (obj->dt).spl.ts); + fprintf(fipo, "End t: %g\n", (obj->dt).spl.te); + fprintf(fipo, "Points: %lu\n", (unsigned long)((obj->dt).spl.np)); + if((obj->dt).spl.po) { + sp = (obj->dt).spl.po; i = (obj->dt).spl.np; + while(i--) { + fprintf(fipo, "%g %g %g\n", sp->x, sp->y, sp->s); + sp++; + } + } else { + fprintf(fipo, "ERROR: NO POINTS!\n"); + } + } break; + case DK3_FIG_OBJ_TEXT: { + fprintf(fipo, "Position x: %g\n", (obj->dt).txt.x); + fprintf(fipo, "Position y: %g\n", (obj->dt).txt.y); + fprintf(fipo, "Angle: %g\n", (obj->dt).txt.an); + fprintf(fipo, "Text: \"%s\"\n", TR_8STR((obj->dt).txt.st)); + fprintf(fipo, "Font flags: %d\n", (obj->dt).txt.ff); + fprintf(fipo, "Font: %d\n", (obj->dt).txt.fo); + fprintf(fipo, "Font size: %g\n", (obj->dt).txt.fs); + } break; + case DK3_FIG_OBJ_ARC: { + fprintf(fipo, "Center x: %g\n", (obj->dt).arc.xc); + fprintf(fipo, "Center y: %g\n", (obj->dt).arc.yc); + fprintf(fipo, "Radius: %g\n", (obj->dt).arc.ra); + fprintf(fipo, "Start: %g\n", (180.0 * (obj->dt).arc.as / M_PI)); + fprintf(fipo, "End: %g\n", (180.0 * (obj->dt).arc.ae / M_PI)); + fprintf(fipo, "Direction: %d", (int)((obj->dt).arc.di)); + fprintf(fipo, "Point 1 x: %g\n", (obj->dt).arc.x1); + fprintf(fipo, "Point 1 y: %g\n", (obj->dt).arc.y1); + fprintf(fipo, "Point 2 x: %g\n", (obj->dt).arc.x2); + fprintf(fipo, "Point 2 y: %g\n", (obj->dt).arc.y2); + fprintf(fipo, "Point 3 x: %g\n", (obj->dt).arc.x3); + fprintf(fipo, "Point 3 y: %g\n", (obj->dt).arc.y3); + } break; + } + if(primobj) { + if(obj->af) { + fprintf(fipo, "ARROWHEAD FORWARD\n"); + dk3fig_prepare_report_ah(obj->af); + } + if(obj->ab) { + fprintf(fipo, "ARROWHEAD BACKWARD\n"); + dk3fig_prepare_report_ah(obj->ab); + } + } + } $? "- dk3fig_prepare_report_object" +} +#endif + + + +/** Check whether the object is an open path and filling is + required, change subtype to closed path if necessary. + @param drw Drawing containing the object. + @param obj Object to check. +*/ +static +void +dk3fig_prepare_check_fill_open_path(dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj) +{ + switch(obj->ot) { + case DK3_FIG_OBJ_POLYLINE: { + if((-1 != obj->fi) && (drw->transcol != obj->fc)) { + switch(obj->st) { + case 1: { + if(drw->cofop) { + obj->st = 3; + obj->cl = 1; + if((drw->app) && (drw->msg)) { + dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10); + } + } else { + if((drw->app) && (drw->msg)) { + dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9); + } + } + } break; + } + } + } break; + case DK3_FIG_OBJ_SPLINE: { + if((-1 != obj->fi) && (drw->transcol != obj->fc)) { + switch(obj->st) { + case 0: { + if(drw->cofop) { + obj->st = 1; + obj->cl = 1; + if((drw->app) && (drw->msg)) { + dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10); + } + } else { + if((drw->app) && (drw->msg)) { + dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9); + } + } + } break; + case 2: { + if(drw->cofop) { + obj->st = 3; + obj->cl = 1; + if((drw->app) && (drw->msg)) { + dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10); + } + } else { + if((drw->app) && (drw->msg)) { + dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9); + } + } + } break; + case 4: { + if(drw->cofop) { + obj->st = 5; + obj->cl = 1; + if((drw->app) && (drw->msg)) { + dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10); + } + } else { + if((drw->app) && (drw->msg)) { + dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9); + } + } + } break; + } + } + } break; + } +} + + + +/** Prepare one object. + @param drw Drawing. + @param obj Object to prepare. + @param objno Object number (starting at 0). + @return 1 on success, 0 on error. +*/ +static +int +dk3fig_prepare_object( + dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno +) +{ + int back = 1; + $? "+ dk3fig_prepare_object" + /* + For object 0 check whether it is a background rectangle. + Set srctype. + */ + dk3fig_prepare_check_bgrect(drw, obj, objno); + /* Check for open path to fill. + */ + dk3fig_prepare_check_fill_open_path(drw, obj); + /* + Object type specific initialization. + For arcs calculate center point and radius. + */ + if(!dk3fig_prepare_initialize_object(drw, obj, objno, 1)) { + back = 0; $? "! initialization failed" + } + /* + For open objects calculate arrowheads. + */ + if(back) { + if(!dk3figah_calculate_arrowheads(drw, obj, objno)) { + back = 0; + $? "! arrowhead calculation failed" + } + } + /* + Add object to bounding box. For open objects add + arrowheads to bounding box too. + */ + if(back) { $!trace-code dk3fig_prepare_report_object(obj, 1); + if(!dk3fig_prepare_add_to_bb(drw, obj, 1)) { + back = 0; $? "! add to bb failed" + dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 4); + } + } $? "- dk3fig_prepare_object %d", back + return back; +} + + + +int +dk3fig_prepare(dk3_fig_drawing_t *drw) +{ + dk3_fig_obj_t *obj; + unsigned long oldsourceline = 0UL; + unsigned long objno = 0UL; + int back = 1; + $? "+ dk3fig_prepare" + /* + Reset bounding box. + */ + dk3bb_reset(&(drw->bb)); + /* + Prepare all drawing elements. + */ + oldsourceline = dk3app_get_source_line(drw->app); + dk3sto_it_reset(drw->iobj); + while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) { + dk3app_set_source_line(drw->app, obj->li); + if(!dk3fig_prepare_object(drw, obj, objno++)) { + back = 0; + } + } + dk3app_set_source_line(drw->app, oldsourceline); + $? ". x = %lg ... %lg y = %lg ... %lg", (drw->bb).xmin, (drw->bb).xmax, (drw->bb).ymin, (drw->bb).ymax + $? "- dk3fig_prepare %d", back + return back; +} + + -- cgit v1.2.3