Mercurial > otakunoraifu
comparison font/font_peer_ft2.cc @ 52:15a18fbe6f21
* Known bugs added to the README
* Code cleaning (0 -> NULL when needed, indentation, spaces, ...)
author | thib |
---|---|
date | Sat, 18 Apr 2009 18:35:39 +0000 |
parents | 5f548e5957a8 |
children | 4416cfac86ae |
comparison
equal
deleted
inserted
replaced
51:cbb301016a4e | 52:15a18fbe6f21 |
---|---|
39 #include "codeconv.h" | 39 #include "codeconv.h" |
40 | 40 |
41 namespace XKFont { | 41 namespace XKFont { |
42 | 42 |
43 typedef struct _FontLibrary { | 43 typedef struct _FontLibrary { |
44 FT_Library super; | 44 FT_Library super; |
45 int ref_count; | 45 int ref_count; |
46 char **paths; | 46 char **paths; |
47 int num_paths; | 47 int num_paths; |
48 } FontLibrary; | 48 } FontLibrary; |
49 | 49 |
50 static FontLibrary *library = NULL; | 50 static FontLibrary *library = NULL; |
51 | 51 |
52 static const char *default_paths[] = { | 52 static const char *default_paths[] = { |
62 static void font_library_ft2_add_path(const char *path); | 62 static void font_library_ft2_add_path(const char *path); |
63 static void font_library_ft2_remove_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); | 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); | 65 static char *font_library_ft2_build_path(const char *base, const char *name); |
66 | 66 |
67 static int | 67 static int font_library_ft2_alloc() |
68 font_library_ft2_alloc() | 68 { |
69 { | 69 int i; |
70 int i; | 70 |
71 | 71 if (!library) { |
72 if (!library) { | 72 library = (FontLibrary*) calloc(sizeof(FontLibrary), 1); |
73 library = (FontLibrary*) calloc(sizeof(FontLibrary), 1); | 73 if (library) { |
74 if (library) { | 74 if (FT_Init_FreeType(&library->super)) { |
75 if (FT_Init_FreeType(&library->super)) | 75 free(library); |
76 goto _1; | 76 library = NULL; |
77 fprintf(stderr, "XKFont::font_library_ft2_alloc : FreeType allocated successfully.\n"); | 77 fprintf(stderr, "XKFont::font_library_ft2_alloc: Couldn't allocate FreeType.\n"); |
78 for (i = 0; default_paths[i]; i++) | 78 return 0; |
79 font_library_ft2_add_path(default_paths[i]); | 79 } |
80 } | 80 fprintf(stderr, "XKFont::font_library_ft2_alloc : FreeType allocated successfully.\n"); |
81 } | 81 for (i = 0; default_paths[i]; i++) |
82 | 82 font_library_ft2_add_path(default_paths[i]); |
83 library->ref_count++; | 83 } |
84 return 1; | 84 } |
85 | 85 |
86 _1: | 86 library->ref_count++; |
87 free(library); | 87 return 1; |
88 library = NULL; | 88 } |
89 fprintf(stderr, "XKFont::font_library_ft2_alloc: Couldn't allocate FreeType.\n"); | 89 |
90 return 0; | 90 static void font_library_ft2_free() |
91 } | 91 { |
92 | 92 int i; |
93 static void | 93 |
94 font_library_ft2_free() | 94 if (!library || library->ref_count <= 0) |
95 { | 95 return; |
96 int i; | 96 if (--library->ref_count == 0) { |
97 | 97 FT_Done_FreeType(library->super); |
98 if (!library || library->ref_count <= 0) | 98 for (i = 0; i < library->num_paths; i++) |
99 return; | 99 free(library->paths[i]); |
100 if (--library->ref_count == 0) { | 100 free(library->paths); |
101 FT_Done_FreeType(library->super); | 101 free(library); |
102 for (i = 0; i < library->num_paths; i++) | 102 library = NULL; |
103 free(library->paths[i]); | 103 fprintf(stderr, "XKFont::font_library_ft2_free : FreeType done.\n"); |
104 free(library->paths); | 104 } |
105 free(library); | 105 } |
106 library = NULL; | 106 |
107 fprintf(stderr, "XKFont::font_library_ft2_free : FreeType done.\n"); | 107 static void font_library_ft2_add_path(const char *path) |
108 } | 108 { |
109 } | 109 library->num_paths++; |
110 | 110 if (!library->paths) |
111 static void | 111 library->paths = (char**) malloc(sizeof(char *)); |
112 font_library_ft2_add_path(const char *path) | 112 else |
113 { | 113 library->paths = (char**) realloc( (void*)library->paths, library->num_paths * sizeof(char *)); |
114 library->num_paths++; | 114 library->paths[library->num_paths - 1] = strdup(path); |
115 if (!library->paths) | 115 } |
116 library->paths = (char**) malloc(sizeof(char *)); | 116 |
117 else | 117 static void font_library_ft2_remove_path(const char *path) |
118 library->paths = (char**) realloc( (void*)library->paths, | 118 { |
119 library->num_paths * sizeof(char *)); | 119 int i, j; |
120 library->paths[library->num_paths - 1] = strdup(path); | 120 |
121 } | 121 for (i = 0; i < library->num_paths; i++) { |
122 | 122 if (!strcmp(path, library->paths[i])) { |
123 static void | 123 library->num_paths--; |
124 font_library_ft2_remove_path(const char *path) | 124 for (j = i; j < library->num_paths; j++) |
125 { | 125 library->paths[j] = library->paths[j + 1]; |
126 int i, j; | 126 if (library->num_paths > 0) |
127 | 127 library->paths = (char**) realloc(library->paths, library->num_paths * sizeof(char *)); |
128 for (i = 0; i < library->num_paths; i++) { | 128 else { |
129 if (!strcmp(path, library->paths[i])) { | 129 free(library->paths); |
130 library->num_paths--; | 130 library->paths = NULL; |
131 for (j = i; j < library->num_paths; j++) | 131 } |
132 library->paths[j] = library->paths[j + 1]; | 132 } |
133 if (library->num_paths > 0) | 133 } |
134 library->paths = (char**) realloc(library->paths, | |
135 library->num_paths * sizeof(char *)); | |
136 else { | |
137 free(library->paths); | |
138 library->paths = NULL; | |
139 } | |
140 } | |
141 } | |
142 } | 134 } |
143 | 135 |
144 typedef struct _FontEncoding { | 136 typedef struct _FontEncoding { |
145 FT_UShort platform_id; | 137 FT_UShort platform_id; |
146 FT_Encoding encoding; | 138 FT_Encoding encoding; |
147 FontCodeConverter conv_func; | 139 FontCodeConverter conv_func; |
148 } FontEncoding; | 140 } FontEncoding; |
149 | 141 |
150 static FontEncoding encodings[] = { | 142 static FontEncoding encodings[] = { |
151 { 3, (FT_Encoding)ft_encoding_unicode, codeconv_euc_to_unicode }, | 143 { 3, (FT_Encoding)ft_encoding_unicode, codeconv_euc_to_unicode }, |
152 { 3, (FT_Encoding)ft_encoding_sjis, codeconv_euc_to_sjis }, | 144 { 3, (FT_Encoding)ft_encoding_sjis, codeconv_euc_to_sjis }, |
153 { 1, (FT_Encoding)ft_encoding_apple_roman, codeconv_euc_to_latin1 }, | 145 { 1, (FT_Encoding)ft_encoding_apple_roman, codeconv_euc_to_latin1 }, |
154 { (FT_UShort)-1, (FT_Encoding)-1, NULL } | 146 { (FT_UShort)-1, (FT_Encoding)-1, NULL } |
155 }; | 147 }; |
156 | 148 |
157 static char * | 149 static char * font_library_ft2_build_path(const char *base, const char *name) |
158 font_library_ft2_build_path(const char *base, const char *name) | 150 { |
159 { | 151 char *path; |
160 char *path; | 152 const char *strs[] = { base, "/", name, NULL }; |
161 const char *strs[] = { base, "/", name, NULL }; | 153 int i = 0; |
162 int i = 0; | 154 |
163 | 155 path = (char*) calloc(sizeof(char), strlen(base) + strlen(name) + 2); |
164 path = (char*) calloc(sizeof(char), strlen(base) + strlen(name) + 2); | 156 if (path) |
165 if (path) | 157 while (strs[i]) |
166 while (strs[i]) | 158 strcat(path, strs[i++]); |
167 strcat(path, strs[i++]); | 159 |
168 | 160 return path; |
169 return path; | |
170 } | 161 } |
171 | 162 |
172 PeerFt2::PeerFt2(const char *name, int index, int hsize, int vsize) | 163 PeerFt2::PeerFt2(const char *name, int index, int hsize, int vsize) |
173 { | 164 { |
174 int i,j; | 165 int i,j; |
175 | 166 |
176 font_library_ft2_alloc(); | 167 font_library_ft2_alloc(); |
177 | 168 |
178 for (i = 0; i < library->num_paths; i++) { | 169 for (i = 0; i < library->num_paths; i++) { |
179 char *path = font_library_ft2_build_path(library->paths[i], name); | 170 char *path = font_library_ft2_build_path(library->paths[i], name); |
180 if (path) { | 171 if (path) { |
181 if (FT_New_Face(library->super, path, index, &face)) | 172 if (FT_New_Face(library->super, path, index, &face)) |
182 face = NULL; | 173 face = NULL; |
183 free(path); | 174 free(path); |
184 } | 175 } |
185 if (face) | 176 if (face) break; |
186 break; | 177 } |
187 } | 178 |
188 | 179 if (!face) { |
189 if (!face) { | 180 string err = string("XKFont::PeerFt2::PeerFt : Cannot open font(TrueType) : ")+name; |
190 string err = string("XKFont::PeerFt2::PeerFt : Cannot open font(TrueType) : ")+name; | 181 throw std::invalid_argument(err); |
191 throw std::invalid_argument(err); | 182 } |
192 } | 183 |
193 | 184 conv_func = 0; |
194 conv_func = 0; | 185 for (i=0; encodings[i].conv_func != 0; i++) { |
195 for (i=0; encodings[i].conv_func != 0; i++) { | 186 FT_UShort platform_id = encodings[i].platform_id; |
196 FT_UShort platform_id = encodings[i].platform_id; | 187 FT_Encoding encoding = encodings[i].encoding; |
197 FT_Encoding encoding = encodings[i].encoding; | 188 for (j = 0; j < face->num_charmaps; j++) { |
198 for (j = 0; j < face->num_charmaps; j++) { | 189 FT_CharMap cmap = face->charmaps[j]; |
199 FT_CharMap cmap = face->charmaps[j]; | 190 if (cmap->platform_id == platform_id && cmap->encoding == encoding) { |
200 if (cmap->platform_id == platform_id && cmap->encoding == encoding) { | 191 if (FT_Set_Charmap(face, cmap) == 0) { |
201 if (FT_Set_Charmap(face, cmap) == 0) { | 192 conv_func = encodings[i].conv_func; |
202 conv_func = encodings[i].conv_func; | 193 break; |
203 break; | 194 } |
204 } | 195 } |
205 } | 196 } |
206 } | 197 if (conv_func) break; |
207 if (conv_func) break; | 198 } |
208 } | 199 |
209 if (conv_func == 0) { | 200 if (conv_func == 0) { |
210 FT_Done_Face(face); | 201 FT_Done_Face(face); |
211 fprintf(stderr,"cannot find charmap\n"); | 202 fprintf(stderr,"cannot find charmap\n"); |
212 string err = string("XKFont::PeerFt2::PeerFt : No supported code converter of font (TrueType) ")+name; | 203 string err = string("XKFont::PeerFt2::PeerFt : No supported code converter of font (TrueType) ")+name; |
213 throw std::invalid_argument(err); | 204 throw std::invalid_argument(err); |
214 } | 205 } |
215 FT_Set_Pixel_Sizes(face, hsize, vsize); | 206 |
216 | 207 FT_Set_Pixel_Sizes(face, hsize, vsize); |
217 } | 208 } |
218 | 209 |
219 PeerFt2::~PeerFt2() { | 210 PeerFt2::~PeerFt2() { |
220 FT_Done_Face(face); | 211 FT_Done_Face(face); |
221 font_library_ft2_free(); | 212 font_library_ft2_free(); |
222 } | 213 } |
223 | 214 |
224 bool | 215 bool PeerFt2::GlyphCreate(unsigned int code, Glyph* glyph) |
225 PeerFt2::GlyphCreate(unsigned int code, Glyph* glyph) | 216 { |
226 { | 217 FT_GlyphSlot slot; |
227 FT_GlyphSlot slot; | 218 FT_UInt index; |
228 FT_UInt index; | 219 int bmsize; |
229 int bmsize; | 220 |
230 | 221 if (face == 0) return false; |
231 if (face == 0) return false; | 222 code = conv_func(code); |
232 code = conv_func(code); | 223 if (code == 0) return false; |
233 if (code == 0) return false; | 224 index = FT_Get_Char_Index(face, code); |
234 index = FT_Get_Char_Index(face, code); | 225 if (index == 0) return false; |
235 if (index == 0) return false; | 226 |
236 | 227 /* Don't consider error */ |
237 /* Don't consider error */ | 228 slot = face->glyph; |
238 slot = face->glyph; | 229 if (slot) { |
239 if (slot) { | 230 // if (! FT_Load_Glyph(face, index, FT_LOAD_DEFAULT)) { |
240 // if (! FT_Load_Glyph(face, index, FT_LOAD_DEFAULT)) { | 231 // BITMAP だと なぜか render してくれない…… |
241 // BITMAP だと なぜか render してくれない…… | 232 // LOAD_DEFAULT でも、下に対応コードを付けたので一応は大丈夫 |
242 // LOAD_DEFAULT でも、下に対応コードを付けたので一応は大丈夫 | 233 if (! FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP)) |
243 if (! FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP)) { | 234 FT_Render_Glyph(slot, ft_render_mode_normal); |
244 FT_Render_Glyph(slot, ft_render_mode_normal); | 235 } |
245 } | 236 |
246 } | 237 glyph->bitmap_left = slot->bitmap_left; |
247 | 238 glyph->bitmap_top = slot->bitmap_top; |
248 glyph->bitmap_left = slot->bitmap_left; | 239 glyph->bitmap.width = slot->bitmap.width; |
249 glyph->bitmap_top = slot->bitmap_top; | 240 glyph->bitmap.rows = slot->bitmap.rows; |
250 glyph->bitmap.width = slot->bitmap.width; | |
251 glyph->bitmap.rows = slot->bitmap.rows; | |
252 | 241 |
253 /* | 242 /* |
254 glyph->metrics.ascender = private->face->size->metrics.ascender >> 6; | 243 glyph->metrics.ascender = private->face->size->metrics.ascender >> 6; |
255 glyph->metrics.descender = private->face->size->metrics.descender >> 6; | 244 glyph->metrics.descender = private->face->size->metrics.descender >> 6; |
256 */ | 245 */ |
257 | 246 |
258 glyph->advance.x = slot->advance.x >> 6; | 247 glyph->advance.x = slot->advance.x >> 6; |
259 glyph->advance.y = slot->advance.y >> 6; | 248 glyph->advance.y = slot->advance.y >> 6; |
260 | 249 |
261 bmsize = glyph->bitmap.width * glyph->bitmap.rows; | 250 bmsize = glyph->bitmap.width * glyph->bitmap.rows; |
262 if (bmsize > 0) { | 251 if (bmsize > 0) { |
263 glyph->bitmap.buffer = new unsigned char[bmsize]; | 252 glyph->bitmap.buffer = new unsigned char[bmsize]; |
264 memcpy(glyph->bitmap.buffer, slot->bitmap.buffer, bmsize); | 253 memcpy(glyph->bitmap.buffer, slot->bitmap.buffer, bmsize); |
265 } | 254 } |
266 // なぜか Render したのに MONO なことがある…… | 255 // なぜか Render したのに MONO なことがある…… |
267 /* for freetype < 2.1.3, use ``ft_pixel_mode_mono'' */ | 256 /* for freetype < 2.1.3, use ``ft_pixel_mode_mono'' */ |
268 if (slot->bitmap.pixel_mode == ft_pixel_mode_mono) {int i,j; | 257 if (slot->bitmap.pixel_mode == ft_pixel_mode_mono) { |
258 int i, j; | |
269 // if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {int i,j; | 259 // if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {int i,j; |
270 char* d = (char*)slot->bitmap.buffer; | 260 char* d = (char*)slot->bitmap.buffer; |
271 for (i=0; i<glyph->bitmap.rows; i++) { | 261 for (i=0; i < glyph->bitmap.rows; i++) { |
272 int flag = *d++; int len = 8; | 262 int flag = *d++; |
273 unsigned char* buf = glyph->bitmap.buffer + i*slot->bitmap.width; | 263 int len = 8; |
274 for (j=0; j<glyph->bitmap.width; j++) { | 264 unsigned char* buf = glyph->bitmap.buffer + i*slot->bitmap.width; |
275 if (len == 0) { | 265 for (j=0; j < glyph->bitmap.width; j++) { |
276 flag = *d++; | 266 if (len == 0) { |
277 len = 8; | 267 flag = *d++; |
278 } | 268 len = 8; |
279 if (flag & 0x80) *buf++ = 0xff; | 269 } |
280 else *buf++ = 0; | 270 if (flag & 0x80) *buf++ = 0xff; |
281 flag <<= 1; | 271 else *buf++ = 0; |
282 len--; | 272 flag <<= 1; |
283 } | 273 len--; |
284 } | 274 } |
285 } | 275 } |
286 | 276 } |
287 return true; | 277 |
288 | 278 return true; |
289 } | 279 } |
290 | 280 |
291 } /* end of namespace XKFont */ | 281 } /* end of namespace XKFont */ |
292 | 282 |