xref: /petsc/src/sys/classes/draw/impls/tikz/tikz.c (revision 009bbdc485cd9ad46be9940d3549e2dde9cdc322)
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(((PetscObject)draw)->comm,win->fd,TikZ_END_FRAME);CHKERRQ(ierr);
52   ierr = PetscFPrintf(((PetscObject)draw)->comm,win->fd,TikZ_END_DOCUMENT);CHKERRQ(ierr);
53   ierr = PetscFClose(((PetscObject)draw)->comm,win->fd);CHKERRQ(ierr);
54   ierr = PetscFree(win->filename);CHKERRQ(ierr);
55   ierr = PetscFree(win);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(((PetscObject)draw)->comm,win->fd,TikZ_END_FRAME);CHKERRQ(ierr);
84   ierr = PetscFPrintf(((PetscObject)draw)->comm,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(((PetscObject)draw)->comm,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(((PetscObject)draw)->comm,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__ "PetscDrawBoxedString_TikZ"
116 /*
117     Does not handle multiline strings correctly
118 */
119 PetscErrorCode PetscDrawBoxedString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
120 {
121   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
122   PetscErrorCode ierr;
123   size_t         len;
124 
125   PetscFunctionBegin;
126   win->written = PETSC_TRUE;
127   ierr = PetscFPrintf(((PetscObject)draw)->comm,win->fd,"\\draw (%g,%g) node [rectangle, draw, align=center, inner sep=1ex] {%s};\n",XTRANS(draw,xl),YTRANS(draw,yl),text);CHKERRQ(ierr);
128 
129   /* make up totally bogus height and width of box */
130   ierr = PetscStrlen(text,&len);CHKERRQ(ierr);
131   if (w) *w = .07*len;
132   if (h) *h = .07;
133   PetscFunctionReturn(0);
134 }
135 
136 static struct _PetscDrawOps DvOps = { 0,
137                                       0,
138                                       PetscDrawLine_TikZ,
139                                       0,
140                                       0,
141                                       0,
142                                       0,
143                                       PetscDrawString_TikZ,
144                                       0,
145                                       0,
146                                       0,
147                                       0,
148                                       PetscDrawClear_TikZ,
149                                       0,
150                                       0,
151                                       0,
152                                       0,
153                                       0,
154                                       0,
155                                       0,
156                                       0,
157                                       0,
158                                       0,
159                                       0,
160                                       0,
161                                       0,
162                                       PetscDrawDestroy_TikZ,
163                                       0,
164                                       0,
165                                       0,
166                                       0,
167                                       0,
168                                       0,
169                                       0,
170                                       0,
171                                       0,
172                                       0,
173                                       PetscDrawBoxedString_TikZ};
174 
175 
176 
177 
178 EXTERN_C_BEGIN
179 #undef __FUNCT__
180 #define __FUNCT__ "PetscDrawCreate_TikZ"
181 PetscErrorCode  PetscDrawCreate_TikZ(PetscDraw draw)
182 {
183   PetscDraw_TikZ *win;
184   PetscErrorCode ierr;
185 
186   PetscFunctionBegin;
187   ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
188   ierr = PetscNew(PetscDraw_TikZ,&win);CHKERRQ(ierr);
189   ierr = PetscLogObjectMemory(draw,sizeof(PetscDraw_TikZ));CHKERRQ(ierr);
190   draw->data = (void*) win;
191 
192   if (draw->title) {
193     ierr = PetscStrallocpy(draw->title,&win->filename);CHKERRQ(ierr);
194   } else {
195     const char *fname;
196     ierr = PetscObjectGetName((PetscObject)draw,&fname);CHKERRQ(ierr);
197     ierr = PetscStrallocpy(fname,&win->filename);CHKERRQ(ierr);
198   }
199   ierr = PetscFOpen(((PetscObject)draw)->comm,win->filename,"w",&win->fd);CHKERRQ(ierr);
200   ierr = PetscFPrintf(((PetscObject)draw)->comm,win->fd,TikZ_BEGIN_DOCUMENT);CHKERRQ(ierr);
201   ierr = PetscFPrintf(((PetscObject)draw)->comm,win->fd,TikZ_BEGIN_FRAME);CHKERRQ(ierr);
202   win->written = PETSC_FALSE;
203   PetscFunctionReturn(0);
204 }
205 EXTERN_C_END
206 
207 
208 
209 
210 
211 
212 
213 
214 
215