Add Font Configuration Dialog, and...
[platform/upstream/enlightenment.git] / src / bin / e_font.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4 #include "e.h"
5
6 /* TODO List:
7  * - export to libe
8  * - use e_path to search for available fonts
9  */
10
11 static Evas_List *_e_font_font_dir_available_get (Evas_List * available_fonts, const char *font_dir);
12
13 static char _fn_buf[1024];
14
15 EAPI int
16 e_font_init(void)
17 {
18    /* all init stuff is in e_config */
19    return 1;
20 }
21
22 EAPI int
23 e_font_shutdown(void)
24 {
25    /* e_config will do this */
26    return 1;
27 }
28
29 EAPI void
30 e_font_apply(void)
31 {
32    char buf[1024];
33    Evas_List *l;
34    E_Font_Fallback *eff;
35    int blen, len;
36    
37    /* setup edje fallback list */
38    blen = sizeof(buf) - 1;
39    buf[0] = 0;
40    buf[blen] = 0;
41    l = e_config->font_fallbacks;
42    if (l)
43      {
44         eff = evas_list_data(l);
45         len = strlen(eff->name);
46         if (len < blen)
47           {
48              strcpy(buf, eff->name);
49              blen -= len;
50           }
51         for (l = evas_list_next(l); l; l = l->next)
52           {
53              eff = evas_list_data(l);
54              len = 1;
55              if (len < blen)
56                {
57                   strcat(buf, ",");
58                   blen -= len;
59                }
60              len = strlen(eff->name);
61              if (len < blen)
62                {
63                   strcat(buf, eff->name);
64                   blen -= len;
65                }
66           }
67         edje_fontset_append_set(buf);
68      }
69    else
70      edje_fontset_append_set(NULL);
71    
72    /* setup edje text classes */
73    for (l = e_config->font_defaults; l; l = l->next)
74      {
75         E_Font_Default *efd;
76
77         efd = evas_list_data(l);
78         edje_text_class_set(efd->text_class, efd->font, efd->size);
79      }
80
81    /* Update borders */
82    for (l = e_border_client_list(); l; l = l->next)
83      {
84         E_Border *bd;
85
86         bd = l->data;
87         e_border_frame_recalc(bd);
88      }
89 }
90
91 EAPI Evas_List *
92 e_font_available_list(void)
93 {
94    Evas_List *dir_list;
95    Evas_List *next;
96    Evas_List *available;   
97
98    dir_list = e_path_dir_list_get(path_fonts);
99    available = NULL;
100    for ( next = dir_list; next; next = next->next)
101      {
102         E_Path_Dir *epd = next->data;
103         available = _e_font_font_dir_available_get(available, epd->dir);
104      }
105    
106    e_path_dir_list_free(dir_list);
107    return available;
108 }
109
110 EAPI void
111 e_font_available_list_free(Evas_List *available)
112 {
113    E_Font_Available *efa;
114    
115    while (available)
116      {
117         efa = available->data;
118         available = evas_list_remove_list(available, available);
119         if (efa->name) evas_stringshare_del(efa->name);
120         E_FREE(efa);    
121      }
122 }
123
124 EAPI void
125 e_font_fallback_clear(void)
126 {
127    E_Font_Fallback *eff;
128     
129    while (e_config->font_fallbacks)
130      {  
131         eff = e_config->font_fallbacks->data;
132         e_config->font_fallbacks = evas_list_remove_list(
133                                         e_config->font_fallbacks, 
134                                         e_config->font_fallbacks);
135         if (eff->name) evas_stringshare_del(eff->name);
136         E_FREE(eff);
137     }
138 }
139
140 EAPI void
141 e_font_fallback_append(const char *font)
142 {
143    E_Font_Fallback *eff;
144    
145    e_font_fallback_remove (font);
146    
147    eff = E_NEW(E_Font_Fallback, 1);
148    eff->name = evas_stringshare_add(font);
149    e_config->font_fallbacks = evas_list_append(e_config->font_fallbacks, eff);
150 }
151
152 EAPI void
153 e_font_fallback_prepend(const char *font)
154 {
155    E_Font_Fallback *eff;
156    
157    e_font_fallback_remove (font);
158    
159    eff = E_NEW(E_Font_Fallback, 1);
160    eff->name = evas_stringshare_add(font);
161    e_config->font_fallbacks = evas_list_prepend(e_config->font_fallbacks, eff);
162 }
163
164 EAPI void
165 e_font_fallback_remove(const char *font)
166 {
167    Evas_List *next;
168
169    for (next = e_config->font_fallbacks; next; next = next->next)
170      {
171         E_Font_Fallback *eff;
172         
173         eff = evas_list_data(next);
174         if (!strcmp(eff->name, font))
175           {
176              e_config->font_fallbacks = evas_list_remove_list(
177                                         e_config->font_fallbacks, next);
178              if (eff->name) evas_stringshare_del(eff->name);
179              E_FREE(eff);
180              break;
181           }
182      }
183 }
184
185 EAPI Evas_List *
186 e_font_fallback_list(void)
187 {
188    return e_config->font_fallbacks;
189 }
190
191 EAPI void
192 e_font_default_set(const char *text_class, const char *font, int size)
193 {
194    E_Font_Default *efd;
195    Evas_List *next;
196
197    /* search for the text class */
198    for (next = e_config->font_defaults; next; next = next->next)
199      {
200         efd = evas_list_data(next);
201         if (!strcmp(efd->text_class, text_class))
202           {
203              if (efd->font) evas_stringshare_del(efd->font);
204              efd->font = evas_stringshare_add(font);
205              efd->size = size;
206              /* move to the front of the list */
207              e_config->font_defaults = evas_list_remove_list(
208                                         e_config->font_defaults, next);
209              e_config->font_defaults = evas_list_prepend(
210                                         e_config->font_defaults, efd);
211              return;
212           }
213      }
214
215    /* the text class doesnt exist */
216    efd = E_NEW(E_Font_Default, 1);
217    efd->text_class = evas_stringshare_add(text_class);
218    efd->font = evas_stringshare_add(font);
219    efd->size = size;
220    
221    e_config->font_defaults = evas_list_prepend(e_config->font_defaults, efd);
222 }
223
224 /*
225  * returns a pointer to the data, return null if nothing if found.
226  */
227 EAPI E_Font_Default *
228 e_font_default_get(const char *text_class)
229 {
230    E_Font_Default *efd = NULL, *defd = NULL;
231    Evas_List *next;
232
233    /* search for the text class */
234    for (next = e_config->font_defaults; next; next = next->next)
235      {
236         efd = evas_list_data(next);
237         if (!strcmp(efd->text_class, text_class))
238           {
239              /* move to the front of the list */
240              e_config->font_defaults = evas_list_remove_list(
241                                         e_config->font_defaults, next);
242              e_config->font_defaults = evas_list_prepend(
243                                         e_config->font_defaults, efd);
244              return efd;
245           }
246         if (!strcmp(efd->text_class, "default"))
247           defd = efd;
248      }
249    if (!defd)
250      defd  = efd;
251    return defd;
252 }
253
254 EAPI void
255 e_font_default_remove(const char *text_class)
256 {
257    E_Font_Default *efd;
258    Evas_List *next;
259    
260    /* search for the text class */
261    for (next = e_config->font_defaults; next; next = next->next)
262      {
263         efd = evas_list_data(next);
264         if (!strcmp(efd->text_class, text_class))
265           {
266              e_config->font_defaults = evas_list_remove_list(
267                                         e_config->font_defaults, next);
268              if (efd->text_class) evas_stringshare_del(efd->text_class);
269              if (efd->font) evas_stringshare_del(efd->font);
270              E_FREE(efd);
271              return;
272           }
273     }
274 }
275
276 EAPI Evas_List *
277 e_font_default_list(void)
278 {
279    return e_config->font_defaults;
280 }
281
282 /* return the default font name with fallbacks, font size is returned
283  * in size_ret. This function is needed when all hell breaks loose and
284  * we need a font name and size.
285  */
286 EAPI const char *
287 e_font_default_string_get(const char *text_class, int *size_ret)
288 {
289    E_Font_Default *efd;
290    Evas_List *next;
291    E_Font_Fallback *eff;
292    int blen, len;
293    
294    _fn_buf[0] = 0;
295    efd = e_font_default_get(text_class);
296    if (!efd)
297      {
298         if (size_ret) *size_ret = 0;
299         return "";
300      }
301    blen = sizeof(_fn_buf) - 1;
302    
303    len = strlen(efd->font);
304    if (len < blen)
305      {
306         strcpy(_fn_buf, efd->font);
307         blen -= len;
308      }
309    
310    next = e_config->font_fallbacks;
311    while (next)
312      {
313         eff = evas_list_data(next);
314         len = 1;
315         if (len < blen)
316           {
317              strcat(_fn_buf, ",");
318              blen -= len;
319           }
320         len = strlen(eff->name);
321         if (len < blen)
322           {
323              strcat(_fn_buf, eff->name);
324              blen -= len;
325           }
326         next = evas_list_next(next);
327      }
328    
329    if (size_ret) *size_ret = efd->size;
330    return _fn_buf;
331 }
332
333 static Evas_List *
334 _e_font_font_dir_available_get(Evas_List *available_fonts, const char *font_dir)
335 {
336    char buf[4096];
337    FILE *f;
338    
339    snprintf(buf, sizeof(buf), "%s/fonts.alias", font_dir);
340    f = fopen(buf, "r");
341    if (f)
342      {
343         char fname[4096], fdef[4096];
344         Evas_List *next;
345         
346         /* read font alias lines */
347         while (fscanf(f, "%4090s %[^\n]\n", fname, fdef) == 2)
348           {
349              E_Font_Available *efa;
350              
351              /* skip comments */
352              if ((fdef[0] == '!') || (fdef[0] == '#'))
353                continue;
354              
355              /* skip duplicates */
356              
357              for (next = available_fonts; next; next = evas_list_next(next))
358                {
359                   efa = (E_Font_Available *)evas_list_data(next);
360                
361                   if (!strcmp(efa->name, fname))
362                     continue;             
363                }
364                 
365              efa = malloc(sizeof(E_Font_Available));
366              efa->name = evas_stringshare_add(fname);
367              available_fonts = evas_list_append(available_fonts, efa);
368           }
369         fclose (f);
370      }
371    return available_fonts;
372 }