Actual source code: pops.c

  1: /* $Id: pops.c,v 1.11 2001/04/10 19:34:15 bsmith Exp $*/

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

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

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

 12:   Collective on MPI_Comm

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

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

 21:   Level: beginner

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

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

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

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

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

 54: static int PetscDrawPoint_PS(PetscDraw draw,PetscReal x,PetscReal  y,int c)
 55: {
 56:   PetscReal     xx,yy;
 57:   int           ierr;
 58:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;

 61:   xx = XTRANS(draw,x);  yy = YTRANS(draw,y);
 62:   PSSetColor(ps,c);
 63:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto stroken",xx,yy,xx+1,yy);
 64:   return(0);
 65: }

 67: static int PetscDrawLine_PS(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
 68: {
 69:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
 70:   PetscReal     x1,y_1,x2,y2;
 71:   int           ierr;

 74:   x1 = XTRANS(draw,xl);   x2  = XTRANS(draw,xr);
 75:   y_1 = YTRANS(draw,yl);   y2  = YTRANS(draw,yr);
 76:   PSSetColor(ps,c);
 77:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto stroken",x1,y_1,x2,y2);
 78:   return(0);
 79: }

 81: static int PetscDrawStringSetSize_PS(PetscDraw draw,PetscReal x,PetscReal  y)
 82: {
 83:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
 84:   int           ierr,w,h;

 87:   w = (int)((WIDTH)*x*(draw->port_xr - draw->port_xl)/(draw->coor_xr - draw->coor_xl));
 88:   h = (int)((HEIGHT)*y*(draw->port_yr - draw->port_yl)/(draw->coor_yr - draw->coor_yl));
 89:   PetscViewerASCIIPrintf(ps->ps_file,"/Helvetica-normal findfont %g scalefont setfontn",(w+h)/2.0);
 90:   return(0);
 91: }

 93: static int PetscDrawStringGetSize_PS(PetscDraw draw,PetscReal *x,PetscReal  *y)
 94: {
 95:   PetscReal   w = 9,h = 9;

 98:   *x = w*(draw->coor_xr - draw->coor_xl)/(WIDTH)*(draw->port_xr - draw->port_xl);
 99:   *y = h*(draw->coor_yr - draw->coor_yl)/(HEIGHT)*(draw->port_yr - draw->port_yl);
100:   return(0);
101: }

103: static int PetscDrawString_PS(PetscDraw draw,PetscReal x,PetscReal  y,int c,char *chrs)
104: {
105:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
106:   PetscReal     x1,y_1;
107:   int           ierr;

110:   PSSetColor(ps,c);
111:   x1 = XTRANS(draw,x);
112:   y_1 = YTRANS(draw,y);
113:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto (%s) shown",x1,y_1,chrs);
114:   return(0);
115: }

117: static int PetscDrawStringVertical_PS(PetscDraw draw,PetscReal x,PetscReal  y,int c,char *chrs)
118: {
119:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
120:   PetscReal     x1,y_1;
121:   int           ierr;

124:   PSSetColor(ps,c);
125:   x1 = XTRANS(draw,x);
126:   y_1 = YTRANS(draw,y);
127:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"gsave %g %g moveto 90 rotate (%s) show grestoren",x1,y_1,chrs);
128:   return(0);
129: }

131: static int PetscDrawInterpolatedTriangle_PS(PetscDraw_PS*,PetscReal,PetscReal,int,PetscReal,PetscReal,int,PetscReal,PetscReal,int);

133: static int PetscDrawTriangle_PS(PetscDraw draw,PetscReal X1,PetscReal Y_1,PetscReal X2,
134:                           PetscReal Y2,PetscReal X3,PetscReal Y3,int c1,int c2,int c3)
135: {
136:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
137:   int           ierr;
138:   PetscReal     x1,y_1,x2,y2,x3,y3;

141:   x1   = XTRANS(draw,X1);
142:   y_1  = YTRANS(draw,Y_1);
143:   x2   = XTRANS(draw,X2);
144:   y2   = YTRANS(draw,Y2);
145:   x3   = XTRANS(draw,X3);
146:   y3   = YTRANS(draw,Y3);

148:   if (c1 == c2 && c2 == c3) {
149:     PSSetColor(ps,c1);
150:     PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto %g %g lineto filln",x1,y_1,x2,y2,x3,y3);
151:   } else {
152:     PetscDrawInterpolatedTriangle_PS(ps,x1,y_1,c1,x2,y2,c2,x3,y3,c3);
153:   }
154:   return(0);
155: }

