Actual source code: tikz.c
petsc-3.14.6 2021-03-30
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",NULL,NULL,"orange","violet","brown","pink",NULL,"yellow",NULL};
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 PetscDrawRectangle_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
97: {
98: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
102: win->written = PETSC_TRUE;
103: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\fill [bottom color=%s,top color=%s] (%g,%g) rectangle (%g,%g);\n",TikZColorMap(c1),TikZColorMap(c4),XTRANS(draw,xl),YTRANS(draw,yl),XTRANS(draw,xr),YTRANS(draw,yr));
104: return(0);
105: }
107: static PetscErrorCode PetscDrawTriangle_TikZ(PetscDraw draw,PetscReal x1,PetscReal y1,PetscReal x2,PetscReal y2,PetscReal x3,PetscReal y3,int c1,int c2,int c3)
108: {
109: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
113: win->written = PETSC_TRUE;
114: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\fill [color=%s] (%g,%g) -- (%g,%g) -- (%g,%g) -- cycle;\n",TikZColorMap(c1),XTRANS(draw,x1),YTRANS(draw,y1),XTRANS(draw,x2),YTRANS(draw,y2),XTRANS(draw,x3),YTRANS(draw,y3));
115: return(0);
116: }
118: static PetscErrorCode PetscDrawEllipse_TikZ(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
119: {
120: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
121: PetscReal rx,ry;
125: win->written = PETSC_TRUE;
126: rx = a/2*(draw->port_xr-draw->port_xl)/(draw->coor_xr-draw->coor_xl);
127: ry = b/2*(draw->port_yr-draw->port_yl)/(draw->coor_yr-draw->coor_yl);
128: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\fill [color=%s] (%g,%g) circle [x radius=%g,y radius=%g];\n",TikZColorMap(c),XTRANS(draw,x),YTRANS(draw,y),(double)rx,(double)ry);
129: return(0);
130: }
132: static PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
133: {
134: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
138: win->written = PETSC_TRUE;
139: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [above right, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
140: return(0);
141: }
143: static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
144: {
145: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
147: size_t len;
148: PetscReal width;
151: win->written = PETSC_TRUE;
152: PetscStrlen(text,&len);
153: PetscDrawStringGetSize(draw,&width,NULL);
154: yl = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
155: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [rotate=90, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
156: return(0);
157: }
159: /*
160: Does not handle multiline strings correctly
161: */
162: static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
163: {
164: PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
166: size_t len;
169: win->written = PETSC_TRUE;
170: 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);
172: /* make up totally bogus height and width of box */
173: PetscStrlen(text,&len);
174: if (w) *w = .07*len;
175: if (h) *h = .07;
176: return(0);
177: }
179: static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal *y)
180: {
182: if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
183: if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
184: return(0);
185: }
187: static struct _PetscDrawOps DvOps = { NULL,
188: NULL,
189: PetscDrawLine_TikZ,
190: NULL,
191: NULL,
192: NULL,
193: NULL,
194: PetscDrawString_TikZ,
195: PetscDrawStringVertical_TikZ,
196: NULL,
197: PetscDrawStringGetSize_TikZ,
198: NULL,
199: PetscDrawClear_TikZ,
200: PetscDrawRectangle_TikZ,
201: PetscDrawTriangle_TikZ,
202: PetscDrawEllipse_TikZ,
203: NULL,
204: NULL,
205: NULL,
206: NULL,
207: NULL,
208: NULL,
209: NULL,
210: NULL,
211: PetscDrawDestroy_TikZ,
212: NULL,
213: NULL,
214: NULL,
215: NULL,
216: NULL,
217: NULL,
218: NULL,
219: NULL,
220: NULL,
221: NULL,
222: PetscDrawStringBoxed_TikZ};
224: PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
225: {
226: PetscDraw_TikZ *win;
230: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
231: PetscNew(&win);
232: PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));
234: draw->data = (void*) win;
236: if (draw->title) {
237: PetscStrallocpy(draw->title,&win->filename);
238: } else {
239: const char *fname;
240: PetscObjectGetName((PetscObject)draw,&fname);
241: PetscStrallocpy(fname,&win->filename);
242: }
243: PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);
244: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);
245: PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);
247: win->written = PETSC_FALSE;
248: return(0);
249: }