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 PetscDrawDestroy_PS(PetscDraw draw)
158: {
159: PetscDraw_PS *ps = (PetscDraw_PS*)draw->data;
160: int ierr;
161: PetscTruth show;
162: char *filename,par[1024];
163:
165: PetscViewerASCIIPrintf(ps->ps_file,"nshowpagen");
166: PetscOptionsHasName(draw->prefix,"-draw_ps_show",&show);
167: if (show) {
168: PetscViewerGetFilename(ps->ps_file,&filename);
169: PetscStrcpy(par,"ghostview ");
170: PetscStrcat(par,filename);
171: PetscPOpen(draw->comm,PETSC_NULL,par,"r",PETSC_NULL);
172: }
173: PetscViewerDestroy(ps->ps_file);
174: PetscFree(ps);
175: return(0);
176: }
178: static int PetscDrawSynchronizedFlush_PS(PetscDraw draw)
179: {
180: int ierr;
181: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
184: PetscViewerFlush(ps->ps_file);
185: return(0);
186: }
188: static int PetscDrawSynchronizedClear_PS(PetscDraw draw)
189: {
190: int ierr;
191: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
194: PetscViewerFlush(ps->ps_file);
195: PetscViewerASCIIPrintf(ps->ps_file,"nshowpagen");
197: return(0);
198: }
200: static struct _PetscDrawOps DvOps = { 0,
201: 0,
202: PetscDrawLine_PS,
203: 0,
204: 0,
205: PetscDrawPoint_PS,
206: 0,
207: PetscDrawString_PS,
208: PetscDrawStringVertical_PS,
209: PetscDrawStringSetSize_PS,
210: PetscDrawStringGetSize_PS,
211: 0,
212: 0,
213: PetscDrawSynchronizedFlush_PS,
214: 0,
215: PetscDrawTriangle_PS,
216: 0,
217: 0,
218: PetscDrawSynchronizedClear_PS,
219: 0,
220: 0,
221: 0,
222: 0,
223: 0,
224: 0,
225: PetscDrawDestroy_PS,
226: 0,
227: 0,
228: 0 };
230: EXTERN_C_BEGIN
231: int PetscDrawCreate_PS(PetscDraw draw)
232: {
233: PetscDraw_PS *ps;
234: int ierr,ncolors,i;
235: unsigned char *red,*green,*blue;
236: static int filecount = 0;
237: char buff[32];
240: if (!draw->display) {
241: sprintf(buff,"defaultps%d.ps",filecount++);
242: PetscStrallocpy(buff,&draw->display);
243: }
245: PetscNew(PetscDraw_PS,&ps);
246: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
247: PetscViewerASCIIOpen(draw->comm,draw->display,&ps->ps_file);
248: PetscViewerASCIIPrintf(ps->ps_file,"%%!PS-Adobe-2.0n");
249: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Creator: PETSc %sn",PETSC_VERSION_NUMBER);
250: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Title: %sn",draw->display);
251: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Pages: 1n");
252: PetscViewerASCIIPrintf(ps->ps_file,"%%%%PageOrder: Ascendn");
253: PetscViewerASCIIPrintf(ps->ps_file,"%%%%BoundingBox: 0 0 612 792n");
254: PetscViewerASCIIPrintf(ps->ps_file,"%%%%DocumentFonts: Helvetica-normal Symboln");
255: PetscViewerASCIIPrintf(ps->ps_file,"%%%%EndCommentsn");
256: PetscViewerASCIIPrintf(ps->ps_file,"/Helvetica-normal findfont 10 scalefont setfontn");
257: PetscViewerASCIIPrintf(ps->ps_file,"/c {setrgbcolor} defn");
258: PetscViewerASCIIPrintf(ps->ps_file,"/l {lineto stroke} defn");
259: PetscViewerASCIIPrintf(ps->ps_file,"/m {moveto} defn");
261: ps->currentcolor = PETSC_DRAW_BLACK;
263: if (!rgbfilled) {
264: rgbfilled = PETSC_TRUE;
265: rgb[0][PETSC_DRAW_WHITE] = 255/255;
266: rgb[1][PETSC_DRAW_WHITE] = 255/255;
267: rgb[2][PETSC_DRAW_WHITE] = 255/255;
268: rgb[0][PETSC_DRAW_BLACK] = 0;
269: rgb[1][PETSC_DRAW_BLACK] = 0;
270: rgb[2][PETSC_DRAW_BLACK] = 0;
271: rgb[0][PETSC_DRAW_RED] = 255/255;
272: rgb[1][PETSC_DRAW_RED] = 0;
273: rgb[2][PETSC_DRAW_RED] = 0;
274: rgb[0][PETSC_DRAW_GREEN] = 0;
275: rgb[1][PETSC_DRAW_GREEN] = 255./255;
276: rgb[2][PETSC_DRAW_GREEN] = 0;
277: rgb[0][PETSC_DRAW_CYAN] = 0;
278: rgb[1][PETSC_DRAW_CYAN] = 255./255;
279: rgb[2][PETSC_DRAW_CYAN] = 255./255;
280: rgb[0][PETSC_DRAW_BLUE] = 0;
281: rgb[1][PETSC_DRAW_BLUE] = 0;
282: rgb[2][PETSC_DRAW_BLUE] = 255./255;
283: rgb[0][PETSC_DRAW_MAGENTA] = 255./255;
284: rgb[1][PETSC_DRAW_MAGENTA] = 0;
285: rgb[2][PETSC_DRAW_MAGENTA] = 255./255;
286: rgb[0][PETSC_DRAW_AQUAMARINE] = 127./255;
287: rgb[1][PETSC_DRAW_AQUAMARINE] = 255./255;
288: rgb[2][PETSC_DRAW_AQUAMARINE] = 212./255;
289: rgb[0][PETSC_DRAW_FORESTGREEN] = 34./255 ;
290: rgb[1][PETSC_DRAW_FORESTGREEN] = 139./255.;
291: rgb[2][PETSC_DRAW_FORESTGREEN] = 34./255. ;
292: rgb[0][PETSC_DRAW_ORANGE] = 255./255. ;
293: rgb[1][PETSC_DRAW_ORANGE] = 165./255.;
294: rgb[2][PETSC_DRAW_ORANGE] = 0 ;
295: rgb[0][PETSC_DRAW_VIOLET] = 238./255. ;
296: rgb[1][PETSC_DRAW_VIOLET] = 130./255.;
297: rgb[2][PETSC_DRAW_VIOLET] = 238./255.;
298: rgb[0][PETSC_DRAW_BROWN] = 165./255. ;
299: rgb[1][PETSC_DRAW_BROWN] = 42./255.;
300: rgb[2][PETSC_DRAW_BROWN] = 42./255.;
301: rgb[0][PETSC_DRAW_PINK] = 255./255. ;
302: rgb[1][PETSC_DRAW_PINK] = 192./255. ;
303: rgb[2][PETSC_DRAW_PINK] = 203./255.;
304: rgb[0][PETSC_DRAW_CORAL] = 255./255.;
305: rgb[1][PETSC_DRAW_CORAL] = 127./255.;
306: rgb[2][PETSC_DRAW_CORAL] = 80./255.;
307: rgb[0][PETSC_DRAW_GRAY] = 190./255. ;
308: rgb[1][PETSC_DRAW_GRAY] = 190./255.;
309: rgb[2][PETSC_DRAW_GRAY] = 190./255.;
310: rgb[0][PETSC_DRAW_YELLOW] = 255./255. ;
311: rgb[1][PETSC_DRAW_YELLOW] = 255./255.;
312: rgb[2][PETSC_DRAW_YELLOW] = 0/255.;
313: rgb[0][PETSC_DRAW_GOLD] = 255./255. ;
314: rgb[1][PETSC_DRAW_GOLD] = 215./255.;
315: rgb[2][PETSC_DRAW_GOLD] = 0;
316: rgb[0][PETSC_DRAW_LIGHTPINK] = 255./255. ;
317: rgb[1][PETSC_DRAW_LIGHTPINK] = 182./255.;
318: rgb[2][PETSC_DRAW_LIGHTPINK] = 193./255.;
319: rgb[0][PETSC_DRAW_MEDIUMTURQUOISE] = 72./255.;
320: rgb[1][PETSC_DRAW_MEDIUMTURQUOISE] = 209./255.;
321: rgb[2][PETSC_DRAW_MEDIUMTURQUOISE] = 204./255.;
322: rgb[0][PETSC_DRAW_KHAKI] = 240./255. ;
323: rgb[1][PETSC_DRAW_KHAKI] = 230./255.;
324: rgb[2][PETSC_DRAW_KHAKI] = 140./255.;
325: rgb[0][PETSC_DRAW_DIMGRAY] = 105./255. ;
326: rgb[1][PETSC_DRAW_DIMGRAY] = 105./255.;
327: rgb[2][PETSC_DRAW_DIMGRAY] = 105./255.;
328: rgb[0][PETSC_DRAW_YELLOWGREEN] = 154./255. ;
329: rgb[1][PETSC_DRAW_YELLOWGREEN] = 205./255.;
330: rgb[2][PETSC_DRAW_YELLOWGREEN] = 50./255.;
331: rgb[0][PETSC_DRAW_SKYBLUE] = 135./255. ;
332: rgb[1][PETSC_DRAW_SKYBLUE] = 206./255.;
333: rgb[2][PETSC_DRAW_SKYBLUE] = 235./255.;
334: rgb[0][PETSC_DRAW_DARKGREEN] = 0 ;
335: rgb[1][PETSC_DRAW_DARKGREEN] = 100./255.;
336: rgb[2][PETSC_DRAW_DARKGREEN] = 0;
337: rgb[0][PETSC_DRAW_NAVYBLUE] = 0 ;
338: rgb[1][PETSC_DRAW_NAVYBLUE] = 0;
339: rgb[2][PETSC_DRAW_NAVYBLUE] = 128./255.;
340: rgb[0][PETSC_DRAW_SANDYBROWN] = 244./255. ;
341: rgb[1][PETSC_DRAW_SANDYBROWN] = 164./255.;
342: rgb[2][PETSC_DRAW_SANDYBROWN] = 96./255.;
343: rgb[0][PETSC_DRAW_CADETBLUE] = 95./255. ;
344: rgb[1][PETSC_DRAW_CADETBLUE] = 158./255.;
345: rgb[2][PETSC_DRAW_CADETBLUE] = 160./255.;
346: rgb[0][PETSC_DRAW_POWDERBLUE] = 176./255. ;
347: rgb[1][PETSC_DRAW_POWDERBLUE] = 224./255.;
348: rgb[2][PETSC_DRAW_POWDERBLUE] = 230./255.;
349: rgb[0][PETSC_DRAW_DEEPPINK] = 255./255. ;
350: rgb[1][PETSC_DRAW_DEEPPINK] = 20./255.;
351: rgb[2][PETSC_DRAW_DEEPPINK] = 147./255.;
352: rgb[0][PETSC_DRAW_THISTLE] = 216./255. ;
353: rgb[1][PETSC_DRAW_THISTLE] = 191./255.;
354: rgb[2][PETSC_DRAW_THISTLE] = 216./255.;
355: rgb[0][PETSC_DRAW_LIMEGREEN] = 50./255. ;
356: rgb[1][PETSC_DRAW_LIMEGREEN] = 205./255.;
357: rgb[2][PETSC_DRAW_LIMEGREEN] = 50./255.;
358: rgb[0][PETSC_DRAW_LAVENDERBLUSH] = 255./255. ;
359: rgb[1][PETSC_DRAW_LAVENDERBLUSH] = 240./255.;
360: rgb[2][PETSC_DRAW_LAVENDERBLUSH] = 245./255.;
362: /* now do the uniform hue part of the colors */
363: ncolors = 256-PETSC_DRAW_BASIC_COLORS;
364: ierr = PetscMalloc(3*ncolors*sizeof(unsigned char),&red);
365: green = red + ncolors;
366: blue = green + ncolors;
367: ierr = PetscDrawUtilitySetCmapHue(red,green,blue,ncolors);
368: for (i=PETSC_DRAW_BASIC_COLORS; i<ncolors+PETSC_DRAW_BASIC_COLORS; i++) {
369: rgb[0][i] = ((double)red[i-PETSC_DRAW_BASIC_COLORS])/255.;
370: rgb[1][i] = ((double)green[i-PETSC_DRAW_BASIC_COLORS])/255.;
371: rgb[2][i] = ((double)blue[i-PETSC_DRAW_BASIC_COLORS])/255.;
372: }
373: PetscFree(red);
374: }
376: draw->data = (void*)ps;
377: return(0);
378: }
379: EXTERN_C_END
383: /*
384: This works in Postscript coordinates
385: */
386: /*
388: this kind of thing should do contour triangles with Postscript level 3
389: 1000 dict begin
390: /ShadingType 4 def
391: /ColorSpace /DeviceRGB def
392: /DataSource [0 10 10 255 255 255 0 400 10 0 0 0 0 200 400 255 0 0] def
393: shfill
395: once we have Postscript level 3 we should put this in as an option
396: */
399: static int PetscDrawInterpolatedTriangle_PS(PetscDraw_PS* ps,PetscReal x1,PetscReal y_1,int t1,
400: PetscReal x2,PetscReal y2,int t2,PetscReal x3,PetscReal y3,int t3)
401: {
402: PetscReal rfrac,lfrac;
403: PetscReal lc,rc = 0.0,lx,rx = 0.0,xx,y;
404: PetscReal rc_lc,rx_lx,t2_t1,x2_x1,t3_t1,x3_x1,t3_t2,x3_x2;
405: PetscReal R_y2_y_1,R_y3_y_1,R_y3_y2;
406: int ierr,c;
409: /*
410: Is triangle even visible in window?
411: */
412: if (x1 < 0 && x2 < 0 && x3 < 0) return(0);
413: if (y_1 < 0 && y2 < 0 && y3 < 0) return(0);
414: if (x1 > 72*8.5 && x2 > 72*8.5 && x3 > 72*8.5) return(0);
415: if (y_1 > 72*11 && y2 > 72*11 && y3 > 72*11) return(0);
417: /* scale everything by two to reduce the huge file; note this reduces the quality */
418: x1 /= 2.0;
419: x2 /= 2.0;
420: x3 /= 2.0;
421: y_1 /= 2.0;
422: y2 /= 2.0;
423: y3 /= 2.0;
424: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"gsave 2 2 scalen");
427: /* Sort the vertices */
428: #define SWAP(a,b) {PetscReal _a; _a=a; a=b; b=_a;}
429: #define ISWAP(a,b) {int _a; _a=a; a=b; b=_a;}
430: if (y_1 > y2) {
431: SWAP(y_1,y2);ISWAP(t1,t2); SWAP(x1,x2);
432: }
433: if (y_1 > y3) {
434: SWAP(y_1,y3);ISWAP(t1,t3); SWAP(x1,x3);
435: }
436: if (y2 > y3) {
437: SWAP(y2,y3);ISWAP(t2,t3); SWAP(x2,x3);
438: }
439: /* This code is decidely non-optimal; it is intended to be a start at
440: an implementation */
442: if (y2 != y_1) R_y2_y_1 = 1.0/((y2-y_1)); else R_y2_y_1 = 0.0;
443: if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
444: t2_t1 = t2 - t1;
445: x2_x1 = x2 - x1;
446: t3_t1 = t3 - t1;
447: x3_x1 = x3 - x1;
448: for (y=y_1; y<=y2; y++) {
449: /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */
450: /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
451: lfrac = ((y-y_1)) * R_y2_y_1;
452: lc = (lfrac * (t2_t1) + t1);
453: lx = (lfrac * (x2_x1) + x1);
454: /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
455: rfrac = ((y - y_1)) * R_y3_y_1;
456: rc = (rfrac * (t3_t1) + t1);
457: rx = (rfrac * (x3_x1) + x1);
458: /* PetscDraw the line */
459: rc_lc = rc - lc;
460: rx_lx = rx - lx;
461: if (rx > lx) {
462: for (xx=lx; xx<=rx; xx++) {
463: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
464: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
465: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
466: }
467: } else if (rx < lx) {
468: for (xx=lx; xx>=rx; xx--) {
469: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
470: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
471: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
472: }
473: } else {
474: c = (int)lc;
475: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
476: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",lx,y,lx+1,y);
477: }
478: }
480: /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
481: We take advantage of the previous iteration. */
482: if (y2 >= y3) {
483: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestoren");
484: return(0);
485: }
486: if (y_1 < y2) {
487: t1 = (int)rc;
488: y_1 = y2;
489: x1 = rx;
491: t3_t1 = t3 - t1;
492: x3_x1 = x3 - x1;
493: }
494: t3_t2 = t3 - t2;
495: x3_x2 = x3 - x2;
496: if (y3 != y2) R_y3_y2 = 1.0/((y3-y2)); else R_y3_y2 = 0.0;
497: if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
498: for (y=y2; y<=y3; y++) {
499: /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */
500: /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
501: lfrac = ((y-y2)) * R_y3_y2;
502: lc = (lfrac * (t3_t2) + t2);
503: lx = (lfrac * (x3_x2) + x2);
504: /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
505: rfrac = ((y - y_1)) * R_y3_y_1;
506: rc = (rfrac * (t3_t1) + t1);
507: rx = (rfrac * (x3_x1) + x1);
508: /* PetscDraw the line */
509: rc_lc = rc - lc;
510: rx_lx = rx - lx;
511: if (rx > lx) {
512: for (xx=lx; xx<=rx; xx++) {
513: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
514: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
515: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
516: }
517: } else if (rx < lx) {
518: for (xx=lx; xx>=rx; xx--) {
519: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
520: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
521: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
522: }
523: } else {
524: c = (int)lc;
525: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
526: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",lx,y,lx+1,y);
527: }
528: }
529: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestoren");
530: return(0);
531: }