%% options copyright owner = Dirk Krause copyright year = 2012-2014 license = bsd %% header #ifdef __cplusplus extern "C" { #endif /** Draw fill patterns for object. @param job Job structure. @param drw Drawing structure. @param obj Object to process. @param ec Pointer to mathematical error code variable. */ void f2lud_pattern( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, int *ec ); #ifdef __cplusplus } #endif %% module #include "dk3all.h" #include "dk3bezcu.h" #include "fig2lat.h" #include "f2lud.h" #include "f2lsvg.h" #include "f2lpgf.h" #include "f2lpdf.h" #include "f2leps.h" #include "dk3figto.h" #include "dkt-version.h" #include "f2ludpat.h" $!trace-include /** One falling line. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param y0 Y value at x=0. @param m Tangens alpha. @param ec Pointer to error code variable. */ static void f2ludpat_one_falling_line( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, double y0, double m, int *ec ) { double xs; /* Start point x. */ double ys; /* Start point y. */ double xe; /* End point x. */ double ye; /* End point y. */ int hs = 0; /* Flag: Have start point. */ int he = 0; /* Flag: Have end point. */ ys = dk3ma_d_sub_ok(y0, dk3ma_d_mul_ok(m, outbb->xmin, ec), ec); if(ys > outbb->ymin) { if(ys <= outbb->ymax) { xs = outbb->xmin; hs = 1; } else { ys = outbb->ymax; xs = dk3ma_d_div_ok(dk3ma_d_sub_ok(y0, outbb->ymax, ec), m, ec); if(xs < outbb->xmax) { hs = 1; } } ye = dk3ma_d_sub_ok(y0, dk3ma_d_mul_ok(m, outbb->xmax, ec), ec); xe = xs; if(ye < outbb->ymax) { if(ye < outbb->ymin) { ye = outbb->ymin; xe = dk3ma_d_div_ok(dk3ma_d_sub_ok(y0, outbb->ymin, ec), m, ec); if(xe > outbb->xmin) { he = 1; } } else { xe = outbb->xmax; he = 1; } } if((hs) && (he)) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, xs, ys); f2lud_lineto(job, drw, obj, xe, ye); f2lud_stroke(job, drw, obj); } } } /** One rising line. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param y0 Y value at x=0. @param m Tangens alpha. @param ec Pointer to error code variable. */ static void f2ludpat_one_rising_line( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, double y0, double m, int *ec ) { double xs; /* Start point x. */ double ys; /* Start point y. */ double xe; /* End point x. */ double ye; /* End point y. */ int hs = 0; /* Flag: Have start point. */ int he = 0; /* Flag: Have end point. */ ye = dk3ma_d_add_ok( y0, dk3ma_d_mul_ok(m, outbb->xmax, ec), ec ); ys = ye; if(ye > outbb->ymin) { if(ye <= outbb->ymax) { xe = outbb->xmax; he = 1; } else { ye = outbb->ymax; xe = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb->ymax, y0, ec), m, ec); if((xe > outbb->xmin) && (xe < outbb->xmax)) { he = 1; } } xs = xe; if(he) { ys = dk3ma_d_add_ok( y0, dk3ma_d_mul_ok(m, outbb->xmin, ec), ec ); if(ys < outbb->ymax) { if(ys >= outbb->ymin) { xs = outbb->xmin; hs = 1; } else { ys = outbb->ymin; xs = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb->ymin, y0, ec), m, ec); if((xs > outbb->xmin) && (xs < outbb->xmax)) { hs = 1; } } } } if((hs) && (he)) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, xs, ys); f2lud_lineto(job, drw, obj, xe, ye); f2lud_stroke(job, drw, obj); } } } /** Falling lines. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param dy Y step. @param m Tangens alpha. @param ec Pointer to error code variable. */ static void f2ludpat_falling_lines( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, double dy, double m, int *ec ) { double ys; /* Start y. */ double ye; /* End y. */ double y; /* Current y. */ ys = dk3ma_d_add_ok( outbb->ymin, dk3ma_d_mul_ok(m, outbb->xmin, ec), ec ); ye = dk3ma_d_add_ok( outbb->ymax, dk3ma_d_mul_ok(m, outbb->xmax, ec), ec ); ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); y = ys; while(y < ye) { f2ludpat_one_falling_line(job, drw, obj, outbb, y, m, ec); y = dk3ma_d_add_ok(y, dy, ec); } } /** Rising lines. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param dy Y step. @param m Tangens alpha. @param ec Pointer to error code variable. */ static void f2ludpat_rising_lines( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, double dy, double m, int *ec ) { double ys; /* Start y. */ double ye; /* End y. */ double y; /* Current y. */ ys = dk3ma_d_sub_ok( outbb->ymin, dk3ma_d_mul_ok(m, outbb->xmax, ec), ec ); ye = dk3ma_d_sub_ok( outbb->ymax, dk3ma_d_mul_ok(m, outbb->xmin, ec), ec ); ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); y = ys; while(y < ye) { f2ludpat_one_rising_line(job, drw, obj, outbb, y, m, ec); y = dk3ma_d_add_ok(y, dy, ec); } } /** 30 degree falling lines. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_30_falling_lines( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { f2ludpat_falling_lines( job, drw, obj, outbb, dk3ma_d_div_ok(3.6, cos(M_PI / 6.0), ec), (1.0 / sqrt(3.0)), ec ); } /** 30 degree rising lines. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_30_rising_lines( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { f2ludpat_rising_lines( job, drw, obj, outbb, dk3ma_d_div_ok(3.6, cos(M_PI / 6.0), ec), (1.0 / sqrt(3.0)), ec ); } /** 45 degree falling lines. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_45_falling_lines( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { f2ludpat_falling_lines(job, drw, obj, outbb, (7.2 * sqrt(2.0)), 1.0, ec); } /** 45 degree rising lines. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_45_rising_lines( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { f2ludpat_rising_lines(job, drw, obj, outbb, (7.2 * sqrt(2.0)), 1.0, ec); } /** Horizontal bricks. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_horizontal_bricks( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double x; /* Current x. */ double y; /* Current y. */ double ys; /* Start y. */ double xs; /* Start x. */ double dy; /* Y delta. */ double dx; /* X delta. */ int lineno; /* Flag: Odd (1) or even (0) line. */ dy = 7.2; dx = 14.4; ys = outbb->ymin; xs = outbb->xmin; lineno = 0; ys = dk3ma_d_mul_ok( (2.0 * dy), floor(dk3ma_d_div_ok(ys, (2.0 * dy), ec)), ec ); y = ys; while(y < outbb->ymax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, outbb->xmin, y); f2lud_lineto(job, drw, obj, outbb->xmax, y); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(xs, (((lineno) ? 0.75 : 0.25) * dx), ec); while(x < outbb->xmax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, y); f2lud_lineto(job, drw, obj, x, dk3ma_d_add_ok(y, dy, ec)); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } y = dk3ma_d_add_ok(y, dy, ec); lineno++; if(lineno > 1) { lineno = 0; } } } /** Vertical bricks. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_vertical_bricks( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double x; /* Current x value. */ double y; /* Current y value. */ double xs; /* Start x. */ double ys; /* Start y. */ double dx; /* Delta x. */ double dy; /* Delta y. */ int lineno; /* Flag: Odd (1) or even (0) line. */ lineno = 0; dy = 14.4; dx = 7.2; xs = outbb->xmin; xs = dk3ma_d_mul_ok( (2.0 * dx), floor(dk3ma_d_div_ok(xs, (2.0 * dx), ec)), ec ); ys = outbb->ymin; ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); x = xs; while(x < outbb->xmax) { x = dk3ma_d_add_ok(x, dx, ec); f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, outbb->ymin); f2lud_lineto(job, drw, obj, x, outbb->ymax); f2lud_stroke(job, drw, obj); y = dk3ma_d_add_ok(ys, (((lineno) ? 0.75 : 0.25) * dy), ec); while(y < outbb->ymax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, y); f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(x, dx, ec), y); f2lud_stroke(job, drw, obj); y = dk3ma_d_add_ok(y, dy, ec); } lineno++; if(lineno > 1) { lineno = 0; } } } /** Horizontal lines. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_horizontal_lines( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double y; /* Current y. */ double ys; /* Start y. */ double dy; /* Delta y per pass. */ dy = 3.6; ys = outbb->ymin; ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); y = ys; while(y < outbb->ymax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, outbb->xmin, y); f2lud_lineto(job, drw, obj, outbb->xmax, y); f2lud_stroke(job, drw, obj); y = dk3ma_d_add_ok(y, dy, ec); } } /** Vertical lines. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_vertical_lines( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double x; /* Current x. */ double xs; /* Start x. */ double dx; /* Delta x. */ dx = 3.6; xs = outbb->xmin; xs = dk3ma_d_mul_ok( dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec ); x = xs; while(x < outbb->xmax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, outbb->ymin); f2lud_lineto(job, drw, obj, x, outbb->ymax); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } } /** Horizontal tire treads. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_horizontal_tire_treads( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double x; /* Current x. */ double y; /* Current y. */ double dx; /* Delta x per step. */ double dy; /* Delta y per pass. */ double xs; /* Start x. */ double ys; /* Start y. */ dy = 7.2; dx = 3.6; xs = outbb->xmin; ys = outbb->ymin; xs = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(xs, dy, ec)), ec ); ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); y = ys; while(y < outbb->ymax) { x = xs; f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, y); f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, dx, ec) ); f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, dy, ec), y ); x = dk3ma_d_add_ok(x, dy, ec); while(x < outbb->xmax) { f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, dx, ec) ); f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, dy, ec), y ); x = dk3ma_d_add_ok(x, dy, ec); } f2lud_stroke(job, drw, obj); y = dk3ma_d_add_ok(y, dy, ec); } } /** Vertical tire treads. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_vertical_tire_treads( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double x; /* Current x. */ double y; /* Current y. */ double dx; /* Delta x per pass. */ double dy; /* Delta y per step. */ double xs; /* Start x. */ double ys; /* Start y. */ dx = 7.2; dy = 3.6; xs = outbb->xmin; ys = outbb->ymin; xs = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(xs, dy, ec)), ec ); ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); x = xs; while(x < outbb->xmax) { y = ys; f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, y); f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(x, dy, ec), dk3ma_d_add_ok(y, dy, ec) ); f2lud_lineto(job, drw, obj, x, dk3ma_d_add_ok(y, dx, ec) ); y = dk3ma_d_add_ok(y, dx, ec); while(y < outbb->ymax) { f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(x, dy, ec), dk3ma_d_add_ok(y, dy, ec) ); f2lud_lineto(job, drw, obj, x, dk3ma_d_add_ok(y, dx, ec) ); y = dk3ma_d_add_ok(y, dx, ec); } f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } } /** Circles. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_circles( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { dk3_fig_poly_point_t p[12]; /* Points for circle around origin. */ dk3_fig_poly_point_t q[12]; /* Points shifted to the specified center. */ double x; /* Current x. */ double y; /* Current y. */ double dx; /* Delta x. */ double dy; /* Delta y. */ double xs; /* Start x. */ double ys; /* Start y. */ double r; /* Circle radius. */ size_t i; /* Index to traverse p and q. */ r = 7.2; dx = dy = 2.0 * r; xs = outbb->xmin; ys = outbb->ymin; xs = dk3ma_d_mul_ok( dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec ); ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); p[ 0].x = dx; p[ 0].y = r; p[ 1].x = dx; p[ 1].y = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r; p[ 2].x = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r; p[ 2].y = dx; p[ 3].x = r; p[ 3].y = dx; p[ 4].x = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r; p[ 4].y = dx; p[ 5].x = 0.0; p[ 5].y = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r; p[ 6].x = 0.0; p[ 6].y = r; p[ 7].x = 0.0; p[ 7].y = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r; p[ 8].x = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r; p[ 8].y = 0.0; p[ 9].x = r; p[ 9].y = 0.0; p[10].x = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r; p[10].y = 0.0; p[11].x = dx; p[11].y = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r; y = ys; while(y < outbb->ymax) { x = xs; while(x < outbb->xmax) { dk3mem_cpy((void *)q, (void *)p, sizeof(p)); for(i = 0; i < 12; i++) { dk3fig_tool_shift_point(&(q[i]), x, y, ec); } f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, q[0].x, q[0].y); f2lud_curveto( job, drw, obj, q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y ); f2lud_curveto( job, drw, obj, q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y ); f2lud_curveto( job, drw, obj, q[7].x, q[7].y, q[8].x, q[8].y, q[9].x, q[9].y ); f2lud_curveto( job, drw, obj, q[10].x, q[10].y, q[11].x, q[11].y, q[0].x, q[0].y ); f2lud_closepath(job, drw, obj); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } y = dk3ma_d_add_ok(y, dy, ec); } } /** Hexagons. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_hexagons( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { dk3_fig_poly_point_t p[6]; /* Hexagon near origin. */ dk3_fig_poly_point_t q[6]; /* Hexagon shifted to current x, y. */ double r; /* Radius. */ double y1; /* Y position of help line. */ double x1; /* X position of help line. */ double dy; /* Delta y. */ double dx; /* Delta x. */ double xs; /* Start x. */ double ys; /* Start y. */ double x; /* Current x. */ double y; /* Current y. */ size_t i; /* Index to traverse p and q. */ r = 16.2 / (2.0 * sin(M_PI / 3.0)); y1 = r * sin(M_PI / 3.0); x1 = r * (1.0 - cos(M_PI / 3.0)); dx = 2.0 * (r + x1); dy = 2.0 * y1; xs = outbb->xmin; ys = outbb->ymin; xs = dk3ma_d_mul_ok( dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec ); ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); p[0].x = 0.0; p[0].y = y1; p[1].x = x1; p[1].y = 0.0; p[2].x = x1 + r; p[2].y = 0.0; p[3].x = 2.0 * r; p[3].y = y1; p[4].x = p[2].x; p[4].y = 2.0 * y1; p[5].x = p[1].x; p[5].y = p[4].y; y = ys; while(y < outbb->ymax) { x = xs; while(x < outbb->xmax) { dk3mem_cpy((void *)q, (void *)p, sizeof(p)); for(i = 0; i < 6; i++) { dk3fig_tool_shift_point(&(q[i]), x, y, ec); } f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, q[0].x, q[0].y); f2lud_lineto(job, drw, obj, q[1].x, q[1].y); f2lud_lineto(job, drw, obj, q[2].x, q[2].y); f2lud_lineto(job, drw, obj, q[3].x, q[3].y); f2lud_lineto(job, drw, obj, q[4].x, q[4].y); f2lud_lineto(job, drw, obj, q[5].x, q[5].y); f2lud_lineto(job, drw, obj, q[0].x, q[0].y); f2lud_closepath(job, drw, obj); f2lud_stroke(job, drw, obj); f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, q[3].x, q[3].y); f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(q[3].x, r, ec), q[3].y); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } y = dk3ma_d_add_ok(y, dy, ec); } } /** Octagons. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_octagons( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { dk3_fig_poly_point_t p[8]; /* Octagon near origin. */ dk3_fig_poly_point_t q[8]; /* Octagon shifted to final position. */ double dx; /* Delta x. */ double dy; /* Delta y. */ double xs; /* Start x. */ double ys; /* Start y. */ double x; /* Current x. */ double y; /* Current y. */ double l; /* Factor for corner length. */ double x1; /* X position of help line 1. */ double x2; /* X position of help line 2. */ size_t i; /* Index to traverse p and q. */ dx = dy = 4.0 * 3.6; xs = outbb->xmin; ys = outbb->ymin; xs = dk3ma_d_mul_ok( dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec ); ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); $? ". dx = %lg", dx l = dx / (1.0 + sqrt(2.0)); $? ". l = %lg", l x1 = (dx - l) / 2.0; $? ". x1 = %lg", x1 x2 = x1 + l; $? ". x2 = %lg", x2 p[0].x = x1; $? ". 0x = %lg", p[0].x p[0].y = 0.0; $? ". 0y = %lg", p[0].y p[1].x = x2; $? ". 1x = %lg", p[1].x p[1].y = 0.0; $? ". 1y = %lg", p[1].y p[2].x = dx; $? ". 2x = %lg", p[2].x p[2].y = x1; $? ". 2y = %lg", p[2].y p[3].x = dx; $? ". 3x = %lg", p[3].x p[3].y = x2; $? ". 3y = %lg", p[3].y p[4].x = x2; $? ". 4x = %lg", p[4].x p[4].y = dy; $? ". 4y = %lg", p[4].y p[5].x = x1; $? ". 5x = %lg", p[5].x p[5].y = dy; $? ". 5y = %lg", p[5].y p[6].x = 0.0; $? ". 6x = %lg", p[6].x p[6].y = x2; $? ". 6y = %lg", p[6].y p[7].x = 0.0; $? ". 7x = %lg", p[7].x p[7].y = x1; $? ". 7y = %lg", p[7].y y = ys; while(y < outbb->ymax) { x = xs; while(x < outbb->xmax) { dk3mem_cpy((void *)q, (void *)p, sizeof(p)); for(i = 0; i < 8; i++) { dk3fig_tool_shift_point(&(q[i]), x, y, ec); } f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, q[0].x, q[0].y); f2lud_lineto(job, drw, obj, q[1].x, q[1].y); f2lud_lineto(job, drw, obj, q[2].x, q[2].y); f2lud_lineto(job, drw, obj, q[3].x, q[3].y); f2lud_lineto(job, drw, obj, q[4].x, q[4].y); f2lud_lineto(job, drw, obj, q[5].x, q[5].y); f2lud_lineto(job, drw, obj, q[6].x, q[6].y); f2lud_lineto(job, drw, obj, q[7].x, q[7].y); f2lud_lineto(job, drw, obj, q[0].x, q[0].y); f2lud_closepath(job, drw, obj); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } y = dk3ma_d_add_ok(y, dy, ec); } } /** Fish scale. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. @param points Curve control points near origin. @param dx X delta. @param dy Y delta. */ static void f2ludpat_fish_scale( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec, dk3_fig_poly_point_t *points, double dx, double dy ) { dk3_fig_poly_point_t q[7]; /* Points shifted to final position. */ double xs; /* Start x. */ double ys; /* Start y. */ double y1; /* Y position of help line. */ double x; /* Current x. */ double y; /* Current y. */ size_t i; /* Index to traverse npoints and q. */ xs = outbb->xmin; ys = outbb->ymin; xs = dk3ma_d_mul_ok( dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec ); ys = dk3ma_d_mul_ok( dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec ); y = ys; while(y < outbb->ymax) { x = xs; while(x < outbb->xmax) { dk3mem_cpy((void *)q, (void *)points, sizeof(q)); for(i = 0; i < 7; i++) { dk3fig_tool_shift_point(&(q[i]), x, y, ec); } f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, q[0].x, q[0].y); f2lud_curveto( job, drw, obj, q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y ); f2lud_curveto( job, drw, obj, q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y ); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } y1 = dk3ma_d_add_ok(y, 0.5 * dy, ec); x = dk3ma_d_sub_ok(xs, 0.5 * dx, ec); while(x < outbb->xmax) { dk3mem_cpy((void *)q, (void *)points, sizeof(q)); for(i = 0; i < 7; i++) { dk3fig_tool_shift_point(&(q[i]), x, y1, ec); } f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, q[0].x, q[0].y); f2lud_curveto( job, drw, obj, q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y ); f2lud_curveto( job, drw, obj, q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y ); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } y = dk3ma_d_add_ok(y, dy, ec); } } /** Large fish scale. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_large_fish_scale( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { dk3_fig_poly_point_t p[7]; /* Curve points of segment near origin. */ double alpha; /* Opening angle. */ double kappa; /* Factor to construct Bezier control points. */ double pat; /* Normal pattern distance. */ double dx; /* Delta x. */ double dy; /* Delta y. */ double r; /* Fishscale radius. */ double as; /* Start angle. */ pat = 3.6; dx = 4.0 * pat; dy = 2.0 * pat; alpha = 0.9272952; /* from iteration in Scilab */ kappa = dk3fig_tool_arc_kappa(alpha, ec); r = dk3ma_d_div_ok(pat, (1.0 - cos(alpha)), ec); as = 1.5 * M_PI - alpha; p[0].x = 0.0; p[0].y = pat; p[1].x = -1.0 * dk3ma_d_mul_ok(r, alpha, ec) * sin(as); p[1].y = dk3ma_d_mul_ok(r, alpha, ec) * cos(as); p[1].x = dk3ma_d_mul_ok(kappa, p[1].x, ec); p[1].y = dk3ma_d_mul_ok(kappa, p[1].y, ec); p[1].y = dk3ma_d_add_ok(p[1].y, p[0].y, ec); p[2].x = dk3ma_d_mul_ok(r, alpha, ec); p[2].x = dk3ma_d_mul_ok(p[2].x, kappa, ec); p[2].x = dk3ma_d_sub_ok(2.0 * pat, p[2].x, ec); p[2].y = 0.0; p[3].x = 2.0 * pat; p[3].y = 0.0; p[4].x = dk3ma_d_sub_ok(dx, p[2].x, ec); p[4].y = 0.0; p[5].x = dk3ma_d_sub_ok(dx, p[1].x, ec); p[5].y = p[1].y; p[6].x = dx; p[6].y = pat; f2ludpat_fish_scale(job, drw, obj, outbb, ec, p, dx, dy); } /** Small fish scale. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_small_fish_scale( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { dk3_fig_poly_point_t p[7]; /* Curve points of segment near origin. */ double pat; /* Normal pattern distance. */ double dx; /* Delta x. */ double dy; /* Delta y. */ pat = 3.6; p[0].x = 0.0; p[0].y = pat; p[1].x = 0.0; p[1].y = pat * (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER); p[2].x = p[1].y; p[2].y = 0.0; p[3].x = pat; p[3].y = 0.0; p[4].x = pat * (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER); p[4].y = 0.0; p[5].x = 2.0 * pat; p[5].y = p[1].y; p[6].x = p[5].x; p[6].y = pat; dx = 2.0 * pat; dy = 2.0 * pat; f2ludpat_fish_scale(job, drw, obj, outbb, ec, p, dx, dy); } /** Horizontal shingles right. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_horizontal_shingles_right( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double pat; /* Normal pattern distance. */ double x; /* Current x. */ double y; /* Current y. */ double xs; /* Start x. */ double dy; /* Start y. */ double dx; /* Delta x. */ int lineno; /* Flag: Odd (1) or even (0) line. */ pat = 3.6; dy = 2.0 * pat; dx = 3.0 * dy; xs = outbb->xmin; xs = dk3ma_d_mul_ok(dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec); y = outbb->ymin; y = dk3ma_d_mul_ok((3.0 * dy), floor(dk3ma_d_div_ok(y, (3.0 * dy), ec)), ec); lineno = 0; while(y < outbb->ymax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, outbb->xmin, y); f2lud_lineto(job, drw, obj, outbb->xmax, y); f2lud_stroke(job, drw, obj); x = xs; switch(lineno) { case 1: { x = dk3ma_d_add_ok(x, (2.0 * dy), ec); } break; case 2: { x = dk3ma_d_add_ok(x, dy, ec); } break; } while(x < outbb->xmax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, y); f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, pat, ec), dk3ma_d_add_ok(y, dy, ec) ); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } y = dk3ma_d_add_ok(y, dy, ec); lineno++; if(lineno >= 3) { lineno = 0; } } } /** Horizontal shingles left. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_horizontal_shingles_left( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double pat; /* Normal pattern distance. */ double x; /* Current x. */ double y; /* Current y. */ double xs; /* Start x. */ double dy; /* Delta y. */ double dx; /* Delta x. */ int lineno; /* Flag: Odd (1) or even (0) line. */ pat = 3.6; dy = 2.0 * pat; dx = 3.0 * dy; xs = outbb->xmin; xs = dk3ma_d_mul_ok(dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec); y = outbb->ymin; y = dk3ma_d_mul_ok((3.0 * dy), floor(dk3ma_d_div_ok(y, (3.0 * dy), ec)), ec); lineno = 0; while(y < outbb->ymax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, outbb->xmin, y); f2lud_lineto(job, drw, obj, outbb->xmax, y); f2lud_stroke(job, drw, obj); x = xs; switch(lineno) { case 2: { x = dk3ma_d_add_ok(x, (2.0 * dy), ec); } break; case 1: { x = dk3ma_d_add_ok(x, dy, ec); } break; } while(x < outbb->xmax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, dk3ma_d_add_ok(y, dy, ec)); f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, pat, ec), y); f2lud_stroke(job, drw, obj); x = dk3ma_d_add_ok(x, dx, ec); } y = dk3ma_d_add_ok(y, dy, ec); lineno++; if(lineno >= 3) { lineno = 0; } } } /** Vertical shingles falling. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_vertical_shingles_falling( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double x; /* Current x. */ double y; /* Current y. */ double pat; /* Normal pattern distance. */ double dx; /* Delta x. */ double dy; /* Delta y. */ double ys; /* Start y. */ int lineno; /* Flag: Odd (1) or even (0) line. */ pat = 3.6; dx = 2.0 * pat; dy = 3.0 * dx; ys = outbb->ymin; ys = dk3ma_d_mul_ok(dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec); x = outbb->xmin; x = dk3ma_d_mul_ok((3.0 * dx), floor(dk3ma_d_div_ok(x, (3.0 * dx), ec)), ec); lineno = 0; while(x < outbb->xmax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, outbb->ymin); f2lud_lineto(job, drw, obj, x, outbb->ymax); f2lud_stroke(job, drw, obj); y = ys; switch(lineno) { case 2: { y = dk3ma_d_add_ok(y, (2.0 * dx), ec); } break; case 1: { y = dk3ma_d_add_ok(y, dx, ec); } break; } while(y < outbb->ymax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, dk3ma_d_add_ok(y, pat, ec)); f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(x, dx, ec), y); f2lud_stroke(job, drw, obj); y = dk3ma_d_add_ok(y, dy, ec); } x = dk3ma_d_add_ok(x, dx, ec); lineno++; if(lineno >= 3) { lineno = 0; } } } /** Vertical shingles rising. @param job Job structure. @param drw Drawing structure. @param obj Object requiring the fill pattern. @param outbb Bounding box to fill with pattern. @param ec Pointer to error code variable. */ static void f2ludpat_vertical_shingles_rising( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_bb_t *outbb, int *ec ) { double x; /* Current x. */ double y; /* Current y. */ double pat; /* Normal pattern distance. */ double dx; /* Delta x. */ double dy; /* Delta y. */ double ys; /* Start y. */ int lineno; /* Flag: Odd (1) or even (0) line. */ pat = 3.6; dx = 2.0 * pat; dy = 3.0 * dx; ys = outbb->ymin; ys = dk3ma_d_mul_ok(dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec); x = outbb->xmin; x = dk3ma_d_mul_ok((3.0 * dx), floor(dk3ma_d_div_ok(x, (3.0 * dx), ec)), ec); lineno = 0; while(x < outbb->xmax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, outbb->ymin); f2lud_lineto(job, drw, obj, x, outbb->ymax); f2lud_stroke(job, drw, obj); y = ys; switch(lineno) { case 2: { y = dk3ma_d_add_ok(y, dx, ec); } break; case 1: { y = dk3ma_d_add_ok(y, 2.0 * dx, ec); } break; } while(y < outbb->ymax) { f2lud_newpath(job, drw, obj); f2lud_moveto(job, drw, obj, x, y); f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, pat, ec) ); f2lud_stroke(job, drw, obj); y = dk3ma_d_add_ok(y, dy, ec); } x = dk3ma_d_add_ok(x, dx, ec); lineno++; if(lineno >= 3) { lineno = 0; } } } void f2lud_pattern( f2l_job_t *job, dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, int *ec ) { dk3_bb_t mybb; /* Bounding box of object. */ dk3_bb_t outbb; /* Box to fill. */ double lw2; /* Half line width. */ dk3bb_reset(&mybb); dk3bb_reset(&outbb); if(dk3fig_prepare_obj_bb(&mybb, drw, obj, 1)) { dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), mybb.xmin, ec)); dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), mybb.xmax, ec)); dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), mybb.ymin, ec)); dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), mybb.ymax, ec)); #if VERSION_BEFORE_20140330 lw2 = 0.45; if(job->lighten) { lw2 = 0.5 * lw2; } #else lw2 = job->lwbp / 2.0; #endif outbb.xmin = dk3ma_d_sub_ok(outbb.xmin, lw2, ec); outbb.xmax = dk3ma_d_add_ok(outbb.xmax, lw2, ec); outbb.ymin = dk3ma_d_sub_ok(outbb.ymin, lw2, ec); outbb.ymax = dk3ma_d_add_ok(outbb.ymax, lw2, ec); switch(obj->fi) { case 41: { f2ludpat_30_falling_lines(job, drw, obj, &outbb, ec); } break; case 42: { f2ludpat_30_rising_lines(job, drw, obj, &outbb, ec); } break; case 43: { f2ludpat_30_falling_lines(job, drw, obj, &outbb, ec); f2ludpat_30_rising_lines(job, drw, obj, &outbb, ec); } break; case 44: { f2ludpat_45_falling_lines(job, drw, obj, &outbb, ec); } break; case 45: { f2ludpat_45_rising_lines(job, drw, obj, &outbb, ec); } break; case 46: { f2ludpat_45_falling_lines(job, drw, obj, &outbb, ec); f2ludpat_45_rising_lines(job, drw, obj, &outbb, ec); } break; case 47: { f2ludpat_horizontal_bricks(job, drw, obj, &outbb, ec); } break; case 48: { f2ludpat_vertical_bricks(job, drw, obj, &outbb, ec); } break; case 49: { f2ludpat_horizontal_lines(job, drw, obj, &outbb, ec); } break; case 50: { f2ludpat_vertical_lines(job, drw, obj, &outbb, ec); } break; case 51: { f2ludpat_horizontal_lines(job, drw, obj, &outbb, ec); f2ludpat_vertical_lines(job, drw, obj, &outbb, ec); } break; case 52: { f2ludpat_horizontal_shingles_right(job, drw, obj, &outbb, ec); } break; case 53: { f2ludpat_horizontal_shingles_left(job, drw, obj, &outbb, ec); } break; case 54: { f2ludpat_vertical_shingles_falling(job, drw, obj, &outbb, ec); } break; case 55: { f2ludpat_vertical_shingles_rising(job, drw, obj, &outbb, ec); } break; case 56: { f2ludpat_large_fish_scale(job, drw, obj, &outbb, ec); } break; case 57: { f2ludpat_small_fish_scale(job, drw, obj, &outbb, ec); } break; case 58: { f2ludpat_circles(job, drw, obj, &outbb, ec); } break; case 59: { f2ludpat_hexagons(job, drw, obj, &outbb, ec); } break; case 60: { f2ludpat_octagons(job, drw, obj, &outbb, ec); } break; case 61: { f2ludpat_horizontal_tire_treads(job, drw, obj, &outbb, ec); } break; case 62: { f2ludpat_vertical_tire_treads(job, drw, obj, &outbb, ec); } break; } } else { $? "! bb" } }