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