Actual source code: pops.c

  2: /*
  3:     Defines the operations for the Postscript PetscDraw implementation.
  4: */

 6:  #include src/sys/src/draw/impls/ps/psimpl.h

 10: /*@C
 11:       PetscDrawOpenPS - Opens a PetscViewer that generates Postscript

 13:   Collective on MPI_Comm

 15:   Input Parameters:
 16: +   comm - communicator that shares the PetscViewer
 17: -   file - name of file where Postscript is to be stored

 19:   Output Parameter:
 20: .  viewer - the PetscViewer object

 22:   Level: beginner

 24: .seealso: PetscDrawDestroy(), PetscDrawOpenX(), PetscDrawCreate(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw()
 25: @*/
 26: PetscErrorCode PetscDrawOpenPS(MPI_Comm comm,char *filename,PetscDraw *draw)
 27: {

 31:   PetscDrawCreate(comm,filename,0,0,0,0,0,draw);
 32:   PetscDrawSetType(*draw,PETSC_DRAW_PS);
 33:   return(0);
 34: }

 36: /*
 37:      These macros transform from the users coordinates to the Postscript
 38: */
 39: #define WIDTH  8.5*72
 40: #define HEIGHT 11*72
 41: #define XTRANS(win,x) \
 42:    ((WIDTH)*((win)->port_xl+(((x-(win)->coor_xl)*((win)->port_xr-(win)->port_xl))/((win)->coor_xr-(win)->coor_xl))))
 43: #define YTRANS(win,y) \
 44:    ((HEIGHT)*((win)->port_yl+(((y-(win)->coor_yl)*((win)->port_yr-(win)->port_yl))/((win)->coor_yr-(win)->coor_yl))))

 46: /*
 47:     Contains the RGB colors for the PETSc defined colors
 48: */
 49: static PetscReal  rgb[3][256];
 50: static PetscTruth rgbfilled = PETSC_FALSE;

 52: #define PSSetColor(ps,c)   (((c) == ps->currentcolor) ? 0 : \
 53: (ps->currentcolor = (c),PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g setrgbcolor\n",rgb[0][c],rgb[1][c],rgb[2][c])))

 57: static PetscErrorCode PetscDrawPoint_PS(PetscDraw draw,PetscReal x,PetscReal  y,int c)
 58: {
 59:   PetscReal     xx,yy;
 61:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;

 64:   xx = XTRANS(draw,x);  yy = YTRANS(draw,y);
 65:   PSSetColor(ps,c);
 66:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto stroke\n",xx,yy,xx+1,yy);
 67:   return(0);
 68: }

 72: static PetscErrorCode PetscDrawLine_PS(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
 73: {
 74:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
 75:   PetscReal     x1,y_1,x2,y2;

 79:   x1 = XTRANS(draw,xl);   x2  = XTRANS(draw,xr);
 80:   y_1 = YTRANS(draw,yl);   y2  = YTRANS(draw,yr);
 81:   PSSetColor(ps,c);
 82:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto stroke\n",x1,y_1,x2,y2);
 83:   return(0);
 84: }

 88: static PetscErrorCode PetscDrawStringSetSize_PS(PetscDraw draw,PetscReal x,PetscReal  y)
 89: {
 90:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
 92:   int           w,h;

 95:   w = (int)((WIDTH)*x*(draw->port_xr - draw->port_xl)/(draw->coor_xr - draw->coor_xl));
 96:   h = (int)((HEIGHT)*y*(draw->port_yr - draw->port_yl)/(draw->coor_yr - draw->coor_yl));
 97:   PetscViewerASCIIPrintf(ps->ps_file,"/Helvetica-normal findfont %g scalefont setfont\n",(w+h)/2.0);
 98:   return(0);
 99: }

103: static PetscErrorCode PetscDrawStringGetSize_PS(PetscDraw draw,PetscReal *x,PetscReal  *y)
104: {
105:   PetscReal   w = 9,h = 9;

108:   *x = w*(draw->coor_xr - draw->coor_xl)/(WIDTH)*(draw->port_xr - draw->port_xl);
109:   *y = h*(draw->coor_yr - draw->coor_yl)/(HEIGHT)*(draw->port_yr - draw->port_yl);
110:   return(0);
111: }

115: static PetscErrorCode PetscDrawString_PS(PetscDraw draw,PetscReal x,PetscReal  y,int c,const char chrs[])
116: {
117:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
118:   PetscReal     x1,y_1;

122:   PSSetColor(ps,c);
123:   x1 = XTRANS(draw,x);
124:   y_1 = YTRANS(draw,y);
125:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto (%s) show\n",x1,y_1,chrs);
126:   return(0);
127: }

131: static PetscErrorCode PetscDrawStringVertical_PS(PetscDraw draw,PetscReal x,PetscReal  y,int c,const char chrs[])
132: {
133:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
134:   PetscReal     x1,y_1;

138:   PSSetColor(ps,c);
139:   x1 = XTRANS(draw,x);
140:   y_1 = YTRANS(draw,y);
141:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"gsave %g %g moveto 90 rotate (%s) show grestore\n",x1,y_1,chrs);
142:   return(0);
143: }

145: static PetscErrorCode PetscDrawInterpolatedTriangle_PS(PetscDraw_PS*,PetscReal,PetscReal,int,PetscReal,PetscReal,int,PetscReal,PetscReal,int);

149: static PetscErrorCode PetscDrawTriangle_PS(PetscDraw draw,PetscReal X1,PetscReal Y_1,PetscReal X2,
150:                           PetscReal Y2,PetscReal X3,PetscReal Y3,int c1,int c2,int c3)
151: {
152:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
154:   PetscReal     x1,y_1,x2,y2,x3,y3;

157:   x1   = XTRANS(draw,X1);
158:   y_1  = YTRANS(draw,Y_1);
159:   x2   = XTRANS(draw,X2);
160:   y2   = YTRANS(draw,Y2);
161:   x3   = XTRANS(draw,X3);
162:   y3   = YTRANS(draw,Y3);

164:   if (c1 == c2 && c2 == c3) {
165:     PSSetColor(ps,c1);
166:     PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto %g %g lineto fill\n",x1,y_1,x2,y2,x3,y3);
167:   } else {
168:     PetscDrawInterpolatedTriangle_PS(ps,x1,y_1,c1,x2,y2,c2,x3,y3,c3);
169:   }
170:   return(0);
171: }

175: static PetscErrorCode PetscDrawRectangle_PS(PetscDraw draw,PetscReal X1,PetscReal Y_1,PetscReal X2,
176:                           PetscReal Y2,int c1,int c2,int c3,int c4)
177: {
178:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
180:   PetscReal     x1,y_1,x2,y2,x3,y3,x4,y4;

183:   x1   = XTRANS(draw,X1);
184:   y_1  = YTRANS(draw,Y_1);
185:   x2   = XTRANS(draw,X2);
186:   y2   = YTRANS(draw,Y_1);
187:   x3   = XTRANS(draw,X2);
188:   y3   = YTRANS(draw,Y2);
189:   x4   = XTRANS(draw,X1);
190:   y4   = YTRANS(draw,Y2);

192:   PSSetColor(ps,(c1+c2+c3+c4)/4);
193:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto %g %g lineto %g %g lineto %g %g lineto fill\n",x1,y_1,x2,y2,x3,y3,x4,y4,x1,y_1);
194:   return(0);
195: }

199: static PetscErrorCode PetscDrawDestroy_PS(PetscDraw draw)
200: {
201:   PetscDraw_PS *ps = (PetscDraw_PS*)draw->data;
203:   PetscTruth   show;
204:   char         *filename,par[PETSC_MAX_PATH_LEN];
205: 
207:   PetscViewerASCIIPrintf(ps->ps_file,"\nshowpage\n");
208:   PetscOptionsHasName(draw->prefix,"-draw_ps_show",&show);
209:   if (show) {
210:     PetscViewerGetFilename(ps->ps_file,&filename);
211:     PetscStrcpy(par,"ghostview ");
212:     PetscStrcat(par,filename);
213:     PetscPOpen(draw->comm,PETSC_NULL,par,"r",PETSC_NULL);
214:   }
215:   PetscViewerDestroy(ps->ps_file);
216:   PetscFree(ps);
217:   return(0);
218: }

222: static PetscErrorCode PetscDrawSynchronizedFlush_PS(PetscDraw draw)
223: {
225:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;

228:   PetscViewerFlush(ps->ps_file);
229:   return(0);
230: }

234: static PetscErrorCode PetscDrawSynchronizedClear_PS(PetscDraw draw)
235: {
237:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;

240:   PetscViewerFlush(ps->ps_file);
241:   PetscViewerASCIIPrintf(ps->ps_file,"\nshowpage\n");

243:   return(0);
244: }

246: static struct _PetscDrawOps DvOps = { 0,
247:                                  0,
248:                                  PetscDrawLine_PS,
249:                                  0,
250:                                  0,
251:                                  PetscDrawPoint_PS,
252:                                  0,
253:                                  PetscDrawString_PS,
254:                                  PetscDrawStringVertical_PS,
255:                                  PetscDrawStringSetSize_PS,
256:                                  PetscDrawStringGetSize_PS,
257:                                  0,
258:                                  0,
259:                                  PetscDrawSynchronizedFlush_PS,
260:                                  PetscDrawRectangle_PS,
261:                                  PetscDrawTriangle_PS,
262:                                  0,
263:                                  0,
264:                                  0,
265:                                  PetscDrawSynchronizedClear_PS,
266:                                  0,
267:                                  0,
268:                                  0,
269:                                  0,
270:                                  0,
271:                                  0,
272:                                  PetscDrawDestroy_PS,
273:                                  0,
274:                                  0,
275:                                  0 };

280: PetscErrorCode PetscDrawCreate_PS(PetscDraw draw)
281: {
282:   PetscDraw_PS  *ps;
284:   int           ncolors,i;
285:   unsigned char *red,*green,*blue;
286:   static int    filecount = 0;
287:   char          buff[32];
288:   char          version[256];

291:   if (!draw->display) {
292:     sprintf(buff,"defaultps%d.ps",filecount++);
293:     PetscStrallocpy(buff,&draw->display);
294:   }

296:   PetscGetVersion(&version);
297:   PetscNew(PetscDraw_PS,&ps);
298:   PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
299:   PetscViewerASCIIOpen(draw->comm,draw->display,&ps->ps_file);
300:   PetscViewerASCIIPrintf(ps->ps_file,"%%!PS-Adobe-2.0\n");
301:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%Creator: PETSc %s\n",version);
302:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%Title: %s\n",draw->display);
303:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%Pages: 1\n");
304:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%PageOrder: Ascend\n");
305:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%BoundingBox: 0 0 612 792\n");
306:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%DocumentFonts: Helvetica-normal Symbol\n");
307:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%EndComments\n");
308:   PetscViewerASCIIPrintf(ps->ps_file,"/Helvetica-normal findfont 10 scalefont setfont\n");
309:   PetscViewerASCIIPrintf(ps->ps_file,"/c {setrgbcolor} def\n");
310:   PetscViewerASCIIPrintf(ps->ps_file,"/l {lineto stroke} def\n");
311:   PetscViewerASCIIPrintf(ps->ps_file,"/m {moveto} def\n");

313:   ps->currentcolor = PETSC_DRAW_BLACK;

315:   if (!rgbfilled) {
316:     rgbfilled = PETSC_TRUE;
317:     rgb[0][PETSC_DRAW_WHITE]       = 255/255;
318:     rgb[1][PETSC_DRAW_WHITE]       = 255/255;
319:     rgb[2][PETSC_DRAW_WHITE]       = 255/255;
320:     rgb[0][PETSC_DRAW_BLACK]       = 0;
321:     rgb[1][PETSC_DRAW_BLACK]       = 0;
322:     rgb[2][PETSC_DRAW_BLACK]       = 0;
323:     rgb[0][PETSC_DRAW_RED]         = 255/255;
324:     rgb[1][PETSC_DRAW_RED]         = 0;
325:     rgb[2][PETSC_DRAW_RED]         = 0;
326:     rgb[0][PETSC_DRAW_GREEN]       = 0;
327:     rgb[1][PETSC_DRAW_GREEN]       = 255./255;
328:     rgb[2][PETSC_DRAW_GREEN]       = 0;
329:     rgb[0][PETSC_DRAW_CYAN]        = 0;
330:     rgb[1][PETSC_DRAW_CYAN]        = 255./255;
331:     rgb[2][PETSC_DRAW_CYAN]        = 255./255;
332:     rgb[0][PETSC_DRAW_BLUE]        = 0;
333:     rgb[1][PETSC_DRAW_BLUE]        = 0;
334:     rgb[2][PETSC_DRAW_BLUE]        = 255./255;
335:     rgb[0][PETSC_DRAW_MAGENTA]     = 255./255;
336:     rgb[1][PETSC_DRAW_MAGENTA]     = 0;
337:     rgb[2][PETSC_DRAW_MAGENTA]     = 255./255;
338:     rgb[0][PETSC_DRAW_AQUAMARINE]  = 127./255;
339:     rgb[1][PETSC_DRAW_AQUAMARINE]  = 255./255;
340:     rgb[2][PETSC_DRAW_AQUAMARINE]  = 212./255;
341:     rgb[0][PETSC_DRAW_FORESTGREEN] = 34./255   ;
342:     rgb[1][PETSC_DRAW_FORESTGREEN] = 139./255.;
343:     rgb[2][PETSC_DRAW_FORESTGREEN] = 34./255. ;
344:     rgb[0][PETSC_DRAW_ORANGE]      = 255./255.    ;
345:     rgb[1][PETSC_DRAW_ORANGE]      = 165./255.;
346:     rgb[2][PETSC_DRAW_ORANGE]      = 0 ;
347:     rgb[0][PETSC_DRAW_VIOLET]      = 238./255.  ;
348:     rgb[1][PETSC_DRAW_VIOLET]      = 130./255.;
349:     rgb[2][PETSC_DRAW_VIOLET]      = 238./255.;
350:     rgb[0][PETSC_DRAW_BROWN]       = 165./255.   ;
351:     rgb[1][PETSC_DRAW_BROWN]       =  42./255.;
352:     rgb[2][PETSC_DRAW_BROWN]       = 42./255.;
353:     rgb[0][PETSC_DRAW_PINK]        = 255./255. ;
354:     rgb[1][PETSC_DRAW_PINK]        = 192./255. ;
355:     rgb[2][PETSC_DRAW_PINK]        = 203./255.;
356:     rgb[0][PETSC_DRAW_CORAL]       = 255./255.;
357:     rgb[1][PETSC_DRAW_CORAL]       = 127./255.;
358:     rgb[2][PETSC_DRAW_CORAL]       = 80./255.;
359:     rgb[0][PETSC_DRAW_GRAY]        = 190./255.  ;
360:     rgb[1][PETSC_DRAW_GRAY]        = 190./255.;
361:     rgb[2][PETSC_DRAW_GRAY]        = 190./255.;
362:     rgb[0][PETSC_DRAW_YELLOW]      = 255./255.    ;
363:     rgb[1][PETSC_DRAW_YELLOW]      = 255./255.;
364:     rgb[2][PETSC_DRAW_YELLOW]      = 0/255.;
365:     rgb[0][PETSC_DRAW_GOLD]        = 255./255.  ;
366:     rgb[1][PETSC_DRAW_GOLD]        =  215./255.;
367:     rgb[2][PETSC_DRAW_GOLD]        =  0;
368:     rgb[0][PETSC_DRAW_LIGHTPINK]   = 255./255.  ;
369:     rgb[1][PETSC_DRAW_LIGHTPINK]   = 182./255.;
370:     rgb[2][PETSC_DRAW_LIGHTPINK]   = 193./255.;
371:     rgb[0][PETSC_DRAW_MEDIUMTURQUOISE] = 72./255.;
372:     rgb[1][PETSC_DRAW_MEDIUMTURQUOISE] =  209./255.;
373:     rgb[2][PETSC_DRAW_MEDIUMTURQUOISE] =  204./255.;
374:     rgb[0][PETSC_DRAW_KHAKI]           = 240./255.  ;
375:     rgb[1][PETSC_DRAW_KHAKI]           = 230./255.;
376:     rgb[2][PETSC_DRAW_KHAKI]           = 140./255.;
377:     rgb[0][PETSC_DRAW_DIMGRAY]         = 105./255.  ;
378:     rgb[1][PETSC_DRAW_DIMGRAY]         = 105./255.;
379:     rgb[2][PETSC_DRAW_DIMGRAY]         = 105./255.;
380:     rgb[0][PETSC_DRAW_YELLOWGREEN]     = 154./255.   ;
381:     rgb[1][PETSC_DRAW_YELLOWGREEN]     = 205./255.;
382:     rgb[2][PETSC_DRAW_YELLOWGREEN]     =  50./255.;
383:     rgb[0][PETSC_DRAW_SKYBLUE]         = 135./255.  ;
384:     rgb[1][PETSC_DRAW_SKYBLUE]         = 206./255.;
385:     rgb[2][PETSC_DRAW_SKYBLUE]         = 235./255.;
386:     rgb[0][PETSC_DRAW_DARKGREEN]       = 0    ;
387:     rgb[1][PETSC_DRAW_DARKGREEN]       = 100./255.;
388:     rgb[2][PETSC_DRAW_DARKGREEN]       = 0;
389:     rgb[0][PETSC_DRAW_NAVYBLUE]        = 0   ;
390:     rgb[1][PETSC_DRAW_NAVYBLUE]        =  0;
391:     rgb[2][PETSC_DRAW_NAVYBLUE]        = 128./255.;
392:     rgb[0][PETSC_DRAW_SANDYBROWN]      = 244./255.   ;
393:     rgb[1][PETSC_DRAW_SANDYBROWN]      = 164./255.;
394:     rgb[2][PETSC_DRAW_SANDYBROWN]      = 96./255.;
395:     rgb[0][PETSC_DRAW_CADETBLUE]       =  95./255.  ;
396:     rgb[1][PETSC_DRAW_CADETBLUE]       = 158./255.;
397:     rgb[2][PETSC_DRAW_CADETBLUE]       = 160./255.;
398:     rgb[0][PETSC_DRAW_POWDERBLUE]      = 176./255.  ;
399:     rgb[1][PETSC_DRAW_POWDERBLUE]      = 224./255.;
400:     rgb[2][PETSC_DRAW_POWDERBLUE]      = 230./255.;
401:     rgb[0][PETSC_DRAW_DEEPPINK]        = 255./255. ;
402:     rgb[1][PETSC_DRAW_DEEPPINK]        =  20./255.;
403:     rgb[2][PETSC_DRAW_DEEPPINK]        = 147./255.;
404:     rgb[0][PETSC_DRAW_THISTLE]         = 216./255.  ;
405:     rgb[1][PETSC_DRAW_THISTLE]         = 191./255.;
406:     rgb[2][PETSC_DRAW_THISTLE]         = 216./255.;
407:     rgb[0][PETSC_DRAW_LIMEGREEN]       = 50./255.  ;
408:     rgb[1][PETSC_DRAW_LIMEGREEN]       = 205./255.;
409:     rgb[2][PETSC_DRAW_LIMEGREEN]       =  50./255.;
410:     rgb[0][PETSC_DRAW_LAVENDERBLUSH]   = 255./255.  ;
411:     rgb[1][PETSC_DRAW_LAVENDERBLUSH]   = 240./255.;
412:     rgb[2][PETSC_DRAW_LAVENDERBLUSH]   = 245./255.;

414:     /* now do the uniform hue part of the colors */
415:     ncolors = 256-PETSC_DRAW_BASIC_COLORS;
416:     PetscMalloc(3*ncolors*sizeof(unsigned char),&red);
417:     green   = red   + ncolors;
418:     blue    = green + ncolors;
419:     PetscDrawUtilitySetCmapHue(red,green,blue,ncolors);
420:     for (i=PETSC_DRAW_BASIC_COLORS; i<ncolors+PETSC_DRAW_BASIC_COLORS; i++) {
421:       rgb[0][i]  = ((double)red[i-PETSC_DRAW_BASIC_COLORS])/255.;
422:       rgb[1][i]  = ((double)green[i-PETSC_DRAW_BASIC_COLORS])/255.;
423:       rgb[2][i]  = ((double)blue[i-PETSC_DRAW_BASIC_COLORS])/255.;
424:     }
425:     PetscFree(red);
426:   }

428:   draw->data    = (void*)ps;
429:   return(0);
430: }



435: /*
436:          This works in Postscript coordinates
437: */
438: /*  

440:    this kind of thing should do contour triangles with Postscript level 3
441: 1000 dict begin
442:   /ShadingType 4 def
443:   /ColorSpace /DeviceRGB def
444:   /DataSource [0 10 10 255 255 255 0 400 10 0 0 0 0 200 400 255 0 0] def
445:   shfill

447:    once we have Postscript level 3 we should put this in as an option
448: */


453: static PetscErrorCode PetscDrawInterpolatedTriangle_PS(PetscDraw_PS* ps,PetscReal x1,PetscReal y_1,int t1,
454:                                 PetscReal x2,PetscReal y2,int t2,PetscReal x3,PetscReal y3,int t3)
455: {
456:   PetscReal rfrac,lfrac;
457:   PetscReal lc,rc = 0.0,lx,rx = 0.0,xx,y;
458:   PetscReal rc_lc,rx_lx,t2_t1,x2_x1,t3_t1,x3_x1,t3_t2,x3_x2;
459:   PetscReal R_y2_y_1,R_y3_y_1,R_y3_y2;
461:   int       c;

464:   /*
465:         Is triangle even visible in window?
466:   */
467:   if (x1 < 0 && x2 < 0 && x3 < 0) return(0);
468:   if (y_1 < 0 && y2 < 0 && y3 < 0) return(0);
469:   if (x1 > 72*8.5 && x2 > 72*8.5 && x3 > 72*8.5) return(0);
470:   if (y_1 > 72*11 && y2 > 72*11 && y3 > 72*11) return(0);

472:   /* scale everything by two to reduce the huge file; note this reduces the quality */
473:   x1  /= 2.0;
474:   x2  /= 2.0;
475:   x3  /= 2.0;
476:   y_1 /= 2.0;
477:   y2  /= 2.0;
478:   y3  /= 2.0;
479:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"gsave 2 2 scale\n");


482:   /* Sort the vertices */
483: #define SWAP(a,b) {PetscReal _a; _a=a; a=b; b=_a;}
484: #define ISWAP(a,b) {int _a; _a=a; a=b; b=_a;}
485:   if (y_1 > y2) {
486:     SWAP(y_1,y2);ISWAP(t1,t2); SWAP(x1,x2);
487:   }
488:   if (y_1 > y3) {
489:     SWAP(y_1,y3);ISWAP(t1,t3); SWAP(x1,x3);
490:   }
491:   if (y2 > y3) {
492:     SWAP(y2,y3);ISWAP(t2,t3); SWAP(x2,x3);
493:   }
494:   /* This code is decidely non-optimal; it is intended to be a start at
495:    an implementation */

497:   if (y2 != y_1) R_y2_y_1 = 1.0/((y2-y_1)); else R_y2_y_1 = 0.0;
498:   if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
499:   t2_t1   = t2 - t1;
500:   x2_x1   = x2 - x1;
501:   t3_t1   = t3 - t1;
502:   x3_x1   = x3 - x1;
503:   for (y=y_1; y<=y2; y++) {
504:     /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */
505:     /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
506:     lfrac = ((y-y_1)) * R_y2_y_1;
507:     lc    = (lfrac * (t2_t1) + t1);
508:     lx    = (lfrac * (x2_x1) + x1);
509:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
510:     rfrac = ((y - y_1)) * R_y3_y_1;
511:     rc    = (rfrac * (t3_t1) + t1);
512:     rx    = (rfrac * (x3_x1) + x1);
513:     /* PetscDraw the line */
514:     rc_lc = rc - lc;
515:     rx_lx = rx - lx;
516:     if (rx > lx) {
517:       for (xx=lx; xx<=rx; xx++) {
518:         c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
519:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
520:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g l\n",xx,y,xx+1,y);
521:       }
522:     } else if (rx < lx) {
523:       for (xx=lx; xx>=rx; xx--) {
524:         c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
525:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
526:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g l\n",xx,y,xx+1,y);
527:       }
528:     } else {
529:       c = (int)lc;
530:       PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
531:       PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g l\n",lx,y,lx+1,y);
532:     }
533:   }

535:   /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
536:      We take advantage of the previous iteration. */
537:   if (y2 >= y3) {
538:     PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestore\n");
539:     return(0);
540:   }
541:   if (y_1 < y2) {
542:     t1  = (int)rc;
543:     y_1 = y2;
544:     x1  = rx;

546:     t3_t1   = t3 - t1;
547:     x3_x1   = x3 - x1;
548:   }
549:   t3_t2 = t3 - t2;
550:   x3_x2 = x3 - x2;
551:   if (y3 != y2) R_y3_y2 = 1.0/((y3-y2)); else R_y3_y2 = 0.0;
552:   if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
553:   for (y=y2; y<=y3; y++) {
554:     /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */
555:     /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
556:     lfrac = ((y-y2)) * R_y3_y2;
557:     lc    = (lfrac * (t3_t2) + t2);
558:     lx    = (lfrac * (x3_x2) + x2);
559:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
560:     rfrac = ((y - y_1)) * R_y3_y_1;
561:     rc    = (rfrac * (t3_t1) + t1);
562:     rx    = (rfrac * (x3_x1) + x1);
563:     /* PetscDraw the line */
564:     rc_lc = rc - lc;
565:     rx_lx = rx - lx;
566:     if (rx > lx) {
567:       for (xx=lx; xx<=rx; xx++) {
568:         c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
569:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
570:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g l\n",xx,y,xx+1,y);
571:       }
572:     } else if (rx < lx) {
573:       for (xx=lx; xx>=rx; xx--) {
574:         c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
575:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
576:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g l\n",xx,y,xx+1,y);
577:       }
578:     } else {
579:       c = (int)lc;
580:       PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
581:       PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g l\n",lx,y,lx+1,y);
582:     }
583:   }
584:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestore\n");
585:   return(0);
586: }