Actual source code: drawimage.c

  1: #include <../src/sys/classes/draw/impls/image/drawimage.h>
  2: #include <petsc/private/drawimpl.h>

  4: #if PetscDefined(USE_DEBUG)
  5:   #define PetscDrawValidColor(color) PetscCheck((color) >= 0 && (color) < 256, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Color value %d out of range [0..255]", (color))
  6: #else
  7:   #define PetscDrawValidColor(color) \
  8:     do { \
  9:     } while (0)
 10: #endif

 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)))))

 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))

 18: static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr)
 19: {
 20:   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: }

 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

 40: static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j)
 41: {
 42:   PetscImage img = (PetscImage)draw->data;

 44:   PetscFunctionBegin;
 45:   if (i) *i = XTRANS(draw, img, x);
 46:   if (j) *j = YTRANS(draw, img, y);
 47:   PetscFunctionReturn(PETSC_SUCCESS);
 48: }

 50: static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y)
 51: {
 52:   PetscImage img = (PetscImage)draw->data;

 54:   PetscFunctionBegin;
 55:   if (x) *x = ITRANS(draw, img, i);
 56:   if (y) *y = JTRANS(draw, img, j);
 57:   PetscFunctionReturn(PETSC_SUCCESS);
 58: }

 60: /*
 61: static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
 62: {
 63:   PetscFunctionBegin;
 64:   PetscFunctionReturn(PETSC_SUCCESS);
 65: }*/
 66: #define PetscDrawPointSetSize_Image NULL

 68: static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c)
 69: {
 70:   PetscImage img = (PetscImage)draw->data;

 72:   PetscFunctionBegin;
 73:   PetscDrawValidColor(c);
 74:   {
 75:     int j, xx = XTRANS(draw, img, x);
 76:     int i, yy = YTRANS(draw, img, y);
 77:     for (i = -1; i <= 1; i++)
 78:       for (j = -1; j <= 1; j++) PetscImageDrawPixel(img, xx + j, yy + i, c);
 79:   }
 80:   PetscFunctionReturn(PETSC_SUCCESS);
 81: }

 83: static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c)
 84: {
 85:   PetscImage img = (PetscImage)draw->data;

 87:   PetscFunctionBegin;
 88:   PetscDrawValidColor(c);
 89:   {
 90:     PetscImageDrawPixel(img, x, y, c);
 91:   }
 92:   PetscFunctionReturn(PETSC_SUCCESS);
 93: }

 95: /*
 96: static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
 97: {
 98:   PetscFunctionBegin;
 99:   PetscFunctionReturn(PETSC_SUCCESS);
100: }*/
101: #define PetscDrawLineSetWidth_Image NULL

103: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width)
104: {
105:   PetscImage img = (PetscImage)draw->data;

107:   PetscFunctionBegin;
108:   {
109:     int lw = 1;
110:     *width = lw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
111:   }
112:   PetscFunctionReturn(PETSC_SUCCESS);
113: }

115: static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
116: {
117:   PetscImage img = (PetscImage)draw->data;

119:   PetscFunctionBegin;
120:   {
121:     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
122:     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
123:     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
124:   }
125:   PetscFunctionReturn(PETSC_SUCCESS);
126: }

128: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
129: {
130:   PetscImage img = (PetscImage)draw->data;

132:   PetscFunctionBegin;
133:   PetscDrawValidColor(c);
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:     if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(PETSC_SUCCESS);
138:     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
139:     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
140:       if (y_2 > y_1) {
141:         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 - 3, c);
142:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
143:       } else {
144:         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 + 3, c);
145:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
146:       }
147:     }
148:     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
149:       if (x_2 > x_1) {
150:         PetscImageDrawLine(img, x_2 - 3, y_2 - 3, x_2, y_2, c);
151:         PetscImageDrawLine(img, x_2 - 3, y_2 + 3, x_2, y_2, c);
152:       } else {
153:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
154:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
155:       }
156:     }
157:   }
158:   PetscFunctionReturn(PETSC_SUCCESS);
159: }

