PaStiX Handbook  6.2.1
symbol_draw.c
Go to the documentation of this file.
1 /**
2  *
3  * @file symbol_draw.c
4  *
5  * PaStiX symbol structure drawing function.
6  *
7  * @copyright 2004-2021 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8  * Univ. Bordeaux. All rights reserved.
9  *
10  * @version 6.2.0
11  * @author Francois Pellegrini
12  * @author Gregoire Pichon
13  * @author Mathieu Faverge
14  * @date 2021-01-03
15  *
16  **/
17 #include <time.h>
18 #include "common.h"
19 #include "symbol/symbol.h"
20 
21 /**
22  * @addtogroup symbol_dev_draw
23  * @{
24  *
25  */
26 
27 /**
28  * @name PostScript parameter
29  * @{
30  * PostScript (tm) output definitions.
31  */
32 
33 /**
34  * @brief PostScript dots-per-inch
35  */
36 #define SYMBOL_PSDPI 72
37 /**
38  * @brief PostScript picture size (in inches)
39  */
40 #define SYMBOL_PSPICTSIZE 6.6
41 
42 /**
43  * @}
44  */
45 
46 /**
47  * @brief Predefined set of colors
48  */
49 static float symbolDrawColorTab[16][3] = {
50  { 1.00, 0.00, 0.00 }, /* Red */
51  { 0.00, 1.00, 0.00 }, /* Green */
52  { 1.00, 1.00, 0.00 }, /* Yellow */
53  { 0.00, 0.00, 1.00 }, /* Blue */
54  { 1.00, 0.00, 1.00 }, /* Magenta */
55  { 0.00, 1.00, 1.00 }, /* Cyan */
56  { 1.00, 0.50, 0.20 }, /* Orange */
57  { 0.30, 0.55, 0.00 }, /* Olive */
58  { 0.72, 0.47, 0.47 }, /* Dark pink */
59  { 0.33, 0.33, 0.81 }, /* Sea blue */
60  { 1.00, 0.63, 0.63 }, /* Pink */
61  { 0.62, 0.44, 0.65 }, /* Violet */
62  { 0.60, 0.80, 0.70 }, /* Pale green */
63  { 0.47, 0.20, 0.00 }, /* Brown */
64  { 0.00, 0.68, 0.68 }, /* Turquoise */
65  { 0.81, 0.00, 0.40 } }; /* Purple */
66 
67 /**
68  *******************************************************************************
69  *
70  * @brief Return one of 16 predefined, visually distinct distinct colors.
71  *
72  *******************************************************************************
73  *
74  * @param[in] labl
75  * The label of the color
76  *
77  * @param[inout] color
78  * The color array in which is returned the selected color.
79  *
80  *******************************************************************************/
81 void
82 pastixSymbolDrawColor ( const pastix_int_t labl,
83  float color[] )
84 {
85  color[0] = (float) symbolDrawColorTab[(labl - 1) % 16][0];
86  color[1] = (float) symbolDrawColorTab[(labl - 1) % 16][1];
87  color[2] = (float) symbolDrawColorTab[(labl - 1) % 16][2];
88 }
89 
90 /**
91  *******************************************************************************
92  *
93  * @brief Export the symbol structure in a PostScript format.
94  *
95  * This routine writes to the given stream a PostScript (tm) picture of the
96  * symbolic block matrix.
97  *
98  *******************************************************************************
99  *
100  * @param[in] symbptr
101  * The pointer to the symbolic structure to draw.
102  *
103  * @param[in] diagfunc
104  * Personal function to draw the diagonal block. NULL by default
105  *
106  * @param[in] offdfunc
107  * Personal function to draw the off-diagonal blocks. NULL by default
108  *
109  * @param[in] dataptr
110  * Data structure for block coloring
111  *
112  * @param[inout] stream
113  * The stream where to write the output.
114  *
115  *******************************************************************************
116  *
117  * @retval 0 on success
118  * @retval -1 on error
119  *
120  *******************************************************************************/
121 int
123  const symbol_matrix_t * const symbptr,
124  int (* diagfunc) (const symbol_matrix_t * const, const symbol_blok_t * const, void * const, float * const),
125  int (* offdfunc) (const symbol_matrix_t * const, const symbol_blok_t * const, void * const, float * const),
126  void * const dataptr, /* Data structure for block coloring */
127  FILE * const stream)
128 {
129  pastix_int_t cblknum; /* Number of current column block */
130  pastix_int_t bloknum; /* Number of current block */
131  time_t picttime; /* Creation time */
132  double pictsize; /* Number of distinct coordinates */
133  int o;
134 
135  time (&picttime); /* Get current time */
136  pictsize = (double) (symbptr->nodenbr + 1); /* Get matrix size */
137 
138  fprintf (stream, "%%!PS-Adobe-2.0 EPSF-2.0\n"); /* Write header */
139  fprintf (stream, "%%%%Title: pastixSymbolmatrix (%ld,%ld,%ld)\n",
140  (long) symbptr->cblknbr, (long) symbptr->bloknbr, (long)symbptr->nodenbr);
141  fprintf (stream, "%%%%Creator: pastixSymbolDraw (LaBRI, Universite Bordeaux I)\n");
142  fprintf (stream, "%%%%CreationDate: %s", ctime (&picttime));
143  fprintf (stream, "%%%%BoundingBox: 0 0 %ld %ld\n",
144  (long) (SYMBOL_PSPICTSIZE * SYMBOL_PSDPI),
145  (long) (SYMBOL_PSPICTSIZE * SYMBOL_PSDPI));
146  fprintf (stream, "%%%%Pages: 0\n");
147  fprintf (stream, "%%%%EndComments\n"); /* Write shortcuts */
148  fprintf (stream, "/c { 4 2 roll pop pop newpath 2 copy 2 copy moveto dup lineto dup lineto closepath fill } bind def\n");
149  fprintf (stream, "/b { 4 copy 2 index exch moveto lineto dup 3 index lineto exch lineto closepath fill pop } bind def\n");
150  fprintf (stream, "/r { setrgbcolor } bind def\n");
151  fprintf (stream, "/g { setgray } bind def\n");
152 
153  fprintf (stream, "gsave\n"); /* Save context */
154  fprintf (stream, "0 setlinecap\n"); /* Use miter caps */
155  fprintf (stream, "%f dup scale\n", /* Print scaling factor */
156  (double) SYMBOL_PSDPI * SYMBOL_PSPICTSIZE / pictsize);
157  fprintf (stream, "[ 1 0 0 -1 0 %d ] concat\n", /* Reverse Y coordinate */
158  (int) (symbptr->nodenbr + 1));
159 
160  fprintf (stream, "0 0\n"); /* Output fake column block */
161  for (cblknum = 0, bloknum = 0; cblknum < symbptr->cblknbr; cblknum ++) {
162  float coloval[3]; /* Color of diagonal block and previous color */
163  pastix_int_t blokend; /* Number of end block for column */
164 
165  coloval[0] =
166  coloval[1] =
167  coloval[2] = 0.5;
168  if (diagfunc != NULL) /* Always display diagonal blocks */
169  diagfunc (symbptr, &symbptr->bloktab[bloknum], dataptr, coloval);
170  if ((coloval[0] == coloval[1]) &&
171  (coloval[1] == coloval[2]))
172  fprintf (stream, "%.2g g ",
173  (float) coloval[0]);
174  else
175  fprintf (stream, "%.2g %.2g %.2g r \n",
176  (float) coloval[0], (float) coloval[1], (float) coloval[2]);
177 
178  fprintf (stream, "%ld\t%ld\tc\n", /* Begin new column block */
179  (long) (symbptr->cblktab[cblknum].fcolnum - symbptr->baseval),
180  (long) (symbptr->cblktab[cblknum].lcolnum - symbptr->baseval + 1));
181 
182  for (bloknum ++, blokend = symbptr->cblktab[cblknum + 1].bloknum; /* Skip diagonal block */
183  bloknum < blokend; bloknum ++) {
184  float colbval[3]; /* Color of off-diagonal block */
185 
186  colbval[0] =
187  colbval[1] =
188  colbval[2] = 0.0;
189  if ((offdfunc == NULL) || (offdfunc (symbptr, &symbptr->bloktab[bloknum], dataptr, colbval) != 0)) { /* If block is kept */
190  if ((coloval[0] != colbval[0]) || /* If change with respect to previous color */
191  (coloval[1] != colbval[1]) ||
192  (coloval[2] != colbval[2])) {
193  coloval[0] = colbval[0]; /* Save new color data */
194  coloval[1] = colbval[1];
195  coloval[2] = colbval[2];
196 
197  if ((coloval[0] == coloval[1]) &&
198  (coloval[1] == coloval[2]))
199  fprintf (stream, "%.2g g ",
200  (float) coloval[0]);
201  else
202  fprintf (stream, "%.2g %.2g %.2g r \n",
203  (float) coloval[0], (float) coloval[1], (float) coloval[2]);
204  }
205 
206  fprintf (stream, "%ld\t%ld\tb\n", /* Write block in column block */
207  (long) (symbptr->bloktab[bloknum].frownum - symbptr->baseval),
208  (long) (symbptr->bloktab[bloknum].lrownum - symbptr->baseval + 1));
209  }
210  }
211  }
212  fprintf (stream, "pop pop\n"); /* Purge last column block indexes */
213  o = fprintf (stream, "grestore\nshowpage\n"); /* Restore context */
214 
215  return ((o != EOF) ? 0 : 1);
216 }
217 
218 /**
219  * @}
220  */
221 
222 /**
223  *******************************************************************************
224  *
225  * @ingroup pastix_symbol
226  *
227  * @brief Export the symbol structure in a PostScript format.
228  *
229  * This routine writes to the given stream a PostScript (tm) picture of the
230  * symbolic block matrix, with diagonal blocks in black and off-diagonal blocks
231  * in dark gray.
232  *
233  *******************************************************************************
234  *
235  * @param[in] symbptr
236  * The pointer to the symbolic structure to draw.
237  *
238  * @param[inout] stream
239  * The stream where to write the output.
240  *
241  *******************************************************************************
242  *
243  * @retval 0 on success
244  * @retval -1 on error
245  *
246  *******************************************************************************/
247 int
248 pastixSymbolDraw ( const symbol_matrix_t * const symbptr,
249  FILE * const stream )
250 {
251  return (pastixSymbolDrawFunc (symbptr, NULL, NULL, NULL, stream));
252 }
symbol_matrix_s
Symbol matrix structure.
Definition: symbol.h:75
symbol_matrix_s::bloktab
symbol_blok_t * bloktab
Definition: symbol.h:82
SYMBOL_PSPICTSIZE
#define SYMBOL_PSPICTSIZE
PostScript picture size (in inches)
Definition: symbol_draw.c:40
symbol_cblk_s::fcolnum
pastix_int_t fcolnum
Definition: symbol.h:44
symbol_matrix_s::nodenbr
pastix_int_t nodenbr
Definition: symbol.h:79
symbol_matrix_s::cblknbr
pastix_int_t cblknbr
Definition: symbol.h:77
SYMBOL_PSDPI
#define SYMBOL_PSDPI
PostScript dots-per-inch.
Definition: symbol_draw.c:36
symbol_matrix_s::baseval
pastix_int_t baseval
Definition: symbol.h:76
symbol_matrix_s::bloknbr
pastix_int_t bloknbr
Definition: symbol.h:78
pastixSymbolDraw
int pastixSymbolDraw(const symbol_matrix_t *symbptr, FILE *stream)
Export the symbol structure in a PostScript format.
Definition: symbol_draw.c:248
symbol_cblk_s::bloknum
pastix_int_t bloknum
Definition: symbol.h:46
symbol.h
symbol_cblk_s::lcolnum
pastix_int_t lcolnum
Definition: symbol.h:45
symbol_blok_s::frownum
pastix_int_t frownum
Definition: symbol.h:58
symbolDrawColorTab
static float symbolDrawColorTab[16][3]
Predefined set of colors.
Definition: symbol_draw.c:49
symbol_matrix_s::cblktab
symbol_cblk_t * cblktab
Definition: symbol.h:81
symbol_blok_s
Symbol block structure.
Definition: symbol.h:57
pastixSymbolDrawColor
void pastixSymbolDrawColor(const pastix_int_t labl, float color[])
Return one of 16 predefined, visually distinct distinct colors.
Definition: symbol_draw.c:82
symbol_blok_s::lrownum
pastix_int_t lrownum
Definition: symbol.h:59
pastixSymbolDrawFunc
int pastixSymbolDrawFunc(const symbol_matrix_t *const symbptr, int(*diagfunc)(const symbol_matrix_t *const, const symbol_blok_t *const, void *const, float *const), int(*offdfunc)(const symbol_matrix_t *const, const symbol_blok_t *const, void *const, float *const), void *const dataptr, FILE *const stream)
Export the symbol structure in a PostScript format.
Definition: symbol_draw.c:122