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