LibVNCServer/LibVNCClient
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
font.c
Go to the documentation of this file.
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 }