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/dk4greps.ctr | |
parent | ac690ca29ad5bf8a5203a65fd6252f7b564f4727 (diff) |
CTAN sync 202009200303
Diffstat (limited to 'support/dktools/dk4greps.ctr')
-rw-r--r-- | support/dktools/dk4greps.ctr | 2507 |
1 files changed, 2507 insertions, 0 deletions
diff --git a/support/dktools/dk4greps.ctr b/support/dktools/dk4greps.ctr new file mode 100644 index 0000000000..514710ee9c --- /dev/null +++ b/support/dktools/dk4greps.ctr @@ -0,0 +1,2507 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2017-xxxx +SPDX-License-Identifier: BSD-3-Clause + +%% module + +#include "dk4conf.h" + +#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 + +#ifndef DK4MEM_H_INCLUDED +#include "dk4mem.h" +#endif + +#ifndef DK4MEMBF_H_INCLUDED +#include "dk4membf.h" +#endif + +#ifndef DK4MBSTRM_H_INCLUDED +#include "dk4mbstrm.h" +#endif + +#ifndef DK4GRA_H_INCLUDED +#include "dk4gra.h" +#endif + +#ifndef GRA_H_INCLUDED +#include "gra.h" +#endif + +#ifndef DK4MAO8D_H_INCLUDED +#include "dk4mao8d.h" +#endif + +#ifndef DK4MAO8DNS_H_INCLUDED +#include "dk4mao8dns.h" +#endif + +#if DK4_HAVE_ASSERT_H +#ifndef ASSERT_H_INCLUDED +#include <assert.h> +#define ASSERT_H_INCLUDED 1 +#endif +#endif + + +$!trace-include + + + +/** Constant text fragments. +*/ +static const char * const dk4gra_eps_c8_kw[] = { +$!string-table +# +# 0 Newline +# +\n +# +# 1 gsave +# +gsave\n +# +# 2 grestore +# +grestore\n +# +# 3 space +# + +# +# 4 setlinewidth +# + setlinewidth\n +# +# 5 setcmykcolor +# + setcmykcolor\n +# +# 6 setrgbcolor +# + setrgbcolor\n +# +# 7 setgray +# + setgray\n +# +# 8 dash for solid line +# +[] 0 setdash\n +# +# 9 10 11 Dash array. +# +[ +] + setdash\n +# +# 12 13 14 Line cap +# +0 setlinecap\n +1 setlinecap\n +2 setlinecap\n +# +# 15 16 17 Line join +# +0 setlinejoin\n +1 setlinejoin\n +2 setlinejoin\n +# +# 18 19 fill +# +fill\n +eofill\n +# +# 20 stroke +# +stroke\n +# +# 21 22 clip +# +clip\n +eoclip\n +# +# 23 newpath +# +newpath\n +# +# 24 moveto +# + moveto\n +# +# 25 lineto +# + lineto\n +# +# 26 curveto +# + curveto\n +# +# 27 closepath +# +closepath\n +# +# 28 circle +# + 0 360 arc closepath\n +# +# 29 arc +# + arc\n +# +# 30 31 PS EPSF +# +%!PS-Adobe-3.0 EPSF-3.0\n +%!PS-Adobe-2.0 EPSF-2.0\n +# +# 32 33 PS +# +%!PS-Adobe-3.0\n +%!PS-Adobe-2.0\n +# +# 34 35 LanguageLevel +# +\%\%LanguageLevel: 3\n +\%\%LanguageLevel: 2\n +# +# 36 BoundingBox +# +\%\%BoundingBox: 0 0 +# +# 37 Pages +# +\%\%Pages: +# +# 38 PageOrder +# +\%\%PageOrder: Ascend\n +# +# 39 DocumentData +# +\%\%DocumentData: Clean7Bit\n +# +# 40 EndComments BeginProlog EndProlog +# +\%\%EndComments\n\%\%BeginProlog\n\%\%EndProlog\n +# +# 41 Trailer EOF +# +\%\%Trailer\n\%\%EOF\n +# +# 42 Page +# +\%\%Page: +# +# 43 44 begin dict +# + dict begin\n +end\n +# +# 45 showpage +# +showpage\n +# +# 46 0 0 moveto +# +0 0 moveto\n +# +# 47 0 +# +0 +# +# 48 1 setlinecap +# +1 setlinecap\n +# +# 49 white background fill color +# +1 setgray\n +# +# 50 +# + setmiterlimit\n +# +# 51-52 Begin and end setup +# +\%\%BeginSetup\n +\%\%EndSetup\n +# +# 53-54 Begin and end feature +# +\%\%BeginFeature: *PageSize BmppPage\n +\%\%EndFeature\n +# +# 55-56 Page size +# +<< /PageSize [ +] /ImagingBBox null >> setpagedevice\n +# +# 57-58 +# +\%\%BeginFeature: *Duplex DuplexNoTumble\n +<< /Duplex true /Tumble false >> setpagedevice\n +# +# 59-60 +# +\%\%BeginFeature: *Duplex DuplexTumble\n +<< /Duplex true /Tumble true >> setpagedevice\n +$!end +}; + + + +/** Write double value to page memory stream. + @param bptr Current page. + @param v Value to write. + @param backptr Address of success variable to reset on errors. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if os is NULL. + - 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, + - DK4_E_MATH_OVERFLOW<br> + if the exponent is out of range for integer values,<br> + - DK4_E_SYNTAX<br> + if input contains invalid characters. +*/ +static +void +dk4gra_eps_double_value( + dk4_gra_ps_page_t *bptr, + double v, + int *backptr, + dk4_er_t *erp + +) +{ +#if DK4_USE_ASSERT + assert(NULL != bptr); +#endif + dk4gratool_stream_double(bptr->memstrm, v, backptr, erp); +} + + + +/** Write a fixed keyword from dk4gra_eps_c8_kw to page memory stream. + @param bptr Current page. + @param i Index of keyword in array. + @param backptr Address of success variable to reset on errors. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if str is NULL or the stream is not opened for writing, + - 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. +*/ +static +void +dk4gra_eps_kw( + dk4_gra_ps_page_t *bptr, + size_t i, + int *backptr, + dk4_er_t *erp +) +{ +#if DK4_USE_ASSERT + assert(NULL != bptr); +#endif + dk4gratool_stream_string(bptr->memstrm, dk4gra_eps_c8_kw[i], backptr, erp); +} + + +/** Delete a PS/EPS page structure. + @param bptr Page structure to delete. +*/ +static +void +dk4gra_eps_page_delete( + dk4_gra_ps_page_t *bptr +) +{ + $? "+ dk4gra_eps_page_delete %d", TR_IPTR(bptr) +#if DK4_USE_ASSERT + assert(NULL != bptr); +#endif + if (NULL != bptr) { + /* + Release all resources + */ + if (NULL != bptr->memstrm) { $? ". close memory stream" + dk4stream_close(bptr->memstrm, NULL); + } + bptr->memstrm = NULL; + if (NULL != bptr->membuf) { $? ". close memory buffer" + dk4membuf_close(bptr->membuf); + } + bptr->membuf = NULL; + /* + Free memory for page structure itself + */ + dk4mem_free(bptr); + } + $? "- dk4gra_eps_page_delete" +} + + + +/** Create new page structure, allocated related resources. + @param pageno Page number of new page. + @param flags Page flags. + @param erp Error report, may be NULL. + @return Valid pointer to new page structure on success, NULL on error. + + Error codes: + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow when calculating the product of elsize and nelem, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + with mem.elsize and mem.nelem set if there is not enough memory + available. +*/ +static +dk4_gra_ps_page_t * +dk4gra_eps_page_new( + size_t pageno, + int flags, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *back = NULL; + size_t i = 0; /* Traverse patterns */ + int ok = 0; + $? "+ dk4gra_eps_page_new" + back = dk4mem_new(dk4_gra_ps_page_t,1,erp); + if (NULL != back) { + /* + Initialize all components + */ + dk4gratool_initialize_attributes(&(back->attr)); + back->membuf = NULL; + back->memstrm = NULL; + back->flags = flags; + for (i = 0; i < 22; i++) { + back->patu[i] = 0x00; + } + back->pageno = pageno; + back->spip = 0; + back->cont = 0; + /* + Allocate resources for memory buffer and stream + */ + back->membuf = dk4membuf_open(erp); + if (NULL != back->membuf) { + back->memstrm = dk4stream_open_membuf_writer(back->membuf, erp); + if (NULL != back->memstrm) { + ok = 1; + } + } + if (0 == ok) { + dk4gra_eps_page_delete(back); + back = NULL; + } + } + $? "- dk4gra_eps_page_new %d", TR_IPTR(back) + return back; +} + + + +/** Write several double values to page memory stream and add keyword. + @param bptr Current page. + @param da Array of double values. + @param szda Number of elements in array. + @param kwi Index of keyword to add. + @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, bptr or da or the current page or the page stream on the + current page is NULL, + - 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. + - DK4_E_MATH_OVERFLOW<br> + if the exponent in one of the double values is out of range for + integer values,<br> + - DK4_E_SYNTAX<br> + if the text representation of the double value + contains invalid characters. +*/ +static +void +dk4gra_eps_values_and_keyword( + dk4_gra_ps_page_t *bptr, + double *da, + size_t szda, + size_t kwi, + int *backptr, + dk4_er_t *erp +) +{ + size_t i; /* Traverse da */ + int back = 1; +#if DK4_USE_ASSERT + assert(NULL != bptr); + assert(NULL != da); + assert(0 < szda); +#endif + for (i = 0; i < szda; i++) { + if (0 != i) { + dk4gra_eps_kw(bptr, 3, &back, erp); + } + dk4gra_eps_double_value(bptr, da[i], &back, erp); + } + if (0 < kwi) { + dk4gra_eps_kw(bptr, kwi, &back, erp); + } + if ((NULL != backptr) && (0 == back)) { *backptr = 0; } +} + + + +/** Set new color if necessary. + @param bptr Current page. + @param p_col_active Currently active color. + @param p_col_requested Requested color. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if gra, bptr or da or the current page or the page stream on the + current page is NULL, + - 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. + - DK4_E_MATH_OVERFLOW<br> + if the exponent in one of the double values is out of range for + integer values,<br> + - DK4_E_SYNTAX<br> + if the text representation of the double value + contains invalid characters. +*/ +static +int +dk4gra_eps_set_color_if_necessary( + dk4_gra_ps_page_t *bptr, + dk4gra_col_t *p_col_active, + dk4gra_col_t *p_col_requested, + dk4_er_t *erp +) +{ + double val[4]; /* Color components */ + int back = 0; + $? "+ dk4gra_eps_set_color_if_necessary" +#if DK4_USE_ASSERT + assert(NULL != bptr); + assert(NULL != p_col_active); + assert(NULL != p_col_requested); +#endif + if (0 == dk4gratool_colors_differ(p_col_active, p_col_requested)) { + back = 1; + goto finished; + } + dk4mem_cpy(p_col_active, p_col_requested, sizeof(dk4gra_col_t), NULL); + switch (p_col_active->what) { + case DK4_GRA_COL_SPEC_CMYK : { + val[0] = p_col_active->data.cmyk.c; + val[1] = p_col_active->data.cmyk.m; + val[2] = p_col_active->data.cmyk.y; + val[3] = p_col_active->data.cmyk.k; + back = 1; + dk4gra_eps_values_and_keyword(bptr, val, 4, 5, &back, erp); + } break; + case DK4_GRA_COL_SPEC_RGB : { + val[0] = p_col_active->data.rgb.r; + val[1] = p_col_active->data.rgb.g; + val[2] = p_col_active->data.rgb.b; + back = 1; + dk4gra_eps_values_and_keyword(bptr, val, 3, 6, &back, erp); + } break; + case DK4_GRA_COL_SPEC_GRAY : { + val[0] = p_col_active->data.gray; + back = 1; + dk4gra_eps_values_and_keyword(bptr, val, 1, 7, &back, erp); + } break; + } + + finished: + $? "- dk4gra_eps_set_color_if_necessary %d", back + return back; +} + + + +/** Write dash setup. + @param bptr Current page in gra. + @param da Array of double values for stroke and gap lengths. + @param sz Number of elements in array. + @param offset Offset to start dash pattern. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if the contents stream of the current page + is NULL or the stream is not opened for writing, + - 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. + - DK4_E_MATH_OVERFLOW<br> + if the exponent of a doublevalue is out of range for integer values,<br> + - DK4_E_SYNTAX<br> + if a double value converted to string contains invalid characters. +*/ +static +int +dk4gra_eps_dash_out( + dk4_gra_ps_page_t *bptr, + double *da, + size_t sz, + double offset, + dk4_er_t *erp +) +{ + size_t i; /* Traverse dash length array da */ + int back = 1; + +#if DK4_USE_ASSERT + assert(NULL != bptr); + assert(NULL != da); + assert(0 < sz); +#endif + dk4gra_eps_kw(bptr, 9, &back, erp); + for (i = 0; i < sz; i++) { + if (0 != i) { + dk4gra_eps_kw(bptr, 3, &back, erp); + } + dk4gra_eps_double_value(bptr, da[i], &back, erp); + } + dk4gra_eps_kw(bptr, 10, &back, erp); + dk4gra_eps_kw(bptr, 3, &back, erp); + dk4gra_eps_double_value(bptr, offset, &back, erp); + dk4gra_eps_kw(bptr, 11, &back, erp); + return back; +} + + + +/** Put string to output file, on error set return code and error code. + @param fout Output file. + @param str String to write. + @param pret Address of return code variable. + @param erp Error report, may be NULL. + + Error codes: + - DK4_E_WRITE_FAILED<br> + if the write attempt failed. +*/ +static +void +dk4gra_eps_string_to_file( + FILE *fout, + const char *str, + int *pret, + dk4_er_t *erp +) +{ +#if DK4_USE_ASSERT + assert(NULL != fout); + assert(NULL != str); +#endif + if (EOF == fputs(str, fout)) { + *pret = 0; + dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); + } +} + + + +/** Construct path for page border. + @param fout Output file to write. + @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 arguments are invalid, + - DK4_E_BUFFER_TOO_SMALL<br> + if the destination buffer size is too small for the result, + - DK4_E_BUG<br> + if an internal buffer is too small (should not happen), + - DK4_E_WRITE_FAILED<br> + if the write attempt failed. +*/ +static +void +dk4gra_eps_page_border_path( + FILE *fout, + dk4_gra_t *gra, + int *backptr, + dk4_er_t *erp +) +{ + char b1[16*sizeof(dk4_um_t)]; /* Width as text */ + char b2[16*sizeof(dk4_um_t)]; /* Height as text */ +#if DK4_USE_ASSERT + assert(NULL != gra); + assert(NULL != fout); +#endif + (void)dk4ma_write_c8_decimal_unsigned(b1, sizeof(b1), gra->w, 0, erp); + (void)dk4ma_write_c8_decimal_unsigned(b2, sizeof(b2), gra->h, 0, erp); + /* 0 0 moveto */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[23], backptr, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[46], backptr, erp); + /* w 0 lineto */ + dk4gra_eps_string_to_file(fout, b1, backptr, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], backptr, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[47], backptr, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[25], backptr, erp); + /* w h lineto */ + dk4gra_eps_string_to_file(fout, b1, backptr, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], backptr, erp); + dk4gra_eps_string_to_file(fout, b2, backptr, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[25], backptr, erp); + /* 0 h lineto */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[47], backptr, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], backptr, erp); + dk4gra_eps_string_to_file(fout, b2, backptr, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[25], backptr, erp); + /* closepath */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[27], backptr, erp); +} + + +/** Write one page to output file. + @param fout Output file. + @param gra Output structure. + @param bptr Current page. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. +*/ +static +int +dk4gra_eps_one_page_to_file( + FILE *fout, + dk4_gra_t *gra, + dk4_gra_ps_page_t *bptr, + dk4_er_t *erp +) +{ + char b1[8*sizeof(dk4_um_t)]; /* Page no as text */ + char b2[8*sizeof(dk4_um_t)]; /* Pages number as text */ + const char * const *pproc; /* Pattern procedure name */ + size_t numpat = 0; /* Number of used pats */ + size_t i = 0; /* Traverse used pats */ + int back = 1; + +#if DK4_USE_ASSERT + assert(NULL != gra); + assert(NULL != fout); +#endif + /* %%Page: 1 1 + */ + if (0 != gra->out.ps.dsc) { + (void)dk4ma_write_c8_decimal_unsigned( + b1, sizeof(b1), (bptr->pageno + 1), 0, erp + ); + (void)dk4ma_write_c8_decimal_unsigned( + b2, sizeof(b2), gra->pages, 0, erp + ); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[42], &back, erp); + dk4gra_eps_string_to_file(fout, b1, &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], &back, erp); + dk4gra_eps_string_to_file(fout, b2, &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[0], &back, erp); + } + + /* Count number of used patterns. + */ + for (i = 0; i <= DK4_GRA_PATTERN_MAX; i++) { + if (0 != bptr->patu[i]) { numpat++; } + } + + /* xxx dict begin + */ + if (0 != numpat) { + (void)dk4ma_write_c8_decimal_unsigned(b1, sizeof(b1), numpat, 0, erp); + dk4gra_eps_string_to_file(fout, b1, &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[43], &back, erp); + for (i = 0; i <= DK4_GRA_PATTERN_MAX; i++) { + if (0 != bptr->patu[i]) { + pproc = dk4gra_eps_pattern_procedure(i); + while (NULL != *pproc) { + if (EOF == fputs(*(pproc++), fout)) { back = 0; } + if (EOF == fputc('\n', fout)) { back = 0; } + } + } + } + } + + /* gsave + */ + if (0 == bptr->spip) { + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[1], &back, erp); + } + + /* clip path + */ + if ( + (0 == ((bptr->flags) & DK4_GRA_PAGE_FLAG_NO_CLIP)) + && (0 == bptr->spip) + ) { + /* construct path */ + dk4gra_eps_page_border_path(fout, gra, &back, erp); + /* clip */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[21], &back, erp); + } + + /* white page background + */ + if ( + (0 == ((bptr->flags) & DK4_GRA_PAGE_FLAG_NO_BG)) + && (0 == bptr->spip) + ) { + /* white color */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[49], &back, erp); + bptr->attr.col_stroke_active.what = DK4_GRA_COL_SPEC_GRAY; + bptr->attr.col_stroke_active.data.gray = 1.0; + /* construct path */ + dk4gra_eps_page_border_path(fout, gra, &back, erp); + /* fill */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[18], &back, erp); + } + + /* page contents + */ + if (NULL != bptr->memstrm) { + if (0 == dk4stream_close(bptr->memstrm, erp)) { + back = 0; + } + bptr->memstrm = NULL; + } + if (NULL != bptr->membuf) { + if (0 == dk4membuf_to_file(fout, bptr->membuf, erp)) { + back = 0; + } + } + + /* grestore + */ + if (0 == bptr->spip) { + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[2], &back, erp); + } + + /* end + */ + if (0 != numpat) { + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[44], &back, erp); + } + + /* showpage + */ + if ((DK4_GRA_DRIVER_EPS != gra->dr) && (0 == bptr->spip)) { + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[45], &back, erp); + } + + return back; +} + + + +/** Write pattern instance. + @param bptr Current page. + @param da Array of values. + @param szda Size of da array (number of elements). + @param pname Pattern name. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. +*/ +static +int +dk4gra_eps_write_pattern_instance( + dk4_gra_ps_page_t *bptr, + const double *da, + size_t szda, + const char *pname, + dk4_er_t *erp +) +{ + size_t i; /* Traverse da array */ + int res; /* Operation result */ + int back = 1; +#if DK4_USE_ASSERT + assert(NULL != bptr); + assert(NULL != da); + assert(0 < szda); + assert(NULL != pname); +#endif + for (i = 0; i < szda; i++) { + if (0 != i) { + dk4gra_eps_kw(bptr, 3, &back, erp); + } + res = dk4ma_write_c8_double_no_sci_to_stream( + bptr->memstrm, *(da++), DK4_GRA_EPSILON_COORDINATES, 0, 1, erp + ); + if (0 == res) { back = 0; } + } + if (0 < i) { + dk4gra_eps_kw(bptr, 3, &back, erp); + } + res = dk4stream_write_char_string(bptr->memstrm, pname, erp); + if (0 == res) { back = 0; } + dk4gra_eps_kw(bptr, 0, &back, erp); + return back; +} + + + +/** Compare page structures by number or a page against a number. + @param l Left page object. + @param r Right page object or page number. + @param cr Comparison criteria (0=page/page, 1=page/number). + @return Comparison result. +*/ +static +int +dk4gra_eps_compare_pages_by_number(const void *l, const void *r, int cr) +{ + const dk4_gra_ps_page_t *pl; /* Left side object */ + const dk4_gra_ps_page_t *pr; /* Right side object */ + const size_t *ppno; /* Address of a page number */ + + int back = 0; + if (NULL != l) { + if (NULL != r) { + pl = (const dk4_gra_ps_page_t *)l; + switch (cr) { + case 1: { + ppno = (const size_t *)r; + if (pl->pageno > *ppno) { + back = 1; + } + else { + if (pl->pageno < *ppno) { + back = -1; + } + } + } break; + default : { + pr = (const dk4_gra_ps_page_t *)r; + if (pl->pageno > pr->pageno) { + back = 1; + } + else { + if (pl->pageno < pr->pageno) { + back = -1; + } + } + } break; + } + } + else { + back = 1; + } + } + else { + if (NULL != r) { + back = -1; + } + } + return back; +} + + + +/** Write PS/EPS contents to file. + @param fout File, opened for write access. + @param gra Output structure. + @param erp Error report, may be NULL. + + Error codes: + - DK4_E_WRITE_FAILED<br> + if the write attempt failed. + - DK4_E_FLUSH_FAILED<br> + if flushing data downwards failed, + - DK4_E_CLOSE_FAILED<br> + if closing downward data failed, + - DK4_E_BUFFER_TOO_SMALL<br> + if an internal buffer in this function is too small (should not happen). + - DK4_E_BUG<br> + if an internal buffer in dk4ma_write_c8_decimal_unsigned() + is too small (should not happen). +*/ +static +int +dk4gra_eps_file( + FILE *fout, + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + char b1[8*sizeof(dk4_um_t)]; /* Buffer for numbers */ + char b2[8*sizeof(dk4_um_t)]; /* Buffer for numbers */ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 1; + $? "+ dk4gra_eps_file" +#if DK4_USE_ASSERT + assert(NULL != gra); + assert(NULL != fout); +#endif + /* Document header + --------------- + */ + + /* %!PS-Adobe-2.0 (EPSF...) + */ + if (DK4_GRA_DRIVER_EPS == gra->dr) { + dk4gra_eps_string_to_file( + fout, dk4gra_eps_c8_kw[(3 == gra->out.ps.llev) ? (30) : (31)], + &back, erp + ); + } + else { + dk4gra_eps_string_to_file( + fout, dk4gra_eps_c8_kw[(3 == gra->out.ps.llev) ? (32) : (33)], + &back, erp + ); + } + + /* %%LanguageLevel + */ + dk4gra_eps_string_to_file( + fout, dk4gra_eps_c8_kw[(3 == gra->out.ps.llev) ? (34) : (35)], + &back, erp + ); + + /* %%BoundingBox + */ + (void)dk4ma_write_c8_decimal_unsigned(b1, sizeof(b1), gra->w, 0, erp); + (void)dk4ma_write_c8_decimal_unsigned(b2, sizeof(b2), gra->h, 0, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[36], &back, erp); + dk4gra_eps_string_to_file(fout, b1, &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], &back, erp); + dk4gra_eps_string_to_file(fout, b2, &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[0], &back, erp); + + + if (0 != gra->out.ps.dsc) { + + /* %%Title -- ignored + */ + + /* %%Creator -- ignored + */ + + /* %%CreationDate -- ignored + */ + + /* %%Pages + */ + (void)dk4ma_write_c8_decimal_unsigned( + b1, sizeof(b1), gra->pages, 0, erp + ); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[37], &back, erp); + dk4gra_eps_string_to_file(fout, b1, &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[0], &back, erp); + + + /* %%PageOrder + */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[38], &back, erp); + + /* %%DocumentData + */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[39], &back, erp); + + /* %%EndComments BeginProlog EndProlog + */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[40], &back, erp); + + /* Page setup for PS documents + */ + if (DK4_GRA_DRIVER_PS == gra->dr) { + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[51], &back, erp); + /* + Paper size + */ + (void)dk4ma_write_c8_decimal_unsigned(b1,sizeof(b1),gra->w,0,erp); + (void)dk4ma_write_c8_decimal_unsigned(b2,sizeof(b2),gra->h,0,erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[53], &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[55], &back, erp); + dk4gra_eps_string_to_file(fout, b1, &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[3], &back, erp); + dk4gra_eps_string_to_file(fout, b2, &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[56], &back, erp); + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[54], &back, erp); + /* + Duplex (and tumble) + */ + if (0 != (DK4_GRA_DOC_FLAG_TUMBLE & (gra->docfl))) { + dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[59],&back,erp); + dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[60],&back,erp); + dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[54],&back,erp); + } + else { + if (0 != (DK4_GRA_DOC_FLAG_DUPLEX & (gra->docfl))) { + dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[57],&back,erp); + dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[58],&back,erp); + dk4gra_eps_string_to_file(fout,dk4gra_eps_c8_kw[54],&back,erp); + } + } + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[52], &back, erp); + } + + } + + /* Pages + ----- + */ + dk4sto_it_reset(gra->i_pages); + do { + bptr = (dk4_gra_ps_page_t *)dk4sto_it_next(gra->i_pages); + if (NULL != bptr) { + if (0 == dk4gra_eps_one_page_to_file(fout, gra, bptr, erp)) { + back = 0; + } + } + } while (NULL != bptr); + + + /* Document trailer + ---------------- + */ + + if (0 != gra->out.ps.dsc) { + /* %%Trailer %%EOF + */ + dk4gra_eps_string_to_file(fout, dk4gra_eps_c8_kw[41], &back, erp); + } + + /* Ctrl-D + */ + if (DK4_GRA_DRIVER_PS == gra->dr) { + if (EOF == fputc(0x04, fout)) { + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); + } + } + + $? "- dk4gra_eps_file %d", back + return back; +} + + + +void +dk4gra_eps_close( + dk4_gra_t *gra +) +{ + dk4_gra_ps_page_t *bptr; /* Current page to release */ + + $? "+ dk4gra_eps_close" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + if (NULL == gra) { + goto finished; + } + if (NULL != gra->s_pages) { + if (NULL != gra->i_pages) { + dk4sto_it_reset(gra->i_pages); + do { + bptr = (dk4_gra_ps_page_t *)dk4sto_it_next(gra->i_pages); + if (NULL != bptr) { + dk4gra_eps_page_delete(bptr); + } + } while (NULL != bptr); + dk4sto_it_close(gra->i_pages); + gra->i_pages = NULL; + } + dk4sto_close(gra->s_pages); + gra->s_pages = NULL; + } + dk4gratool_close(gra); + + finished: + $? "- dk4gra_eps_close" + return; +} + + + +dk4_gra_t * +dk4gra_eps_open( + const dkChar *fn, + size_t w, + size_t h, + int docfl, + dk4_er_t *erp +) +{ + dk4_gra_t *back = NULL; + int ok = 0; + $? "+ dk4gra_eps_open_ps" +#if DK4_USE_ASSERT + assert(NULL != fn); +#endif + + /* Open output structure, set up default components + */ + back = dk4gratool_open(fn, w, h, docfl, erp); + if (NULL == back) { + goto finished; + } + + /* Set driver + */ + if (0 != (DK4_GRA_DOC_FLAG_EPS & docfl)) { + back->dr = DK4_GRA_DRIVER_EPS; + } + else { + back->dr = DK4_GRA_DRIVER_PS; + } + if (0 != (DK4_GRA_DOC_FLAG_PS_DSC & docfl)) { + back->out.ps.dsc = 1; + } + if (0 != (DK4_GRA_DOC_FLAG_PS2 & docfl)) { + back->out.ps.llev = 2; + } + else { + back->out.ps.llev = 3; + } + back->out.ps.fspd = 0; + back->out.ps.fdu = 0; + back->out.ps.ftu = 0; + + /* Set up container and iterator for pages + */ + back->s_pages = dk4sto_open(erp); + if (NULL == back->s_pages) { + goto finished; + } + (void)dk4sto_set_comp(back->s_pages, dk4gra_eps_compare_pages_by_number, 0); + back->i_pages = dk4sto_it_open(back->s_pages, erp); + if (NULL == back->i_pages) { + goto finished; + } + + /* Indicate success to cleanup section + */ + ok = 1; + + /* End of function, clean up if not successful + */ + finished: + if ((NULL != back) && (0 == ok)) { + dk4gra_eps_close(back); + back = NULL; + } + $? "- dk4gra_eps_open_ps %d", TR_IPTR(back) + return back; +} + + + +int +dk4gra_eps_write_file_and_close( + FILE *fout, + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + int back = 0; + $? "+ dk4gra_eps_write_file_and_close" +#if DK4_USE_ASSERT + assert(NULL != gra); + assert(NULL != fout); +#endif + back = dk4gra_eps_file(fout, gra, erp); + dk4gra_eps_close(gra); + $? "- dk4gra_eps_write_file_and_close %d", back + return back; +} + + + +int +dk4gra_eps_page( + dk4_gra_t *gra, + int flags, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *curpg; /* New current page */ + int back = 0; + $? "+ dk4gra_eps_page" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + /* + Check number of pages already defined + */ + if (SIZE_MAX == gra->pages) { + dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); + goto finished; + } + if ((DK4_GRA_DRIVER_EPS == gra->dr) && (0 != gra->pages)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + /* Create new page and add to containter and mark as current page + */ + curpg = dk4gra_eps_page_new(gra->pages, flags, erp); + if (NULL == curpg) { + goto finished; + } + /* Add new page to pages container + */ + if (0 == dk4sto_add(gra->s_pages, curpg, erp)) { + dk4gra_eps_page_delete(curpg); + goto finished; + } + /* Set new page as current page, indicate success + */ + gra->curpg = curpg; + gra->pages += 1; + back = 1; + + finished: + $? "- dk4gra_eps_page %d", back + return back; +} + + + +int +dk4gra_eps_gsave( + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_gsave" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + back = 1; + dk4gra_eps_kw(bptr, 1, &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_gsave %d", back + return back; +} + + + +int +dk4gra_eps_grestore( + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_grestore" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + back = 1; + dk4gra_eps_kw(bptr, 2, &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_grestore %d", back + return back; +} + + + +int +dk4gra_eps_set_line_width( + dk4_gra_t *gra, + double lw, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_line_width" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + bptr->attr.lw_requested = lw; + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_line_width %d", back + return back; +} + + + +int +dk4gra_eps_set_line_style( + dk4_gra_t *gra, + int ls, + double sv, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_line_style" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + bptr->attr.ls_requested = ls; + bptr->attr.sv_requested = sv; + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_line_style %d", back + return back; +} + + + +int +dk4gra_eps_set_line_cap( + dk4_gra_t *gra, + int lc, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_line_cap" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + bptr->attr.lc_requested = lc; + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_line_cap %d", back + return back; +} + + + +int +dk4gra_eps_set_line_join( + dk4_gra_t *gra, + int lj, + double ml, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_line_join" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + bptr->attr.lj_requested = lj; + bptr->attr.ml_requested = ml; + back = 1; + if (1.0 > bptr->attr.ml_requested) { + bptr->attr.ml_requested = 1.0; + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_line_join %d", back + return back; +} + + + +int +dk4gra_eps_set_fill_gray( + dk4_gra_t *gra, + double g, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_fill_gray %g", g +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + dk4gratool_set_color_requested( + &(bptr->attr.col_fill_requested), + DK4_GRA_COL_SPEC_GRAY, g, 0.0, 0.0, 0.0 + ); + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_fill_gray %d", back + return back; +} + + + +int +dk4gra_eps_set_fill_rgb( + dk4_gra_t *gra, + double r, + double g, + double b, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_fill_rgb %g %g %g", r, g, b +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + dk4gratool_set_color_requested( + &(bptr->attr.col_fill_requested), + DK4_GRA_COL_SPEC_RGB, r, g, b, 0.0 + ); + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_fill_rgb %d", back + return back; +} + + + +int +dk4gra_eps_set_fill_cmyk( + dk4_gra_t *gra, + double c, + double m, + double y, + double k, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_fill_cmyk %g %g %g %g", c, m, y, k +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + dk4gratool_set_color_requested( + &(bptr->attr.col_fill_requested), + DK4_GRA_COL_SPEC_CMYK, c, m, y, k + ); + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_fill_cmyk %d", back + return back; +} + + + +int +dk4gra_eps_set_stroke_gray( + dk4_gra_t *gra, + double g, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_stroke_gray %g", g +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + dk4gratool_set_color_requested( + &(bptr->attr.col_stroke_requested), + DK4_GRA_COL_SPEC_GRAY, g, 0.0, 0.0, 0.0 + ); + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_stroke_gray %d", back + return back; +} + + + +int +dk4gra_eps_set_stroke_rgb( + dk4_gra_t *gra, + double r, + double g, + double b, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_stroke_rgb %g %g %g", r, g, b +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + dk4gratool_set_color_requested( + &(bptr->attr.col_stroke_requested), + DK4_GRA_COL_SPEC_RGB, r, g, b, 0.0 + ); + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_stroke_rgb %d", back + return back; +} + + + +int +dk4gra_eps_set_stroke_cmyk( + dk4_gra_t *gra, + double c, + double m, + double y, + double k, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_set_stroke_cmyk %g %g %g %g", c, m, y, k +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + dk4gratool_set_color_requested( + &(bptr->attr.col_stroke_requested), + DK4_GRA_COL_SPEC_CMYK, c, m, y, k + ); + back = 1; + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_set_stroke_cmyk %d", back + return back; +} + + + +int +dk4gra_eps_prepare_fill( + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_prepare_fill" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + /* + Fill color + */ + back = dk4gra_eps_set_color_if_necessary( + bptr, + &(bptr->attr.col_stroke_active), &(bptr->attr.col_fill_requested), + erp + ); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_prepare_fill %d", back + return back; +} + + + +int +dk4gra_eps_prepare_stroke( + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + double da[8]; /* Dash array */ + dk4_gra_ps_page_t *bptr; /* Current page */ + double gw; /* Gap width */ + size_t lci; /* Line cap index */ + int res; /* Operation result */ + int back = 0; /* Function result */ + int lwc = 0; /* Flag: Line width was changed */ + $? "+ dk4gra_eps_prepare_stroke" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + /* Stroke color + */ + back = dk4gra_eps_set_color_if_necessary( + bptr, + &(bptr->attr.col_stroke_active), &(bptr->attr.col_stroke_requested), + erp + ); + /* Line width + */ + if ( + DK4_GRA_EPSILON_LINEWIDTH + < fabs(bptr->attr.lw_active - bptr->attr.lw_requested) + ) { + dk4gra_eps_double_value(bptr, bptr->attr.lw_requested, &back, erp); + dk4gra_eps_kw(bptr, 4, &back, erp); + lwc = 1; + bptr->attr.lw_active = bptr->attr.lw_requested; + } + /* Line style + */ + res = dk4gratool_line_style_differs( + bptr->attr.ls_active, bptr->attr.ls_requested, + bptr->attr.sv_active, bptr->attr.sv_requested, + lwc + ); + if (0 != res) { + bptr->attr.ls_active = bptr->attr.ls_requested; + bptr->attr.sv_active = bptr->attr.sv_requested; + gw = (bptr->attr.sv_active + bptr->attr.lw_active) / 2.0; + if ((2.0 * bptr->attr.lw_active) < gw) { + gw = 2.0 * bptr->attr.lw_active; + } + switch (bptr->attr.lc_requested) { + case DK4_GRA_LC_ROUNDED : case DK4_GRA_LC_PROJECTING : { + gw += bptr->attr.lw_requested; + } break; + } + switch (bptr->attr.ls_active) { + case DK4_GRA_LS_DASH : { + da[0] = bptr->attr.sv_active; + da[1] = gw; + res = dk4gra_eps_dash_out( + bptr, da, 2, (bptr->attr.sv_active / 2.0), erp + ); + if (0 == res) { back = 0; } + } break; + case DK4_GRA_LS_DOT : { + da[0] = da[1] = bptr->attr.lw_active; + res = dk4gra_eps_dash_out(bptr, da, 2, 0.0, erp); + if (0 == res) { back = 0; } + } break; + case DK4_GRA_LS_DASH_DOT : { + da[0] = bptr->attr.sv_active; + da[1] = gw; + da[2] = bptr->attr.lw_active; + da[3] = gw; + res = dk4gra_eps_dash_out( + bptr, da, 4, (bptr->attr.sv_active / 2.0), erp + ); + if (0 == res) { back = 0; } + } break; + case DK4_GRA_LS_DASH_DOT_DOT : { + da[0] = bptr->attr.sv_active; + da[1] = gw; + da[2] = bptr->attr.lw_active; + da[3] = gw; + da[4] = bptr->attr.lw_active; + da[5] = gw; + res = dk4gra_eps_dash_out( + bptr, da, 6, (bptr->attr.sv_active / 2.0), erp + ); + if (0 == res) { back = 0; } + } break; + case DK4_GRA_LS_DASH_DOT_DOT_DOT : { + da[0] = bptr->attr.sv_active; + da[1] = gw; + da[2] = bptr->attr.lw_active; + da[3] = gw; + da[4] = bptr->attr.lw_active; + da[5] = gw; + da[6] = bptr->attr.lw_active; + da[7] = gw; + res = dk4gra_eps_dash_out( + bptr, da, 8, (bptr->attr.sv_active / 2.0), erp + ); + if (0 == res) { back = 0; } + } break; + default : { + dk4gra_eps_kw(bptr, 8, &back, erp); + } break; + } + } + /* Line cap + */ + if (bptr->attr.lc_active != bptr->attr.lc_requested) { + bptr->attr.lc_active = bptr->attr.lc_requested; + switch (bptr->attr.lc_active) { + case DK4_GRA_LC_ROUNDED : { + lci = 13; + } break; + case DK4_GRA_LC_PROJECTING : { + lci = 14; + } break; + default : { + lci = 12; + } break; + } + dk4gra_eps_kw(bptr, lci, &back, erp); + } + /* Line join + */ + if (bptr->attr.lj_active != bptr->attr.lj_requested) { + bptr->attr.lj_active = bptr->attr.lj_requested; + switch (bptr->attr.lj_active) { + case DK4_GRA_LJ_ROUNDED : { + lci = 16; + } break; + case DK4_GRA_LJ_BEVELED : { + lci = 17; + } break; + default : { + lci = 15; + } break; + } + dk4gra_eps_kw(bptr, lci, &back, erp); + } + /* Miter limit, only if line join is mitered + */ + if (DK4_GRA_LJ_MITERED == bptr->attr.lj_active) { + if ( + DK4_GRA_EPSILON_MITERLIMIT + < fabs(bptr->attr.ml_active - bptr->attr.ml_requested) + ) { + dk4gra_eps_values_and_keyword( + bptr, &(bptr->attr.ml_requested), 1, 50, &back, erp + ); + bptr->attr.ml_active = bptr->attr.ml_requested; + } + } + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_prepare_stroke %d", back + return back; +} + + + +int +dk4gra_eps_fill( + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_fill" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + back = 1; + dk4gra_eps_kw(bptr, ((0 != gra->eor) ? (19) : (18)), &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_fill %d", back + return back; +} + + + +int +dk4gra_eps_stroke( + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_stroke" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + back = 1; + dk4gra_eps_kw(bptr, 20, &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_stroke %d", back + return back; +} + + + +int +dk4gra_eps_clip( + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_clip" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + back = 1; + dk4gra_eps_kw(bptr, ((0 != gra->eor) ? (22) : (21)), &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_clip %d", back + return back; +} + + + +int +dk4gra_eps_pattern( + dk4_gra_t *gra, + int pn, + double *xval, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + const char *pname; /* Pattern name */ + int back = 0; + int res; /* Operation result */ + $? "+ dk4gra_eps_pattern" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + if ((0 > pn) || (DK4_GRA_PATTERN_MAX < pn)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + pname = dk4gra_eps_pattern_name(pn); + if (NULL == pname) { + dk4error_set_simple_error_code(erp, DK4_E_BUG); + goto finished; + } + bptr->patu[pn] = 0x01; + + back = 1; + + switch (pn) { + case DK4_GRA_PATTERN_30_DEGREE_RIGHT : { + /* ys = yb - (xe - xs) / sqrt(3) */ + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_30_DEGREE_SIEVE : { + /* ys = yb - (xe - xs) / sqrt(3) */ + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_45_DEGREE_LEFT : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_45_DEGREE_RIGHT : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_45_DEGREE_SIEVE : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_HORIZONTAL_BRICKS : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_VERTICAL_BRICKS : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_HORIZONTAL_LINES : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_VERTICAL_LINES : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_HORIZONTAL_VERTICAL_SIEVE : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_LEFT : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_RIGHT : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_VERTICAL_SHINGLES_1 : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_VERTICAL_SHINGLES_2 : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_LARGE_FISH_SCALES : { + /* xs xe ys ye dx dy r a1 a2 */ + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 9, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_SMALL_FISH_SCALES : { + /* xs xe ys ye dx dy r a1 a2 */ + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 9, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_CIRCLES : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_HEXAGONS : { + /* xs xe ys ye dx dy */ + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 6, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_OCTAGONS : { + /* xs xe ys ye dx co */ + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 6, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_HORIZONTAL_TIRES : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + case DK4_GRA_PATTERN_VERTICAL_TIRES : { + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + /* DK4_GRA_PATTERN_30_DEGREE_LEFT */ + default : { + /* ys = yb - (xe - xs) / sqrt(3) */ + res = dk4gra_eps_write_pattern_instance( + bptr, xval, 5, pname, erp + ); if (0 == res) { back = 0; } + } break; + } + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_pattern %d", back + return back; +} + + + +int +dk4gra_eps_newpath_moveto( + dk4_gra_t *gra, + double x, + double y, + dk4_er_t *erp +) +{ + double val[4]; /* Array for function call */ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_newpath_moveto" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + $? ". PS: %g %g moveto", x, y + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + back = 1; + dk4gra_eps_kw(bptr, 23, &back, erp); + val[0] = x; val[1] = y; + dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_newpath_moveto %d", back + return back; +} + + + +int +dk4gra_eps_lineto( + dk4_gra_t *gra, + double x, + double y, + dk4_er_t *erp +) +{ + double val[4]; /* Array for function call */ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_lineto" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + $? ". PS: %g %g lineto", x, y + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + val[0] = x; val[1] = y; + back = 1; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_lineto %d", back + return back; +} + + + +int +dk4gra_eps_curveto( + dk4_gra_t *gra, + double xc1, + double yc1, + double xc2, + double yc2, + double x, + double y, + dk4_er_t *erp +) +{ + double val[8]; /* Array for function call */ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_curveto" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + $? ". PS: %g %g %g %g %g %g curveto", xc1, yc1, xc2, yc2, x, y + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + val[0] = xc1; val[1] = yc1; val[2] = xc2; val[3] = yc2; + val[4] = x; val[5] = y; + back = 1; + dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_curveto %d", back + return back; +} + + + +int +dk4gra_eps_closepath( + dk4_gra_t *gra, + dk4_er_t *erp +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_closepath" +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + $? ". PS: closepath" + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + back = 1; + dk4gra_eps_kw(bptr, 27, &back, erp); + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_closepath %d", back + return back; +} + + + +int +dk4gra_eps_circle( + dk4_gra_t *gra, + double xc, + double yc, + double r, + dk4_er_t *erp +) +{ + double val[8]; /* Array for function call */ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_circle x=%g y=%g r=%g", xc, yc, r +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + back = 1; + dk4gra_eps_kw(bptr, 23, &back, erp); + val[0] = xc + r; + val[1] = yc; + dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp); + val[0] = xc; val[1] = yc; val[2] = r; + dk4gra_eps_values_and_keyword(bptr, val, 3, 28, &back, erp); + bptr->cont = 1; + + finished: + $? "-dk4gra_eps_circle %d", back + return back; +} + + + +int +dk4gra_eps_rectangle( + dk4_gra_t *gra, + double xl, + double xr, + double yb, + double yt, + double r, + dk4_er_t *erp +) +{ + double val[8]; /* Array for function call */ + dk4_gra_ps_page_t *bptr; /* Current page */ + int back = 0; + $? "+ dk4gra_eps_rectangle x=%g %g y=%g %g r=%g", xl, xr, yb, yt, r +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + + /* Correct radius if necessary + */ + back = 1; + + /* Output + */ + dk4gra_eps_kw(bptr, 23, &back, erp); + if (0.0 < r) { + val[0] = xl + r; + val[1] = yb; + dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp); + val[0] = xr - r; + val[1] = yb; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + val[0] = xr - (1.0 - KAPPA_4) * r; + val[1] = yb; + val[2] = xr; + val[3] = yb + (1.0 - KAPPA_4) * r; + val[4] = xr; + val[5] = yb + r; + dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp); + val[0] = xr; + val[1] = yt - r; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + val[0] = xr; + val[1] = yt - (1.0 - KAPPA_4) * r; + val[2] = xr - (1.0 - KAPPA_4) * r; + val[3] = yt; + val[4] = xr - r; + val[5] = yt; + dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp); + val[0] = xl + r; + val[1] = yt; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + val[0] = xl + (1.0 - KAPPA_4) * r; + val[1] = yt; + val[2] = xl; + val[3] = yt - (1.0 - KAPPA_4) * r; + val[4] = xl; + val[5] = yt - r; + dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp); + val[0] = xl; + val[1] = yb + r; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + val[0] = xl; + val[1] = yb + (1.0 - KAPPA_4) * r; + val[2] = xl + (1.0 - KAPPA_4) * r; + val[3] = yb; + val[4] = xl + r; + val[5] = yb; + dk4gra_eps_values_and_keyword(bptr, val, 6, 26, &back, erp); + dk4gra_eps_kw(bptr, 27, &back, erp); + } + else { + val[0] = xl; val[1] = yb; + dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp); + val[0] = xr; val[1] = yb; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + val[0] = xr; val[1] = yt; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + val[0] = xl; val[1] = yt; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + dk4gra_eps_kw(bptr, 27, &back, erp); + } + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_rectangle %d", back + return back; +} + + + +int +dk4gra_eps_arc( + dk4_gra_t *gra, + double xc, + double yc, + double ra, + double start, + double end, + int cl, + dk4_er_t *erp +) +{ + double val[8]; /* Array for function call */ + dk4_gra_ps_page_t *bptr; /* Current page */ + double xstart; /* Start X coordinate */ + double ystart; /* Start Y coordinate */ + int back = 0; + $? "+ dk4gra_eps_arc x=%g y=%g r=%g a=%g b=%g cl=%d",xc,yc,ra,start,end,cl +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + if ((NULL == bptr->memstrm) || (0 != bptr->spip)) { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + goto finished; + } + xstart = (M_PI * start) / 180.0; + ystart = xstart; + xstart = xc + ra * cos(xstart); + ystart = yc + ra * sin(ystart); + back = 1; + dk4gra_eps_kw(bptr, 23, &back, erp); + val[0] = xstart; val[1] = ystart; + dk4gra_eps_values_and_keyword(bptr, val, 2, 24, &back, erp); + val[0] = xc; val[1] = yc; val[2] = ra; val[3] = start; val[4] = end; + dk4gra_eps_values_and_keyword(bptr, val, 5, 29, &back, erp); + if (0 != cl) { + val[0] = xc; val[1] = yc; + dk4gra_eps_values_and_keyword(bptr, val, 2, 25, &back, erp); + dk4gra_eps_kw(bptr, 27, &back, erp); + } + bptr->cont = 1; + + finished: + $? "- dk4gra_eps_arc %d", back + return back; +} + + + +void +dk4gra_eps_save_attributes( + dk4_gra_t *gra +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + dk4mem_cpy( + &(bptr->catt), + &(bptr->attr), + sizeof(dk4gra_attributes_t), + NULL + ); +} + + + +void +dk4gra_eps_restore_attributes( + dk4_gra_t *gra +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + dk4mem_cpy( + &(bptr->attr), + &(bptr->catt), + sizeof(dk4gra_attributes_t), + NULL + ); +} + + + +void +dk4gra_eps_reset_attributes( + dk4_gra_t *gra +) +{ + dk4_gra_ps_page_t *bptr; /* Current page */ +#if DK4_USE_ASSERT + assert(NULL != gra); +#endif + bptr = (dk4_gra_ps_page_t *)(gra->curpg); + dk4gratool_reset_active_attributes(&(bptr->attr)); +} + +/* vim: set ai sw=4 ts=4 : */ |