Mercurial > otakunoraifu
annotate font/font_peer_ft2.cc @ 66:d112357a0ec1
Fix a bug with savegames introduced with changeset c7bcc0ec2267.
Warning: savegames created since c7bcc0ec2267 are probably corrupted,
you may have to start the game over.
If you chose not to do so, you should replace all occurrences of 'TextWindow' by 'TextImplWindow',
and 'Text Window' by 'TextImpl Window' in your save files.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sat, 11 Dec 2010 18:36:20 +0100 |
parents | 4416cfac86ae |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright (c) 2004 Kazunori "jagarl" Ueno | |
3 * Copyright (c) 2000, 2001 Yuki Sawada | |
4 * All rights reserved. | |
5 * | |
6 * Redistribution and use in source and binary forms, with or without | |
7 * modification, are permitted provided that the following conditions | |
8 * are met: | |
9 * 1. Redistributions of source code must retain the above copyright | |
10 * notice, this list of conditions and the following disclaimer. | |
11 * 2. Redistributions in binary form must reproduce the above copyright | |
12 * notice, this list of conditions and the following disclaimer in the | |
13 * documentation and/or other materials provided with the distribution. | |
14 * 3. The name of the author may not be used to endorse or promote products | |
15 * derived from this software without specific prior written permission. | |
16 * | |
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 */ | |
28 | |
29 #include <stdio.h> | |
30 #include <stdlib.h> | |
31 #include <string.h> | |
32 #include <stdexcept> | |
33 #include <string> | |
34 | |
35 using namespace std; | |
36 | |
37 #include "font.h" | |
38 #include "font_peer.h" | |
39 #include "codeconv.h" | |
40 | |
41 namespace XKFont { | |
42 | |
43 typedef struct _FontLibrary { | |
52 | 44 FT_Library super; |
45 int ref_count; | |
46 char **paths; | |
47 int num_paths; | |
0 | 48 } FontLibrary; |
49 | |
50 static FontLibrary *library = NULL; | |
51 | |
47
5f548e5957a8
* get rid of the "deprecated conversion from string constant to ‘char*’" warnings
thib
parents:
0
diff
changeset
|
52 static const char *default_paths[] = { |
0 | 53 ".", |
54 "/", | |
55 "/usr/X11R6/lib/X11/fonts/TrueType", | |
56 "/usr/local/share/fonts/TrueType", | |
57 "/usr//share/fonts/TrueType", | |
58 "/usr//share/fonts/tt", | |
59 NULL | |
60 }; | |
61 | |
62 static void font_library_ft2_add_path(const char *path); | |
63 static void font_library_ft2_remove_path(const char *path); | |
64 static void font_library_ft2_add_path(const char *path); | |
65 static char *font_library_ft2_build_path(const char *base, const char *name); | |
66 | |
52 | 67 static int font_library_ft2_alloc() |
0 | 68 { |
52 | 69 int i; |
0 | 70 |
52 | 71 if (!library) { |
72 library = (FontLibrary*) calloc(sizeof(FontLibrary), 1); | |
73 if (library) { | |
74 if (FT_Init_FreeType(&library->super)) { | |
75 free(library); | |
76 library = NULL; | |
77 fprintf(stderr, "XKFont::font_library_ft2_alloc: Couldn't allocate FreeType.\n"); | |
78 return 0; | |
79 } | |
80 fprintf(stderr, "XKFont::font_library_ft2_alloc : FreeType allocated successfully.\n"); | |
81 for (i = 0; default_paths[i]; i++) | |
82 font_library_ft2_add_path(default_paths[i]); | |
83 } | |
84 } | |
0 | 85 |
52 | 86 library->ref_count++; |
87 return 1; | |
0 | 88 } |
89 | |
52 | 90 static void font_library_ft2_free() |
0 | 91 { |
52 | 92 int i; |
93 | |
94 if (!library || library->ref_count <= 0) | |
95 return; | |
96 if (--library->ref_count == 0) { | |
97 FT_Done_FreeType(library->super); | |
98 for (i = 0; i < library->num_paths; i++) | |
99 free(library->paths[i]); | |
100 free(library->paths); | |
101 free(library); | |
102 library = NULL; | |
103 fprintf(stderr, "XKFont::font_library_ft2_free : FreeType done.\n"); | |
104 } | |
0 | 105 } |
106 | |
52 | 107 static void font_library_ft2_add_path(const char *path) |
0 | 108 { |
52 | 109 library->num_paths++; |
110 if (!library->paths) | |
111 library->paths = (char**) malloc(sizeof(char *)); | |
112 else | |
113 library->paths = (char**) realloc( (void*)library->paths, library->num_paths * sizeof(char *)); | |
114 library->paths[library->num_paths - 1] = strdup(path); | |
0 | 115 } |
116 | |
52 | 117 static void font_library_ft2_remove_path(const char *path) |
0 | 118 { |
52 | 119 int i, j; |
0 | 120 |
52 | 121 for (i = 0; i < library->num_paths; i++) { |
122 if (!strcmp(path, library->paths[i])) { | |
123 library->num_paths--; | |
124 for (j = i; j < library->num_paths; j++) | |
125 library->paths[j] = library->paths[j + 1]; | |
126 if (library->num_paths > 0) | |
127 library->paths = (char**) realloc(library->paths, library->num_paths * sizeof(char *)); | |
128 else { | |
129 free(library->paths); | |
130 library->paths = NULL; | |
131 } | |
132 } | |
133 } | |
0 | 134 } |
135 | |
136 typedef struct _FontEncoding { | |
52 | 137 FT_UShort platform_id; |
138 FT_Encoding encoding; | |
139 FontCodeConverter conv_func; | |
0 | 140 } FontEncoding; |
141 | |
142 static FontEncoding encodings[] = { | |
143 { 3, (FT_Encoding)ft_encoding_unicode, codeconv_euc_to_unicode }, | |
144 { 3, (FT_Encoding)ft_encoding_sjis, codeconv_euc_to_sjis }, | |
145 { 1, (FT_Encoding)ft_encoding_apple_roman, codeconv_euc_to_latin1 }, | |
146 { (FT_UShort)-1, (FT_Encoding)-1, NULL } | |
147 }; | |
148 | |
52 | 149 static char * font_library_ft2_build_path(const char *base, const char *name) |
0 | 150 { |
52 | 151 char *path; |
152 const char *strs[] = { base, "/", name, NULL }; | |
153 int i = 0; | |
154 | |
155 path = (char*) calloc(sizeof(char), strlen(base) + strlen(name) + 2); | |
156 if (path) | |
157 while (strs[i]) | |
158 strcat(path, strs[i++]); | |
159 | |
160 return path; | |
0 | 161 } |
162 | |
163 PeerFt2::PeerFt2(const char *name, int index, int hsize, int vsize) | |
164 { | |
52 | 165 int i,j; |
166 | |
167 font_library_ft2_alloc(); | |
168 | |
169 for (i = 0; i < library->num_paths; i++) { | |
170 char *path = font_library_ft2_build_path(library->paths[i], name); | |
171 if (path) { | |
172 if (FT_New_Face(library->super, path, index, &face)) | |
173 face = NULL; | |
174 free(path); | |
175 } | |
176 if (face) break; | |
177 } | |
178 | |
179 if (!face) { | |
180 string err = string("XKFont::PeerFt2::PeerFt : Cannot open font(TrueType) : ")+name; | |
181 throw std::invalid_argument(err); | |
182 } | |
0 | 183 |
52 | 184 conv_func = 0; |
185 for (i=0; encodings[i].conv_func != 0; i++) { | |
186 FT_UShort platform_id = encodings[i].platform_id; | |
187 FT_Encoding encoding = encodings[i].encoding; | |
188 for (j = 0; j < face->num_charmaps; j++) { | |
189 FT_CharMap cmap = face->charmaps[j]; | |
190 if (cmap->platform_id == platform_id && cmap->encoding == encoding) { | |
191 if (FT_Set_Charmap(face, cmap) == 0) { | |
192 conv_func = encodings[i].conv_func; | |
193 break; | |
194 } | |
195 } | |
196 } | |
197 if (conv_func) break; | |
198 } | |
0 | 199 |
52 | 200 if (conv_func == 0) { |
201 FT_Done_Face(face); | |
202 fprintf(stderr,"cannot find charmap\n"); | |
203 string err = string("XKFont::PeerFt2::PeerFt : No supported code converter of font (TrueType) ")+name; | |
204 throw std::invalid_argument(err); | |
205 } | |
206 | |
207 FT_Set_Pixel_Sizes(face, hsize, vsize); | |
0 | 208 } |
209 | |
210 PeerFt2::~PeerFt2() { | |
211 FT_Done_Face(face); | |
212 font_library_ft2_free(); | |
213 } | |
214 | |
52 | 215 bool PeerFt2::GlyphCreate(unsigned int code, Glyph* glyph) |
0 | 216 { |
52 | 217 FT_GlyphSlot slot; |
218 FT_UInt index; | |
219 int bmsize; | |
0 | 220 |
52 | 221 if (face == 0) return false; |
222 code = conv_func(code); | |
223 if (code == 0) return false; | |
224 index = FT_Get_Char_Index(face, code); | |
225 if (index == 0) return false; | |
0 | 226 |
52 | 227 /* Don't consider error */ |
228 slot = face->glyph; | |
229 if (slot) { | |
230 // if (! FT_Load_Glyph(face, index, FT_LOAD_DEFAULT)) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
231 // BITMAP だと なぜか render してくれない…… |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
232 // LOAD_DEFAULT でも、下に対応コードを付けたので一応は大丈夫 |
52 | 233 if (! FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP)) |
234 FT_Render_Glyph(slot, ft_render_mode_normal); | |
235 } | |
236 | |
237 glyph->bitmap_left = slot->bitmap_left; | |
238 glyph->bitmap_top = slot->bitmap_top; | |
239 glyph->bitmap.width = slot->bitmap.width; | |
240 glyph->bitmap.rows = slot->bitmap.rows; | |
0 | 241 |
242 /* | |
52 | 243 glyph->metrics.ascender = private->face->size->metrics.ascender >> 6; |
244 glyph->metrics.descender = private->face->size->metrics.descender >> 6; | |
0 | 245 */ |
246 | |
52 | 247 glyph->advance.x = slot->advance.x >> 6; |
248 glyph->advance.y = slot->advance.y >> 6; | |
0 | 249 |
52 | 250 bmsize = glyph->bitmap.width * glyph->bitmap.rows; |
251 if (bmsize > 0) { | |
252 glyph->bitmap.buffer = new unsigned char[bmsize]; | |
253 memcpy(glyph->bitmap.buffer, slot->bitmap.buffer, bmsize); | |
254 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
255 // なぜか Render したのに MONO なことがある…… |
0 | 256 /* for freetype < 2.1.3, use ``ft_pixel_mode_mono'' */ |
52 | 257 if (slot->bitmap.pixel_mode == ft_pixel_mode_mono) { |
258 int i, j; | |
0 | 259 // if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {int i,j; |
52 | 260 char* d = (char*)slot->bitmap.buffer; |
261 for (i=0; i < glyph->bitmap.rows; i++) { | |
262 int flag = *d++; | |
263 int len = 8; | |
264 unsigned char* buf = glyph->bitmap.buffer + i*slot->bitmap.width; | |
265 for (j=0; j < glyph->bitmap.width; j++) { | |
266 if (len == 0) { | |
267 flag = *d++; | |
268 len = 8; | |
269 } | |
270 if (flag & 0x80) *buf++ = 0xff; | |
271 else *buf++ = 0; | |
272 flag <<= 1; | |
273 len--; | |
0 | 274 } |
275 } | |
276 } | |
277 | |
52 | 278 return true; |
0 | 279 } |
280 | |
281 } /* end of namespace XKFont */ | |
282 |