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