1 #include <../src/sys/classes/draw/impls/image/drawimage.h>   /*I  "petscdraw.h" I*/
2 #include <petsc/private/drawimpl.h>                          /*I  "petscdraw.h" I*/
3 
4 #if defined(PETSC_USE_DEBUG)
5 #define PetscDrawValidColor(color) \
6 do { if (PetscUnlikely((color)<0||(color)>=256)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Color value %D out of range [0..255]",(PetscInt)(color)); } while (0)
7 #else
8 #define PetscDrawValidColor(color) do {} while (0)
9 #endif
10 
11 #define XTRANS(draw,img,x)  ((int)(((img)->w-1)*((draw)->port_xl + ((((x) - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl)))))
12 #define YTRANS(draw,img,y)  (((img)->h-1) - (int)(((img)->h-1)*((draw)->port_yl + ((((y) - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl)))))
13 
14 #define ITRANS(draw,img,i)  ((draw)->coor_xl + (((PetscReal)(i))*((draw)->coor_xr - (draw)->coor_xl)/((img)->w-1) - (draw)->port_xl)/((draw)->port_xr - (draw)->port_xl))
15 #define JTRANS(draw,img,j)  ((draw)->coor_yl + (((PetscReal)(j))/((img)->h-1) + (draw)->port_yl - 1)*((draw)->coor_yr - (draw)->coor_yl)/((draw)->port_yl - (draw)->port_yr))
16 
17 
PetscDrawSetViewport_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)18 static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
19 {
20   PetscImage img = (PetscImage)draw->data;
21   PetscFunctionBegin;
22   {
23     int xmax = img->w - 1,   ymax = img->h - 1;
24     int xa = (int)(xl*xmax), ya = ymax - (int)(yr*ymax);
25     int xb = (int)(xr*xmax), yb = ymax - (int)(yl*ymax);
26     PetscImageSetClip(img,xa,ya,xb+1-xa,yb+1-ya);
27   }
28   PetscFunctionReturn(0);
29 }
30 
31 /*
32 static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
33 {
34   PetscFunctionBegin;
35   PetscFunctionReturn(0);
36 }*/
37 #define PetscDrawSetCoordinates_Image NULL
38 
PetscDrawCoordinateToPixel_Image(PetscDraw draw,PetscReal x,PetscReal y,int * i,int * j)39 static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw,PetscReal x,PetscReal y,int *i,int *j)
40 {
41   PetscImage img = (PetscImage)draw->data;
42   PetscFunctionBegin;
43   if (i) *i = XTRANS(draw,img,x);
44   if (j) *j = YTRANS(draw,img,y);
45   PetscFunctionReturn(0);
46 }
47 
PetscDrawPixelToCoordinate_Image(PetscDraw draw,int i,int j,PetscReal * x,PetscReal * y)48 static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw,int i,int j,PetscReal *x,PetscReal *y)
49 {
50   PetscImage img = (PetscImage)draw->data;
51   PetscFunctionBegin;
52   if (x) *x = ITRANS(draw,img,i);
53   if (y) *y = JTRANS(draw,img,j);
54   PetscFunctionReturn(0);
55 }
56 
57 /*
58 static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
59 {
60   PetscFunctionBegin;
61   PetscFunctionReturn(0);
62 }*/
63 #define PetscDrawPointSetSize_Image NULL
64 
PetscDrawPoint_Image(PetscDraw draw,PetscReal x,PetscReal y,int c)65 static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw,PetscReal x,PetscReal y,int c)
66 {
67   PetscImage img = (PetscImage)draw->data;
68   PetscFunctionBegin;
69   PetscDrawValidColor(c);
70   {
71     int j, xx = XTRANS(draw,img,x);
72     int i, yy = YTRANS(draw,img,y);
73     for (i=-1; i<=1; i++)
74       for (j=-1; j<=1; j++)
75         PetscImageDrawPixel(img,xx+j,yy+i,c);
76   }
77   PetscFunctionReturn(0);
78 }
79 
PetscDrawPointPixel_Image(PetscDraw draw,int x,int y,int c)80 static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw,int x,int y,int c)
81 {
82   PetscImage img = (PetscImage)draw->data;
83   PetscFunctionBegin;
84   PetscDrawValidColor(c);
85   {
86     PetscImageDrawPixel(img,x,y,c);
87   }
88   PetscFunctionReturn(0);
89 }
90 
91 /*
92 static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
93 {
94   PetscFunctionBegin;
95   PetscFunctionReturn(0);
96 }*/
97 #define PetscDrawLineSetWidth_Image NULL
98 
PetscDrawLineGetWidth_Image(PetscDraw draw,PetscReal * width)99 static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw,PetscReal *width)
100 {
101   PetscImage img = (PetscImage)draw->data;
102   PetscFunctionBegin;
103   {
104     int lw = 1;
105     *width = lw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
106   }
107   PetscFunctionReturn(0);
108 }
109 
PetscDrawLine_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)110 static PetscErrorCode PetscDrawLine_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
111 {
112   PetscImage img = (PetscImage)draw->data;
113   PetscFunctionBegin;
114   {
115     int x_1 = XTRANS(draw,img,xl), x_2 = XTRANS(draw,img,xr);
116     int y_1 = YTRANS(draw,img,yl), y_2 = YTRANS(draw,img,yr);
117     PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
118   }
119   PetscFunctionReturn(0);
120 }
121 
PetscDrawArrow_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)122 static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
123 {
124   PetscImage img = (PetscImage)draw->data;
125   PetscFunctionBegin;
126   PetscDrawValidColor(c);
127   {
128     int x_1 = XTRANS(draw,img,xl), x_2 = XTRANS(draw,img,xr);
129     int y_1 = YTRANS(draw,img,yl), y_2 = YTRANS(draw,img,yr);
130     if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(0);
131     PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
132     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
133       if (y_2 > y_1) {
134         PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2-3,c);
135         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2-3,c);
136       } else {
137         PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2+3,c);
138         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2+3,c);
139       }
140     }
141     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
142       if (x_2 > x_1) {
143         PetscImageDrawLine(img,x_2-3,y_2-3,x_2,y_2,c);
144         PetscImageDrawLine(img,x_2-3,y_2+3,x_2,y_2,c);
145       } else {
146         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2-3,c);
147         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2+3,c);
148       }
149     }
150    }
151   PetscFunctionReturn(0);
152 }
153 
PetscDrawRectangle_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)154 static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
155 {
156   PetscImage img = (PetscImage)draw->data;
157   PetscFunctionBegin;
158   PetscDrawValidColor(c1);
159   PetscDrawValidColor(c2);
160   PetscDrawValidColor(c3);
161   PetscDrawValidColor(c4);
162   {
163     int x = XTRANS(draw,img,xl), w = XTRANS(draw,img,xr) + 1 - x;
164     int y = YTRANS(draw,img,yr), h = YTRANS(draw,img,yl) + 1 - y;
165     int c  = (c1 + c2 + c3 + c4)/4;
166     PetscImageDrawRectangle(img,x,y,w,h,c);
167   }
168   PetscFunctionReturn(0);
169 }
170 
PetscDrawEllipse_Image(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)171 static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
172 {
173   PetscImage img = (PetscImage)draw->data;
174   PetscFunctionBegin;
175   PetscDrawValidColor(c);
176   a = PetscAbsReal(a);
177   b = PetscAbsReal(b);
178   {
179     int xc = XTRANS(draw,img,x), w = XTRANS(draw,img,x + a/2) + 0 - xc;
180     int yc = YTRANS(draw,img,y), h = YTRANS(draw,img,y - b/2) + 0 - yc;
181     if (PetscAbsReal(a-b) <= 0)  w = h = PetscMin(w,h); /* workaround truncation errors */
182     PetscImageDrawEllipse(img,xc,yc,w,h,c);
183   }
184   PetscFunctionReturn(0);
185 }
186 
PetscDrawTriangle_Image(PetscDraw draw,PetscReal X_1,PetscReal Y_1,PetscReal X_2,PetscReal Y_2,PetscReal X_3,PetscReal Y_3,int c1,int c2,int c3)187 static PetscErrorCode PetscDrawTriangle_Image(PetscDraw draw,PetscReal X_1,PetscReal Y_1,PetscReal X_2,PetscReal Y_2,PetscReal X_3,PetscReal Y_3,int c1,int c2,int c3)
188 {
189   PetscImage img = (PetscImage)draw->data;
190   PetscFunctionBegin;
191   PetscDrawValidColor(c1);
192   PetscDrawValidColor(c2);
193   PetscDrawValidColor(c3);
194   {
195     int x_1 = XTRANS(draw,img,X_1), x_2 = XTRANS(draw,img,X_2), x_3 = XTRANS(draw,img,X_3);
196     int y_1 = YTRANS(draw,img,Y_1), y_2 = YTRANS(draw,img,Y_2), y_3 = YTRANS(draw,img,Y_3);
197     PetscImageDrawTriangle(img,x_1,y_1,c1,x_2,y_2,c2,x_3,y_3,c3);
198   }
199   PetscFunctionReturn(0);
200 }
201 
202 /*
203 static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
204 {
205   PetscFunctionBegin;
206   PetscFunctionReturn(0);
207 }*/
208 #define PetscDrawStringSetSize_Image NULL
209 
PetscDrawStringGetSize_Image(PetscDraw draw,PetscReal * w,PetscReal * h)210 static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw,PetscReal *w,PetscReal  *h)
211 {
212   PetscImage img = (PetscImage)draw->data;
213   PetscFunctionBegin;
214   {
215     int tw = PetscImageFontWidth;
216     int th = PetscImageFontHeight;
217     if (w) *w = tw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
218     if (h) *h = th*(draw->coor_yr - draw->coor_yl)/(img->h*(draw->port_yr - draw->port_yl));
219   }
220   PetscFunctionReturn(0);
221 }
222 
PetscDrawString_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])223 static PetscErrorCode PetscDrawString_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
224 {
225   PetscImage     img = (PetscImage)draw->data;
226   PetscToken     token;
227   char           *subtext;
228   PetscErrorCode ierr;
229   PetscFunctionBegin;
230   PetscDrawValidColor(c);
231   {
232     int xx = XTRANS(draw,img,x);
233     int yy = YTRANS(draw,img,y);
234     ierr = PetscTokenCreate(text,'\n',&token);CHKERRQ(ierr);
235     ierr = PetscTokenFind(token,&subtext);CHKERRQ(ierr);
236     while (subtext) {
237       PetscImageDrawText(img,xx,yy,c,subtext);
238       yy += PetscImageFontHeight;
239       ierr = PetscTokenFind(token,&subtext);CHKERRQ(ierr);
240     }
241     ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
242   }
243   PetscFunctionReturn(0);
244 }
245 
PetscDrawStringVertical_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])246 static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
247 {
248   PetscImage img = (PetscImage)draw->data;
249   PetscFunctionBegin;
250   PetscDrawValidColor(c);
251   {
252     char chr[2] = {0, 0};
253     int  xx = XTRANS(draw,img,x);
254     int  yy = YTRANS(draw,img,y);
255     int  offset = PetscImageFontHeight;
256     while ((chr[0] = *text++)) {
257       PetscImageDrawText(img,xx,yy+offset,c,chr);
258       yy += PetscImageFontHeight;
259     }
260   }
261   PetscFunctionReturn(0);
262 }
263 
264 /*
265 static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
266 {
267   PetscFunctionBegin;
268   if (w) *w = 0;
269   if (h) *h = 0;
270   PetscFunctionReturn(0);
271 */
272 #define PetscDrawStringBoxed_Image NULL
273 
274 /*
275 static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
276 {
277   PetscFunctionBegin;
278   PetscFunctionReturn(0);
279 }*/
280 #define PetscDrawFlush_Image NULL
281 
PetscDrawClear_Image(PetscDraw draw)282 static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
283 {
284   PetscImage     img = (PetscImage)draw->data;
285   PetscFunctionBegin;
286   {
287     PetscImageClear(img);
288   }
289   PetscFunctionReturn(0);
290 }
291 
292 /*
293 static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
294 {
295   PetscFunctionBegin;
296   PetscFunctionReturn(0);
297 }*/
298 #define PetscDrawSetDoubleBuffer_Image NULL
299 
PetscDrawGetPopup_Image(PetscDraw draw,PetscDraw * popup)300 static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw,PetscDraw *popup)
301 {
302   PetscBool      flg = PETSC_FALSE;
303   PetscErrorCode ierr;
304 
305   PetscFunctionBegin;
306   ierr = PetscOptionsGetBool(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_popup",&flg,NULL);CHKERRQ(ierr);
307   if (!flg) {*popup = NULL; PetscFunctionReturn(0);}
308   ierr = PetscDrawCreate(PetscObjectComm((PetscObject)draw),NULL,NULL,0,0,220,220,popup);CHKERRQ(ierr);
309   ierr = PetscDrawSetType(*popup,PETSC_DRAW_IMAGE);CHKERRQ(ierr);
310   ierr = PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_");CHKERRQ(ierr);
311   ierr = PetscObjectAppendOptionsPrefix((PetscObject)*popup,((PetscObject)draw)->prefix);CHKERRQ(ierr);
312   draw->popup = *popup;
313   PetscFunctionReturn(0);
314 }
315 
316 /*
317 static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
318 {
319   PetscFunctionBegin;
320   PetscFunctionReturn(0);
321 }*/
322 #define PetscDrawSetTitle_Image NULL
323 
324 /*
325 static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
326 {
327   PetscFunctionBegin;
328   PetscFunctionReturn(0);
329 }*/
330 #define PetscDrawCheckResizedWindow_Image NULL
331 
PetscDrawResizeWindow_Image(PetscDraw draw,int w,int h)332 static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw,int w,int h)
333 {
334   PetscImage     img = (PetscImage)draw->data;
335   PetscErrorCode ierr;
336 
337   PetscFunctionBegin;
338   if (w == img->w && h == img->h) PetscFunctionReturn(0);
339   ierr = PetscFree(img->buffer);CHKERRQ(ierr);
340 
341   img->w = w; img->h = h;
342   ierr = PetscCalloc1((size_t)(img->w*img->h),&img->buffer);CHKERRQ(ierr);
343   ierr = PetscDrawSetViewport_Image(draw,draw->port_xl,draw->port_yl,draw->port_xr,draw->port_yr);CHKERRQ(ierr);
344   PetscFunctionReturn(0);
345 }
346 
PetscDrawDestroy_Image(PetscDraw draw)347 static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
348 {
349   PetscImage     img = (PetscImage)draw->data;
350   PetscErrorCode ierr;
351 
352   PetscFunctionBegin;
353   ierr = PetscDrawDestroy(&draw->popup);CHKERRQ(ierr);
354   ierr = PetscFree(img->buffer);CHKERRQ(ierr);
355   ierr = PetscFree(draw->data);CHKERRQ(ierr);
356   PetscFunctionReturn(0);
357 }
358 
359 /*
360 static PetscErrorCode PetscDrawView_Image(PetscDraw draw,PetscViewer viewer)
361 {
362   PetscFunctionBegin;
363   PetscFunctionReturn(0);
364 }*/
365 #define PetscDrawView_Image NULL
366 
367 /*
368 static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
369 {
370   PetscFunctionBegin;
371   *button = PETSC_BUTTON_NONE;
372   if (x_user) *x_user = 0;
373   if (y_user) *y_user = 0;
374   if (x_phys) *x_phys = 0;
375   if (y_phys) *y_phys = 0;
376   PetscFunctionReturn(0);
377 }*/
378 #define PetscDrawGetMouseButton_Image NULL
379 
380 /*
381 static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
382 {
383   PetscFunctionBegin;
384   PetscFunctionReturn(0);
385 }*/
386 #define PetscDrawPause_Image NULL
387 
388 /*
389 static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
390 {
391   PetscFunctionBegin;
392   PetscFunctionReturn(0);
393 }*/
394 #define PetscDrawBeginPage_Image NULL
395 
396 /*
397 static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
398 {
399   PetscFunctionBegin;
400   PetscFunctionReturn(0);
401 }*/
402 #define PetscDrawEndPage_Image NULL
403 
PetscDrawGetSingleton_Image(PetscDraw draw,PetscDraw * sdraw)404 static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
405 {
406   PetscImage     pimg = (PetscImage)draw->data;
407   PetscImage     simg;
408   PetscErrorCode ierr;
409 
410   PetscFunctionBegin;
411   ierr = PetscDrawCreate(PETSC_COMM_SELF,NULL,NULL,0,0,draw->w,draw->h,sdraw);CHKERRQ(ierr);
412   ierr = PetscDrawSetType(*sdraw,PETSC_DRAW_IMAGE);CHKERRQ(ierr);
413   (*sdraw)->ops->resizewindow = NULL;
414   simg = (PetscImage)(*sdraw)->data;
415   ierr = PetscArraycpy(simg->buffer,pimg->buffer,pimg->w*pimg->h);CHKERRQ(ierr);
416   PetscFunctionReturn(0);
417 }
418 
PetscDrawRestoreSingleton_Image(PetscDraw draw,PetscDraw * sdraw)419 static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
420 {
421   PetscImage     pimg = (PetscImage)draw->data;
422   PetscImage     simg = (PetscImage)(*sdraw)->data;
423   PetscErrorCode ierr;
424 
425   PetscFunctionBegin;
426   ierr = PetscArraycpy(pimg->buffer,simg->buffer,pimg->w*pimg->h);CHKERRQ(ierr);
427   ierr = PetscDrawDestroy(sdraw);CHKERRQ(ierr);
428   PetscFunctionReturn(0);
429 }
430 
431 /*
432 static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
433 {
434   PetscFunctionBegin;
435   PetscFunctionReturn(0);
436 }*/
437 #define PetscDrawSave_Image NULL
438 
PetscDrawGetImage_Image(PetscDraw draw,unsigned char palette[256][3],unsigned int * w,unsigned int * h,unsigned char * pixels[])439 static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw,unsigned char palette[256][3],unsigned int *w,unsigned int *h,unsigned char *pixels[])
440 {
441   PetscImage     img = (PetscImage)draw->data;
442   unsigned char  *buffer = NULL;
443   PetscMPIInt    rank,size;
444   PetscErrorCode ierr;
445 
446   PetscFunctionBegin;
447   if (w) *w = (unsigned int)img->w;
448   if (h) *h = (unsigned int)img->h;
449   if (pixels) *pixels = NULL;
450   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
451   if (!rank) {
452     ierr = PetscMemcpy(palette,img->palette,sizeof(img->palette));CHKERRQ(ierr);
453     ierr = PetscMalloc1((size_t)(img->w*img->h),&buffer);CHKERRQ(ierr);
454     if (pixels) *pixels = buffer;
455   }
456   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
457   if (size == 1) {
458     ierr = PetscArraycpy(buffer,img->buffer,img->w*img->h);CHKERRQ(ierr);
459   } else {
460     ierr = MPI_Reduce(img->buffer,buffer,img->w*img->h,MPI_UNSIGNED_CHAR,MPI_MAX,0,PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
461   }
462   PetscFunctionReturn(0);
463 }
464 
465 static struct _PetscDrawOps DvOps = {
466   PetscDrawSetDoubleBuffer_Image,
467   PetscDrawFlush_Image,
468   PetscDrawLine_Image,
469   PetscDrawLineSetWidth_Image,
470   PetscDrawLineGetWidth_Image,
471   PetscDrawPoint_Image,
472   PetscDrawPointSetSize_Image,
473   PetscDrawString_Image,
474   PetscDrawStringVertical_Image,
475   PetscDrawStringSetSize_Image,
476   PetscDrawStringGetSize_Image,
477   PetscDrawSetViewport_Image,
478   PetscDrawClear_Image,
479   PetscDrawRectangle_Image,
480   PetscDrawTriangle_Image,
481   PetscDrawEllipse_Image,
482   PetscDrawGetMouseButton_Image,
483   PetscDrawPause_Image,
484   PetscDrawBeginPage_Image,
485   PetscDrawEndPage_Image,
486   PetscDrawGetPopup_Image,
487   PetscDrawSetTitle_Image,
488   PetscDrawCheckResizedWindow_Image,
489   PetscDrawResizeWindow_Image,
490   PetscDrawDestroy_Image,
491   PetscDrawView_Image,
492   PetscDrawGetSingleton_Image,
493   PetscDrawRestoreSingleton_Image,
494   PetscDrawSave_Image,
495   PetscDrawGetImage_Image,
496   PetscDrawSetCoordinates_Image,
497   PetscDrawArrow_Image,
498   PetscDrawCoordinateToPixel_Image,
499   PetscDrawPixelToCoordinate_Image,
500   PetscDrawPointPixel_Image,
501   PetscDrawStringBoxed_Image
502 };
503 
504 static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
505   { 255, 255, 255 }, /* white */
506   {   0,   0,   0 }, /* black */
507   { 255,   0,   0 }, /* red */
508   {   0, 255,   0 }, /* green */
509   {   0, 255, 255 }, /* cyan */
510   {   0,   0, 255 }, /* blue */
511   { 255,   0, 255 }, /* magenta */
512   { 127, 255, 212 }, /* aquamarine */
513   {  34, 139,  34 }, /* forestgreen */
514   { 255, 165,   0 }, /* orange */
515   { 238, 130, 238 }, /* violet */
516   { 165,  42,  42 }, /* brown */
517   { 255, 192, 203 }, /* pink */
518   { 255, 127,  80 }, /* coral */
519   { 190, 190, 190 }, /* gray */
520   { 255, 255,   0 }, /* yellow */
521   { 255, 215,   0 }, /* gold */
522   { 255, 182, 193 }, /* lightpink */
523   {  72, 209, 204 }, /* mediumturquoise */
524   { 240, 230, 140 }, /* khaki */
525   { 105, 105, 105 }, /* dimgray */
526   {  54, 205,  50 }, /* yellowgreen */
527   { 135, 206, 235 }, /* skyblue */
528   {   0, 100,   0 }, /* darkgreen */
529   {   0,   0, 128 }, /* navyblue */
530   { 244, 164,  96 }, /* sandybrown */
531   {  95, 158, 160 }, /* cadetblue */
532   { 176, 224, 230 }, /* powderblue */
533   { 255,  20, 147 }, /* deeppink */
534   { 216, 191, 216 }, /* thistle */
535   {  50, 205,  50 }, /* limegreen */
536   { 255, 240, 245 }, /* lavenderblush */
537   { 221, 160, 221 }, /* plum */
538 };
539 
540 
541 /*MC
542    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer
543 
544    Options Database Keys:
545 .  -draw_size w,h - size of image in pixels
546 
547    Level: beginner
548 
549 .seealso:  PetscDrawOpenImage(), PetscDrawSetFromOptions()
550 M*/
551 PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);
552 
PetscDrawCreate_Image(PetscDraw draw)553 PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
554 {
555   PetscImage     img;
556   int            w = draw->w, h = draw->h;
557   PetscInt       size[2], nsize = 2;
558   PetscBool      set;
559   PetscErrorCode ierr;
560 
561   PetscFunctionBegin;
562   draw->pause   = 0;
563   draw->coor_xl = 0; draw->coor_xr = 1;
564   draw->coor_yl = 0; draw->coor_yr = 1;
565   draw->port_xl = 0; draw->port_xr = 1;
566   draw->port_yl = 0; draw->port_yr = 1;
567 
568   size[0] = w; if (size[0] < 1) size[0] = 300;
569   size[1] = h; if (size[1] < 1) size[1] = size[0];
570   ierr = PetscOptionsGetIntArray(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_size",size,&nsize,&set);CHKERRQ(ierr);
571   if (set && nsize == 1) size[1] = size[0];
572   if (size[0] < 1) size[0] = 300;
573   if (size[1] < 1) size[1] = size[0];
574   draw->w = w = size[0]; draw->x = 0;
575   draw->h = h = size[1]; draw->x = 0;
576 
577   ierr = PetscNewLog(draw,&img);CHKERRQ(ierr);
578   ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
579   draw->data = (void*)img;
580 
581   img->w = w; img->h = h;
582   ierr = PetscCalloc1((size_t)(img->w*img->h),&img->buffer);CHKERRQ(ierr);
583   PetscImageSetClip(img,0,0,img->w,img->h);
584   {
585     int i,k,ncolors = 256-PETSC_DRAW_BASIC_COLORS;
586     unsigned char R[256-PETSC_DRAW_BASIC_COLORS];
587     unsigned char G[256-PETSC_DRAW_BASIC_COLORS];
588     unsigned char B[256-PETSC_DRAW_BASIC_COLORS];
589     ierr = PetscDrawUtilitySetCmap(NULL,ncolors,R,G,B);CHKERRQ(ierr);
590     for (k=0; k<PETSC_DRAW_BASIC_COLORS; k++) {
591       img->palette[k][0] = BasicColors[k][0];
592       img->palette[k][1] = BasicColors[k][1];
593       img->palette[k][2] = BasicColors[k][2];
594     }
595     for (i=0; i<ncolors; i++, k++) {
596       img->palette[k][0] = R[i];
597       img->palette[k][1] = G[i];
598       img->palette[k][2] = B[i];
599     }
600   }
601 
602   if (!draw->savefilename) {ierr = PetscDrawSetSave(draw,draw->title);CHKERRQ(ierr);}
603   PetscFunctionReturn(0);
604 }
605 
606 /*@C
607    PetscDrawOpenImage - Opens an image for use with the PetscDraw routines.
608 
609    Collective
610 
611    Input Parameters:
612 +  comm - the communicator that will share image
613 -  filename - optional name of the file
614 -  w, h - the image width and height in pixels
615 
616    Output Parameters:
617 .  draw - the drawing context.
618 
619    Level: beginner
620 
621 .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
622 @*/
PetscDrawOpenImage(MPI_Comm comm,const char filename[],int w,int h,PetscDraw * draw)623 PetscErrorCode PetscDrawOpenImage(MPI_Comm comm,const char filename[],int w,int h,PetscDraw *draw)
624 {
625   PetscErrorCode ierr;
626 
627   PetscFunctionBegin;
628   ierr = PetscDrawCreate(comm,NULL,NULL,0,0,w,h,draw);CHKERRQ(ierr);
629   ierr = PetscDrawSetType(*draw,PETSC_DRAW_IMAGE);CHKERRQ(ierr);
630   ierr = PetscDrawSetSave(*draw,filename);CHKERRQ(ierr);
631   PetscFunctionReturn(0);
632 }
633