xref: /petsc/src/sys/classes/draw/impls/image/drawimage.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
12b8d69caSLisandro Dalcin #include <../src/sys/classes/draw/impls/image/drawimage.h> /*I  "petscdraw.h" I*/
22b8d69caSLisandro Dalcin #include <petsc/private/drawimpl.h>                        /*I  "petscdraw.h" I*/
32b8d69caSLisandro Dalcin 
42b8d69caSLisandro Dalcin #if defined(PETSC_USE_DEBUG)
52c71b3e2SJacob Faibussowitsch #define PetscDrawValidColor(color) PetscCheck((color) >= 0 && (color) < 256, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Color value %" PetscInt_FMT " out of range [0..255]", (PetscInt)(color))
62b8d69caSLisandro Dalcin #else
79371c9d4SSatish Balay #define PetscDrawValidColor(color) \
89371c9d4SSatish Balay   do { \
99371c9d4SSatish Balay   } while (0)
102b8d69caSLisandro Dalcin #endif
112b8d69caSLisandro Dalcin 
122b8d69caSLisandro Dalcin #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)))))
132b8d69caSLisandro Dalcin #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)))))
142b8d69caSLisandro Dalcin 
152b8d69caSLisandro Dalcin #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))
162b8d69caSLisandro Dalcin #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))
172b8d69caSLisandro Dalcin 
189371c9d4SSatish Balay static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr) {
192b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
202b8d69caSLisandro Dalcin   PetscFunctionBegin;
212b8d69caSLisandro Dalcin   {
222b8d69caSLisandro Dalcin     int xmax = img->w - 1, ymax = img->h - 1;
232b8d69caSLisandro Dalcin     int xa = (int)(xl * xmax), ya = ymax - (int)(yr * ymax);
242b8d69caSLisandro Dalcin     int xb = (int)(xr * xmax), yb = ymax - (int)(yl * ymax);
252b8d69caSLisandro Dalcin     PetscImageSetClip(img, xa, ya, xb + 1 - xa, yb + 1 - ya);
262b8d69caSLisandro Dalcin   }
272b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
282b8d69caSLisandro Dalcin }
292b8d69caSLisandro Dalcin 
302b8d69caSLisandro Dalcin /*
312b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
322b8d69caSLisandro Dalcin {
332b8d69caSLisandro Dalcin   PetscFunctionBegin;
342b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
352b8d69caSLisandro Dalcin }*/
362b8d69caSLisandro Dalcin #define PetscDrawSetCoordinates_Image NULL
372b8d69caSLisandro Dalcin 
389371c9d4SSatish Balay static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j) {
392b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
402b8d69caSLisandro Dalcin   PetscFunctionBegin;
412b8d69caSLisandro Dalcin   if (i) *i = XTRANS(draw, img, x);
422b8d69caSLisandro Dalcin   if (j) *j = YTRANS(draw, img, y);
432b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
442b8d69caSLisandro Dalcin }
452b8d69caSLisandro Dalcin 
469371c9d4SSatish Balay static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y) {
472b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
482b8d69caSLisandro Dalcin   PetscFunctionBegin;
492b8d69caSLisandro Dalcin   if (x) *x = ITRANS(draw, img, i);
502b8d69caSLisandro Dalcin   if (y) *y = JTRANS(draw, img, j);
512b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
522b8d69caSLisandro Dalcin }
532b8d69caSLisandro Dalcin 
542b8d69caSLisandro Dalcin /*
552b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
562b8d69caSLisandro Dalcin {
572b8d69caSLisandro Dalcin   PetscFunctionBegin;
582b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
592b8d69caSLisandro Dalcin }*/
602b8d69caSLisandro Dalcin #define PetscDrawPointSetSize_Image NULL
612b8d69caSLisandro Dalcin 
629371c9d4SSatish Balay static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c) {
632b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
642b8d69caSLisandro Dalcin   PetscFunctionBegin;
652b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
662b8d69caSLisandro Dalcin   {
672b8d69caSLisandro Dalcin     int j, xx = XTRANS(draw, img, x);
682b8d69caSLisandro Dalcin     int i, yy = YTRANS(draw, img, y);
692b8d69caSLisandro Dalcin     for (i = -1; i <= 1; i++)
709371c9d4SSatish Balay       for (j = -1; j <= 1; j++) PetscImageDrawPixel(img, xx + j, yy + i, c);
712b8d69caSLisandro Dalcin   }
722b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
732b8d69caSLisandro Dalcin }
742b8d69caSLisandro Dalcin 
759371c9d4SSatish Balay static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c) {
762b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
772b8d69caSLisandro Dalcin   PetscFunctionBegin;
782b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
799371c9d4SSatish Balay   { PetscImageDrawPixel(img, x, y, c); }
802b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
812b8d69caSLisandro Dalcin }
822b8d69caSLisandro Dalcin 
832b8d69caSLisandro Dalcin /*
842b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
852b8d69caSLisandro Dalcin {
862b8d69caSLisandro Dalcin   PetscFunctionBegin;
872b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
882b8d69caSLisandro Dalcin }*/
892b8d69caSLisandro Dalcin #define PetscDrawLineSetWidth_Image NULL
902b8d69caSLisandro Dalcin 
919371c9d4SSatish Balay static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width) {
922b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
932b8d69caSLisandro Dalcin   PetscFunctionBegin;
942b8d69caSLisandro Dalcin   {
952b8d69caSLisandro Dalcin     int lw = 1;
962b8d69caSLisandro Dalcin     *width = lw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
972b8d69caSLisandro Dalcin   }
982b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
992b8d69caSLisandro Dalcin }
1002b8d69caSLisandro Dalcin 
1019371c9d4SSatish Balay static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c) {
1022b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1032b8d69caSLisandro Dalcin   PetscFunctionBegin;
1042b8d69caSLisandro Dalcin   {
1052b8d69caSLisandro Dalcin     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
1062b8d69caSLisandro Dalcin     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
1072b8d69caSLisandro Dalcin     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
1082b8d69caSLisandro Dalcin   }
1092b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
1102b8d69caSLisandro Dalcin }
1112b8d69caSLisandro Dalcin 
1129371c9d4SSatish Balay static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c) {
1132b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1142b8d69caSLisandro Dalcin   PetscFunctionBegin;
1152b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
1162b8d69caSLisandro Dalcin   {
1172b8d69caSLisandro Dalcin     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
1182b8d69caSLisandro Dalcin     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
1192b8d69caSLisandro Dalcin     if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(0);
1202b8d69caSLisandro Dalcin     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
1212b8d69caSLisandro Dalcin     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
1222b8d69caSLisandro Dalcin       if (y_2 > y_1) {
1232b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 - 3, c);
1242b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
1252b8d69caSLisandro Dalcin       } else {
1262b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 + 3, c);
1272b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
1282b8d69caSLisandro Dalcin       }
1292b8d69caSLisandro Dalcin     }
1302b8d69caSLisandro Dalcin     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
1312b8d69caSLisandro Dalcin       if (x_2 > x_1) {
1322b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2 - 3, y_2 - 3, x_2, y_2, c);
1332b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2 - 3, y_2 + 3, x_2, y_2, c);
1342b8d69caSLisandro Dalcin       } else {
1352b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
1362b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
1372b8d69caSLisandro Dalcin       }
1382b8d69caSLisandro Dalcin     }
1392b8d69caSLisandro Dalcin   }
1402b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
1412b8d69caSLisandro Dalcin }
1422b8d69caSLisandro Dalcin 
1439371c9d4SSatish Balay static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4) {
1442b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1452b8d69caSLisandro Dalcin   PetscFunctionBegin;
1462b8d69caSLisandro Dalcin   PetscDrawValidColor(c1);
1472b8d69caSLisandro Dalcin   PetscDrawValidColor(c2);
1482b8d69caSLisandro Dalcin   PetscDrawValidColor(c3);
1492b8d69caSLisandro Dalcin   PetscDrawValidColor(c4);
1502b8d69caSLisandro Dalcin   {
1512b8d69caSLisandro Dalcin     int x = XTRANS(draw, img, xl), w = XTRANS(draw, img, xr) + 1 - x;
1522b8d69caSLisandro Dalcin     int y = YTRANS(draw, img, yr), h = YTRANS(draw, img, yl) + 1 - y;
1532b8d69caSLisandro Dalcin     int c = (c1 + c2 + c3 + c4) / 4;
1542b8d69caSLisandro Dalcin     PetscImageDrawRectangle(img, x, y, w, h, c);
1552b8d69caSLisandro Dalcin   }
1562b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
1572b8d69caSLisandro Dalcin }
1582b8d69caSLisandro Dalcin 
1599371c9d4SSatish Balay static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c) {
1602b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1612b8d69caSLisandro Dalcin   PetscFunctionBegin;
1622b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
1632b8d69caSLisandro Dalcin   a = PetscAbsReal(a);
1642b8d69caSLisandro Dalcin   b = PetscAbsReal(b);
1652b8d69caSLisandro Dalcin   {
1662b8d69caSLisandro Dalcin     int xc = XTRANS(draw, img, x), w = XTRANS(draw, img, x + a / 2) + 0 - xc;
1672b8d69caSLisandro Dalcin     int yc = YTRANS(draw, img, y), h = YTRANS(draw, img, y - b / 2) + 0 - yc;
1682b8d69caSLisandro Dalcin     if (PetscAbsReal(a - b) <= 0) w = h = PetscMin(w, h); /* workaround truncation errors */
1692b8d69caSLisandro Dalcin     PetscImageDrawEllipse(img, xc, yc, w, h, c);
1702b8d69caSLisandro Dalcin   }
1712b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
1722b8d69caSLisandro Dalcin }
1732b8d69caSLisandro Dalcin 
1749371c9d4SSatish Balay 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) {
1752b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1762b8d69caSLisandro Dalcin   PetscFunctionBegin;
1772b8d69caSLisandro Dalcin   PetscDrawValidColor(c1);
1782b8d69caSLisandro Dalcin   PetscDrawValidColor(c2);
1792b8d69caSLisandro Dalcin   PetscDrawValidColor(c3);
1802b8d69caSLisandro Dalcin   {
1812b8d69caSLisandro Dalcin     int x_1 = XTRANS(draw, img, X_1), x_2 = XTRANS(draw, img, X_2), x_3 = XTRANS(draw, img, X_3);
1822b8d69caSLisandro Dalcin     int y_1 = YTRANS(draw, img, Y_1), y_2 = YTRANS(draw, img, Y_2), y_3 = YTRANS(draw, img, Y_3);
1832b8d69caSLisandro Dalcin     PetscImageDrawTriangle(img, x_1, y_1, c1, x_2, y_2, c2, x_3, y_3, c3);
1842b8d69caSLisandro Dalcin   }
1852b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
1862b8d69caSLisandro Dalcin }
1872b8d69caSLisandro Dalcin 
1882b8d69caSLisandro Dalcin /*
1892b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
1902b8d69caSLisandro Dalcin {
1912b8d69caSLisandro Dalcin   PetscFunctionBegin;
1922b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
1932b8d69caSLisandro Dalcin }*/
1942b8d69caSLisandro Dalcin #define PetscDrawStringSetSize_Image NULL
1952b8d69caSLisandro Dalcin 
1969371c9d4SSatish Balay static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h) {
1972b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1982b8d69caSLisandro Dalcin   PetscFunctionBegin;
1992b8d69caSLisandro Dalcin   {
2002b8d69caSLisandro Dalcin     int tw = PetscImageFontWidth;
2012b8d69caSLisandro Dalcin     int th = PetscImageFontHeight;
2022b8d69caSLisandro Dalcin     if (w) *w = tw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
2032b8d69caSLisandro Dalcin     if (h) *h = th * (draw->coor_yr - draw->coor_yl) / (img->h * (draw->port_yr - draw->port_yl));
2042b8d69caSLisandro Dalcin   }
2052b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
2062b8d69caSLisandro Dalcin }
2072b8d69caSLisandro Dalcin 
2089371c9d4SSatish Balay static PetscErrorCode PetscDrawString_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[]) {
2092b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
2102b8d69caSLisandro Dalcin   PetscToken token;
2112b8d69caSLisandro Dalcin   char      *subtext;
2122b8d69caSLisandro Dalcin   PetscFunctionBegin;
2132b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
2142b8d69caSLisandro Dalcin   {
2152b8d69caSLisandro Dalcin     int xx = XTRANS(draw, img, x);
2162b8d69caSLisandro Dalcin     int yy = YTRANS(draw, img, y);
2179566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(text, '\n', &token));
2189566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &subtext));
2192b8d69caSLisandro Dalcin     while (subtext) {
2202b8d69caSLisandro Dalcin       PetscImageDrawText(img, xx, yy, c, subtext);
2212b8d69caSLisandro Dalcin       yy += PetscImageFontHeight;
2229566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &subtext));
2232b8d69caSLisandro Dalcin     }
2249566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
2252b8d69caSLisandro Dalcin   }
2262b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
2272b8d69caSLisandro Dalcin }
2282b8d69caSLisandro Dalcin 
2299371c9d4SSatish Balay static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[]) {
2302b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
2312b8d69caSLisandro Dalcin   PetscFunctionBegin;
2322b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
2332b8d69caSLisandro Dalcin   {
2342b8d69caSLisandro Dalcin     char chr[2] = {0, 0};
2352b8d69caSLisandro Dalcin     int  xx     = XTRANS(draw, img, x);
2362b8d69caSLisandro Dalcin     int  yy     = YTRANS(draw, img, y);
2372b8d69caSLisandro Dalcin     int  offset = PetscImageFontHeight;
2382b8d69caSLisandro Dalcin     while ((chr[0] = *text++)) {
2392b8d69caSLisandro Dalcin       PetscImageDrawText(img, xx, yy + offset, c, chr);
2402b8d69caSLisandro Dalcin       yy += PetscImageFontHeight;
2412b8d69caSLisandro Dalcin     }
2422b8d69caSLisandro Dalcin   }
2432b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
2442b8d69caSLisandro Dalcin }
2452b8d69caSLisandro Dalcin 
2462b8d69caSLisandro Dalcin /*
2472b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
2482b8d69caSLisandro Dalcin {
2492b8d69caSLisandro Dalcin   PetscFunctionBegin;
2502b8d69caSLisandro Dalcin   if (w) *w = 0;
2512b8d69caSLisandro Dalcin   if (h) *h = 0;
2522b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
2532b8d69caSLisandro Dalcin */
2542b8d69caSLisandro Dalcin #define PetscDrawStringBoxed_Image NULL
2552b8d69caSLisandro Dalcin 
2562b8d69caSLisandro Dalcin /*
2572b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
2582b8d69caSLisandro Dalcin {
2592b8d69caSLisandro Dalcin   PetscFunctionBegin;
2602b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
2612b8d69caSLisandro Dalcin }*/
2622b8d69caSLisandro Dalcin #define PetscDrawFlush_Image NULL
2632b8d69caSLisandro Dalcin 
2649371c9d4SSatish Balay static PetscErrorCode PetscDrawClear_Image(PetscDraw draw) {
2652b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
2662b8d69caSLisandro Dalcin   PetscFunctionBegin;
2679371c9d4SSatish Balay   { PetscImageClear(img); }
2682b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
2692b8d69caSLisandro Dalcin }
2702b8d69caSLisandro Dalcin 
2712b8d69caSLisandro Dalcin /*
2722b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
2732b8d69caSLisandro Dalcin {
2742b8d69caSLisandro Dalcin   PetscFunctionBegin;
2752b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
2762b8d69caSLisandro Dalcin }*/
2772b8d69caSLisandro Dalcin #define PetscDrawSetDoubleBuffer_Image NULL
2782b8d69caSLisandro Dalcin 
2799371c9d4SSatish Balay static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup) {
2802b8d69caSLisandro Dalcin   PetscBool flg = PETSC_FALSE;
2812b8d69caSLisandro Dalcin 
2822b8d69caSLisandro Dalcin   PetscFunctionBegin;
2839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL));
2849371c9d4SSatish Balay   if (!flg) {
2859371c9d4SSatish Balay     *popup = NULL;
2869371c9d4SSatish Balay     PetscFunctionReturn(0);
2879371c9d4SSatish Balay   }
2889566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, 0, 0, 220, 220, popup));
2899566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_IMAGE));
2909566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
2919566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*popup, ((PetscObject)draw)->prefix));
2922b8d69caSLisandro Dalcin   draw->popup = *popup;
2932b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
2942b8d69caSLisandro Dalcin }
2952b8d69caSLisandro Dalcin 
2962b8d69caSLisandro Dalcin /*
2972b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
2982b8d69caSLisandro Dalcin {
2992b8d69caSLisandro Dalcin   PetscFunctionBegin;
3002b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3012b8d69caSLisandro Dalcin }*/
3022b8d69caSLisandro Dalcin #define PetscDrawSetTitle_Image NULL
3032b8d69caSLisandro Dalcin 
3042b8d69caSLisandro Dalcin /*
3052b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
3062b8d69caSLisandro Dalcin {
3072b8d69caSLisandro Dalcin   PetscFunctionBegin;
3082b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3092b8d69caSLisandro Dalcin }*/
3102b8d69caSLisandro Dalcin #define PetscDrawCheckResizedWindow_Image NULL
3112b8d69caSLisandro Dalcin 
3129371c9d4SSatish Balay static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h) {
3132b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
3142b8d69caSLisandro Dalcin 
3152b8d69caSLisandro Dalcin   PetscFunctionBegin;
3162b8d69caSLisandro Dalcin   if (w == img->w && h == img->h) PetscFunctionReturn(0);
3179566063dSJacob Faibussowitsch   PetscCall(PetscFree(img->buffer));
3182b8d69caSLisandro Dalcin 
3199371c9d4SSatish Balay   img->w = w;
3209371c9d4SSatish Balay   img->h = h;
3219566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
3229566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetViewport_Image(draw, draw->port_xl, draw->port_yl, draw->port_xr, draw->port_yr));
3232b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3242b8d69caSLisandro Dalcin }
3252b8d69caSLisandro Dalcin 
3269371c9d4SSatish Balay static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw) {
3272b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
3282b8d69caSLisandro Dalcin 
3292b8d69caSLisandro Dalcin   PetscFunctionBegin;
3309566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw->popup));
3319566063dSJacob Faibussowitsch   PetscCall(PetscFree(img->buffer));
3329566063dSJacob Faibussowitsch   PetscCall(PetscFree(draw->data));
3332b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3342b8d69caSLisandro Dalcin }
3352b8d69caSLisandro Dalcin 
3362b8d69caSLisandro Dalcin /*
3372b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawView_Image(PetscDraw draw,PetscViewer viewer)
3382b8d69caSLisandro Dalcin {
3392b8d69caSLisandro Dalcin   PetscFunctionBegin;
3402b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3412b8d69caSLisandro Dalcin }*/
3422b8d69caSLisandro Dalcin #define PetscDrawView_Image NULL
3432b8d69caSLisandro Dalcin 
3442b8d69caSLisandro Dalcin /*
3452b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
3462b8d69caSLisandro Dalcin {
3472b8d69caSLisandro Dalcin   PetscFunctionBegin;
3482b8d69caSLisandro Dalcin   *button = PETSC_BUTTON_NONE;
3492b8d69caSLisandro Dalcin   if (x_user) *x_user = 0;
3502b8d69caSLisandro Dalcin   if (y_user) *y_user = 0;
3512b8d69caSLisandro Dalcin   if (x_phys) *x_phys = 0;
3522b8d69caSLisandro Dalcin   if (y_phys) *y_phys = 0;
3532b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3542b8d69caSLisandro Dalcin }*/
3552b8d69caSLisandro Dalcin #define PetscDrawGetMouseButton_Image NULL
3562b8d69caSLisandro Dalcin 
3572b8d69caSLisandro Dalcin /*
3582b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
3592b8d69caSLisandro Dalcin {
3602b8d69caSLisandro Dalcin   PetscFunctionBegin;
3612b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3622b8d69caSLisandro Dalcin }*/
3632b8d69caSLisandro Dalcin #define PetscDrawPause_Image NULL
3642b8d69caSLisandro Dalcin 
3652b8d69caSLisandro Dalcin /*
3662b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
3672b8d69caSLisandro Dalcin {
3682b8d69caSLisandro Dalcin   PetscFunctionBegin;
3692b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3702b8d69caSLisandro Dalcin }*/
3712b8d69caSLisandro Dalcin #define PetscDrawBeginPage_Image NULL
3722b8d69caSLisandro Dalcin 
3732b8d69caSLisandro Dalcin /*
3742b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
3752b8d69caSLisandro Dalcin {
3762b8d69caSLisandro Dalcin   PetscFunctionBegin;
3772b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3782b8d69caSLisandro Dalcin }*/
3792b8d69caSLisandro Dalcin #define PetscDrawEndPage_Image NULL
3802b8d69caSLisandro Dalcin 
3819371c9d4SSatish Balay static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw) {
3822b8d69caSLisandro Dalcin   PetscImage pimg = (PetscImage)draw->data;
3832b8d69caSLisandro Dalcin   PetscImage simg;
3842b8d69caSLisandro Dalcin 
3852b8d69caSLisandro Dalcin   PetscFunctionBegin;
3869566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(PETSC_COMM_SELF, NULL, NULL, 0, 0, draw->w, draw->h, sdraw));
3879566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetType(*sdraw, PETSC_DRAW_IMAGE));
3882b8d69caSLisandro Dalcin   (*sdraw)->ops->resizewindow = NULL;
3892b8d69caSLisandro Dalcin   simg                        = (PetscImage)(*sdraw)->data;
3909566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(simg->buffer, pimg->buffer, pimg->w * pimg->h));
3912b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
3922b8d69caSLisandro Dalcin }
3932b8d69caSLisandro Dalcin 
3949371c9d4SSatish Balay static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw) {
3952b8d69caSLisandro Dalcin   PetscImage pimg = (PetscImage)draw->data;
3962b8d69caSLisandro Dalcin   PetscImage simg = (PetscImage)(*sdraw)->data;
3972b8d69caSLisandro Dalcin 
3982b8d69caSLisandro Dalcin   PetscFunctionBegin;
3999566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h));
4009566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(sdraw));
4012b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
4022b8d69caSLisandro Dalcin }
4032b8d69caSLisandro Dalcin 
4042b8d69caSLisandro Dalcin /*
4052b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
4062b8d69caSLisandro Dalcin {
4072b8d69caSLisandro Dalcin   PetscFunctionBegin;
4082b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
4092b8d69caSLisandro Dalcin }*/
4102b8d69caSLisandro Dalcin #define PetscDrawSave_Image NULL
4112b8d69caSLisandro Dalcin 
4129371c9d4SSatish Balay static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw, unsigned char palette[256][3], unsigned int *w, unsigned int *h, unsigned char *pixels[]) {
4132b8d69caSLisandro Dalcin   PetscImage     img    = (PetscImage)draw->data;
4142b8d69caSLisandro Dalcin   unsigned char *buffer = NULL;
4152b8d69caSLisandro Dalcin   PetscMPIInt    rank, size;
4162b8d69caSLisandro Dalcin 
4172b8d69caSLisandro Dalcin   PetscFunctionBegin;
4182b8d69caSLisandro Dalcin   if (w) *w = (unsigned int)img->w;
4192b8d69caSLisandro Dalcin   if (h) *h = (unsigned int)img->h;
4202b8d69caSLisandro Dalcin   if (pixels) *pixels = NULL;
4219566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank));
422dd400576SPatrick Sanan   if (rank == 0) {
4239566063dSJacob Faibussowitsch     PetscCall(PetscMemcpy(palette, img->palette, sizeof(img->palette)));
4249566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((size_t)(img->w * img->h), &buffer));
425f416af30SBarry Smith     if (pixels) *pixels = buffer;
4262b8d69caSLisandro Dalcin   }
4279566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
4282b8d69caSLisandro Dalcin   if (size == 1) {
4299566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(buffer, img->buffer, img->w * img->h));
4302b8d69caSLisandro Dalcin   } else {
4319566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Reduce(img->buffer, buffer, img->w * img->h, MPI_UNSIGNED_CHAR, MPI_MAX, 0, PetscObjectComm((PetscObject)draw)));
4322b8d69caSLisandro Dalcin   }
4332b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
4342b8d69caSLisandro Dalcin }
4352b8d69caSLisandro Dalcin 
4369371c9d4SSatish Balay static struct _PetscDrawOps DvOps = {PetscDrawSetDoubleBuffer_Image, PetscDrawFlush_Image, PetscDrawLine_Image, PetscDrawLineSetWidth_Image, PetscDrawLineGetWidth_Image, PetscDrawPoint_Image, PetscDrawPointSetSize_Image, PetscDrawString_Image, PetscDrawStringVertical_Image, PetscDrawStringSetSize_Image, PetscDrawStringGetSize_Image, PetscDrawSetViewport_Image, PetscDrawClear_Image, PetscDrawRectangle_Image, PetscDrawTriangle_Image, PetscDrawEllipse_Image, PetscDrawGetMouseButton_Image, PetscDrawPause_Image, PetscDrawBeginPage_Image, PetscDrawEndPage_Image, PetscDrawGetPopup_Image, PetscDrawSetTitle_Image, PetscDrawCheckResizedWindow_Image, PetscDrawResizeWindow_Image, PetscDrawDestroy_Image, PetscDrawView_Image, PetscDrawGetSingleton_Image, PetscDrawRestoreSingleton_Image, PetscDrawSave_Image, PetscDrawGetImage_Image, PetscDrawSetCoordinates_Image, PetscDrawArrow_Image, PetscDrawCoordinateToPixel_Image, PetscDrawPixelToCoordinate_Image, PetscDrawPointPixel_Image, PetscDrawStringBoxed_Image};
4372b8d69caSLisandro Dalcin 
4382b8d69caSLisandro Dalcin static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
4392b8d69caSLisandro Dalcin   {255, 255, 255}, /* white */
4402b8d69caSLisandro Dalcin   {0,   0,   0  }, /* black */
4412b8d69caSLisandro Dalcin   {255, 0,   0  }, /* red */
4422b8d69caSLisandro Dalcin   {0,   255, 0  }, /* green */
4432b8d69caSLisandro Dalcin   {0,   255, 255}, /* cyan */
4442b8d69caSLisandro Dalcin   {0,   0,   255}, /* blue */
4452b8d69caSLisandro Dalcin   {255, 0,   255}, /* magenta */
4462b8d69caSLisandro Dalcin   {127, 255, 212}, /* aquamarine */
4472b8d69caSLisandro Dalcin   {34,  139, 34 }, /* forestgreen */
4482b8d69caSLisandro Dalcin   {255, 165, 0  }, /* orange */
4492b8d69caSLisandro Dalcin   {238, 130, 238}, /* violet */
4502b8d69caSLisandro Dalcin   {165, 42,  42 }, /* brown */
4512b8d69caSLisandro Dalcin   {255, 192, 203}, /* pink */
4522b8d69caSLisandro Dalcin   {255, 127, 80 }, /* coral */
4532b8d69caSLisandro Dalcin   {190, 190, 190}, /* gray */
4542b8d69caSLisandro Dalcin   {255, 255, 0  }, /* yellow */
4552b8d69caSLisandro Dalcin   {255, 215, 0  }, /* gold */
4562b8d69caSLisandro Dalcin   {255, 182, 193}, /* lightpink */
4572b8d69caSLisandro Dalcin   {72,  209, 204}, /* mediumturquoise */
4582b8d69caSLisandro Dalcin   {240, 230, 140}, /* khaki */
4592b8d69caSLisandro Dalcin   {105, 105, 105}, /* dimgray */
4602b8d69caSLisandro Dalcin   {54,  205, 50 }, /* yellowgreen */
4612b8d69caSLisandro Dalcin   {135, 206, 235}, /* skyblue */
4622b8d69caSLisandro Dalcin   {0,   100, 0  }, /* darkgreen */
4632b8d69caSLisandro Dalcin   {0,   0,   128}, /* navyblue */
4642b8d69caSLisandro Dalcin   {244, 164, 96 }, /* sandybrown */
4652b8d69caSLisandro Dalcin   {95,  158, 160}, /* cadetblue */
4662b8d69caSLisandro Dalcin   {176, 224, 230}, /* powderblue */
4672b8d69caSLisandro Dalcin   {255, 20,  147}, /* deeppink */
4682b8d69caSLisandro Dalcin   {216, 191, 216}, /* thistle */
4692b8d69caSLisandro Dalcin   {50,  205, 50 }, /* limegreen */
4702b8d69caSLisandro Dalcin   {255, 240, 245}, /* lavenderblush */
4712b8d69caSLisandro Dalcin   {221, 160, 221}, /* plum */
4722b8d69caSLisandro Dalcin };
4732b8d69caSLisandro Dalcin 
4742b8d69caSLisandro Dalcin /*MC
4752b8d69caSLisandro Dalcin    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer
4762b8d69caSLisandro Dalcin 
4772b8d69caSLisandro Dalcin    Options Database Keys:
4782b8d69caSLisandro Dalcin .  -draw_size w,h - size of image in pixels
4792b8d69caSLisandro Dalcin 
4802b8d69caSLisandro Dalcin    Level: beginner
4812b8d69caSLisandro Dalcin 
482db781477SPatrick Sanan .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`
4832b8d69caSLisandro Dalcin M*/
4842b8d69caSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);
4852b8d69caSLisandro Dalcin 
4869371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw) {
4872b8d69caSLisandro Dalcin   PetscImage img;
4882b8d69caSLisandro Dalcin   int        w = draw->w, h = draw->h;
4892b8d69caSLisandro Dalcin   PetscInt   size[2], nsize = 2;
4902b8d69caSLisandro Dalcin   PetscBool  set;
4912b8d69caSLisandro Dalcin 
4922b8d69caSLisandro Dalcin   PetscFunctionBegin;
4932b8d69caSLisandro Dalcin   draw->pause   = 0;
4949371c9d4SSatish Balay   draw->coor_xl = 0;
4959371c9d4SSatish Balay   draw->coor_xr = 1;
4969371c9d4SSatish Balay   draw->coor_yl = 0;
4979371c9d4SSatish Balay   draw->coor_yr = 1;
4989371c9d4SSatish Balay   draw->port_xl = 0;
4999371c9d4SSatish Balay   draw->port_xr = 1;
5009371c9d4SSatish Balay   draw->port_yl = 0;
5019371c9d4SSatish Balay   draw->port_yr = 1;
5022b8d69caSLisandro Dalcin 
5039371c9d4SSatish Balay   size[0] = w;
5049371c9d4SSatish Balay   if (size[0] < 1) size[0] = 300;
5059371c9d4SSatish Balay   size[1] = h;
5069371c9d4SSatish Balay   if (size[1] < 1) size[1] = size[0];
5079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_size", size, &nsize, &set));
5082b8d69caSLisandro Dalcin   if (set && nsize == 1) size[1] = size[0];
5092b8d69caSLisandro Dalcin   if (size[0] < 1) size[0] = 300;
5102b8d69caSLisandro Dalcin   if (size[1] < 1) size[1] = size[0];
5119371c9d4SSatish Balay   draw->w = w = size[0];
5129371c9d4SSatish Balay   draw->x     = 0;
5139371c9d4SSatish Balay   draw->h = h = size[1];
5149371c9d4SSatish Balay   draw->x     = 0;
5152b8d69caSLisandro Dalcin 
516*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&img));
5179566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(draw->ops, &DvOps, sizeof(DvOps)));
5182b8d69caSLisandro Dalcin   draw->data = (void *)img;
5192b8d69caSLisandro Dalcin 
5209371c9d4SSatish Balay   img->w = w;
5219371c9d4SSatish Balay   img->h = h;
5229566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
5232b8d69caSLisandro Dalcin   PetscImageSetClip(img, 0, 0, img->w, img->h);
5242b8d69caSLisandro Dalcin   {
5252b8d69caSLisandro Dalcin     int           i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS;
5262b8d69caSLisandro Dalcin     unsigned char R[256 - PETSC_DRAW_BASIC_COLORS];
5272b8d69caSLisandro Dalcin     unsigned char G[256 - PETSC_DRAW_BASIC_COLORS];
5282b8d69caSLisandro Dalcin     unsigned char B[256 - PETSC_DRAW_BASIC_COLORS];
5299566063dSJacob Faibussowitsch     PetscCall(PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B));
5302b8d69caSLisandro Dalcin     for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) {
5312b8d69caSLisandro Dalcin       img->palette[k][0] = BasicColors[k][0];
5322b8d69caSLisandro Dalcin       img->palette[k][1] = BasicColors[k][1];
5332b8d69caSLisandro Dalcin       img->palette[k][2] = BasicColors[k][2];
5342b8d69caSLisandro Dalcin     }
5352b8d69caSLisandro Dalcin     for (i = 0; i < ncolors; i++, k++) {
5362b8d69caSLisandro Dalcin       img->palette[k][0] = R[i];
5372b8d69caSLisandro Dalcin       img->palette[k][1] = G[i];
5382b8d69caSLisandro Dalcin       img->palette[k][2] = B[i];
5392b8d69caSLisandro Dalcin     }
5402b8d69caSLisandro Dalcin   }
5412b8d69caSLisandro Dalcin 
5429566063dSJacob Faibussowitsch   if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title));
5432b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
5442b8d69caSLisandro Dalcin }
5452b8d69caSLisandro Dalcin 
5462b8d69caSLisandro Dalcin /*@C
547811af0c4SBarry Smith    PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines.
5482b8d69caSLisandro Dalcin 
549d083f849SBarry Smith    Collective
5502b8d69caSLisandro Dalcin 
5512b8d69caSLisandro Dalcin    Input Parameters:
5522b8d69caSLisandro Dalcin +  comm - the communicator that will share image
553811af0c4SBarry Smith -  filename - optional name of the file where the image will be stored
5542b8d69caSLisandro Dalcin -  w, h - the image width and height in pixels
5552b8d69caSLisandro Dalcin 
5562b8d69caSLisandro Dalcin    Output Parameters:
5572b8d69caSLisandro Dalcin .  draw - the drawing context.
5582b8d69caSLisandro Dalcin 
5592b8d69caSLisandro Dalcin    Level: beginner
5602b8d69caSLisandro Dalcin 
561811af0c4SBarry Smith .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`
5622b8d69caSLisandro Dalcin @*/
5639371c9d4SSatish Balay PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw) {
5642b8d69caSLisandro Dalcin   PetscFunctionBegin;
5659566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw));
5669566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetType(*draw, PETSC_DRAW_IMAGE));
5679566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetSave(*draw, filename));
5682b8d69caSLisandro Dalcin   PetscFunctionReturn(0);
5692b8d69caSLisandro Dalcin }
570