Actual source code: drawimage.c

      1: #include <../src/sys/classes/draw/impls/image/drawimage.h>
      2: #include <petsc/private/drawimpl.h>
      3: #include <petscviewer.h>

      5: #if defined(PETSC_USE_DEBUG)
      6:   #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))
      7: #else
      8:   #define PetscDrawValidColor(color) \
      9:     do { \
     10:     } while (0)
     11: #endif

     13: #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)))))
     14: #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)))))

     16: #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))
     17: #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))

     19: static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr)
     20: {
     21:   PetscImage img = (PetscImage)draw->data;

     23:   PetscFunctionBegin;
     24:   {
     25:     int xmax = img->w - 1, ymax = img->h - 1;
     26:     int xa = (int)(xl * xmax), ya = ymax - (int)(yr * ymax);
     27:     int xb = (int)(xr * xmax), yb = ymax - (int)(yl * ymax);
     28:     PetscImageSetClip(img, xa, ya, xb + 1 - xa, yb + 1 - ya);
     29:   }
     30:   PetscFunctionReturn(PETSC_SUCCESS);
     31: }

     33: /*
     34: static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
     35: {
     36:   PetscFunctionBegin;
     37:   PetscFunctionReturn(PETSC_SUCCESS);
     38: }*/
     39: #define PetscDrawSetCoordinates_Image NULL

     41: static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j)
     42: {
     43:   PetscImage img = (PetscImage)draw->data;

     45:   PetscFunctionBegin;
     46:   if (i) *i = XTRANS(draw, img, x);
     47:   if (j) *j = YTRANS(draw, img, y);
     48:   PetscFunctionReturn(PETSC_SUCCESS);
     49: }

     51: static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y)
     52: {
     53:   PetscImage img = (PetscImage)draw->data;

     55:   PetscFunctionBegin;
     56:   if (x) *x = ITRANS(draw, img, i);
     57:   if (y) *y = JTRANS(draw, img, j);
     58:   PetscFunctionReturn(PETSC_SUCCESS);
     59: }

     61: /*
     62: static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
     63: {
     64:   PetscFunctionBegin;
     65:   PetscFunctionReturn(PETSC_SUCCESS);
     66: }*/
     67: #define PetscDrawPointSetSize_Image NULL

     69: static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c)
     70: {
     71:   PetscImage img = (PetscImage)draw->data;

     73:   PetscFunctionBegin;
     74:   PetscDrawValidColor(c);
     75:   {
     76:     int j, xx = XTRANS(draw, img, x);
     77:     int i, yy = YTRANS(draw, img, y);
     78:     for (i = -1; i <= 1; i++)
     79:       for (j = -1; j <= 1; j++) PetscImageDrawPixel(img, xx + j, yy + i, c);
     80:   }
     81:   PetscFunctionReturn(PETSC_SUCCESS);
     82: }

     84: static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c)
     85: {
     86:   PetscImage img = (PetscImage)draw->data;

     88:   PetscFunctionBegin;
     89:   PetscDrawValidColor(c);
     90:   {
     91:     PetscImageDrawPixel(img, x, y, c);
     92:   }
     93:   PetscFunctionReturn(PETSC_SUCCESS);
     94: }

     96: /*
     97: static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
     98: {
     99:   PetscFunctionBegin;
    100:   PetscFunctionReturn(PETSC_SUCCESS);
    101: }*/
    102: #define PetscDrawLineSetWidth_Image NULL

    104: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width)
    105: {
    106:   PetscImage img = (PetscImage)draw->data;

    108:   PetscFunctionBegin;
    109:   {
    110:     int lw = 1;
    111:     *width = lw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
    112:   }
    113:   PetscFunctionReturn(PETSC_SUCCESS);
    114: }

    116: static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
    117: {
    118:   PetscImage img = (PetscImage)draw->data;

    120:   PetscFunctionBegin;
    121:   {
    122:     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
    123:     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
    124:     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
    125:   }
    126:   PetscFunctionReturn(PETSC_SUCCESS);
    127: }

    129: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
    130: {
    131:   PetscImage img = (PetscImage)draw->data;

    133:   PetscFunctionBegin;
    134:   PetscDrawValidColor(c);
    135:   {
    136:     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
    137:     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
    138:     if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(PETSC_SUCCESS);
    139:     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
    140:     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
    141:       if (y_2 > y_1) {
    142:         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 - 3, c);
    143:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
    144:       } else {
    145:         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 + 3, c);
    146:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
    147:       }
    148:     }
    149:     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
    150:       if (x_2 > x_1) {
    151:         PetscImageDrawLine(img, x_2 - 3, y_2 - 3, x_2, y_2, c);
    152:         PetscImageDrawLine(img, x_2 - 3, y_2 + 3, x_2, y_2, c);
    153:       } else {
    154:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
    155:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
    156:       }
    157:     }
    158:   }
    159:   PetscFunctionReturn(PETSC_SUCCESS);
    160: }

    162: static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4)
    163: {
    164:   PetscImage img = (PetscImage)draw->data;

    166:   PetscFunctionBegin;
    167:   PetscDrawValidColor(c1);
    168:   PetscDrawValidColor(c2);
    169:   PetscDrawValidColor(c3);
    170:   PetscDrawValidColor(c4);
    171:   {
    172:     int x = XTRANS(draw, img, xl), w = XTRANS(draw, img, xr) + 1 - x;
    173:     int y = YTRANS(draw, img, yr), h = YTRANS(draw, img, yl) + 1 - y;
    174:     int c = (c1 + c2 + c3 + c4) / 4;
    175:     PetscImageDrawRectangle(img, x, y, w, h, c);
    176:   }
    177:   PetscFunctionReturn(PETSC_SUCCESS);
    178: }

    180: static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c)
    181: {
    182:   PetscImage img = (PetscImage)draw->data;

    184:   PetscFunctionBegin;
    185:   PetscDrawValidColor(c);
    186:   a = PetscAbsReal(a);
    187:   b = PetscAbsReal(b);
    188:   {
    189:     int xc = XTRANS(draw, img, x), w = XTRANS(draw, img, x + a / 2) + 0 - xc;
    190:     int yc = YTRANS(draw, img, y), h = YTRANS(draw, img, y - b / 2) + 0 - yc;
    191:     if (PetscAbsReal(a - b) <= 0) w = h = PetscMin(w, h); /* workaround truncation errors */
    192:     PetscImageDrawEllipse(img, xc, yc, w, h, c);
    193:   }
    194:   PetscFunctionReturn(PETSC_SUCCESS);
    195: }

    197: 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)
    198: {
    199:   PetscImage img = (PetscImage)draw->data;

    201:   PetscFunctionBegin;
    202:   PetscDrawValidColor(c1);
    203:   PetscDrawValidColor(c2);
    204:   PetscDrawValidColor(c3);
    205:   {
    206:     int x_1 = XTRANS(draw, img, X_1), x_2 = XTRANS(draw, img, X_2), x_3 = XTRANS(draw, img, X_3);
    207:     int y_1 = YTRANS(draw, img, Y_1), y_2 = YTRANS(draw, img, Y_2), y_3 = YTRANS(draw, img, Y_3);
    208:     PetscImageDrawTriangle(img, x_1, y_1, c1, x_2, y_2, c2, x_3, y_3, c3);
    209:   }
    210:   PetscFunctionReturn(PETSC_SUCCESS);
    211: }

    213: /*
    214: static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
    215: {
    216:   PetscFunctionBegin;
    217:   PetscFunctionReturn(PETSC_SUCCESS);
    218: }*/
    219: #define PetscDrawStringSetSize_Image NULL

    221: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h)
    222: {
    223:   PetscImage img = (PetscImage)draw->data;

    225:   PetscFunctionBegin;
    226:   {
    227:     int tw = PetscImageFontWidth;
    228:     int th = PetscImageFontHeight;
    229:     if (w) *w = tw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
    230:     if (h) *h = th * (draw->coor_yr - draw->coor_yl) / (img->h * (draw->port_yr - draw->port_yl));
    231:   }
    232:   PetscFunctionReturn(PETSC_SUCCESS);
    233: }

    235: static PetscErrorCode PetscDrawString_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
    236: {
    237:   PetscImage img = (PetscImage)draw->data;
    238:   PetscToken token;
    239:   char      *subtext;

    241:   PetscFunctionBegin;
    242:   PetscDrawValidColor(c);
    243:   {
    244:     int xx = XTRANS(draw, img, x);
    245:     int yy = YTRANS(draw, img, y);
    246:     PetscCall(PetscTokenCreate(text, '\n', &token));
    247:     PetscCall(PetscTokenFind(token, &subtext));
    248:     while (subtext) {
    249:       PetscImageDrawText(img, xx, yy, c, subtext);
    250:       yy += PetscImageFontHeight;
    251:       PetscCall(PetscTokenFind(token, &subtext));
    252:     }
    253:     PetscCall(PetscTokenDestroy(&token));
    254:   }
    255:   PetscFunctionReturn(PETSC_SUCCESS);
    256: }

    258: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
    259: {
    260:   PetscImage img = (PetscImage)draw->data;

    262:   PetscFunctionBegin;
    263:   PetscDrawValidColor(c);
    264:   {
    265:     char chr[2] = {0, 0};
    266:     int  xx     = XTRANS(draw, img, x);
    267:     int  yy     = YTRANS(draw, img, y);
    268:     int  offset = PetscImageFontHeight;
    269:     while ((chr[0] = *text++)) {
    270:       PetscImageDrawText(img, xx, yy + offset, c, chr);
    271:       yy += PetscImageFontHeight;
    272:     }
    273:   }
    274:   PetscFunctionReturn(PETSC_SUCCESS);
    275: }

    277: /*
    278: static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
    279: {
    280:   PetscFunctionBegin;
    281:   if (w) *w = 0;
    282:   if (h) *h = 0;
    283:   PetscFunctionReturn(PETSC_SUCCESS);
    284: */
    285: #define PetscDrawStringBoxed_Image NULL

    287: /*
    288: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
    289: {
    290:   PetscFunctionBegin;
    291:   PetscFunctionReturn(PETSC_SUCCESS);
    292: }*/
    293: #define PetscDrawFlush_Image NULL

    295: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
    296: {
    297:   PetscImage img = (PetscImage)draw->data;

    299:   PetscFunctionBegin;
    300:   {
    301:     PetscImageClear(img);
    302:   }
    303:   PetscFunctionReturn(PETSC_SUCCESS);
    304: }

    306: /*
    307: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
    308: {
    309:   PetscFunctionBegin;
    310:   PetscFunctionReturn(PETSC_SUCCESS);
    311: }*/
    312: #define PetscDrawSetDoubleBuffer_Image NULL

    314: static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup)
    315: {
    316:   PetscBool flg = PETSC_FALSE;

    318:   PetscFunctionBegin;
    319:   PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL));
    320:   if (!flg) {
    321:     *popup = NULL;
    322:     PetscFunctionReturn(PETSC_SUCCESS);
    323:   }
    324:   PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, 0, 0, 220, 220, popup));
    325:   PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_IMAGE));
    326:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
    327:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*popup, ((PetscObject)draw)->prefix));
    328:   draw->popup = *popup;
    329:   PetscFunctionReturn(PETSC_SUCCESS);
    330: }

    332: /*
    333: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
    334: {
    335:   PetscFunctionBegin;
    336:   PetscFunctionReturn(PETSC_SUCCESS);
    337: }*/
    338: #define PetscDrawSetTitle_Image NULL

    340: /*
    341: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
    342: {
    343:   PetscFunctionBegin;
    344:   PetscFunctionReturn(PETSC_SUCCESS);
    345: }*/
    346: #define PetscDrawCheckResizedWindow_Image NULL

    348: static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h)
    349: {
    350:   PetscImage img = (PetscImage)draw->data;

    352:   PetscFunctionBegin;
    353:   if (w == img->w && h == img->h) PetscFunctionReturn(PETSC_SUCCESS);
    354:   PetscCall(PetscFree(img->buffer));

    356:   img->w = w;
    357:   img->h = h;
    358:   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
    359:   PetscCall(PetscDrawSetViewport_Image(draw, draw->port_xl, draw->port_yl, draw->port_xr, draw->port_yr));
    360:   PetscFunctionReturn(PETSC_SUCCESS);
    361: }

    363: static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
    364: {
    365:   PetscImage img = (PetscImage)draw->data;

    367:   PetscFunctionBegin;
    368:   PetscCall(PetscDrawDestroy(&draw->popup));
    369:   PetscCall(PetscFree(img->buffer));
    370:   PetscCall(PetscFree(draw->data));
    371:   PetscFunctionReturn(PETSC_SUCCESS);
    372: }

    374: static PetscErrorCode PetscDrawView_Image(PetscDraw draw, PetscViewer viewer)
    375: {
    376:   PetscBool iascii;

    378:   PetscFunctionBegin;
    379:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
    380:   if (iascii) {
    381:     const char *filename = draw->savefilename ? draw->savefilename : draw->title;
    382:     PetscCall(PetscViewerASCIIPrintf(viewer, "  Image file name %s\n", filename));
    383:   }
    384:   PetscFunctionReturn(PETSC_SUCCESS);
    385: }

    387: /*
    388: static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
    389: {
    390:   PetscFunctionBegin;
    391:   *button = PETSC_BUTTON_NONE;
    392:   if (x_user) *x_user = 0;
    393:   if (y_user) *y_user = 0;
    394:   if (x_phys) *x_phys = 0;
    395:   if (y_phys) *y_phys = 0;
    396:   PetscFunctionReturn(PETSC_SUCCESS);
    397: }*/
    398: #define PetscDrawGetMouseButton_Image NULL

    400: /*
    401: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
    402: {
    403:   PetscFunctionBegin;
    404:   PetscFunctionReturn(PETSC_SUCCESS);
    405: }*/
    406: #define PetscDrawPause_Image NULL

    408: /*
    409: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
    410: {
    411:   PetscFunctionBegin;
    412:   PetscFunctionReturn(PETSC_SUCCESS);
    413: }*/
    414: #define PetscDrawBeginPage_Image NULL

    416: /*
    417: static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
    418: {
    419:   PetscFunctionBegin;
    420:   PetscFunctionReturn(PETSC_SUCCESS);
    421: }*/
    422: #define PetscDrawEndPage_Image NULL

    424: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
    425: {
    426:   PetscImage pimg = (PetscImage)draw->data;
    427:   PetscImage simg;

    429:   PetscFunctionBegin;
    430:   PetscCall(PetscDrawCreate(PETSC_COMM_SELF, NULL, NULL, 0, 0, draw->w, draw->h, sdraw));
    431:   PetscCall(PetscDrawSetType(*sdraw, PETSC_DRAW_IMAGE));
    432:   (*sdraw)->ops->resizewindow = NULL;
    433:   simg                        = (PetscImage)(*sdraw)->data;
    434:   PetscCall(PetscArraycpy(simg->buffer, pimg->buffer, pimg->w * pimg->h));
    435:   PetscFunctionReturn(PETSC_SUCCESS);
    436: }

    438: static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
    439: {
    440:   PetscImage pimg = (PetscImage)draw->data;
    441:   PetscImage simg = (PetscImage)(*sdraw)->data;

    443:   PetscFunctionBegin;
    444:   PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h));
    445:   PetscCall(PetscDrawDestroy(sdraw));
    446:   PetscFunctionReturn(PETSC_SUCCESS);
    447: }

    449: /*
    450: static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
    451: {
    452:   PetscFunctionBegin;
    453:   PetscFunctionReturn(PETSC_SUCCESS);
    454: }*/
    455: #define PetscDrawSave_Image NULL

    457: static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw, unsigned char palette[256][3], unsigned int *w, unsigned int *h, unsigned char *pixels[])
    458: {
    459:   PetscImage     img    = (PetscImage)draw->data;
    460:   unsigned char *buffer = NULL;
    461:   PetscMPIInt    rank, size;

    463:   PetscFunctionBegin;
    464:   if (w) *w = (unsigned int)img->w;
    465:   if (h) *h = (unsigned int)img->h;
    466:   if (pixels) *pixels = NULL;
    467:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank));
    468:   if (rank == 0) {
    469:     PetscCall(PetscMemcpy(palette, img->palette, sizeof(img->palette)));
    470:     PetscCall(PetscMalloc1((size_t)(img->w * img->h), &buffer));
    471:     if (pixels) *pixels = buffer;
    472:   }
    473:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
    474:   if (size == 1) {
    475:     PetscCall(PetscArraycpy(buffer, img->buffer, img->w * img->h));
    476:   } else {
    477:     PetscCallMPI(MPI_Reduce(img->buffer, buffer, img->w * img->h, MPI_UNSIGNED_CHAR, MPI_MAX, 0, PetscObjectComm((PetscObject)draw)));
    478:   }
    479:   PetscFunctionReturn(PETSC_SUCCESS);
    480: }

    482: 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};

    484: static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
    485:   {255, 255, 255}, /* white */
    486:   {0,   0,   0  }, /* black */
    487:   {255, 0,   0  }, /* red */
    488:   {0,   255, 0  }, /* green */
    489:   {0,   255, 255}, /* cyan */
    490:   {0,   0,   255}, /* blue */
    491:   {255, 0,   255}, /* magenta */
    492:   {127, 255, 212}, /* aquamarine */
    493:   {34,  139, 34 }, /* forestgreen */
    494:   {255, 165, 0  }, /* orange */
    495:   {238, 130, 238}, /* violet */
    496:   {165, 42,  42 }, /* brown */
    497:   {255, 192, 203}, /* pink */
    498:   {255, 127, 80 }, /* coral */
    499:   {190, 190, 190}, /* gray */
    500:   {255, 255, 0  }, /* yellow */
    501:   {255, 215, 0  }, /* gold */
    502:   {255, 182, 193}, /* lightpink */
    503:   {72,  209, 204}, /* mediumturquoise */
    504:   {240, 230, 140}, /* khaki */
    505:   {105, 105, 105}, /* dimgray */
    506:   {54,  205, 50 }, /* yellowgreen */
    507:   {135, 206, 235}, /* skyblue */
    508:   {0,   100, 0  }, /* darkgreen */
    509:   {0,   0,   128}, /* navyblue */
    510:   {244, 164, 96 }, /* sandybrown */
    511:   {95,  158, 160}, /* cadetblue */
    512:   {176, 224, 230}, /* powderblue */
    513:   {255, 20,  147}, /* deeppink */
    514:   {216, 191, 216}, /* thistle */
    515:   {50,  205, 50 }, /* limegreen */
    516:   {255, 240, 245}, /* lavenderblush */
    517:   {221, 160, 221}, /* plum */
    518: };

    520: /*MC
    521:    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer

    523:    Options Database Keys:
    524: .  -draw_size w,h - size of image in pixels

    526:    Level: beginner

    528: .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`
    529: M*/
    530: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);

    532: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
    533: {
    534:   PetscImage img;
    535:   int        w = draw->w, h = draw->h;
    536:   PetscInt   size[2], nsize = 2;
    537:   PetscBool  set;

    539:   PetscFunctionBegin;
    540:   draw->pause   = 0;
    541:   draw->coor_xl = 0;
    542:   draw->coor_xr = 1;
    543:   draw->coor_yl = 0;
    544:   draw->coor_yr = 1;
    545:   draw->port_xl = 0;
    546:   draw->port_xr = 1;
    547:   draw->port_yl = 0;
    548:   draw->port_yr = 1;

    550:   size[0] = w;
    551:   if (size[0] < 1) size[0] = 300;
    552:   size[1] = h;
    553:   if (size[1] < 1) size[1] = size[0];
    554:   PetscCall(PetscOptionsGetIntArray(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_size", size, &nsize, &set));
    555:   if (set && nsize == 1) size[1] = size[0];
    556:   if (size[0] < 1) size[0] = 300;
    557:   if (size[1] < 1) size[1] = size[0];
    558:   draw->w = w = (int)size[0];
    559:   draw->x     = 0;
    560:   draw->h = h = (int)size[1];
    561:   draw->x     = 0;

    563:   PetscCall(PetscNew(&img));
    564:   draw->ops[0] = DvOps;
    565:   draw->data   = (void *)img;

    567:   img->w = w;
    568:   img->h = h;
    569:   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
    570:   PetscImageSetClip(img, 0, 0, img->w, img->h);
    571:   {
    572:     int           i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS;
    573:     unsigned char R[256 - PETSC_DRAW_BASIC_COLORS];
    574:     unsigned char G[256 - PETSC_DRAW_BASIC_COLORS];
    575:     unsigned char B[256 - PETSC_DRAW_BASIC_COLORS];
    576:     PetscCall(PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B));
    577:     for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) {
    578:       img->palette[k][0] = BasicColors[k][0];
    579:       img->palette[k][1] = BasicColors[k][1];
    580:       img->palette[k][2] = BasicColors[k][2];
    581:     }
    582:     for (i = 0; i < ncolors; i++, k++) {
    583:       img->palette[k][0] = R[i];
    584:       img->palette[k][1] = G[i];
    585:       img->palette[k][2] = B[i];
    586:     }
    587:   }

    589:   if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title));
    590:   PetscFunctionReturn(PETSC_SUCCESS);
    591: }

    593: /*@
    594:   PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines.

    596:   Collective

    598:   Input Parameters:
    599: + comm     - the communicator that will share image
    600: . filename - optional name of the file where the image will be stored
    601: . w        - the image width in pixels
    602: - h        - the image height in pixels

    604:   Output Parameter:
    605: . draw - the drawing context.

    607:   Level: beginner

    609: .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`
    610: @*/
    611: PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw)
    612: {
    613:   PetscFunctionBegin;
    614:   PetscCall(PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw));
    615:   PetscCall(PetscDrawSetType(*draw, PETSC_DRAW_IMAGE));
    616:   PetscCall(PetscDrawSetSave(*draw, filename));
    617:   PetscFunctionReturn(PETSC_SUCCESS);
    618: }