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