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: }