/apps/desktop/libvncserver/font.c
http://ftk.googlecode.com/ · C · 195 lines · 168 code · 21 blank · 6 comment · 30 complexity · 46c051a3a19d41b96af5fda44ecdff91 MD5 · raw file
- #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;j<height;j++) {
- for(i=0;i<width;i++) {
- if((i&7)==0) {
- d=*data;
- data++;
- }
- if(d&0x80)
- memcpy(rfbScreen->frameBuffer+(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<y+height) height-=y+height-y2;
- if(x2<x+width) { extra_bytes+=(x1+width)/8-(x+width-x2+7)/8; width-=x+width-x2; }
- d=*data;
- for(j=y1;j<height;j++) {
- if((x1&7)!=0)
- d=data[-1]; /* TODO: check if in this case extra_bytes is correct! */
- for(i=x1;i<width;i++) {
- if((i&7)==0) {
- d=*data;
- data++;
- }
- /* if(x+i>=x1 && x+i<x2 && y+j>=y1 && y+j<y2) */ {
- if(d&0x80) {
- memcpy(rfbScreen->frameBuffer+(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);
- }