Actual source code: drawimage.h

  1: #ifndef _PETSCIMAGE_H
  2: #define _PETSCIMAGE_H

  4: #include <petscdraw.h>

  6: typedef struct _n_PetscImage *PetscImage;
  7: typedef struct _n_PetscImage {
  8:   unsigned char *buffer;          /* raster buffer  */
  9:   int            w, h;            /* width, height  */
 10:   int            clip[4];         /* clip ranges    */
 11:   unsigned char  palette[256][3]; /* colormap       */
 12: } _n_PetscImage;

 14: static inline void PetscImageSetClip(PetscImage img, int x, int y, int w, int h)
 15: {
 16:   img->clip[0] = PetscClipInterval(x, 0, img->w - 1); /* xmin   */
 17:   img->clip[1] = PetscClipInterval(y, 0, img->h - 1); /* ymin   */
 18:   img->clip[2] = PetscClipInterval(x + w, 0, img->w); /* xmax+1 */
 19:   img->clip[3] = PetscClipInterval(y + h, 0, img->h); /* ymax+1 */
 20: }

 22: static inline void PetscImageClear(PetscImage img)
 23: {
 24:   int x, xs = img->clip[0], xe = img->clip[2];
 25:   int y, ys = img->clip[1], ye = img->clip[3];
 26:   for (y = ys; y < ye; y++)
 27:     for (x = xs; x < xe; x++) img->buffer[y * img->w + x] = 0;
 28: }

 30: static inline void PetscImageDrawPixel(PetscImage img, int x, int y, int c)
 31: {
 32:   if (x < img->clip[0] || x >= img->clip[2]) return;
 33:   if (y < img->clip[1] || y >= img->clip[3]) return;
 34:   img->buffer[y * img->w + x] = (unsigned char)c;
 35: }

 37: static inline void PetscImageDrawLine(PetscImage img, int x_1, int y_1, int x_2, int y_2, int c)
 38: {
 39:   if (y_1 == y_2) {
 40:     /* Horizontal line */
 41:     if (x_2 - x_1 < 0) {
 42:       int tmp = x_1;
 43:       x_1     = x_2;
 44:       x_2     = tmp;
 45:     }
 46:     while (x_1 <= x_2) PetscImageDrawPixel(img, x_1++, y_1, c);
 47:   } else if (x_1 == x_2) {
 48:     /* Vertical line */
 49:     if (y_2 - y_1 < 0) {
 50:       int tmp = y_1;
 51:       y_1     = y_2;
 52:       y_2     = tmp;
 53:     }
 54:     while (y_1 <= y_2) PetscImageDrawPixel(img, x_1, y_1++, c);
 55:   } else {
 56:     /* Bresenham's line drawing algorithm */
 57:     int dx = PetscAbs(x_2 - x_1), sx = (x_2 - x_1) >= 0 ? +1 : -1;
 58:     int dy = PetscAbs(y_2 - y_1), sy = (y_2 - y_1) >= 0 ? +1 : -1;
 59:     int error = (dx > dy ? dx : -dy) / 2, err;
 60:     while (1) {
 61:       PetscImageDrawPixel(img, x_1, y_1, c);
 62:       if (x_1 == x_2 && y_1 == y_2) break;
 63:       err = error;
 64:       if (err > -dx) {
 65:         error -= dy;
 66:         x_1 += sx;
 67:       }
 68:       if (err < +dy) {
 69:         error += dx;
 70:         y_1 += sy;
 71:       }
 72:     }
 73:   }
 74: }

 76: static inline void PetscImageDrawRectangle(PetscImage img, int x, int y, int w, int h, int c)
 77: {
 78:   int xs = PetscMax(x, img->clip[0]), xe = PetscMin(x + w, img->clip[2]);
 79:   int ys = PetscMax(y, img->clip[1]), ye = PetscMin(y + h, img->clip[3]);
 80:   if (xs >= xe || ys >= ye) return;
 81:   for (y = ys; y < ye; y++)
 82:     for (x = xs; x < xe; x++) img->buffer[y * img->w + x] = (unsigned char)c;
 83: }

 85: static inline void PetscImageDrawEllipse(PetscImage img, int xc, int yc, int w, int h, int c)
 86: {
 87:   /* Bresenham's circle/ellipse drawing algorithm */
 88:   int x, y, s, a2 = w * w, b2 = h * h;
 89:   for (x = 0, y = h, s = 2 * b2 + a2 * (1 - 2 * h); b2 * x <= a2 * y; x++) {
 90:     PetscImageDrawLine(img, xc + x, yc + y, xc - x, yc + y, c);
 91:     PetscImageDrawLine(img, xc + x, yc - y, xc - x, yc - y, c);
 92:     if (s >= 0) {
 93:       s += 4 * a2 * (1 - y);
 94:       y--;
 95:     }
 96:     s += b2 * ((4 * x) + 6);
 97:   }
 98:   for (x = w, y = 0, s = 2 * a2 + b2 * (1 - 2 * w); a2 * y <= b2 * x; y++) {
 99:     PetscImageDrawLine(img, xc + x, yc + y, xc - x, yc + y, c);
100:     PetscImageDrawLine(img, xc + x, yc - y, xc - x, yc - y, c);
101:     if (s >= 0) {
102:       s += 4 * b2 * (1 - x);
103:       x--;
104:     }
105:     s += a2 * ((4 * y) + 6);
106:   }
107: }

