1 /* 2 Defines the operations for the TikZ PetscDraw implementation. 3 */ 4 5 #include <petsc/private/drawimpl.h> /*I "petscsys.h" I*/ 6 7 typedef struct { 8 char *filename; 9 FILE *fd; 10 PetscBool written; /* something has been written to the current frame */ 11 } PetscDraw_TikZ; 12 13 #define TikZ_BEGIN_DOCUMENT "\\documentclass{beamer}\n\n\ 14 \\usepackage{tikz}\n\ 15 \\usepackage{pgflibraryshapes}\n\ 16 \\usetikzlibrary{backgrounds}\n\ 17 \\usetikzlibrary{arrows}\n\ 18 \\newenvironment{changemargin}[2]{%%\n\ 19 \\begin{list}{}{%%\n\ 20 \\setlength{\\topsep}{0pt}%%\n\ 21 \\setlength{\\leftmargin}{#1}%%\n\ 22 \\setlength{\\rightmargin}{#2}%%\n\ 23 \\setlength{\\listparindent}{\\parindent}%%\n\ 24 \\setlength{\\itemindent}{\\parindent}%%\n\ 25 \\setlength{\\parsep}{\\parskip}%%\n\ 26 }%%\n\ 27 \\item[]}{\\end{list}}\n\n\ 28 \\begin{document}\n" 29 30 #define TikZ_BEGIN_FRAME "\\begin{frame}{}\n\ 31 \\begin{changemargin}{-1cm}{0cm}\n\ 32 \\begin{center}\n\ 33 \\begin{tikzpicture}[scale = 10.00,font=\\fontsize{8}{8}\\selectfont]\n" 34 35 #define TikZ_END_FRAME "\\end{tikzpicture}\n\ 36 \\end{center}\n\ 37 \\end{changemargin}\n\ 38 \\end{frame}\n" 39 40 #define TikZ_END_DOCUMENT "\\end{document}\n" 41 42 #undef __FUNCT__ 43 #define __FUNCT__ "PetscDrawDestroy_TikZ" 44 static PetscErrorCode PetscDrawDestroy_TikZ(PetscDraw draw) 45 { 46 PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data; 47 PetscErrorCode ierr; 48 49 PetscFunctionBegin; 50 ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);CHKERRQ(ierr); 51 ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_DOCUMENT);CHKERRQ(ierr); 52 ierr = PetscFClose(PetscObjectComm((PetscObject)draw),win->fd);CHKERRQ(ierr); 53 ierr = PetscFree(win->filename);CHKERRQ(ierr); 54 ierr = PetscFree(draw->data);CHKERRQ(ierr); 55 PetscFunctionReturn(0); 56 } 57 58 static const char *TikZColors[] = {"white","black","red","green","cyan","blue","magenta",0,0,"orange","violet","brown","pink",0,"yellow",0}; 59 60 PETSC_STATIC_INLINE const char *TikZColorMap(int cl) 61 { 62 return((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black"); 63 } 64 65 /* 66 These macros transform from the users coordinates to the (0,0) -> (1,1) coordinate system 67 */ 68 #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 #define YTRANS(draw,y) (double)(((draw)->port_yl + (((y - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl)))) 70 71 #undef __FUNCT__ 72 #define __FUNCT__ "PetscDrawClear_TikZ" 73 static PetscErrorCode PetscDrawClear_TikZ(PetscDraw draw) 74 { 75 PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data; 76 PetscBool written; 77 PetscErrorCode ierr; 78 79 PetscFunctionBegin; 80 /* often PETSc generates unneeded clears, we want avoid creating empy pictures for them */ 81 ierr = MPI_Allreduce(&win->written,&written,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)(draw)));CHKERRQ(ierr); 82 if (!written) PetscFunctionReturn(0); 83 ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);CHKERRQ(ierr); 84 ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);CHKERRQ(ierr); 85 win->written = PETSC_FALSE; 86 PetscFunctionReturn(0); 87 } 88 89 #undef __FUNCT__ 90 #define __FUNCT__ "PetscDrawLine_TikZ" 91 static PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl) 92 { 93 PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data; 94 PetscErrorCode ierr; 95 96 PetscFunctionBegin; 97 win->written = PETSC_TRUE; 98 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); 99 PetscFunctionReturn(0); 100 } 101 102 #undef __FUNCT__ 103 #define __FUNCT__ "PetscDrawString_TikZ" 104 static PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[]) 105 { 106 PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data; 107 PetscErrorCode ierr; 108 109 PetscFunctionBegin; 110 win->written = PETSC_TRUE; 111 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); 112 PetscFunctionReturn(0); 113 } 114 115 #undef __FUNCT__ 116 #define __FUNCT__ "PetscDrawStringVertical_TikZ" 117 static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[]) 118 { 119 PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data; 120 PetscErrorCode ierr; 121 size_t len; 122 PetscReal width; 123 124 PetscFunctionBegin; 125 win->written = PETSC_TRUE; 126 ierr = PetscStrlen(text,&len);CHKERRQ(ierr); 127 ierr = PetscDrawStringGetSize(draw,&width,NULL);CHKERRQ(ierr); 128 yl = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl); 129 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); 130 PetscFunctionReturn(0); 131 } 132 133 #undef __FUNCT__ 134 #define __FUNCT__ "PetscDrawStringBoxed_TikZ" 135 /* 136 Does not handle multiline strings correctly 137 */ 138 static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h) 139 { 140 PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data; 141 PetscErrorCode ierr; 142 size_t len; 143 144 PetscFunctionBegin; 145 win->written = PETSC_TRUE; 146 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); 147 148 /* make up totally bogus height and width of box */ 149 ierr = PetscStrlen(text,&len);CHKERRQ(ierr); 150 if (w) *w = .07*len; 151 if (h) *h = .07; 152 PetscFunctionReturn(0); 153 } 154 155 #undef __FUNCT__ 156 #define __FUNCT__ "PetscDrawStringGetSize_TikZ" 157 static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal *y) 158 { 159 PetscFunctionBegin; 160 if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl)); 161 if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl)); 162 PetscFunctionReturn(0); 163 } 164 165 static struct _PetscDrawOps DvOps = { 0, 166 0, 167 PetscDrawLine_TikZ, 168 0, 169 0, 170 0, 171 0, 172 PetscDrawString_TikZ, 173 PetscDrawStringVertical_TikZ, 174 0, 175 PetscDrawStringGetSize_TikZ, 176 0, 177 PetscDrawClear_TikZ, 178 0, 179 0, 180 0, 181 0, 182 0, 183 0, 184 0, 185 0, 186 0, 187 0, 188 0, 189 PetscDrawDestroy_TikZ, 190 0, 191 0, 192 0, 193 0, 194 0, 195 0, 196 0, 197 0, 198 0, 199 0, 200 PetscDrawStringBoxed_TikZ}; 201 202 #undef __FUNCT__ 203 #define __FUNCT__ "PetscDrawCreate_TikZ" 204 PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw) 205 { 206 PetscDraw_TikZ *win; 207 PetscErrorCode ierr; 208 209 PetscFunctionBegin; 210 ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr); 211 ierr = PetscNew(&win);CHKERRQ(ierr); 212 ierr = PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));CHKERRQ(ierr); 213 214 draw->data = (void*) win; 215 216 if (draw->title) { 217 ierr = PetscStrallocpy(draw->title,&win->filename);CHKERRQ(ierr); 218 } else { 219 const char *fname; 220 ierr = PetscObjectGetName((PetscObject)draw,&fname);CHKERRQ(ierr); 221 ierr = PetscStrallocpy(fname,&win->filename);CHKERRQ(ierr); 222 } 223 ierr = PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);CHKERRQ(ierr); 224 ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);CHKERRQ(ierr); 225 ierr = PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);CHKERRQ(ierr); 226 227 win->written = PETSC_FALSE; 228 PetscFunctionReturn(0); 229 } 230