157: static int PetscDrawRectangle_PS(PetscDraw draw,PetscReal X1,PetscReal Y_1,PetscReal X2,
158:                           PetscReal Y2,int c1,int c2,int c3,int c4)
159: {
160:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
161:   int           ierr;
162:   PetscReal     x1,y_1,x2,y2,x3,y3,x4,y4;

165:   x1   = XTRANS(draw,X1);
166:   y_1  = YTRANS(draw,Y_1);
167:   x2   = XTRANS(draw,X2);
168:   y2   = YTRANS(draw,Y_1);
169:   x3   = XTRANS(draw,X2);
170:   y3   = YTRANS(draw,Y2);
171:   x4   = XTRANS(draw,X1);
172:   y4   = YTRANS(draw,Y2);

174:   PSSetColor(ps,(c1+c2+c3+c4)/4);
175:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto %g %g lineto %g %g lineto %g %g lineto filln",x1,y_1,x2,y2,x3,y3,x4,y4,x1,y_1);
176:   return(0);
177: }

179: static int PetscDrawDestroy_PS(PetscDraw draw)
180: {
181:   PetscDraw_PS *ps = (PetscDraw_PS*)draw->data;
182:   int          ierr;
183:   PetscTruth   show;
184:   char         *filename,par[1024];
185: 
187:   PetscViewerASCIIPrintf(ps->ps_file,"nshowpagen");
188:   PetscOptionsHasName(draw->prefix,"-draw_ps_show",&show);
189:   if (show) {
190:     PetscViewerGetFilename(ps->ps_file,&filename);
191:     PetscStrcpy(par,"ghostview ");
192:     PetscStrcat(par,filename);
193:     PetscPOpen(draw->comm,PETSC_NULL,par,"r",PETSC_NULL);
194:   }
195:   PetscViewerDestroy(ps->ps_file);
196:   PetscFree(ps);
197:   return(0);
198: }

200: static int PetscDrawSynchronizedFlush_PS(PetscDraw draw)
201: {
202:   int           ierr;
203:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;

206:   PetscViewerFlush(ps->ps_file);
207:   return(0);
208: }

210: static int PetscDrawSynchronizedClear_PS(PetscDraw draw)
211: {
212:   int           ierr;
213:   PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;

216:   PetscViewerFlush(ps->ps_file);
217:   PetscViewerASCIIPrintf(ps->ps_file,"nshowpagen");

219:   return(0);
220: }

222: static struct _PetscDrawOps DvOps = { 0,
223:                                  0,
224:                                  PetscDrawLine_PS,
225:                                  0,
226:                                  0,
227:                                  PetscDrawPoint_PS,
228:                                  0,
229:                                  PetscDrawString_PS,
230:                                  PetscDrawStringVertical_PS,
231:                                  PetscDrawStringSetSize_PS,
232:                                  PetscDrawStringGetSize_PS,
233:                                  0,
234:                                  0,
235:                                  PetscDrawSynchronizedFlush_PS,
236:                                  PetscDrawRectangle_PS,
237:                                  PetscDrawTriangle_PS,
238:                                  0,
239:                                  0,
240:                                  0,
241:                                  PetscDrawSynchronizedClear_PS,
242:                                  0,
243:                                  0,
244:                                  0,
245:                                  0,
246:                                  0,
247:                                  0,
248:                                  PetscDrawDestroy_PS,
249:                                  0,
250:                                  0,
251:                                  0 };

