1 #include <rfb/rfb.h>
2
rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,rfbPixel col)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
rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char * string,rfbPixel colour)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 */
rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,int x1,int y1,int x2,int y2,rfbPixel col,rfbPixel bcol)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
rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char * string,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour)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
rfbWidthOfString(rfbFontDataPtr font,const char * string)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
rfbWidthOfChar(rfbFontDataPtr font,unsigned char c)126 int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c)
127 {
128 return(font->metaData[c*5+1]+font->metaData[c*5+3]);
129 }
130
rfbFontBBox(rfbFontDataPtr font,unsigned char c,int * x1,int * y1,int * x2,int * y2)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
rfbWholeFontBBox(rfbFontDataPtr font,int * x1,int * y1,int * x2,int * y2)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
rfbLoadConsoleFont(char * filename)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
rfbFreeFont(rfbFontDataPtr f)191 void rfbFreeFont(rfbFontDataPtr f)
192 {
193 free(f->data);
194 free(f->metaData);
195 free(f);
196 }
197