xref: /petsc/src/sys/classes/draw/impls/tikz/tikz.c (revision bebe2cf65d55febe21a5af8db2bd2e168caaa2e7)
1 
2 /*
3     Defines the operations for the X PetscDraw implementation.
4 */
5 
6 #include <petsc/private/drawimpl.h>         /*I  "petscsys.h" I*/
7 
8 typedef struct {
9   char      *filename;
10   FILE      *fd;
11   PetscBool written;  /* something has been written to the current frame */
12 } PetscDraw_TikZ;
13 
14 #define TikZ_BEGIN_DOCUMENT  "\\documentclass{beamer}\n\n\
15 \\usepackage{tikz}\n\
16 \\usepackage{pgflibraryshapes}\n\
17 \\usetikzlibrary{backgrounds}\n\
18 \\usetikzlibrary{arrows}\n\
19 \\newenvironment{changemargin}[2]{%%\n\
20   \\begin{list}{}{%%\n\
21     \\setlength{\\topsep}{0pt}%%\n\
22     \\setlength{\\leftmargin}{#1}%%\n\
23     \\setlength{\\rightmargin}{#2}%%\n\
24     \\setlength{\\listparindent}{\\parindent}%%\n\
25     \\setlength{\\itemindent}{\\parindent}%%\n\
26     \\setlength{\\parsep}{\\parskip}%%\n\
27   }%%\n\
28   \\item[]}{\\end{list}}\n\n\
29 \\begin{document}\n"
30 
31 #define TikZ_BEGIN_FRAME "\\begin{frame}{}\n\
32 \\begin{changemargin}{-1cm}{0cm}\n\
33 \\begin{center}\n\
34 \\begin{tikzpicture}[scale = 10.00,font=\\fontsize{8}{8}\\selectfont]\n"
35 
36 #define TikZ_END_FRAME "\\end{tikzpicture}\n\
37 \\end{center}\n\
38 \\end{changemargin}\n\
39 \\end{frame}\n"
40 
41 #define TikZ_END_DOCUMENT  "\\end{document}\n"
42 
43 #undef __FUNCT__
44 #define __FUNCT__ "PetscDrawDestroy_TikZ"
45 PetscErrorCode  PetscDrawDestroy_TikZ(PetscDraw draw)
46 {
47   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
48   PetscErrorCode ierr;
49 
50   PetscFunctionBegin;
51   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);CHKERRQ(ierr);
52   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_DOCUMENT);CHKERRQ(ierr);
53   ierr = PetscFClose(PetscObjectComm((PetscObject)draw),win->fd);CHKERRQ(ierr);
54   ierr = PetscFree(win->filename);CHKERRQ(ierr);
55   ierr = PetscFree(draw->data);CHKERRQ(ierr);
56   PetscFunctionReturn(0);
57 }
58 
59 static const char *TikZColors[] = { "white",  "black", "red",  "green", "cyan",   "blue", "magenta", 0, 0, "orange",
60                                     "violet", "brown", "pink", 0,       "yellow", 0};
61 
62 PETSC_STATIC_INLINE const char *TikZColorMap(int cl)
63 {
64   return((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black");
65 }
66 
67 /*
68      These macros transform from the users coordinates to the (0,0) -> (1,1) coordinate system
69 */
70 #define XTRANS(draw,x)  (double)(((draw)->port_xl + (((x - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl))))
71 #define YTRANS(draw,y)  (double)(((draw)->port_yl + (((y - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl))))
72 
73 #undef __FUNCT__
74 #define __FUNCT__ "PetscDrawClear_TikZ"
75 PetscErrorCode PetscDrawClear_TikZ(PetscDraw draw)
76 {
77   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
78   PetscErrorCode ierr;
79 
80   PetscFunctionBegin;
81   /* often PETSc generates unneeded clears, we want avoid creating empy pictures for them */
82   if (!win->written) PetscFunctionReturn(0);
83   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);CHKERRQ(ierr);
84   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);CHKERRQ(ierr);
85   PetscFunctionReturn(0);
86 }
87 
88 #undef __FUNCT__
89 #define __FUNCT__ "PetscDrawLine_TikZ"
90 PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
91 {
92   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
93   PetscErrorCode ierr;
94 
95   PetscFunctionBegin;
96   win->written = PETSC_TRUE;
97   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\draw [%s] (%g,%g) --(%g,%g);\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),XTRANS(draw,xr),YTRANS(draw,yr));CHKERRQ(ierr);
98   PetscFunctionReturn(0);
99 }
100 
101 #undef __FUNCT__
102 #define __FUNCT__ "PetscDrawString_TikZ"
103 PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
104 {
105   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
106   PetscErrorCode ierr;
107 
108   PetscFunctionBegin;
109   win->written = PETSC_TRUE;
110   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [above right, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);CHKERRQ(ierr);
111   PetscFunctionReturn(0);
112 }
113 
114 #undef __FUNCT__
115 #define __FUNCT__ "PetscDrawStringVertical_TikZ"
116 PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
117 {
118   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
119   PetscErrorCode ierr;
120   size_t         len;
121   PetscReal      width;
122 
123   PetscFunctionBegin;
124   win->written = PETSC_TRUE;
125   ierr = PetscStrlen(text,&len);CHKERRQ(ierr);
126   ierr = PetscDrawStringGetSize(draw,&width,NULL);CHKERRQ(ierr);
127   yl   = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
128   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [rotate=90, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);CHKERRQ(ierr);
129   PetscFunctionReturn(0);
130 }
131 
132 #undef __FUNCT__
133 #define __FUNCT__ "PetscDrawStringBoxed_TikZ"
134 /*
135     Does not handle multiline strings correctly
136 */
137 PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
138 {
139   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
140   PetscErrorCode ierr;
141   size_t         len;
142 
143   PetscFunctionBegin;
144   win->written = PETSC_TRUE;
145   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\draw (%g,%g) node [rectangle, draw, align=center, inner sep=1ex] {%s};\n",XTRANS(draw,xl),YTRANS(draw,yl),text);CHKERRQ(ierr);
146 
147   /* make up totally bogus height and width of box */
148   ierr = PetscStrlen(text,&len);CHKERRQ(ierr);
149   if (w) *w = .07*len;
150   if (h) *h = .07;
151   PetscFunctionReturn(0);
152 }
153 
154 #undef __FUNCT__
155 #define __FUNCT__ "PetscDrawStringGetSize_TikZ"
156 PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal  *y)
157 {
158   PetscFunctionBegin;
159   if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
160   if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
161   PetscFunctionReturn(0);
162 }
163 
164 static struct _PetscDrawOps DvOps = { 0,
165                                       0,
166                                       PetscDrawLine_TikZ,
167                                       0,
168                                       0,
169                                       0,
170                                       0,
171                                       PetscDrawString_TikZ,
172                                       PetscDrawStringVertical_TikZ,
173                                       0,
174                                       PetscDrawStringGetSize_TikZ,
175                                       0,
176                                       PetscDrawClear_TikZ,
177                                       0,
178                                       0,
179                                       0,
180                                       0,
181                                       0,
182                                       0,
183                                       0,
184                                       0,
185                                       0,
186                                       0,
187                                       0,
188                                       0,
189                                       0,
190                                       PetscDrawDestroy_TikZ,
191                                       0,
192                                       0,
193                                       0,
194                                       0,
195                                       0,
196                                       0,
197                                       0,
198                                       0,
199                                       0,
200                                       0,
201                                       PetscDrawStringBoxed_TikZ};
202 
203 #undef __FUNCT__
204 #define __FUNCT__ "PetscDrawCreate_TikZ"
205 PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
206 {
207   PetscDraw_TikZ *win;
208   PetscErrorCode ierr;
209 
210   PetscFunctionBegin;
211   ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
212   ierr = PetscNew(&win);CHKERRQ(ierr);
213   ierr = PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));CHKERRQ(ierr);
214 
215   draw->data = (void*) win;
216 
217   if (draw->title) {
218     ierr = PetscStrallocpy(draw->title,&win->filename);CHKERRQ(ierr);
219   } else {
220     const char *fname;
221     ierr = PetscObjectGetName((PetscObject)draw,&fname);CHKERRQ(ierr);
222     ierr = PetscStrallocpy(fname,&win->filename);CHKERRQ(ierr);
223   }
224   ierr = PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);CHKERRQ(ierr);
225   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);CHKERRQ(ierr);
226   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);CHKERRQ(ierr);
227 
228   win->written = PETSC_FALSE;
229   PetscFunctionReturn(0);
230 }
231 
232 
233 
234 
235 
236 
237 
238 
239 
240