diff options
author | Norbert Preining <norbert@preining.info> | 2020-09-20 03:03:26 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-09-20 03:03:26 +0000 |
commit | 1f457376b478257b88d4a857f5ec1b6155442dd7 (patch) | |
tree | 2a06a60551dea362cf8cb0cb0ba66c78608717c4 /support/dktools/dk4gra.ctr | |
parent | ac690ca29ad5bf8a5203a65fd6252f7b564f4727 (diff) |
CTAN sync 202009200303
Diffstat (limited to 'support/dktools/dk4gra.ctr')
-rw-r--r-- | support/dktools/dk4gra.ctr | 5529 |
1 files changed, 5529 insertions, 0 deletions
diff --git a/support/dktools/dk4gra.ctr b/support/dktools/dk4gra.ctr new file mode 100644 index 0000000000..df4cbf52a4 --- /dev/null +++ b/support/dktools/dk4gra.ctr @@ -0,0 +1,5529 @@ +%% 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 <dktools-4/dk4conf.h> +#endif +#endif + +#ifndef DK4MEM_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4mem.h" +#else +#include <dktools-4/dk4mem.h> +#endif +#endif + +#ifndef DK4FONT_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4font.h" +#else +#include <dktools-4/dk4font.h> +#endif +#endif + +#ifndef DK4ALIGN_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4align.h" +#else +#include <dktools-4/dk4align.h> +#endif +#endif + +#ifndef DK4ERROR_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4error.h" +#else +#include <dktools-4/dk4error.h> +#endif +#endif + +#ifndef DK4BB_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4bb.h" +#else +#include <dktools-4/dk4bb.h> +#endif +#endif + +#ifndef DK4BIFTY_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4bifty.h" +#else +#include <dktools-4/dk4bifty.h> +#endif +#endif + +#ifndef DK4CS_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4cs.h" +#else +#include <dktools-4/dk4cs.h> +#endif +#endif + +#ifndef DK4MEMBF_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4membuf.h" +#else +#include <dktools-4/dk4membuf.h> +#endif +#endif + +#ifndef DK4MBSTRM_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4mbstrm.h" +#else +#include <dktools-4/dk4mbstrm.h> +#endif +#endif + +#ifndef DK4FONTC_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4fontc.h" +#else +#include <dktools-4/dk4fontc.h> +#endif +#endif + +#ifndef DK4UC2L_H_INCLUDED +#if DK4_BUILDING_DKTOOLS4 +#include "dk4uc2l.h" +#else +#include <dktools-4/dk4uc2l.h> +#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<br> + to produce PS level 2 instead of level 3, + - DK4_GRA_DOC_FLAG_EPS<br> + to produce EPS instead of PS, + - DK4_GRA_DOC_FLAG_PS_DSC<br> + to write document structuring comments, + - DK4_GRA_DOC_FLAG_FORCE_GRAY<br> + to enforce grayscaled output. + + The following page flags are available: + + - DK4_GRA_PAGE_FLAG_NO_CLIP<br> + to skip setting the clip path to page size, + - DK4_GRA_PAGE_FLAG_NO_BG<br> + to skip filling the page with a white background, + - DK4_GRA_PAGE_FLAG_NOT_COMPRESSED<br> + 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<br> + if fn is NULL, w or h is 0, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + 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<br> + if fn is NULL, w or h is 0 or ll is neither 2 nor 3. + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + 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<br> + if fn is NULL, w or h is 0, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + 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<br> + 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<br> + if gra is NULL or in a state allowing this operation, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL, + - DK4_E_INVALID_ARGUMENTS<br> + if gra is not in a state allowing this operation, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL, or in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + to avoid setting the clip path at start of page, + - DK4_GRA_PAGE_FLAG_NO_BG<br> + to avoid white background filling, + - DK4_GRA_PAGE_FLAG_NOT_COMPRESSED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + 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<br> + 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<br> + 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<br> + 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<br> + 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<br> + 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<br> + 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<br> + 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<br> + 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<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + 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<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + 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<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or bif is NULL or gra is + not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or bif is NULL or gra is + not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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<br> + if gra is NULL or bif is NULL or gra is + not in a state allowing this operation, + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow in memory size calculation, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + if there is not enough memory available, + - DK4_E_WRITE_FAILED<br> + if writing one ore multiple bytes to the stream failed, + - DK4_E_FLUSH_FAILED<br> + 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 <fcntl.h> +#define FCNTL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_IO_H +#ifndef IO_H_INCLUDED +#include <io.h> +#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 <math.h> +#define MATH_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_FLOAT_H +#ifndef FLOAT_H_INCLUDED +#include <float.h> +#define FLOAT_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_ERRNO_H +#ifndef ERRNO_H_INCLUDED +#include <errno.h> +#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 <assert.h> +#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 : */ |