PageRenderTime 31ms CodeModel.GetById 2ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/apps/desktop/libvncserver/font.c

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