253: EXTERN_C_BEGIN
254: int PetscDrawCreate_PS(PetscDraw draw)
255: {
256:   PetscDraw_PS  *ps;
257:   int           ierr,ncolors,i;
258:   unsigned char *red,*green,*blue;
259:   static int    filecount = 0;
260:   char          buff[32];
261:   char          version[256];

264:   if (!draw->display) {
265:     sprintf(buff,"defaultps%d.ps",filecount++);
266:     PetscStrallocpy(buff,&draw->display);
267:   }

269:   PetscGetVersion(&version);
270:   PetscNew(PetscDraw_PS,&ps);
271:   PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
272:   PetscViewerASCIIOpen(draw->comm,draw->display,&ps->ps_file);
273:   PetscViewerASCIIPrintf(ps->ps_file,"%%!PS-Adobe-2.0n");
274:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%Creator: PETSc %sn",version);
275:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%Title: %sn",draw->display);
276:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%Pages: 1n");
277:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%PageOrder: Ascendn");
278:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%BoundingBox: 0 0 612 792n");
279:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%DocumentFonts: Helvetica-normal Symboln");
280:   PetscViewerASCIIPrintf(ps->ps_file,"%%%%EndCommentsn");
281:   PetscViewerASCIIPrintf(ps->ps_file,"/Helvetica-normal findfont 10 scalefont setfontn");
282:   PetscViewerASCIIPrintf(ps->ps_file,"/c {setrgbcolor} defn");
283:   PetscViewerASCIIPrintf(ps->ps_file,"/l {lineto stroke} defn");
284:   PetscViewerASCIIPrintf(ps->ps_file,"/m {moveto} defn");

286:   ps->currentcolor = PETSC_DRAW_BLACK;

288:   if (!rgbfilled) {
289:     rgbfilled = PETSC_TRUE;
290:     rgb[0][PETSC_DRAW_WHITE]       = 255/255;
291:     rgb[1][PETSC_DRAW_WHITE]       = 255/255;
292:     rgb[2][PETSC_DRAW_WHITE]       = 255/255;
293:     rgb[0][PETSC_DRAW_BLACK]       = 0;
294:     rgb[1][PETSC_DRAW_BLACK]       = 0;
295:     rgb[2][PETSC_DRAW_BLACK]       = 0;
296:     rgb[0][PETSC_DRAW_RED]         = 255/255;
297:     rgb[1][PETSC_DRAW_RED]         = 0;
298:     rgb[2][PETSC_DRAW_RED]         = 0;
299:     rgb[0][PETSC_DRAW_GREEN]       = 0;
300:     rgb[1][PETSC_DRAW_GREEN]       = 255./255;
301:     rgb[2][PETSC_DRAW_GREEN]       = 0;
302:     rgb[0][PETSC_DRAW_CYAN]        = 0;
303:     rgb[1][PETSC_DRAW_CYAN]        = 255./255;
304:     rgb[2][PETSC_DRAW_CYAN]        = 255./255;
305:     rgb[0][PETSC_DRAW_BLUE]        = 0;
306:     rgb[1][PETSC_DRAW_BLUE]        = 0;
307:     rgb[2][PETSC_DRAW_BLUE]        = 255./255;
308:     rgb[0][PETSC_DRAW_MAGENTA]     = 255./255;
309:     rgb[1][PETSC_DRAW_MAGENTA]     = 0;
310:     rgb[2][PETSC_DRAW_MAGENTA]     = 255./255;
311:     rgb[0][PETSC_DRAW_AQUAMARINE]  = 127./255;
312:     rgb[1][PETSC_DRAW_AQUAMARINE]  = 255./255;
313:     rgb[2][PETSC_DRAW_AQUAMARINE]  = 212./255;
314:     rgb[0][PETSC_DRAW_FORESTGREEN] = 34./255   ;
315:     rgb[1][PETSC_DRAW_FORESTGREEN] = 139./255.;
316:     rgb[2][PETSC_DRAW_FORESTGREEN] = 34./255. ;
317:     rgb[0][PETSC_DRAW_ORANGE]      = 255./255.    ;
318:     rgb[1][PETSC_DRAW_ORANGE]      = 165./255.;
319:     rgb[2][PETSC_DRAW_ORANGE]      = 0 ;
320:     rgb[0][PETSC_DRAW_VIOLET]      = 238./255.  ;
321:     rgb[1][PETSC_DRAW_VIOLET]      = 130./255.;
322:     rgb[2][PETSC_DRAW_VIOLET]      = 238./255.;
323:     rgb[0][PETSC_DRAW_BROWN]       = 165./255.   ;
324:     rgb[1][PETSC_DRAW_BROWN]       =  42./255.;
325:     rgb[2][PETSC_DRAW_BROWN]       = 42./255.;
326:     rgb[0][PETSC_DRAW_PINK]        = 255./255. ;
327:     rgb[1][PETSC_DRAW_PINK]        = 192./255. ;
328:     rgb[2][PETSC_DRAW_PINK]        = 203./255.;
329:     rgb[0][PETSC_DRAW_CORAL]       = 255./255.;
330:     rgb[1][PETSC_DRAW_CORAL]       = 127./255.;
331:     rgb[2][PETSC_DRAW_CORAL]       = 80./255.;
332:     rgb[0][PETSC_DRAW_GRAY]        = 190./255.  ;
333:     rgb[1][PETSC_DRAW_GRAY]        = 190./255.;
334:     rgb[2][PETSC_DRAW_GRAY]        = 190./255.;
335:     rgb[0][PETSC_DRAW_YELLOW]      = 255./255.    ;
336:     rgb[1][PETSC_DRAW_YELLOW]      = 255./255.;
337:     rgb[2][PETSC_DRAW_YELLOW]      = 0/255.;
338:     rgb[0][PETSC_DRAW_GOLD]        = 255./255.  ;
339:     rgb[1][PETSC_DRAW_GOLD]        =  215./255.;
340:     rgb[2][PETSC_DRAW_GOLD]        =  0;
341:     rgb[0][PETSC_DRAW_LIGHTPINK]   = 255./255.  ;
342:     rgb[1][PETSC_DRAW_LIGHTPINK]   = 182./255.;
343:     rgb[2][PETSC_DRAW_LIGHTPINK]   = 193./255.;
344:     rgb[0][PETSC_DRAW_MEDIUMTURQUOISE] = 72./255.;
345:     rgb[1][PETSC_DRAW_MEDIUMTURQUOISE] =  209./255.;
346:     rgb[2][PETSC_DRAW_MEDIUMTURQUOISE] =  204./255.;
347:     rgb[0][PETSC_DRAW_KHAKI]           = 240./255.  ;
348:     rgb[1][PETSC_DRAW_KHAKI]           = 230./255.;
349:     rgb[2][PETSC_DRAW_KHAKI]           = 140./255.;
350:     rgb[0][PETSC_DRAW_DIMGRAY]         = 105./255.  ;
351:     rgb[1][PETSC_DRAW_DIMGRAY]         = 105./255.;
352:     rgb[2][PETSC_DRAW_DIMGRAY]         = 105./255.;
353:     rgb[0][PETSC_DRAW_YELLOWGREEN]     = 154./255.   ;
354:     rgb[1][PETSC_DRAW_YELLOWGREEN]     = 205./255.;
355:     rgb[2][PETSC_DRAW_YELLOWGREEN]     =  50./255.;
356:     rgb[0][PETSC_DRAW_SKYBLUE]         = 135./255.  ;
357:     rgb[1][PETSC_DRAW_SKYBLUE]         = 206./255.;
358:     rgb[2][PETSC_DRAW_SKYBLUE]         = 235./255.;
359:     rgb[0][PETSC_DRAW_DARKGREEN]       = 0    ;
360:     rgb[1][PETSC_DRAW_DARKGREEN]       = 100./255.;
361:     rgb[2][PETSC_DRAW_DARKGREEN]       = 0;
362:     rgb[0][PETSC_DRAW_NAVYBLUE]        = 0   ;
363:     rgb[1][PETSC_DRAW_NAVYBLUE]        =  0;
364:     rgb[2][PETSC_DRAW_NAVYBLUE]        = 128./255.;
365:     rgb[0][PETSC_DRAW_SANDYBROWN]      = 244./255.   ;
366:     rgb[1][PETSC_DRAW_SANDYBROWN]      = 164./255.;
367:     rgb[2][PETSC_DRAW_SANDYBROWN]      = 96./255.;
368:     rgb[0][PETSC_DRAW_CADETBLUE]       =  95./255.  ;
369:     rgb[1][PETSC_DRAW_CADETBLUE]       = 158./255.;
370:     rgb[2][PETSC_DRAW_CADETBLUE]       = 160./255.;
371:     rgb[0][PETSC_DRAW_POWDERBLUE]      = 176./255.  ;
372:     rgb[1][PETSC_DRAW_POWDERBLUE]      = 224./255.;
373:     rgb[2][PETSC_DRAW_POWDERBLUE]      = 230./255.;
374:     rgb[0][PETSC_DRAW_DEEPPINK]        = 255./255. ;
375:     rgb[1][PETSC_DRAW_DEEPPINK]        =  20./255.;
376:     rgb[2][PETSC_DRAW_DEEPPINK]        = 147./255.;
377:     rgb[0][PETSC_DRAW_THISTLE]         = 216./255.  ;
378:     rgb[1][PETSC_DRAW_THISTLE]         = 191./255.;
379:     rgb[2][PETSC_DRAW_THISTLE]         = 216./255.;
380:     rgb[0][PETSC_DRAW_LIMEGREEN]       = 50./255.  ;
381:     rgb[1][PETSC_DRAW_LIMEGREEN]       = 205./255.;
382:     rgb[2][PETSC_DRAW_LIMEGREEN]       =  50./255.;
383:     rgb[0][PETSC_DRAW_LAVENDERBLUSH]   = 255./255.  ;
384:     rgb[1][PETSC_DRAW_LAVENDERBLUSH]   = 240./255.;
385:     rgb[2][PETSC_DRAW_LAVENDERBLUSH]   = 245./255.;

387:     /* now do the uniform hue part of the colors */
388:     ncolors = 256-PETSC_DRAW_BASIC_COLORS;
389:     ierr    = PetscMalloc(3*ncolors*sizeof(unsigned char),&red);
390:     green   = red   + ncolors;
391:     blue    = green + ncolors;
392:     ierr    = PetscDrawUtilitySetCmapHue(red,green,blue,ncolors);
393:     for (i=PETSC_DRAW_BASIC_COLORS; i<ncolors+PETSC_DRAW_BASIC_COLORS; i++) {
394:       rgb[0][i]  = ((double)red[i-PETSC_DRAW_BASIC_COLORS])/255.;
395:       rgb[1][i]  = ((double)green[i-PETSC_DRAW_BASIC_COLORS])/255.;
396:       rgb[2][i]  = ((double)blue[i-PETSC_DRAW_BASIC_COLORS])/255.;
397:     }
398:     PetscFree(red);
399:   }

401:   draw->data    = (void*)ps;
402:   return(0);
403: }
404: EXTERN_C_END



