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