Actual source code: tikz.c

  1: /*
  2:     Defines the operations for the TikZ PetscDraw implementation.
  3: */

  5: #include <petsc/private/drawimpl.h>

  7: typedef struct {
  8:   char      *filename;
  9:   FILE      *fd;
 10:   PetscBool written;  /* something has been written to the current frame */
 11: } PetscDraw_TikZ;

 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"

 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"

 35: #define TikZ_END_FRAME "\\end{tikzpicture}\n\
 36: \\end{center}\n\
 37: \\end{changemargin}\n\
 38: \\end{frame}\n"

 40: #define TikZ_END_DOCUMENT  "\\end{document}\n"

 42: static PetscErrorCode  PetscDrawDestroy_TikZ(PetscDraw draw)
 43: {
 44:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;

 46:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);
 47:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_DOCUMENT);
 48:   PetscFClose(PetscObjectComm((PetscObject)draw),win->fd);
 49:   PetscFree(win->filename);
 50:   PetscFree(draw->data);
 51:   return 0;
 52: }

 54: static const char *TikZColors[] = {"white","black","red","green","cyan","blue","magenta",NULL,NULL,"orange","violet","brown","pink",NULL,"yellow",NULL};

 56: static inline const char *TikZColorMap(int cl)
 57: {
 58:   return((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black");
 59: }

 61: /*
 62:      These macros transform from the users coordinates to the (0,0) -> (1,1) coordinate system
 63: */
 64: #define XTRANS(draw,x)  (double)(((draw)->port_xl + (((x - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl))))
 65: #define YTRANS(draw,y)  (double)(((draw)->port_yl + (((y - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl))))

 67: static PetscErrorCode PetscDrawClear_TikZ(PetscDraw draw)
 68: {
 69:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
 70:   PetscBool      written;

 72:   /* often PETSc generates unneeded clears, we want avoid creating empy pictures for them */
 73:   MPI_Allreduce(&win->written,&written,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)(draw)));
 74:   if (!written) return 0;
 75:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_END_FRAME);
 76:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);
 77:   win->written = PETSC_FALSE;
 78:   return 0;
 79: }

 81: static PetscErrorCode PetscDrawLine_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
 82: {
 83:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;

 85:   win->written = PETSC_TRUE;
 86:   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));
 87:   return 0;
 88: }

 90: static PetscErrorCode PetscDrawRectangle_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
 91: {
 92:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;

 94:   win->written = PETSC_TRUE;
 95:   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));
 96:   return 0;
 97: }

 99: static PetscErrorCode PetscDrawTriangle_TikZ(PetscDraw draw,PetscReal x1,PetscReal y1,PetscReal x2,PetscReal y2,PetscReal x3,PetscReal y3,int c1,int c2,int c3)
100: {
101:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;

103:   win->written = PETSC_TRUE;
104:   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));
105:   return 0;
106: }

108: static PetscErrorCode PetscDrawEllipse_TikZ(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
109: {
110:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
111:   PetscReal      rx,ry;

113:   win->written = PETSC_TRUE;
114:   rx = a/2*(draw->port_xr-draw->port_xl)/(draw->coor_xr-draw->coor_xl);
115:   ry = b/2*(draw->port_yr-draw->port_yl)/(draw->coor_yr-draw->coor_yl);
116:   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);
117:   return 0;
118: }

120: static PetscErrorCode PetscDrawString_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
121: {
122:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;

124:   win->written = PETSC_TRUE;
125:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [above right, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
126:   return 0;
127: }

129: static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
130: {
131:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
132:   size_t         len;
133:   PetscReal      width;

135:   win->written = PETSC_TRUE;
136:   PetscStrlen(text,&len);
137:   PetscDrawStringGetSize(draw,&width,NULL);
138:   yl   = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
139:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [rotate=90, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
140:   return 0;
141: }

143: /*
144:     Does not handle multiline strings correctly
145: */
146: static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
147: {
148:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
149:   size_t         len;

151:   win->written = PETSC_TRUE;
152:   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);

154:   /* make up totally bogus height and width of box */
155:   PetscStrlen(text,&len);
156:   if (w) *w = .07*len;
157:   if (h) *h = .07;
158:   return 0;
159: }

161: static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal  *y)
162: {
163:   if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
164:   if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
165:   return 0;
166: }

168: static struct _PetscDrawOps DvOps = { NULL,
169:                                       NULL,
170:                                       PetscDrawLine_TikZ,
171:                                       NULL,
172:                                       NULL,
173:                                       NULL,
174:                                       NULL,
175:                                       PetscDrawString_TikZ,
176:                                       PetscDrawStringVertical_TikZ,
177:                                       NULL,
178:                                       PetscDrawStringGetSize_TikZ,
179:                                       NULL,
180:                                       PetscDrawClear_TikZ,
181:                                       PetscDrawRectangle_TikZ,
182:                                       PetscDrawTriangle_TikZ,
183:                                       PetscDrawEllipse_TikZ,
184:                                       NULL,
185:                                       NULL,
186:                                       NULL,
187:                                       NULL,
188:                                       NULL,
189:                                       NULL,
190:                                       NULL,
191:                                       NULL,
192:                                       PetscDrawDestroy_TikZ,
193:                                       NULL,
194:                                       NULL,
195:                                       NULL,
196:                                       NULL,
197:                                       NULL,
198:                                       NULL,
199:                                       NULL,
200:                                       NULL,
201:                                       NULL,
202:                                       NULL,
203:                                       PetscDrawStringBoxed_TikZ};

205: PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
206: {
207:   PetscDraw_TikZ *win;

209:   PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
210:   PetscNew(&win);
211:   PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));

213:   draw->data = (void*) win;

215:   if (draw->title) {
216:     PetscStrallocpy(draw->title,&win->filename);
217:   } else {
218:     const char *fname;
219:     PetscObjectGetName((PetscObject)draw,&fname);
220:     PetscStrallocpy(fname,&win->filename);
221:   }
222:   PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);
223:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);
224:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);

226:   win->written = PETSC_FALSE;
227:   return 0;
228: }