%% options copyright owner = Dirk Krause copyright year = 2017-xxxx SPDX-License-Identifier: BSD-3-Clause %% header /** @file dk4gra.h Graphics output (PS/EPS/PDF/PGF). This module contains functions to create PS/EPS/PDF/PGF graphics. Coordinates are specified in PS points, called bp in LaTeX. 72 PS points are one inch. The origin is in the lower left corner, x values grow to the right, y values grow to top. Colors specified as double values are in the range from 0.0 to 1.0. For each object to draw follow an algorithm like @code dk4_bb_t bb; dk4gra_set_line_width(...); dk4gra_set_line_style(...); dk4gra_set_line_cap(...); dk4gra_set_line_join(...); dk4gra_set_stroke_...(...); dk4gra_set_fill_...(...); if (want_a_pattern_filled_object) { dk4bb_init(&bb); dk4gra_prepare_fill(...); construct_path(...); dk4gra_fill(...); dk4gra_set_gs_for_pattern_only(gra, 1, ...); dk4gra_gsave(...); construct_path(..., &bb, ...); dk4gra_clip(...); dk4gra_pattern(..., bb.xmin, bb.xmax, bb.ymin, bb.ymax, ...); dk4gra_grestore(...); dk4gra_set_gs_for_pattern_only(gra, 0, ...); if (want_a_stroked_object) { dk4gra_prepare_stroke(...); construct_path(...); dk4gra_stroke(...); } } else { if (want_a_filled_object) { if (want_a_stroked_object) { if (0 != dk4gra_can_fill_and_stroke(...)) { dk4gra_prepare_fill_and_stroke(...); construct_path(...); dk4gra_fill_and_stroke(...); } else { dk4gra_prepare_fill(...); construct_path(...); dk4gra_fill(...); dk4gra_prepare_stroke(...); construct_path(...); dk4gra_stroke(...); } } else { dk4gra_prepare_fill(...); construct_path(...); dk4gra_fill(...); } } else { if (want_a_stroked_object) { dk4gra_prepare_stroke(...); construct_path(...); dk4gra_stroke(...); } } } @endcode The dk4gra_set_fill_...() and dk4gra_set_stroke_...() functions set color space and color values. You must use the same color space for both fill and stroke color. */ #ifndef DK4CONF_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4conf.h" #else #include #endif #endif #ifndef DK4MEM_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4mem.h" #else #include #endif #endif #ifndef DK4FONT_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4font.h" #else #include #endif #endif #ifndef DK4ALIGN_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4align.h" #else #include #endif #endif #ifndef DK4ERROR_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4error.h" #else #include #endif #endif #ifndef DK4BB_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4bb.h" #else #include #endif #endif #ifndef DK4BIFTY_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4bifty.h" #else #include #endif #endif #ifndef DK4CS_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4cs.h" #else #include #endif #endif #ifndef DK4MEMBF_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4membuf.h" #else #include #endif #endif #ifndef DK4MBSTRM_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4mbstrm.h" #else #include #endif #endif #ifndef DK4FONTC_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4fontc.h" #else #include #endif #endif #ifndef DK4UC2L_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4uc2l.h" #else #include #endif #endif /** Epsilon value for coordinates. All values smaller than this are treated as 0.0. */ #define DK4_GRA_EPSILON_COORDINATES 1.0e-5 /** Epsilon value for line widths. Line width differing less are treated as equal. */ #define DK4_GRA_EPSILON_LINEWIDTH 1.0e-3 /** Epsilon value for miter limits. Miter limits differing less are treated as equal. */ #define DK4_GRA_EPSILON_MITERLIMIT 1.0e-3 /** Flags for adding images to a page. */ enum { /** The image is the only page contents. For PS output the gsave operator, clipping and white filling at start of page are removed, the grestore at end of page too. */ DK4_GRA_IMG_FLAG_ONLY_PAGE_CONTENTS = 0x0001 , /** Fill image background with color from background chunk before applying image data. Only in effect when producing PDF output in DK4_CS_RGB_ALPHA or DK4_CS_GRAY_ALPHA color space. */ DK4_GRA_IMG_FLAG_FILL_BACKGROUND = 0x0002 , /** Allow colored output. Otherwise grayscaled output is enforced. */ DK4_GRA_IMG_FLAG_COLOR = 0x0004 , /** Allow LZW compression in PS language level 2 output. */ DK4_GRA_IMG_FLAG_LZW = 0x0008 , /** Allow to use DCT encoded data from JPEG files directly. */ DK4_GRA_IMG_FLAG_DCT = 0x0010 , /** Set image interpolation flag to allow PS/PDF renderers to optimize representation. */ DK4_GRA_IMG_FLAG_INTERPOLATION = 0x0020 , /** Set image interpolation flag when directly using DCT encoded data from JPEG files. */ DK4_GRA_IMG_FLAG_DCT_INTERPOLATION = 0x0040 , /** Analyze number of bits per component, reduce if possible without quality loss. */ DK4_GRA_IMG_FLAG_ANALYZE_BPC = 0x0080 , /** Analyze use of colors, switch to grayscale if possible without quality loss. */ DK4_GRA_IMG_FLAG_ANALYZE_COLOR = 0x0100 , /** Analyze use of alpha channel data, ignore alpha data if all pixels have full opacity. */ DK4_GRA_IMG_FLAG_ANALYZE_ALPHA = 0x0200 , /** Allow to rotate the image to fit paper size. */ DK4_GRA_IMG_FLAG_ALLOW_ROTATION = 0x0400 , /** Ignore image resolution saved in file. */ DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION = 0x0800 , /** Ignore aspect ratio, allow distorsion while filling the specified image range completely. */ DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO = 0x1000 , }; /** Text flags for use with dk4gra_pgf_simple_text(), dk4gra_pgf_special_text(), dk4gra_app_pgf_simple_text(), dk4gra_app_pgf_special_text(), dk4pppt_simple_text(), and dk4pppt_special_text(), can be or-combined. */ enum { /** Draw oval box around text. */ DK4_GRA_TEXT_FLAG_OVAL_BOX = 0x0001 , /** Put white box around text and oval box. */ DK4_GRA_TEXT_FLAG_WHITE_BOX = 0x0002 }; /** Output driver to choose. */ typedef enum { DK4_GRA_DRIVER_PDF = 0, /**< Produce PDF file. */ DK4_GRA_DRIVER_EPS , /**< Produce EPS file. */ DK4_GRA_DRIVER_PS , /**< Produce PS file. */ DK4_GRA_DRIVER_PGF , /**< Produce PGF file. */ DK4_GRA_DRIVER_BB /**< Produce bounding box file. */ } dk4_gra_driver_t; /** Intended purpose for output. */ typedef enum { DK4_GRA_PURPOSE_OBJECT = 0 , /**< Object to include in a document. */ DK4_GRA_PURPOSE_IMAGE , /**< Standalone image. */ DK4_GRA_PURPOSE_DOCUMENT /**< Document for viewing or printing. */ } dk4_gra_purpose_t; /** Line styles. */ typedef enum { DK4_GRA_LS_SOLID = 0 , /**< Solid line. */ DK4_GRA_LS_DASH , /**< Dashed line. */ DK4_GRA_LS_DOT , /**< Dotted line. */ DK4_GRA_LS_DASH_DOT , /**< Dash dot line. */ DK4_GRA_LS_DASH_DOT_DOT , /**< Dash dot dot line. */ DK4_GRA_LS_DASH_DOT_DOT_DOT /**< Dash dot dot dot line. */ } dk4_gra_ls_t; /** Line cap styles. */ typedef enum { DK4_GRA_LC_BUTTED = 0, /**< Line finished exactly at point. */ DK4_GRA_LC_ROUNDED , /**< Half circle added at each line end. */ DK4_GRA_LC_PROJECTING /**< Half square added at each line end. */ } dk4_gra_lc_t; /** Line join styles. */ typedef enum { DK4_GRA_LJ_MITERED = 0, /**< Pointed. */ DK4_GRA_LJ_ROUNDED , /**< Rounded. */ DK4_GRA_LJ_BEVELED /**< Cutted point. */ } dk4_gra_lj_t; /** Flags for new pages. Or-combinations allowed. */ enum { /** Do not set clip path. */ DK4_GRA_PAGE_FLAG_NO_CLIP = 0x0001 , /** Do not fill background in white. */ DK4_GRA_PAGE_FLAG_NO_BG = 0x0002 , /** Use uncompressed PDF page stream. Intended for debugging purposes only. */ DK4_GRA_PAGE_FLAG_NOT_COMPRESSED = 0x0004 , /** Use front side and back side of paper. */ DK4_GRA_DOC_FLAG_DUPLEX = 0x0200 , /** Use front side and back side of paper, binding like a calendar. */ DK4_GRA_DOC_FLAG_TUMBLE = 0x0400 , /** Force use of grayscaled output instead of colors. */ DK4_GRA_DOC_FLAG_FORCE_GRAY = 0x0800 , /** Use PS level 2 instead of level 3. */ DK4_GRA_DOC_FLAG_PS2 = 0x1000 , /** Produce document structuring comments. */ DK4_GRA_DOC_FLAG_PS_DSC = 0x2000 , /** Produce EPS instead of normal PS. */ DK4_GRA_DOC_FLAG_EPS = 0x4000 }; /** Fill patterns. */ typedef enum { /** Diagonal lines 30 degrees to the left. */ DK4_GRA_PATTERN_30_DEGREE_LEFT = 0, /** Diagonal lines 30 degrees to the right. */ DK4_GRA_PATTERN_30_DEGREE_RIGHT , /** Crosshatch of lines 30 degrees to the left and right. */ DK4_GRA_PATTERN_30_DEGREE_SIEVE , /** Diagonal lines 45 degrees to the left. */ DK4_GRA_PATTERN_45_DEGREE_LEFT , /** Diagonal lines 45 degrees to the left. */ DK4_GRA_PATTERN_45_DEGREE_RIGHT , /** Crosshatch of lines 45 degrees to the left and right. */ DK4_GRA_PATTERN_45_DEGREE_SIEVE , /** Horizontal bricks. */ DK4_GRA_PATTERN_HORIZONTAL_BRICKS , /** Vertical bricks. */ DK4_GRA_PATTERN_VERTICAL_BRICKS , /** Horizontal lines. */ DK4_GRA_PATTERN_HORIZONTAL_LINES , /** Vertical lines. */ DK4_GRA_PATTERN_VERTICAL_LINES , /** Crosshatch of horizontal and vertical lines. */ DK4_GRA_PATTERN_HORIZONTAL_VERTICAL_SIEVE , /** Horizontal shingles skewed to the left. */ DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_LEFT , /** Horizontal shingles skewed to the right. */ DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_RIGHT , /** Vertical shingles skewed to one side. */ DK4_GRA_PATTERN_VERTICAL_SHINGLES_1 , /** Vertical shingles skewed to the other side. */ DK4_GRA_PATTERN_VERTICAL_SHINGLES_2 , /** Large fish scales. */ DK4_GRA_PATTERN_LARGE_FISH_SCALES , /** Small fish scales. */ DK4_GRA_PATTERN_SMALL_FISH_SCALES , /** Circles. */ DK4_GRA_PATTERN_CIRCLES , /** Hexagons. */ DK4_GRA_PATTERN_HEXAGONS , /** Octagons. */ DK4_GRA_PATTERN_OCTAGONS , /** Horizontal tire treads. */ DK4_GRA_PATTERN_HORIZONTAL_TIRES , /** Vertical tire treads. */ DK4_GRA_PATTERN_VERTICAL_TIRES } dk4_gra_pattern_t; /** Maximum pattern number. */ enum { /** Maximum pattern number. */ DK4_GRA_PATTERN_MAX = DK4_GRA_PATTERN_VERTICAL_TIRES }; /** Type of preamble line to add. */ enum { DK4_GRA_PREAMBLE_FONT = 0 , /**< Line to load font package. */ DK4_GRA_PREAMBLE_PACKAGE , /**< Line to load other packages. */ DK4_GRA_PREAMBLE_OTHER /**< Any other configuration line. */ }; /** Output structure to produce a PS or EPS file. */ typedef struct { int llev; /**< PS language level. */ int dsc; /**< Flag: Write DSC comments. */ int fspd; /**< Flag: Use setpagedevice for paper size. */ int fdu; /**< Flag: Duplex. */ int ftu; /**< Flag: Duplex and tumble. */ } dk4_gra_ps_output_t; /** Output structure to produce a PDF file. */ typedef struct { dk4_sto_t *s_imagno; /**< Images container by object number. */ dk4_sto_it_t *i_imagno; /**< Images iterator. */ dk4_sto_t *s_images; /**< Images container by data source. */ dk4_sto_it_t *i_images; /**< Images iterator. */ dk4_sto_t *s_objpos; /**< Object positions container. */ dk4_sto_it_t *i_objpos; /**< Object positions iterator. */ size_t nextobj; /**< Object number of next XObject. */ size_t unxo; /**< Number of XObjects without file name. */ } dk4_gra_pdf_output_t; /** Output structure to produce a PGF file. */ typedef struct { dk4_font_collector_t *fc; /**< Font collector. */ dk4_sto_t *s_imagno; /**< Images container by number. */ dk4_sto_it_t *i_imagno; /**< Images iterator. */ dk4_sto_t *s_images; /**< Images container by data source. */ dk4_sto_it_t *i_images; /**< Images iterator. */ dk4_sto_t *s_prelfo; /**< Containter for font setup. */ dk4_sto_it_t *i_prelfo; /**< Font setup iterator. */ dk4_sto_t *s_prelpa; /**< Container for packages. */ dk4_sto_it_t *i_prelpa; /**< Packages iterator. */ dk4_sto_t *s_prelot; /**< Container for other setup. */ dk4_sto_it_t *i_prelot; /**< Other setup iterator. */ double dfs; /**< Document font size. */ size_t n_images; /**< Next image number. */ size_t n_prelfo; /**< Number of font setup lines. */ size_t n_prelpa; /**< Number of package setup lines. */ size_t n_prelot; /**< Number of other setup lines. */ int sa; /**< Flag: Produce standalone doc. */ } dk4_gra_pgf_output_t; /** Union of output structure types. */ typedef union { dk4_gra_ps_output_t ps; /**< Produce PS/EPS output. */ dk4_gra_pdf_output_t pdf; /**< Produce PDF output. */ dk4_gra_pgf_output_t pgf; /**< Produce PGF output. */ } dk4_gra_all_output_t; /** Output structure to produce a graphics file. */ typedef struct { dk4_gra_all_output_t out; /**< Output structure. */ dk4_cs_conv_ctx_t cscctx; /**< Color space conversion context. */ dk4_sto_t *s_pages; /**< Pages container. */ dk4_sto_it_t *i_pages; /**< Iterator through container. */ dkChar *fn; /**< Output file name. */ void *curpg; /**< Current page. */ double cur_x; /**< Current x position. */ double cur_y; /**< Current y position. */ double patlw; /**< Pattern line width. */ size_t pages; /**< Number of pages. */ size_t w; /**< Image width. */ size_t h; /**< Image height. */ int dr; /**< Output driver. */ int gscp; /**< Flag: Graphics state pattern clip. */ int eor; /**< Flag: Use even-odd-rule fill clip. */ int le; /**< Previous error. */ int lec; /**< Previous error code. */ int len; /**< Number how often previous error. */ int docfl; /**< Document flag set. */ } dk4_gra_t; /** Point coordinates in a graphics. */ typedef struct { double x; /**< X value. */ double y; /**< Y value. */ } dk4_gra_point_t; #ifdef __cplusplus extern "C" { #endif /** Open output structure to create a PDF file. @param fn File name for output file, NULL for standard output. @param w Image width in bp. @param h Image height in bp. @param docfl Document flags. The flags can contain both document and page flags, page flags here are applied as default page flags for pages added by the dk4gra_page() function. The following document flags are available: - DK4_GRA_DOC_FLAG_PS2
to produce PS level 2 instead of level 3, - DK4_GRA_DOC_FLAG_EPS
to produce EPS instead of PS, - DK4_GRA_DOC_FLAG_PS_DSC
to write document structuring comments, - DK4_GRA_DOC_FLAG_FORCE_GRAY
to enforce grayscaled output. The following page flags are available: - DK4_GRA_PAGE_FLAG_NO_CLIP
to skip setting the clip path to page size, - DK4_GRA_PAGE_FLAG_NO_BG
to skip filling the page with a white background, - DK4_GRA_PAGE_FLAG_NOT_COMPRESSED
to create an uncompressed page contents stream in PDF output (intended for debugging only). @param erp Error report, may be NULL. @return Valid pointer to new structure on success, NULL on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if fn is NULL, w or h is 0, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available. */ dk4_gra_t * dk4gra_open_pdf( const dkChar *fn, size_t w, size_t h, int docfl, dk4_er_t *erp ); /** Open output structure to create a PS or EPS file. @param fn File name for output file, NULL for standard output. @param w Image width in bp. @param h Image height in bp. @param docfl Document flags. The flags can contain both document and page flags, page flags here are applied as default page flags for pages added by the dk4gra_page() function. @param erp Error report, may be NULL. @return Valid pointer to new structure on success, NULL on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if fn is NULL, w or h is 0 or ll is neither 2 nor 3. - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available. */ dk4_gra_t * dk4gra_open_ps( const dkChar *fn, size_t w, size_t h, int docfl, dk4_er_t *erp ); /** Open output structure to create a PGF file. @param fn File name for output file, NULL for standard output. @param w Image width in bp. @param h Image height in bp. @param docfl Document flags. The flags can contain both document and page flags, page flags here are applied as default page flags for pages added by the dk4gra_page() function. @param sa Flag: Produce standalone TeX file. @param erp Error report, may be NULL. @return Valid pointer to new structure on success, NULL on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if fn is NULL, w or h is 0, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available. */ dk4_gra_t * dk4gra_open_pgf( const dkChar *fn, size_t w, size_t h, int docfl, int sa, dk4_er_t *erp ); /** Set color space conversion context. @param gra Output structure. @param ctx Color space conversion context to copy. @param backptr Address of success variable to reset on error. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra or ctx is NULL. */ void dk4gra_set_color_conversion( dk4_gra_t *gra, dk4_cs_conv_ctx_t const *ctx, int *backptr, dk4_er_t *erp ); /** Write output file and close output structure. @param gra Output structure. @param erp Error report, may be NULL. @param backptr Address of success variable to reset on errors. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or in a state allowing this operation, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_write_and_close( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Write output file and close output structure. @param fout Output file already opened. @param gra Output structure. @param erp Error report, may be NULL. @param backptr Address of success variable to reset on errors. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL, - DK4_E_INVALID_ARGUMENTS
if gra is not in a state allowing this operation, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_write_file_and_close( FILE *fout, dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Close output structure (without writing output file). You might want to use this function instead of dk4gra_write_and_close() if the drawing functions indicated an error. @param gra Output structure. */ void dk4gra_close( dk4_gra_t *gra ); /** Start new page. Default flags are used for the page: - The clip path is set to the image dimensions. - Background is filled white. - For PDF the contents stream is compressed. To start a new page with different setup, use dk4gra_page_with_flags() instead and specify flags. @param gra Output structure. @param erp Error report, may be NULL. @param backptr Address of success variable to reset on errors. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL, or in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_page( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Start new page with non-default setup. @param gra Output structure. @param flags Or-combined flags: - DK4_GRA_PAGE_FLAG_NO_CLIP
to avoid setting the clip path at start of page, - DK4_GRA_PAGE_FLAG_NO_BG
to avoid white background filling, - DK4_GRA_PAGE_FLAG_NOT_COMPRESSED
to avoid compression of page content stream in PDF. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_page_with_flags( dk4_gra_t *gra, int flags, int *backptr, dk4_er_t *erp ); /** Set flag for simplified gsave/grestore handling. Set this flag, if you use gsave and grestore only when dealing with clip path for pattern filling. @param gra Output structure. @param val New flag value. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL. */ void dk4gra_set_gs_for_pattern_only( dk4_gra_t *gra, int val, dk4_er_t *erp ); /** Save current graphics state (especially clip path). @param gra Output structure. @param erp Error report, may be NULL. @param backptr Address of success variable to reset on errors. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_gsave( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Restore graphics state (especially clip path). @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_grestore( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Set line width. @param gra Output structure. @param lw Line width in bp. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_line_width( dk4_gra_t *gra, double lw, int *backptr, dk4_er_t *erp ); /** Set line style. @param gra Output structure. @param ls Line style. @param sv Style value (dash length in bp). @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_line_style( dk4_gra_t *gra, dk4_gra_ls_t ls, double sv, int *backptr, dk4_er_t *erp ); /** Set line cap. @param gra Output structure. @param lc Line cap type. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_line_cap( dk4_gra_t *gra, dk4_gra_lc_t lc, int *backptr, dk4_er_t *erp ); /** Set line join. @param gra Output structure. @param lj Line join type. @param ml Miter limit, only used if lj is DK4_GRA_LJ_MITERED. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_line_join( dk4_gra_t *gra, dk4_gra_lj_t lj, double ml, int *backptr, dk4_er_t *erp ); /** Set fill color to gray. @param gra Output structure. @param g Gray value in interval 0 to 1. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_fill_gray( dk4_gra_t *gra, double g, int *backptr, dk4_er_t *erp ); /** Set fill color to RGB. @param gra Output structure. @param r Red value in interval 0 to 1. @param g Green value in interval 0 to 1. @param b Blue value in interval 0 to 1. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_fill_rgb( dk4_gra_t *gra, double r, double g, double b, int *backptr, dk4_er_t *erp ); /** Set fill color to CMYK. @param gra Output structure. @param c Cyan value in interval 0 to 1. @param m Magenta value in interval 0 to 1. @param y Yellow value in interval 0 to 1. @param k Black value in interval 0 to 1. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_fill_cmyk( dk4_gra_t *gra, double c, double m, double y, double k, int *backptr, dk4_er_t *erp ); /** Set stroke color to gray. @param gra Output structure. @param g Gray value in interval 0 to 1. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_stroke_gray( dk4_gra_t *gra, double g, int *backptr, dk4_er_t *erp ); /** Set stroke color to RGB. @param gra Output structure. @param r Red value in interval 0 to 1. @param g Green value in interval 0 to 1. @param b Blue value in interval 0 to 1. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_stroke_rgb( dk4_gra_t *gra, double r, double g, double b, int *backptr, dk4_er_t *erp ); /** Set stroke color to CMYK. @param gra Output structure. @param c Cyan value in interval 0 to 1. @param m Magenta value in interval 0 to 1. @param y Yellow value in interval 0 to 1. @param k Black value in interval 0 to 1. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation. */ void dk4gra_set_stroke_cmyk( dk4_gra_t *gra, double c, double m, double y, double k, int *backptr, dk4_er_t *erp ); /** Prepare output structure for a fill operation. Use this function before you start to construct a path you plan to fill. @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_prepare_fill( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Prepare output structure for a stroke operation. Use this function before you start to construct a path you plan to stroke. @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_prepare_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Prepare output structure for a combined fill and stroke operation. Use this function before you start to construct a path you plan to fill and stroke. @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_prepare_fill_and_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Check whether a combined fill and close operation is available for an output structure. @param gra Output structure to test. @return 1 if a fill-and-close operation is available, 0 otherwise. */ int dk4gra_can_fill_and_stroke( const dk4_gra_t *gra ); /** Fill current path. Note: Use dk4gra_prepare_fill() before you start to construct a path you plan to fill. The value of the even-odd-rule flag is used to choose either even-odd-rule or nonzero-winding-rule, the dk4gra_set_eorule() function can be used to set the flag. @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_fill( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Stroke current path. Note: Use dk4gra_prepare_stroke() before you start to construct a path you plan to stroke. @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Fill and stroke current path. Note: Use dk4gra_prepare_fill_and_stroke() before you start to construct a path you plan to fill and stroke. The value of the even-odd-rule flag is used to choose either even-odd-rule or nonzero-winding-rule, the dk4gra_set_eorule() function can be used to set the flag. @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_fill_and_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Use current path for clipping. The value of the even-odd-rule flag is used to choose either even-odd-rule or nonzero-winding-rule, the dk4gra_set_eorule() function can be used to set the flag. @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_clip( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Set line width for pattern drawing. The pattern line width should be in range 0.0 to 2.0. @param gra Output structure. @param plw New pattern line width in bp. */ void dk4gra_set_pattern_line_width( dk4_gra_t *gra, double plw ); /** Pattern a region (clipping should be set to the path). @param gra Output structure. @param xl Left y coordinate. @param xr Right x coordinate. @param yb Bottom y coordinate. @param yt Top y coordinate. @param pn Pattern number. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Set flag for even-odd-rule. If this flag is on, the even-odd-rule is used for filling and clipping. Otherwise the nonzero-winding rule is used. By default this flag is turned on when creating a dk4_gra_t structure. @param gra Output structure. @param val New flag value. */ void dk4gra_set_eorule( dk4_gra_t *gra, int val ); /** Start a new path and move to first point. @param gra Output structure. @param x X coordinate of start point. @param y Y coordinate of start point. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_newpath_moveto( dk4_gra_t *gra, double x, double y, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ); /** Add line from current point to new point to path. @param gra Output structure. @param x X coordinate of new point. @param y Y coordinate of new point. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_lineto( dk4_gra_t *gra, double x, double y, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ); /** Add Bezier curve segment from current point to new point in path. @param gra Output structure. @param xc1 X coordinate of first control point. @param yc1 Y coordinate of first control point. @param xc2 X coordinate of second control point. @param yc2 Y coordinate of second control point. @param x X coordinate of new point. @param y Y coordinate of new point. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Close current path. @param gra Output structure. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_closepath( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ); /** Create path for a circle. @param gra Output structure. @param xc Center point x coordinate. @param yc Center point y coordinate. @param r Radius. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_circle( dk4_gra_t *gra, double xc, double yc, double r, dk4_bb_t *bbptr, int *backptr, dk4_er_t *erp ); /** Create path for rectangle parallel to axes, optionally with rounded corners. @param gra Output structure. @param xl Left x coordinate. @param xr Right x coordinate. @param yb Bottom y coordinate. @param yt Top y coordinate. @param r Corner radius, maximum is a half of the smaller side length. Use negative values to avoid rounded corners. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Add path for an arc. @param gra Output structure. @param xc Center point x coordinate. @param yc Center point y coordinate. @param ra Radius. @param start Start angle in degree. @param end End angle in degree. @param cl Flag: Draw closed arc (piece of cake) instead of simple arc. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Create path for an ellipse. @param gra Output structure. @param xc Center point x coordinate. @param yc Center point y coordinate. @param rx Radius in x direction. @param ry Radius in y direction. @param rot Rotation counterclockwise in degree. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Add simple (non-special) text to PGF graphics. The text is shown in the current fill color (non-stroking color) unless a color is specified in colspec. @param gra Output structure, must be initialized for PGF. @param x X coordinate. @param y Y coordinate. @param rot Rotation counterclockwise in degree. @param txt Text to show. @param colspec Color specification, may be NULL to use fill color. @param ie Text encoding, only used for char text. @param ha Horizontal alignment. @param va Vertical alignment. @param fno Font number. @param fsz Font size in pt. @param fex Flag: Use exact font (1) or similar font (0). @param uc2l UC to LaTeX conversion structure. @param flags Text flags DK4_GRA_TEXT_FLAG_xxx, can be or-combined. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_pgf_simple_text( dk4_gra_t *gra, double x, double y, double rot, const dkChar *txt, const char *colspec, int ie, dk4_text_align_h_t ha, dk4_text_align_v_t va, int fno, double fsz, dk4_gra_tf_t fex, dk4_uc2l_t *uc2l, int flags, int *backptr, dk4_er_t *erp ); /** Add simple (non-special) text to PGF graphics. The text is shown in the current fill color (non-stroking color) unless a color is specified in colspec. @param gra Output structure, must be initialized for PGF. @param x X coordinate. @param y Y coordinate. @param rot Rotation counterclockwise in degree. @param txt Text to show. @param colspec Color specification, may be NULL to use fill color. @param ha Horizontal alignment. @param va Vertical alignment. @param fno Font number. @param fsz Font size in pt. @param fex Flag: Use exact font (1) or similar font (0). @param uc2l UC to LaTeX conversion structure. @param flags Text flags DK4_GRA_TEXT_FLAG_xxx, can be or-combined. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_pgf_simple_utf8_text( dk4_gra_t *gra, double x, double y, double rot, const char *txt, const char *colspec, dk4_text_align_h_t ha, dk4_text_align_v_t va, int fno, double fsz, dk4_gra_tf_t fex, dk4_uc2l_t *uc2l, int flags, int *backptr, dk4_er_t *erp ); /** Add special text to PGF graphics. The text is shown in the current fill color (non-stroking color) unless a color is specified in colspec. @param gra Output structure, must be initialized for PGF. @param x X coordinate. @param y Y coordinate. @param rot Rotation counterclockwise in degree. @param txt Text to show. @param colspec Color specification, may be NULL to use fill color. @param ha Horizontal alignment. @param va Vertical alignment. @param fno Font number. @param fsz Font size. @param fex Flag: Use exact font. @param flags Text flags DK4_GRA_TEXT_FLAG_xxx, can be or-combined. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ void dk4gra_pgf_special_text( dk4_gra_t *gra, double x, double y, double rot, const char *txt, const char *colspec, dk4_text_align_h_t ha, dk4_text_align_v_t va, int fno, double fsz, dk4_gra_tf_t fex, int flags, int *backptr, dk4_er_t *erp ); /** Set the font size for the documentclass line. @param gra Output structure, must be initialized for PGF. @param fs Font size in pt. @param backptr Address of success variable to reset on error. @param erp Error report, may be NULL. */ void dk4gra_pgf_doc_font_size( dk4_gra_t *gra, double fs, int *backptr, dk4_er_t *erp ); /** Add a preamble line. For font setup and package setup the lines added by this function replace the default contents. For other setup the lines added by this function are appended after the default contents. @param gra Output structure, must be initialized for PGF. @param line Line text without trailing newline. @param tp Line type: DK4_GRA_PREAMBLE_FONT, DK4_GRA_PREAMBLE_PACKAGE, or DK4_GRA_PREAMBLE_OTHER. @param backptr Address of success variable to reset on error. @param erp Error report, may be NULL. */ void dk4gra_pgf_doc_preamble_line( dk4_gra_t *gra, const char *line, int tp, int *backptr, dk4_er_t *erp ); /** Add bitmap image with coordinates transformations already calculated. @param gra Output structure. @param cotra Array containing 5 elements for coordinates transformations. @param bif Bitmap image file. @param fn Image file name. @param fno Frame number. The frame number given here is used by the PDF output driver only. You must call dk4bif_set_current_frame() on the bitmap image file before calling this function. @param ifl Image flags. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or bif is NULL or a frame number other than 0 was specified for PGF output or gra is not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Add bitmap image XFig style from opened bitmap image file. @param gra Output structure. @param xl Left x coordinate. @param xr Right x coordinate. @param yb Bottom y coordinate. @param yt Top y coordinate. @param bif Bitmap image file. @param fn Image file name. @param fno Frame number (0 for first frame). @param pos Image positioning: - 0 not rotated, not flipped, - 1 rotated 90 degree counterclockwise, not flipped, - 2 rotated 180 degree counterclockwise, not flipped, - 3 rotated 270 degree counterclockwise, not flipped, - 4 not rotated, flipped, - 5 rotated 90 degree counterclockwise, flipped, - 6 rotated 180 degree counterclockwise, flipped, - 7 rotated 270 degree counterclockwise, flipped. @param ifl Image flags. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or bif is NULL or a frame number other than 0 was specified for PGF output or gra is not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Add bitmap image from opened bitmap image file. @param gra Output structure. @param xl Left x coordinate. @param xr Right x coordinate. @param yb Bottom y coordinate. @param yt Top y coordinate. @param bif Bitmap image file data. @param fn Image file name. @param fno Frame number (0 for first frame). @param ifl Image flags. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or bif is NULL or gra is not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Add bitmap image specified by file name. @param gra Output structure. @param xl Left x coordinate. @param xr Right x coordinate. @param yb Bottom y coordinate. @param yt Top y coordinate. @param fn Image file name. @param fno Frame number (0 for first frame). @param ctx Bitmap image conversion context, may be NULL. @param ifl Image flags. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or bif is NULL or gra is not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); /** Add bitmap image XFig style specified by file name. @param gra Output structure. @param xl Left x coordinate. @param xr Right x coordinate. @param yb Bottom y coordinate. @param yt Top y coordinate. @param fn Image file name. @param fno Frame number (0 for first frame). @param ctx Bitmap image conversion context, may be NULL. @param pos Image positioning: - 0 not rotated, not flipped, - 1 rotated 90 degree counterclockwise, not flipped, - 2 rotated 180 degree counterclockwise, not flipped, - 3 rotated 270 degree counterclockwise, not flipped, - 4 not rotated, flipped, - 5 rotated 90 degree counterclockwise, flipped, - 6 rotated 180 degree counterclockwise, flipped, - 7 rotated 270 degree counterclockwise, flipped. @param ifl Image flags. @param bbptr Bounding box, may be NULL. @param backptr Address of success variable to reset on errors. @param erp Error report, may be NULL. Error codes: - DK4_E_INVALID_ARGUMENTS
if gra is NULL or bif is NULL or gra is not in a state allowing this operation, - DK4_E_MATH_OVERFLOW
on numeric overflow in memory size calculation, - DK4_E_MEMORY_ALLOCATION_FAILED
if there is not enough memory available, - DK4_E_WRITE_FAILED
if writing one ore multiple bytes to the stream failed, - DK4_E_FLUSH_FAILED
if flushing data downwards failed. */ 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 ); #ifdef __cplusplus } #endif /** Number of points to calculate for a circle or ellipse. */ enum { /** Number of points to calculate for a circle or ellipse. */ DK4_GRA_CIRCLE_POINTS = 24 }; /* vim: set ai sw=4 ts=4 : */ %% 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 "dk4math.h" #endif #ifndef DK4UC2L_H_INCLUDED #include "dk4uc2l.h" #endif #ifndef DK4GRA_H_INCLUDED #include "dk4gra.h" #endif #ifndef DK4GRAT_H_INCLUDED #include "dk4grat.h" #endif #ifndef GRA_H_INCLUDED #include "gra.h" #endif #ifndef DK4BIF_H_INCLUDED #include "dk4bif.h" #endif #ifndef DK4FOPD_H_INCLUDED #include "dk4fopd.h" #endif #ifndef DK4FOPT_H_INCLUDED #include "dk4fopt.h" #endif #ifndef DK4ISADM_H_INCLUDED #include "dk4isadm.h" #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif $!trace-include 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 ) { $? "+ dk4gra_close" #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: $? "- dk4gra_close" 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; $? "+ dk4gra_open_pdf \"%!ds\"", TR_STR(fn) #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: $? "- dk4gra_open_pdf %d", TR_IPTR(back) 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; $? "+ dk4gra_open_ps" #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: $? "- dk4gra_open_ps %d", TR_IPTR(back) 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; $? "+ dk4gra_open_pgf" #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: $? "- dk4gra_open_pgf %d", TR_IPTR(back) 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; $? "+ dk4gra_write_file_and_close" #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: $? "- dk4gra_write_file_and_close %d", back 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 $? "+ dk4gra_write_and_close" #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: $? "- dk4gra_write_and_close %d", back 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; $? "+ dk4gra_page" #if DK4_USE_ASSERT assert(NULL != gra); #endif if (NULL == gra) { $? "! 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)) { $? "! s_pages, 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 : { $? ". eps driver" back = dk4gra_eps_page(gra, flags, erp); } break; case DK4_GRA_DRIVER_PGF : { $? ". pgf driver" back = dk4gra_pgf_page(gra, flags, erp); } break; default : { $? ". pdf driver" back = dk4gra_pdf_page(gra, flags, erp); } break; } finished: $? "- dk4gra_page %d", back 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 ) { $? "+ dk4gra_i_newpath_moveto" #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (gra->dr) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { $? ". PS/EPS" if (0 == dk4gra_eps_newpath_moveto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { $? ". PGF" if (0 == dk4gra_pgf_newpath_moveto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; default : { $? ". PDF" if (0 == dk4gra_pdf_newpath_moveto(gra, x, y, erp)) { if (NULL != backptr) { *backptr = 0; } } } break; } $? "- dk4gra_i_newpath_moveto" } void dk4gra_i_lineto( dk4_gra_t *gra, double x, double y, int *backptr, dk4_er_t *erp ) { $? "+ dk4gra_i_lineto" #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; } $? "- dk4gra_i_lineto" } 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 ) { $? "+ dk4gra_i_curveto" #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; } $? "- dk4gra_i_curveto" } void dk4gra_i_closepath( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { $? "+ dk4gra_i_closepath" #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; } $? "- dk4gra_i_closepath" } 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 ); } $? ". test 1" $? ". xmin=%g", bbptr->xmin $? ". xmax=%g", bbptr->xmax $? ". ymin=%g", bbptr->ymin $? ". ymax=%g", bbptr->ymax dk4bb_add_rotated_ellipse(bbptr, xc, yc, rx, ry, rot); $? ". test 2" $? ". xmin=%g", bbptr->xmin $? ". xmax=%g", bbptr->xmax $? ". ymin=%g", bbptr->ymin $? ". ymax=%g", bbptr->ymax } finished: return; } void dk4gra_i_circle( dk4_gra_t *gra, double xc, double yc, double r, int *backptr, dk4_er_t *erp ) { $? "+ dk4gra_i_circle" #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; } $? "- dk4gra_i_circle" } 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; $? "+ dk4gra_i_rectangle" #if DK4_USE_ASSERT assert(NULL != gra); #endif $!trace-code if (NULL != backptr) { $? ". *backptr = %d", *backptr $!trace-code } if (0.0 < r) { dx = xr - xl; dy = yt - yb; dx = 0.4999 * fabs(dx); dy = 0.4999 * fabs(dy); if (r > dx) { $? ". r = %g dx = %g", r, dx r = dx; #if 0 /* Silently correct radius */ if (NULL != backptr) { $? "! r > dx" *backptr = 0; } #endif } if (r > dy) { $? ". r = %g dy = %g", r, dy r = dy; #if 0 /* Silently correct radius */ if (NULL != backptr) { $? "! r > dy" *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) { $? "! dk4gra_eps_rectangle" *backptr = 0; } } } break; case DK4_GRA_DRIVER_PGF : { if (0 == dk4gra_pgf_rectangle(gra, xl, xr, yb, yt, r, erp)) { if (NULL != backptr) { $? "! dk4gra_pgf_rectangle" *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; } $? "- dk4gra_i_rectangle" } 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 */ $? "+ dk4gra_i_arc" #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; } $? "- dk4gra_i_arc" } void dk4gra_gsave( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_gsave" #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: $? "- dk4gra_gsave %d", back if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_grestore( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_grestore" #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: $? "- dk4gra_grestore %d", back 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; $? "+ dk4gra_set_line_width" #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: $? "- dk4gra_set_line_width %d", back 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; $? "+ dk4gra_set_line_style" #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: $? "- dk4gra_set_line_style %d", back 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; $? "+ dk4gra_set_line_cap" #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: $? "- dk4gra_set_line_cap %d", back 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; $? "+ dk4gra_set_line_join" #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: $? "- dk4gra_set_line_join %d", back 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; $? "+ dk4gra_set_fill_gray" #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: $? "- dk4gra_set_fill_gray %d", back 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; $? "+ dk4gra_set_fill_rgb" #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: $? "- dk4gra_set_fill_rgb %d", back 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; $? "+ dk4gra_set_fill_cmyk" #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: $? "- dk4gra_set_fill_cmyk %d", back 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; $? "+ dk4gra_set_stroke_gray" #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: $? "- dk4gra_set_stroke_gray %d", back 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; $? "+ dk4gra_set_stroke_rgb" #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: $? "- dk4gra_set_stroke_rgb %d", back 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; $? "+ dk4gra_set_stroke_cmyk" #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: $? "- dk4gra_set_stroke_cmyk %d", back if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_prepare_fill( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_prepare_fill" #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: $? "- dk4gra_prepare_fill %d", back if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_prepare_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_prepare_stroke" #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: $? "- dk4gra_prepare_stroke %d", back 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; $? "+ dk4gra_prepare_fill_and_stroke" #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: $? "- dk4gra_prepare_fill_and_stroke %d", back if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } int dk4gra_can_fill_and_stroke( const dk4_gra_t *gra ) { int back = 0; $? "+ dk4gra_can_fill_and_stroke" #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; } $? "- dk4gra_can_fill_and_stroke %d", back return back; } void dk4gra_fill( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_fill" #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: $? "- dk4gra_fill %d", back if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_stroke( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_stroke" #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: $? "- dk4gra_stroke %d", back 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; $? "+ dk4gra_fill_and_stroke" #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: $? "- dk4gra_fill_and_stroke %d", back if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_clip( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_clip" #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: $? "- dk4gra_clip %d", back 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; $? "+ dk4gra_newpath_moveto" #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: $? "- dk4gra_newpath_moveto %d", back 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; $? "+ dk4gra_lineto" #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: $? "- dk4gra_lineto %d", back 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; $? "+ dk4gra_curveto" #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: $? "- dk4gra_curveto %d", back if ((NULL != backptr) && (0 == back)) { *backptr = 0; } } void dk4gra_closepath( dk4_gra_t *gra, int *backptr, dk4_er_t *erp ) { int back = 0; $? "+ dk4gra_closepath" #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: $? "- dk4gra_closepath %d", back 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; $? "+ dk4gra_circle" #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: $? "- dk4gra_circle %d", back 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; $? "+ dk4gra_rectangle" #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: $? "- dk4gra_rectangle %d", back 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; $? "+ dk4gra_arc" #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: $? "- dk4gra_arc %d", back 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; $? "+ dk4gra_ellipse" #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: $? "- dk4gra_ellipse %d", back 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; $? "+ dk4gra_pattern" #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: $? "- dk4gra_pattern %d", back 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 */ $? "+ dk4gra_bif_cotra_image \"%!ds\"", TR_STR(fn) #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: $? "- dk4gra_bif_cotra_image %d", back 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; $? "+ dk4gra_bif_fig_image" #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != bif); #endif $? ". xl = %lg", xl $? ". xr = %lg", xr $? ". yb = %lg", yb $? ". yt = %lg", yt $? ". bif = %d", TR_IPTR(bif) $? ". fn = \"%!ds\"", TR_STR(fn) $? ". fno = %u", (unsigned)fno $? ". ipol = %d", (DK4_GRA_IMG_FLAG_INTERPOLATION & ifl) $? ". ignres = %d", (DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION & ifl) $? ". ignar = %d", (DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO & ifl) $? ". pos = %d", pos $? ". oiop = %d", (DK4_GRA_IMG_FLAG_ONLY_PAGE_CONTENTS & ifl) $? ". alzw = %d", (DK4_GRA_IMG_FLAG_LZW & ifl) $? ". ajpg = %d", (DK4_GRA_IMG_FLAG_DCT & ifl) $? ". ijpg = %d", (DK4_GRA_IMG_FLAG_DCT_INTERPOLATION & ifl) $? ". acol = %d", (DK4_GRA_IMG_FLAG_COLOR & ifl) $? ". anb = %d", (DK4_GRA_IMG_FLAG_ANALYZE_BPC & ifl) $? ". anc = %d", (DK4_GRA_IMG_FLAG_ANALYZE_COLOR & ifl) $? ". ana = %d", (DK4_GRA_IMG_FLAG_ANALYZE_ALPHA & ifl) $? ". fbgf = %d", (DK4_GRA_IMG_FLAG_FILL_BACKGROUND & ifl) /* 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: $? "- dk4gra_bif_fig_image %d", back 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; $? "+ dk4gra_bif_image" #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != bif); #endif $? ". xl = %lg", xl $? ". xr = %lg", xr $? ". yb = %lg", yb $? ". yt = %lg", yt $? ". bif = %d", TR_IPTR(bif) $? ". fn = \"%!ds\"", TR_STR(fn) $? ". fno = %u", (unsigned)fno $? ". ipol = %d", (DK4_GRA_IMG_FLAG_INTERPOLATION & ifl) $? ". ignres = %d", (DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION & ifl) $? ". ignar = %d", (DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO & ifl) $? ". arot = %d", (DK4_GRA_IMG_FLAG_ALLOW_ROTATION & ifl) $? ". oiop = %d", (DK4_GRA_IMG_FLAG_ONLY_PAGE_CONTENTS & ifl) $? ". alzw = %d", (DK4_GRA_IMG_FLAG_LZW & ifl) $? ". ajpg = %d", (DK4_GRA_IMG_FLAG_DCT & ifl) $? ". ijpg = %d", (DK4_GRA_IMG_FLAG_DCT_INTERPOLATION & ifl) $? ". acol = %d", (DK4_GRA_IMG_FLAG_COLOR & ifl) $? ". anb = %d", (DK4_GRA_IMG_FLAG_ANALYZE_BPC & ifl) $? ". anc = %d", (DK4_GRA_IMG_FLAG_ANALYZE_COLOR & ifl) $? ". ana = %d", (DK4_GRA_IMG_FLAG_ANALYZE_ALPHA & ifl) $? ". fbgf = %d", (DK4_GRA_IMG_FLAG_FILL_BACKGROUND & ifl) /* 2018-03-19 Removed (NULL == fn) */ if ((NULL == gra) || (NULL == bif)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } $? ". gra, bif, fn ok" if ((xr <= xl) || (yt <= yb)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } $? ". xl, yt ok" 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: $? "- dk4gra_bif_image %d", back 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; $? "+ dk4gra_fig_image" #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != fn); #endif $? ". xl = %lg", xl $? ". xr = %lg", xr $? ". yb = %lg", yb $? ". yt = %lg", yt $? ". fn = \"%!ds\"", TR_STR(fn) $? ". fno = %u", (unsigned)fno $? ". ctx = %i", TR_IPTR(ctx) $? ". ipol = %d", (DK4_GRA_IMG_FLAG_INTERPOLATION & ifl) $? ". ignres = %d", (DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION & ifl) $? ". ignar = %d", (DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO & ifl) $? ". pos = %d", pos $? ". oiop = %d", (DK4_GRA_IMG_FLAG_ONLY_PAGE_CONTENTS & ifl) $? ". alzw = %d", (DK4_GRA_IMG_FLAG_LZW & ifl) $? ". ajpg = %d", (DK4_GRA_IMG_FLAG_DCT & ifl) $? ". ijpg = %d", (DK4_GRA_IMG_FLAG_DCT_INTERPOLATION & ifl) $? ". acol = %d", (DK4_GRA_IMG_FLAG_COLOR & ifl) $? ". anb = %d", (DK4_GRA_IMG_FLAG_ANALYZE_BPC & ifl) $? ". anc = %d", (DK4_GRA_IMG_FLAG_ANALYZE_COLOR & ifl) $? ". ana = %d", (DK4_GRA_IMG_FLAG_ANALYZE_ALPHA & ifl) $? ". fbgf = %d", (DK4_GRA_IMG_FLAG_FILL_BACKGROUND & ifl) 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); } $? "- dk4gra_fig_image %d", back 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 */ $? "+ dk4gra_image" #if DK4_USE_ASSERT assert(NULL != gra); assert(NULL != fn); #endif $? ". xl = %lg", xl $? ". xr = %lg", xr $? ". yb = %lg", yb $? ". yt = %lg", yt $? ". fn = \"%!ds\"", TR_STR(fn) $? ". fno = %u", (unsigned)fno $? ". ctx = %i", TR_IPTR(ctx) $? ". ipol = %d", (DK4_GRA_IMG_FLAG_INTERPOLATION & ifl) $? ". ignres = %d", (DK4_GRA_IMG_FLAG_IGNORE_RESOLUTION & ifl) $? ". ignar = %d", (DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO & ifl) $? ". arot = %d", (DK4_GRA_IMG_FLAG_ALLOW_ROTATION & ifl) $? ". oiop = %d", (DK4_GRA_IMG_FLAG_ONLY_PAGE_CONTENTS & ifl) $? ". alzw = %d", (DK4_GRA_IMG_FLAG_LZW & ifl) $? ". ajpg = %d", (DK4_GRA_IMG_FLAG_DCT & ifl) $? ". ijpg = %d", (DK4_GRA_IMG_FLAG_DCT_INTERPOLATION & ifl) $? ". acol = %d", (DK4_GRA_IMG_FLAG_COLOR & ifl) $? ". anb = %d", (DK4_GRA_IMG_FLAG_ANALYZE_BPC & ifl) $? ". anc = %d", (DK4_GRA_IMG_FLAG_ANALYZE_COLOR & ifl) $? ". ana = %d", (DK4_GRA_IMG_FLAG_ANALYZE_ALPHA & ifl) $? ". fbgf = %d", (DK4_GRA_IMG_FLAG_FILL_BACKGROUND & ifl) /* Check argument */ if ((NULL == gra) || (NULL == fn)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } $? ". gra and fn ok" if ((xr <= xl) || (yt <= yb)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } $? ". xr and yb ok" 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) { $? "! failed to open bitmap file" goto finished; } $? ". bitmap file opened" /* 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: $? ". cleanup section" if (NULL != bifptr) { $? ". close bitmap file" dk4bif_close(bifptr); } $? "- dk4gra_image %d", back 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 : */