1 #ifndef _PETSCIMAGE_H 2 #define _PETSCIMAGE_H 3 4 #include <petscdraw.h> 5 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; 13 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 } 21 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 } 29 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 } 36 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 } 75 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 } 84 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 } 108 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; 118 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; 124 125 t_1 = t_1 << SHIFT_VAL; 126 t_2 = t_2 << SHIFT_VAL; 127 t_3 = t_3 << SHIFT_VAL; 128 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 153 154 /* This code is decidely non-optimal; 155 it is intended to be a start at an implementation */ 156 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; 163 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 } 192 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; 207 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 } 237 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 }; 338 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 } 351 352 #endif 353