Actual source code: tikz.c
petsc-3.8.4 2018-03-24
1: /*
2: Defines the operations for the TikZ PetscDraw implementation.
3: */
5: #include <petsc/private/drawimpl.h>
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"
42: static PetscErrorCode PetscDrawDestroy_TikZ(PetscDraw draw)
43: {
44: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
48: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);
49: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_DOCUMENT);
50: PetscFClose(PetscObjectComm((PetscObject)draw),win->fd);
51: PetscFree(win->filename);
52: PetscFree(draw->data);
53: return(0);
54: }
56: static const char *TikZColors[] = {"white","black","red","green","cyan","blue","magenta",0,0,"orange","violet","brown","pink",0,"yellow",0};
58: PETSC_STATIC_INLINE const char *TikZColorMap(int cl)
59: {
60: return((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black");
61: }
63: /*
64: These macros transform from the users coordinates to the (0,0) -> (1,1) coordinate system
65: */
66: #define XTRANS(draw,x) (double)(((draw)->port_xl + (((x - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl))))
67: #define YTRANS(draw,y) (double)(((draw)->port_yl + (((y - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl))))
69: static PetscErrorCode PetscDrawClear_TikZ(PetscDraw draw)
70: {
71: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
72: PetscBool written;
76: /* often PETSc generates unneeded clears, we want avoid creating empy pictures for them */
77: MPI_Allreduce(&win->written,&written,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)(draw)));
78: if (!written) return(0);
79: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);
80: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);
81: win->written = PETSC_FALSE;
82: return(0);
83: }
85: static PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
86: {
87: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
91: win->written = PETSC_TRUE;
92: 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));
93: return(0);
94: }
96: static PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
97: {
98: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
102: win->written = PETSC_TRUE;
103: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [above right, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
104: return(0);
105: }
107: static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
108: {
109: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
111: size_t len;
112: PetscReal width;
115: win->written = PETSC_TRUE;
116: PetscStrlen(text,&len);
117: PetscDrawStringGetSize(draw,&width,NULL);
118: yl = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
119: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [rotate=90, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
120: return(0);
121: }
123: /*
124: Does not handle multiline strings correctly
125: */
126: static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
127: {
128: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
130: size_t len;
133: win->written = PETSC_TRUE;
134: 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);
136: /* make up totally bogus height and width of box */
137: PetscStrlen(text,&len);
138: if (w) *w = .07*len;
139: if (h) *h = .07;
140: return(0);
141: }
143: static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal *y)
144: {
146: if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
147: if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
148: return(0);
149: }
151: static struct _PetscDrawOps DvOps = { 0,
152: 0,
153: PetscDrawLine_TikZ,
154: 0,
155: 0,
156: 0,
157: 0,
158: PetscDrawString_TikZ,
159: PetscDrawStringVertical_TikZ,
160: 0,
161: PetscDrawStringGetSize_TikZ,
162: 0,
163: PetscDrawClear_TikZ,
164: 0,
165: 0,
166: 0,
167: 0,
168: 0,
169: 0,
170: 0,
171: 0,
172: 0,
173: 0,
174: 0,
175: PetscDrawDestroy_TikZ,
176: 0,
177: 0,
178: 0,
179: 0,
180: 0,
181: 0,
182: 0,
183: 0,
184: 0,
185: 0,
186: PetscDrawStringBoxed_TikZ};
188: PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
189: {
190: PetscDraw_TikZ *win;
194: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
195: PetscNew(&win);
196: PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));
198: draw->data = (void*) win;
200: if (draw->title) {
201: PetscStrallocpy(draw->title,&win->filename);
202: } else {
203: const char *fname;
204: PetscObjectGetName((PetscObject)draw,&fname);
205: PetscStrallocpy(fname,&win->filename);
206: }
207: PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);
208: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);
209: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);
211: win->written = PETSC_FALSE;
212: return(0);
213: }