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