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