Add font size configuation file
[platform/core/api/system-settings.git] / libutil / sstu.c
1 /*
2  * Copyright (c) 2011-2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "sst_utils_wrapper.h"
17
18 #include <string.h>
19 #include <vconf.h>
20 #include <fontconfig/fontconfig.h>
21 #include <efl_extension.h>
22 #include <json-glib/json-glib.h>
23 #include "system_settings.h"
24 #include "sst.h"
25
26 #define FONT_SCALE_CONF_PATH SYSCONF_DIR"/font_scale.json"
27 #define INTERNAL_API __attribute__((visibility("default")))
28
29 #ifdef TIZEN_WEARABLE
30 #define SMALL_FONT_DPI                                          (-90)
31 #else
32 #define SMALL_FONT_DPI                                          (-80)
33 #endif
34
35 #define MIDDLE_FONT_DPI                                         (-100)
36
37 #ifdef TIZEN_WEARABLE
38 #define LARGE_FONT_DPI                                          (-110)
39 #else
40 #define LARGE_FONT_DPI                                          (-150)
41 #endif
42
43 #define HUGE_FONT_DPI                                           (-190)
44 #define GIANT_FONT_DPI                                          (-250)
45
46 #define SETTING_FONT_PRELOAD_FONT_PATH _TZ_SYS_RO_SHARE"/fonts"
47 #define SETTING_FONT_DOWNLOADED_FONT_PATH _TZ_SYS_SHARE"/fonts"
48
49 #define SETTING_FONT_TIZEN_FONT_ALIAS "Tizen"
50 #define SETTING_FONT_TIZEN_DEFAULT_FONT_ALIAS "TizenDefaultFont"
51
52
53 typedef struct __font_size_info {
54         int small;
55         int normal;
56         int large;
57         int huge;
58         int giant;
59 } font_size_info;
60
61 static char* _get_main_font_family(char *alias)
62 {
63         FcFontSet *set;
64         FcPattern *pat;
65         FcConfig *font_config = NULL;
66         FcChar8 *family = NULL;
67         char *ret = NULL;
68         FcResult res = 0;
69
70         font_config = FcInitLoadConfigAndFonts();
71         if (NULL == font_config) {
72                 ERR("FcInitLoadConfigAndFonts() Fail");
73                 return NULL;
74         }
75
76         pat = FcPatternBuild(0, FC_FAMILY, FcTypeString, alias, NULL);
77         if (NULL == pat) {
78                 ERR("FcPatternBuild() Fail");
79                 FcConfigDestroy(font_config);
80                 return NULL;
81         }
82
83         FcConfigSubstitute(font_config, pat, FcMatchPattern);
84         FcDefaultSubstitute(pat);
85
86         /* do matching */
87         set = FcFontSort(font_config, pat, FcTrue, NULL, &res);
88         do {
89                 if (set && 0 < set->nfont) {
90                         int result = FcPatternGetString(set->fonts[0], FC_FAMILY, 0, &family);
91                         if (FcResultMatch != result) {
92                                 ERR("FcPatternGetString() Fail(%d)", result);
93                                 ret = NULL;
94                                 break;
95                         }
96                         if (family)
97                                 ret = strdup((char*)family);
98                 }
99         } while(0);
100
101         if (set)
102                 FcFontSetDestroy(set);
103
104         FcPatternDestroy(pat);
105         FcConfigDestroy(font_config);
106
107         return ret;
108 }
109
110 API void sstu_font_config_set_notification()
111 {
112 }
113
114 API int sstu_is_available_font(const char *font_name)
115 {
116         FcObjectSet *os;
117         FcFontSet *fs;
118         FcPattern *pat;
119         FcConfig *font_config;
120         int ret = 0;
121
122         RETV_IF(NULL == font_name, -1);
123
124         font_config = FcInitLoadConfigAndFonts();
125         if (NULL == font_config)
126                 ERR("FcInitLoadConfigAndFonts() Fail");
127
128         char *locale = setlocale(0, NULL);
129         os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_FAMILYLANG, NULL);
130         if (NULL == os) {
131                 ERR("FcObjectSetBuild() Fail");
132                 FcConfigDestroy(font_config);
133                 return 0;
134         }
135
136         pat = FcPatternCreate();
137         if (NULL == pat) {
138                 ERR("FcPatternCreate() Fail");
139                 FcObjectSetDestroy(os);
140                 FcConfigDestroy(font_config);
141                 return 0;
142         }
143
144         fs = FcFontList(font_config, pat, os);
145         FcPatternDestroy(pat);
146         FcObjectSetDestroy(os);
147         if (NULL == fs) {
148                 ERR("FcFontList() Fail");
149                 FcConfigDestroy(font_config);
150                 return 0;
151         }
152
153         INFO("fs->nfont = %d", fs->nfont);
154
155         int i;
156         for (i = 0; i < fs->nfont; i++) {
157                 FcChar8 *file = NULL;
158                 FcChar8 *family = NULL;
159
160                 FcResult result;
161                 result = FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file);
162                 if (FcResultMatch != result || NULL == file) {
163                         ERR("FcPatternGetString() Fail(%d)", result);
164                         FcFontSetDestroy(fs);
165                         FcConfigDestroy(font_config);
166                         return 0;
167                 }
168                 const char *preloaded = SETTING_FONT_PRELOAD_FONT_PATH;
169                 const char *downloaded = SETTING_FONT_DOWNLOADED_FONT_PATH;
170                 int preload_len = sizeof(SETTING_FONT_PRELOAD_FONT_PATH) - 1;
171                 int download_len = sizeof(SETTING_FONT_DOWNLOADED_FONT_PATH) - 1;
172
173                 if (SST_EQUAL == strncmp((char*)file, preloaded, preload_len)
174                         || SST_EQUAL == strncmp((char*)file, downloaded, download_len)) {
175                         char *family_result = NULL;
176                         FcChar8 *lang = NULL;
177                         int id = 0;
178                         if (FcPatternGetString(fs->fonts[i], FC_FAMILY, id, &family) != FcResultMatch)
179                                 break;
180                         if (FcPatternGetString(fs->fonts[i], FC_FAMILYLANG, id, &lang) != FcResultMatch)
181                                 break;
182                         family_result = (char*)family;
183
184                         /* Find proper family name for current locale. */
185                         while (locale && family && lang) {
186                                 if (SST_EQUAL == strncmp(locale, (char*)lang, strlen((char*)lang))) {
187                                         family_result = (char*)family;
188                                         break;
189                                 }
190
191                                 /* I will set english as default family language. */
192                                 /* If there is no proper family language for current locale, */
193                                 /* we have to show the english family name. */
194                                 if (SST_EQUAL == strcmp((char*)lang, "en"))
195                                         family_result = (char*)family;
196
197                                 id++;
198                                 if (FcPatternGetString(fs->fonts[i], FC_FAMILY, id, &family) != FcResultMatch)
199                                         break;
200                                 if (FcPatternGetString(fs->fonts[i], FC_FAMILYLANG, id, &lang) != FcResultMatch)
201                                         break;
202                         }
203
204                         if (family_result) {
205                                 DBG("family = %s", family_result);
206                                 if (strcmp(family_result, font_name) == 0) {
207                                         ret = 1;
208                                         break;
209                                 }
210                         }
211                 }
212         }
213         FcFontSetDestroy(fs);
214         FcConfigDestroy(font_config);
215         return ret;
216 }
217
218 API char* sstu_get_default_font()
219 {
220         return _get_main_font_family(SETTING_FONT_TIZEN_DEFAULT_FONT_ALIAS);
221 }
222
223 /*
224 To support different variable product, font_scale.json is added.
225 With %config option in .spec file, the font_scale.json can be
226 uploaded only when there is no the font_scale.json in /etc.
227
228 In font_scale.json, there are 5 grade of font size, below.
229
230 $ cat /etc/font_scale.json
231 {
232         "SMALL"  : -80,
233         "NORMAL" : -100,
234         "LARGE"  : -150,
235         "HUGE"   : -190,
236         "GIANT"  : -250
237 }
238
239 -80 means that 80% font scale of each application font size.
240 Each grade is mapping, below.
241
242 SYSTEM_SETTINGS_FONT_SIZE_SMALL == "SMALL" in font_scale.json value
243 SYSTEM_SETTINGS_FONT_SIZE_NORMAL == "NORMAL" in font_scale.json value
244 SYSTEM_SETTINGS_FONT_SIZE_LARGE == "LARGE" in font_scale.json value
245 SYSTEM_SETTINGS_FONT_SIZE_HUGE == "HUGE" in font_scale.json value
246 SYSTEM_SETTINGS_FONT_SIZE_GIANT == "GIANT" in font_scale.json value
247 */
248
249 static int get_int_from_object(JsonObject *obj, const char *key, int *data)
250 {
251         JsonNode *tmp = json_object_get_member(obj, key);
252
253         if (tmp == NULL){
254                 ERR("json_object_object_get_ex(key:%s) error", key);
255                 return -EINVAL;
256         }
257
258         int tmp_int = json_node_get_int(tmp);
259         if (tmp_int < 0) {
260                 *data = tmp_int;
261         } else {
262                 ERR("%s key Wrong value : %d ", key, tmp_int);
263         }
264
265         return 0;
266 }
267
268 INTERNAL_API int load_font_size_info(font_size_info *info, const gchar *path)
269 {
270         GError *error = NULL;
271
272         if (info == NULL)
273             return -EINVAL;
274
275         info->small = SMALL_FONT_DPI;
276         info->normal = MIDDLE_FONT_DPI;
277         info->large = LARGE_FONT_DPI;
278         info->huge = HUGE_FONT_DPI;
279         info->giant = GIANT_FONT_DPI;
280
281         JsonParser *parser  = json_parser_new();
282         json_parser_load_from_file (parser, path, &error);
283         /* Parse configuration file */
284         if (error) {
285                 INFO("There is no json_object file(%s), loaded default font size values", path);
286                 return 0;
287         }
288
289         JsonObject *obj = json_node_get_object(json_parser_get_root (parser));
290         INFO("json_object file(%s) OPENED! Try to load font size values from the file.", path);
291         get_int_from_object(obj, "SMALL", &info->small);
292         get_int_from_object(obj, "NORMAL", &info->normal);
293         get_int_from_object(obj, "LARGE", &info->large);
294         get_int_from_object(obj, "HUGE", &info->huge);
295         get_int_from_object(obj, "GIANT", &info->giant);
296
297         g_object_unref(parser);
298
299         return 0;
300 }
301
302 static int _get_font_size()
303 {
304         int font_size = -1;
305         font_size_info info;
306
307         int vconf_value = -1;
308         if (vconf_get_int(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, &vconf_value)) {
309                 ERR("vconf_get_int() Fail");
310                 return -1;
311         }
312
313         load_font_size_info(&info, FONT_SCALE_CONF_PATH);
314
315         switch (vconf_value) {
316         case SYSTEM_SETTINGS_FONT_SIZE_SMALL:
317                 font_size = info.small;
318                 break;
319         case SYSTEM_SETTINGS_FONT_SIZE_NORMAL:
320                 font_size = info.normal;
321                 break;
322         case SYSTEM_SETTINGS_FONT_SIZE_LARGE:
323                 font_size = info.large;
324                 break;
325         case SYSTEM_SETTINGS_FONT_SIZE_HUGE:
326                 font_size = info.huge;
327                 break;
328         case SYSTEM_SETTINGS_FONT_SIZE_GIANT:
329                 font_size = info.giant;
330                 break;
331         default:
332                 font_size = info.normal;
333                 break;
334         }
335         return font_size;
336 }
337
338 API bool sstu_set_font_config(const char *font_name)
339 {
340         int font_size = _get_font_size();
341         return eext_config_font_set((char*)font_name, font_size);
342 }
343
344 API void sstu_set_font_size()
345 {
346         int font_size = _get_font_size();
347         char *font_name = NULL;
348         font_name = vconf_get_str(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME);
349         eext_config_font_set(font_name, font_size);
350         free(font_name);
351 }