109: 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)
110: {
111:   const int SHIFT_VAL = 6;
112:   const int xmin = img->clip[0], xmax = img->clip[2] - 1;
113:   const int ymin = img->clip[1], ymax = img->clip[3] - 1;
114:   float     rfrac, lfrac, one = 1;
115:   float     R_y2_y1, R_y3_y1, R_y3_y2;
116:   int       lc, rc = 0, lx, rx = 0, xx, y, c;
117:   int       rc_lc, rx_lx, t2_t1, x2_x1, t3_t1, x3_x1, t3_t2, x3_x2;

119:   /* Is triangle ever visible in image? */
120:   if (x_1 < xmin && x_2 < xmin && x_3 < xmin) return;
121:   if (y_1 < ymin && y_2 < ymin && y_3 < ymin) return;
122:   if (x_1 > xmax && x_2 > xmax && x_3 > xmax) return;
123:   if (y_1 > ymax && y_2 > ymax && y_3 > ymax) return;

125:   t_1 = t_1 << SHIFT_VAL;
126:   t_2 = t_2 << SHIFT_VAL;
127:   t_3 = t_3 << SHIFT_VAL;

129:   /* Sort the vertices */
130: #define SWAP(a, b) \
131:   do { \
132:     int _tmp; \
133:     _tmp = a; \
134:     a    = b; \
135:     b    = _tmp; \
136:   } while (0)
137:   if (y_1 > y_2) {
138:     SWAP(x_1, x_2);
139:     SWAP(y_1, y_2);
140:     SWAP(t_1, t_2);
141:   }
142:   if (y_1 > y_3) {
143:     SWAP(x_1, x_3);
144:     SWAP(y_1, y_3);
145:     SWAP(t_1, t_3);
146:   }
147:   if (y_2 > y_3) {
148:     SWAP(x_2, x_3);
149:     SWAP(y_2, y_3);
150:     SWAP(t_2, t_3);
151:   }
152: #undef SWAP

154:   /* This code is decidedly non-optimal;
155:    it is intended to be a start at an implementation */

157:   t2_t1   = t_2 - t_1;
158:   x2_x1   = x_2 - x_1;
159:   R_y2_y1 = (y_2 != y_1) ? one / (y_2 - y_1) : 0;
160:   R_y3_y1 = (y_3 != y_1) ? one / (y_3 - y_1) : 0;
161:   x3_x1   = x_3 - x_1;
162:   t3_t1   = t_3 - t_1;

164:   for (y = y_1; y <= y_2; y++) {
165:     /* Draw a line with the correct color from t1-t2 to t1-t3 */
166:     /* Left color is (y-y1)/(y2-y1) * (t2-t1) + t1 */
167:     lfrac = (y - y_1) * R_y2_y1;
168:     lc    = (int)(lfrac * (t2_t1) + t_1);
169:     lx    = (int)(lfrac * (x2_x1) + x_1);
170:     /* Right color is (y-y1)/(y3-y1) * (t3-t1) + t1 */
171:     rfrac = (y - y_1) * R_y3_y1;
172:     rc    = (int)(rfrac * (t3_t1) + t_1);
173:     rx    = (int)(rfrac * (x3_x1) + x_1);
174:     /* Draw the line */
175:     rc_lc = rc - lc;
176:     rx_lx = rx - lx;
177:     if (rx > lx) {
178:       for (xx = lx; xx <= rx; xx++) {
179:         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
180:         PetscImageDrawPixel(img, xx, y, c);
181:       }
182:     } else if (rx < lx) {
183:       for (xx = lx; xx >= rx; xx--) {
184:         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
185:         PetscImageDrawPixel(img, xx, y, c);
186:       }
187:     } else {
188:       c = lc >> SHIFT_VAL;
189:       PetscImageDrawPixel(img, lx, y, c);
190:     }
191:   }

193:   /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
194:      We take advantage of the previous iteration. */
195:   if (y_2 >= y_3) return;
196:   if (y_1 < y_2) {
197:     x_1   = rx;
198:     y_1   = y_2;
199:     t_1   = rc;
200:     x3_x1 = x_3 - x_1;
201:     t3_t1 = t_3 - t_1;
202:   }
203:   R_y3_y1 = (y_3 != y_1) ? one / (y_3 - y_1) : 0;
204:   R_y3_y2 = (y_3 != y_2) ? one / (y_3 - y_2) : 0;
205:   x3_x2   = x_3 - x_2;
206:   t3_t2   = t_3 - t_2;

208:   for (y = y_2; y <= y_3; y++) {
209:     /* Draw a line with the correct color from t2-t3 to t1-t3 */
210:     /* Left color is (y-y1)/(y2-y1) * (t2-t1) + t1 */
211:     lfrac = (y - y_2) * R_y3_y2;
212:     lc    = (int)(lfrac * (t3_t2) + t_2);
213:     lx    = (int)(lfrac * (x3_x2) + x_2);
214:     /* Right color is (y-y1)/(y3-y1) * (t3-t1) + t1 */
215:     rfrac = (y - y_1) * R_y3_y1;
216:     rc    = (int)(rfrac * (t3_t1) + t_1);
217:     rx    = (int)(rfrac * (x3_x1) + x_1);
218:     /* Draw the line */
219:     rc_lc = rc - lc;
220:     rx_lx = rx - lx;
221:     if (rx > lx) {
222:       for (xx = lx; xx <= rx; xx++) {
223:         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
224:         PetscImageDrawPixel(img, xx, y, c);
225:       }
226:     } else if (rx < lx) {
227:       for (xx = lx; xx >= rx; xx--) {
228:         c = (((xx - lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
229:         PetscImageDrawPixel(img, xx, y, c);
230:       }
231:     } else {
232:       c = lc >> SHIFT_VAL;
233:       PetscImageDrawPixel(img, lx, y, c);
234:     }
235:   }
236: }

238: #define PetscImageFontWidth  6
239: #define PetscImageFontHeight 10
240: static const unsigned char PetscImageFontBitmap[128 - 32][10] = {
241:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*   */
242:   {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00}, /* ! */
243:   {0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* " */
244:   {0x00, 0x14, 0x14, 0x3E, 0x14, 0x3E, 0x14, 0x14, 0x00, 0x00}, /* # */
245:   {0x00, 0x08, 0x1C, 0x28, 0x1C, 0x0A, 0x1C, 0x08, 0x00, 0x00}, /* $ */
246:   {0x00, 0x12, 0x2A, 0x14, 0x08, 0x14, 0x2A, 0x24, 0x00, 0x00}, /* % */
247:   {0x00, 0x10, 0x28, 0x28, 0x10, 0x2A, 0x24, 0x1A, 0x00, 0x00}, /* & */
248:   {0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ' */
249:   {0x00, 0x04, 0x08, 0x10, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00}, /* ( */
250:   {0x00, 0x10, 0x08, 0x04, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00}, /*) */
251:   {0x00, 0x00, 0x22, 0x14, 0x3E, 0x14, 0x22, 0x00, 0x00, 0x00}, /* * */
252:   {0x00, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00}, /* + */
253:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x08, 0x10, 0x00}, /* , */
254:   {0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00}, /* - */
255:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x08, 0x00}, /* . */
256:   {0x00, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x00, 0x00}, /* / */
257:   {0x00, 0x08, 0x14, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x00}, /* 0 */
258:   {0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, /* 1 */
259:   {0x00, 0x1C, 0x22, 0x02, 0x0C, 0x10, 0x20, 0x3E, 0x00, 0x00}, /* 2 */
260:   {0x00, 0x3E, 0x02, 0x04, 0x0C, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* 3 */
261:   {0x00, 0x04, 0x0C, 0x14, 0x24, 0x3E, 0x04, 0x04, 0x00, 0x00}, /* 4 */
262:   {0x00, 0x3E, 0x20, 0x2C, 0x32, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* 5 */
263:   {0x00, 0x0C, 0x10, 0x20, 0x2C, 0x32, 0x22, 0x1C, 0x00, 0x00}, /* 6 */
264:   {0x00, 0x3E, 0x02, 0x04, 0x04, 0x08, 0x10, 0x10, 0x00, 0x00}, /* 7 */
265:   {0x00, 0x1C, 0x22, 0x22, 0x1C, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* 8 */
266:   {0x00, 0x1C, 0x22, 0x26, 0x1A, 0x02, 0x04, 0x18, 0x00, 0x00}, /* 9 */
267:   {0x00, 0x00, 0x08, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x08, 0x00}, /* : */
268:   {0x00, 0x00, 0x08, 0x1C, 0x08, 0x00, 0x0C, 0x08, 0x10, 0x00}, /* } */
269:   {0x00, 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00}, /* < */
270:   {0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00}, /* = */
271:   {0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00}, /* > */
272:   {0x00, 0x1C, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00}, /* ? */
273:   {0x00, 0x1C, 0x22, 0x26, 0x2A, 0x2C, 0x20, 0x1C, 0x00, 0x00}, /* @ */
274:   {0x00, 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00, 0x00}, /* A */
275:   {0x00, 0x3C, 0x12, 0x12, 0x1C, 0x12, 0x12, 0x3C, 0x00, 0x00}, /* B */
276:   {0x00, 0x1C, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00, 0x00}, /* C */
277:   {0x00, 0x3C, 0x12, 0x12, 0x12, 0x12, 0x12, 0x3C, 0x00, 0x00}, /* D */
278:   {0x00, 0x3E, 0x20, 0x20, 0x3C, 0x20, 0x20, 0x3E, 0x00, 0x00}, /* E */
279:   {0x00, 0x3E, 0x20, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x00, 0x00}, /* F */
280:   {0x00, 0x1C, 0x22, 0x20, 0x20, 0x26, 0x22, 0x1C, 0x00, 0x00}, /* G */
281:   {0x00, 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00, 0x00}, /* H */
282:   {0x00, 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* I */
283:   {0x00, 0x0E, 0x04, 0x04, 0x04, 0x04, 0x24, 0x18, 0x00, 0x00}, /* J */
284:   {0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00, 0x00}, /* K */
285:   {0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3E, 0x00, 0x00}, /* L */
286:   {0x00, 0x22, 0x22, 0x36, 0x2A, 0x22, 0x22, 0x22, 0x00, 0x00}, /* M */
287:   {0x00, 0x22, 0x22, 0x32, 0x2A, 0x26, 0x22, 0x22, 0x00, 0x00}, /* N */
288:   {0x00, 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* O */
289:   {0x00, 0x3C, 0x22, 0x22, 0x3C, 0x20, 0x20, 0x20, 0x00, 0x00}, /* P */
290:   {0x00, 0x1C, 0x22, 0x22, 0x22, 0x22, 0x2A, 0x1C, 0x02, 0x00}, /* Q */
291:   {0x00, 0x3C, 0x22, 0x22, 0x3C, 0x28, 0x24, 0x22, 0x00, 0x00}, /* R */
292:   {0x00, 0x1C, 0x22, 0x20, 0x1C, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* S */
293:   {0x00, 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* T */
294:   {0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* U */
295:   {0x00, 0x22, 0x22, 0x22, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00}, /* V */
296:   {0x00, 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00, 0x00}, /* W */
297:   {0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00}, /* X */
298:   {0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* Y */
299:   {0x00, 0x3E, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3E, 0x00, 0x00}, /* Z */
300:   {0x00, 0x1C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1C, 0x00, 0x00}, /* [ */
301:   {0x00, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x00, 0x00}, /* \ */
302:   {0x00, 0x1C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1C, 0x00, 0x00}, /* ] */
303:   {0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ^ */
304:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00}, /* _ */
305:   {0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ` */
306:   {0x00, 0x00, 0x00, 0x1C, 0x02, 0x1E, 0x22, 0x1E, 0x00, 0x00}, /* a */
307:   {0x00, 0x20, 0x20, 0x2C, 0x32, 0x22, 0x32, 0x2C, 0x00, 0x00}, /* b */
308:   {0x00, 0x00, 0x00, 0x1C, 0x22, 0x20, 0x22, 0x1C, 0x00, 0x00}, /* c */
309:   {0x00, 0x02, 0x02, 0x1A, 0x26, 0x22, 0x26, 0x1A, 0x00, 0x00}, /* d */
310:   {0x00, 0x00, 0x00, 0x1C, 0x22, 0x3E, 0x20, 0x1C, 0x00, 0x00}, /* e */
311:   {0x00, 0x0C, 0x12, 0x10, 0x3C, 0x10, 0x10, 0x10, 0x00, 0x00}, /* f */
312:   {0x00, 0x00, 0x00, 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x22, 0x1C}, /* g */
313:   {0x00, 0x20, 0x20, 0x2C, 0x32, 0x22, 0x22, 0x22, 0x00, 0x00}, /* h */
314:   {0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* i */
315:   {0x00, 0x02, 0x00, 0x06, 0x02, 0x02, 0x02, 0x12, 0x12, 0x0C}, /* j */
316:   {0x00, 0x20, 0x20, 0x22, 0x24, 0x38, 0x24, 0x22, 0x00, 0x00}, /* k */
317:   {0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* l */
318:   {0x00, 0x00, 0x00, 0x34, 0x2A, 0x2A, 0x2A, 0x22, 0x00, 0x00}, /* m */
319:   {0x00, 0x00, 0x00, 0x2C, 0x32, 0x22, 0x22, 0x22, 0x00, 0x00}, /* n */
320:   {0x00, 0x00, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* o */
321:   {0x00, 0x00, 0x00, 0x2C, 0x32, 0x22, 0x32, 0x2C, 0x20, 0x20}, /* p */
322:   {0x00, 0x00, 0x00, 0x1A, 0x26, 0x22, 0x26, 0x1A, 0x02, 0x02}, /* q */
323:   {0x00, 0x00, 0x00, 0x2C, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00}, /* r */
324:   {0x00, 0x00, 0x00, 0x1C, 0x20, 0x1C, 0x02, 0x3C, 0x00, 0x00}, /* s */
325:   {0x00, 0x10, 0x10, 0x3C, 0x10, 0x10, 0x12, 0x0C, 0x00, 0x00}, /* t */
326:   {0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x26, 0x1A, 0x00, 0x00}, /* u */
327:   {0x00, 0x00, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0x00}, /* v */
328:   {0x00, 0x00, 0x00, 0x22, 0x22, 0x2A, 0x2A, 0x14, 0x00, 0x00}, /* w */
329:   {0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00}, /* x */
330:   {0x00, 0x00, 0x00, 0x22, 0x22, 0x26, 0x1A, 0x02, 0x22, 0x1C}, /* y */
331:   {0x00, 0x00, 0x00, 0x3E, 0x04, 0x08, 0x10, 0x3E, 0x00, 0x00}, /* z */
332:   {0x00, 0x06, 0x08, 0x04, 0x18, 0x04, 0x08, 0x06, 0x00, 0x00}, /* { */
333:   {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* | */
334:   {0x00, 0x18, 0x04, 0x08, 0x06, 0x08, 0x04, 0x18, 0x00, 0x00}, /* } */
335:   {0x00, 0x12, 0x2A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ~ */
336:   {0x00, 0x2A, 0x00, 0x22, 0x00, 0x22, 0x00, 0x2A, 0x00, 0x00}, /* ASCII 127 */
337: };

339: static inline void PetscImageDrawText(PetscImage img, int x, int y, int c, const char text[])
340: {
341:   int i, j, k, tw = PetscImageFontWidth, th = PetscImageFontHeight;
342:   for (i = 0; i < th; i++) {
343:     for (k = 0; text[k]; k++) {
344:       int chr = PetscClipInterval(text[k], 32, 127);
345:       for (j = 0; j < tw; j++) {
346:         if (PetscImageFontBitmap[chr - 32][i] & (1 << (tw - 1 - j))) PetscImageDrawPixel(img, x + j + k * tw, y + i - th, c);
347:       }
348:     }
349:   }
350: }

352: #endif