161: static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4)
162: {
163:   PetscImage img = (PetscImage)draw->data;

165:   PetscFunctionBegin;
166:   PetscDrawValidColor(c1);
167:   PetscDrawValidColor(c2);
168:   PetscDrawValidColor(c3);
169:   PetscDrawValidColor(c4);
170:   {
171:     int x = XTRANS(draw, img, xl), w = XTRANS(draw, img, xr) + 1 - x;
172:     int y = YTRANS(draw, img, yr), h = YTRANS(draw, img, yl) + 1 - y;
173:     int c = (c1 + c2 + c3 + c4) / 4;
174:     PetscImageDrawRectangle(img, x, y, w, h, c);
175:   }
176:   PetscFunctionReturn(PETSC_SUCCESS);
177: }

179: static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c)
180: {
181:   PetscImage img = (PetscImage)draw->data;

183:   PetscFunctionBegin;
184:   PetscDrawValidColor(c);
185:   a = PetscAbsReal(a);
186:   b = PetscAbsReal(b);
187:   {
188:     int xc = XTRANS(draw, img, x), w = XTRANS(draw, img, x + a / 2) + 0 - xc;
189:     int yc = YTRANS(draw, img, y), h = YTRANS(draw, img, y - b / 2) + 0 - yc;
190:     if (PetscAbsReal(a - b) <= 0) w = h = PetscMin(w, h); /* workaround truncation errors */
191:     PetscImageDrawEllipse(img, xc, yc, w, h, c);
192:   }
193:   PetscFunctionReturn(PETSC_SUCCESS);
194: }

196: 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)
197: {
198:   PetscImage img = (PetscImage)draw->data;

200:   PetscFunctionBegin;
201:   PetscDrawValidColor(c1);
202:   PetscDrawValidColor(c2);
203:   PetscDrawValidColor(c3);
204:   {
205:     int x_1 = XTRANS(draw, img, X_1), x_2 = XTRANS(draw, img, X_2), x_3 = XTRANS(draw, img, X_3);
206:     int y_1 = YTRANS(draw, img, Y_1), y_2 = YTRANS(draw, img, Y_2), y_3 = YTRANS(draw, img, Y_3);
207:     PetscImageDrawTriangle(img, x_1, y_1, c1, x_2, y_2, c2, x_3, y_3, c3);
208:   }
209:   PetscFunctionReturn(PETSC_SUCCESS);
210: }

212: /*
213: static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
214: {
215:   PetscFunctionBegin;
216:   PetscFunctionReturn(PETSC_SUCCESS);
217: }*/
218: #define PetscDrawStringSetSize_Image NULL

220: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h)
221: {
222:   PetscImage img = (PetscImage)draw->data;

224:   PetscFunctionBegin;
225:   {
226:     int tw = PetscImageFontWidth;
227:     int th = PetscImageFontHeight;
228:     if (w) *w = tw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
229:     if (h) *h = th * (draw->coor_yr - draw->coor_yl) / (img->h * (draw->port_yr - draw->port_yl));
230:   }
231:   PetscFunctionReturn(PETSC_SUCCESS);
232: }

234: static PetscErrorCode PetscDrawString_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
235: {
236:   PetscImage  img = (PetscImage)draw->data;
237:   PetscToken  token;
238:   const char *subtext;

240:   PetscFunctionBegin;
241:   PetscDrawValidColor(c);
242:   {
243:     int xx = XTRANS(draw, img, x);
244:     int yy = YTRANS(draw, img, y);
245:     PetscCall(PetscTokenCreate(text, '\n', &token));
246:     PetscCall(PetscTokenFind(token, &subtext));
247:     while (subtext) {
248:       PetscImageDrawText(img, xx, yy, c, subtext);
249:       yy += PetscImageFontHeight;
250:       PetscCall(PetscTokenFind(token, &subtext));
251:     }
252:     PetscCall(PetscTokenDestroy(&token));
253:   }
254:   PetscFunctionReturn(PETSC_SUCCESS);
255: }

257: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
258: {
259:   PetscImage img = (PetscImage)draw->data;

261:   PetscFunctionBegin;
262:   PetscDrawValidColor(c);
263:   {
264:     char chr[2] = {0, 0};
265:     int  xx     = XTRANS(draw, img, x);
266:     int  yy     = YTRANS(draw, img, y);
267:     int  offset = PetscImageFontHeight;
268:     while ((chr[0] = *text++)) {
269:       PetscImageDrawText(img, xx, yy + offset, c, chr);
270:       yy += PetscImageFontHeight;
271:     }
272:   }
273:   PetscFunctionReturn(PETSC_SUCCESS);
274: }

