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 139371c9d4SSatish Balay #define TikZ_BEGIN_DOCUMENT \ 149371c9d4SSatish Balay "\\documentclass{beamer}\n\n\ 1542963b84SBarry Smith \\usepackage{tikz}\n\ 1642963b84SBarry Smith \\usepackage{pgflibraryshapes}\n\ 1742963b84SBarry Smith \\usetikzlibrary{backgrounds}\n\ 1842963b84SBarry Smith \\usetikzlibrary{arrows}\n\ 1942963b84SBarry Smith \\newenvironment{changemargin}[2]{%%\n\ 2042963b84SBarry Smith \\begin{list}{}{%%\n\ 2142963b84SBarry Smith \\setlength{\\topsep}{0pt}%%\n\ 2242963b84SBarry Smith \\setlength{\\leftmargin}{#1}%%\n\ 2342963b84SBarry Smith \\setlength{\\rightmargin}{#2}%%\n\ 2442963b84SBarry Smith \\setlength{\\listparindent}{\\parindent}%%\n\ 2542963b84SBarry Smith \\setlength{\\itemindent}{\\parindent}%%\n\ 2642963b84SBarry Smith \\setlength{\\parsep}{\\parskip}%%\n\ 2742963b84SBarry Smith }%%\n\ 2842963b84SBarry Smith \\item[]}{\\end{list}}\n\n\ 2942963b84SBarry Smith \\begin{document}\n" 3042963b84SBarry Smith 319371c9d4SSatish Balay #define TikZ_BEGIN_FRAME \ 329371c9d4SSatish Balay "\\begin{frame}{}\n\ 3342963b84SBarry Smith \\begin{changemargin}{-1cm}{0cm}\n\ 3442963b84SBarry Smith \\begin{center}\n\ 3542963b84SBarry Smith \\begin{tikzpicture}[scale = 10.00,font=\\fontsize{8}{8}\\selectfont]\n" 3642963b84SBarry Smith 379371c9d4SSatish Balay #define TikZ_END_FRAME \ 389371c9d4SSatish Balay "\\end{tikzpicture}\n\ 3942963b84SBarry Smith \\end{center}\n\ 4042963b84SBarry Smith \\end{changemargin}\n\ 4142963b84SBarry Smith \\end{frame}\n" 4242963b84SBarry Smith 4342963b84SBarry Smith #define TikZ_END_DOCUMENT "\\end{document}\n" 4442963b84SBarry Smith 45d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawDestroy_TikZ(PetscDraw draw) 46d71ae5a4SJacob Faibussowitsch { 4742963b84SBarry Smith PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 4842963b84SBarry Smith 4942963b84SBarry Smith PetscFunctionBegin; 509566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw), win->fd, TikZ_END_FRAME)); 519566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw), win->fd, TikZ_END_DOCUMENT)); 529566063dSJacob Faibussowitsch PetscCall(PetscFClose(PetscObjectComm((PetscObject)draw), win->fd)); 539566063dSJacob Faibussowitsch PetscCall(PetscFree(win->filename)); 549566063dSJacob Faibussowitsch PetscCall(PetscFree(draw->data)); 553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5642963b84SBarry Smith } 5742963b84SBarry Smith 5802c9f0b5SLisandro Dalcin static const char *TikZColors[] = {"white", "black", "red", "green", "cyan", "blue", "magenta", NULL, NULL, "orange", "violet", "brown", "pink", NULL, "yellow", NULL}; 5942963b84SBarry Smith 60d71ae5a4SJacob Faibussowitsch static inline const char *TikZColorMap(int cl) 61d71ae5a4SJacob Faibussowitsch { 6242963b84SBarry Smith return ((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black"); 6342963b84SBarry Smith } 6442963b84SBarry Smith 6542963b84SBarry Smith /* 6642963b84SBarry Smith These macros transform from the users coordinates to the (0,0) -> (1,1) coordinate system 6742963b84SBarry Smith */ 68*f4f49eeaSPierre Jolivet #define XTRANS(draw, x) (double)((draw)->port_xl + (((x - (draw)->coor_xl) * ((draw)->port_xr - (draw)->port_xl)) / ((draw)->coor_xr - (draw)->coor_xl))) 69*f4f49eeaSPierre Jolivet #define YTRANS(draw, y) (double)((draw)->port_yl + (((y - (draw)->coor_yl) * ((draw)->port_yr - (draw)->port_yl)) / ((draw)->coor_yr - (draw)->coor_yl))) 7042963b84SBarry Smith 71d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawClear_TikZ(PetscDraw draw) 72d71ae5a4SJacob Faibussowitsch { 7342963b84SBarry Smith PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 745b399a63SLisandro Dalcin PetscBool written; 7542963b84SBarry Smith 7642963b84SBarry Smith PetscFunctionBegin; 77da81f932SPierre Jolivet /* often PETSc generates unneeded clears, we want avoid creating empty pictures for them */ 78*f4f49eeaSPierre Jolivet PetscCall(MPIU_Allreduce(&win->written, &written, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)draw))); 793ba16761SJacob Faibussowitsch if (!written) PetscFunctionReturn(PETSC_SUCCESS); 809566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw), win->fd, TikZ_END_FRAME)); 819566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw), win->fd, TikZ_BEGIN_FRAME)); 825b399a63SLisandro Dalcin win->written = PETSC_FALSE; 833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8471d8d82dSLisandro Dalcin } 8571d8d82dSLisandro Dalcin 86d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int cl) 87d71ae5a4SJacob Faibussowitsch { 8842963b84SBarry Smith PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 8942963b84SBarry Smith 9042963b84SBarry Smith PetscFunctionBegin; 9142963b84SBarry Smith win->written = PETSC_TRUE; 929566063dSJacob 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))); 933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9442963b84SBarry Smith } 9542963b84SBarry Smith 96d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawRectangle_TikZ(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4) 97d71ae5a4SJacob Faibussowitsch { 9832115b0cSJose E. Roman PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 9932115b0cSJose E. Roman 10032115b0cSJose E. Roman PetscFunctionBegin; 10132115b0cSJose E. Roman win->written = PETSC_TRUE; 1029566063dSJacob 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))); 1033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10432115b0cSJose E. Roman } 10532115b0cSJose E. Roman 106d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawTriangle_TikZ(PetscDraw draw, PetscReal x1, PetscReal y1, PetscReal x2, PetscReal y2, PetscReal x3, PetscReal y3, int c1, int c2, int c3) 107d71ae5a4SJacob Faibussowitsch { 10832115b0cSJose E. Roman PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 10932115b0cSJose E. Roman 11032115b0cSJose E. Roman PetscFunctionBegin; 11132115b0cSJose E. Roman win->written = PETSC_TRUE; 1129566063dSJacob 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))); 1133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11432115b0cSJose E. Roman } 11532115b0cSJose E. Roman 116d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawEllipse_TikZ(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c) 117d71ae5a4SJacob Faibussowitsch { 11832115b0cSJose E. Roman PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 11932115b0cSJose E. Roman PetscReal rx, ry; 12032115b0cSJose E. Roman 12132115b0cSJose E. Roman PetscFunctionBegin; 12232115b0cSJose E. Roman win->written = PETSC_TRUE; 12332115b0cSJose E. Roman rx = a / 2 * (draw->port_xr - draw->port_xl) / (draw->coor_xr - draw->coor_xl); 12432115b0cSJose E. Roman ry = b / 2 * (draw->port_yr - draw->port_yl) / (draw->coor_yr - draw->coor_yl); 1259566063dSJacob 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)); 1263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12732115b0cSJose E. Roman } 12832115b0cSJose E. Roman 129d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawString_TikZ(PetscDraw draw, PetscReal xl, PetscReal yl, int cl, const char text[]) 130d71ae5a4SJacob Faibussowitsch { 13142963b84SBarry Smith PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 13242963b84SBarry Smith 13342963b84SBarry Smith PetscFunctionBegin; 13442963b84SBarry Smith win->written = PETSC_TRUE; 1359566063dSJacob 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)); 1363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13742963b84SBarry Smith } 13842963b84SBarry Smith 139d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw, PetscReal xl, PetscReal yl, int cl, const char text[]) 140d71ae5a4SJacob Faibussowitsch { 141d6ed00deSBarry Smith PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 142d6ed00deSBarry Smith size_t len; 143d6ed00deSBarry Smith PetscReal width; 144d6ed00deSBarry Smith 145d6ed00deSBarry Smith PetscFunctionBegin; 146d6ed00deSBarry Smith win->written = PETSC_TRUE; 1479566063dSJacob Faibussowitsch PetscCall(PetscStrlen(text, &len)); 1489566063dSJacob Faibussowitsch PetscCall(PetscDrawStringGetSize(draw, &width, NULL)); 149d6ed00deSBarry Smith yl = yl - len * width * (draw->coor_yr - draw->coor_yl) / (draw->coor_xr - draw->coor_xl); 1509566063dSJacob 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)); 1513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 152d6ed00deSBarry Smith } 153d6ed00deSBarry Smith 15442963b84SBarry Smith /* 15542963b84SBarry Smith Does not handle multiline strings correctly 15642963b84SBarry Smith */ 157d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw, PetscReal xl, PetscReal yl, int cl, int ct, const char text[], PetscReal *w, PetscReal *h) 158d71ae5a4SJacob Faibussowitsch { 15942963b84SBarry Smith PetscDraw_TikZ *win = (PetscDraw_TikZ *)draw->data; 16042963b84SBarry Smith size_t len; 16142963b84SBarry Smith 16242963b84SBarry Smith PetscFunctionBegin; 16342963b84SBarry Smith win->written = PETSC_TRUE; 1649566063dSJacob 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)); 16542963b84SBarry Smith 16642963b84SBarry Smith /* make up totally bogus height and width of box */ 1679566063dSJacob Faibussowitsch PetscCall(PetscStrlen(text, &len)); 16842963b84SBarry Smith if (w) *w = .07 * len; 16942963b84SBarry Smith if (h) *h = .07; 1703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17142963b84SBarry Smith } 17242963b84SBarry Smith 173d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw, PetscReal *x, PetscReal *y) 174d71ae5a4SJacob Faibussowitsch { 175d6ed00deSBarry Smith PetscFunctionBegin; 176*f4f49eeaSPierre Jolivet if (x) *x = .014 * (draw->coor_xr - draw->coor_xl) / (draw->port_xr - draw->port_xl); 177*f4f49eeaSPierre Jolivet if (y) *y = .05 * (draw->coor_yr - draw->coor_yl) / (draw->port_yr - draw->port_yl); 1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 179d6ed00deSBarry Smith } 180d6ed00deSBarry Smith 1816e4289a0SDuncan Campbell static struct _PetscDrawOps DvOps = {NULL, NULL, PetscDrawLine_TikZ, NULL, NULL, NULL, NULL, PetscDrawString_TikZ, PetscDrawStringVertical_TikZ, NULL, PetscDrawStringGetSize_TikZ, NULL, PetscDrawClear_TikZ, PetscDrawRectangle_TikZ, PetscDrawTriangle_TikZ, PetscDrawEllipse_TikZ, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, PetscDrawDestroy_TikZ, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, PetscDrawStringBoxed_TikZ, NULL}; 18242963b84SBarry Smith 183d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw) 184d71ae5a4SJacob Faibussowitsch { 18542963b84SBarry Smith PetscDraw_TikZ *win; 18642963b84SBarry Smith 18742963b84SBarry Smith PetscFunctionBegin; 188aea10558SJacob Faibussowitsch draw->ops[0] = DvOps; 1899566063dSJacob Faibussowitsch PetscCall(PetscNew(&win)); 190a297a907SKarl Rupp 19142963b84SBarry Smith draw->data = (void *)win; 19242963b84SBarry Smith 19342963b84SBarry Smith if (draw->title) { 1949566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(draw->title, &win->filename)); 19542963b84SBarry Smith } else { 19642963b84SBarry Smith const char *fname; 1979566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)draw, &fname)); 1989566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fname, &win->filename)); 19942963b84SBarry Smith } 2009566063dSJacob Faibussowitsch PetscCall(PetscFOpen(PetscObjectComm((PetscObject)draw), win->filename, "w", &win->fd)); 2019566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw), win->fd, TikZ_BEGIN_DOCUMENT)); 2029566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(PetscObjectComm((PetscObject)draw), win->fd, TikZ_BEGIN_FRAME)); 203a297a907SKarl Rupp 20442963b84SBarry Smith win->written = PETSC_FALSE; 2053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20642963b84SBarry Smith } 207