xref: /petsc/src/sys/classes/draw/impls/tikz/tikz.c (revision e52336cb213eafb6e0bc1e6a0d4ebe153339e097)
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__ "PetscDrawSynchronizedClear_TikZ"
90 PetscErrorCode PetscDrawSynchronizedClear_TikZ(PetscDraw draw)
91 {
92   PetscErrorCode ierr;
93 
94   PetscFunctionBegin;
95   ierr = PetscDrawClear_TikZ(draw);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 #undef __FUNCT__
100 #define __FUNCT__ "PetscDrawLine_TikZ"
101 PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
102 {
103   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
104   PetscErrorCode ierr;
105 
106   PetscFunctionBegin;
107   win->written = PETSC_TRUE;
108   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);
109   PetscFunctionReturn(0);
110 }
111 
112 #undef __FUNCT__
113 #define __FUNCT__ "PetscDrawString_TikZ"
114 PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
115 {
116   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
117   PetscErrorCode ierr;
118 
119   PetscFunctionBegin;
120   win->written = PETSC_TRUE;
121   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);
122   PetscFunctionReturn(0);
123 }
124 
125 #undef __FUNCT__
126 #define __FUNCT__ "PetscDrawStringVertical_TikZ"
127 PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
128 {
129   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
130   PetscErrorCode ierr;
131   size_t         len;
132   PetscReal      width;
133 
134   PetscFunctionBegin;
135   win->written = PETSC_TRUE;
136   ierr = PetscStrlen(text,&len);CHKERRQ(ierr);
137   ierr = PetscDrawStringGetSize(draw,&width,NULL);CHKERRQ(ierr);
138   yl   = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
139   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);
140   PetscFunctionReturn(0);
141 }
142 
143 #undef __FUNCT__
144 #define __FUNCT__ "PetscDrawStringBoxed_TikZ"
145 /*
146     Does not handle multiline strings correctly
147 */
148 PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
149 {
150   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
151   PetscErrorCode ierr;
152   size_t         len;
153 
154   PetscFunctionBegin;
155   win->written = PETSC_TRUE;
156   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);
157 
158   /* make up totally bogus height and width of box */
159   ierr = PetscStrlen(text,&len);CHKERRQ(ierr);
160   if (w) *w = .07*len;
161   if (h) *h = .07;
162   PetscFunctionReturn(0);
163 }
164 
165 #undef __FUNCT__
166 #define __FUNCT__ "PetscDrawStringGetSize_TikZ"
167 PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal  *y)
168 {
169   PetscFunctionBegin;
170   if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
171   if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
172   PetscFunctionReturn(0);
173 }
174 
175 static struct _PetscDrawOps DvOps = { 0,
176                                       0,
177                                       PetscDrawLine_TikZ,
178                                       0,
179                                       0,
180                                       0,
181                                       0,
182                                       PetscDrawString_TikZ,
183                                       PetscDrawStringVertical_TikZ,
184                                       0,
185                                       PetscDrawStringGetSize_TikZ,
186                                       0,
187                                       PetscDrawClear_TikZ,
188                                       0,
189                                       0,
190                                       0,
191                                       0,
192                                       0,
193                                       0,
194                                       PetscDrawSynchronizedClear_TikZ,
195                                       0,
196                                       0,
197                                       0,
198                                       0,
199                                       0,
200                                       0,
201                                       PetscDrawDestroy_TikZ,
202                                       0,
203                                       0,
204                                       0,
205                                       0,
206                                       0,
207                                       0,
208                                       0,
209                                       0,
210                                       0,
211                                       0,
212                                       PetscDrawStringBoxed_TikZ};
213 
214 #undef __FUNCT__
215 #define __FUNCT__ "PetscDrawCreate_TikZ"
216 PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
217 {
218   PetscDraw_TikZ *win;
219   PetscErrorCode ierr;
220 
221   PetscFunctionBegin;
222   ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
223   ierr = PetscNew(&win);CHKERRQ(ierr);
224   ierr = PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));CHKERRQ(ierr);
225 
226   draw->data = (void*) win;
227 
228   if (draw->title) {
229     ierr = PetscStrallocpy(draw->title,&win->filename);CHKERRQ(ierr);
230   } else {
231     const char *fname;
232     ierr = PetscObjectGetName((PetscObject)draw,&fname);CHKERRQ(ierr);
233     ierr = PetscStrallocpy(fname,&win->filename);CHKERRQ(ierr);
234   }
235   ierr = PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);CHKERRQ(ierr);
236   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);CHKERRQ(ierr);
237   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);CHKERRQ(ierr);
238 
239   win->written = PETSC_FALSE;
240   PetscFunctionReturn(0);
241 }
242 
243 
244 
245 
246 
247 
248 
249 
250 
251