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 %d out of range [0..255]", (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 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 } 32 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 40 41 static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j) 42 { 43 PetscImage img = (PetscImage)draw->data; 44 45 PetscFunctionBegin; 46 if (i) *i = XTRANS(draw, img, x); 47 if (j) *j = YTRANS(draw, img, y); 48 PetscFunctionReturn(PETSC_SUCCESS); 49 } 50 51 static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y) 52 { 53 PetscImage img = (PetscImage)draw->data; 54 55 PetscFunctionBegin; 56 if (x) *x = ITRANS(draw, img, i); 57 if (y) *y = JTRANS(draw, img, j); 58 PetscFunctionReturn(PETSC_SUCCESS); 59 } 60 61 /* 62 static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width) 63 { 64 PetscFunctionBegin; 65 PetscFunctionReturn(PETSC_SUCCESS); 66 }*/ 67 #define PetscDrawPointSetSize_Image NULL 68 69 static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c) 70 { 71 PetscImage img = (PetscImage)draw->data; 72 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 } 83 84 static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c) 85 { 86 PetscImage img = (PetscImage)draw->data; 87 88 PetscFunctionBegin; 89 PetscDrawValidColor(c); 90 { 91 PetscImageDrawPixel(img, x, y, c); 92 } 93 PetscFunctionReturn(PETSC_SUCCESS); 94 } 95 96 /* 97 static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width) 98 { 99 PetscFunctionBegin; 100 PetscFunctionReturn(PETSC_SUCCESS); 101 }*/ 102 #define PetscDrawLineSetWidth_Image NULL 103 104 static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width) 105 { 106 PetscImage img = (PetscImage)draw->data; 107 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 } 115 116 static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c) 117 { 118 PetscImage img = (PetscImage)draw->data; 119 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 } 128 129 static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c) 130 { 131 PetscImage img = (PetscImage)draw->data; 132 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 } 161 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; 165 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 } 179 180 static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c) 181 { 182 PetscImage img = (PetscImage)draw->data; 183 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 } 196 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; 200 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 } 212 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 220 221 static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h) 222 { 223 PetscImage img = (PetscImage)draw->data; 224 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 } 234 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 const char *subtext; 240 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 } 257 258 static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[]) 259 { 260 PetscImage img = (PetscImage)draw->data; 261 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 } 276 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 286 287 /* 288 static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw) 289 { 290 PetscFunctionBegin; 291 PetscFunctionReturn(PETSC_SUCCESS); 292 }*/ 293 #define PetscDrawFlush_Image NULL 294 295 static PetscErrorCode PetscDrawClear_Image(PetscDraw draw) 296 { 297 PetscImage img = (PetscImage)draw->data; 298 299 PetscFunctionBegin; 300 { 301 PetscImageClear(img); 302 } 303 PetscFunctionReturn(PETSC_SUCCESS); 304 } 305 306 /* 307 static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw) 308 { 309 PetscFunctionBegin; 310 PetscFunctionReturn(PETSC_SUCCESS); 311 }*/ 312 #define PetscDrawSetDoubleBuffer_Image NULL 313 314 static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup) 315 { 316 PetscBool flg = PETSC_FALSE; 317 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 } 331 332 /* 333 static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[]) 334 { 335 PetscFunctionBegin; 336 PetscFunctionReturn(PETSC_SUCCESS); 337 }*/ 338 #define PetscDrawSetTitle_Image NULL 339 340 /* 341 static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw) 342 { 343 PetscFunctionBegin; 344 PetscFunctionReturn(PETSC_SUCCESS); 345 }*/ 346 #define PetscDrawCheckResizedWindow_Image NULL 347 348 static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h) 349 { 350 PetscImage img = (PetscImage)draw->data; 351 352 PetscFunctionBegin; 353 if (w == img->w && h == img->h) PetscFunctionReturn(PETSC_SUCCESS); 354 PetscCall(PetscFree(img->buffer)); 355 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 } 362 363 static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw) 364 { 365 PetscImage img = (PetscImage)draw->data; 366 367 PetscFunctionBegin; 368 PetscCall(PetscDrawDestroy(&draw->popup)); 369 PetscCall(PetscFree(img->buffer)); 370 PetscCall(PetscFree(draw->data)); 371 PetscFunctionReturn(PETSC_SUCCESS); 372 } 373 374 static PetscErrorCode PetscDrawView_Image(PetscDraw draw, PetscViewer viewer) 375 { 376 PetscBool iascii; 377 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 } 386 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 399 400 /* 401 static PetscErrorCode PetscDrawPause_Image(PetscDraw draw) 402 { 403 PetscFunctionBegin; 404 PetscFunctionReturn(PETSC_SUCCESS); 405 }*/ 406 #define PetscDrawPause_Image NULL 407 408 /* 409 static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw) 410 { 411 PetscFunctionBegin; 412 PetscFunctionReturn(PETSC_SUCCESS); 413 }*/ 414 #define PetscDrawBeginPage_Image NULL 415 416 /* 417 static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw) 418 { 419 PetscFunctionBegin; 420 PetscFunctionReturn(PETSC_SUCCESS); 421 }*/ 422 #define PetscDrawEndPage_Image NULL 423 424 static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw) 425 { 426 PetscImage pimg = (PetscImage)draw->data; 427 PetscImage simg; 428 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 } 437 438 static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw) 439 { 440 PetscImage pimg = (PetscImage)draw->data; 441 PetscImage simg = (PetscImage)(*sdraw)->data; 442 443 PetscFunctionBegin; 444 PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h)); 445 PetscCall(PetscDrawDestroy(sdraw)); 446 PetscFunctionReturn(PETSC_SUCCESS); 447 } 448 449 /* 450 static PetscErrorCode PetscDrawSave_Image(PetscDraw draw) 451 { 452 PetscFunctionBegin; 453 PetscFunctionReturn(PETSC_SUCCESS); 454 }*/ 455 #define PetscDrawSave_Image NULL 456 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; 462 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 } 481 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}; 483 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 }; 519 520 /*MC 521 PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer 522 523 Options Database Keys: 524 . -draw_size w,h - size of image in pixels 525 526 Level: beginner 527 528 .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()` 529 M*/ 530 PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw); 531 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; 538 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; 549 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 PetscCall(PetscCIntCast(size[0], &w)); 559 PetscCall(PetscCIntCast(size[1], &h)); 560 draw->w = w; 561 draw->h = h; 562 draw->x = 0; 563 564 PetscCall(PetscNew(&img)); 565 draw->ops[0] = DvOps; 566 draw->data = (void *)img; 567 568 img->w = w; 569 img->h = h; 570 PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer)); 571 PetscImageSetClip(img, 0, 0, img->w, img->h); 572 { 573 int i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS; 574 unsigned char R[256 - PETSC_DRAW_BASIC_COLORS]; 575 unsigned char G[256 - PETSC_DRAW_BASIC_COLORS]; 576 unsigned char B[256 - PETSC_DRAW_BASIC_COLORS]; 577 PetscCall(PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B)); 578 for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) { 579 img->palette[k][0] = BasicColors[k][0]; 580 img->palette[k][1] = BasicColors[k][1]; 581 img->palette[k][2] = BasicColors[k][2]; 582 } 583 for (i = 0; i < ncolors; i++, k++) { 584 img->palette[k][0] = R[i]; 585 img->palette[k][1] = G[i]; 586 img->palette[k][2] = B[i]; 587 } 588 } 589 590 if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title)); 591 PetscFunctionReturn(PETSC_SUCCESS); 592 } 593 594 /*@ 595 PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines. 596 597 Collective 598 599 Input Parameters: 600 + comm - the communicator that will share image 601 . filename - optional name of the file where the image will be stored 602 . w - the image width in pixels 603 - h - the image height in pixels 604 605 Output Parameter: 606 . draw - the drawing context. 607 608 Level: beginner 609 610 .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()` 611 @*/ 612 PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw) 613 { 614 PetscFunctionBegin; 615 PetscCall(PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw)); 616 PetscCall(PetscDrawSetType(*draw, PETSC_DRAW_IMAGE)); 617 PetscCall(PetscDrawSetSave(*draw, filename)); 618 PetscFunctionReturn(PETSC_SUCCESS); 619 } 620