Actual source code: tikz.c
petsc-3.7.3 2016-08-01
1: /*
2: Defines the operations for the X PetscDraw implementation.
3: */
5: #include <petsc/private/drawimpl.h> /*I "petscsys.h" I*/
7: typedef struct {
8: char *filename;
9: FILE *fd;
10: PetscBool written; /* something has been written to the current frame */
11: } PetscDraw_TikZ;
13: #define TikZ_BEGIN_DOCUMENT "\\documentclass{beamer}\n\n\
14: \\usepackage{tikz}\n\
15: \\usepackage{pgflibraryshapes}\n\
16: \\usetikzlibrary{backgrounds}\n\
17: \\usetikzlibrary{arrows}\n\
18: \\newenvironment{changemargin}[2]{%%\n\
19: \\begin{list}{}{%%\n\
20: \\setlength{\\topsep}{0pt}%%\n\
21: \\setlength{\\leftmargin}{#1}%%\n\
22: \\setlength{\\rightmargin}{#2}%%\n\
23: \\setlength{\\listparindent}{\\parindent}%%\n\
24: \\setlength{\\itemindent}{\\parindent}%%\n\
25: \\setlength{\\parsep}{\\parskip}%%\n\
26: }%%\n\
27: \\item[]}{\\end{list}}\n\n\
28: \\begin{document}\n"
30: #define TikZ_BEGIN_FRAME "\\begin{frame}{}\n\
31: \\begin{changemargin}{-1cm}{0cm}\n\
32: \\begin{center}\n\
33: \\begin{tikzpicture}[scale = 10.00,font=\\fontsize{8}{8}\\selectfont]\n"
35: #define TikZ_END_FRAME "\\end{tikzpicture}\n\
36: \\end{center}\n\
37: \\end{changemargin}\n\
38: \\end{frame}\n"
40: #define TikZ_END_DOCUMENT "\\end{document}\n"
44: static PetscErrorCode PetscDrawDestroy_TikZ(PetscDraw draw)
45: {
46: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
50: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);
51: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_DOCUMENT);
52: PetscFClose(PetscObjectComm((PetscObject)draw),win->fd);
53: PetscFree(win->filename);
54: PetscFree(draw->data);
55: return(0);
56: }
58: static const char *TikZColors[] = { "white", "black", "red", "green", "cyan", "blue", "magenta", 0, 0, "orange",
59: "violet", "brown", "pink", 0, "yellow", 0};
61: PETSC_STATIC_INLINE const char *TikZColorMap(int cl)
62: {
63: return((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black");
64: }
66: /*
67: These macros transform from the users coordinates to the (0,0) -> (1,1) coordinate system
68: */
69: #define XTRANS(draw,x) (double)(((draw)->port_xl + (((x - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl))))
70: #define YTRANS(draw,y) (double)(((draw)->port_yl + (((y - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl))))
74: static PetscErrorCode PetscDrawClear_TikZ(PetscDraw draw)
75: {
76: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
77: PetscBool written;
81: /* often PETSc generates unneeded clears, we want avoid creating empy pictures for them */
82: MPI_Allreduce(&win->written,&written,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)(draw)));
83: if (!written) return(0);
84: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);
85: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);
86: win->written = PETSC_FALSE;
87: return(0);
88: }
92: static PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
93: {
94: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
98: win->written = PETSC_TRUE;
99: 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));
100: return(0);
101: }
105: static PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
106: {
107: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
111: win->written = PETSC_TRUE;
112: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [above right, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
113: return(0);
114: }
118: static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
119: {
120: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
122: size_t len;
123: PetscReal width;
126: win->written = PETSC_TRUE;
127: PetscStrlen(text,&len);
128: PetscDrawStringGetSize(draw,&width,NULL);
129: yl = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
130: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [rotate=90, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
131: return(0);
132: }
136: /*
137: Does not handle multiline strings correctly
138: */
139: static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
140: {
141: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
143: size_t len;
146: win->written = PETSC_TRUE;
147: 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);
149: /* make up totally bogus height and width of box */
150: PetscStrlen(text,&len);
151: if (w) *w = .07*len;
152: if (h) *h = .07;
153: return(0);
154: }
158: static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal *y)
159: {
161: if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
162: if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
163: return(0);
164: }
166: static struct _PetscDrawOps DvOps = { 0,
167: 0,
168: PetscDrawLine_TikZ,
169: 0,
170: 0,
171: 0,
172: 0,
173: PetscDrawString_TikZ,
174: PetscDrawStringVertical_TikZ,
175: 0,
176: PetscDrawStringGetSize_TikZ,
177: 0,
178: PetscDrawClear_TikZ,
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};
205: PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
206: {
207: PetscDraw_TikZ *win;
211: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
212: PetscNew(&win);
213: PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));
215: draw->data = (void*) win;
217: if (draw->title) {
218: PetscStrallocpy(draw->title,&win->filename);
219: } else {
220: const char *fname;
221: PetscObjectGetName((PetscObject)draw,&fname);
222: PetscStrallocpy(fname,&win->filename);
223: }
224: PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);
225: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);
226: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);
228: win->written = PETSC_FALSE;
229: return(0);
230: }