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