Actual source code: drawimage.c
1: #include <../src/sys/classes/draw/impls/image/drawimage.h>
2: #include <petsc/private/drawimpl.h>
3: #include <petscviewer.h>
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
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)))))
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))
19: static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr)
20: {
21: 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(PETSC_SUCCESS);
31: }
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
41: static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j)
42: {
43: PetscImage img = (PetscImage)draw->data;
45: PetscFunctionBegin;
46: if (i) *i = XTRANS(draw, img, x);
47: if (j) *j = YTRANS(draw, img, y);
48: PetscFunctionReturn(PETSC_SUCCESS);
49: }
51: static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y)
52: {
53: PetscImage img = (PetscImage)draw->data;
55: PetscFunctionBegin;
56: if (x) *x = ITRANS(draw, img, i);
57: if (y) *y = JTRANS(draw, img, j);
58: PetscFunctionReturn(PETSC_SUCCESS);
59: }
61: /*
62: static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
63: {
64: PetscFunctionBegin;
65: PetscFunctionReturn(PETSC_SUCCESS);
66: }*/
67: #define PetscDrawPointSetSize_Image NULL
69: static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c)
70: {
71: PetscImage img = (PetscImage)draw->data;
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: }
84: static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c)
85: {
86: PetscImage img = (PetscImage)draw->data;
88: PetscFunctionBegin;
89: PetscDrawValidColor(c);
90: {
91: PetscImageDrawPixel(img, x, y, c);
92: }
93: PetscFunctionReturn(PETSC_SUCCESS);
94: }
96: /*
97: static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
98: {
99: PetscFunctionBegin;
100: PetscFunctionReturn(PETSC_SUCCESS);
101: }*/
102: #define PetscDrawLineSetWidth_Image NULL
104: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width)
105: {
106: PetscImage img = (PetscImage)draw->data;
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: }
116: static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
117: {
118: PetscImage img = (PetscImage)draw->data;
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: }
129: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
130: {
131: PetscImage img = (PetscImage)draw->data;
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: }
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;
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: }
180: static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c)
181: {
182: PetscImage img = (PetscImage)draw->data;
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: }
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;
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: }
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
221: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h)
222: {
223: PetscImage img = (PetscImage)draw->data;
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: }
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: char *subtext;
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: }
258: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
259: {
260: PetscImage img = (PetscImage)draw->data;
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: }
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
287: /*
288: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
289: {
290: PetscFunctionBegin;
291: PetscFunctionReturn(PETSC_SUCCESS);
292: }*/
293: #define PetscDrawFlush_Image NULL
295: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
296: {
297: PetscImage img = (PetscImage)draw->data;
299: PetscFunctionBegin;
300: {
301: PetscImageClear(img);
302: }
303: PetscFunctionReturn(PETSC_SUCCESS);
304: }
306: /*
307: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
308: {
309: PetscFunctionBegin;
310: PetscFunctionReturn(PETSC_SUCCESS);
311: }*/
312: #define PetscDrawSetDoubleBuffer_Image NULL
314: static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup)
315: {
316: PetscBool flg = PETSC_FALSE;
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: }
332: /*
333: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
334: {
335: PetscFunctionBegin;
336: PetscFunctionReturn(PETSC_SUCCESS);
337: }*/
338: #define PetscDrawSetTitle_Image NULL
340: /*
341: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
342: {
343: PetscFunctionBegin;
344: PetscFunctionReturn(PETSC_SUCCESS);
345: }*/
346: #define PetscDrawCheckResizedWindow_Image NULL
348: static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h)
349: {
350: PetscImage img = (PetscImage)draw->data;
352: PetscFunctionBegin;
353: if (w == img->w && h == img->h) PetscFunctionReturn(PETSC_SUCCESS);
354: PetscCall(PetscFree(img->buffer));
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: }
363: static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
364: {
365: PetscImage img = (PetscImage)draw->data;
367: PetscFunctionBegin;
368: PetscCall(PetscDrawDestroy(&draw->popup));
369: PetscCall(PetscFree(img->buffer));
370: PetscCall(PetscFree(draw->data));
371: PetscFunctionReturn(PETSC_SUCCESS);
372: }
374: static PetscErrorCode PetscDrawView_Image(PetscDraw draw, PetscViewer viewer)
375: {
376: PetscBool iascii;
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: }
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
400: /*
401: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
402: {
403: PetscFunctionBegin;
404: PetscFunctionReturn(PETSC_SUCCESS);
405: }*/
406: #define PetscDrawPause_Image NULL
408: /*
409: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
410: {
411: PetscFunctionBegin;
412: PetscFunctionReturn(PETSC_SUCCESS);
413: }*/
414: #define PetscDrawBeginPage_Image NULL
416: /*
417: static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
418: {
419: PetscFunctionBegin;
420: PetscFunctionReturn(PETSC_SUCCESS);
421: }*/
422: #define PetscDrawEndPage_Image NULL
424: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
425: {
426: PetscImage pimg = (PetscImage)draw->data;
427: PetscImage simg;
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: }
438: static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
439: {
440: PetscImage pimg = (PetscImage)draw->data;
441: PetscImage simg = (PetscImage)(*sdraw)->data;
443: PetscFunctionBegin;
444: PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h));
445: PetscCall(PetscDrawDestroy(sdraw));
446: PetscFunctionReturn(PETSC_SUCCESS);
447: }
449: /*
450: static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
451: {
452: PetscFunctionBegin;
453: PetscFunctionReturn(PETSC_SUCCESS);
454: }*/
455: #define PetscDrawSave_Image NULL
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;
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: }
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};
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: };
520: /*MC
521: PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer
523: Options Database Keys:
524: . -draw_size w,h - size of image in pixels
526: Level: beginner
528: .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`
529: M*/
530: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);
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;
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;
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;
564: PetscCall(PetscNew(&img));
565: draw->ops[0] = DvOps;
566: draw->data = (void *)img;
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: }
590: if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title));
591: PetscFunctionReturn(PETSC_SUCCESS);
592: }
594: /*@
595: PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines.
597: Collective
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
605: Output Parameter:
606: . draw - the drawing context.
608: Level: beginner
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: }