xref: /petsc/src/sys/classes/draw/impls/tikz/tikz.c (revision 02c9f0b548ed2228330a66acd2df0a92dd2a8bb1)
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 
56*02c9f0b5SLisandro Dalcin static const char *TikZColors[] = {"white","black","red","green","cyan","blue","magenta",NULL,NULL,"orange","violet","brown","pink",NULL,"yellow",NULL};
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 
9632115b0cSJose E. Roman static PetscErrorCode PetscDrawRectangle_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
9732115b0cSJose E. Roman {
9832115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
9932115b0cSJose E. Roman   PetscErrorCode ierr;
10032115b0cSJose E. Roman 
10132115b0cSJose E. Roman   PetscFunctionBegin;
10232115b0cSJose E. Roman   win->written = PETSC_TRUE;
10332115b0cSJose 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);
10432115b0cSJose E. Roman   PetscFunctionReturn(0);
10532115b0cSJose E. Roman }
10632115b0cSJose E. Roman 
10732115b0cSJose 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)
10832115b0cSJose E. Roman {
10932115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
11032115b0cSJose E. Roman   PetscErrorCode ierr;
11132115b0cSJose E. Roman 
11232115b0cSJose E. Roman   PetscFunctionBegin;
11332115b0cSJose E. Roman   win->written = PETSC_TRUE;
11432115b0cSJose 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);
11532115b0cSJose E. Roman   PetscFunctionReturn(0);
11632115b0cSJose E. Roman }
11732115b0cSJose E. Roman 
11832115b0cSJose E. Roman static PetscErrorCode PetscDrawEllipse_TikZ(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
11932115b0cSJose E. Roman {
12032115b0cSJose E. Roman   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
12132115b0cSJose E. Roman   PetscReal      rx,ry;
12232115b0cSJose E. Roman   PetscErrorCode ierr;
12332115b0cSJose E. Roman 
12432115b0cSJose E. Roman   PetscFunctionBegin;
12532115b0cSJose E. Roman   win->written = PETSC_TRUE;
12632115b0cSJose E. Roman   rx = a/2*(draw->port_xr-draw->port_xl)/(draw->coor_xr-draw->coor_xl);
12732115b0cSJose E. Roman   ry = b/2*(draw->port_yr-draw->port_yl)/(draw->coor_yr-draw->coor_yl);
128dd557b95SJose 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),(double)rx,(double)ry);CHKERRQ(ierr);
12932115b0cSJose E. Roman   PetscFunctionReturn(0);
13032115b0cSJose E. Roman }
13132115b0cSJose 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 
187*02c9f0b5SLisandro Dalcin static struct _PetscDrawOps DvOps = { NULL,
188*02c9f0b5SLisandro Dalcin                                       NULL,
18942963b84SBarry Smith                                       PetscDrawLine_TikZ,
190*02c9f0b5SLisandro Dalcin                                       NULL,
191*02c9f0b5SLisandro Dalcin                                       NULL,
192*02c9f0b5SLisandro Dalcin                                       NULL,
193*02c9f0b5SLisandro Dalcin                                       NULL,
19442963b84SBarry Smith                                       PetscDrawString_TikZ,
195d6ed00deSBarry Smith                                       PetscDrawStringVertical_TikZ,
196*02c9f0b5SLisandro Dalcin                                       NULL,
197d6ed00deSBarry Smith                                       PetscDrawStringGetSize_TikZ,
198*02c9f0b5SLisandro Dalcin                                       NULL,
19942963b84SBarry Smith                                       PetscDrawClear_TikZ,
20032115b0cSJose E. Roman                                       PetscDrawRectangle_TikZ,
20132115b0cSJose E. Roman                                       PetscDrawTriangle_TikZ,
20232115b0cSJose E. Roman                                       PetscDrawEllipse_TikZ,
203*02c9f0b5SLisandro Dalcin                                       NULL,
204*02c9f0b5SLisandro Dalcin                                       NULL,
205*02c9f0b5SLisandro Dalcin                                       NULL,
206*02c9f0b5SLisandro Dalcin                                       NULL,
207*02c9f0b5SLisandro Dalcin                                       NULL,
208*02c9f0b5SLisandro Dalcin                                       NULL,
209*02c9f0b5SLisandro Dalcin                                       NULL,
210*02c9f0b5SLisandro Dalcin                                       NULL,
21142963b84SBarry Smith                                       PetscDrawDestroy_TikZ,
212*02c9f0b5SLisandro Dalcin                                       NULL,
213*02c9f0b5SLisandro Dalcin                                       NULL,
214*02c9f0b5SLisandro Dalcin                                       NULL,
215*02c9f0b5SLisandro Dalcin                                       NULL,
216*02c9f0b5SLisandro Dalcin                                       NULL,
217*02c9f0b5SLisandro Dalcin                                       NULL,
218*02c9f0b5SLisandro Dalcin                                       NULL,
219*02c9f0b5SLisandro Dalcin                                       NULL,
220*02c9f0b5SLisandro Dalcin                                       NULL,
221*02c9f0b5SLisandro Dalcin                                       NULL,
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