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
PetscDrawDestroy_TikZ(PetscDraw draw)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
TikZColorMap(int cl)60d71ae5a4SJacob Faibussowitsch static inline const char *TikZColorMap(int cl)
61d71ae5a4SJacob Faibussowitsch {
624ad8454bSPierre Jolivet 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 */
68f4f49eeaSPierre 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)))
69f4f49eeaSPierre 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
PetscDrawClear_TikZ(PetscDraw draw)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*5440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(&win->written, &written, 1, MPI_C_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
PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)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
PetscDrawRectangle_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)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
PetscDrawTriangle_TikZ(PetscDraw draw,PetscReal x1,PetscReal y1,PetscReal x2,PetscReal y2,PetscReal x3,PetscReal y3,int c1,int c2,int c3)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
PetscDrawEllipse_TikZ(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)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
PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])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
PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])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));
1496497c311SBarry Smith yl = yl - ((PetscReal)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 */
PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal * w,PetscReal * h)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));
1686497c311SBarry Smith if (w) *w = .07 * (PetscReal)len;
16942963b84SBarry Smith if (h) *h = .07;
1703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
17142963b84SBarry Smith }
17242963b84SBarry Smith
PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal * x,PetscReal * y)173d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw, PetscReal *x, PetscReal *y)
174d71ae5a4SJacob Faibussowitsch {
175d6ed00deSBarry Smith PetscFunctionBegin;
176f4f49eeaSPierre Jolivet if (x) *x = .014 * (draw->coor_xr - draw->coor_xl) / (draw->port_xr - draw->port_xl);
177f4f49eeaSPierre 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
PetscDrawCreate_TikZ(PetscDraw draw)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