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: }