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