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