bitch--
[framework/uifw/elementary.git] / src / lib / elm_font.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #ifdef HAVE_EVIL
6 # include <Evil.h>
7 #endif
8
9 #include <Elementary.h>
10 #include "elm_priv.h"
11
12 Elm_Font_Properties *
13 _elm_font_properties_get(Eina_Hash **font_hash,
14                          const char *font)
15 {
16    Elm_Font_Properties *efp = NULL;
17    char *token = strchr(font, ':');
18
19    if (token &&
20        !strncmp(token, ELM_FONT_TOKEN_STYLE, strlen(ELM_FONT_TOKEN_STYLE)))
21      {
22         char *name, *subname, *style, *substyle;
23         int len;
24
25         /* get font name */
26         len = token - font;
27         name = calloc(sizeof(char), len + 1);
28         if (!name) return NULL;
29         strncpy(name, font, len);
30
31         /* remove subnames from the font name (should be english)  */
32         subname = strchr(name, ',');
33         if (subname)
34           {
35              len = subname - name;
36              name = realloc(name, sizeof(char) * len + 1);
37              if (name)
38                {
39                   memset(name, 0, sizeof(char) * len + 1);
40                   strncpy(name, font, len);
41                }
42           }
43
44         /* add a font name */
45         if (font_hash)
46           efp = eina_hash_find(*font_hash, name);
47         if (!efp)
48           {
49              efp = calloc(1, sizeof(Elm_Font_Properties));
50              if (!efp) return NULL;
51              
52              efp->name = eina_stringshare_add(name);
53              if (font_hash)
54                {
55                   if (!*font_hash)
56                     *font_hash = eina_hash_string_superfast_new(NULL);
57                   eina_hash_add(*font_hash, name, efp);
58                }
59           }
60
61         free(name);
62
63         style = token + strlen(ELM_FONT_TOKEN_STYLE);
64         substyle = strchr(style, ',');
65
66         //TODO: Seems to need to add all styles. not only one.
67         if (substyle)
68           {
69              char *style_old = style;
70
71              len = substyle - style;
72              style = calloc(sizeof(char), len + 1);
73              if (style)
74                {
75                   strncpy(style, style_old, len);
76                   efp->styles = eina_list_append(efp->styles,
77                                                  eina_stringshare_add(style));
78                   free(style);
79                }
80           }
81         else
82           efp->styles = eina_list_append(efp->styles,
83                                          eina_stringshare_add(style));
84      }
85    else if ((font_hash) && (!eina_hash_find(*font_hash, font)))
86      {
87         efp = calloc(1, sizeof(Elm_Font_Properties));
88         if (!efp) return NULL;
89
90         efp->name = eina_stringshare_add(font);
91         if (!*font_hash) *font_hash = eina_hash_string_superfast_new(NULL);
92         eina_hash_add(*font_hash, font, efp);
93      }
94
95    return efp;
96 }
97
98 Eina_Hash *
99 _elm_font_available_hash_add(Eina_Hash  *font_hash,
100                              const char *full_name)
101 {
102    _elm_font_properties_get(&font_hash, full_name);
103    return font_hash;
104 }
105
106 static void
107 _elm_font_properties_free(Elm_Font_Properties *efp)
108 {
109    const char *str;
110
111    EINA_LIST_FREE(efp->styles, str)
112      if (str) eina_stringshare_del(str);
113
114    if (efp->name) eina_stringshare_del(efp->name);
115    free(efp);
116 }
117
118 static Eina_Bool
119 _font_hash_free_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
120 {
121    Elm_Font_Properties *efp;
122
123    efp = data;
124    _elm_font_properties_free(efp);
125    return EINA_TRUE;
126 }
127
128 void
129 _elm_font_available_hash_del(Eina_Hash *hash)
130 {
131    if (!hash) return;
132
133    eina_hash_foreach(hash, _font_hash_free_cb, NULL);
134    eina_hash_free(hash);
135 }
136
137 EAPI Elm_Font_Properties *
138 elm_font_properties_get(const char *font)
139 {
140    EINA_SAFETY_ON_NULL_RETURN_VAL(font, NULL);
141    return _elm_font_properties_get(NULL, font);
142 }
143
144 EAPI void
145 elm_font_properties_free(Elm_Font_Properties *efp)
146 {
147    const char *str;
148
149    EINA_SAFETY_ON_NULL_RETURN(efp);
150    EINA_LIST_FREE(efp->styles, str)
151      if (str) eina_stringshare_del(str);
152    if (efp->name) eina_stringshare_del(efp->name);
153    free(efp);
154 }
155
156 EAPI char *
157 elm_font_fontconfig_name_get(const char *name,
158                              const char *style)
159 {
160    char buf[256];
161
162    EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
163    if (!style || style[0] == 0) return (char *) eina_stringshare_add(name);
164    snprintf(buf, 256, "%s" ELM_FONT_TOKEN_STYLE "%s", name, style);
165    return (char *) eina_stringshare_add(buf);
166 }
167
168 EAPI void
169 elm_font_fontconfig_name_free(char *name)
170 {
171    eina_stringshare_del(name);
172 }
173
174 EAPI Eina_Hash *
175 elm_font_available_hash_add(Eina_List *list)
176 {
177    Eina_Hash *font_hash;
178    Eina_List *l;
179    void *key;
180
181    font_hash = NULL;
182
183    /* populate with default font families */
184    //FIXME: Need to check whether fonts are being added multiple times.
185    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Regular");
186    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Bold");
187    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Oblique");
188    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Bold Oblique");
189    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Regular");
190    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Bold");
191    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Oblique");
192    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Bold Oblique");
193    font_hash = _elm_font_available_hash_add(font_hash, "Monospace:style=Regular");
194    font_hash = _elm_font_available_hash_add(font_hash, "Monospace:style=Bold");
195    font_hash = _elm_font_available_hash_add(font_hash, "Monospace:style=Oblique");
196    font_hash = _elm_font_available_hash_add(font_hash, "Monospace:style=Bold Oblique");
197
198    EINA_LIST_FOREACH(list, l, key)
199      if (key) _elm_font_available_hash_add(font_hash, key);
200
201    return font_hash;
202 }
203
204 EAPI void
205 elm_font_available_hash_del(Eina_Hash *hash)
206 {
207    _elm_font_available_hash_del(hash);
208 }