xref: /petsc/src/sys/classes/draw/impls/tikz/tikz.c (revision 9566063d113dddea24716c546802770db7481bc0)
142963b84SBarry Smith /*
2183a438dSBarry Smith     Defines the operations for the TikZ PetscDraw implementation.
342963b84SBarry Smith */
442963b84SBarry Smith 
5af0996ceSBarry Smith #include <petsc/private/drawimpl.h>         /*I  "petscsys.h" I*/
642963b84SBarry Smith 
742963b84SBarry Smith typedef struct {
842963b84SBarry Smith   char      *filename;
942963b84SBarry Smith   FILE      *fd;
1042963b84SBarry Smith   PetscBool written;  /* something has been written to the current frame */
1142963b84SBarry Smith } PetscDraw_TikZ;
1242963b84SBarry Smith 
1342963b84SBarry Smith #define TikZ_BEGIN_DOCUMENT  "\\documentclass{beamer}\n\n\
1442963b84SBarry Smith \\usepackage{tikz}\n\
1542963b84SBarry Smith \\usepackage{pgflibraryshapes}\n\
1642963b84SBarry Smith \\usetikzlibrary{backgrounds}\n\
1742963b84SBarry Smith \\usetikzlibrary{arrows}\n\
1842963b84SBarry Smith \\newenvironment{changemargin}[2]{%%\n\
1942963b84SBarry Smith   \\begin{list}{}{%%\n\
2042963b84SBarry Smith     \\setlength{\\topsep}{0pt}%%\n\
2142963b84SBarry Smith     \\setlength{\\leftmargin}{#1}%%\n\
2242963b84SBarry Smith     \\setlength{\\rightmargin}{#2}%%\n\
2342963b84SBarry Smith     \\setlength{\\listparindent}{\\parindent}%%\n\
2442963b84SBarry Smith     \\setlength{\\itemindent}{\\parindent}%%\n\
2542963b84SBarry Smith     \\setlength{\\parsep}{\\parskip}%%\n\
2642963b84SBarry Smith   }%%\n\
2742963b84SBarry Smith   \\item[]}{\\end{list}}\n\n\
2842963b84SBarry Smith \\begin{document}\n"
2942963b84SBarry Smith 
3042963b84SBarry Smith #define TikZ_BEGIN_FRAME "\\begin{frame}{}\n\
3142963b84SBarry Smith \\begin{changemargin}{-1cm}{0cm}\n\
3242963b84SBarry Smith \\begin{center}\n\
3342963b84SBarry Smith \\begin{tikzpicture}[scale = 10.00,font=\\fontsize{8}{8}\\selectfont]\n"
3442963b84SBarry Smith 
3542963b84SBarry Smith #define TikZ_END_FRAME "\\end{tikzpicture}\n\
3642963b84SBarry Smith \\end{center}\n\
3742963b84SBarry Smith \\end{changemargin}\n\
3842963b84SBarry Smith \\end{frame}\n"
3942963b84SBarry Smith 
4042963b84SBarry Smith #define TikZ_END_DOCUMENT  "\\end{document}\n"
4142963b84SBarry Smith 
42eecff6a3SLisandro Dalcin static PetscErrorCode  PetscDrawDestroy_TikZ(PetscDraw draw)
4342963b84SBarry Smith {
4442963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
4542963b84SBarry Smith 
4642963b84SBarry Smith   PetscFunctionBegin;
47*9566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME));
48*9566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_DOCUMENT));
49*9566063dSJacob Faibussowitsch   PetscCall(PetscFClose(PetscObjectComm((PetscObject)draw),win->fd));
50*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(win->filename));
51*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(draw->data));
5242963b84SBarry Smith   PetscFunctionReturn(0);
5342963b84SBarry Smith }
5442963b84SBarry Smith 
5502c9f0b5SLisandro Dalcin static const char *TikZColors[] = {"white","black","red","green","cyan","blue","magenta",NULL,NULL,"orange","violet","brown","pink",NULL,"yellow",NULL};
5642963b84SBarry Smith 
579fbee547SJacob Faibussowitsch static inline const char *TikZColorMap(int cl)
5842963b84SBarry Smith {
5942963b84SBarry Smith   return((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black");
6042963b84SBarry Smith }
6142963b84SBarry Smith 
6242963b84SBarry Smith /*
6342963b84SBarry Smith      These macros transform from the users coordinates to the (0,0) -> (1,1) coordinate system
6442963b84SBarry Smith */
6542963b84SBarry Smith #define XTRANS(draw,x)  (double)(((draw)->port_xl + (((x - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl))))
6642963b84SBarry Smith #define YTRANS(draw,y)  (double)(((draw)->port_yl + (((y - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl))))
6742963b84SBarry Smith 
68eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawClear_TikZ(PetscDraw draw)
6942963b84SBarry Smith {
7042963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
715b399a63SLisandro Dalcin   PetscBool      written;
7242963b84SBarry Smith 
7342963b84SBarry Smith   PetscFunctionBegin;
7442963b84SBarry Smith   /* often PETSc generates unneeded clears, we want avoid creating empy pictures for them */
75*9566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allreduce(&win->written,&written,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)(draw))));
765b399a63SLisandro Dalcin   if (!written) PetscFunctionReturn(0);
77*9566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME));
78*9566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME));
795b399a63SLisandro Dalcin   win->written = PETSC_FALSE;
8071d8d82dSLisandro Dalcin   PetscFunctionReturn(0);
8171d8d82dSLisandro Dalcin }
8271d8d82dSLisandro Dalcin 
83eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
8442963b84SBarry Smith {
8542963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
8642963b84SBarry Smith 
8742963b84SBarry Smith   PetscFunctionBegin;
8842963b84SBarry Smith   win->written = PETSC_TRUE;
89*9566063dSJacob Faibussowitsch   PetscCall(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)));
9042963b84SBarry Smith   PetscFunctionReturn(0);
9142963b84SBarry Smith }
9242963b84SBarry Smith 
9332115b0cSJose E. Roman static PetscErrorCode PetscDrawRectangle_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
9432115b0cSJose E. Roman {
9532115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
9632115b0cSJose E. Roman 
9732115b0cSJose E. Roman   PetscFunctionBegin;
9832115b0cSJose E. Roman   win->written = PETSC_TRUE;
99*9566063dSJacob Faibussowitsch   PetscCall(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)));
10032115b0cSJose E. Roman   PetscFunctionReturn(0);
10132115b0cSJose E. Roman }
10232115b0cSJose E. Roman 
10332115b0cSJose E. Roman static PetscErrorCode PetscDrawTriangle_TikZ(PetscDraw draw,PetscReal x1,PetscReal y1,PetscReal x2,PetscReal y2,PetscReal x3,PetscReal y3,int c1,int c2,int c3)
10432115b0cSJose E. Roman {
10532115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
10632115b0cSJose E. Roman 
10732115b0cSJose E. Roman   PetscFunctionBegin;
10832115b0cSJose E. Roman   win->written = PETSC_TRUE;
109*9566063dSJacob Faibussowitsch   PetscCall(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)));
11032115b0cSJose E. Roman   PetscFunctionReturn(0);
11132115b0cSJose E. Roman }
11232115b0cSJose E. Roman 
11332115b0cSJose E. Roman static PetscErrorCode PetscDrawEllipse_TikZ(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
11432115b0cSJose E. Roman {
11532115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
11632115b0cSJose E. Roman   PetscReal      rx,ry;
11732115b0cSJose E. Roman 
11832115b0cSJose E. Roman   PetscFunctionBegin;
11932115b0cSJose E. Roman   win->written = PETSC_TRUE;
12032115b0cSJose E. Roman   rx = a/2*(draw->port_xr-draw->port_xl)/(draw->coor_xr-draw->coor_xl);
12132115b0cSJose E. Roman   ry = b/2*(draw->port_yr-draw->port_yl)/(draw->coor_yr-draw->coor_yl);
122*9566063dSJacob Faibussowitsch   PetscCall(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));
12332115b0cSJose E. Roman   PetscFunctionReturn(0);
12432115b0cSJose E. Roman }
12532115b0cSJose E. Roman 
126eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
12742963b84SBarry Smith {
12842963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
12942963b84SBarry Smith 
13042963b84SBarry Smith   PetscFunctionBegin;
13142963b84SBarry Smith   win->written = PETSC_TRUE;
132*9566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [above right, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text));
13342963b84SBarry Smith   PetscFunctionReturn(0);
13442963b84SBarry Smith }
13542963b84SBarry Smith 
136eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
137d6ed00deSBarry Smith {
138d6ed00deSBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
139d6ed00deSBarry Smith   size_t         len;
140d6ed00deSBarry Smith   PetscReal      width;
141d6ed00deSBarry Smith 
142d6ed00deSBarry Smith   PetscFunctionBegin;
143d6ed00deSBarry Smith   win->written = PETSC_TRUE;
144*9566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(text,&len));
145*9566063dSJacob Faibussowitsch   PetscCall(PetscDrawStringGetSize(draw,&width,NULL));
146d6ed00deSBarry Smith   yl   = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
147*9566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [rotate=90, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text));
148d6ed00deSBarry Smith   PetscFunctionReturn(0);
149d6ed00deSBarry Smith }
150d6ed00deSBarry Smith 
15142963b84SBarry Smith /*
15242963b84SBarry Smith     Does not handle multiline strings correctly
15342963b84SBarry Smith */
154eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
15542963b84SBarry Smith {
15642963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
15742963b84SBarry Smith   size_t         len;
15842963b84SBarry Smith 
15942963b84SBarry Smith   PetscFunctionBegin;
16042963b84SBarry Smith   win->written = PETSC_TRUE;
161*9566063dSJacob Faibussowitsch   PetscCall(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));
16242963b84SBarry Smith 
16342963b84SBarry Smith   /* make up totally bogus height and width of box */
164*9566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(text,&len));
16542963b84SBarry Smith   if (w) *w = .07*len;
16642963b84SBarry Smith   if (h) *h = .07;
16742963b84SBarry Smith   PetscFunctionReturn(0);
16842963b84SBarry Smith }
16942963b84SBarry Smith 
170eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal  *y)
171d6ed00deSBarry Smith {
172d6ed00deSBarry Smith   PetscFunctionBegin;
173d6ed00deSBarry Smith   if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
174d6ed00deSBarry Smith   if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
175d6ed00deSBarry Smith   PetscFunctionReturn(0);
176d6ed00deSBarry Smith }
177d6ed00deSBarry Smith 
17802c9f0b5SLisandro Dalcin static struct _PetscDrawOps DvOps = { NULL,
17902c9f0b5SLisandro Dalcin                                       NULL,
18042963b84SBarry Smith                                       PetscDrawLine_TikZ,
18102c9f0b5SLisandro Dalcin                                       NULL,
18202c9f0b5SLisandro Dalcin                                       NULL,
18302c9f0b5SLisandro Dalcin                                       NULL,
18402c9f0b5SLisandro Dalcin                                       NULL,
18542963b84SBarry Smith                                       PetscDrawString_TikZ,
186d6ed00deSBarry Smith                                       PetscDrawStringVertical_TikZ,
18702c9f0b5SLisandro Dalcin                                       NULL,
188d6ed00deSBarry Smith                                       PetscDrawStringGetSize_TikZ,
18902c9f0b5SLisandro Dalcin                                       NULL,
19042963b84SBarry Smith                                       PetscDrawClear_TikZ,
19132115b0cSJose E. Roman                                       PetscDrawRectangle_TikZ,
19232115b0cSJose E. Roman                                       PetscDrawTriangle_TikZ,
19332115b0cSJose E. Roman                                       PetscDrawEllipse_TikZ,
19402c9f0b5SLisandro Dalcin                                       NULL,
19502c9f0b5SLisandro Dalcin                                       NULL,
19602c9f0b5SLisandro Dalcin                                       NULL,
19702c9f0b5SLisandro Dalcin                                       NULL,
19802c9f0b5SLisandro Dalcin                                       NULL,
19902c9f0b5SLisandro Dalcin                                       NULL,
20002c9f0b5SLisandro Dalcin                                       NULL,
20102c9f0b5SLisandro Dalcin                                       NULL,
20242963b84SBarry Smith                                       PetscDrawDestroy_TikZ,
20302c9f0b5SLisandro Dalcin                                       NULL,
20402c9f0b5SLisandro Dalcin                                       NULL,
20502c9f0b5SLisandro Dalcin                                       NULL,
20602c9f0b5SLisandro Dalcin                                       NULL,
20702c9f0b5SLisandro Dalcin                                       NULL,
20802c9f0b5SLisandro Dalcin                                       NULL,
20902c9f0b5SLisandro Dalcin                                       NULL,
21002c9f0b5SLisandro Dalcin                                       NULL,
21102c9f0b5SLisandro Dalcin                                       NULL,
21202c9f0b5SLisandro Dalcin                                       NULL,
21351fa3d41SBarry Smith                                       PetscDrawStringBoxed_TikZ};
21442963b84SBarry Smith 
2158cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
21642963b84SBarry Smith {
21742963b84SBarry Smith   PetscDraw_TikZ *win;
21842963b84SBarry Smith 
21942963b84SBarry Smith   PetscFunctionBegin;
220*9566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps)));
221*9566063dSJacob Faibussowitsch   PetscCall(PetscNew(&win));
222*9566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ)));
223a297a907SKarl Rupp 
22442963b84SBarry Smith   draw->data = (void*) win;
22542963b84SBarry Smith 
22642963b84SBarry Smith   if (draw->title) {
227*9566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(draw->title,&win->filename));
22842963b84SBarry Smith   } else {
22942963b84SBarry Smith     const char *fname;
230*9566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)draw,&fname));
231*9566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(fname,&win->filename));
23242963b84SBarry Smith   }
233*9566063dSJacob Faibussowitsch   PetscCall(PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd));
234*9566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT));
235*9566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME));
236a297a907SKarl Rupp 
23742963b84SBarry Smith   win->written = PETSC_FALSE;
23842963b84SBarry Smith   PetscFunctionReturn(0);
23942963b84SBarry Smith }
240