Rev 5025 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5025 | Rev 6865 | ||
---|---|---|---|
1 | #include |
1 | #include |
2 | #include |
2 | #include |
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include |
5 | #include |
6 | #include FT_FREETYPE_H |
6 | #include FT_FREETYPE_H |
7 | #include FT_GLYPH_H |
7 | #include FT_GLYPH_H |
8 | #include |
8 | #include |
9 | 9 | ||
10 | typedef struct |
- | |
11 | { |
- | |
12 | int l; |
- | |
13 | int t; |
- | |
14 | int r; |
- | |
15 | int b; |
- | |
16 | }rect_t; |
- | |
17 | - | ||
18 | typedef struct |
10 | typedef struct |
19 | { |
11 | { |
20 | FT_Face face; |
12 | FT_Face face; |
21 | int height; |
13 | int fontsize; |
- | 14 | int height; |
|
22 | int base; |
15 | int base; |
23 | 16 | ||
24 | FT_Glyph glyph[256]; |
17 | FT_Glyph glyph[256]; |
25 | 18 | ||
26 | }font_t; |
19 | }font_t; |
27 | 20 | ||
28 | static FT_Face def_face; |
21 | static FT_Face def_face; |
29 | 22 | static FT_Face sym_face; |
|
- | 23 | ||
- | 24 | font_t *sym_font; |
|
- | 25 | ||
30 | typedef unsigned int color_t; |
26 | typedef unsigned int color_t; |
31 | 27 | ||
32 | unsigned int ansi2utf32(unsigned char ch); |
28 | unsigned int ansi2utf32(unsigned char ch); |
33 | 29 | ||
34 | font_t *create_font(FT_Face face, int size); |
30 | font_t *create_font(FT_Face face, int size); |
35 | 31 | ||
36 | void my_draw_bitmap(bitmap_t *win, FT_Bitmap *bitmap, int dstx, int dsty, int col) |
32 | void draw_glyph(ctx_t *ctx, void *buffer, int pitch, rect_t *rc, color_t color); |
37 | { |
- | |
38 | uint8_t *dst; |
- | |
39 | uint8_t *src, *tmpsrc; |
- | |
40 | - | ||
41 | uint32_t *tmpdst; |
- | |
42 | int i, j; |
- | |
43 | - | ||
44 | dst = win->data + dsty * win->pitch + dstx*4; |
- | |
45 | src = bitmap->buffer; |
- | |
46 | - | ||
47 | // printf("buffer %x width %d rows %d\n", |
- | |
48 | // bitmap->buffer, bitmap->width, bitmap->rows); |
- | |
49 | - | ||
50 | 33 | ||
51 | for( i = 0; i < bitmap->rows; i++ ) |
- | |
52 | { |
- | |
53 | tmpdst = (uint32_t*)dst; |
- | |
54 | tmpsrc = src; |
- | |
55 | - | ||
56 | dst+= win->pitch; |
- | |
57 | src+= bitmap->pitch; |
- | |
58 | - | ||
59 | for( j = 0; j < bitmap->width; j++) |
34 | unsigned int ansi2utf32(unsigned char ch) |
60 | { |
- | |
61 | int a = *tmpsrc++; |
35 | { |
62 | int sr, sg, sb; |
36 | if(ch < 0x80) |
63 | int dr, dg, db; |
- | |
64 | - | ||
65 | if( a != 0) a++; |
37 | return ch; |
66 | 38 | ||
67 | db = *tmpdst & 0xFF; |
- | |
68 | dg = (*tmpdst >> 8) & 0xFF; |
39 | if(ch < 0xB0) |
69 | dr = (*tmpdst >> 16) & 0xFF; |
- | |
70 | 40 | return 0x410-0x80 + ch; |
|
71 | sb = col & 0xFF; |
- | |
72 | sg = (col >> 8) & 0xFF; |
41 | |
73 | sr = (col >> 16) &0xFF; |
42 | if(ch < 0xE0) |
- | 43 | return 0; |
|
74 | 44 | ||
- | 45 | if(ch < 0xF0) |
|
75 | db = (a*sb + db*(256-a))/256; |
46 | return 0x440-0xE0 + ch; |
- | 47 | ||
76 | dg = (a*sg + dg*(256-a))/256; |
48 | if(ch == 0xF0) |
77 | dr = (a*sr + dr*(256-a))/256; |
- | |
78 | - | ||
79 | *tmpdst++ = 0xFF000000|(dr<<16)|(dg<<8)|db; |
49 | return 0x401; |
80 | }; |
50 | else if(ch==0xF1) |
81 | } |
51 | return 0x451; |
82 | }; |
52 | else return 0; |
83 | 53 | } |
|
84 | 54 | ||
85 | int draw_text_ext(bitmap_t *winbitmap, font_t *font, char *text, int len, rect_t *rc, int color) |
55 | int draw_text_ext(ctx_t *ctx, font_t *font, char *text, int len, rect_t *rc, color_t color) |
86 | { |
56 | { |
87 | FT_UInt glyph_index; |
57 | FT_UInt glyph_index; |
88 | FT_Bool use_kerning = 0; |
58 | FT_Bool use_kerning = 0; |
89 | FT_BitmapGlyph glyph; |
59 | FT_BitmapGlyph glyph; |
90 | FT_UInt previous; |
60 | FT_UInt previous; |
91 | 61 | ||
92 | int x, y, w; |
62 | int x, y, xend; |
93 | int col, ncol; |
63 | int col, ncol; |
94 | unsigned char ch; |
64 | unsigned char ch; |
95 | int err = 0; |
65 | int err = 0; |
96 | 66 | ||
97 | use_kerning = FT_HAS_KERNING( font->face ); |
67 | use_kerning = FT_HAS_KERNING( font->face ); |
98 | previous = 0; |
68 | previous = 0; |
99 | col = 0; |
69 | col = 0; |
100 | 70 | ||
101 | x = rc->l << 6; |
71 | x = rc->l << 6; |
102 | y = rc->b; |
72 | xend = rc->r << 6; |
103 | 73 | y = rc->t + font->base; |
|
104 | w = (rc->r - rc->l) << 6; |
- | |
105 | 74 | ||
106 | while( len-- ) |
75 | while( len-- ) |
107 | { |
76 | { |
108 | ch = *text++; |
77 | ch = *text++; |
109 | 78 | ||
110 | if(ch == '\n' || ch == '\r') |
79 | if(ch == '\n' || ch == '\r') |
111 | continue; |
80 | continue; |
112 | 81 | ||
113 | if(ch == '\t') |
82 | if(ch == '\t') |
114 | { |
83 | { |
115 | ncol = (col+4) & ~3; |
84 | ncol = (col+3) & ~4; |
116 | if( col < ncol) |
85 | if( col < ncol) |
117 | { |
86 | { |
118 | glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(' ') ); |
87 | glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(' ') ); |
119 | 88 | ||
120 | while( col < ncol) |
89 | while( col < ncol) |
121 | { |
90 | { |
122 | if ( use_kerning && previous && glyph_index ) |
91 | if ( use_kerning && previous && glyph_index ) |
123 | { |
92 | { |
124 | FT_Vector delta; |
93 | FT_Vector delta; |
125 | FT_Get_Kerning( font->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta ); |
94 | FT_Get_Kerning( font->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta ); |
126 | x += delta.x ; |
95 | x += delta.x ; |
127 | } |
96 | } |
128 | 97 | ||
129 | if( x + (font->glyph[ch]->advance.x >> 10) > w) |
98 | if( x + (font->glyph[ch]->advance.x >> 10) >= xend) |
130 | break; |
99 | break; |
131 | 100 | ||
132 | x += font->glyph[ch]->advance.x >> 10; |
101 | x += font->glyph[ch]->advance.x >> 10; |
133 | previous = glyph_index; |
102 | previous = glyph_index; |
134 | col ++; |
103 | col ++; |
135 | }; |
104 | }; |
136 | }; |
105 | }; |
137 | continue; |
106 | continue; |
138 | }; |
107 | }; |
139 | 108 | ||
140 | glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(ch) ); |
109 | glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(ch) ); |
141 | 110 | ||
142 | if ( use_kerning && previous && glyph_index ) |
111 | if ( use_kerning && previous && glyph_index ) |
143 | { |
112 | { |
144 | FT_Vector delta; |
113 | FT_Vector delta; |
145 | FT_Get_Kerning( font->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta ); |
114 | FT_Get_Kerning( font->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta ); |
146 | x += delta.x ; |
115 | x += delta.x ; |
147 | } |
116 | } |
148 | 117 | ||
149 | if( x + (font->glyph[ch]->advance.x >> 10) > w) |
118 | // if( x + (font->glyph[ch]->advance.x >> 10) >= xend) |
- | 119 | // break; |
|
- | 120 | ||
- | 121 | if( x >= xend) |
|
150 | break; |
122 | break; |
151 | 123 | ||
152 | glyph = (FT_BitmapGlyph)font->glyph[ch]; |
124 | glyph = (FT_BitmapGlyph)font->glyph[ch]; |
153 | 125 | ||
- | 126 | if(glyph != NULL) |
|
- | 127 | { |
|
- | 128 | rect_t rc_dst; |
|
- | 129 | ||
154 | my_draw_bitmap(winbitmap, &glyph->bitmap, (x >> 6) + glyph->left, |
130 | rc_dst.l = (x >> 6) + glyph->left; |
155 | y - glyph->top, color); |
131 | rc_dst.t = y - glyph->top; |
- | 132 | rc_dst.r = rc_dst.l + glyph->bitmap.width; |
|
- | 133 | if(rc_dst.r > (xend >> 6)) |
|
- | 134 | rc_dst.r = xend >> 6; |
|
- | 135 | rc_dst.b = rc_dst.t + glyph->bitmap.rows; |
|
- | 136 | ||
- | 137 | // printf("char: %c ", ch); |
|
- | 138 | px_draw_glyph(ctx, glyph->bitmap.buffer, glyph->bitmap.pitch, &rc_dst, color); |
|
156 | 139 | ||
- | 140 | x += font->glyph[ch]->advance.x >> 10; |
|
157 | x += font->glyph[ch]->advance.x >> 10; |
141 | }; |
158 | previous = glyph_index; |
142 | previous = glyph_index; |
159 | }; |
143 | }; |
160 | 144 | ||
161 | return err; |
145 | return err; |
162 | }; |
146 | }; |
163 | 147 | ||
164 | 148 | ||
165 | int init_fontlib() |
149 | int init_fontlib() |
166 | { |
150 | { |
167 | static FT_Library library; |
151 | static FT_Library library; |
168 | FT_Face face = NULL; |
152 | FT_Face face = NULL; |
169 | int err; |
153 | int err; |
170 | 154 | ||
171 | err = FT_Init_FreeType( &library ); |
155 | err = FT_Init_FreeType( &library ); |
172 | if ( err ) |
156 | if ( err ) |
173 | { |
157 | { |
174 | printf("an error occurred during FreeType initialization\n"); |
158 | printf("an error occurred during FreeType initialization\n"); |
175 | goto done; |
159 | goto done; |
176 | } |
160 | } |
177 | 161 | ||
178 | // err = FT_New_Face( library, "/kolibrios/Fonts/IstokWeb.ttf", 0, &face ); |
162 | // err = FT_New_Face( library, "/kolibrios/Fonts/IstokWeb.ttf", 0, &face ); |
179 | // err = FT_New_Face( library, "/kolibrios/Fonts/lucon.ttf", 0, &face ); |
163 | // err = FT_New_Face( library, "/kolibrios/Fonts/lucon.ttf", 0, &face ); |
180 | 164 | ||
181 | err = FT_New_Face( library, "/kolibrios/Fonts/DroidSansMono.ttf", 0, &face ); |
165 | err = FT_New_Face( library, "/kolibrios/Fonts/DroidSansMono.ttf", 0, &face ); |
182 | 166 | if ( err == FT_Err_Unknown_File_Format ) |
|
183 | if ( err == FT_Err_Unknown_File_Format ) |
- | |
184 | { |
167 | { |
185 | printf("font format is unsupported\n"); |
168 | printf("font format is unsupported\n"); |
186 | goto done; |
169 | goto done; |
187 | 170 | ||
188 | } |
171 | } |
189 | else if ( err ) |
172 | else if ( err ) |
190 | { |
173 | { |
191 | printf("font file could not be read or broken\n"); |
174 | printf("font file could not be read or broken\n"); |
192 | goto done; |
175 | goto done; |
193 | 176 | } |
|
194 | } |
- | |
195 | 177 | ||
196 | def_face = face; |
178 | def_face = face; |
197 | 179 | ||
- | 180 | err = FT_New_Face( library, "/kolibrios/Fonts/Symbols.ttf", 0, &face ); |
|
- | 181 | if ( err == FT_Err_Unknown_File_Format ) |
|
198 | done: |
182 | { |
- | 183 | printf("font format is unsupported\n"); |
|
- | 184 | goto done; |
|
- | 185 | ||
199 | 186 | } |
|
200 | return err; |
187 | else if ( err ) |
- | 188 | { |
|
- | 189 | printf("font file could not be read or broken\n"); |
|
- | 190 | goto done; |
|
- | 191 | } |
|
201 | }; |
192 | |
202 | - | ||
203 | - | ||
204 | unsigned int ansi2utf32(unsigned char ch) |
- | |
205 | { |
193 | sym_face = face; |
206 | if(ch < 0x80) |
- | |
207 | return ch; |
- | |
208 | 194 | ||
- | 195 | sym_font = create_font(sym_face, 14); |
|
209 | if(ch < 0xB0) |
- | |
210 | return 0x410-0x80 + ch; |
- | |
211 | - | ||
212 | if(ch < 0xE0) |
- | |
213 | return 0; |
- | |
214 | - | ||
215 | if(ch < 0xF0) |
- | |
216 | return 0x440-0xE0 + ch; |
- | |
217 | 196 | ||
218 | if(ch == 0xF0) |
197 | done: |
219 | return 0x401; |
198 | |
220 | else if(ch==0xF1) |
199 | return err; |
221 | return 0x451; |
200 | }; |
222 | else return 0; |
201 | |
223 | } |
202 | |
224 | 203 | ||
225 | 204 | ||
226 | font_t *create_font(FT_Face xface, int size) |
205 | font_t *create_font(FT_Face xface, int size) |
227 | { |
206 | { |
228 | font_t *font; |
207 | font_t *font; |
229 | int i, err; |
208 | int i, err; |
230 | 209 | ||
231 | font = malloc(sizeof(*font)); |
210 | font = malloc(sizeof(*font)); |
232 | if(font == NULL) |
211 | if(font == NULL) |
233 | return font; |
212 | return font; |
234 | 213 | ||
235 | memset(font, 0, sizeof(*font)); |
214 | memset(font, 0, sizeof(*font)); |
236 | 215 | ||
237 | font->face = (xface == NULL) ? def_face : xface; |
216 | font->face = (xface == NULL) ? def_face : xface; |
238 | font->height = size+1; |
217 | font->height = size; |
239 | 218 | ||
240 | err = FT_Set_Pixel_Sizes( font->face, 0, size ); |
219 | err = FT_Set_Pixel_Sizes( font->face, 0, size ); |
241 | 220 | ||
242 | for(i = 0; i < 256; i++) |
221 | for(i = 0; i < 256; i++) |
243 | { |
222 | { |
244 | FT_UInt glyph_index; |
223 | FT_UInt glyph_index; |
245 | FT_BitmapGlyph glyph_bitmap; |
224 | FT_BitmapGlyph glyph_bitmap; |
246 | 225 | ||
247 | glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(i) ); |
226 | glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(i) ); |
248 | 227 | ||
249 | err = FT_Load_Glyph( font->face, glyph_index, FT_LOAD_DEFAULT ); |
228 | err = FT_Load_Glyph( font->face, glyph_index, FT_LOAD_DEFAULT ); |
250 | if ( err ) |
229 | if ( err ) |
251 | { |
230 | { |
252 | font->glyph[i] = font->glyph[0] ; |
231 | font->glyph[i] = font->glyph[0] ; |
253 | continue; |
232 | continue; |
254 | }; |
233 | }; |
255 | 234 | ||
256 | err = FT_Get_Glyph( font->face->glyph, &font->glyph[i] ); |
235 | err = FT_Get_Glyph( font->face->glyph, &font->glyph[i] ); |
257 | if (err) |
236 | if (err) |
258 | { |
237 | { |
259 | font->glyph[i] = font->glyph[0] ; |
238 | font->glyph[i] = font->glyph[0] ; |
260 | continue; |
239 | continue; |
261 | }; |
240 | }; |
262 | 241 | ||
263 | if ( font->glyph[i]->format != FT_GLYPH_FORMAT_BITMAP ) |
242 | if ( font->glyph[i]->format != FT_GLYPH_FORMAT_BITMAP ) |
264 | { |
243 | { |
265 | err = FT_Glyph_To_Bitmap( &font->glyph[i], FT_RENDER_MODE_NORMAL, 0, 1 ); |
244 | err = FT_Glyph_To_Bitmap( &font->glyph[i], FT_RENDER_MODE_NORMAL, 0, 1 ); |
266 | if ( err ) |
245 | if ( err ) |
267 | continue; |
246 | continue; |
268 | 247 | ||
269 | glyph_bitmap = (FT_BitmapGlyph)font->glyph[i]; |
248 | glyph_bitmap = (FT_BitmapGlyph)font->glyph[i]; |
270 | 249 | ||
271 | if(glyph_bitmap->top > font->base) |
250 | if(glyph_bitmap->top > font->base) |
272 | font->base = glyph_bitmap->top; |
251 | font->base = glyph_bitmap->top; |
273 | } |
252 | } |
274 | } |
253 | } |
275 | 254 | ||
276 | return font; |
255 | return font; |
277 | }>>>>>>>><>><>8)|db; |
256 | } |
278 | ><8)|db; |
257 | |
- | 258 | int get_font_height(font_t *font) |
|
- | 259 | { |
|
- | 260 | return font->height; |
|
- | 261 | }>>>><>><>>>>> |
|
- | 262 | ||
- | 263 | ||
279 | >16)|(dg<<8)|db; |
- | |
280 | ><16)|(dg<<8)|db; |
- | |
281 | >>> |
- |