xref: /petsc/src/sys/classes/draw/impls/image/drawimage.c (revision 6e4289a0dd4d962ed977e39cfbc50d2f2c3b3d96)
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*/
3ccb5f961SBarry Smith #include <petscviewer.h>
42b8d69caSLisandro Dalcin 
52b8d69caSLisandro Dalcin #if defined(PETSC_USE_DEBUG)
62c71b3e2SJacob 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))
72b8d69caSLisandro Dalcin #else
89371c9d4SSatish Balay   #define PetscDrawValidColor(color) \
99371c9d4SSatish Balay     do { \
109371c9d4SSatish Balay     } while (0)
112b8d69caSLisandro Dalcin #endif
122b8d69caSLisandro Dalcin 
132b8d69caSLisandro 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)))))
142b8d69caSLisandro 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)))))
152b8d69caSLisandro Dalcin 
162b8d69caSLisandro 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))
172b8d69caSLisandro 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))
182b8d69caSLisandro Dalcin 
19d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr)
20d71ae5a4SJacob Faibussowitsch {
212b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
222b8d69caSLisandro Dalcin   PetscFunctionBegin;
232b8d69caSLisandro Dalcin   {
242b8d69caSLisandro Dalcin     int xmax = img->w - 1, ymax = img->h - 1;
252b8d69caSLisandro Dalcin     int xa = (int)(xl * xmax), ya = ymax - (int)(yr * ymax);
262b8d69caSLisandro Dalcin     int xb = (int)(xr * xmax), yb = ymax - (int)(yl * ymax);
272b8d69caSLisandro Dalcin     PetscImageSetClip(img, xa, ya, xb + 1 - xa, yb + 1 - ya);
282b8d69caSLisandro Dalcin   }
293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
302b8d69caSLisandro Dalcin }
312b8d69caSLisandro Dalcin 
322b8d69caSLisandro Dalcin /*
332b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
342b8d69caSLisandro Dalcin {
352b8d69caSLisandro Dalcin   PetscFunctionBegin;
363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
372b8d69caSLisandro Dalcin }*/
382b8d69caSLisandro Dalcin #define PetscDrawSetCoordinates_Image NULL
392b8d69caSLisandro Dalcin 
40d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j)
41d71ae5a4SJacob Faibussowitsch {
422b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
432b8d69caSLisandro Dalcin   PetscFunctionBegin;
442b8d69caSLisandro Dalcin   if (i) *i = XTRANS(draw, img, x);
452b8d69caSLisandro Dalcin   if (j) *j = YTRANS(draw, img, y);
463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
472b8d69caSLisandro Dalcin }
482b8d69caSLisandro Dalcin 
49d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y)
50d71ae5a4SJacob Faibussowitsch {
512b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
522b8d69caSLisandro Dalcin   PetscFunctionBegin;
532b8d69caSLisandro Dalcin   if (x) *x = ITRANS(draw, img, i);
542b8d69caSLisandro Dalcin   if (y) *y = JTRANS(draw, img, j);
553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
562b8d69caSLisandro Dalcin }
572b8d69caSLisandro Dalcin 
582b8d69caSLisandro Dalcin /*
592b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
602b8d69caSLisandro Dalcin {
612b8d69caSLisandro Dalcin   PetscFunctionBegin;
623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
632b8d69caSLisandro Dalcin }*/
642b8d69caSLisandro Dalcin #define PetscDrawPointSetSize_Image NULL
652b8d69caSLisandro Dalcin 
66d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c)
67d71ae5a4SJacob Faibussowitsch {
682b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
692b8d69caSLisandro Dalcin   PetscFunctionBegin;
702b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
712b8d69caSLisandro Dalcin   {
722b8d69caSLisandro Dalcin     int j, xx = XTRANS(draw, img, x);
732b8d69caSLisandro Dalcin     int i, yy = YTRANS(draw, img, y);
742b8d69caSLisandro Dalcin     for (i = -1; i <= 1; i++)
759371c9d4SSatish Balay       for (j = -1; j <= 1; j++) PetscImageDrawPixel(img, xx + j, yy + i, c);
762b8d69caSLisandro Dalcin   }
773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
782b8d69caSLisandro Dalcin }
792b8d69caSLisandro Dalcin 
80d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c)
81d71ae5a4SJacob Faibussowitsch {
822b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
832b8d69caSLisandro Dalcin   PetscFunctionBegin;
842b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
85d71ae5a4SJacob Faibussowitsch   {
86d71ae5a4SJacob Faibussowitsch     PetscImageDrawPixel(img, x, y, c);
87d71ae5a4SJacob Faibussowitsch   }
883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
892b8d69caSLisandro Dalcin }
902b8d69caSLisandro Dalcin 
912b8d69caSLisandro Dalcin /*
922b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
932b8d69caSLisandro Dalcin {
942b8d69caSLisandro Dalcin   PetscFunctionBegin;
953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
962b8d69caSLisandro Dalcin }*/
972b8d69caSLisandro Dalcin #define PetscDrawLineSetWidth_Image NULL
982b8d69caSLisandro Dalcin 
99d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width)
100d71ae5a4SJacob Faibussowitsch {
1012b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1022b8d69caSLisandro Dalcin   PetscFunctionBegin;
1032b8d69caSLisandro Dalcin   {
1042b8d69caSLisandro Dalcin     int lw = 1;
1052b8d69caSLisandro Dalcin     *width = lw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
1062b8d69caSLisandro Dalcin   }
1073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1082b8d69caSLisandro Dalcin }
1092b8d69caSLisandro Dalcin 
110d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
111d71ae5a4SJacob Faibussowitsch {
1122b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1132b8d69caSLisandro Dalcin   PetscFunctionBegin;
1142b8d69caSLisandro Dalcin   {
1152b8d69caSLisandro Dalcin     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
1162b8d69caSLisandro Dalcin     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
1172b8d69caSLisandro Dalcin     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
1182b8d69caSLisandro Dalcin   }
1193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1202b8d69caSLisandro Dalcin }
1212b8d69caSLisandro Dalcin 
122d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
123d71ae5a4SJacob Faibussowitsch {
1242b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1252b8d69caSLisandro Dalcin   PetscFunctionBegin;
1262b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
1272b8d69caSLisandro Dalcin   {
1282b8d69caSLisandro Dalcin     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
1292b8d69caSLisandro Dalcin     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
1303ba16761SJacob Faibussowitsch     if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(PETSC_SUCCESS);
1312b8d69caSLisandro Dalcin     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
1322b8d69caSLisandro Dalcin     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
1332b8d69caSLisandro Dalcin       if (y_2 > y_1) {
1342b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 - 3, c);
1352b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
1362b8d69caSLisandro Dalcin       } else {
1372b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 + 3, c);
1382b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
1392b8d69caSLisandro Dalcin       }
1402b8d69caSLisandro Dalcin     }
1412b8d69caSLisandro Dalcin     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
1422b8d69caSLisandro Dalcin       if (x_2 > x_1) {
1432b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2 - 3, y_2 - 3, x_2, y_2, c);
1442b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2 - 3, y_2 + 3, x_2, y_2, c);
1452b8d69caSLisandro Dalcin       } else {
1462b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
1472b8d69caSLisandro Dalcin         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
1482b8d69caSLisandro Dalcin       }
1492b8d69caSLisandro Dalcin     }
1502b8d69caSLisandro Dalcin   }
1513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1522b8d69caSLisandro Dalcin }
1532b8d69caSLisandro Dalcin 
154d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4)
155d71ae5a4SJacob Faibussowitsch {
1562b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1572b8d69caSLisandro Dalcin   PetscFunctionBegin;
1582b8d69caSLisandro Dalcin   PetscDrawValidColor(c1);
1592b8d69caSLisandro Dalcin   PetscDrawValidColor(c2);
1602b8d69caSLisandro Dalcin   PetscDrawValidColor(c3);
1612b8d69caSLisandro Dalcin   PetscDrawValidColor(c4);
1622b8d69caSLisandro Dalcin   {
1632b8d69caSLisandro Dalcin     int x = XTRANS(draw, img, xl), w = XTRANS(draw, img, xr) + 1 - x;
1642b8d69caSLisandro Dalcin     int y = YTRANS(draw, img, yr), h = YTRANS(draw, img, yl) + 1 - y;
1652b8d69caSLisandro Dalcin     int c = (c1 + c2 + c3 + c4) / 4;
1662b8d69caSLisandro Dalcin     PetscImageDrawRectangle(img, x, y, w, h, c);
1672b8d69caSLisandro Dalcin   }
1683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1692b8d69caSLisandro Dalcin }
1702b8d69caSLisandro Dalcin 
171d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c)
172d71ae5a4SJacob Faibussowitsch {
1732b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1742b8d69caSLisandro Dalcin   PetscFunctionBegin;
1752b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
1762b8d69caSLisandro Dalcin   a = PetscAbsReal(a);
1772b8d69caSLisandro Dalcin   b = PetscAbsReal(b);
1782b8d69caSLisandro Dalcin   {
1792b8d69caSLisandro Dalcin     int xc = XTRANS(draw, img, x), w = XTRANS(draw, img, x + a / 2) + 0 - xc;
1802b8d69caSLisandro Dalcin     int yc = YTRANS(draw, img, y), h = YTRANS(draw, img, y - b / 2) + 0 - yc;
1812b8d69caSLisandro Dalcin     if (PetscAbsReal(a - b) <= 0) w = h = PetscMin(w, h); /* workaround truncation errors */
1822b8d69caSLisandro Dalcin     PetscImageDrawEllipse(img, xc, yc, w, h, c);
1832b8d69caSLisandro Dalcin   }
1843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1852b8d69caSLisandro Dalcin }
1862b8d69caSLisandro Dalcin 
187d71ae5a4SJacob Faibussowitsch 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)
188d71ae5a4SJacob Faibussowitsch {
1892b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
1902b8d69caSLisandro Dalcin   PetscFunctionBegin;
1912b8d69caSLisandro Dalcin   PetscDrawValidColor(c1);
1922b8d69caSLisandro Dalcin   PetscDrawValidColor(c2);
1932b8d69caSLisandro Dalcin   PetscDrawValidColor(c3);
1942b8d69caSLisandro Dalcin   {
1952b8d69caSLisandro Dalcin     int x_1 = XTRANS(draw, img, X_1), x_2 = XTRANS(draw, img, X_2), x_3 = XTRANS(draw, img, X_3);
1962b8d69caSLisandro Dalcin     int y_1 = YTRANS(draw, img, Y_1), y_2 = YTRANS(draw, img, Y_2), y_3 = YTRANS(draw, img, Y_3);
1972b8d69caSLisandro Dalcin     PetscImageDrawTriangle(img, x_1, y_1, c1, x_2, y_2, c2, x_3, y_3, c3);
1982b8d69caSLisandro Dalcin   }
1993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2002b8d69caSLisandro Dalcin }
2012b8d69caSLisandro Dalcin 
2022b8d69caSLisandro Dalcin /*
2032b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
2042b8d69caSLisandro Dalcin {
2052b8d69caSLisandro Dalcin   PetscFunctionBegin;
2063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2072b8d69caSLisandro Dalcin }*/
2082b8d69caSLisandro Dalcin #define PetscDrawStringSetSize_Image NULL
2092b8d69caSLisandro Dalcin 
210d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h)
211d71ae5a4SJacob Faibussowitsch {
2122b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
2132b8d69caSLisandro Dalcin   PetscFunctionBegin;
2142b8d69caSLisandro Dalcin   {
2152b8d69caSLisandro Dalcin     int tw = PetscImageFontWidth;
2162b8d69caSLisandro Dalcin     int th = PetscImageFontHeight;
2172b8d69caSLisandro Dalcin     if (w) *w = tw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
2182b8d69caSLisandro Dalcin     if (h) *h = th * (draw->coor_yr - draw->coor_yl) / (img->h * (draw->port_yr - draw->port_yl));
2192b8d69caSLisandro Dalcin   }
2203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2212b8d69caSLisandro Dalcin }
2222b8d69caSLisandro Dalcin 
223d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawString_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
224d71ae5a4SJacob Faibussowitsch {
2252b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
2262b8d69caSLisandro Dalcin   PetscToken token;
2272b8d69caSLisandro Dalcin   char      *subtext;
2282b8d69caSLisandro Dalcin   PetscFunctionBegin;
2292b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
2302b8d69caSLisandro Dalcin   {
2312b8d69caSLisandro Dalcin     int xx = XTRANS(draw, img, x);
2322b8d69caSLisandro Dalcin     int yy = YTRANS(draw, img, y);
2339566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(text, '\n', &token));
2349566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &subtext));
2352b8d69caSLisandro Dalcin     while (subtext) {
2362b8d69caSLisandro Dalcin       PetscImageDrawText(img, xx, yy, c, subtext);
2372b8d69caSLisandro Dalcin       yy += PetscImageFontHeight;
2389566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &subtext));
2392b8d69caSLisandro Dalcin     }
2409566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
2412b8d69caSLisandro Dalcin   }
2423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2432b8d69caSLisandro Dalcin }
2442b8d69caSLisandro Dalcin 
245d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
246d71ae5a4SJacob Faibussowitsch {
2472b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
2482b8d69caSLisandro Dalcin   PetscFunctionBegin;
2492b8d69caSLisandro Dalcin   PetscDrawValidColor(c);
2502b8d69caSLisandro Dalcin   {
2512b8d69caSLisandro Dalcin     char chr[2] = {0, 0};
2522b8d69caSLisandro Dalcin     int  xx     = XTRANS(draw, img, x);
2532b8d69caSLisandro Dalcin     int  yy     = YTRANS(draw, img, y);
2542b8d69caSLisandro Dalcin     int  offset = PetscImageFontHeight;
2552b8d69caSLisandro Dalcin     while ((chr[0] = *text++)) {
2562b8d69caSLisandro Dalcin       PetscImageDrawText(img, xx, yy + offset, c, chr);
2572b8d69caSLisandro Dalcin       yy += PetscImageFontHeight;
2582b8d69caSLisandro Dalcin     }
2592b8d69caSLisandro Dalcin   }
2603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2612b8d69caSLisandro Dalcin }
2622b8d69caSLisandro Dalcin 
2632b8d69caSLisandro Dalcin /*
2642b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
2652b8d69caSLisandro Dalcin {
2662b8d69caSLisandro Dalcin   PetscFunctionBegin;
2672b8d69caSLisandro Dalcin   if (w) *w = 0;
2682b8d69caSLisandro Dalcin   if (h) *h = 0;
2693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2702b8d69caSLisandro Dalcin */
2712b8d69caSLisandro Dalcin #define PetscDrawStringBoxed_Image NULL
2722b8d69caSLisandro Dalcin 
2732b8d69caSLisandro Dalcin /*
2742b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
2752b8d69caSLisandro Dalcin {
2762b8d69caSLisandro Dalcin   PetscFunctionBegin;
2773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2782b8d69caSLisandro Dalcin }*/
2792b8d69caSLisandro Dalcin #define PetscDrawFlush_Image NULL
2802b8d69caSLisandro Dalcin 
281d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
282d71ae5a4SJacob Faibussowitsch {
2832b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
2842b8d69caSLisandro Dalcin   PetscFunctionBegin;
285d71ae5a4SJacob Faibussowitsch   {
286d71ae5a4SJacob Faibussowitsch     PetscImageClear(img);
287d71ae5a4SJacob Faibussowitsch   }
2883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2892b8d69caSLisandro Dalcin }
2902b8d69caSLisandro Dalcin 
2912b8d69caSLisandro Dalcin /*
2922b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
2932b8d69caSLisandro Dalcin {
2942b8d69caSLisandro Dalcin   PetscFunctionBegin;
2953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2962b8d69caSLisandro Dalcin }*/
2972b8d69caSLisandro Dalcin #define PetscDrawSetDoubleBuffer_Image NULL
2982b8d69caSLisandro Dalcin 
299d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup)
300d71ae5a4SJacob Faibussowitsch {
3012b8d69caSLisandro Dalcin   PetscBool flg = PETSC_FALSE;
3022b8d69caSLisandro Dalcin 
3032b8d69caSLisandro Dalcin   PetscFunctionBegin;
3049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL));
3059371c9d4SSatish Balay   if (!flg) {
3069371c9d4SSatish Balay     *popup = NULL;
3073ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
3089371c9d4SSatish Balay   }
3099566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, 0, 0, 220, 220, popup));
3109566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_IMAGE));
3119566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
3129566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*popup, ((PetscObject)draw)->prefix));
3132b8d69caSLisandro Dalcin   draw->popup = *popup;
3143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3152b8d69caSLisandro Dalcin }
3162b8d69caSLisandro Dalcin 
3172b8d69caSLisandro Dalcin /*
3182b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
3192b8d69caSLisandro Dalcin {
3202b8d69caSLisandro Dalcin   PetscFunctionBegin;
3213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3222b8d69caSLisandro Dalcin }*/
3232b8d69caSLisandro Dalcin #define PetscDrawSetTitle_Image NULL
3242b8d69caSLisandro Dalcin 
3252b8d69caSLisandro Dalcin /*
3262b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
3272b8d69caSLisandro Dalcin {
3282b8d69caSLisandro Dalcin   PetscFunctionBegin;
3293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3302b8d69caSLisandro Dalcin }*/
3312b8d69caSLisandro Dalcin #define PetscDrawCheckResizedWindow_Image NULL
3322b8d69caSLisandro Dalcin 
333d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h)
334d71ae5a4SJacob Faibussowitsch {
3352b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
3362b8d69caSLisandro Dalcin 
3372b8d69caSLisandro Dalcin   PetscFunctionBegin;
3383ba16761SJacob Faibussowitsch   if (w == img->w && h == img->h) PetscFunctionReturn(PETSC_SUCCESS);
3399566063dSJacob Faibussowitsch   PetscCall(PetscFree(img->buffer));
3402b8d69caSLisandro Dalcin 
3419371c9d4SSatish Balay   img->w = w;
3429371c9d4SSatish Balay   img->h = h;
3439566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
3449566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetViewport_Image(draw, draw->port_xl, draw->port_yl, draw->port_xr, draw->port_yr));
3453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3462b8d69caSLisandro Dalcin }
3472b8d69caSLisandro Dalcin 
348d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
349d71ae5a4SJacob Faibussowitsch {
3502b8d69caSLisandro Dalcin   PetscImage img = (PetscImage)draw->data;
3512b8d69caSLisandro Dalcin 
3522b8d69caSLisandro Dalcin   PetscFunctionBegin;
3539566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw->popup));
3549566063dSJacob Faibussowitsch   PetscCall(PetscFree(img->buffer));
3559566063dSJacob Faibussowitsch   PetscCall(PetscFree(draw->data));
3563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3572b8d69caSLisandro Dalcin }
3582b8d69caSLisandro Dalcin 
3592b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawView_Image(PetscDraw draw, PetscViewer viewer)
3602b8d69caSLisandro Dalcin {
361ccb5f961SBarry Smith   PetscBool iascii;
362ccb5f961SBarry Smith 
3632b8d69caSLisandro Dalcin   PetscFunctionBegin;
364ccb5f961SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
365ccb5f961SBarry Smith   if (iascii) {
366ccb5f961SBarry Smith     const char *filename = draw->savefilename ? draw->savefilename : draw->title;
367ccb5f961SBarry Smith     PetscCall(PetscViewerASCIIPrintf(viewer, "  Image file name %s\n", filename));
368ccb5f961SBarry Smith   }
3693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
370ccb5f961SBarry Smith }
3712b8d69caSLisandro Dalcin 
3722b8d69caSLisandro Dalcin /*
3732b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
3742b8d69caSLisandro Dalcin {
3752b8d69caSLisandro Dalcin   PetscFunctionBegin;
3762b8d69caSLisandro Dalcin   *button = PETSC_BUTTON_NONE;
3772b8d69caSLisandro Dalcin   if (x_user) *x_user = 0;
3782b8d69caSLisandro Dalcin   if (y_user) *y_user = 0;
3792b8d69caSLisandro Dalcin   if (x_phys) *x_phys = 0;
3802b8d69caSLisandro Dalcin   if (y_phys) *y_phys = 0;
3813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3822b8d69caSLisandro Dalcin }*/
3832b8d69caSLisandro Dalcin #define PetscDrawGetMouseButton_Image NULL
3842b8d69caSLisandro Dalcin 
3852b8d69caSLisandro Dalcin /*
3862b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
3872b8d69caSLisandro Dalcin {
3882b8d69caSLisandro Dalcin   PetscFunctionBegin;
3893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3902b8d69caSLisandro Dalcin }*/
3912b8d69caSLisandro Dalcin #define PetscDrawPause_Image NULL
3922b8d69caSLisandro Dalcin 
3932b8d69caSLisandro Dalcin /*
3942b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
3952b8d69caSLisandro Dalcin {
3962b8d69caSLisandro Dalcin   PetscFunctionBegin;
3973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3982b8d69caSLisandro Dalcin }*/
3992b8d69caSLisandro Dalcin #define PetscDrawBeginPage_Image NULL
4002b8d69caSLisandro Dalcin 
4012b8d69caSLisandro Dalcin /*
4022b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
4032b8d69caSLisandro Dalcin {
4042b8d69caSLisandro Dalcin   PetscFunctionBegin;
4053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4062b8d69caSLisandro Dalcin }*/
4072b8d69caSLisandro Dalcin #define PetscDrawEndPage_Image NULL
4082b8d69caSLisandro Dalcin 
409d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
410d71ae5a4SJacob Faibussowitsch {
4112b8d69caSLisandro Dalcin   PetscImage pimg = (PetscImage)draw->data;
4122b8d69caSLisandro Dalcin   PetscImage simg;
4132b8d69caSLisandro Dalcin 
4142b8d69caSLisandro Dalcin   PetscFunctionBegin;
4159566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(PETSC_COMM_SELF, NULL, NULL, 0, 0, draw->w, draw->h, sdraw));
4169566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetType(*sdraw, PETSC_DRAW_IMAGE));
4172b8d69caSLisandro Dalcin   (*sdraw)->ops->resizewindow = NULL;
4182b8d69caSLisandro Dalcin   simg                        = (PetscImage)(*sdraw)->data;
4199566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(simg->buffer, pimg->buffer, pimg->w * pimg->h));
4203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4212b8d69caSLisandro Dalcin }
4222b8d69caSLisandro Dalcin 
423d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
424d71ae5a4SJacob Faibussowitsch {
4252b8d69caSLisandro Dalcin   PetscImage pimg = (PetscImage)draw->data;
4262b8d69caSLisandro Dalcin   PetscImage simg = (PetscImage)(*sdraw)->data;
4272b8d69caSLisandro Dalcin 
4282b8d69caSLisandro Dalcin   PetscFunctionBegin;
4299566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h));
4309566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(sdraw));
4313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4322b8d69caSLisandro Dalcin }
4332b8d69caSLisandro Dalcin 
4342b8d69caSLisandro Dalcin /*
4352b8d69caSLisandro Dalcin static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
4362b8d69caSLisandro Dalcin {
4372b8d69caSLisandro Dalcin   PetscFunctionBegin;
4383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4392b8d69caSLisandro Dalcin }*/
4402b8d69caSLisandro Dalcin #define PetscDrawSave_Image NULL
4412b8d69caSLisandro Dalcin 
442d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw, unsigned char palette[256][3], unsigned int *w, unsigned int *h, unsigned char *pixels[])
443d71ae5a4SJacob Faibussowitsch {
4442b8d69caSLisandro Dalcin   PetscImage     img    = (PetscImage)draw->data;
4452b8d69caSLisandro Dalcin   unsigned char *buffer = NULL;
4462b8d69caSLisandro Dalcin   PetscMPIInt    rank, size;
4472b8d69caSLisandro Dalcin 
4482b8d69caSLisandro Dalcin   PetscFunctionBegin;
4492b8d69caSLisandro Dalcin   if (w) *w = (unsigned int)img->w;
4502b8d69caSLisandro Dalcin   if (h) *h = (unsigned int)img->h;
4512b8d69caSLisandro Dalcin   if (pixels) *pixels = NULL;
4529566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank));
453dd400576SPatrick Sanan   if (rank == 0) {
4549566063dSJacob Faibussowitsch     PetscCall(PetscMemcpy(palette, img->palette, sizeof(img->palette)));
4559566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((size_t)(img->w * img->h), &buffer));
456f416af30SBarry Smith     if (pixels) *pixels = buffer;
4572b8d69caSLisandro Dalcin   }
4589566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
4592b8d69caSLisandro Dalcin   if (size == 1) {
4609566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(buffer, img->buffer, img->w * img->h));
4612b8d69caSLisandro Dalcin   } else {
4629566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Reduce(img->buffer, buffer, img->w * img->h, MPI_UNSIGNED_CHAR, MPI_MAX, 0, PetscObjectComm((PetscObject)draw)));
4632b8d69caSLisandro Dalcin   }
4643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4652b8d69caSLisandro Dalcin }
4662b8d69caSLisandro Dalcin 
467*6e4289a0SDuncan Campbell 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, NULL};
4682b8d69caSLisandro Dalcin 
4692b8d69caSLisandro Dalcin static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
4702b8d69caSLisandro Dalcin   {255, 255, 255}, /* white */
4712b8d69caSLisandro Dalcin   {0,   0,   0  }, /* black */
4722b8d69caSLisandro Dalcin   {255, 0,   0  }, /* red */
4732b8d69caSLisandro Dalcin   {0,   255, 0  }, /* green */
4742b8d69caSLisandro Dalcin   {0,   255, 255}, /* cyan */
4752b8d69caSLisandro Dalcin   {0,   0,   255}, /* blue */
4762b8d69caSLisandro Dalcin   {255, 0,   255}, /* magenta */
4772b8d69caSLisandro Dalcin   {127, 255, 212}, /* aquamarine */
4782b8d69caSLisandro Dalcin   {34,  139, 34 }, /* forestgreen */
4792b8d69caSLisandro Dalcin   {255, 165, 0  }, /* orange */
4802b8d69caSLisandro Dalcin   {238, 130, 238}, /* violet */
4812b8d69caSLisandro Dalcin   {165, 42,  42 }, /* brown */
4822b8d69caSLisandro Dalcin   {255, 192, 203}, /* pink */
4832b8d69caSLisandro Dalcin   {255, 127, 80 }, /* coral */
4842b8d69caSLisandro Dalcin   {190, 190, 190}, /* gray */
4852b8d69caSLisandro Dalcin   {255, 255, 0  }, /* yellow */
4862b8d69caSLisandro Dalcin   {255, 215, 0  }, /* gold */
4872b8d69caSLisandro Dalcin   {255, 182, 193}, /* lightpink */
4882b8d69caSLisandro Dalcin   {72,  209, 204}, /* mediumturquoise */
4892b8d69caSLisandro Dalcin   {240, 230, 140}, /* khaki */
4902b8d69caSLisandro Dalcin   {105, 105, 105}, /* dimgray */
4912b8d69caSLisandro Dalcin   {54,  205, 50 }, /* yellowgreen */
4922b8d69caSLisandro Dalcin   {135, 206, 235}, /* skyblue */
4932b8d69caSLisandro Dalcin   {0,   100, 0  }, /* darkgreen */
4942b8d69caSLisandro Dalcin   {0,   0,   128}, /* navyblue */
4952b8d69caSLisandro Dalcin   {244, 164, 96 }, /* sandybrown */
4962b8d69caSLisandro Dalcin   {95,  158, 160}, /* cadetblue */
4972b8d69caSLisandro Dalcin   {176, 224, 230}, /* powderblue */
4982b8d69caSLisandro Dalcin   {255, 20,  147}, /* deeppink */
4992b8d69caSLisandro Dalcin   {216, 191, 216}, /* thistle */
5002b8d69caSLisandro Dalcin   {50,  205, 50 }, /* limegreen */
5012b8d69caSLisandro Dalcin   {255, 240, 245}, /* lavenderblush */
5022b8d69caSLisandro Dalcin   {221, 160, 221}, /* plum */
5032b8d69caSLisandro Dalcin };
5042b8d69caSLisandro Dalcin 
5052b8d69caSLisandro Dalcin /*MC
5062b8d69caSLisandro Dalcin    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer
5072b8d69caSLisandro Dalcin 
5082b8d69caSLisandro Dalcin    Options Database Keys:
5092b8d69caSLisandro Dalcin .  -draw_size w,h - size of image in pixels
5102b8d69caSLisandro Dalcin 
5112b8d69caSLisandro Dalcin    Level: beginner
5122b8d69caSLisandro Dalcin 
513db781477SPatrick Sanan .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`
5142b8d69caSLisandro Dalcin M*/
5152b8d69caSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);
5162b8d69caSLisandro Dalcin 
517d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
518d71ae5a4SJacob Faibussowitsch {
5192b8d69caSLisandro Dalcin   PetscImage img;
5202b8d69caSLisandro Dalcin   int        w = draw->w, h = draw->h;
5212b8d69caSLisandro Dalcin   PetscInt   size[2], nsize = 2;
5222b8d69caSLisandro Dalcin   PetscBool  set;
5232b8d69caSLisandro Dalcin 
5242b8d69caSLisandro Dalcin   PetscFunctionBegin;
5252b8d69caSLisandro Dalcin   draw->pause   = 0;
5269371c9d4SSatish Balay   draw->coor_xl = 0;
5279371c9d4SSatish Balay   draw->coor_xr = 1;
5289371c9d4SSatish Balay   draw->coor_yl = 0;
5299371c9d4SSatish Balay   draw->coor_yr = 1;
5309371c9d4SSatish Balay   draw->port_xl = 0;
5319371c9d4SSatish Balay   draw->port_xr = 1;
5329371c9d4SSatish Balay   draw->port_yl = 0;
5339371c9d4SSatish Balay   draw->port_yr = 1;
5342b8d69caSLisandro Dalcin 
5359371c9d4SSatish Balay   size[0] = w;
5369371c9d4SSatish Balay   if (size[0] < 1) size[0] = 300;
5379371c9d4SSatish Balay   size[1] = h;
5389371c9d4SSatish Balay   if (size[1] < 1) size[1] = size[0];
5399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_size", size, &nsize, &set));
5402b8d69caSLisandro Dalcin   if (set && nsize == 1) size[1] = size[0];
5412b8d69caSLisandro Dalcin   if (size[0] < 1) size[0] = 300;
5422b8d69caSLisandro Dalcin   if (size[1] < 1) size[1] = size[0];
5439371c9d4SSatish Balay   draw->w = w = size[0];
5449371c9d4SSatish Balay   draw->x     = 0;
5459371c9d4SSatish Balay   draw->h = h = size[1];
5469371c9d4SSatish Balay   draw->x     = 0;
5472b8d69caSLisandro Dalcin 
5484dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&img));
5499566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(draw->ops, &DvOps, sizeof(DvOps)));
5502b8d69caSLisandro Dalcin   draw->data = (void *)img;
5512b8d69caSLisandro Dalcin 
5529371c9d4SSatish Balay   img->w = w;
5539371c9d4SSatish Balay   img->h = h;
5549566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
5552b8d69caSLisandro Dalcin   PetscImageSetClip(img, 0, 0, img->w, img->h);
5562b8d69caSLisandro Dalcin   {
5572b8d69caSLisandro Dalcin     int           i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS;
5582b8d69caSLisandro Dalcin     unsigned char R[256 - PETSC_DRAW_BASIC_COLORS];
5592b8d69caSLisandro Dalcin     unsigned char G[256 - PETSC_DRAW_BASIC_COLORS];
5602b8d69caSLisandro Dalcin     unsigned char B[256 - PETSC_DRAW_BASIC_COLORS];
5619566063dSJacob Faibussowitsch     PetscCall(PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B));
5622b8d69caSLisandro Dalcin     for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) {
5632b8d69caSLisandro Dalcin       img->palette[k][0] = BasicColors[k][0];
5642b8d69caSLisandro Dalcin       img->palette[k][1] = BasicColors[k][1];
5652b8d69caSLisandro Dalcin       img->palette[k][2] = BasicColors[k][2];
5662b8d69caSLisandro Dalcin     }
5672b8d69caSLisandro Dalcin     for (i = 0; i < ncolors; i++, k++) {
5682b8d69caSLisandro Dalcin       img->palette[k][0] = R[i];
5692b8d69caSLisandro Dalcin       img->palette[k][1] = G[i];
5702b8d69caSLisandro Dalcin       img->palette[k][2] = B[i];
5712b8d69caSLisandro Dalcin     }
5722b8d69caSLisandro Dalcin   }
5732b8d69caSLisandro Dalcin 
5749566063dSJacob Faibussowitsch   if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title));
5753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5762b8d69caSLisandro Dalcin }
5772b8d69caSLisandro Dalcin 
5782b8d69caSLisandro Dalcin /*@C
579811af0c4SBarry Smith    PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines.
5802b8d69caSLisandro Dalcin 
581d083f849SBarry Smith    Collective
5822b8d69caSLisandro Dalcin 
5832b8d69caSLisandro Dalcin    Input Parameters:
5842b8d69caSLisandro Dalcin +  comm - the communicator that will share image
585811af0c4SBarry Smith -  filename - optional name of the file where the image will be stored
5862b8d69caSLisandro Dalcin -  w, h - the image width and height in pixels
5872b8d69caSLisandro Dalcin 
5882b8d69caSLisandro Dalcin    Output Parameters:
5892b8d69caSLisandro Dalcin .  draw - the drawing context.
5902b8d69caSLisandro Dalcin 
5912b8d69caSLisandro Dalcin    Level: beginner
5922b8d69caSLisandro Dalcin 
593811af0c4SBarry Smith .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`
5942b8d69caSLisandro Dalcin @*/
595d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw)
596d71ae5a4SJacob Faibussowitsch {
5972b8d69caSLisandro Dalcin   PetscFunctionBegin;
5989566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw));
5999566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetType(*draw, PETSC_DRAW_IMAGE));
6009566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetSave(*draw, filename));
6013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6022b8d69caSLisandro Dalcin }
603