xref: /petsc/src/sys/classes/draw/impls/tikz/tikz.c (revision 32115b0cc036d49ff1f6481cb12d58df75dab440)
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   PetscErrorCode ierr;
4642963b84SBarry Smith 
4742963b84SBarry Smith   PetscFunctionBegin;
48ce94432eSBarry Smith   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);CHKERRQ(ierr);
49ce94432eSBarry Smith   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_DOCUMENT);CHKERRQ(ierr);
50ce94432eSBarry Smith   ierr = PetscFClose(PetscObjectComm((PetscObject)draw),win->fd);CHKERRQ(ierr);
5142963b84SBarry Smith   ierr = PetscFree(win->filename);CHKERRQ(ierr);
5250c74209SLisandro Dalcin   ierr = PetscFree(draw->data);CHKERRQ(ierr);
5342963b84SBarry Smith   PetscFunctionReturn(0);
5442963b84SBarry Smith }
5542963b84SBarry Smith 
56183a438dSBarry Smith static const char *TikZColors[] = {"white","black","red","green","cyan","blue","magenta",0,0,"orange","violet","brown","pink",0,"yellow",0};
5742963b84SBarry Smith 
5842963b84SBarry Smith PETSC_STATIC_INLINE const char *TikZColorMap(int cl)
5942963b84SBarry Smith {
6042963b84SBarry Smith   return((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black");
6142963b84SBarry Smith }
6242963b84SBarry Smith 
6342963b84SBarry Smith /*
6442963b84SBarry Smith      These macros transform from the users coordinates to the (0,0) -> (1,1) coordinate system
6542963b84SBarry Smith */
6642963b84SBarry 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))))
6742963b84SBarry 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))))
6842963b84SBarry Smith 
69eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawClear_TikZ(PetscDraw draw)
7042963b84SBarry Smith {
7142963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
725b399a63SLisandro Dalcin   PetscBool      written;
7342963b84SBarry Smith   PetscErrorCode ierr;
7442963b84SBarry Smith 
7542963b84SBarry Smith   PetscFunctionBegin;
7642963b84SBarry Smith   /* often PETSc generates unneeded clears, we want avoid creating empy pictures for them */
775b399a63SLisandro Dalcin   ierr = MPI_Allreduce(&win->written,&written,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)(draw)));CHKERRQ(ierr);
785b399a63SLisandro Dalcin   if (!written) PetscFunctionReturn(0);
79ce94432eSBarry Smith   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);CHKERRQ(ierr);
80ce94432eSBarry Smith   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);CHKERRQ(ierr);
815b399a63SLisandro Dalcin   win->written = PETSC_FALSE;
8271d8d82dSLisandro Dalcin   PetscFunctionReturn(0);
8371d8d82dSLisandro Dalcin }
8471d8d82dSLisandro Dalcin 
85eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
8642963b84SBarry Smith {
8742963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
8842963b84SBarry Smith   PetscErrorCode ierr;
8942963b84SBarry Smith 
9042963b84SBarry Smith   PetscFunctionBegin;
9142963b84SBarry Smith   win->written = PETSC_TRUE;
92ce94432eSBarry Smith   ierr = 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));CHKERRQ(ierr);
9342963b84SBarry Smith   PetscFunctionReturn(0);
9442963b84SBarry Smith }
9542963b84SBarry Smith 
96*32115b0cSJose E. Roman static PetscErrorCode PetscDrawRectangle_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
97*32115b0cSJose E. Roman {
98*32115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
99*32115b0cSJose E. Roman   PetscErrorCode ierr;
100*32115b0cSJose E. Roman 
101*32115b0cSJose E. Roman   PetscFunctionBegin;
102*32115b0cSJose E. Roman   win->written = PETSC_TRUE;
103*32115b0cSJose E. Roman   ierr = 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));CHKERRQ(ierr);
104*32115b0cSJose E. Roman   PetscFunctionReturn(0);
105*32115b0cSJose E. Roman }
106*32115b0cSJose E. Roman 
107*32115b0cSJose 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)
108*32115b0cSJose E. Roman {
109*32115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
110*32115b0cSJose E. Roman   PetscErrorCode ierr;
111*32115b0cSJose E. Roman 
112*32115b0cSJose E. Roman   PetscFunctionBegin;
113*32115b0cSJose E. Roman   win->written = PETSC_TRUE;
114*32115b0cSJose E. Roman   ierr = 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));CHKERRQ(ierr);
115*32115b0cSJose E. Roman   PetscFunctionReturn(0);
116*32115b0cSJose E. Roman }
117*32115b0cSJose E. Roman 
118*32115b0cSJose E. Roman static PetscErrorCode PetscDrawEllipse_TikZ(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
119*32115b0cSJose E. Roman {
120*32115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
121*32115b0cSJose E. Roman   PetscReal      rx,ry;
122*32115b0cSJose E. Roman   PetscErrorCode ierr;
123*32115b0cSJose E. Roman 
124*32115b0cSJose E. Roman   PetscFunctionBegin;
125*32115b0cSJose E. Roman   win->written = PETSC_TRUE;
126*32115b0cSJose E. Roman   rx = a/2*(draw->port_xr-draw->port_xl)/(draw->coor_xr-draw->coor_xl);
127*32115b0cSJose E. Roman   ry = b/2*(draw->port_yr-draw->port_yl)/(draw->coor_yr-draw->coor_yl);
128*32115b0cSJose E. Roman   ierr = 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),rx,ry);CHKERRQ(ierr);
129*32115b0cSJose E. Roman   PetscFunctionReturn(0);
130*32115b0cSJose E. Roman }
131*32115b0cSJose E. Roman 
132eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
13342963b84SBarry Smith {
13442963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
13542963b84SBarry Smith   PetscErrorCode ierr;
13642963b84SBarry Smith 
13742963b84SBarry Smith   PetscFunctionBegin;
13842963b84SBarry Smith   win->written = PETSC_TRUE;
139ce94432eSBarry Smith   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [above right, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);CHKERRQ(ierr);
14042963b84SBarry Smith   PetscFunctionReturn(0);
14142963b84SBarry Smith }
14242963b84SBarry Smith 
143eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
144d6ed00deSBarry Smith {
145d6ed00deSBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
146d6ed00deSBarry Smith   PetscErrorCode ierr;
147d6ed00deSBarry Smith   size_t         len;
148d6ed00deSBarry Smith   PetscReal      width;
149d6ed00deSBarry Smith 
150d6ed00deSBarry Smith   PetscFunctionBegin;
151d6ed00deSBarry Smith   win->written = PETSC_TRUE;
152d6ed00deSBarry Smith   ierr = PetscStrlen(text,&len);CHKERRQ(ierr);
153d6ed00deSBarry Smith   ierr = PetscDrawStringGetSize(draw,&width,NULL);CHKERRQ(ierr);
154d6ed00deSBarry Smith   yl   = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
155d6ed00deSBarry Smith   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [rotate=90, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);CHKERRQ(ierr);
156d6ed00deSBarry Smith   PetscFunctionReturn(0);
157d6ed00deSBarry Smith }
158d6ed00deSBarry Smith 
15942963b84SBarry Smith /*
16042963b84SBarry Smith     Does not handle multiline strings correctly
16142963b84SBarry Smith */
162eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
16342963b84SBarry Smith {
16442963b84SBarry Smith   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
16542963b84SBarry Smith   PetscErrorCode ierr;
16642963b84SBarry Smith   size_t         len;
16742963b84SBarry Smith 
16842963b84SBarry Smith   PetscFunctionBegin;
16942963b84SBarry Smith   win->written = PETSC_TRUE;
170ce94432eSBarry Smith   ierr = 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);CHKERRQ(ierr);
17142963b84SBarry Smith 
17242963b84SBarry Smith   /* make up totally bogus height and width of box */
17342963b84SBarry Smith   ierr = PetscStrlen(text,&len);CHKERRQ(ierr);
17442963b84SBarry Smith   if (w) *w = .07*len;
17542963b84SBarry Smith   if (h) *h = .07;
17642963b84SBarry Smith   PetscFunctionReturn(0);
17742963b84SBarry Smith }
17842963b84SBarry Smith 
179eecff6a3SLisandro Dalcin static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal  *y)
180d6ed00deSBarry Smith {
181d6ed00deSBarry Smith   PetscFunctionBegin;
182d6ed00deSBarry Smith   if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
183d6ed00deSBarry Smith   if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
184d6ed00deSBarry Smith   PetscFunctionReturn(0);
185d6ed00deSBarry Smith }
186d6ed00deSBarry Smith 
18742963b84SBarry Smith static struct _PetscDrawOps DvOps = { 0,
18842963b84SBarry Smith                                       0,
18942963b84SBarry Smith                                       PetscDrawLine_TikZ,
19042963b84SBarry Smith                                       0,
19142963b84SBarry Smith                                       0,
19242963b84SBarry Smith                                       0,
19342963b84SBarry Smith                                       0,
19442963b84SBarry Smith                                       PetscDrawString_TikZ,
195d6ed00deSBarry Smith                                       PetscDrawStringVertical_TikZ,
19642963b84SBarry Smith                                       0,
197d6ed00deSBarry Smith                                       PetscDrawStringGetSize_TikZ,
19842963b84SBarry Smith                                       0,
19942963b84SBarry Smith                                       PetscDrawClear_TikZ,
200*32115b0cSJose E. Roman                                       PetscDrawRectangle_TikZ,
201*32115b0cSJose E. Roman                                       PetscDrawTriangle_TikZ,
202*32115b0cSJose E. Roman                                       PetscDrawEllipse_TikZ,
20342963b84SBarry Smith                                       0,
20442963b84SBarry Smith                                       0,
20542963b84SBarry Smith                                       0,
20642963b84SBarry Smith                                       0,
20742963b84SBarry Smith                                       0,
20842963b84SBarry Smith                                       0,
20942963b84SBarry Smith                                       0,
21042963b84SBarry Smith                                       0,
21142963b84SBarry Smith                                       PetscDrawDestroy_TikZ,
21242963b84SBarry Smith                                       0,
21342963b84SBarry Smith                                       0,
21442963b84SBarry Smith                                       0,
21542963b84SBarry Smith                                       0,
21642963b84SBarry Smith                                       0,
21742963b84SBarry Smith                                       0,
21842963b84SBarry Smith                                       0,
21942963b84SBarry Smith                                       0,
22042963b84SBarry Smith                                       0,
22142963b84SBarry Smith                                       0,
22251fa3d41SBarry Smith                                       PetscDrawStringBoxed_TikZ};
22342963b84SBarry Smith 
2248cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
22542963b84SBarry Smith {
22642963b84SBarry Smith   PetscDraw_TikZ *win;
22742963b84SBarry Smith   PetscErrorCode ierr;
22842963b84SBarry Smith 
22942963b84SBarry Smith   PetscFunctionBegin;
23042963b84SBarry Smith   ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
231b00a9115SJed Brown   ierr = PetscNew(&win);CHKERRQ(ierr);
2323bb1ff40SBarry Smith   ierr = PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));CHKERRQ(ierr);
233a297a907SKarl Rupp 
23442963b84SBarry Smith   draw->data = (void*) win;
23542963b84SBarry Smith 
23642963b84SBarry Smith   if (draw->title) {
23742963b84SBarry Smith     ierr = PetscStrallocpy(draw->title,&win->filename);CHKERRQ(ierr);
23842963b84SBarry Smith   } else {
23942963b84SBarry Smith     const char *fname;
24042963b84SBarry Smith     ierr = PetscObjectGetName((PetscObject)draw,&fname);CHKERRQ(ierr);
24142963b84SBarry Smith     ierr = PetscStrallocpy(fname,&win->filename);CHKERRQ(ierr);
24242963b84SBarry Smith   }
243ce94432eSBarry Smith   ierr = PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);CHKERRQ(ierr);
244ce94432eSBarry Smith   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);CHKERRQ(ierr);
245ce94432eSBarry Smith   ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);CHKERRQ(ierr);
246a297a907SKarl Rupp 
24742963b84SBarry Smith   win->written = PETSC_FALSE;
24842963b84SBarry Smith   PetscFunctionReturn(0);
24942963b84SBarry Smith }
250