1 #include <rfb/rfb.h> 2 3 int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, 4 int x,int y,unsigned char c,rfbPixel col) 5 { 6 int i,j,width,height; 7 unsigned char* data=font->data+font->metaData[c*5]; 8 unsigned char d=*data; 9 int rowstride=rfbScreen->paddedWidthInBytes; 10 int bpp=rfbScreen->serverFormat.bitsPerPixel/8; 11 char *colour=(char*)&col; 12 13 if(!rfbEndianTest) 14 colour += 4-bpp; 15 16 width=font->metaData[c*5+1]; 17 height=font->metaData[c*5+2]; 18 x+=font->metaData[c*5+3]; 19 y+=-font->metaData[c*5+4]-height+1; 20 21 for(j=0;j<height;j++) { 22 for(i=0;i<width;i++) { 23 if((i&7)==0) { 24 d=*data; 25 data++; 26 } 27 if(d&0x80 && y+j >= 0 && y+j < rfbScreen->height && 28 x+i >= 0 && x+i < rfbScreen->width) 29 memcpy(rfbScreen->frameBuffer+(y+j)*rowstride+(x+i)*bpp,colour,bpp); 30 d<<=1; 31 } 32 /* if((i&7)!=0) data++; */ 33 } 34 return(width); 35 } 36 37 void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, 38 int x,int y,const char* string,rfbPixel colour) 39 { 40 while(*string) { 41 x+=rfbDrawChar(rfbScreen,font,x,y,*string,colour); 42 string++; 43 } 44 } 45 46 /* TODO: these two functions need to be more efficient */ 47 /* if col==bcol, assume transparent background */ 48 int rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, 49 int x,int y,unsigned char c, 50 int x1,int y1,int x2,int y2, 51 rfbPixel col,rfbPixel bcol) 52 { 53 int i,j,width,height; 54 unsigned char* data=font->data+font->metaData[c*5]; 55 unsigned char d; 56 int rowstride=rfbScreen->paddedWidthInBytes; 57 int bpp=rfbScreen->serverFormat.bitsPerPixel/8,extra_bytes=0; 58 char* colour=(char*)&col; 59 char* bcolour=(char*)&bcol; 60 61 if(!rfbEndianTest) { 62 colour+=4-bpp; 63 bcolour+=4-bpp; 64 } 65 66 width=font->metaData[c*5+1]; 67 height=font->metaData[c*5+2]; 68 x+=font->metaData[c*5+3]; 69 y+=-font->metaData[c*5+4]-height+1; 70 71 /* after clipping, x2 will be count of bytes between rows, 72 * x1 start of i, y1 start of j, width and height will be adjusted. */ 73 if(y1>y) { y1-=y; data+=(width+7)/8; height-=y1; y+=y1; } else y1=0; 74 if(x1>x) { x1-=x; data+=x1; width-=x1; x+=x1; extra_bytes+=x1/8; } else x1=0; 75 if(y2<y+height) height-=y+height-y2; 76 if(x2<x+width) { extra_bytes+=(x1+width)/8-(x+width-x2+7)/8; width-=x+width-x2; } 77 78 d=*data; 79 for(j=y1;j<height;j++) { 80 if((x1&7)!=0) 81 d=data[-1]; /* TODO: check if in this case extra_bytes is correct! */ 82 for(i=x1;i<width;i++) { 83 if((i&7)==0) { 84 d=*data; 85 data++; 86 } 87 /* if(x+i>=x1 && x+i<x2 && y+j>=y1 && y+j<y2) */ { 88 if(d&0x80) { 89 memcpy(rfbScreen->frameBuffer+(y+j)*rowstride+(x+i)*bpp, 90 colour,bpp); 91 } else if(bcol!=col) { 92 memcpy(rfbScreen->frameBuffer+(y+j)*rowstride+(x+i)*bpp, 93 bcolour,bpp); 94 } 95 } 96 d<<=1; 97 } 98 /* if((i&7)==0) data++; */ 99 data += extra_bytes; 100 } 101 return(width); 102 } 103 104 void rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, 105 int x,int y,const char* string, 106 int x1,int y1,int x2,int y2, 107 rfbPixel colour,rfbPixel backColour) 108 { 109 while(*string) { 110 x+=rfbDrawCharWithClip(rfbScreen,font,x,y,*string,x1,y1,x2,y2, 111 colour,backColour); 112 string++; 113 } 114 } 115 116 int rfbWidthOfString(rfbFontDataPtr font,const char* string) 117 { 118 int i=0; 119 while(*string) { 120 i+=font->metaData[*string*5+1]; 121 string++; 122 } 123 return(i); 124 } 125 126 int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c) 127 { 128 return(font->metaData[c*5+1]+font->metaData[c*5+3]); 129 } 130 131 void rfbFontBBox(rfbFontDataPtr font,unsigned char c,int* x1,int* y1,int* x2,int* y2) 132 { 133 *x1+=font->metaData[c*5+3]; 134 *y1+=-font->metaData[c*5+4]-font->metaData[c*5+2]+1; 135 *x2=*x1+font->metaData[c*5+1]+1; 136 *y2=*y1+font->metaData[c*5+2]+1; 137 } 138 139 #ifndef INT_MAX 140 #define INT_MAX 0x7fffffff 141 #endif 142 143 void rfbWholeFontBBox(rfbFontDataPtr font, 144 int *x1, int *y1, int *x2, int *y2) 145 { 146 int i; 147 int* m=font->metaData; 148 149 (*x1)=(*y1)=INT_MAX; (*x2)=(*y2)=1-(INT_MAX); 150 for(i=0;i<256;i++) { 151 if(m[i*5+1]-m[i*5+3]>(*x2)) 152 (*x2)=m[i*5+1]-m[i*5+3]; 153 if(-m[i*5+2]+m[i*5+4]<(*y1)) 154 (*y1)=-m[i*5+2]+m[i*5+4]; 155 if(m[i*5+3]<(*x1)) 156 (*x1)=m[i*5+3]; 157 if(-m[i*5+4]>(*y2)) 158 (*y2)=-m[i*5+4]; 159 } 160 (*x2)++; 161 (*y2)++; 162 } 163 164 rfbFontDataPtr rfbLoadConsoleFont(char *filename) 165 { 166 FILE *f=fopen(filename,"rb"); 167 rfbFontDataPtr p; 168 int i; 169 170 if(!f) return NULL; 171 172 p=(rfbFontDataPtr)malloc(sizeof(rfbFontData)); 173 p->data=(unsigned char*)malloc(4096); 174 if(1!=fread(p->data,4096,1,f)) { 175 free(p->data); 176 free(p); 177 return NULL; 178 } 179 fclose(f); 180 p->metaData=(int*)malloc(256*5*sizeof(int)); 181 for(i=0;i<256;i++) { 182 p->metaData[i*5+0]=i*16; /* offset */ 183 p->metaData[i*5+1]=8; /* width */ 184 p->metaData[i*5+2]=16; /* height */ 185 p->metaData[i*5+3]=0; /* xhot */ 186 p->metaData[i*5+4]=0; /* yhot */ 187 } 188 return(p); 189 } 190 191 void rfbFreeFont(rfbFontDataPtr f) 192 { 193 free(f->data); 194 free(f->metaData); 195 free(f); 196 } 197