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