408: /*
409:          This works in Postscript coordinates
410: */
411: /*  

413:    this kind of thing should do contour triangles with Postscript level 3
414: 1000 dict begin
415:   /ShadingType 4 def
416:   /ColorSpace /DeviceRGB def
417:   /DataSource [0 10 10 255 255 255 0 400 10 0 0 0 0 200 400 255 0 0] def
418:   shfill

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


424: static int PetscDrawInterpolatedTriangle_PS(PetscDraw_PS* ps,PetscReal x1,PetscReal y_1,int t1,
425:                                 PetscReal x2,PetscReal y2,int t2,PetscReal x3,PetscReal y3,int t3)
426: {
427:   PetscReal rfrac,lfrac;
428:   PetscReal lc,rc = 0.0,lx,rx = 0.0,xx,y;
429:   PetscReal rc_lc,rx_lx,t2_t1,x2_x1,t3_t1,x3_x1,t3_t2,x3_x2;
430:   PetscReal R_y2_y_1,R_y3_y_1,R_y3_y2;
431:   int       ierr,c;

434:   /*
435:         Is triangle even visible in window?
436:   */
437:   if (x1 < 0 && x2 < 0 && x3 < 0) return(0);
438:   if (y_1 < 0 && y2 < 0 && y3 < 0) return(0);
439:   if (x1 > 72*8.5 && x2 > 72*8.5 && x3 > 72*8.5) return(0);
440:   if (y_1 > 72*11 && y2 > 72*11 && y3 > 72*11) return(0);