276: /*
277: static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
278: {
279:   PetscFunctionBegin;
280:   if (w) *w = 0;
281:   if (h) *h = 0;
282:   PetscFunctionReturn(PETSC_SUCCESS);
283: */
284: #define PetscDrawStringBoxed_Image NULL

286: /*
287: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
288: {
289:   PetscFunctionBegin;
290:   PetscFunctionReturn(PETSC_SUCCESS);
291: }*/
292: #define PetscDrawFlush_Image NULL

294: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
295: {
296:   PetscImage img = (PetscImage)draw->data;

298:   PetscFunctionBegin;
299:   {
300:     PetscImageClear(img);
301:   }
302:   PetscFunctionReturn(PETSC_SUCCESS);
303: }

305: /*
306: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
307: {
308:   PetscFunctionBegin;
309:   PetscFunctionReturn(PETSC_SUCCESS);
310: }*/
311: #define PetscDrawSetDoubleBuffer_Image NULL

313: static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup)
314: {
315:   PetscBool flg = PETSC_FALSE;

317:   PetscFunctionBegin;
318:   PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL));
319:   if (!flg) {
320:     *popup = NULL;
321:     PetscFunctionReturn(PETSC_SUCCESS);
322:   }
323:   PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, 0, 0, 220, 220, popup));
324:   PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_IMAGE));
325:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
326:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*popup, ((PetscObject)draw)->prefix));
327:   draw->popup = *popup;
328:   PetscFunctionReturn(PETSC_SUCCESS);
329: }

331: /*
332: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
333: {
334:   PetscFunctionBegin;
335:   PetscFunctionReturn(PETSC_SUCCESS);
336: }*/
337: #define PetscDrawSetTitle_Image NULL

339: /*
340: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
341: {
342:   PetscFunctionBegin;
343:   PetscFunctionReturn(PETSC_SUCCESS);
344: }*/
345: #define PetscDrawCheckResizedWindow_Image NULL

347: static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h)
348: {
349:   PetscImage img = (PetscImage)draw->data;

351:   PetscFunctionBegin;
352:   if (w == img->w && h == img->h) PetscFunctionReturn(PETSC_SUCCESS);
353:   PetscCall(PetscFree(img->buffer));

355:   img->w = w;
356:   img->h = h;
357:   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
358:   PetscCall(PetscDrawSetViewport_Image(draw, draw->port_xl, draw->port_yl, draw->port_xr, draw->port_yr));
359:   PetscFunctionReturn(PETSC_SUCCESS);
360: }

362: static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
363: {
364:   PetscImage img = (PetscImage)draw->data;

366:   PetscFunctionBegin;
367:   PetscCall(PetscDrawDestroy(&draw->popup));
368:   PetscCall(PetscFree(img->buffer));
369:   PetscCall(PetscFree(draw->data));
370:   PetscFunctionReturn(PETSC_SUCCESS);
371: }

373: static PetscErrorCode PetscDrawView_Image(PetscDraw draw, PetscViewer viewer)
374: {
375:   PetscBool isascii;

377:   PetscFunctionBegin;
378:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
379:   if (isascii) {
380:     const char *filename = draw->savefilename ? draw->savefilename : draw->title;
381:     PetscCall(PetscViewerASCIIPrintf(viewer, "  Image file name %s\n", filename));
382:   }
383:   PetscFunctionReturn(PETSC_SUCCESS);
384: }

386: /*
387: static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
388: {
389:   PetscFunctionBegin;
390:   *button = PETSC_BUTTON_NONE;
391:   if (x_user) *x_user = 0;
392:   if (y_user) *y_user = 0;
393:   if (x_phys) *x_phys = 0;
394:   if (y_phys) *y_phys = 0;
395:   PetscFunctionReturn(PETSC_SUCCESS);
396: }*/
397: #define PetscDrawGetMouseButton_Image NULL

