Actual source code: pops.c
1: #define PETSC_DLL
3: /*
4: Defines the operations for the Postscript PetscDraw implementation.
5: */
7: #include src/sys/draw/impls/ps/psimpl.h
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: PetscErrorCode 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 setrgbcolor\n",rgb[0][c],rgb[1][c],rgb[2][c])))
58: static PetscErrorCode PetscDrawPoint_PS(PetscDraw draw,PetscReal x,PetscReal y,int c)
59: {
60: PetscReal xx,yy;
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 stroke\n",xx,yy,xx+1,yy);
68: return(0);
69: }
73: static PetscErrorCode 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;
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 stroke\n",x1,y_1,x2,y2);
84: return(0);
85: }
89: static PetscErrorCode PetscDrawStringSetSize_PS(PetscDraw draw,PetscReal x,PetscReal y)
90: {
91: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
93: int w,h;
96: w = (int)((WIDTH)*x*(draw->port_xr - draw->port_xl)/(draw->coor_xr - draw->coor_xl));
97: h = (int)((HEIGHT)*y*(draw->port_yr - draw->port_yl)/(draw->coor_yr - draw->coor_yl));
98: PetscViewerASCIIPrintf(ps->ps_file,"/Helvetica-normal findfont %G scalefont setfont\n",(w+h)/2.0);
99: return(0);
100: }
104: static PetscErrorCode PetscDrawStringGetSize_PS(PetscDraw draw,PetscReal *x,PetscReal *y)
105: {
106: PetscReal w = 9,h = 9;
109: *x = w*(draw->coor_xr - draw->coor_xl)/(WIDTH)*(draw->port_xr - draw->port_xl);
110: *y = h*(draw->coor_yr - draw->coor_yl)/(HEIGHT)*(draw->port_yr - draw->port_yl);
111: return(0);
112: }
116: static PetscErrorCode PetscDrawString_PS(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
117: {
118: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
119: PetscReal x1,y_1;
123: PSSetColor(ps,c);
124: x1 = XTRANS(draw,x);
125: y_1 = YTRANS(draw,y);
126: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G moveto (%s) show\n",x1,y_1,chrs);
127: return(0);
128: }
132: static PetscErrorCode PetscDrawStringVertical_PS(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
133: {
134: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
135: PetscReal x1,y_1;
139: PSSetColor(ps,c);
140: x1 = XTRANS(draw,x);
141: y_1 = YTRANS(draw,y);
142: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"gsave %G %G moveto 90 rotate (%s) show grestore\n",x1,y_1,chrs);
143: return(0);
144: }
146: static PetscErrorCode PetscDrawInterpolatedTriangle_PS(PetscDraw_PS*,PetscReal,PetscReal,int,PetscReal,PetscReal,int,PetscReal,PetscReal,int);
150: static PetscErrorCode PetscDrawTriangle_PS(PetscDraw draw,PetscReal X1,PetscReal Y_1,PetscReal X2,
151: PetscReal Y2,PetscReal X3,PetscReal Y3,int c1,int c2,int c3)
152: {
153: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
155: PetscReal x1,y_1,x2,y2,x3,y3;
158: x1 = XTRANS(draw,X1);
159: y_1 = YTRANS(draw,Y_1);
160: x2 = XTRANS(draw,X2);
161: y2 = YTRANS(draw,Y2);
162: x3 = XTRANS(draw,X3);
163: y3 = YTRANS(draw,Y3);
165: if (c1 == c2 && c2 == c3) {
166: PSSetColor(ps,c1);
167: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G moveto %G %G lineto %G %G lineto fill\n",x1,y_1,x2,y2,x3,y3);
168: } else {
169: PetscDrawInterpolatedTriangle_PS(ps,x1,y_1,c1,x2,y2,c2,x3,y3,c3);
170: }
171: return(0);
172: }
176: static PetscErrorCode PetscDrawRectangle_PS(PetscDraw draw,PetscReal X1,PetscReal Y_1,PetscReal X2,
177: PetscReal Y2,int c1,int c2,int c3,int c4)
178: {
179: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
181: PetscReal x1,y_1,x2,y2,x3,y3,x4,y4;
184: x1 = XTRANS(draw,X1);
185: y_1 = YTRANS(draw,Y_1);
186: x2 = XTRANS(draw,X2);
187: y2 = YTRANS(draw,Y_1);
188: x3 = XTRANS(draw,X2);
189: y3 = YTRANS(draw,Y2);
190: x4 = XTRANS(draw,X1);
191: y4 = YTRANS(draw,Y2);
193: PSSetColor(ps,(c1+c2+c3+c4)/4);
194: 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);
195: return(0);
196: }
200: static PetscErrorCode PetscDrawDestroy_PS(PetscDraw draw)
201: {
202: PetscDraw_PS *ps = (PetscDraw_PS*)draw->data;
204: PetscTruth show;
205: char *filename,par[PETSC_MAX_PATH_LEN];
206:
208: PetscViewerASCIIPrintf(ps->ps_file,"\nshowpage\n");
209: PetscOptionsHasName(draw->prefix,"-draw_ps_show",&show);
210: if (show) {
211: PetscViewerFileGetName(ps->ps_file,&filename);
212: PetscStrcpy(par,"ghostview ");
213: PetscStrcat(par,filename);
214: #if defined(PETSC_HAVE_POPEN)
215: PetscPOpen(draw->comm,PETSC_NULL,par,"r",PETSC_NULL);
216: #else
217: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
218: #endif
219: }
220: PetscViewerDestroy(ps->ps_file);
221: PetscFree(ps);
222: return(0);
223: }
227: static PetscErrorCode PetscDrawSynchronizedFlush_PS(PetscDraw draw)
228: {
230: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
233: PetscViewerFlush(ps->ps_file);
234: return(0);
235: }
239: static PetscErrorCode PetscDrawSynchronizedClear_PS(PetscDraw draw)
240: {
242: PetscDraw_PS* ps = (PetscDraw_PS*)draw->data;
245: PetscViewerFlush(ps->ps_file);
246: PetscViewerASCIIPrintf(ps->ps_file,"\nshowpage\n");
247: return(0);
248: }
250: static struct _PetscDrawOps DvOps = { 0,
251: 0,
252: PetscDrawLine_PS,
253: 0,
254: 0,
255: PetscDrawPoint_PS,
256: 0,
257: PetscDrawString_PS,
258: PetscDrawStringVertical_PS,
259: PetscDrawStringSetSize_PS,
260: PetscDrawStringGetSize_PS,
261: 0,
262: 0,
263: PetscDrawSynchronizedFlush_PS,
264: PetscDrawRectangle_PS,
265: PetscDrawTriangle_PS,
266: 0,
267: 0,
268: 0,
269: PetscDrawSynchronizedClear_PS,
270: 0,
271: 0,
272: 0,
273: 0,
274: 0,
275: 0,
276: PetscDrawDestroy_PS,
277: 0,
278: 0,
279: 0 };
284: PetscErrorCode PetscDrawCreate_PS(PetscDraw draw)
285: {
286: PetscDraw_PS *ps;
288: int ncolors,i;
289: unsigned char *red,*green,*blue;
290: static int filecount = 0;
291: char buff[32];
292: char version[256];
295: if (!draw->display) {
296: sprintf(buff,"defaultps%d.ps",filecount++);
297: PetscStrallocpy(buff,&draw->display);
298: }
300: PetscGetVersion(&version,256);
301: PetscNew(PetscDraw_PS,&ps);
302: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
303: PetscViewerASCIIOpen(draw->comm,draw->display,&ps->ps_file);
304: PetscViewerASCIIPrintf(ps->ps_file,"%%!PS-Adobe-2.0\n");
305: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Creator: PETSc %s\n",version);
306: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Title: %s\n",draw->display);
307: PetscViewerASCIIPrintf(ps->ps_file,"%%%%Pages: 1\n");
308: PetscViewerASCIIPrintf(ps->ps_file,"%%%%PageOrder: Ascend\n");
309: PetscViewerASCIIPrintf(ps->ps_file,"%%%%BoundingBox: 0 0 612 792\n");
310: PetscViewerASCIIPrintf(ps->ps_file,"%%%%DocumentFonts: Helvetica-normal Symbol\n");
311: PetscViewerASCIIPrintf(ps->ps_file,"%%%%EndComments\n");
312: PetscViewerASCIIPrintf(ps->ps_file,"/Helvetica-normal findfont 10 scalefont setfont\n");
313: PetscViewerASCIIPrintf(ps->ps_file,"/c {setrgbcolor} def\n");
314: PetscViewerASCIIPrintf(ps->ps_file,"/l {lineto stroke} def\n");
315: PetscViewerASCIIPrintf(ps->ps_file,"/m {moveto} def\n");
317: ps->currentcolor = PETSC_DRAW_BLACK;
319: if (!rgbfilled) {
320: rgbfilled = PETSC_TRUE;
321: rgb[0][PETSC_DRAW_WHITE] = 255/255;
322: rgb[1][PETSC_DRAW_WHITE] = 255/255;
323: rgb[2][PETSC_DRAW_WHITE] = 255/255;
324: rgb[0][PETSC_DRAW_BLACK] = 0;
325: rgb[1][PETSC_DRAW_BLACK] = 0;
326: rgb[2][PETSC_DRAW_BLACK] = 0;
327: rgb[0][PETSC_DRAW_RED] = 255/255;
328: rgb[1][PETSC_DRAW_RED] = 0;
329: rgb[2][PETSC_DRAW_RED] = 0;
330: rgb[0][PETSC_DRAW_GREEN] = 0;
331: rgb[1][PETSC_DRAW_GREEN] = 255./255;
332: rgb[2][PETSC_DRAW_GREEN] = 0;
333: rgb[0][PETSC_DRAW_CYAN] = 0;
334: rgb[1][PETSC_DRAW_CYAN] = 255./255;
335: rgb[2][PETSC_DRAW_CYAN] = 255./255;
336: rgb[0][PETSC_DRAW_BLUE] = 0;
337: rgb[1][PETSC_DRAW_BLUE] = 0;
338: rgb[2][PETSC_DRAW_BLUE] = 255./255;
339: rgb[0][PETSC_DRAW_MAGENTA] = 255./255;
340: rgb[1][PETSC_DRAW_MAGENTA] = 0;
341: rgb[2][PETSC_DRAW_MAGENTA] = 255./255;
342: rgb[0][PETSC_DRAW_AQUAMARINE] = 127./255;
343: rgb[1][PETSC_DRAW_AQUAMARINE] = 255./255;
344: rgb[2][PETSC_DRAW_AQUAMARINE] = 212./255;
345: rgb[0][PETSC_DRAW_FORESTGREEN] = 34./255 ;
346: rgb[1][PETSC_DRAW_FORESTGREEN] = 139./255.;
347: rgb[2][PETSC_DRAW_FORESTGREEN] = 34./255. ;
348: rgb[0][PETSC_DRAW_ORANGE] = 255./255. ;
349: rgb[1][PETSC_DRAW_ORANGE] = 165./255.;
350: rgb[2][PETSC_DRAW_ORANGE] = 0 ;
351: rgb[0][PETSC_DRAW_VIOLET] = 238./255. ;
352: rgb[1][PETSC_DRAW_VIOLET] = 130./255.;
353: rgb[2][PETSC_DRAW_VIOLET] = 238./255.;
354: rgb[0][PETSC_DRAW_BROWN] = 165./255. ;
355: rgb[1][PETSC_DRAW_BROWN] = 42./255.;
356: rgb[2][PETSC_DRAW_BROWN] = 42./255.;
357: rgb[0][PETSC_DRAW_PINK] = 255./255. ;
358: rgb[1][PETSC_DRAW_PINK] = 192./255. ;
359: rgb[2][PETSC_DRAW_PINK] = 203./255.;
360: rgb[0][PETSC_DRAW_CORAL] = 255./255.;
361: rgb[1][PETSC_DRAW_CORAL] = 127./255.;
362: rgb[2][PETSC_DRAW_CORAL] = 80./255.;
363: rgb[0][PETSC_DRAW_GRAY] = 190./255. ;
364: rgb[1][PETSC_DRAW_GRAY] = 190./255.;
365: rgb[2][PETSC_DRAW_GRAY] = 190./255.;
366: rgb[0][PETSC_DRAW_YELLOW] = 255./255. ;
367: rgb[1][PETSC_DRAW_YELLOW] = 255./255.;
368: rgb[2][PETSC_DRAW_YELLOW] = 0/255.;
369: rgb[0][PETSC_DRAW_GOLD] = 255./255. ;
370: rgb[1][PETSC_DRAW_GOLD] = 215./255.;
371: rgb[2][PETSC_DRAW_GOLD] = 0;
372: rgb[0][PETSC_DRAW_LIGHTPINK] = 255./255. ;
373: rgb[1][PETSC_DRAW_LIGHTPINK] = 182./255.;
374: rgb[2][PETSC_DRAW_LIGHTPINK] = 193./255.;
375: rgb[0][PETSC_DRAW_MEDIUMTURQUOISE] = 72./255.;
376: rgb[1][PETSC_DRAW_MEDIUMTURQUOISE] = 209./255.;
377: rgb[2][PETSC_DRAW_MEDIUMTURQUOISE] = 204./255.;
378: rgb[0][PETSC_DRAW_KHAKI] = 240./255. ;
379: rgb[1][PETSC_DRAW_KHAKI] = 230./255.;
380: rgb[2][PETSC_DRAW_KHAKI] = 140./255.;
381: rgb[0][PETSC_DRAW_DIMGRAY] = 105./255. ;
382: rgb[1][PETSC_DRAW_DIMGRAY] = 105./255.;
383: rgb[2][PETSC_DRAW_DIMGRAY] = 105./255.;
384: rgb[0][PETSC_DRAW_YELLOWGREEN] = 154./255. ;
385: rgb[1][PETSC_DRAW_YELLOWGREEN] = 205./255.;
386: rgb[2][PETSC_DRAW_YELLOWGREEN] = 50./255.;
387: rgb[0][PETSC_DRAW_SKYBLUE] = 135./255. ;
388: rgb[1][PETSC_DRAW_SKYBLUE] = 206./255.;
389: rgb[2][PETSC_DRAW_SKYBLUE] = 235./255.;
390: rgb[0][PETSC_DRAW_DARKGREEN] = 0 ;
391: rgb[1][PETSC_DRAW_DARKGREEN] = 100./255.;
392: rgb[2][PETSC_DRAW_DARKGREEN] = 0;
393: rgb[0][PETSC_DRAW_NAVYBLUE] = 0 ;
394: rgb[1][PETSC_DRAW_NAVYBLUE] = 0;
395: rgb[2][PETSC_DRAW_NAVYBLUE] = 128./255.;
396: rgb[0][PETSC_DRAW_SANDYBROWN] = 244./255. ;
397: rgb[1][PETSC_DRAW_SANDYBROWN] = 164./255.;
398: rgb[2][PETSC_DRAW_SANDYBROWN] = 96./255.;
399: rgb[0][PETSC_DRAW_CADETBLUE] = 95./255. ;
400: rgb[1][PETSC_DRAW_CADETBLUE] = 158./255.;
401: rgb[2][PETSC_DRAW_CADETBLUE] = 160./255.;
402: rgb[0][PETSC_DRAW_POWDERBLUE] = 176./255. ;
403: rgb[1][PETSC_DRAW_POWDERBLUE] = 224./255.;
404: rgb[2][PETSC_DRAW_POWDERBLUE] = 230./255.;
405: rgb[0][PETSC_DRAW_DEEPPINK] = 255./255. ;
406: rgb[1][PETSC_DRAW_DEEPPINK] = 20./255.;
407: rgb[2][PETSC_DRAW_DEEPPINK] = 147./255.;
408: rgb[0][PETSC_DRAW_THISTLE] = 216./255. ;
409: rgb[1][PETSC_DRAW_THISTLE] = 191./255.;
410: rgb[2][PETSC_DRAW_THISTLE] = 216./255.;
411: rgb[0][PETSC_DRAW_LIMEGREEN] = 50./255. ;
412: rgb[1][PETSC_DRAW_LIMEGREEN] = 205./255.;
413: rgb[2][PETSC_DRAW_LIMEGREEN] = 50./255.;
414: rgb[0][PETSC_DRAW_LAVENDERBLUSH] = 255./255. ;
415: rgb[1][PETSC_DRAW_LAVENDERBLUSH] = 240./255.;
416: rgb[2][PETSC_DRAW_LAVENDERBLUSH] = 245./255.;
418: /* now do the uniform hue part of the colors */
419: ncolors = 256-PETSC_DRAW_BASIC_COLORS;
420: PetscMalloc(3*ncolors*sizeof(unsigned char),&red);
421: green = red + ncolors;
422: blue = green + ncolors;
423: PetscDrawUtilitySetCmapHue(red,green,blue,ncolors);
424: for (i=PETSC_DRAW_BASIC_COLORS; i<ncolors+PETSC_DRAW_BASIC_COLORS; i++) {
425: rgb[0][i] = ((double)red[i-PETSC_DRAW_BASIC_COLORS])/255.;
426: rgb[1][i] = ((double)green[i-PETSC_DRAW_BASIC_COLORS])/255.;
427: rgb[2][i] = ((double)blue[i-PETSC_DRAW_BASIC_COLORS])/255.;
428: }
429: PetscFree(red);
430: }
432: draw->data = (void*)ps;
433: return(0);
434: }
439: /*
440: This works in Postscript coordinates
441: */
442: /*
444: this kind of thing should do contour triangles with Postscript level 3
445: 1000 dict begin
446: /ShadingType 4 def
447: /ColorSpace /DeviceRGB def
448: /DataSource [0 10 10 255 255 255 0 400 10 0 0 0 0 200 400 255 0 0] def
449: shfill
451: once we have Postscript level 3 we should put this in as an option
452: */
457: static PetscErrorCode PetscDrawInterpolatedTriangle_PS(PetscDraw_PS* ps,PetscReal x1,PetscReal y_1,int t1,
458: PetscReal x2,PetscReal y2,int t2,PetscReal x3,PetscReal y3,int t3)
459: {
460: PetscReal rfrac,lfrac;
461: PetscReal lc,rc = 0.0,lx,rx = 0.0,xx,y;
462: PetscReal rc_lc,rx_lx,t2_t1,x2_x1,t3_t1,x3_x1,t3_t2,x3_x2;
463: PetscReal R_y2_y_1,R_y3_y_1,R_y3_y2;
465: int c;
468: /*
469: Is triangle even visible in window?
470: */
471: if (x1 < 0 && x2 < 0 && x3 < 0) return(0);
472: if (y_1 < 0 && y2 < 0 && y3 < 0) return(0);
473: if (x1 > 72*8.5 && x2 > 72*8.5 && x3 > 72*8.5) return(0);
474: if (y_1 > 72*11 && y2 > 72*11 && y3 > 72*11) return(0);
476: /* scale everything by two to reduce the huge file; note this reduces the quality */
477: x1 /= 2.0;
478: x2 /= 2.0;
479: x3 /= 2.0;
480: y_1 /= 2.0;
481: y2 /= 2.0;
482: y3 /= 2.0;
483: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"gsave 2 2 scale\n");
486: /* Sort the vertices */
487: #define SWAP(a,b) {PetscReal _a; _a=a; a=b; b=_a;}
488: #define ISWAP(a,b) {int _a; _a=a; a=b; b=_a;}
489: if (y_1 > y2) {
490: SWAP(y_1,y2);ISWAP(t1,t2); SWAP(x1,x2);
491: }
492: if (y_1 > y3) {
493: SWAP(y_1,y3);ISWAP(t1,t3); SWAP(x1,x3);
494: }
495: if (y2 > y3) {
496: SWAP(y2,y3);ISWAP(t2,t3); SWAP(x2,x3);
497: }
498: /* This code is decidely non-optimal; it is intended to be a start at
499: an implementation */
501: if (y2 != y_1) R_y2_y_1 = 1.0/((y2-y_1)); else R_y2_y_1 = 0.0;
502: if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
503: t2_t1 = t2 - t1;
504: x2_x1 = x2 - x1;
505: t3_t1 = t3 - t1;
506: x3_x1 = x3 - x1;
507: for (y=y_1; y<=y2; y++) {
508: /* PetscDraw a line with the correct color from t1-t2 to t1-t3 */
509: /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
510: lfrac = ((y-y_1)) * R_y2_y_1;
511: lc = (lfrac * (t2_t1) + t1);
512: lx = (lfrac * (x2_x1) + x1);
513: /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
514: rfrac = ((y - y_1)) * R_y3_y_1;
515: rc = (rfrac * (t3_t1) + t1);
516: rx = (rfrac * (x3_x1) + x1);
517: /* PetscDraw the line */
518: rc_lc = rc - lc;
519: rx_lx = rx - lx;
520: 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 c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
524: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G m %G %G l\n",xx,y,xx+1,y);
525: }
526: } else if (rx < lx) {
527: for (xx=lx; xx>=rx; xx--) {
528: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
529: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G %G c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
530: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G m %G %G l\n",xx,y,xx+1,y);
531: }
532: } else {
533: c = (int)lc;
534: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G %G c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
535: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G m %G %G l\n",lx,y,lx+1,y);
536: }
537: }
539: /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
540: We take advantage of the previous iteration. */
541: if (y2 >= y3) {
542: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestore\n");
543: return(0);
544: }
545: if (y_1 < y2) {
546: t1 = (int)rc;
547: y_1 = y2;
548: x1 = rx;
550: t3_t1 = t3 - t1;
551: x3_x1 = x3 - x1;
552: }
553: t3_t2 = t3 - t2;
554: x3_x2 = x3 - x2;
555: if (y3 != y2) R_y3_y2 = 1.0/((y3-y2)); else R_y3_y2 = 0.0;
556: if (y3 != y_1) R_y3_y_1 = 1.0/((y3-y_1)); else R_y3_y_1 = 0.0;
557: for (y=y2; y<=y3; y++) {
558: /* PetscDraw a line with the correct color from t2-t3 to t1-t3 */
559: /* Left color is (y-y_1)/(y2-y_1) * (t2-t1) + t1 */
560: lfrac = ((y-y2)) * R_y3_y2;
561: lc = (lfrac * (t3_t2) + t2);
562: lx = (lfrac * (x3_x2) + x2);
563: /* Right color is (y-y_1)/(y3-y_1) * (t3-t1) + t1 */
564: rfrac = ((y - y_1)) * R_y3_y_1;
565: rc = (rfrac * (t3_t1) + t1);
566: rx = (rfrac * (x3_x1) + x1);
567: /* PetscDraw the line */
568: rc_lc = rc - lc;
569: rx_lx = rx - lx;
570: 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 c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
574: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G m %G %G l\n",xx,y,xx+1,y);
575: }
576: } else if (rx < lx) {
577: for (xx=lx; xx>=rx; xx--) {
578: c = (int)(((xx-lx) * (rc_lc)) / (rx_lx) + lc);
579: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G %G c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
580: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G m %G %G l\n",xx,y,xx+1,y);
581: }
582: } else {
583: c = (int)lc;
584: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G %G c\n",rgb[0][c],rgb[1][c],rgb[2][c]);
585: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"%G %G m %G %G l\n",lx,y,lx+1,y);
586: }
587: }
588: PetscViewerASCIISynchronizedPrintf(ps->ps_file,"grestore\n");
589: return(0);
590: }