xref: /petsc/src/sys/classes/draw/impls/image/drawimage.h (revision d8e47b638cf8f604a99e9678e1df24f82d959cd7)
1a4963045SJacob Faibussowitsch #pragma once
22b8d69caSLisandro Dalcin 
32b8d69caSLisandro Dalcin #include <petscdraw.h>
42b8d69caSLisandro Dalcin 
52b8d69caSLisandro Dalcin typedef struct _n_PetscImage *PetscImage;
62b8d69caSLisandro Dalcin typedef struct _n_PetscImage {
72b8d69caSLisandro Dalcin   unsigned char *buffer;          /* raster buffer  */
82b8d69caSLisandro Dalcin   int            w, h;            /* width, height  */
92b8d69caSLisandro Dalcin   int            clip[4];         /* clip ranges    */
102b8d69caSLisandro Dalcin   unsigned char  palette[256][3]; /* colormap       */
112b8d69caSLisandro Dalcin } _n_PetscImage;
122b8d69caSLisandro Dalcin 
PetscImageSetClip(PetscImage img,int x,int y,int w,int h)13d71ae5a4SJacob Faibussowitsch static inline void PetscImageSetClip(PetscImage img, int x, int y, int w, int h)
14d71ae5a4SJacob Faibussowitsch {
152b8d69caSLisandro Dalcin   img->clip[0] = PetscClipInterval(x, 0, img->w - 1); /* xmin   */
162b8d69caSLisandro Dalcin   img->clip[1] = PetscClipInterval(y, 0, img->h - 1); /* ymin   */
172b8d69caSLisandro Dalcin   img->clip[2] = PetscClipInterval(x + w, 0, img->w); /* xmax+1 */
182b8d69caSLisandro Dalcin   img->clip[3] = PetscClipInterval(y + h, 0, img->h); /* ymax+1 */
192b8d69caSLisandro Dalcin }
202b8d69caSLisandro Dalcin 
PetscImageClear(PetscImage img)21d71ae5a4SJacob Faibussowitsch static inline void PetscImageClear(PetscImage img)
22d71ae5a4SJacob Faibussowitsch {
232b8d69caSLisandro Dalcin   int x, xs = img->clip[0], xe = img->clip[2];
242b8d69caSLisandro Dalcin   int y, ys = img->clip[1], ye = img->clip[3];
252b8d69caSLisandro Dalcin   for (y = ys; y < ye; y++)
269371c9d4SSatish Balay     for (x = xs; x < xe; x++) img->buffer[y * img->w + x] = 0;
272b8d69caSLisandro Dalcin }
282b8d69caSLisandro Dalcin 
PetscImageDrawPixel(PetscImage img,int x,int y,int c)29d71ae5a4SJacob Faibussowitsch static inline void PetscImageDrawPixel(PetscImage img, int x, int y, int c)
30d71ae5a4SJacob Faibussowitsch {
312b8d69caSLisandro Dalcin   if (x < img->clip[0] || x >= img->clip[2]) return;
322b8d69caSLisandro Dalcin   if (y < img->clip[1] || y >= img->clip[3]) return;
332b8d69caSLisandro Dalcin   img->buffer[y * img->w + x] = (unsigned char)c;
342b8d69caSLisandro Dalcin }
352b8d69caSLisandro Dalcin 
PetscImageDrawLine(PetscImage img,int x_1,int y_1,int x_2,int y_2,int c)36d71ae5a4SJacob Faibussowitsch static inline void PetscImageDrawLine(PetscImage img, int x_1, int y_1, int x_2, int y_2, int c)
37d71ae5a4SJacob Faibussowitsch {
382b8d69caSLisandro Dalcin   if (y_1 == y_2) {
392b8d69caSLisandro Dalcin     /* Horizontal line */
409371c9d4SSatish Balay     if (x_2 - x_1 < 0) {
419371c9d4SSatish Balay       int tmp = x_1;
429371c9d4SSatish Balay       x_1     = x_2;
439371c9d4SSatish Balay       x_2     = tmp;
449371c9d4SSatish Balay     }
452b8d69caSLisandro Dalcin     while (x_1 <= x_2) PetscImageDrawPixel(img, x_1++, y_1, c);
462b8d69caSLisandro Dalcin   } else if (x_1 == x_2) {
472b8d69caSLisandro Dalcin     /* Vertical line */
489371c9d4SSatish Balay     if (y_2 - y_1 < 0) {
499371c9d4SSatish Balay       int tmp = y_1;
509371c9d4SSatish Balay       y_1     = y_2;
519371c9d4SSatish Balay       y_2     = tmp;
529371c9d4SSatish Balay     }
532b8d69caSLisandro Dalcin     while (y_1 <= y_2) PetscImageDrawPixel(img, x_1, y_1++, c);
542b8d69caSLisandro Dalcin   } else {
552b8d69caSLisandro Dalcin     /* Bresenham's line drawing algorithm */
562b8d69caSLisandro Dalcin     int dx = PetscAbs(x_2 - x_1), sx = (x_2 - x_1) >= 0 ? +1 : -1;
572b8d69caSLisandro Dalcin     int dy = PetscAbs(y_2 - y_1), sy = (y_2 - y_1) >= 0 ? +1 : -1;
582b8d69caSLisandro Dalcin     int error = (dx > dy ? dx : -dy) / 2, err;
592b8d69caSLisandro Dalcin     while (1) {
602b8d69caSLisandro Dalcin       PetscImageDrawPixel(img, x_1, y_1, c);
612b8d69caSLisandro Dalcin       if (x_1 == x_2 && y_1 == y_2) break;
622b8d69caSLisandro Dalcin       err = error;
639371c9d4SSatish Balay       if (err > -dx) {
649371c9d4SSatish Balay         error -= dy;
659371c9d4SSatish Balay         x_1 += sx;
669371c9d4SSatish Balay       }
679371c9d4SSatish Balay       if (err < +dy) {
689371c9d4SSatish Balay         error += dx;
699371c9d4SSatish Balay         y_1 += sy;
709371c9d4SSatish Balay       }
712b8d69caSLisandro Dalcin     }
722b8d69caSLisandro Dalcin   }
732b8d69caSLisandro Dalcin }
742b8d69caSLisandro Dalcin 
PetscImageDrawRectangle(PetscImage img,int x,int y,int w,int h,int c)75d71ae5a4SJacob Faibussowitsch static inline void PetscImageDrawRectangle(PetscImage img, int x, int y, int w, int h, int c)
76d71ae5a4SJacob Faibussowitsch {
772b8d69caSLisandro Dalcin   int xs = PetscMax(x, img->clip[0]), xe = PetscMin(x + w, img->clip[2]);
782b8d69caSLisandro Dalcin   int ys = PetscMax(y, img->clip[1]), ye = PetscMin(y + h, img->clip[3]);
792b8d69caSLisandro Dalcin   if (xs >= xe || ys >= ye) return;
802b8d69caSLisandro Dalcin   for (y = ys; y < ye; y++)
819371c9d4SSatish Balay     for (x = xs; x < xe; x++) img->buffer[y * img->w + x] = (unsigned char)c;
822b8d69caSLisandro Dalcin }
832b8d69caSLisandro Dalcin 
PetscImageDrawEllipse(PetscImage img,int xc,int yc,int w,int h,int c)84d71ae5a4SJacob Faibussowitsch static inline void PetscImageDrawEllipse(PetscImage img, int xc, int yc, int w, int h, int c)
85d71ae5a4SJacob Faibussowitsch {
862b8d69caSLisandro Dalcin   /* Bresenham's circle/ellipse drawing algorithm */
872b8d69caSLisandro Dalcin   int x, y, s, a2 = w * w, b2 = h * h;
882b8d69caSLisandro Dalcin   for (x = 0, y = h, s = 2 * b2 + a2 * (1 - 2 * h); b2 * x <= a2 * y; x++) {
892b8d69caSLisandro Dalcin     PetscImageDrawLine(img, xc + x, yc + y, xc - x, yc + y, c);
902b8d69caSLisandro Dalcin     PetscImageDrawLine(img, xc + x, yc - y, xc - x, yc - y, c);
919371c9d4SSatish Balay     if (s >= 0) {
929371c9d4SSatish Balay       s += 4 * a2 * (1 - y);
939371c9d4SSatish Balay       y--;
949371c9d4SSatish Balay     }
952b8d69caSLisandro Dalcin     s += b2 * ((4 * x) + 6);
962b8d69caSLisandro Dalcin   }
972b8d69caSLisandro Dalcin   for (x = w, y = 0, s = 2 * a2 + b2 * (1 - 2 * w); a2 * y <= b2 * x; y++) {
982b8d69caSLisandro Dalcin     PetscImageDrawLine(img, xc + x, yc + y, xc - x, yc + y, c);
992b8d69caSLisandro Dalcin     PetscImageDrawLine(img, xc + x, yc - y, xc - x, yc - y, c);
1009371c9d4SSatish Balay     if (s >= 0) {
1019371c9d4SSatish Balay       s += 4 * b2 * (1 - x);
1029371c9d4SSatish Balay       x--;
1039371c9d4SSatish Balay     }
1042b8d69caSLisandro Dalcin     s += a2 * ((4 * y) + 6);
1052b8d69caSLisandro Dalcin   }
1062b8d69caSLisandro Dalcin }
1072b8d69caSLisandro Dalcin 
PetscImageDrawTriangle(PetscImage img,int x_1,int y_1,int t_1,int x_2,int y_2,int t_2,int x_3,int y_3,int t_3)108d71ae5a4SJacob Faibussowitsch static inline void PetscImageDrawTriangle(PetscImage img, int x_1, int y_1, int t_1, int x_2, int y_2, int t_2, int x_3, int y_3, int t_3)
109d71ae5a4SJacob Faibussowitsch {
1102b8d69caSLisandro Dalcin   const int SHIFT_VAL = 6;
1112b8d69caSLisandro Dalcin   const int xmin = img->clip[0], xmax = img->clip[2] - 1;
1122b8d69caSLisandro Dalcin   const int ymin = img->clip[1], ymax = img->clip[3] - 1;
1132b8d69caSLisandro Dalcin   float     rfrac, lfrac, one = 1;
1142b8d69caSLisandro Dalcin   float     R_y2_y1, R_y3_y1, R_y3_y2;
1152b8d69caSLisandro Dalcin   int       lc, rc = 0, lx, rx = 0, xx, y, c;
1162b8d69caSLisandro Dalcin   int       rc_lc, rx_lx, t2_t1, x2_x1, t3_t1, x3_x1, t3_t2, x3_x2;
1172b8d69caSLisandro Dalcin 
1182b8d69caSLisandro Dalcin   /* Is triangle ever visible in image? */
1192b8d69caSLisandro Dalcin   if (x_1 < xmin && x_2 < xmin && x_3 < xmin) return;
1202b8d69caSLisandro Dalcin   if (y_1 < ymin && y_2 < ymin && y_3 < ymin) return;
1212b8d69caSLisandro Dalcin   if (x_1 > xmax && x_2 > xmax && x_3 > xmax) return;
1222b8d69caSLisandro Dalcin   if (y_1 > ymax && y_2 > ymax && y_3 > ymax) return;
1232b8d69caSLisandro Dalcin 
1242b8d69caSLisandro Dalcin   t_1 = t_1 << SHIFT_VAL;
1252b8d69caSLisandro Dalcin   t_2 = t_2 << SHIFT_VAL;
1262b8d69caSLisandro Dalcin   t_3 = t_3 << SHIFT_VAL;
1272b8d69caSLisandro Dalcin 
1282b8d69caSLisandro Dalcin   /* Sort the vertices */
1299371c9d4SSatish Balay #define SWAP(a, b) \
1309371c9d4SSatish Balay   do { \
1319371c9d4SSatish Balay     int _tmp; \
1329371c9d4SSatish Balay     _tmp = a; \
1339371c9d4SSatish Balay     a    = b; \
1349371c9d4SSatish Balay     b    = _tmp; \
1359371c9d4SSatish Balay   } while (0)
1369371c9d4SSatish Balay   if (y_1 > y_2) {
1379371c9d4SSatish Balay     SWAP(x_1, x_2);
1389371c9d4SSatish Balay     SWAP(y_1, y_2);
1399371c9d4SSatish Balay     SWAP(t_1, t_2);
1409371c9d4SSatish Balay   }
1419371c9d4SSatish Balay   if (y_1 > y_3) {
1429371c9d4SSatish Balay     SWAP(x_1, x_3);
1439371c9d4SSatish Balay     SWAP(y_1, y_3);
1449371c9d4SSatish Balay     SWAP(t_1, t_3);
1459371c9d4SSatish Balay   }
1469371c9d4SSatish Balay   if (y_2 > y_3) {
1479371c9d4SSatish Balay     SWAP(x_2, x_3);
1489371c9d4SSatish Balay     SWAP(y_2, y_3);
1499371c9d4SSatish Balay     SWAP(t_2, t_3);
1509371c9d4SSatish Balay   }
1512b8d69caSLisandro Dalcin #undef SWAP
1522b8d69caSLisandro Dalcin 
153da81f932SPierre Jolivet   /* This code is decidedly non-optimal;
1542b8d69caSLisandro Dalcin    it is intended to be a start at an implementation */
1552b8d69caSLisandro Dalcin 
1562b8d69caSLisandro Dalcin   t2_t1   = t_2 - t_1;
1572b8d69caSLisandro Dalcin   x2_x1   = x_2 - x_1;
158*6497c311SBarry Smith   R_y2_y1 = (y_2 != y_1) ? one / ((float)(y_2 - y_1)) : 0;
159*6497c311SBarry Smith   R_y3_y1 = (y_3 != y_1) ? one / ((float)(y_3 - y_1)) : 0;
1602b8d69caSLisandro Dalcin   x3_x1   = x_3 - x_1;
1612b8d69caSLisandro Dalcin   t3_t1   = t_3 - t_1;
1622b8d69caSLisandro Dalcin 
1632b8d69caSLisandro Dalcin   for (y = y_1; y <= y_2; y++) {
1642b8d69caSLisandro Dalcin     /* Draw a line with the correct color from t1-t2 to t1-t3 */
1652b8d69caSLisandro Dalcin     /* Left color is (y-y1)/(y2-y1) * (t2-t1) + t1 */
166*6497c311SBarry Smith     lfrac = ((float)(y - y_1)) * R_y2_y1;
167*6497c311SBarry Smith     lc    = (int)(lfrac * ((float)t2_t1) + (float)t_1);
168*6497c311SBarry Smith     lx    = (int)(lfrac * ((float)x2_x1) + (float)x_1);
1692b8d69caSLisandro Dalcin     /* Right color is (y-y1)/(y3-y1) * (t3-t1) + t1 */
170*6497c311SBarry Smith     rfrac = ((float)(y - y_1)) * R_y3_y1;
171*6497c311SBarry Smith     rc    = (int)(rfrac * ((float)t3_t1) + (float)t_1);
172*6497c311SBarry Smith     rx    = (int)(rfrac * ((float)x3_x1) + (float)x_1);
1732b8d69caSLisandro Dalcin     /* Draw the line */
1742b8d69caSLisandro Dalcin     rc_lc = rc - lc;
1752b8d69caSLisandro Dalcin     rx_lx = rx - lx;
1762b8d69caSLisandro Dalcin     if (rx > lx) {
1772b8d69caSLisandro Dalcin       for (xx = lx; xx <= rx; xx++) {
1782b8d69caSLisandro Dalcin         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
1792b8d69caSLisandro Dalcin         PetscImageDrawPixel(img, xx, y, c);
1802b8d69caSLisandro Dalcin       }
1812b8d69caSLisandro Dalcin     } else if (rx < lx) {
1822b8d69caSLisandro Dalcin       for (xx = lx; xx >= rx; xx--) {
1832b8d69caSLisandro Dalcin         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
1842b8d69caSLisandro Dalcin         PetscImageDrawPixel(img, xx, y, c);
1852b8d69caSLisandro Dalcin       }
1862b8d69caSLisandro Dalcin     } else {
1872b8d69caSLisandro Dalcin       c = lc >> SHIFT_VAL;
1882b8d69caSLisandro Dalcin       PetscImageDrawPixel(img, lx, y, c);
1892b8d69caSLisandro Dalcin     }
1902b8d69caSLisandro Dalcin   }
1912b8d69caSLisandro Dalcin 
1922b8d69caSLisandro Dalcin   /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
1932b8d69caSLisandro Dalcin      We take advantage of the previous iteration. */
1942b8d69caSLisandro Dalcin   if (y_2 >= y_3) return;
1952b8d69caSLisandro Dalcin   if (y_1 < y_2) {
1962b8d69caSLisandro Dalcin     x_1   = rx;
1972b8d69caSLisandro Dalcin     y_1   = y_2;
1982b8d69caSLisandro Dalcin     t_1   = rc;
1992b8d69caSLisandro Dalcin     x3_x1 = x_3 - x_1;
2002b8d69caSLisandro Dalcin     t3_t1 = t_3 - t_1;
2012b8d69caSLisandro Dalcin   }
202*6497c311SBarry Smith   R_y3_y1 = (y_3 != y_1) ? one / ((float)(y_3 - y_1)) : 0;
203*6497c311SBarry Smith   R_y3_y2 = (y_3 != y_2) ? one / ((float)(y_3 - y_2)) : 0;
2042b8d69caSLisandro Dalcin   x3_x2   = x_3 - x_2;
2052b8d69caSLisandro Dalcin   t3_t2   = t_3 - t_2;
2062b8d69caSLisandro Dalcin 
2072b8d69caSLisandro Dalcin   for (y = y_2; y <= y_3; y++) {
2082b8d69caSLisandro Dalcin     /* Draw a line with the correct color from t2-t3 to t1-t3 */
2092b8d69caSLisandro Dalcin     /* Left color is (y-y1)/(y2-y1) * (t2-t1) + t1 */
210*6497c311SBarry Smith     lfrac = ((float)(y - y_2)) * R_y3_y2;
211*6497c311SBarry Smith     lc    = (int)(lfrac * ((float)t3_t2) + (float)t_2);
212*6497c311SBarry Smith     lx    = (int)(lfrac * ((float)x3_x2) + (float)x_2);
2132b8d69caSLisandro Dalcin     /* Right color is (y-y1)/(y3-y1) * (t3-t1) + t1 */
214*6497c311SBarry Smith     rfrac = ((float)(y - y_1)) * R_y3_y1;
215*6497c311SBarry Smith     rc    = (int)(rfrac * ((float)t3_t1) + (float)t_1);
216*6497c311SBarry Smith     rx    = (int)(rfrac * ((float)x3_x1) + (float)x_1);
2172b8d69caSLisandro Dalcin     /* Draw the line */
2182b8d69caSLisandro Dalcin     rc_lc = rc - lc;
2192b8d69caSLisandro Dalcin     rx_lx = rx - lx;
2202b8d69caSLisandro Dalcin     if (rx > lx) {
2212b8d69caSLisandro Dalcin       for (xx = lx; xx <= rx; xx++) {
2222b8d69caSLisandro Dalcin         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
2232b8d69caSLisandro Dalcin         PetscImageDrawPixel(img, xx, y, c);
2242b8d69caSLisandro Dalcin       }
2252b8d69caSLisandro Dalcin     } else if (rx < lx) {
2262b8d69caSLisandro Dalcin       for (xx = lx; xx >= rx; xx--) {
2272b8d69caSLisandro Dalcin         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
2282b8d69caSLisandro Dalcin         PetscImageDrawPixel(img, xx, y, c);
2292b8d69caSLisandro Dalcin       }
2302b8d69caSLisandro Dalcin     } else {
2312b8d69caSLisandro Dalcin       c = lc >> SHIFT_VAL;
2322b8d69caSLisandro Dalcin       PetscImageDrawPixel(img, lx, y, c);
2332b8d69caSLisandro Dalcin     }
2342b8d69caSLisandro Dalcin   }
2352b8d69caSLisandro Dalcin }
2362b8d69caSLisandro Dalcin 
2372b8d69caSLisandro Dalcin #define PetscImageFontWidth  6
2382b8d69caSLisandro Dalcin #define PetscImageFontHeight 10
2392b8d69caSLisandro Dalcin static const unsigned char PetscImageFontBitmap[128 - 32][10] = {
2402b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*   */
2412b8d69caSLisandro Dalcin   {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00}, /* ! */
2422b8d69caSLisandro Dalcin   {0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* " */
2432b8d69caSLisandro Dalcin   {0x00, 0x14, 0x14, 0x3E, 0x14, 0x3E, 0x14, 0x14, 0x00, 0x00}, /* # */
2442b8d69caSLisandro Dalcin   {0x00, 0x08, 0x1C, 0x28, 0x1C, 0x0A, 0x1C, 0x08, 0x00, 0x00}, /* $ */
2452b8d69caSLisandro Dalcin   {0x00, 0x12, 0x2A, 0x14, 0x08, 0x14, 0x2A, 0x24, 0x00, 0x00}, /* % */
2462b8d69caSLisandro Dalcin   {0x00, 0x10, 0x28, 0x28, 0x10, 0x2A, 0x24, 0x1A, 0x00, 0x00}, /* & */
2472b8d69caSLisandro Dalcin   {0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ' */
2482b8d69caSLisandro Dalcin   {0x00, 0x04, 0x08, 0x10, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00}, /* ( */
2492b8d69caSLisandro Dalcin   {0x00, 0x10, 0x08, 0x04, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00}, /*) */
2502b8d69caSLisandro Dalcin   {0x00, 0x00, 0x22, 0x14, 0x3E, 0x14, 0x22, 0x00, 0x00, 0x00}, /* * */
2512b8d69caSLisandro Dalcin   {0x00, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00}, /* + */
2522b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x08, 0x10, 0x00}, /* , */
2532b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00}, /* - */
2542b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x08, 0x00}, /* . */
2552b8d69caSLisandro Dalcin   {0x00, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x00, 0x00}, /* / */
2562b8d69caSLisandro Dalcin   {0x00, 0x08, 0x14, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x00}, /* 0 */
2572b8d69caSLisandro Dalcin   {0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, /* 1 */
2582b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x02, 0x0C, 0x10, 0x20, 0x3E, 0x00, 0x00}, /* 2 */
2592b8d69caSLisandro Dalcin   {0x00, 0x3E, 0x02, 0x04, 0x0C, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* 3 */
2602b8d69caSLisandro Dalcin   {0x00, 0x04, 0x0C, 0x14, 0x24, 0x3E, 0x04, 0x04, 0x00, 0x00}, /* 4 */
2612b8d69caSLisandro Dalcin   {0x00, 0x3E, 0x20, 0x2C, 0x32, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* 5 */
2622b8d69caSLisandro Dalcin   {0x00, 0x0C, 0x10, 0x20, 0x2C, 0x32, 0x22, 0x1C, 0x00, 0x00}, /* 6 */
2632b8d69caSLisandro Dalcin   {0x00, 0x3E, 0x02, 0x04, 0x04, 0x08, 0x10, 0x10, 0x00, 0x00}, /* 7 */
2642b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x22, 0x1C, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* 8 */
2652b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x26, 0x1A, 0x02, 0x04, 0x18, 0x00, 0x00}, /* 9 */
2662b8d69caSLisandro Dalcin   {0x00, 0x00, 0x08, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x08, 0x00}, /* : */
2672b8d69caSLisandro Dalcin   {0x00, 0x00, 0x08, 0x1C, 0x08, 0x00, 0x0C, 0x08, 0x10, 0x00}, /* } */
2682b8d69caSLisandro Dalcin   {0x00, 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00}, /* < */
2692b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00}, /* = */
2702b8d69caSLisandro Dalcin   {0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00}, /* > */
2712b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00}, /* ? */
2722b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x26, 0x2A, 0x2C, 0x20, 0x1C, 0x00, 0x00}, /* @ */
2732b8d69caSLisandro Dalcin   {0x00, 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00, 0x00}, /* A */
2742b8d69caSLisandro Dalcin   {0x00, 0x3C, 0x12, 0x12, 0x1C, 0x12, 0x12, 0x3C, 0x00, 0x00}, /* B */
2752b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00, 0x00}, /* C */
2762b8d69caSLisandro Dalcin   {0x00, 0x3C, 0x12, 0x12, 0x12, 0x12, 0x12, 0x3C, 0x00, 0x00}, /* D */
2772b8d69caSLisandro Dalcin   {0x00, 0x3E, 0x20, 0x20, 0x3C, 0x20, 0x20, 0x3E, 0x00, 0x00}, /* E */
2782b8d69caSLisandro Dalcin   {0x00, 0x3E, 0x20, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x00, 0x00}, /* F */
2792b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x20, 0x20, 0x26, 0x22, 0x1C, 0x00, 0x00}, /* G */
2802b8d69caSLisandro Dalcin   {0x00, 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00, 0x00}, /* H */
2812b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* I */
2822b8d69caSLisandro Dalcin   {0x00, 0x0E, 0x04, 0x04, 0x04, 0x04, 0x24, 0x18, 0x00, 0x00}, /* J */
2832b8d69caSLisandro Dalcin   {0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00, 0x00}, /* K */
2842b8d69caSLisandro Dalcin   {0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3E, 0x00, 0x00}, /* L */
2852b8d69caSLisandro Dalcin   {0x00, 0x22, 0x22, 0x36, 0x2A, 0x22, 0x22, 0x22, 0x00, 0x00}, /* M */
2862b8d69caSLisandro Dalcin   {0x00, 0x22, 0x22, 0x32, 0x2A, 0x26, 0x22, 0x22, 0x00, 0x00}, /* N */
2872b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* O */
2882b8d69caSLisandro Dalcin   {0x00, 0x3C, 0x22, 0x22, 0x3C, 0x20, 0x20, 0x20, 0x00, 0x00}, /* P */
2892b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x22, 0x22, 0x22, 0x2A, 0x1C, 0x02, 0x00}, /* Q */
2902b8d69caSLisandro Dalcin   {0x00, 0x3C, 0x22, 0x22, 0x3C, 0x28, 0x24, 0x22, 0x00, 0x00}, /* R */
2912b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x22, 0x20, 0x1C, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* S */
2922b8d69caSLisandro Dalcin   {0x00, 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* T */
2932b8d69caSLisandro Dalcin   {0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* U */
2942b8d69caSLisandro Dalcin   {0x00, 0x22, 0x22, 0x22, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00}, /* V */
2952b8d69caSLisandro Dalcin   {0x00, 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00, 0x00}, /* W */
2962b8d69caSLisandro Dalcin   {0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00}, /* X */
2972b8d69caSLisandro Dalcin   {0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* Y */
2982b8d69caSLisandro Dalcin   {0x00, 0x3E, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3E, 0x00, 0x00}, /* Z */
2992b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1C, 0x00, 0x00}, /* [ */
3002b8d69caSLisandro Dalcin   {0x00, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x00, 0x00}, /* \ */
3012b8d69caSLisandro Dalcin   {0x00, 0x1C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1C, 0x00, 0x00}, /* ] */
3022b8d69caSLisandro Dalcin   {0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ^ */
3032b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00}, /* _ */
3042b8d69caSLisandro Dalcin   {0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ` */
3052b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x1C, 0x02, 0x1E, 0x22, 0x1E, 0x00, 0x00}, /* a */
3062b8d69caSLisandro Dalcin   {0x00, 0x20, 0x20, 0x2C, 0x32, 0x22, 0x32, 0x2C, 0x00, 0x00}, /* b */
3072b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x1C, 0x22, 0x20, 0x22, 0x1C, 0x00, 0x00}, /* c */
3082b8d69caSLisandro Dalcin   {0x00, 0x02, 0x02, 0x1A, 0x26, 0x22, 0x26, 0x1A, 0x00, 0x00}, /* d */
3092b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x1C, 0x22, 0x3E, 0x20, 0x1C, 0x00, 0x00}, /* e */
3102b8d69caSLisandro Dalcin   {0x00, 0x0C, 0x12, 0x10, 0x3C, 0x10, 0x10, 0x10, 0x00, 0x00}, /* f */
3112b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x22, 0x1C}, /* g */
3122b8d69caSLisandro Dalcin   {0x00, 0x20, 0x20, 0x2C, 0x32, 0x22, 0x22, 0x22, 0x00, 0x00}, /* h */
3132b8d69caSLisandro Dalcin   {0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* i */
3142b8d69caSLisandro Dalcin   {0x00, 0x02, 0x00, 0x06, 0x02, 0x02, 0x02, 0x12, 0x12, 0x0C}, /* j */
3152b8d69caSLisandro Dalcin   {0x00, 0x20, 0x20, 0x22, 0x24, 0x38, 0x24, 0x22, 0x00, 0x00}, /* k */
3162b8d69caSLisandro Dalcin   {0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* l */
3172b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x34, 0x2A, 0x2A, 0x2A, 0x22, 0x00, 0x00}, /* m */
3182b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x2C, 0x32, 0x22, 0x22, 0x22, 0x00, 0x00}, /* n */
3192b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* o */
3202b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x2C, 0x32, 0x22, 0x32, 0x2C, 0x20, 0x20}, /* p */
3212b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x1A, 0x26, 0x22, 0x26, 0x1A, 0x02, 0x02}, /* q */
3222b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x2C, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00}, /* r */
3232b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x1C, 0x20, 0x1C, 0x02, 0x3C, 0x00, 0x00}, /* s */
3242b8d69caSLisandro Dalcin   {0x00, 0x10, 0x10, 0x3C, 0x10, 0x10, 0x12, 0x0C, 0x00, 0x00}, /* t */
3252b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x26, 0x1A, 0x00, 0x00}, /* u */
3262b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0x00}, /* v */
3272b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x22, 0x22, 0x2A, 0x2A, 0x14, 0x00, 0x00}, /* w */
3282b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00}, /* x */
3292b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x22, 0x22, 0x26, 0x1A, 0x02, 0x22, 0x1C}, /* y */
3302b8d69caSLisandro Dalcin   {0x00, 0x00, 0x00, 0x3E, 0x04, 0x08, 0x10, 0x3E, 0x00, 0x00}, /* z */
3312b8d69caSLisandro Dalcin   {0x00, 0x06, 0x08, 0x04, 0x18, 0x04, 0x08, 0x06, 0x00, 0x00}, /* { */
3322b8d69caSLisandro Dalcin   {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* | */
3332b8d69caSLisandro Dalcin   {0x00, 0x18, 0x04, 0x08, 0x06, 0x08, 0x04, 0x18, 0x00, 0x00}, /* } */
3342b8d69caSLisandro Dalcin   {0x00, 0x12, 0x2A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ~ */
3352b8d69caSLisandro Dalcin   {0x00, 0x2A, 0x00, 0x22, 0x00, 0x22, 0x00, 0x2A, 0x00, 0x00}, /* ASCII 127 */
3362b8d69caSLisandro Dalcin };
3372b8d69caSLisandro Dalcin 
PetscImageDrawText(PetscImage img,int x,int y,int c,const char text[])338d71ae5a4SJacob Faibussowitsch static inline void PetscImageDrawText(PetscImage img, int x, int y, int c, const char text[])
339d71ae5a4SJacob Faibussowitsch {
3402b8d69caSLisandro Dalcin   int i, j, k, tw = PetscImageFontWidth, th = PetscImageFontHeight;
3412b8d69caSLisandro Dalcin   for (i = 0; i < th; i++) {
3422b8d69caSLisandro Dalcin     for (k = 0; text[k]; k++) {
3432b8d69caSLisandro Dalcin       int chr = PetscClipInterval(text[k], 32, 127);
3442b8d69caSLisandro Dalcin       for (j = 0; j < tw; j++) {
3459371c9d4SSatish Balay         if (PetscImageFontBitmap[chr - 32][i] & (1 << (tw - 1 - j))) PetscImageDrawPixel(img, x + j + k * tw, y + i - th, c);
3462b8d69caSLisandro Dalcin       }
3472b8d69caSLisandro Dalcin     }
3482b8d69caSLisandro Dalcin   }
3492b8d69caSLisandro Dalcin }
350