/* Copyright (C) 2017-2021, 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: dk4gra.ctr */ /** @file dk4gra.c The dk4gra module. */ #include "dk4conf.h" #if DK4_HAVE_FCNTL_H #ifndef FCNTL_H_INCLUDED #include #define FCNTL_H_INCLUDED 1 #endif #endif #if DK4_HAVE_IO_H #ifndef IO_H_INCLUDED #include #define IO_H_INCLUDED 1 #endif #endif #if DK4_HAVE_MATH_H #ifndef MATH_H_INCLUDED #if DK4_ON_WINDOWS #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES 1 #endif #endif #include #define MATH_H_INCLUDED 1 #endif #endif #if DK4_HAVE_FLOAT_H #ifndef FLOAT_H_INCLUDED #include #define FLOAT_H_INCLUDED 1 #endif #endif #if DK4_HAVE_ERRNO_H #ifndef ERRNO_H_INCLUDED #include #define ERRNO_H_INCLUDED 1 #endif #endif #ifndef DK4MATH_H_INCLUDED #include #endif #ifndef DK4UC2L_H_INCLUDED #include #endif #ifndef DK4GRA_H_INCLUDED #include #endif #ifndef DK4GRAT_H_INCLUDED #include #endif #ifndef GRA_H_INCLUDED #include #endif #ifndef DK4BIF_H_INCLUDED #include #endif #ifndef DK4FOPD_H_INCLUDED #include #endif #ifndef DK4FOPT_H_INCLUDED #include #endif #ifndef DK4ISADM_H_INCLUDED #include #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif static void dk4gra_i_save_attributes( dk4_gra_t *gra ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { dk4gra_eps_save_attributes(gra); } break; case DK4_GRA_DRIVER_PGF : { dk4gra_pgf_save_attributes(gra); } break; default : { dk4gra_pdf_save_attributes(gra); } break; } } static void dk4gra_i_restore_attributes( dk4_gra_t *gra ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { dk4gra_eps_restore_attributes(gra); } break; case DK4_GRA_DRIVER_PGF : { dk4gra_pgf_restore_attributes(gra); } break; default : { dk4gra_pdf_restore_attributes(gra); } break; } } static void dk4gra_i_reset_attributes( dk4_gra_t *gra ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { dk4gra_eps_reset_attributes(gra); } break; case DK4_GRA_DRIVER_PGF : { dk4gra_pgf_reset_attributes(gra); } break; default : { dk4gra_pdf_reset_attributes(gra); } break; } } static double dk4gra_i_to_range(double x, double min, double max) { if (min > x) { x = min; } if (max < x) { x = max; } return x; } void dk4gra_close( dk4_gra_t *gra ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { goto finished; } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { dk4gra_eps_close(gra); } break; case DK4_GRA_DRIVER_PGF : { dk4gra_pgf_close(gra); } break; default : { dk4gra_pdf_close(gra); } break; } finished: return; } dk4_gra_t * dk4gra_open_pdf( const dkChar *fn, size_t w, size_t h, int docfl, dk4_er_t *erp ) { dk4_gra_t *back = NULL; #if DK4_USE_ASSERT assert(NULL != fn); #endif if ((0 == w) || (0 == h)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = dk4gra_pdf_open(fn, w, h, docfl, erp); finished: return back; } dk4_gra_t * dk4gra_open_ps( const dkChar *fn, size_t w, size_t h, int docfl, dk4_er_t *erp ) { dk4_gra_t *back = NULL; #if DK4_USE_ASSERT assert(NULL != fn); #endif if ((0 == w) || (0 == h)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = dk4gra_eps_open(fn, w, h, docfl, erp); finished: return back; } dk4_gra_t * dk4gra_open_pgf( const dkChar *fn, size_t w, size_t h, int docfl, int sa, dk4_er_t *erp ) { dk4_gra_t *back = NULL; #if DK4_USE_ASSERT assert(NULL != fn); #endif if ((0 == w) || (0 == h)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = dk4gra_pgf_open(fn, w, h, docfl, sa, erp); finished: return back; } void dk4gra_set_color_conversion( dk4_gra_t *gra, dk4_cs_conv_ctx_t const *ctx, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if ((NULL != gra) && (NULL != ctx)) { DK4_MEMCPY(&(gra->cscctx),ctx,sizeof(dk4_cs_conv_ctx_t)); back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } if ((0 == back) && (NULL != backptr)) { *backptr = 0; } } void dk4gra_write_file_and_close( FILE *fout, dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != fout); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((NULL == gra->s_pages) || (NULL == gra->i_pages)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); dk4gra_close(gra); goto finished; } if ((0 == gra->pages) || (NULL == gra->curpg)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); dk4gra_close(gra); goto finished; } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_write_file_and_close(fout, gra, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_write_file_and_close(fout, gra, erp); } break; default : { back = dk4gra_pdf_write_file_and_close(fout, gra, erp); } break; } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_write_and_close( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { FILE *fout = NULL; /* Output file to write */ int tests = DK4_FOPEN_SC_USER; /* Tests for opening file */ int back = 0; #if DK4_ON_WINDOWS int oldm = _O_TEXT; /* Previous DOS stdout mode */ #endif #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((NULL == gra->s_pages) || (NULL == gra->i_pages)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); dk4gra_close(gra); goto finished; } if ((0 == gra->pages) || (NULL == gra->curpg)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); dk4gra_close(gra); goto finished; } /* Open and write output file if name specified, otherwise write to standard output. */ if (NULL != gra->fn) { if (0 != dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; } fout = dk4fopen(gra->fn, dkT("wb"), tests, erp); if (NULL != fout) { back = 1; dk4gra_write_file_and_close(fout, gra, &back, erp); if (0 != fclose(fout)) { dk4error_set_simple_error_code(erp, DK4_E_CLOSE_FAILED); back = 0; } } else { dk4gra_close(gra); } } else { back = 1; #if DK4_ON_WINDOWS oldm = _setmode(_fileno(stdout), _O_BINARY); #endif dk4gra_write_file_and_close(stdout, gra, &back, erp); #if DK4_ON_WINDOWS _setmode(_fileno(stdout), oldm); #endif } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_page_with_flags( dk4_gra_t *gra, int flags, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } gra->cur_x = 0.0; gra->cur_y = 0.0; if ((NULL == gra->s_pages) || (NULL == gra->i_pages)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_page(gra, flags, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_page(gra, flags, erp); } break; default : { back = dk4gra_pdf_page(gra, flags, erp); } break; } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_page( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif dk4gra_page_with_flags(gra, gra->docfl, backptr, erp); } void dk4gra_i_gsave( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_gsave(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_gsave(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_gsave(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_grestore( dk4_gra_t *gra, int res, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_grestore(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_grestore(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_grestore(gra, erp)) { if (NULL != backptr) { * backptr = 0; } } } break; } if ((0 != gra->gscp) && (0 != res)) { dk4gra_i_reset_attributes(gra); } } void dk4gra_i_prepare_fill( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_prepare_fill(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_prepare_fill(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_prepare_fill(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_prepare_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_prepare_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_prepare_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_prepare_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_prepare_fill_and_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); if (NULL != backptr) { *backptr = 0; } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_prepare_fill_and_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_prepare_fill_and_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_fill( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_fill(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_fill(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_fill(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_fill_and_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); if (NULL != backptr) {*backptr = 0; } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_fill_and_stroke(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_fill_and_stroke(gra, erp)) { if (NULL != backptr) {*backptr = 0; } } } break; } } void dk4gra_i_clip( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_clip(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_clip(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_clip(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_set_eorule( dk4_gra_t *gra, int val ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL != gra) { gra->eor = val; } } void dk4gra_i_newpath_moveto( dk4_gra_t *gra, double x, double y, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_newpath_moveto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_newpath_moveto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_newpath_moveto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_lineto( dk4_gra_t *gra, double x, double y, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_lineto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_lineto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_lineto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_curveto( dk4_gra_t *gra, double xc1, double yc1, double xc2, double yc2, double x, double y, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_curveto(gra,xc1,yc1,xc2,yc2,x,y,erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_curveto(gra,xc1,yc1,xc2,yc2,x,y,erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_curveto(gra,xc1,yc1,xc2,yc2,x,y,erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_closepath( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_closepath(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_closepath(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0 == dk4gra_pdf_closepath(gra, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } } void dk4gra_i_ellipse( dk4_gra_t *gra, double xc, double yc, double rx, double ry, double rot, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { dk4_gra_point_t points[DK4_GRA_CIRCLE_POINTS]; /* Points for circle */ size_t i; /* Index of current point */ size_t c1; /* Index of first control point after point */ size_t c2; /* Index of second control point after point */ size_t c3; /* Index of third control point after point */ #if DK4_USE_ASSERT assert(NULL != gra); #endif /* 2017-10-31 The TikZ and PGF manual explains that the pgfpathellipse command will apply coordinate transformations to all coordinates. So better calculate the curve ourselves. */ if ( 0 == dk4gratool_points_for_ellipse( points, DK4_GRA_CIRCLE_POINTS, xc, yc, rx, ry, rot, erp ) ) { if (NULL != backptr) { *backptr = 0; } goto finished; } /* Construct path as cycle of Bezier segments */ for (i = 0; i < ((DK4_GRA_CIRCLE_POINTS) / 3); i++) { if (0 == i) { dk4gra_i_newpath_moveto(gra,points[0].x,points[0].y,backptr,erp); } c1 = 3 * i + 1; c2 = 3 * i + 2; c3 = 3 * i + 3; if (DK4_GRA_CIRCLE_POINTS <= c3) { c3 = 0; } dk4gra_i_curveto( gra, points[c1].x, points[c1].y, points[c2].x, points[c2].y, points[c3].x, points[c3].y, backptr, erp ); } dk4gra_i_closepath(gra, backptr, erp); if (NULL != bbptr) { for (i = 0; i < ((DK4_GRA_CIRCLE_POINTS) / 3); i++) { c1 = 3 * i + 1; c2 = 3 * i + 2; c3 = 3 * i + 3; if (DK4_GRA_CIRCLE_POINTS <= c3) { c3 = 0; } dk4bb_add_bezier( bbptr, points[i].x, points[i].y, points[c1].x, points[c1].y, points[c2].x, points[c2].y, points[c3].x, points[c3].y ); } dk4bb_add_rotated_ellipse(bbptr, xc, yc, rx, ry, rot); } finished: return; } void dk4gra_i_circle( dk4_gra_t *gra, double xc, double yc, double r, int *backptr, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_circle(gra, xc, yc, r, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_circle(gra, xc, yc, r, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { dk4gra_i_ellipse(gra, xc, yc, r, r, 0.0, NULL, backptr, erp); } break; } } void dk4gra_i_rectangle( dk4_gra_t *gra, double xl, double xr, double yb, double yt, double r, int *backptr, dk4_er_t *erp ) { double dx; /* Width */ double dy; /* Height */ double xc1; /* Control point coordinates for rounded corners */ double yc1; double xc2; double yc2; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (0.0 < r) { dx = xr - xl; dy = yt - yb; dx = 0.4999 * fabs(dx); dy = 0.4999 * fabs(dy); if (r > dx) { r = dx; #if 0 /* Silently correct radius */ if (NULL != backptr) { *backptr = 0; } #endif } if (r > dy) { r = dy; #if 0 /* Silently correct radius */ if (NULL != backptr) { *backptr = 0; } #endif } } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_rectangle(gra, xl, xr, yb, yt, r, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_rectangle(gra, xl, xr, yb, yt, r, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { if (0.0 >= r) { dk4gra_i_newpath_moveto(gra, xl, yb, backptr, erp); dk4gra_i_lineto(gra, xr, yb, backptr, erp); dk4gra_i_lineto(gra, xr, yt, backptr, erp); dk4gra_i_lineto(gra, xl, yt, backptr, erp); dk4gra_i_closepath(gra, backptr, erp); } else { dk4gra_i_newpath_moveto(gra, (xl + r), yb, backptr, erp); dk4gra_i_lineto(gra, (xr - r), yb, backptr, erp); xc1 = xr - (1.0 - KAPPA_4) * r; yc1 = yb; xc2 = xr; yc2 = yb + (1.0 - KAPPA_4) * r; dk4gra_i_curveto(gra,xc1,yc1,xc2,yc2,xr,(yb+r),backptr,erp); dk4gra_i_lineto(gra, xr, (yt - r), backptr, erp); xc1 = xr; yc1 = yt - (1.0 - KAPPA_4) * r; xc2 = xr - (1.0 - KAPPA_4) * r; yc2 = yt; dk4gra_i_curveto(gra,xc1,yc1,xc2,yc2,(xr-r),yt,backptr,erp); dk4gra_i_lineto(gra, (xl+r), yt, backptr, erp); xc1 = xl + (1.0 - KAPPA_4) * r; yc1 = yt; xc2 = xl; yc2 = yt - (1.0 - KAPPA_4) * r; dk4gra_i_curveto(gra,xc1,yc1,xc2,yc2,xl,(yt-r),backptr,erp); dk4gra_i_lineto(gra, xl, (yb + r), backptr, erp); xc1 = xl; yc1 = yb + (1.0 - KAPPA_4) * r; xc2 = xl + (1.0 - KAPPA_4) * r; yc2 = yb; dk4gra_i_curveto(gra,xc1,yc1,xc2,yc2,(xl+r),yb,backptr,erp); dk4gra_i_closepath(gra, backptr, erp); } } break; } } void dk4gra_i_arc( dk4_gra_t *gra, double xc, double yc, double ra, double start, double end, int cl, int *backptr, dk4_er_t *erp ) { double angdiff; /* Angle difference end - start */ double x0; /* Start of current arc segment */ double y0; /* Start of current arc segment */ double dxdt0; /* First x derivative at start */ double dydt0; /* First y derivative at start */ double x1; /* End of current arg segment */ double y1; /* End of current arg segment */ double dxdt1; /* First x derivative at end */ double dydt1; /* First y derivative at end */ double segcalc; /* Number of segments */ double seglgt; /* Angle per segment */ double kappa; /* Kappa value */ double segend; /* Angle at end of segment */ size_t segments; /* Number of segments */ size_t i; /* Current segment to draw */ #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_arc(gra, xc, yc, ra, start, end, cl, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; /* 2017-10-31 The TikZ and PGF manual warns the computation done by the pgfpatharcto command are numerically very unstable and the arc will not necessary end at the intended end point. So we do not use that command and do the necessary calculations ourselves in the default branch. */ default : { start *= M_PI; end *= M_PI; start /= 180.0; end /= 180.0; angdiff = end - start; segcalc = angdiff * 4.0 / M_PI; segments = (size_t)ceil(segcalc); seglgt = angdiff / (double)segments; kappa = dk4gratool_kappa_for_angle(seglgt); x0 = xc + ra * cos(start); y0 = yc + ra * sin(start); dxdt0 = -1.0 * ra * seglgt * sin(start); dydt0 = ra * seglgt * cos(start); dk4gra_i_newpath_moveto(gra, x0, y0, backptr, erp); for (i = 0; i < segments; i++) { segend = start + angdiff * (double)(i + 1) / (double)segments; x1 = xc + ra * cos(segend); y1 = yc + ra * sin(segend); dxdt1 = -1.0 * ra * seglgt * sin(segend); dydt1 = ra * seglgt * cos(segend); dk4gra_i_curveto(gra, x0 + kappa * dxdt0, y0 + kappa * dydt0, x1 - kappa * dxdt1, y1 - kappa * dydt1, x1, y1, backptr, erp ); x0 = x1; y0 = y1; dxdt0 = dxdt1; dydt0 = dydt1; } if (0 != cl) { dk4gra_i_lineto(gra, xc, yc, backptr, erp); dk4gra_i_closepath(gra, backptr, erp); } } break; } } void dk4gra_gsave( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_gsave(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_grestore( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_grestore(gra, 1, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_gs_for_pattern_only( dk4_gra_t *gra, int val, dk4_er_t *erp ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL != gra) { gra->gscp = ((0 != val) ? (1) : (0)); } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } } void dk4gra_set_line_width( dk4_gra_t *gra, double lw, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_line_width(gra, lw, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_line_width(gra, lw, erp); } break; default : { back = dk4gra_pdf_set_line_width(gra, lw, erp); } break; } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_line_style( dk4_gra_t *gra, dk4_gra_ls_t ls, double sv, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_line_style(gra, ls, sv, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_line_style(gra, ls, sv, erp); } break; default : { back = dk4gra_pdf_set_line_style(gra, ls, sv, erp); } break; } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_line_cap( dk4_gra_t *gra, dk4_gra_lc_t lc, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_line_cap(gra, lc, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_line_cap(gra, lc, erp); } break; default : { back = dk4gra_pdf_set_line_cap(gra, lc, erp); } break; } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_line_join( dk4_gra_t *gra, dk4_gra_lj_t lj, double ml, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_line_join(gra, lj, ml, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_line_join(gra, lj, ml, erp); } break; default : { back = dk4gra_pdf_set_line_join(gra, lj, ml, erp); } break; } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_fill_gray( dk4_gra_t *gra, double g, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } g = dk4gra_i_to_range(g, 0.0, 1.0); switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_fill_gray(gra, g, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_fill_gray(gra, g, erp); } break; default : { back = dk4gra_pdf_set_fill_gray(gra, g, erp); } break; } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_fill_rgb( dk4_gra_t *gra, double r, double g, double b, int *backptr, dk4_er_t *erp ) { double array1[4]; double array2[4]; double array3[4]; size_t i; int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } r = dk4gra_i_to_range(r, 0.0, 1.0); g = dk4gra_i_to_range(g, 0.0, 1.0); b = dk4gra_i_to_range(b, 0.0, 1.0); if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { for (i = 0; i < 4 ; i++) { array1[i] = array2[i] = array3[i] = 0.0; } array1[0] = r; array1[1] = g; array1[2] = b; dk4cs_color_convert( array2, DK4_CS_GRAY, 4, array1, DK4_CS_RGB, 3, array3, 3, &(gra->cscctx), erp ); array2[0] = dk4gra_i_to_range(array2[0], 0.0, 1.0); switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_fill_gray(gra, array2[0], erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_fill_gray(gra, array2[0], erp); } break; default : { back = dk4gra_pdf_set_fill_gray(gra, array2[0], erp); } break; } } else { switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_fill_rgb(gra, r, g, b, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_fill_rgb(gra, r, g, b, erp); } break; default : { back = dk4gra_pdf_set_fill_rgb(gra, r, g, b, erp); } break; } } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_fill_cmyk( dk4_gra_t *gra, double c, double m, double y, double k, int *backptr, dk4_er_t *erp ) { double array1[4]; double array2[4]; double array3[4]; size_t i; int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } c = dk4gra_i_to_range(c, 0.0, 1.0); m = dk4gra_i_to_range(m, 0.0, 1.0); y = dk4gra_i_to_range(y, 0.0, 1.0); k = dk4gra_i_to_range(k, 0.0, 1.0); if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { for (i = 0; i < 4 ; i++) { array1[i] = array2[i] = array3[i] = 0.0; } array1[0] = c; array1[1] = m; array1[2] = y; array1[3] = k; dk4cs_color_convert( array2, DK4_CS_GRAY, 4, array1, DK4_CS_CMYK, 4, array3, 4, &(gra->cscctx), erp ); array2[0] = dk4gra_i_to_range(array2[0], 0.0, 1.0); switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_fill_gray(gra, array2[0], erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_fill_gray(gra, array2[0], erp); } break; default : { back = dk4gra_pdf_set_fill_gray(gra, array2[0], erp); } break; } } else { switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_fill_cmyk(gra, c, m, y, k, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_fill_cmyk(gra, c, m, y, k, erp); } break; default : { back = dk4gra_pdf_set_fill_cmyk(gra, c, m, y, k, erp); } break; } } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_stroke_gray( dk4_gra_t *gra, double g, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } g = dk4gra_i_to_range(g, 0.0, 1.0); switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_stroke_gray(gra, g, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_stroke_gray(gra, g, erp); } break; default : { back = dk4gra_pdf_set_stroke_gray(gra, g, erp); } break; } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_stroke_rgb( dk4_gra_t *gra, double r, double g, double b, int *backptr, dk4_er_t *erp ) { double array1[4]; double array2[4]; double array3[4]; size_t i; int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } r = dk4gra_i_to_range(r, 0.0, 1.0); g = dk4gra_i_to_range(g, 0.0, 1.0); b = dk4gra_i_to_range(b, 0.0, 1.0); if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { /* Force gray */ for (i = 0; i < 4 ; i++) { array1[i] = array2[i] = array3[i] = 0.0; } array1[0] = r; array1[1] = g; array1[2] = b; dk4cs_color_convert( array2, DK4_CS_GRAY, 4, array1, DK4_CS_RGB, 3, array3, 3, &(gra->cscctx), erp ); array2[0] = dk4gra_i_to_range(array2[0], 0.0, 1.0); switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_stroke_gray(gra, array2[0], erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_stroke_gray(gra, array2[0], erp); } break; default : { back = dk4gra_pdf_set_stroke_gray(gra, array2[0], erp); } break; } } else { /* RGB allowed */ switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_stroke_rgb(gra, r, g, b, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_stroke_rgb(gra, r, g, b, erp); } break; default : { back = dk4gra_pdf_set_stroke_rgb(gra, r, g, b, erp); } break; } } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_stroke_cmyk( dk4_gra_t *gra, double c, double m, double y, double k, int *backptr, dk4_er_t *erp ) { double array1[4]; double array2[4]; double array3[4]; size_t i; int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } c = dk4gra_i_to_range(c, 0.0, 1.0); m = dk4gra_i_to_range(m, 0.0, 1.0); y = dk4gra_i_to_range(y, 0.0, 1.0); k = dk4gra_i_to_range(k, 0.0, 1.0); if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { /* Force gray */ for (i = 0; i < 4 ; i++) { array1[i] = array2[i] = array3[i] = 0.0; } array1[0] = c; array1[1] = m; array1[2] = y; array1[3] = k; dk4cs_color_convert( array2, DK4_CS_GRAY, 4, array1, DK4_CS_CMYK, 3, array3, 3, &(gra->cscctx), erp ); array2[0] = dk4gra_i_to_range(array2[0], 0.0, 1.0); switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_stroke_gray(gra, array2[0], erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_stroke_gray(gra, array2[0], erp); } break; default : { back = dk4gra_pdf_set_stroke_gray(gra, array2[0], erp); } break; } } else { /* CMYK allowed */ switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_set_stroke_cmyk(gra, c, m, y, k, erp); } break; case DK4_GRA_DRIVER_PGF : { back = dk4gra_pgf_set_stroke_cmyk(gra, c, m, y, k, erp); } break; default : { back = dk4gra_pdf_set_stroke_cmyk(gra, c, m, y, k, erp); } break; } } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_prepare_fill( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_prepare_fill(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_prepare_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_prepare_stroke(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_prepare_fill_and_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_prepare_fill_and_stroke(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } int dk4gra_can_fill_and_stroke( const dk4_gra_t *gra ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = 0; } break; case DK4_GRA_DRIVER_PGF : { back = 1; } break; default : { back = 1; } break; } return back; } void dk4gra_fill( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_fill(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_stroke(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_fill_and_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_fill_and_stroke(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_clip( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_clip(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_newpath_moveto( dk4_gra_t *gra, double x, double y, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } gra->cur_x = x; gra->cur_y = y; if (NULL != bbptr) { dk4bb_add_x(bbptr, x); dk4bb_add_y(bbptr, y); } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_newpath_moveto(gra, x, y, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_lineto( dk4_gra_t *gra, double x, double y, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } gra->cur_x = x; gra->cur_y = y; if (NULL != bbptr) { dk4bb_add_x(bbptr, x); dk4bb_add_y(bbptr, y); } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_lineto(gra, x, y, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_curveto( dk4_gra_t *gra, double xc1, double yc1, double xc2, double yc2, double x, double y, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL != bbptr) { dk4bb_add_bezier( bbptr, gra->cur_x, gra->cur_y, xc1, yc1, xc2, yc2, x, y ); } gra->cur_x = x; gra->cur_y = y; if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_curveto(gra, xc1, yc1, xc2, yc2, x, y, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_closepath( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_closepath(gra, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_circle( dk4_gra_t *gra, double xc, double yc, double r, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if ((NULL == gra) || (0.0 >= r)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL != bbptr) { dk4bb_add_x(bbptr, xc - r); dk4bb_add_x(bbptr, xc + r); dk4bb_add_y(bbptr, yc - r); dk4bb_add_y(bbptr, yc + r); } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_circle(gra, xc, yc, r, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_rectangle( dk4_gra_t *gra, double xl, double xr, double yb, double yt, double r, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL != bbptr) { dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr); dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt); } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_rectangle(gra, xl, xr, yb, yt, r, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_arc( dk4_gra_t *gra, double xc, double yc, double ra, double start, double end, int cl, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if ((NULL == gra) || (0.0 >= ra)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL != bbptr) { dk4bb_add_x(bbptr, xc + ra * cos((M_PI * start)/ 180.0)); dk4bb_add_y(bbptr, yc + ra * sin((M_PI * start)/ 180.0)); dk4bb_add_x(bbptr, xc + ra * cos((M_PI * end)/ 180.0)); dk4bb_add_y(bbptr, yc + ra * sin((M_PI * end)/ 180.0)); } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_arc(gra, xc, yc, ra, start, end, cl, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_ellipse( dk4_gra_t *gra, double xc, double yc, double rx, double ry, double rot, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif rot *= M_PI; rot /= 180.0; if ((NULL == gra) || (0.0 >= rx) || (0.0 >= ry)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } back = 1; dk4gra_i_ellipse(gra, xc, yc, rx, ry, rot, bbptr, &back, erp); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_pattern( dk4_gra_t *gra, double xl, double xr, double yb, double yt, dk4_gra_pattern_t pn, int *backptr, dk4_er_t *erp ) { double val[16]; /* Values passed to EPS pattern functions */ double y01; /* Temporary value */ double y02; /* Temporary value */ dk4_gra_lc_t lc; /* Line cap used while drawing the pattern */ dk4_gra_lj_t lj; /* Line join used while drawing the pattern */ dk4_gra_ls_t ls; /* Line style used while drawing the pattern */ int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == gra->curpg) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } /* Extend pattern area for line width */ #if VERSION_BEFORE_20181212 xl -= 0.9; xr += 0.9; yb -= 0.9; yt += 0.9; #else xl -= gra->patlw; xr += gra->patlw; yb -= gra->patlw; yt += gra->patlw; #endif /* Calculate arguments for EPS pattern functions */ val[0] = xl; val[1] = xr; val[2] = yb; val[3] = yt; val[4] = 3.6; switch (pn) { case DK4_GRA_PATTERN_30_DEGREE_RIGHT : { /* ys = yb - (xe - xs) / sqrt(3) */ val[2] -= ((val[1] - val[0]) / sqrt(3.0)); val[4] = 7.2 / sqrt(3.0); y01 = val[2] - val[0] / sqrt(3.0); y02 = y01 / val[4]; y02 = floor(y02); y02 = y02 * val[4]; val[2] -= (y01 - y02); } break; case DK4_GRA_PATTERN_30_DEGREE_SIEVE : { /* ys = yb - (xe - xs) / sqrt(3) */ val[2] -= ((val[1] - val[0]) / sqrt(3.0)); val[4] = 7.2 / sqrt(3.0); y01 = val[2] + val[1] / sqrt(3.0); y02 = y01 / val[4]; y02 = floor(y02); y02 = y02 * val[4]; val[2] -= (y01 - y02); y01 = val[0] - val[2] * sqrt(3.0); y02 = y01 / 7.2; y02 = floor(y02); y02 = y02 * 7.2; val[0] -= (y01 - y02); val[2] -= val[4]; } break; case DK4_GRA_PATTERN_45_DEGREE_LEFT : { val[2] -= (val[1] - val[0]); val[4] = 3.6 * M_SQRT2; y01 = val[2] + val[1]; y02 = y01 / val[4]; y02 = floor(y02); y02 *= val[4]; val[2] -= (y01 - y02); } break; case DK4_GRA_PATTERN_45_DEGREE_RIGHT : { val[2] -= (val[1] - val[0]); val[4] = 3.6 * M_SQRT2; y01 = val[2] - val[0]; y02 = y01 / val[4]; y02 = floor(y02); y02 *= val[4]; val[2] -= (y01 - y02); } break; case DK4_GRA_PATTERN_45_DEGREE_SIEVE : { val[2] -= (val[1] - val[0]); val[4] = 3.6 * M_SQRT2; y01 = val[2] + val[1]; y02 = y01 / val[4]; y02 = floor(y02); y02 *= val[4]; val[2] -= (y01 - y02); y01 = val[0] - val[2]; y02 = y01 / val[4]; y02 = floor(y02); y02 *= val[4]; val[0] -= (y01 - y02); val[2] -= val[4]; } break; case DK4_GRA_PATTERN_HORIZONTAL_BRICKS : { y01 = val[2] / 7.2; y01 = floor(y01); val[2] = y01 * 7.2; y01 = val[0] / 14.4; y01 = floor(y01); val[0] = y01 * 14.4; val[4] = 7.2; } break; case DK4_GRA_PATTERN_VERTICAL_BRICKS : { y01 = val[2] / 14.4; y01 = floor(y01); val[2] = y01 * 14.4; y01 = val[0] / 7.2; y01 = floor(y01); val[0] = y01 * 7.2; val[4] = 7.2; } break; case DK4_GRA_PATTERN_HORIZONTAL_LINES : { y01 = val[2] / 3.6; y01 = floor(y01); val[2] = y01 * 3.6; } break; case DK4_GRA_PATTERN_VERTICAL_LINES : { y01 = val[0] / 3.6; y01 = floor(y01); val[0] = y01 * 3.6; } break; case DK4_GRA_PATTERN_HORIZONTAL_VERTICAL_SIEVE : { y01 = val[2] / 3.6; y01 = floor(y01); val[2] = y01 * 3.6; y01 = val[0] / 3.6; y01 = floor(y01); val[0] = y01 * 3.6; } break; case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_LEFT : { y01 = val[2] / 28.8; y01 = floor(y01); val[2] = y01 * 28.8; y01 = val[0] / 14.4; y01 = floor(y01); val[0] = y01 * 14.4; val[4] = 7.2; } break; case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_RIGHT : { y01 = val[2] / 28.8; y01 = floor(y01); val[2] = y01 * 28.8; y01 = val[0] / 14.4; y01 = floor(y01); val[0] = y01 * 14.4; val[4] = 7.2; } break; case DK4_GRA_PATTERN_VERTICAL_SHINGLES_1 : { y01 = val[2] / 14.4; y01 = floor(y01); val[2] = y01 * 14.4; y01 = val[0] / 28.8; y01 = floor(y01); val[0] = y01 * 28.8; val[4] = 7.2; } break; case DK4_GRA_PATTERN_VERTICAL_SHINGLES_2 : { y01 = val[2] / 14.4; y01 = floor(y01); val[2] = y01 * 14.4; y01 = val[0] / 28.8; y01 = floor(y01); val[0] = y01 * 28.8; val[4] = 7.2; } break; case DK4_GRA_PATTERN_LARGE_FISH_SCALES : { /* xs xe ys ye dx dy r a1 a2 */ val[4] = 14.54; val[5] = 3.7; val[6] = 9.0; val[7] = 216.1; val[8] = 323.9; y01 = val[0] / val[4]; y01 = floor(y01); val[0] = y01 * val[4]; y01 = val[2] / (2 * val[5]); y01 = floor(y01); val[2] = 2.0 * y01 * val[5]; } break; case DK4_GRA_PATTERN_SMALL_FISH_SCALES : { /* xs xe ys ye dx dy r a1 a2 */ val[4] = 7.2; val[5] = 3.6; val[6] = 3.6; val[7] = 180.0; val[8] = 360.0; y01 = val[0] / val[4]; y01 = floor(y01); val[0] = y01 * val[4]; y01 = val[2] / (2 * val[5]); y01 = floor(y01); val[2] = 2.0 * y01 * val[5]; } break; case DK4_GRA_PATTERN_CIRCLES : { val[4] = 7.2; y01 = val[0] / 14.4; y01 = floor(y01); val[0] = 14.4 * y01; y01 = val[2] / 14.4; y01 = floor(y01); val[2] = 14.4 * y01; } break; case DK4_GRA_PATTERN_HEXAGONS : { /* xs xe ys ye dx dy */ val[4] = 21.6; val[5] = 12.47; y01 = val[0] / 21.6; y01 = floor(y01); val[0] = y01 * 21.6; y01 = val[2] / 12.47; y01 = floor(y01); val[2] = y01 * 12.47; } break; case DK4_GRA_PATTERN_OCTAGONS : { /* xs xe ys ye dx co */ /* 2020-08-10 Bugfix Pattern size too small, increased now. */ val[4] = 14.4; /* previously 7.2; */ val[5] = 4.22; /* previously 2.11; */ y01 = val[0] / val[4]; y01 = floor(y01); val[0] = y01 * val[4]; y01 = val[2] / val[4]; y01 = floor(y01); val[2] = y01 * val[4]; } break; case DK4_GRA_PATTERN_HORIZONTAL_TIRES : { val[4] = 7.2; y01 = val[0] / val[4]; y01 = floor(y01); val[0] = y01 * val[4]; y01 = val[2] / val[4]; y01 = floor(y01); val[2] = y01 * val[4]; } break; case DK4_GRA_PATTERN_VERTICAL_TIRES : { val[4] = 7.2; y01 = val[0] / val[4]; y01 = floor(y01); val[0] = y01 * val[4]; y01 = val[2] / val[4]; y01 = floor(y01); val[2] = y01 * val[4]; } break; /* DK4_GRA_PATTERN_30_DEGREE_LEFT */ default : { /* ys = yb - (xe - xs) / sqrt(3) */ val[2] -= ((val[1] - val[0]) / sqrt(3.0)); val[4] = 7.2 / sqrt(3.0); y01 = val[2] + val[1] / sqrt(3.0); y02 = y01 / val[4]; y02 = floor(y02); y02 = y02 * val[4]; val[2] -= (y01 - y02); } break; } back = 1; /* Save attributes and graphics state */ dk4gra_i_save_attributes(gra); dk4gra_i_gsave(gra, &back, erp); /* Set attributes for stroking */ dk4gra_set_line_width(gra, gra->patlw, &back, erp); lc = DK4_GRA_LC_ROUNDED; dk4gra_set_line_cap(gra, lc, &back, erp); lj = DK4_GRA_LJ_MITERED; switch (pn) { case DK4_GRA_PATTERN_LARGE_FISH_SCALES: case DK4_GRA_PATTERN_SMALL_FISH_SCALES: { lj = DK4_GRA_LJ_ROUNDED; } break; default : { /* Intentionally empty to avoid compiler warnings. */ } break; } dk4gra_set_line_join(gra, lj, 10.0, &back, erp); ls = DK4_GRA_LS_SOLID; dk4gra_set_line_style(gra, ls, 3.6, &back, erp); dk4gra_prepare_stroke(gra, &back, erp); /* Driver specific pattern functions */ switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { if (0 == dk4gra_eps_pattern(gra, pn, val, erp)) { back = 0; } } break; default : { dk4gra_i_pattern(gra, xl, xr, yb, yt, pn, val, &back, erp); } break; } /* Restore graphics state and attributes */ dk4gra_i_grestore(gra, 0, &back, erp); dk4gra_i_restore_attributes(gra); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_bif_cotra_image( dk4_gra_t *gra, double *cotra, dk4_bif_t *bif, const dkChar *fn, size_t fno, int ifl, int *backptr, dk4_er_t *erp ) { int cs; /* Color space */ int back = 0; dk4_px_bit_depth_t bpc; /* Number of bits per component */ #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != bif); assert(NULL != cotra); #endif /* Check arguments */ if ((NULL == gra) || (NULL == cotra) || (NULL == bif)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } /* When enforcing grayscaled output, do not write colored image */ if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { ifl &= (~(DK4_GRA_IMG_FLAG_COLOR)); } /* Direct re-use of DCT encoded data requires a file name */ if (NULL == fn) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); } /* Direct re-use of DCT encoded data requires given bits per component */ bpc = dk4bif_get_original_bit_depth(bif); if (8 != bpc) { if (4 != bpc) { if (2 != bpc) { if (1 != bpc) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); } } } } /* Direct re-use of DCT encoded data restricts color spaces */ cs = dk4bif_get_color_space(bif); if (DK4_CS_GRAY != cs) { if (DK4_CS_RGB != cs) { if (DK4_CS_CMYK != cs) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); } } } /* Direct re-use of DCT encoded data impossible for colored images when enforcing grayscaled output */ if ((DK4_CS_GRAY != cs) && (0 == (DK4_GRA_IMG_FLAG_COLOR & ifl))) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); } switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { back = dk4gra_eps_bif_fig_image( gra, cotra, bif, fn, ifl, erp ); } break; case DK4_GRA_DRIVER_PGF : { if (NULL != fn) { back = dk4gra_pgf_bif_fig_image( gra, cotra, bif, fn, ifl, erp ); } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } } break; default : { /* PDF */ back = dk4gra_pdf_bif_fig_image( gra, cotra, bif, fn, fno, ifl, erp ); } break; } finished: if ((0 == back) && (NULL != backptr)) { *backptr = 0; } } void dk4gra_bif_fig_image( dk4_gra_t *gra, double xl, double xr, double yb, double yt, dk4_bif_t *bif, const dkChar *fn, size_t fno, int pos, int ifl, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { double val[8]; /* Values passed to low level functions */ double w; /* Image width */ double h; /* Image height */ double xres; /* X resolution */ double yres; /* Y resolution */ int res; /* Operation result */ int cs; /* Color space */ int back = 0; dk4_px_bit_depth_t bpc; #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != bif); #endif /* 2018-03-19 Removed (NULL == fn) */ if ((NULL == gra) || (NULL == bif)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((xr <= xl) || (yt <= yb)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { ifl &= (~(DK4_GRA_IMG_FLAG_COLOR)); } if (NULL != bbptr) { dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr); dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt); } /* Select frame */ if (0 == dk4bif_set_current_frame(bif, fno)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } /* Retrieve image dimensions */ w = (double)dk4bif_get_width(bif); h = (double)dk4bif_get_height(bif); if (0 == (DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION & ifl)) { xres = dk4bif_get_xres(bif); yres = dk4bif_get_yres(bif); if ((isgreater(xres, 0.0)) && (isgreater(yres, 0.0))) { w = (72.0 * w) / xres; h = (72.0 * h) / yres; #if DK4_HAVE_ISFINITE if ((!(isfinite(w))) || (!(isfinite(h)))) { w = (double)dk4bif_get_width(bif); h = (double)dk4bif_get_height(bif); } #else #if DK4_HAVE__FINITE if ((!(_finite(w))) || (!(_finite(h)))) { w = (double)dk4bif_get_width(bif); h = (double)dk4bif_get_height(bif); } #endif #endif } } /* Calculate coordinate system transformations */ res = dk4gratool_calculate_transformations( val, xl, xr, yb, yt, w, h, ((0 == (DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO & ifl)) ? (1) : (0)), pos, erp ); if (0 == res) { goto finished; } /* Direct re-use of DCT encoded data from JPEG requires file name */ if (NULL == fn) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); } /* DCT encoding restricts usable number of bits per component */ bpc = dk4bif_get_original_bit_depth(bif); if (8 != bpc) { if (4 != bpc) { if (2 != bpc) { if (1 != bpc) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); } } } } /* DCT encoding restricts color spaces */ cs = dk4bif_get_color_space(bif); if (DK4_CS_GRAY != cs) { if (DK4_CS_RGB != cs) { if (DK4_CS_CMYK != cs) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); } } } /* Direct re-use of DCT encoded data from colored image not possible when enforcing grayscaled output */ if ((DK4_CS_GRAY != cs) && (0 == (DK4_GRA_IMG_FLAG_COLOR & ifl))) { ifl &= (~(DK4_GRA_IMG_FLAG_DCT)); } /* Can not specify frame number in PGF output, only frame 0 can be used */ if ((DK4_GRA_DRIVER_PGF == gra->dr) && (0 != fno)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } /* Call function to produce output with given coordinates transformation */ back = 1; dk4gra_bif_cotra_image( gra, val, bif, fn, fno, ifl, &back, erp ); finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_bif_image( dk4_gra_t *gra, double xl, double xr, double yb, double yt, dk4_bif_t *bif, const dkChar *fn, size_t fno, int ifl, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { double xres = 1.0; /* X resolution */ double yres = 1.0; /* Y resolution */ double w; /* Width */ double h; /* Height */ double xdiff; /* Available X space */ double ydiff; /* Available Y space */ int pos = 0; /* Image position */ int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != bif); #endif /* 2018-03-19 Removed (NULL == fn) */ if ((NULL == gra) || (NULL == bif)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((xr <= xl) || (yt <= yb)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL != bbptr) { dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr); dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt); } if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { ifl &= (~(DK4_GRA_IMG_FLAG_COLOR)); } if (0 == (DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO & ifl)) { if (0 != (DK4_GRA_IMG_FLAG_ALLOW_ROTATION & ifl)) { if (0 != dk4bif_set_current_frame(bif, fno)) { xdiff = fabs(xr - xl); ydiff = fabs(yt - yb); w = (double)dk4bif_get_width(bif); h = (double)dk4bif_get_height(bif); if (0 == (DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION & ifl)) { xres = dk4bif_get_xres(bif); yres = dk4bif_get_yres(bif); if ((isgreater(xres, 0.0)) && (isgreater(yres, 0.0))) { w = (72.0 * w) / xres; h = (72.0 * h) / yres; } } #if DK4_HAVE_ISFINITE if ((isfinite(w)) && (isfinite(h))) #else #if DK4_HAVE__FINITE if ((_finite(w)) && (_finite(h))) #else #endif #endif { if ((isgreater(w, h)) && (isless(xdiff, ydiff))) { pos = 1; } else { if ((isless(w, h)) && (isgreater(xdiff, ydiff))) { pos = 1; } } } #if (DK4_HAVE_ISFINITE) || (DK4_HAVE__FINITE) else { /* ERROR: Width and height calculation failed */ dk4error_set_simple_error_code(erp,DK4_E_MATH_OVERFLOW); } #endif } else { /* ERROR: Frame number does not exist! */ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } back = 1; dk4gra_bif_fig_image( gra, xl, xr, yb, yt, bif, fn, fno, pos, ifl, bbptr, &back, erp ); } else { back = 1; dk4gra_bif_fig_image( gra, xl, xr, yb, yt, bif, fn, fno, pos, ifl, bbptr, &back, erp ); } } else { back = 1; dk4gra_bif_fig_image( gra, xl, xr, yb, yt, bif, fn, fno, pos, ifl, bbptr, &back, erp ); } finished: if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_fig_image( dk4_gra_t *gra, double xl, double xr, double yb, double yt, const dkChar *fn, size_t fno, dk4_cs_conv_ctx_t *ctx, int pos, int ifl, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { dk4_bif_t *bifptr = NULL; /* Bitmap image file */ int ho = 0; /* Flag: Read header only */ int back = 0; #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != fn); #endif if ((NULL == gra) || (NULL == fn)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((xr <= xl) || (yt <= yb)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == ctx) { ctx = &(gra->cscctx); } if (NULL != bbptr) { dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr); dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt); } if (DK4_GRA_DRIVER_PGF == gra->dr) { ho = 1; } if ( (0 != (DK4_GRA_IMG_FLAG_DCT & ifl)) && (DK4_BIF_TYPE_JPEG == dk4bif_type_for_suffix(fn)) ) { if (0 != (DK4_GRA_IMG_FLAG_COLOR & ifl)) { ho = 1; } } bifptr = dk4bif_open(fn, ho, ctx, erp); if (NULL == bifptr) { goto finished; } back = 1; if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { ifl &= (~(DK4_GRA_IMG_FLAG_COLOR)); } dk4gra_bif_fig_image( gra, xl, xr, yb, yt, bifptr, fn, fno, pos, ifl, bbptr, &back, erp ); finished: if (NULL != bifptr) { dk4bif_close(bifptr); } if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_image( dk4_gra_t *gra, double xl, double xr, double yb, double yt, const dkChar *fn, size_t fno, dk4_cs_conv_ctx_t *ctx, int ifl, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ) { dk4_bif_t *bifptr = NULL; /* Bitmap image */ int back = 0; /* Function result */ int ho = 0; /* Flag: Read image header only */ #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != fn); #endif /* Check argument */ if ((NULL == gra) || (NULL == fn)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((xr <= xl) || (yt <= yb)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if (NULL == ctx) { ctx = &(gra->cscctx); } if (NULL != bbptr) { dk4bb_add_x(bbptr, xl); dk4bb_add_x(bbptr, xr); dk4bb_add_y(bbptr, yb); dk4bb_add_y(bbptr, yt); } /* Open bitmap file */ if (DK4_GRA_DRIVER_PGF == gra->dr) { ho = 1; } if ( (0 != (DK4_GRA_IMG_FLAG_DCT & ifl)) && (DK4_BIF_TYPE_JPEG == dk4bif_type_for_suffix(fn)) ) { if (0 != (DK4_GRA_IMG_FLAG_COLOR & ifl)) { ho = 1; } } bifptr = dk4bif_open(fn, ho, ctx, erp); if (NULL == bifptr) { goto finished; } /* Process bitmap file */ back = 1; if (0 != (DK4_GRA_DOC_FLAG_FORCE_GRAY & (gra->docfl))) { ifl &= (~(DK4_GRA_IMG_FLAG_COLOR)); } dk4gra_bif_image( gra, xl, xr, yb, yt, bifptr, fn, fno, ifl, bbptr, &back, erp ); /* Clean up and exit */ finished: if (NULL != bifptr) { dk4bif_close(bifptr); } if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_set_pattern_line_width( dk4_gra_t *gra, double plw ) { #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL != gra) { if (0.0 < plw) { gra->patlw = plw; } } } /* vim: set ai sw=4 ts=4 : */