1 /**
2  * xrdp: A Remote Desktop Protocol server.
3  *
4  * Copyright (C) Jay Sorg 2004-2014
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * fonts
19  */
20 
21 /*
22   The fv1 files contain
23   Font File Header (just one)
24     FNT1       4 bytes
25     Font Name  32 bytes
26     Font Size  2 bytes
27     Font Style 2 bytes
28     Pad        8 bytes
29   Font Data (repeats)
30     Width      2 bytes
31     Height     2 bytes
32     Baseline   2 bytes
33     Offset     2 bytes
34     Incby      2 bytes
35     Pad        6 bytes
36     Glyph Data var, see FONT_DATASIZE macro
37 */
38 
39 #if defined(HAVE_CONFIG_H)
40 #include <config_ac.h>
41 #endif
42 
43 #include "xrdp.h"
44 #include "log.h"
45 
46 #if 0 /* not used */
47 static char w_char[] =
48 {
49     0x00, 0x00, 0x00,
50     0x00, 0x00, 0x00,
51     0x00, 0x00, 0x00,
52     0x08, 0x20, 0x80,
53     0x08, 0x50, 0x80,
54     0x04, 0x51, 0x00,
55     0x04, 0x51, 0x00,
56     0x04, 0x51, 0x00,
57     0x02, 0x8a, 0x00,
58     0x02, 0x8a, 0x00,
59     0x02, 0x8a, 0x00,
60     0x01, 0x04, 0x00,
61     0x01, 0x04, 0x00,
62     0x00, 0x00, 0x00,
63     0x00, 0x00, 0x00,
64     0x00, 0x00, 0x00,
65 };
66 #endif
67 
68 /*****************************************************************************/
69 struct xrdp_font *
xrdp_font_create(struct xrdp_wm * wm)70 xrdp_font_create(struct xrdp_wm *wm)
71 {
72     struct xrdp_font *self;
73     struct stream *s;
74     int fd;
75     int b;
76     int i;
77     int index;
78     int datasize;
79     int file_size;
80     struct xrdp_font_char *f;
81     char file_path[256];
82 
83     LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_font_create");
84     g_snprintf(file_path, 255, "%s/%s", XRDP_SHARE_PATH, DEFAULT_FONT_NAME);
85 
86     if (!g_file_exist(file_path))
87     {
88         LOG(LOG_LEVEL_ERROR, "xrdp_font_create: error font file [%s] does not exist",
89             file_path);
90         return 0;
91     }
92 
93     file_size = g_file_get_size(file_path);
94 
95     if (file_size < 1)
96     {
97         LOG(LOG_LEVEL_ERROR, "xrdp_font_create: error reading font from file [%s]",
98             file_path);
99         return 0;
100     }
101 
102     self = (struct xrdp_font *)g_malloc(sizeof(struct xrdp_font), 1);
103     self->wm = wm;
104     make_stream(s);
105     init_stream(s, file_size + 1024);
106     fd = g_file_open(file_path);
107 
108     if (fd != -1)
109     {
110         b = g_file_read(fd, s->data, file_size + 1024);
111         g_file_close(fd);
112 
113         if (b > 0)
114         {
115             s->end = s->data + b;
116             in_uint8s(s, 4);
117             in_uint8a(s, self->name, 32);
118             in_uint16_le(s, self->size);
119             in_uint16_le(s, self->style);
120             in_uint8s(s, 8);
121             index = 32;
122 
123             while (s_check_rem(s, 16))
124             {
125                 f = self->font_items + index;
126                 in_sint16_le(s, i);
127                 f->width = i;
128                 in_sint16_le(s, i);
129                 f->height = i;
130                 in_sint16_le(s, i);
131                 f->baseline = i;
132                 in_sint16_le(s, i);
133                 f->offset = i;
134                 in_sint16_le(s, i);
135                 f->incby = i;
136                 in_uint8s(s, 6);
137                 datasize = FONT_DATASIZE(f);
138 
139                 if (datasize < 0 || datasize > 512)
140                 {
141                     /* shouldn't happen */
142                     LOG(LOG_LEVEL_ERROR, "error in xrdp_font_create, datasize wrong "
143                         "width %d, height %d, datasize %d, index %d",
144                         f->width, f->height, datasize, index);
145                     break;
146                 }
147 
148                 if (s_check_rem(s, datasize))
149                 {
150                     f->data = (char *)g_malloc(datasize, 0);
151                     in_uint8a(s, f->data, datasize);
152                 }
153                 else
154                 {
155                     LOG(LOG_LEVEL_ERROR, "error in xrdp_font_create");
156                 }
157 
158                 index++;
159             }
160         }
161     }
162 
163     free_stream(s);
164     /*
165       self->font_items[0].offset = -4;
166       self->font_items[0].baseline = -16;
167       self->font_items[0].width = 24;
168       self->font_items[0].height = 16;
169       self->font_items[0].data = g_malloc(3 * 16, 0);
170       g_memcpy(self->font_items[0].data, w_char, 3 * 16);
171     */
172     LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_font_create");
173     return self;
174 }
175 
176 /*****************************************************************************/
177 /* free the font and all the items */
178 void
xrdp_font_delete(struct xrdp_font * self)179 xrdp_font_delete(struct xrdp_font *self)
180 {
181     int i;
182 
183     if (self == 0)
184     {
185         return;
186     }
187 
188     for (i = 0; i < NUM_FONTS; i++)
189     {
190         g_free(self->font_items[i].data);
191     }
192 
193     g_free(self);
194 }
195 
196 /*****************************************************************************/
197 /* compare the two font items returns 1 if they match */
198 int
xrdp_font_item_compare(struct xrdp_font_char * font1,struct xrdp_font_char * font2)199 xrdp_font_item_compare(struct xrdp_font_char *font1,
200                        struct xrdp_font_char *font2)
201 {
202     int datasize;
203 
204     if (font1 == 0)
205     {
206         return 0;
207     }
208 
209     if (font2 == 0)
210     {
211         return 0;
212     }
213 
214     if (font1->offset != font2->offset)
215     {
216         return 0;
217     }
218 
219     if (font1->baseline != font2->baseline)
220     {
221         return 0;
222     }
223 
224     if (font1->width != font2->width)
225     {
226         return 0;
227     }
228 
229     if (font1->height != font2->height)
230     {
231         return 0;
232     }
233 
234     datasize = FONT_DATASIZE(font1);
235 
236     if (g_memcmp(font1->data, font2->data, datasize) == 0)
237     {
238         return 1;
239     }
240 
241     return 0;
242 }
243