399: /*
400: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
401: {
402:   PetscFunctionBegin;
403:   PetscFunctionReturn(PETSC_SUCCESS);
404: }*/
405: #define PetscDrawPause_Image NULL

407: /*
408: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
409: {
410:   PetscFunctionBegin;
411:   PetscFunctionReturn(PETSC_SUCCESS);
412: }*/
413: #define PetscDrawBeginPage_Image NULL

415: /*
416: static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
417: {
418:   PetscFunctionBegin;
419:   PetscFunctionReturn(PETSC_SUCCESS);
420: }*/
421: #define PetscDrawEndPage_Image NULL

423: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
424: {
425:   PetscImage pimg = (PetscImage)draw->data;
426:   PetscImage simg;

428:   PetscFunctionBegin;
429:   PetscCall(PetscDrawCreate(PETSC_COMM_SELF, NULL, NULL, 0, 0, draw->w, draw->h, sdraw));
430:   PetscCall(PetscDrawSetType(*sdraw, PETSC_DRAW_IMAGE));
431:   (*sdraw)->ops->resizewindow = NULL;
432:   simg                        = (PetscImage)(*sdraw)->data;
433:   PetscCall(PetscArraycpy(simg->buffer, pimg->buffer, pimg->w * pimg->h));
434:   PetscFunctionReturn(PETSC_SUCCESS);
435: }

437: static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
438: {
439:   PetscImage pimg = (PetscImage)draw->data;
440:   PetscImage simg = (PetscImage)(*sdraw)->data;

442:   PetscFunctionBegin;
443:   PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h));
444:   PetscCall(PetscDrawDestroy(sdraw));
445:   PetscFunctionReturn(PETSC_SUCCESS);
446: }

448: /*
449: static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
450: {
451:   PetscFunctionBegin;
452:   PetscFunctionReturn(PETSC_SUCCESS);
453: }*/
454: #define PetscDrawSave_Image NULL

456: static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw, unsigned char palette[256][3], unsigned int *w, unsigned int *h, unsigned char *pixels[])
457: {
458:   PetscImage     img    = (PetscImage)draw->data;
459:   unsigned char *buffer = NULL;
460:   PetscMPIInt    rank, size;

462:   PetscFunctionBegin;
463:   if (w) *w = (unsigned int)img->w;
464:   if (h) *h = (unsigned int)img->h;
465:   if (pixels) *pixels = NULL;
466:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank));
467:   if (rank == 0) {
468:     PetscCall(PetscMemcpy(palette, img->palette, sizeof(img->palette)));
469:     PetscCall(PetscMalloc1((size_t)(img->w * img->h), &buffer));
470:     if (pixels) *pixels = buffer;
471:   }
472:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
473:   if (size == 1) {
474:     PetscCall(PetscArraycpy(buffer, img->buffer, img->w * img->h));
475:   } else {
476:     PetscCallMPI(MPI_Reduce(img->buffer, buffer, img->w * img->h, MPI_UNSIGNED_CHAR, MPI_MAX, 0, PetscObjectComm((PetscObject)draw)));
477:   }
478:   PetscFunctionReturn(PETSC_SUCCESS);
479: }

481: 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: static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
484:   {255, 255, 255}, /* white */
485:   {0,   0,   0  }, /* black */
486:   {255, 0,   0  }, /* red */
487:   {0,   255, 0  }, /* green */
488:   {0,   255, 255}, /* cyan */
489:   {0,   0,   255}, /* blue */
490:   {255, 0,   255}, /* magenta */
491:   {127, 255, 212}, /* aquamarine */
492:   {34,  139, 34 }, /* forestgreen */
493:   {255, 165, 0  }, /* orange */
494:   {238, 130, 238}, /* violet */
495:   {165, 42,  42 }, /* brown */
496:   {255, 192, 203}, /* pink */
497:   {255, 127, 80 }, /* coral */
498:   {190, 190, 190}, /* gray */
499:   {255, 255, 0  }, /* yellow */
500:   {255, 215, 0  }, /* gold */
501:   {255, 182, 193}, /* lightpink */
502:   {72,  209, 204}, /* mediumturquoise */
503:   {240, 230, 140}, /* khaki */
504:   {105, 105, 105}, /* dimgray */
505:   {54,  205, 50 }, /* yellowgreen */
506:   {135, 206, 235}, /* skyblue */
507:   {0,   100, 0  }, /* darkgreen */
508:   {0,   0,   128}, /* navyblue */
509:   {244, 164, 96 }, /* sandybrown */
510:   {95,  158, 160}, /* cadetblue */
511:   {176, 224, 230}, /* powderblue */
512:   {255, 20,  147}, /* deeppink */
513:   {216, 191, 216}, /* thistle */
514:   {50,  205, 50 }, /* limegreen */
515:   {255, 240, 245}, /* lavenderblush */
516:   {221, 160, 221}, /* plum */
517: };

