Actual source code: tikz.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      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;

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

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

     58: PETSC_STATIC_INLINE const char *TikZColorMap(int cl)
     59: {
     60:   return((cl < 16) ? (TikZColors[cl] ? TikZColors[cl] : "black") : "black");
     61: }

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

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

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

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

     91:   win->written = PETSC_TRUE;
     92:   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));
     93:   return(0);
     94: }

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

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

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

    113:   win->written = PETSC_TRUE;
    114:   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));
    115:   return(0);
    116: }

    118: static PetscErrorCode PetscDrawEllipse_TikZ(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
    119: {
    120:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
    121:   PetscReal      rx,ry;

    125:   win->written = PETSC_TRUE;
    126:   rx = a/2*(draw->port_xr-draw->port_xl)/(draw->coor_xr-draw->coor_xl);
    127:   ry = b/2*(draw->port_yr-draw->port_yl)/(draw->coor_yr-draw->coor_yl);
    128:   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);
    129:   return(0);
    130: }

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

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

    143: static PetscErrorCode PetscDrawStringVertical_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,const char text[])
    144: {
    145:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
    147:   size_t         len;
    148:   PetscReal      width;

    151:   win->written = PETSC_TRUE;
    152:   PetscStrlen(text,&len);
    153:   PetscDrawStringGetSize(draw,&width,NULL);
    154:   yl   = yl - len*width*(draw->coor_yr - draw->coor_yl)/(draw->coor_xr - draw->coor_xl);
    155:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,"\\node [rotate=90, %s] at (%g,%g) {%s};\n",TikZColorMap(cl),XTRANS(draw,xl),YTRANS(draw,yl),text);
    156:   return(0);
    157: }

    159: /*
    160:     Does not handle multiline strings correctly
    161: */
    162: static PetscErrorCode PetscDrawStringBoxed_TikZ(PetscDraw draw,PetscReal xl,PetscReal yl,int cl,int ct,const char text[],PetscReal *w,PetscReal *h)
    163: {
    164:   PetscDraw_TikZ *win = (PetscDraw_TikZ*)draw->data;
    166:   size_t         len;

    169:   win->written = PETSC_TRUE;
    170:   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);

    172:   /* make up totally bogus height and width of box */
    173:   PetscStrlen(text,&len);
    174:   if (w) *w = .07*len;
    175:   if (h) *h = .07;
    176:   return(0);
    177: }

    179: static PetscErrorCode PetscDrawStringGetSize_TikZ(PetscDraw draw,PetscReal *x,PetscReal  *y)
    180: {
    182:   if (x) *x = .014*(draw->coor_xr - draw->coor_xl)/((draw->port_xr - draw->port_xl));
    183:   if (y) *y = .05*(draw->coor_yr - draw->coor_yl)/((draw->port_yr - draw->port_yl));
    184:   return(0);
    185: }

    187: static struct _PetscDrawOps DvOps = { 0,
    188:                                       0,
    189:                                       PetscDrawLine_TikZ,
    190:                                       0,
    191:                                       0,
    192:                                       0,
    193:                                       0,
    194:                                       PetscDrawString_TikZ,
    195:                                       PetscDrawStringVertical_TikZ,
    196:                                       0,
    197:                                       PetscDrawStringGetSize_TikZ,
    198:                                       0,
    199:                                       PetscDrawClear_TikZ,
    200:                                       PetscDrawRectangle_TikZ,
    201:                                       PetscDrawTriangle_TikZ,
    202:                                       PetscDrawEllipse_TikZ,
    203:                                       0,
    204:                                       0,
    205:                                       0,
    206:                                       0,
    207:                                       0,
    208:                                       0,
    209:                                       0,
    210:                                       0,
    211:                                       PetscDrawDestroy_TikZ,
    212:                                       0,
    213:                                       0,
    214:                                       0,
    215:                                       0,
    216:                                       0,
    217:                                       0,
    218:                                       0,
    219:                                       0,
    220:                                       0,
    221:                                       0,
    222:                                       PetscDrawStringBoxed_TikZ};

    224: PETSC_EXTERN PetscErrorCode PetscDrawCreate_TikZ(PetscDraw draw)
    225: {
    226:   PetscDraw_TikZ *win;

    230:   PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
    231:   PetscNew(&win);
    232:   PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_TikZ));

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

    236:   if (draw->title) {
    237:     PetscStrallocpy(draw->title,&win->filename);
    238:   } else {
    239:     const char *fname;
    240:     PetscObjectGetName((PetscObject)draw,&fname);
    241:     PetscStrallocpy(fname,&win->filename);
    242:   }
    243:   PetscFOpen(PetscObjectComm((PetscObject)draw),win->filename,"w",&win->fd);
    244:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_DOCUMENT);
    245:   PetscFPrintf(PetscObjectComm((PetscObject)draw),win->fd,TikZ_BEGIN_FRAME);

    247:   win->written = PETSC_FALSE;
    248:   return(0);
    249: }