442:   /* scale everything by two to reduce the huge file; note this reduces the quality */
443:   x1  /= 2.0;
444:   x2  /= 2.0;
445:   x3  /= 2.0;
446:   y_1 /= 2.0;
447:   y2  /= 2.0;
448:   y3  /= 2.0;
449:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"gsave 2 2 scalen");


452:   /* Sort the vertices */
453: #define SWAP(a,b) {PetscReal _a; _a=a; a=b; b=_a;}
454: #define ISWAP(a,b) {int _a; _a=a; a=b; b=_a;}
455:   if (y_1 > y2) {
456:     SWAP(y_1,y2);ISWAP(t1,t2); SWAP(x1,x2);
457:   }
458:   if (y_1 > y3) {
459:     SWAP(y_1,y3);ISWAP(t1,t3); SWAP(x1,x3);
460:   }
461:   if (y2 > y3) {
462:     SWAP(y2,y3);ISWAP(t2,t3); SWAP(x2,x3);
463:   }
464:   /* This code is decidely non-optimal; it is intended to be a start at
465:    an implementation */

467:   if (y2 != y_1) R_y2_y_1 = 1.0/((y2-y_1)); else R_y2_y_1 = 0.0;
468:   if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
469:   t2_t1   = t2 - t1;
470:   x2_x1   = x2 - x1;
471:   t3_t1   = t3 - t1;
472:   x3_x1   = x3 - x1;
473:   for (y=y_1; y<=y2; y++) {
474:     /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */
475:     /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
476:     lfrac = ((y-y_1)) * R_y2_y_1;
477:     lc    = (lfrac * (t2_t1) + t1);
478:     lx    = (lfrac * (x2_x1) + x1);
479:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
480:     rfrac = ((y - y_1)) * R_y3_y_1;
481:     rc    = (rfrac * (t3_t1) + t1);
482:     rx    = (rfrac * (x3_x1) + x1);
483:     /* PetscDraw the line */
484:     rc_lc = rc - lc;
485:     rx_lx = rx - lx;
486:     if (rx > lx) {
487:       for (xx=lx; xx<=rx; xx++) {
488:         c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
489:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
490:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
491:       }
492:     } else if (rx < lx) {
493:       for (xx=lx; xx>=rx; xx--) {
494:         c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
495:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
496:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
497:       }
498:     } else {
499:       c = (int)lc;
500:       PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
501:       PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",lx,y,lx+1,y);
502:     }
503:   }