519: /*MC
520:    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer

522:    Options Database Keys:
523: .  -draw_size w,h - size of image in pixels

525:    Level: beginner

527: .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`
528: M*/
529: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);

531: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
532: {
533:   PetscImage img;
534:   int        w = draw->w, h = draw->h;
535:   PetscInt   size[2], nsize = 2;
536:   PetscBool  set;

538:   PetscFunctionBegin;
539:   draw->pause   = 0;
540:   draw->coor_xl = 0;
541:   draw->coor_xr = 1;
542:   draw->coor_yl = 0;
543:   draw->coor_yr = 1;
544:   draw->port_xl = 0;
545:   draw->port_xr = 1;
546:   draw->port_yl = 0;
547:   draw->port_yr = 1;

549:   size[0] = w;
550:   if (size[0] < 1) size[0] = 300;
551:   size[1] = h;
552:   if (size[1] < 1) size[1] = size[0];
553:   PetscCall(PetscOptionsGetIntArray(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_size", size, &nsize, &set));
554:   if (set && nsize == 1) size[1] = size[0];
555:   if (size[0] < 1) size[0] = 300;
556:   if (size[1] < 1) size[1] = size[0];
557:   PetscCall(PetscCIntCast(size[0], &w));
558:   PetscCall(PetscCIntCast(size[1], &h));
559:   draw->w = w;
560:   draw->h = h;
561:   draw->x = 0;

563:   PetscCall(PetscNew(&img));
564:   draw->ops[0] = DvOps;
565:   draw->data   = (void *)img;

567:   img->w = w;
568:   img->h = h;
569:   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
570:   PetscImageSetClip(img, 0, 0, img->w, img->h);
571:   {
572:     int           i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS;
573:     unsigned char R[256 - PETSC_DRAW_BASIC_COLORS];
574:     unsigned char G[256 - PETSC_DRAW_BASIC_COLORS];
575:     unsigned char B[256 - PETSC_DRAW_BASIC_COLORS];
576:     PetscCall(PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B));
577:     for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) {
578:       img->palette[k][0] = BasicColors[k][0];
579:       img->palette[k][1] = BasicColors[k][1];
580:       img->palette[k][2] = BasicColors[k][2];
581:     }
582:     for (i = 0; i < ncolors; i++, k++) {
583:       img->palette[k][0] = R[i];
584:       img->palette[k][1] = G[i];
585:       img->palette[k][2] = B[i];
586:     }
587:   }

589:   if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title));
590:   PetscFunctionReturn(PETSC_SUCCESS);
591: }

593: /*@
594:   PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines.

596:   Collective

598:   Input Parameters:
599: + comm     - the communicator that will share image
600: . filename - optional name of the file where the image will be stored, the file extension determines the image format, see `PetscDrawSetSave()`
601: . w        - the image width in pixels
602: - h        - the image height in pixels

604:   Output Parameter:
605: . draw - the drawing context.

607:   Level: beginner

609:   Note:
610:   See `PetscDrawSetFromOptions()` for other options that may be set if that routine is also called.

612: .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`,
613:           `PetscDrawSave()`, `PetscDrawSetSaveMovie()`
614: @*/
615: PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw)
616: {
617:   PetscFunctionBegin;
618:   PetscCall(PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw));
619:   PetscCall(PetscDrawSetType(*draw, PETSC_DRAW_IMAGE));
620:   PetscCall(PetscDrawSetSave(*draw, filename));
621:   PetscFunctionReturn(PETSC_SUCCESS);
622: }