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