#include "rfb/rfb.h" int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, int x,int y,unsigned char c,rfbPixel col) { int i,j,width,height; unsigned char* data=font->data+font->metaData[c*5]; unsigned char d=*data; int rowstride=rfbScreen->paddedWidthInBytes; int bpp=rfbScreen->serverFormat.bitsPerPixel/8; char *colour=(char*)&col; if(!rfbEndianTest) colour += 4-bpp; width=font->metaData[c*5+1]; height=font->metaData[c*5+2]; x+=font->metaData[c*5+3]; y+=-font->metaData[c*5+4]-height+1; for(j=0;jframeBuffer+(y+j)*rowstride+(x+i)*bpp,colour,bpp); d<<=1; } /* if((i&7)!=0) data++; */ } return(width); } void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, int x,int y,const char* string,rfbPixel colour) { while(*string) { x+=rfbDrawChar(rfbScreen,font,x,y,*string,colour); string++; } } /* TODO: these two functions need to be more efficient */ /* if col==bcol, assume transparent background */ int rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, int x,int y,unsigned char c, int x1,int y1,int x2,int y2, rfbPixel col,rfbPixel bcol) { int i,j,width,height; unsigned char* data=font->data+font->metaData[c*5]; unsigned char d; int rowstride=rfbScreen->paddedWidthInBytes; int bpp=rfbScreen->serverFormat.bitsPerPixel/8,extra_bytes=0; char* colour=(char*)&col; char* bcolour=(char*)&bcol; if(!rfbEndianTest) { colour+=4-bpp; bcolour+=4-bpp; } width=font->metaData[c*5+1]; height=font->metaData[c*5+2]; x+=font->metaData[c*5+3]; y+=-font->metaData[c*5+4]-height+1; /* after clipping, x2 will be count of bytes between rows, * x1 start of i, y1 start of j, width and height will be adjusted. */ if(y1>y) { y1-=y; data+=(width+7)/8; height-=y1; y+=y1; } else y1=0; if(x1>x) { x1-=x; data+=x1; width-=x1; x+=x1; extra_bytes+=x1/8; } else x1=0; if(y2=x1 && x+i=y1 && y+jframeBuffer+(y+j)*rowstride+(x+i)*bpp, colour,bpp); } else if(bcol!=col) { memcpy(rfbScreen->frameBuffer+(y+j)*rowstride+(x+i)*bpp, bcolour,bpp); } } d<<=1; } /* if((i&7)==0) data++; */ data += extra_bytes; } return(width); } void rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, int x,int y,const char* string, int x1,int y1,int x2,int y2, rfbPixel colour,rfbPixel backColour) { while(*string) { x+=rfbDrawCharWithClip(rfbScreen,font,x,y,*string,x1,y1,x2,y2, colour,backColour); string++; } } int rfbWidthOfString(rfbFontDataPtr font,const char* string) { int i=0; while(*string) { i+=font->metaData[*string*5+1]; string++; } return(i); } int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c) { return(font->metaData[c*5+1]+font->metaData[c*5+3]); } void rfbFontBBox(rfbFontDataPtr font,unsigned char c,int* x1,int* y1,int* x2,int* y2) { *x1+=font->metaData[c*5+3]; *y1+=-font->metaData[c*5+4]-font->metaData[c*5+2]+1; *x2=*x1+font->metaData[c*5+1]+1; *y2=*y1+font->metaData[c*5+2]+1; } #ifndef INT_MAX #define INT_MAX 0x7fffffff #endif void rfbWholeFontBBox(rfbFontDataPtr font, int *x1, int *y1, int *x2, int *y2) { int i; int* m=font->metaData; (*x1)=(*y1)=INT_MAX; (*x2)=(*y2)=1-(INT_MAX); for(i=0;i<256;i++) { if(m[i*5+1]-m[i*5+3]>(*x2)) (*x2)=m[i*5+1]-m[i*5+3]; if(-m[i*5+2]+m[i*5+4]<(*y1)) (*y1)=-m[i*5+2]+m[i*5+4]; if(m[i*5+3]<(*x1)) (*x1)=m[i*5+3]; if(-m[i*5+4]>(*y2)) (*y2)=-m[i*5+4]; } (*x2)++; (*y2)++; } rfbFontDataPtr rfbLoadConsoleFont(char *filename) { FILE *f=fopen(filename,"rb"); rfbFontDataPtr p; int i; if(!f) return NULL; p=(rfbFontDataPtr)malloc(sizeof(rfbFontData)); p->data=(unsigned char*)malloc(4096); if(1!=fread(p->data,4096,1,f)) { free(p->data); free(p); return NULL; } fclose(f); p->metaData=(int*)malloc(256*5*sizeof(int)); for(i=0;i<256;i++) { p->metaData[i*5+0]=i*16; /* offset */ p->metaData[i*5+1]=8; /* width */ p->metaData[i*5+2]=16; /* height */ p->metaData[i*5+3]=0; /* xhot */ p->metaData[i*5+4]=0; /* yhot */ } return(p); } void rfbFreeFont(rfbFontDataPtr f) { free(f->data); free(f->metaData); free(f); }