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: #undef __FUNCT__
11: /*@C
12: PetscDrawOpenPS - Opens a PetscViewer that generates Postscript
14: Collective on MPI_Comm
16: Input Parameters:
17: + comm - communicator that shares the PetscViewer
18: - file - name of file where Postscript is to be stored
20: Output Parameter:
21: . viewer - the PetscViewer object
23: Level: beginner
25: .seealso: PetscDrawDestroy(), PetscDrawOpenX(), PetscDrawCreate(), PetscViewerDrawOpen(), PetscViewerDrawGetDraw()
26: @*/
27: int PetscDrawOpenPS(MPI_Comm comm,char *filename,PetscDraw *draw)
28: {
32: PetscDrawCreate(comm,filename,0,0,0,0,0,draw);
33: PetscDrawSetType(*draw,PETSC_DRAW_PS);
34: return(0);
35: }
37: /*
38: These macros transform from the users coordinates to the Postscript
39: */
40: #define WIDTH 8.5*72
41: #define HEIGHT 11*72
42: #define XTRANS(win,x)
43: ((WIDTH)*((win)->port_xl+(((x-(win)->coor_xl)*((win)->port_xr-(win)->port_xl))/((win)->coor_xr-(win)->coor_xl))))
44: #define YTRANS(win,y)
45: ((HEIGHT)*((win)->port_yl+(((y-(win)->coor_yl)*((win)->port_yr-(win)->port_yl))/((win)->coor_yr-(win)->coor_yl))))
47: /*
48: Contains the RGB colors for the PETSc defined colors
49: */
50: static PetscReal rgb[3][256];
51: static PetscTruth rgbfilled = PETSC_FALSE;
53: #define PSSetColor(ps,c) (((c) == ps->currentcolor) ? 0 :
54: (ps->currentcolor = (c),PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g setrgbcolorn",rgb[0][c],rgb[1][c],rgb[2][c])))
56: #undef __FUNCT__
58: static int PetscDrawPoint_PS(PetscDraw draw,PetscReal x,PetscReal y,int c)
59: {
60: PetscReal xx,yy;
61: int ierr;
62: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
65: xx = XTRANS(draw,x); yy = YTRANS(draw,y);
66: PSSetColor(ps,c);
67: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto stroken",xx,yy,xx+1,yy);
68: return(0);
69: }
71: #undef __FUNCT__
73: static int PetscDrawLine_PS(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
74: {
75: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
76: PetscReal x1,y_1,x2,y2;
77: int ierr;
80: x1 = XTRANS(draw,xl); x2 = XTRANS(draw,xr);
81: y_1 = YTRANS(draw,yl); y2 = YTRANS(draw,yr);
82: PSSetColor(ps,c);
83: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto %g %g lineto stroken",x1,y_1,x2,y2);
84: return(0);
85: }
87: #undef __FUNCT__
89: static int PetscDrawStringSetSize_PS(PetscDraw draw,PetscReal x,PetscReal y)
90: {
91: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
92: int ierr,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 setfontn",(w+h)/2.0);
98: return(0);
99: }
101: #undef __FUNCT__
103: static int 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: }
113: #undef __FUNCT__
115: static int PetscDrawString_PS(PetscDraw draw,PetscReal x,PetscReal y,int c,char *chrs)
116: {
117: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
118: PetscReal x1,y_1;
119: int ierr;
122: PSSetColor(ps,c);
123: x1 = XTRANS(draw,x);
124: y_1 = YTRANS(draw,y);
125: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g moveto (%s) shown",x1,y_1,chrs);
126: return(0);
127: }
129: #undef __FUNCT__
131: static int PetscDrawStringVertical_PS(PetscDraw draw,PetscReal x,PetscReal y,int c,char *chrs)
132: {
133: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
134: PetscReal x1,y_1;
135: int ierr;
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 grestoren",x1,y_1,chrs);
142: return(0);
143: }
145: static int PetscDrawInterpolatedTriangle_PS(PetscDraw_PS*,PetscReal,PetscReal,int,PetscReal,PetscReal,int,PetscReal,PetscReal,int);
147: #undef __FUNCT__
149: static int 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;
153: int ierr;
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 filln",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: }
173: #undef __FUNCT__
175: static int 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;
179: int ierr;
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 filln",x1,y_1,x2,y2,x3,y3,x4,y4,x1,y_1);
194: return(0);
195: }
197: #undef __FUNCT__
199: static int PetscDrawDestroy_PS(PetscDraw draw)
200: {
201: PetscDraw_PS *ps = (PetscDraw_PS*)draw->data;
202: int ierr;
203: PetscTruth show;
204: char *filename,par[PETSC_MAX_PATH_LEN];
205:
207: PetscViewerASCIIPrintf(ps->ps_file,"nshowpagen");
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: }
220: #undef __FUNCT__
222: static int PetscDrawSynchronizedFlush_PS(PetscDraw draw)
223: {
224: int ierr;
225: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
228: PetscViewerFlush(ps->ps_file);
229: return(0);
230: }
232: #undef __FUNCT__
234: static int PetscDrawSynchronizedClear_PS(PetscDraw draw)
235: {
236: int ierr;
237: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
240: PetscViewerFlush(ps->ps_file);
241: PetscViewerASCIIPrintf(ps->ps_file,"nshowpagen");
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 };
277: EXTERN_C_BEGIN
278: #undef __FUNCT__
280: int PetscDrawCreate_PS(PetscDraw draw)
281: {
282: PetscDraw_PS *ps;
283: int ierr,ncolors,i;
284: unsigned char *red,*green,*blue;
285: static int filecount = 0;
286: char buff[32];
287: char version[256];
290: if (!draw->display) {
291: sprintf(buff,"defaultps%d.ps",filecount++);
292: PetscStrallocpy(buff,&draw->display);
293: }
295: PetscGetVersion(&version);
296: PetscNew(PetscDraw_PS,&ps);
297: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
298: PetscViewerASCIIOpen(draw->comm,draw->display,&ps->ps_file);
299: PetscViewerASCIIPrintf(ps->ps_file,"%%!PS-Adobe-2.0n");
300: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Creator: PETSc %sn",version);
301: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Title: %sn",draw->display);
302: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Pages: 1n");
303: PetscViewerASCIIPrintf(ps->ps_file,"%%%%PageOrder: Ascendn");
304: PetscViewerASCIIPrintf(ps->ps_file,"%%%%BoundingBox: 0 0 612 792n");
305: PetscViewerASCIIPrintf(ps->ps_file,"%%%%DocumentFonts: Helvetica-normal Symboln");
306: PetscViewerASCIIPrintf(ps->ps_file,"%%%%EndCommentsn");
307: PetscViewerASCIIPrintf(ps->ps_file,"/Helvetica-normal findfont 10 scalefont setfontn");
308: PetscViewerASCIIPrintf(ps->ps_file,"/c {setrgbcolor} defn");
309: PetscViewerASCIIPrintf(ps->ps_file,"/l {lineto stroke} defn");
310: PetscViewerASCIIPrintf(ps->ps_file,"/m {moveto} defn");
312: ps->currentcolor = PETSC_DRAW_BLACK;
314: if (!rgbfilled) {
315: rgbfilled = PETSC_TRUE;
316: rgb[0][PETSC_DRAW_WHITE] = 255/255;
317: rgb[1][PETSC_DRAW_WHITE] = 255/255;
318: rgb[2][PETSC_DRAW_WHITE] = 255/255;
319: rgb[0][PETSC_DRAW_BLACK] = 0;
320: rgb[1][PETSC_DRAW_BLACK] = 0;
321: rgb[2][PETSC_DRAW_BLACK] = 0;
322: rgb[0][PETSC_DRAW_RED] = 255/255;
323: rgb[1][PETSC_DRAW_RED] = 0;
324: rgb[2][PETSC_DRAW_RED] = 0;
325: rgb[0][PETSC_DRAW_GREEN] = 0;
326: rgb[1][PETSC_DRAW_GREEN] = 255./255;
327: rgb[2][PETSC_DRAW_GREEN] = 0;
328: rgb[0][PETSC_DRAW_CYAN] = 0;
329: rgb[1][PETSC_DRAW_CYAN] = 255./255;
330: rgb[2][PETSC_DRAW_CYAN] = 255./255;
331: rgb[0][PETSC_DRAW_BLUE] = 0;
332: rgb[1][PETSC_DRAW_BLUE] = 0;
333: rgb[2][PETSC_DRAW_BLUE] = 255./255;
334: rgb[0][PETSC_DRAW_MAGENTA] = 255./255;
335: rgb[1][PETSC_DRAW_MAGENTA] = 0;
336: rgb[2][PETSC_DRAW_MAGENTA] = 255./255;
337: rgb[0][PETSC_DRAW_AQUAMARINE] = 127./255;
338: rgb[1][PETSC_DRAW_AQUAMARINE] = 255./255;
339: rgb[2][PETSC_DRAW_AQUAMARINE] = 212./255;
340: rgb[0][PETSC_DRAW_FORESTGREEN] = 34./255 ;
341: rgb[1][PETSC_DRAW_FORESTGREEN] = 139./255.;
342: rgb[2][PETSC_DRAW_FORESTGREEN] = 34./255. ;
343: rgb[0][PETSC_DRAW_ORANGE] = 255./255. ;
344: rgb[1][PETSC_DRAW_ORANGE] = 165./255.;
345: rgb[2][PETSC_DRAW_ORANGE] = 0 ;
346: rgb[0][PETSC_DRAW_VIOLET] = 238./255. ;
347: rgb[1][PETSC_DRAW_VIOLET] = 130./255.;
348: rgb[2][PETSC_DRAW_VIOLET] = 238./255.;
349: rgb[0][PETSC_DRAW_BROWN] = 165./255. ;
350: rgb[1][PETSC_DRAW_BROWN] = 42./255.;
351: rgb[2][PETSC_DRAW_BROWN] = 42./255.;
352: rgb[0][PETSC_DRAW_PINK] = 255./255. ;
353: rgb[1][PETSC_DRAW_PINK] = 192./255. ;
354: rgb[2][PETSC_DRAW_PINK] = 203./255.;
355: rgb[0][PETSC_DRAW_CORAL] = 255./255.;
356: rgb[1][PETSC_DRAW_CORAL] = 127./255.;
357: rgb[2][PETSC_DRAW_CORAL] = 80./255.;
358: rgb[0][PETSC_DRAW_GRAY] = 190./255. ;
359: rgb[1][PETSC_DRAW_GRAY] = 190./255.;
360: rgb[2][PETSC_DRAW_GRAY] = 190./255.;
361: rgb[0][PETSC_DRAW_YELLOW] = 255./255. ;
362: rgb[1][PETSC_DRAW_YELLOW] = 255./255.;
363: rgb[2][PETSC_DRAW_YELLOW] = 0/255.;
364: rgb[0][PETSC_DRAW_GOLD] = 255./255. ;
365: rgb[1][PETSC_DRAW_GOLD] = 215./255.;
366: rgb[2][PETSC_DRAW_GOLD] = 0;
367: rgb[0][PETSC_DRAW_LIGHTPINK] = 255./255. ;
368: rgb[1][PETSC_DRAW_LIGHTPINK] = 182./255.;
369: rgb[2][PETSC_DRAW_LIGHTPINK] = 193./255.;
370: rgb[0][PETSC_DRAW_MEDIUMTURQUOISE] = 72./255.;
371: rgb[1][PETSC_DRAW_MEDIUMTURQUOISE] = 209./255.;
372: rgb[2][PETSC_DRAW_MEDIUMTURQUOISE] = 204./255.;
373: rgb[0][PETSC_DRAW_KHAKI] = 240./255. ;
374: rgb[1][PETSC_DRAW_KHAKI] = 230./255.;
375: rgb[2][PETSC_DRAW_KHAKI] = 140./255.;
376: rgb[0][PETSC_DRAW_DIMGRAY] = 105./255. ;
377: rgb[1][PETSC_DRAW_DIMGRAY] = 105./255.;
378: rgb[2][PETSC_DRAW_DIMGRAY] = 105./255.;
379: rgb[0][PETSC_DRAW_YELLOWGREEN] = 154./255. ;
380: rgb[1][PETSC_DRAW_YELLOWGREEN] = 205./255.;
381: rgb[2][PETSC_DRAW_YELLOWGREEN] = 50./255.;
382: rgb[0][PETSC_DRAW_SKYBLUE] = 135./255. ;
383: rgb[1][PETSC_DRAW_SKYBLUE] = 206./255.;
384: rgb[2][PETSC_DRAW_SKYBLUE] = 235./255.;
385: rgb[0][PETSC_DRAW_DARKGREEN] = 0 ;
386: rgb[1][PETSC_DRAW_DARKGREEN] = 100./255.;
387: rgb[2][PETSC_DRAW_DARKGREEN] = 0;
388: rgb[0][PETSC_DRAW_NAVYBLUE] = 0 ;
389: rgb[1][PETSC_DRAW_NAVYBLUE] = 0;
390: rgb[2][PETSC_DRAW_NAVYBLUE] = 128./255.;
391: rgb[0][PETSC_DRAW_SANDYBROWN] = 244./255. ;
392: rgb[1][PETSC_DRAW_SANDYBROWN] = 164./255.;
393: rgb[2][PETSC_DRAW_SANDYBROWN] = 96./255.;
394: rgb[0][PETSC_DRAW_CADETBLUE] = 95./255. ;
395: rgb[1][PETSC_DRAW_CADETBLUE] = 158./255.;
396: rgb[2][PETSC_DRAW_CADETBLUE] = 160./255.;
397: rgb[0][PETSC_DRAW_POWDERBLUE] = 176./255. ;
398: rgb[1][PETSC_DRAW_POWDERBLUE] = 224./255.;
399: rgb[2][PETSC_DRAW_POWDERBLUE] = 230./255.;
400: rgb[0][PETSC_DRAW_DEEPPINK] = 255./255. ;
401: rgb[1][PETSC_DRAW_DEEPPINK] = 20./255.;
402: rgb[2][PETSC_DRAW_DEEPPINK] = 147./255.;
403: rgb[0][PETSC_DRAW_THISTLE] = 216./255. ;
404: rgb[1][PETSC_DRAW_THISTLE] = 191./255.;
405: rgb[2][PETSC_DRAW_THISTLE] = 216./255.;
406: rgb[0][PETSC_DRAW_LIMEGREEN] = 50./255. ;
407: rgb[1][PETSC_DRAW_LIMEGREEN] = 205./255.;
408: rgb[2][PETSC_DRAW_LIMEGREEN] = 50./255.;
409: rgb[0][PETSC_DRAW_LAVENDERBLUSH] = 255./255. ;
410: rgb[1][PETSC_DRAW_LAVENDERBLUSH] = 240./255.;
411: rgb[2][PETSC_DRAW_LAVENDERBLUSH] = 245./255.;
413: /* now do the uniform hue part of the colors */
414: ncolors = 256-PETSC_DRAW_BASIC_COLORS;
415: ierr = PetscMalloc(3*ncolors*sizeof(unsigned char),&red);
416: green = red + ncolors;
417: blue = green + ncolors;
418: ierr = PetscDrawUtilitySetCmapHue(red,green,blue,ncolors);
419: for (i=PETSC_DRAW_BASIC_COLORS; i<ncolors+PETSC_DRAW_BASIC_COLORS; i++) {
420: rgb[0][i] = ((double)red[i-PETSC_DRAW_BASIC_COLORS])/255.;
421: rgb[1][i] = ((double)green[i-PETSC_DRAW_BASIC_COLORS])/255.;
422: rgb[2][i] = ((double)blue[i-PETSC_DRAW_BASIC_COLORS])/255.;
423: }
424: PetscFree(red);
425: }
427: draw->data = (void*)ps;
428: return(0);
429: }
430: EXTERN_C_END
434: /*
435: This works in Postscript coordinates
436: */
437: /*
439: this kind of thing should do contour triangles with Postscript level 3
440: 1000 dict begin
441: /ShadingType 4 def
442: /ColorSpace /DeviceRGB def
443: /DataSource [0 10 10 255 255 255 0 400 10 0 0 0 0 200 400 255 0 0] def
444: shfill
446: once we have Postscript level 3 we should put this in as an option
447: */
450: #undef __FUNCT__
452: static int PetscDrawInterpolatedTriangle_PS(PetscDraw_PS* ps,PetscReal x1,PetscReal y_1,int t1,
453: PetscReal x2,PetscReal y2,int t2,PetscReal x3,PetscReal y3,int t3)
454: {
455: PetscReal rfrac,lfrac;
456: PetscReal lc,rc = 0.0,lx,rx = 0.0,xx,y;
457: PetscReal rc_lc,rx_lx,t2_t1,x2_x1,t3_t1,x3_x1,t3_t2,x3_x2;
458: PetscReal R_y2_y_1,R_y3_y_1,R_y3_y2;
459: int ierr,c;
462: /*
463: Is triangle even visible in window?
464: */
465: if (x1 < 0 && x2 < 0 && x3 < 0) return(0);
466: if (y_1 < 0 && y2 < 0 && y3 < 0) return(0);
467: if (x1 > 72*8.5 && x2 > 72*8.5 && x3 > 72*8.5) return(0);
468: if (y_1 > 72*11 && y2 > 72*11 && y3 > 72*11) return(0);
470: /* scale everything by two to reduce the huge file; note this reduces the quality */
471: x1 /= 2.0;
472: x2 /= 2.0;
473: x3 /= 2.0;
474: y_1 /= 2.0;
475: y2 /= 2.0;
476: y3 /= 2.0;
477: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"gsave 2 2 scalen");
480: /* Sort the vertices */
481: #define SWAP(a,b) {PetscReal _a; _a=a; a=b; b=_a;}
482: #define ISWAP(a,b) {int _a; _a=a; a=b; b=_a;}
483: if (y_1 > y2) {
484: SWAP(y_1,y2);ISWAP(t1,t2); SWAP(x1,x2);
485: }
486: if (y_1 > y3) {
487: SWAP(y_1,y3);ISWAP(t1,t3); SWAP(x1,x3);
488: }
489: if (y2 > y3) {
490: SWAP(y2,y3);ISWAP(t2,t3); SWAP(x2,x3);
491: }
492: /* This code is decidely non-optimal; it is intended to be a start at
493: an implementation */
495: if (y2 != y_1) R_y2_y_1 = 1.0/((y2-y_1)); else R_y2_y_1 = 0.0;
496: if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
497: t2_t1 = t2 - t1;
498: x2_x1 = x2 - x1;
499: t3_t1 = t3 - t1;
500: x3_x1 = x3 - x1;
501: for (y=y_1; y<=y2; y++) {
502: /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */
503: /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
504: lfrac = ((y-y_1)) * R_y2_y_1;
505: lc = (lfrac * (t2_t1) + t1);
506: lx = (lfrac * (x2_x1) + x1);
507: /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
508: rfrac = ((y - y_1)) * R_y3_y_1;
509: rc = (rfrac * (t3_t1) + t1);
510: rx = (rfrac * (x3_x1) + x1);
511: /* PetscDraw the line */
512: rc_lc = rc - lc;
513: rx_lx = rx - lx;
514: if (rx > lx) {
515: for (xx=lx; xx<=rx; xx++) {
516: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
517: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
518: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
519: }
520: } else if (rx < lx) {
521: for (xx=lx; xx>=rx; xx--) {
522: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
523: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
524: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
525: }
526: } else {
527: c = (int)lc;
528: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
529: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",lx,y,lx+1,y);
530: }
531: }
533: /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
534: We take advantage of the previous iteration. */
535: if (y2 >= y3) {
536: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestoren");
537: return(0);
538: }
539: if (y_1 < y2) {
540: t1 = (int)rc;
541: y_1 = y2;
542: x1 = rx;
544: t3_t1 = t3 - t1;
545: x3_x1 = x3 - x1;
546: }
547: t3_t2 = t3 - t2;
548: x3_x2 = x3 - x2;
549: if (y3 != y2) R_y3_y2 = 1.0/((y3-y2)); else R_y3_y2 = 0.0;
550: if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
551: for (y=y2; y<=y3; y++) {
552: /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */
553: /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
554: lfrac = ((y-y2)) * R_y3_y2;
555: lc = (lfrac * (t3_t2) + t2);
556: lx = (lfrac * (x3_x2) + x2);
557: /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
558: rfrac = ((y - y_1)) * R_y3_y_1;
559: rc = (rfrac * (t3_t1) + t1);
560: rx = (rfrac * (x3_x1) + x1);
561: /* PetscDraw the line */
562: rc_lc = rc - lc;
563: rx_lx = rx - lx;
564: if (rx > lx) {
565: for (xx=lx; xx<=rx; xx++) {
566: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
567: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
568: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
569: }
570: } else if (rx < lx) {
571: for (xx=lx; xx>=rx; xx--) {
572: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
573: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
574: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",xx,y,xx+1,y);
575: }
576: } else {
577: c = (int)lc;
578: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g %g cn",rgb[0][c],rgb[1][c],rgb[2][c]);
579: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%g %g m %g %g ln",lx,y,lx+1,y);
580: }
581: }
582: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestoren");
583: return(0);
584: }