Actual source code: drawimage.h
petsc-3.9.4 2018-09-11
1: #if !defined(_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: PETSC_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: PETSC_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++)
28: img->buffer[y * img->w + x] = 0;
29: }
31: PETSC_STATIC_INLINE void PetscImageDrawPixel(PetscImage img,int x,int y,int c)
32: {
33: if (x < img->clip[0] || x >= img->clip[2]) return;
34: if (y < img->clip[1] || y >= img->clip[3]) return;
35: img->buffer[y * img->w + x] = (unsigned char)c;
36: }
38: PETSC_STATIC_INLINE void PetscImageDrawLine(PetscImage img,int x_1,int y_1,int x_2,int y_2,int c)
39: {
40: if (y_1 == y_2) {
41: /* Horizontal line */
42: if (x_2 - x_1 < 0) {int tmp = x_1; x_1 = x_2; x_2 = tmp;}
43: while (x_1 <= x_2) PetscImageDrawPixel(img,x_1++,y_1,c);
44: } else if (x_1 == x_2) {
45: /* Vertical line */
46: if (y_2 - y_1 < 0) {int tmp = y_1; y_1 = y_2; y_2 = tmp;}
47: while (y_1 <= y_2) PetscImageDrawPixel(img,x_1,y_1++,c);
48: } else {
49: /* Bresenham's line drawing algorithm */
50: int dx = PetscAbs(x_2 - x_1), sx = (x_2 - x_1) >= 0 ? +1 : -1;
51: int dy = PetscAbs(y_2 - y_1), sy = (y_2 - y_1) >= 0 ? +1 : -1;
52: int error = (dx > dy ? dx : -dy)/2, err;
53: while (1) {
54: PetscImageDrawPixel(img,x_1,y_1,c);
55: if (x_1 == x_2 && y_1 == y_2) break;
56: err = error;
57: if (err > -dx) { error -= dy; x_1 += sx; }
58: if (err < +dy) { error += dx; y_1 += sy; }
59: }
60: }
61: }
63: PETSC_STATIC_INLINE void PetscImageDrawRectangle(PetscImage img,int x,int y,int w,int h,int c)
64: {
66: int xs = PetscMax(x,img->clip[0]), xe = PetscMin(x+w,img->clip[2]);
67: int ys = PetscMax(y,img->clip[1]), ye = PetscMin(y+h,img->clip[3]);
68: if (xs >= xe || ys >= ye) return;
69: for (y = ys; y < ye; y++)
70: for (x = xs; x < xe; x++)
71: img->buffer[y * img->w + x] = (unsigned char)c;
72: }
74: PETSC_STATIC_INLINE void PetscImageDrawEllipse(PetscImage img,int xc,int yc,int w,int h,int c)
75: {
76: /* Bresenham's circle/ellipse drawing algorithm */
77: int x, y, s, a2 = w*w, b2 = h*h;
78: for (x = 0, y = h, s = 2*b2+a2*(1-2*h); b2*x <= a2*y; x++) {
79: PetscImageDrawLine(img,xc + x,yc + y,xc - x,yc + y,c);
80: PetscImageDrawLine(img,xc + x,yc - y,xc - x,yc - y,c);
81: if (s >= 0) { s += 4*a2*(1-y); y--; }
82: s += b2*((4*x)+6);
83: }
84: for (x = w, y = 0, s = 2*a2+b2*(1-2*w); a2*y <= b2*x; y++) {
85: PetscImageDrawLine(img,xc + x,yc + y,xc - x,yc + y,c);
86: PetscImageDrawLine(img,xc + x,yc - y,xc - x,yc - y,c);
87: if (s >= 0) { s += 4*b2*(1-x); x--; }
88: s += a2*((4*y)+6);
89: }
90: }
92: PETSC_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)
93: {
94: const int SHIFT_VAL = 6;
95: const int xmin = img->clip[0], xmax = img->clip[2]-1;
96: const int ymin = img->clip[1], ymax = img->clip[3]-1;
97: float rfrac,lfrac, one = 1;
98: float R_y2_y1,R_y3_y1,R_y3_y2;
99: int lc,rc = 0,lx,rx = 0,xx,y,c;
100: int rc_lc,rx_lx,t2_t1,x2_x1,t3_t1,x3_x1,t3_t2,x3_x2;
102: /* Is triangle ever visible in image? */
103: if (x_1 < xmin && x_2 < xmin && x_3 < xmin) return;
104: if (y_1 < ymin && y_2 < ymin && y_3 < ymin) return;
105: if (x_1 > xmax && x_2 > xmax && x_3 > xmax) return;
106: if (y_1 > ymax && y_2 > ymax && y_3 > ymax) return;
108: t_1 = t_1 << SHIFT_VAL;
109: t_2 = t_2 << SHIFT_VAL;
110: t_3 = t_3 << SHIFT_VAL;
112: /* Sort the vertices */
113: #define SWAP(a,b) do {int _tmp; _tmp=a; a=b; b=_tmp;} while (0)
114: if (y_1 > y_2) {SWAP(x_1,x_2); SWAP(y_1,y_2); SWAP(t_1,t_2);}
115: if (y_1 > y_3) {SWAP(x_1,x_3); SWAP(y_1,y_3); SWAP(t_1,t_3);}
116: if (y_2 > y_3) {SWAP(x_2,x_3); SWAP(y_2,y_3); SWAP(t_2,t_3);}
117: #undef SWAP
119: /* This code is decidely non-optimal;
120: it is intended to be a start at an implementation */
122: t2_t1 = t_2 - t_1;
123: x2_x1 = x_2 - x_1;
124: R_y2_y1 = (y_2 != y_1) ? one/(y_2-y_1) : 0;
125: R_y3_y1 = (y_3 != y_1) ? one/(y_3-y_1) : 0;
126: x3_x1 = x_3 - x_1;
127: t3_t1 = t_3 - t_1;
129: for (y=y_1; y<=y_2; y++) {
130: /* Draw a line with the correct color from t1-t2 to t1-t3 */
131: /* Left color is (y-y1)/(y2-y1) * (t2-t1) + t1 */
132: lfrac = (y - y_1) * R_y2_y1;
133: lc = (int)(lfrac * (t2_t1) + t_1);
134: lx = (int)(lfrac * (x2_x1) + x_1);
135: /* Right color is (y-y1)/(y3-y1) * (t3-t1) + t1 */
136: rfrac = (y - y_1) * R_y3_y1;
137: rc = (int)(rfrac * (t3_t1) + t_1);
138: rx = (int)(rfrac * (x3_x1) + x_1);
139: /* Draw the line */
140: rc_lc = rc - lc;
141: rx_lx = rx - lx;
142: if (rx > lx) {
143: for (xx=lx; xx<=rx; xx++) {
144: c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
145: PetscImageDrawPixel(img,xx,y,c);
146: }
147: } else if (rx < lx) {
148: for (xx=lx; xx>=rx; xx--) {
149: c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
150: PetscImageDrawPixel(img,xx,y,c);
151: }
152: } else {
153: c = lc >> SHIFT_VAL;
154: PetscImageDrawPixel(img,lx,y,c);
155: }
156: }
158: /* For simplicity,"move" t1 to the intersection of t1-t3 with the line y=y2.
159: We take advantage of the previous iteration. */
160: if (y_2 >= y_3) return;
161: if (y_1 < y_2) {
162: x_1 = rx;
163: y_1 = y_2;
164: t_1 = rc;
165: x3_x1 = x_3 - x_1;
166: t3_t1 = t_3 - t_1;
167: }
168: R_y3_y1 = (y_3 != y_1) ? one/(y_3-y_1) : 0;
169: R_y3_y2 = (y_3 != y_2) ? one/(y_3-y_2) : 0;
170: x3_x2 = x_3 - x_2;
171: t3_t2 = t_3 - t_2;
173: for (y=y_2; y<=y_3; y++) {
174: /* Draw a line with the correct color from t2-t3 to t1-t3 */
175: /* Left color is (y-y1)/(y2-y1) * (t2-t1) + t1 */
176: lfrac = (y - y_2) * R_y3_y2;
177: lc = (int)(lfrac * (t3_t2) + t_2);
178: lx = (int)(lfrac * (x3_x2) + x_2);
179: /* Right color is (y-y1)/(y3-y1) * (t3-t1) + t1 */
180: rfrac = (y - y_1) * R_y3_y1;
181: rc = (int)(rfrac * (t3_t1) + t_1);
182: rx = (int)(rfrac * (x3_x1) + x_1);
183: /* Draw the line */
184: rc_lc = rc - lc;
185: rx_lx = rx - lx;
186: if (rx > lx) {
187: for (xx=lx; xx<=rx; xx++) {
188: c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
189: PetscImageDrawPixel(img,xx,y,c);
190: }
191: } else if (rx < lx) {
192: for (xx=lx; xx>=rx; xx--) {
193: c = (((xx-lx) * (rc_lc)) / (rx_lx) + lc) >> SHIFT_VAL;
194: PetscImageDrawPixel(img,xx,y,c);
195: }
196: } else {
197: c = lc >> SHIFT_VAL;
198: PetscImageDrawPixel(img,lx,y,c);
199: }
200: }
201: }
203: #define PetscImageFontWidth 6
204: #define PetscImageFontHeight 10
205: static const unsigned char PetscImageFontBitmap[128-32][10] = {
206: {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* */
207: {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00}, /* ! */
208: {0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* " */
209: {0x00, 0x14, 0x14, 0x3E, 0x14, 0x3E, 0x14, 0x14, 0x00, 0x00}, /* # */
210: {0x00, 0x08, 0x1C, 0x28, 0x1C, 0x0A, 0x1C, 0x08, 0x00, 0x00}, /* $ */
211: {0x00, 0x12, 0x2A, 0x14, 0x08, 0x14, 0x2A, 0x24, 0x00, 0x00}, /* % */
212: {0x00, 0x10, 0x28, 0x28, 0x10, 0x2A, 0x24, 0x1A, 0x00, 0x00}, /* & */
213: {0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ' */
214: {0x00, 0x04, 0x08, 0x10, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00}, /* ( */
215: {0x00, 0x10, 0x08, 0x04, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00}, /* ) */
216: {0x00, 0x00, 0x22, 0x14, 0x3E, 0x14, 0x22, 0x00, 0x00, 0x00}, /* * */
217: {0x00, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00}, /* + */
218: {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x08, 0x10, 0x00}, /* , */
219: {0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00}, /* - */
220: {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x08, 0x00}, /* . */
221: {0x00, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x00, 0x00}, /* / */
222: {0x00, 0x08, 0x14, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x00}, /* 0 */
223: {0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00}, /* 1 */
224: {0x00, 0x1C, 0x22, 0x02, 0x0C, 0x10, 0x20, 0x3E, 0x00, 0x00}, /* 2 */
225: {0x00, 0x3E, 0x02, 0x04, 0x0C, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* 3 */
226: {0x00, 0x04, 0x0C, 0x14, 0x24, 0x3E, 0x04, 0x04, 0x00, 0x00}, /* 4 */
227: {0x00, 0x3E, 0x20, 0x2C, 0x32, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* 5 */
228: {0x00, 0x0C, 0x10, 0x20, 0x2C, 0x32, 0x22, 0x1C, 0x00, 0x00}, /* 6 */
229: {0x00, 0x3E, 0x02, 0x04, 0x04, 0x08, 0x10, 0x10, 0x00, 0x00}, /* 7 */
230: {0x00, 0x1C, 0x22, 0x22, 0x1C, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* 8 */
231: {0x00, 0x1C, 0x22, 0x26, 0x1A, 0x02, 0x04, 0x18, 0x00, 0x00}, /* 9 */
232: {0x00, 0x00, 0x08, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x08, 0x00}, /* : */
233: {0x00, 0x00, 0x08, 0x1C, 0x08, 0x00, 0x0C, 0x08, 0x10, 0x00}, /* } */
234: {0x00, 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00}, /* < */
235: {0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00}, /* = */
236: {0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00}, /* > */
237: {0x00, 0x1C, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00}, /* ? */
238: {0x00, 0x1C, 0x22, 0x26, 0x2A, 0x2C, 0x20, 0x1C, 0x00, 0x00}, /* @ */
239: {0x00, 0x08, 0x14, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x00, 0x00}, /* A */
240: {0x00, 0x3C, 0x12, 0x12, 0x1C, 0x12, 0x12, 0x3C, 0x00, 0x00}, /* B */
241: {0x00, 0x1C, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1C, 0x00, 0x00}, /* C */
242: {0x00, 0x3C, 0x12, 0x12, 0x12, 0x12, 0x12, 0x3C, 0x00, 0x00}, /* D */
243: {0x00, 0x3E, 0x20, 0x20, 0x3C, 0x20, 0x20, 0x3E, 0x00, 0x00}, /* E */
244: {0x00, 0x3E, 0x20, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x00, 0x00}, /* F */
245: {0x00, 0x1C, 0x22, 0x20, 0x20, 0x26, 0x22, 0x1C, 0x00, 0x00}, /* G */
246: {0x00, 0x22, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x22, 0x00, 0x00}, /* H */
247: {0x00, 0x1C, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* I */
248: {0x00, 0x0E, 0x04, 0x04, 0x04, 0x04, 0x24, 0x18, 0x00, 0x00}, /* J */
249: {0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00, 0x00}, /* K */
250: {0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3E, 0x00, 0x00}, /* L */
251: {0x00, 0x22, 0x22, 0x36, 0x2A, 0x22, 0x22, 0x22, 0x00, 0x00}, /* M */
252: {0x00, 0x22, 0x22, 0x32, 0x2A, 0x26, 0x22, 0x22, 0x00, 0x00}, /* N */
253: {0x00, 0x1C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* O */
254: {0x00, 0x3C, 0x22, 0x22, 0x3C, 0x20, 0x20, 0x20, 0x00, 0x00}, /* P */
255: {0x00, 0x1C, 0x22, 0x22, 0x22, 0x22, 0x2A, 0x1C, 0x02, 0x00}, /* Q */
256: {0x00, 0x3C, 0x22, 0x22, 0x3C, 0x28, 0x24, 0x22, 0x00, 0x00}, /* R */
257: {0x00, 0x1C, 0x22, 0x20, 0x1C, 0x02, 0x22, 0x1C, 0x00, 0x00}, /* S */
258: {0x00, 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* T */
259: {0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* U */
260: {0x00, 0x22, 0x22, 0x22, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00}, /* V */
261: {0x00, 0x22, 0x22, 0x22, 0x2A, 0x2A, 0x36, 0x22, 0x00, 0x00}, /* W */
262: {0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00}, /* X */
263: {0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* Y */
264: {0x00, 0x3E, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3E, 0x00, 0x00}, /* Z */
265: {0x00, 0x1C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1C, 0x00, 0x00}, /* [ */
266: {0x00, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x00, 0x00}, /* \ */
267: {0x00, 0x1C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1C, 0x00, 0x00}, /* ] */
268: {0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ^ */
269: {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00}, /* _ */
270: {0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ` */
271: {0x00, 0x00, 0x00, 0x1C, 0x02, 0x1E, 0x22, 0x1E, 0x00, 0x00}, /* a */
272: {0x00, 0x20, 0x20, 0x2C, 0x32, 0x22, 0x32, 0x2C, 0x00, 0x00}, /* b */
273: {0x00, 0x00, 0x00, 0x1C, 0x22, 0x20, 0x22, 0x1C, 0x00, 0x00}, /* c */
274: {0x00, 0x02, 0x02, 0x1A, 0x26, 0x22, 0x26, 0x1A, 0x00, 0x00}, /* d */
275: {0x00, 0x00, 0x00, 0x1C, 0x22, 0x3E, 0x20, 0x1C, 0x00, 0x00}, /* e */
276: {0x00, 0x0C, 0x12, 0x10, 0x3C, 0x10, 0x10, 0x10, 0x00, 0x00}, /* f */
277: {0x00, 0x00, 0x00, 0x1E, 0x22, 0x22, 0x1E, 0x02, 0x22, 0x1C}, /* g */
278: {0x00, 0x20, 0x20, 0x2C, 0x32, 0x22, 0x22, 0x22, 0x00, 0x00}, /* h */
279: {0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* i */
280: {0x00, 0x02, 0x00, 0x06, 0x02, 0x02, 0x02, 0x12, 0x12, 0x0C}, /* j */
281: {0x00, 0x20, 0x20, 0x22, 0x24, 0x38, 0x24, 0x22, 0x00, 0x00}, /* k */
282: {0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00}, /* l */
283: {0x00, 0x00, 0x00, 0x34, 0x2A, 0x2A, 0x2A, 0x22, 0x00, 0x00}, /* m */
284: {0x00, 0x00, 0x00, 0x2C, 0x32, 0x22, 0x22, 0x22, 0x00, 0x00}, /* n */
285: {0x00, 0x00, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x00}, /* o */
286: {0x00, 0x00, 0x00, 0x2C, 0x32, 0x22, 0x32, 0x2C, 0x20, 0x20}, /* p */
287: {0x00, 0x00, 0x00, 0x1A, 0x26, 0x22, 0x26, 0x1A, 0x02, 0x02}, /* q */
288: {0x00, 0x00, 0x00, 0x2C, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00}, /* r */
289: {0x00, 0x00, 0x00, 0x1C, 0x20, 0x1C, 0x02, 0x3C, 0x00, 0x00}, /* s */
290: {0x00, 0x10, 0x10, 0x3C, 0x10, 0x10, 0x12, 0x0C, 0x00, 0x00}, /* t */
291: {0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x26, 0x1A, 0x00, 0x00}, /* u */
292: {0x00, 0x00, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0x00}, /* v */
293: {0x00, 0x00, 0x00, 0x22, 0x22, 0x2A, 0x2A, 0x14, 0x00, 0x00}, /* w */
294: {0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00}, /* x */
295: {0x00, 0x00, 0x00, 0x22, 0x22, 0x26, 0x1A, 0x02, 0x22, 0x1C}, /* y */
296: {0x00, 0x00, 0x00, 0x3E, 0x04, 0x08, 0x10, 0x3E, 0x00, 0x00}, /* z */
297: {0x00, 0x06, 0x08, 0x04, 0x18, 0x04, 0x08, 0x06, 0x00, 0x00}, /* { */
298: {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, /* | */
299: {0x00, 0x18, 0x04, 0x08, 0x06, 0x08, 0x04, 0x18, 0x00, 0x00}, /* } */
300: {0x00, 0x12, 0x2A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ~ */
301: {0x00, 0x2A, 0x00, 0x22, 0x00, 0x22, 0x00, 0x2A, 0x00, 0x00}, /* ASCII 127 */
302: };
304: PETSC_STATIC_INLINE void PetscImageDrawText(PetscImage img,int x, int y,int c,const char text[])
305: {
306: int i,j,k, tw = PetscImageFontWidth, th = PetscImageFontHeight;
307: for (i = 0; i < th; i++) {
308: for (k = 0; text[k]; k++) {
309: int chr = PetscClipInterval(text[k],32,127);
310: for (j = 0; j < tw; j++) {
311: if (PetscImageFontBitmap[chr-32][i] & (1<<(tw-1-j)))
312: PetscImageDrawPixel(img,x+j+k*tw,y+i-th,c);
313: }
314: }
315: }
316: }
318: #endif