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