/apps/desktop/libvncserver/font.c

http://ftk.googlecode.com/ · C · 195 lines · 168 code · 21 blank · 6 comment · 30 complexity · 46c051a3a19d41b96af5fda44ecdff91 MD5 · raw file

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