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