505:   /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
506:      We take advantage of the previous iteration. */
507:   if (y2 >= y3) {
508:     PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestoren");
509:     return(0);
510:   }
511:   if (y_1 < y2) {
512:     t1  = (int)rc;
513:     y_1 = y2;
514:     x1  = rx;

516:     t3_t1   = t3 - t1;
517:     x3_x1   = x3 - x1;
518:   }
519:   t3_t2 = t3 - t2;
520:   x3_x2 = x3 - x2;
521:   if (y3 != y2) R_y3_y2 = 1.0/((y3-y2)); else R_y3_y2 = 0.0;
522:   if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
523:   for (y=y2; y<=y3; y++) {
524:     /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */
525:     /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
526:     lfrac = ((y-y2)) * R_y3_y2;
527:     lc    = (lfrac * (t3_t2) + t2);
528:     lx    = (lfrac * (x3_x2) + x2);
529:     /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
530:     rfrac = ((y - y_1)) * R_y3_y_1;
531:     rc    = (rfrac * (t3_t1) + t1);
532:     rx    = (rfrac * (x3_x1) + x1);
533:     /* PetscDraw the line */
534:     rc_lc = rc - lc;
535:     rx_lx = rx - lx;
536:     if (rx > lx) {
537:       for (xx=lx; xx<=rx; xx++) {
538:         c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
539:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
540:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
541:       }
542:     } else if (rx < lx) {
543:       for (xx=lx; xx>=rx; xx--) {
544:         c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
545:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
546:         PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
547:       }
548:     } else {
549:       c = (int)lc;
550:       PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
551:       PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",lx,y,lx+1,y);
552:     }
553:   }
554:   PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestoren");
555:   return(0);
556: }