From f9172244acd9d9ea6e7f17413c66b5987c9adb24 Mon Sep 17 00:00:00 2001 From: Gustavo Lima Chaves Date: Thu, 18 Nov 2010 10:01:24 +0000 Subject: [PATCH] Elementary welcomes text classes support. I'm now populating the default theme with text classes, just commit with one for now. There can be tweakings at Elm config app's UI fonts page, I know, but that will come later (editable preview field, font hinting/fallback, blablabla). WARNING: for users testing elm config, an old "rm -rf ~/.elementary/config" might be needed here, after this commit. SVN revision: 54681 --- legacy/elementary/data/objects/Makefile.am | 12 +- .../elementary/data/objects/font_preview.edc | 40 + legacy/elementary/data/themes/default.edc | 30 + legacy/elementary/src/bin/config.c | 805 +++++++++++++++++- legacy/elementary/src/lib/Elementary.h.in | 35 + legacy/elementary/src/lib/Makefile.am | 1 + legacy/elementary/src/lib/elm_config.c | 202 ++++- legacy/elementary/src/lib/elm_font.c | 128 +++ legacy/elementary/src/lib/elm_main.c | 274 ++++++ legacy/elementary/src/lib/elm_priv.h | 14 + 10 files changed, 1526 insertions(+), 15 deletions(-) create mode 100644 legacy/elementary/data/objects/font_preview.edc create mode 100644 legacy/elementary/src/lib/elm_font.c diff --git a/legacy/elementary/data/objects/Makefile.am b/legacy/elementary/data/objects/Makefile.am index 7a2a16e11f..0f80b6c4be 100644 --- a/legacy/elementary/data/objects/Makefile.am +++ b/legacy/elementary/data/objects/Makefile.am @@ -6,13 +6,14 @@ EDJE_FLAGS = -v -id $(top_srcdir)/data/objects -fd $(top_srcdir)/data/objects filesdir = $(datadir)/elementary/objects -files_DATA = test.edj multip.edj colorpreview.edj cursors.edj +files_DATA = test.edj multip.edj colorpreview.edj cursors.edj font_preview.edj EXTRA_DIST = \ test.edc \ multip.edc \ colorpreview.edc \ cursors.edc \ +font_preview.edc \ grid_bg.png \ over.png \ under.png \ @@ -24,7 +25,7 @@ test.edj: Makefile $(EXTRA_DIST) $(EDJE_CC) $(EDJE_FLAGS) \ $(top_srcdir)/data/objects/test.edc \ $(top_builddir)/data/objects/test.edj - + multip.edj: Makefile $(EXTRA_DIST) $(EDJE_CC) $(EDJE_FLAGS) \ $(top_srcdir)/data/objects/multip.edc \ @@ -39,6 +40,11 @@ cursors.edj: Makefile $(EXTRA_DIST) $(EDJE_CC) $(EDJE_FLAGS) \ $(top_srcdir)/data/objects/cursors.edc \ $(top_builddir)/data/objects/cursors.edj - + +font_preview.edj: Makefile $(EXTRA_DIST) + $(EDJE_CC) $(EDJE_FLAGS) \ + $(top_srcdir)/data/objects/font_preview.edc \ + $(top_builddir)/data/objects/font_preview.edj + clean-local: rm -f *.edj diff --git a/legacy/elementary/data/objects/font_preview.edc b/legacy/elementary/data/objects/font_preview.edc new file mode 100644 index 0000000000..302c2e85e5 --- /dev/null +++ b/legacy/elementary/data/objects/font_preview.edc @@ -0,0 +1,40 @@ +color_classes { + color_class { + name: "entry_text"; + color: 0 0 0 255; + } +} + +collections { + + group { name: "font_preview"; + parts { + + /* some fonts have weird alignments, thus they overflow badly */ + part { name: "clipper"; + type: RECT; + description { + state: "default" 0.0; + } + } + + part { name: "elm.text"; + type: TEXT; + mouse_events: 0; + scale: 1; + clip_to: "clipper"; + description { + state: "default" 0.0; + color_class: "entry_text"; + text { + font: "Sans"; + min: 0 1; + size: 10; + align: 0.5 0.5; + text_class: "font_preview"; + } + } + } + } + } +} diff --git a/legacy/elementary/data/themes/default.edc b/legacy/elementary/data/themes/default.edc index 561ed780b2..6367ab4747 100644 --- a/legacy/elementary/data/themes/default.edc +++ b/legacy/elementary/data/themes/default.edc @@ -639,6 +639,20 @@ collections { } } } + part { name: "disabler"; + type: RECT; + description { state: "default" 0.0; + rel1.to: "clipper"; + rel2.to: "clipper"; + color: 0 0 0 0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 128 128 128 128; + } + } } programs { program { name: "load"; @@ -809,6 +823,18 @@ collections { target: "focus_highlight"; target: "conf_over"; } + program { name: "disable"; + signal: "elm,state,disabled"; + source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "disabler"; + } + program { name: "enable"; + signal: "elm,state,enabled"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "disabler"; + } } } @@ -1628,6 +1654,7 @@ collections { size: 10; min: 0 0; align: 0.5 0.5; + text_class: "button"; } } description { state: "visible" 0.0; @@ -1966,6 +1993,7 @@ collections { size: 10; min: 0 0; align: 0.5 0.5; + text_class: "button"; } } description { state: "visible" 0.0; @@ -2247,6 +2275,7 @@ collections { size: 10; min: 0 0; align: 0.5 0.5; + text_class: "button"; } } description { state: "visible" 0.0; @@ -2428,6 +2457,7 @@ collections { size: 10; min: 0 0; align: 0.5 0.5; + text_class: "button"; } } description { state: "visible" 0.0; diff --git a/legacy/elementary/src/bin/config.c b/legacy/elementary/src/bin/config.c index 28ab7b44ad..a1b5feaffb 100644 --- a/legacy/elementary/src/bin/config.c +++ b/legacy/elementary/src/bin/config.c @@ -5,6 +5,9 @@ #ifndef ELM_LIB_QUICKLAUNCH typedef struct _Theme Theme; +typedef struct _Fonts_Data Fonts_Data; +typedef struct _Elm_Text_Class_Data Elm_Text_Class_Data; +typedef struct _Elm_Font_Size_Data Elm_Font_Size_Data; struct _Theme { @@ -17,18 +20,101 @@ struct _Theme static Theme *tsel = NULL; static Eina_List *themes = NULL; +struct _Elm_Text_Class_Data +{ + const char *name; + const char *desc; + const char *font; + const char *style; + Evas_Font_Size size; +}; + +struct _Elm_Font_Size_Data +{ + const char *size_str; + Evas_Font_Size size; +}; + +struct _Fonts_Data +{ + Eina_List *text_classes; + + Eina_Hash *font_hash; + Eina_List *font_px_list; + Eina_List *font_scale_list; + + const char *cur_font; + const char *cur_style; + double cur_size; +}; + +#define ELM_LIST_DISABLE(list) \ + do \ + { \ + const Eina_List *l = elm_list_items_get(list); \ + if (l) \ + { \ + elm_list_item_show(eina_list_data_get(l)); \ + elm_object_disabled_set(list, EINA_TRUE); \ + } \ + } \ + while (0); + +#define ELM_LIST_ENABLE(list) \ + do \ + { \ + elm_object_disabled_set(list, EINA_FALSE); \ + } \ + while (0); + static int quiet = 0; static int interactive = 1; static const char *theme_set = NULL; static const char *finger_size_set = NULL; static const char *scale_set = NULL; +static Fonts_Data fdata = {NULL, NULL, NULL, NULL, NULL, NULL, 0.0}; static void -my_win_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +_font_styles_list_sel(void *data __UNUSED__, + Evas_Object *obj, + void *event_info); + +static void +config_exit(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) { + Elm_Text_Class_Data *tc_data; + Elm_Font_Size_Data *sd; + + EINA_LIST_FREE(fdata.text_classes, tc_data) + { + eina_stringshare_del(tc_data->name); + eina_stringshare_del(tc_data->desc); + eina_stringshare_del(tc_data->font); + eina_stringshare_del(tc_data->style); + free(tc_data); + } + + elm_font_available_hash_del(fdata.font_hash); + + EINA_LIST_FREE(fdata.font_px_list, sd) + { + eina_stringshare_del(sd->size_str); + free(sd); + } + + EINA_LIST_FREE(fdata.font_scale_list, sd) + { + eina_stringshare_del(sd->size_str); + free(sd); + } + + if (fdata.cur_font) eina_stringshare_del(fdata.cur_font); + if (fdata.cur_style) eina_stringshare_del(fdata.cur_style); + elm_config_save(); - /* called when my_win_main is requested to be deleted */ elm_exit(); /* exit the program's main loop that runs in elm_run() */ } @@ -260,6 +346,110 @@ _elm_theme_current_get(const char *theme_search_order) return ret; } +static void +_font_overlay_reset(void *data, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *win, *fclasses, *fnames, *fstyles, *fsizes; + Elm_Text_Class_Data *tc_data; + Elm_List_Item *it; + + win = data; + + fclasses = evas_object_data_get(win, "font_classes_list"); + it = elm_list_selected_item_get(fclasses); + if (!it) return; + tc_data = elm_list_item_data_get(it); + + fnames = evas_object_data_get(win, "font_names_list"); + fstyles = evas_object_data_get(win, "font_styles_list"); + fsizes = evas_object_data_get(win, "font_sizes_list"); + + elm_font_overlay_unset(tc_data->name); + + eina_stringshare_replace(&fdata.cur_font, NULL); + eina_stringshare_replace(&tc_data->font, NULL); + eina_stringshare_replace(&fdata.cur_style, NULL); + eina_stringshare_replace(&tc_data->style, NULL); + fdata.cur_size = 0.0; + tc_data->size = 0.0; + + ELM_LIST_DISABLE(fnames); + ELM_LIST_DISABLE(fstyles); + ELM_LIST_DISABLE(fsizes); + + elm_config_save(); +} + +static void +_font_overlay_reset_all(void *data, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *win, *fclasses, *fnames, *fstyles, *fsizes; + Elm_Text_Class_Data *tc_data; + Elm_List_Item *it; + Eina_List *l; + + win = data; + eina_stringshare_replace(&fdata.cur_font, NULL); + eina_stringshare_replace(&fdata.cur_style, NULL); + fdata.cur_size = 0.0; + + EINA_LIST_FOREACH(fdata.text_classes, l, tc_data) + { + elm_font_overlay_unset(tc_data->name); + + eina_stringshare_replace(&tc_data->font, NULL); + eina_stringshare_replace(&tc_data->style, NULL); + tc_data->size = 0.0; + } + + fclasses = evas_object_data_get(win, "font_classes_list"); + fnames = evas_object_data_get(win, "font_names_list"); + fstyles = evas_object_data_get(win, "font_styles_list"); + fsizes = evas_object_data_get(win, "font_sizes_list"); + + it = elm_list_selected_item_get(fclasses); + if (it) elm_list_item_selected_set(it, EINA_FALSE); + + ELM_LIST_DISABLE(fnames); + ELM_LIST_DISABLE(fstyles); + ELM_LIST_DISABLE(fsizes); + + elm_config_save(); +} + +static void +_font_overlay_change(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Elm_Text_Class_Data *tc_data; + Eina_List *l; + + EINA_LIST_FOREACH(fdata.text_classes, l, tc_data) + { + if (tc_data->font) + { + const char *name; + + name = elm_font_fontconfig_name_get(tc_data->font, tc_data->style); + elm_font_overlay_set(tc_data->name, name, + tc_data->size ? tc_data->size : -100); + elm_font_fontconfig_name_free(name); + } + else + elm_font_overlay_unset(tc_data->name); + } + + elm_config_save(); + elm_font_overlay_all_apply(); + + /* TODO: apply hinting */ +} + static void _profile_change_do(Evas_Object *win, const char *profile) { @@ -774,9 +964,614 @@ _unimplemented(Evas_Object *win, Evas_Object *pager, const char *name) } static void -_status_config_fonts(Evas_Object *win, Evas_Object *pager) +_font_preview_update(Evas_Object *win) { - _unimplemented(win, pager, "fonts"); + Evas_Font_Size sz; + const char *name; + + if (!fdata.cur_font) + return; + + name = elm_font_fontconfig_name_get(fdata.cur_font, fdata.cur_style); + sz = fdata.cur_size; + + if (sz < 0) + sz = (-sz * 10) / 100; + if (sz == 0) + sz = 10; + + edje_object_text_class_set(evas_object_data_get(win, "font_preview"), + "font_preview", name, sz); + + elm_font_fontconfig_name_free(name); +} + +static void +_font_classes_list_sel(void *data __UNUSED__, + Evas_Object *obj, + void *event_info) +{ + const Eina_List *f_names_items, *l; + Elm_Text_Class_Data *tc_data; + Evas_Object *f_names_list; + Elm_List_Item *it; + + tc_data = elm_list_item_data_get(event_info); + + f_names_list = evas_object_data_get(elm_object_top_widget_get(obj), + "font_names_list"); + ELM_LIST_ENABLE(f_names_list); + + f_names_items = elm_list_items_get(f_names_list); + + EINA_LIST_FOREACH(f_names_items, l, it) + { + const char *l; + + l = elm_list_item_label_get(it); + + if (tc_data->font && !strcmp(l, tc_data->font)) + { + elm_list_item_selected_set(it, EINA_TRUE); + elm_list_item_show(it); + break; + } + } +} + +static void +_font_names_list_sel(void *data __UNUSED__, + Evas_Object *obj, + void *event_info) +{ + Evas_Object *style_list, *cls_list, *sizes_list, *win; + const char *style, *sel_font; + Elm_Text_Class_Data *tc_data; + Elm_List_Item *it, *fc_it; + Elm_Font_Properties *efp; + const Eina_List *l; + + it = event_info; + sel_font = elm_list_item_label_get(it); + + win = elm_object_top_widget_get(obj); + style_list = evas_object_data_get(win, "font_styles_list"); + cls_list = evas_object_data_get(win, "font_classes_list"); + sizes_list = evas_object_data_get(win, "font_sizes_list"); + + fc_it = elm_list_selected_item_get(cls_list); + if (!fc_it) return; /* should not happen, fonts list disabled in + * this case */ + + eina_stringshare_replace(&fdata.cur_font, sel_font); + + tc_data = elm_list_item_data_get(fc_it); + if (tc_data->font) eina_stringshare_del(tc_data->font); + if (fdata.cur_font) tc_data->font = eina_stringshare_ref(fdata.cur_font); + + /* load styles list */ + efp = eina_hash_find(fdata.font_hash, sel_font); + + ELM_LIST_ENABLE(style_list); + elm_list_clear(style_list); + + evas_event_freeze(evas_object_evas_get(style_list)); + edje_freeze(); + + it = NULL; + + EINA_LIST_FOREACH(efp->styles, l, style) + { + Elm_List_Item *i; + + i = elm_list_item_append(style_list, style, NULL, NULL, + _font_styles_list_sel, NULL); + + if (tc_data->style && (!strcmp(style, tc_data->style))) + it = i; + } + + elm_list_go(style_list); + + edje_thaw(); + evas_event_thaw(evas_object_evas_get(style_list)); + + if (it) + elm_list_item_selected_set(it, EINA_TRUE); + + _font_preview_update(win); +} + +static void +_font_styles_list_sel(void *data __UNUSED__, + Evas_Object *obj, + void *event_info) +{ + Evas_Object *fc_list, *fs_list, *win; + Elm_Text_Class_Data *tc_data; + const Eina_List *l; + Elm_List_Item *it; + + win = elm_object_top_widget_get(obj); + fc_list = evas_object_data_get(win, "font_classes_list"); + fs_list = evas_object_data_get(win, "font_sizes_list"); + + it = elm_list_selected_item_get(fc_list); + if (!it) return; /* should not happen */ + + eina_stringshare_replace(&fdata.cur_style, + elm_list_item_label_get(event_info)); + ELM_LIST_ENABLE(fs_list); + + tc_data = elm_list_item_data_get(it); + eina_stringshare_del(tc_data->style); + tc_data->style = eina_stringshare_ref(fdata.cur_style); + + evas_event_freeze(evas_object_evas_get(fs_list)); + edje_freeze(); + + EINA_LIST_FOREACH(elm_list_items_get(fs_list), l, it) + { + Elm_Font_Size_Data *sdata; + + sdata = elm_list_item_data_get(it); + elm_list_item_selected_set(l->data, EINA_FALSE); + + if (tc_data->size == sdata->size) + { + elm_list_item_selected_set(it, EINA_TRUE); + elm_list_item_show(it); + break; + } + } + + edje_thaw(); + evas_event_thaw(evas_object_evas_get(fs_list)); + + _font_preview_update(win); +} + +static void +_font_sizes_list_sel(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Elm_Text_Class_Data *tc_data; + Evas_Object *fc_list, *win; + Elm_Font_Size_Data *sd; + Elm_List_Item *it; + + win = elm_object_top_widget_get(obj); + fc_list = evas_object_data_get(win, "font_classes_list"); + + it = elm_list_selected_item_get(fc_list); + if (!it) return; /* should not happen */ + + sd = elm_list_item_data_get(event_info); + fdata.cur_size = sd->size; + + tc_data = elm_list_item_data_get(it); + tc_data->size = fdata.cur_size; + + _font_preview_update(win); +} + +static void +_fstyle_list_unselect_cb(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Evas_Object *sizes_list, *win; + + if (elm_list_selected_item_get(obj)) return; + + win = elm_object_top_widget_get(obj); + + sizes_list = evas_object_data_get(win, "font_sizes_list"); + ELM_LIST_DISABLE(sizes_list); +} + +static void +_fc_list_unselect_cb(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Evas_Object *font_names_list, *styles_list, *sizes_list, *win; + + if (elm_list_selected_item_get(obj)) return; + + win = elm_object_top_widget_get(obj); + + font_names_list = evas_object_data_get(win, "font_names_list"); + ELM_LIST_DISABLE(font_names_list); + + styles_list = evas_object_data_get(win, "font_styles_list"); + ELM_LIST_DISABLE(styles_list); + + sizes_list = evas_object_data_get(win, "font_sizes_list"); + ELM_LIST_DISABLE(sizes_list); +} + +static void +_font_classes_list_load(Evas_Object *li) +{ + Elm_Text_Class_Data *tc_data; + Eina_List *l; + Evas *evas; + + evas = evas_object_evas_get(li); + evas_event_freeze(evas); + edje_freeze(); + + EINA_LIST_FOREACH(fdata.text_classes, l, tc_data) + elm_list_item_append(li, tc_data->desc, NULL, NULL, _font_classes_list_sel, + tc_data); + + evas_object_smart_callback_add(li, "unselected", _fc_list_unselect_cb, + NULL); + + elm_list_go(li); + edje_thaw(); + evas_event_thaw(evas); +} + +static void +_fonts_data_fill(Evas *evas) +{ + const Eina_List *fo_list, *text_classes, *l; + Elm_Text_Class_Data *tc_data; + Elm_Font_Size_Data *sd; + Elm_Font_Overlay *efo; + Eina_List *evas_fonts; + Elm_Text_Class *etc; + int i; + + evas_fonts = evas_font_available_list(evas); + fdata.font_hash = elm_font_available_hash_add(evas_fonts); + evas_font_available_list_free(evas, evas_fonts); + + text_classes = elm_text_classes_list_get(); + fo_list = elm_font_overlay_list_get(); + + EINA_LIST_FOREACH(text_classes, l, etc) + { + const Eina_List *ll; + + tc_data = calloc(1, sizeof(*tc_data)); + tc_data->name = eina_stringshare_add(etc->name); + tc_data->desc = eina_stringshare_add(etc->desc); + + EINA_LIST_FOREACH(fo_list, ll, efo) + { + if (strcmp(tc_data->name, efo->text_class)) + continue; + + if (efo->font) + { + Elm_Font_Properties *efp; + + efp = elm_font_properties_get(efo->font); + if (efp) + { + tc_data->font = eina_stringshare_add(efp->name); + /* we're sure we recorded with only 1 style selected */ + tc_data->style = eina_stringshare_add(efp->styles->data); + elm_font_properties_free(efp); + } + } + tc_data->size = efo->size; + } + + fdata.text_classes = eina_list_append(fdata.text_classes, tc_data); + } + + elm_text_classes_list_free(text_classes); + + /* FIXME: hinting later */ + /* fdata.hinting = e_config->font_hinting; */ + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Tiny"); + sd->size = -50; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Small"); + sd->size = -80; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Normal"); + sd->size = -100; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Big"); + sd->size = -150; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Really Big"); + sd->size = -190; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Huge"); + sd->size = -250; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + for (i = 5; i < 21; i++) + { + char str[16]; + + str[0] = 0; + snprintf(str, sizeof(str), "%d pixels", i); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add(str); + sd->size = i; + fdata.font_px_list = eina_list_append(fdata.font_px_list, sd); + } +} + +static int +_font_sort_cb(const void *data1, + const void *data2) +{ + if (!data1) return 1; + if (!data2) return -1; + return strcmp(data1, data2); +} + +static void +_font_sizes_list_load(Evas_Object *size_list) +{ + Elm_Font_Size_Data *size_data; + Eina_List *l; + Evas *evas; + + evas = evas_object_evas_get(size_list); + evas_event_freeze(evas); + edje_freeze(); + + EINA_LIST_FOREACH(fdata.font_scale_list, l, size_data) + elm_list_item_append(size_list, size_data->size_str, NULL, NULL, + _font_sizes_list_sel, size_data); + + EINA_LIST_FOREACH(fdata.font_px_list, l, size_data) + elm_list_item_append(size_list, size_data->size_str, NULL, NULL, + _font_sizes_list_sel, size_data); + + elm_list_go(size_list); + edje_thaw(); + evas_event_thaw(evas); +} + +static void +_fnames_list_unselect_cb(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Evas_Object *styles_list, *sizes_list, *win; + + if (elm_list_selected_item_get(obj)) return; + + win = elm_object_top_widget_get(obj); + + styles_list = evas_object_data_get(win, "font_styles_list"); + ELM_LIST_DISABLE(styles_list); + + sizes_list = evas_object_data_get(win, "font_sizes_list"); + ELM_LIST_DISABLE(sizes_list); +} + +static Eina_Bool +_font_list_fill(const Eina_Hash *hash __UNUSED__, + const void *key __UNUSED__, + void *data, + void *fdata) +{ + Elm_Font_Properties *efp; + Eina_List **flist; + + flist = fdata; + efp = data; + + *flist = eina_list_append(*flist, efp->name); + + return EINA_TRUE; +} + +static void +_font_names_list_load(Evas_Object *flist) +{ + Eina_List *l, *names_list = NULL; + const char *font; + Evas *evas; + + evas = evas_object_evas_get(flist); + evas_event_freeze(evas); + edje_freeze(); + + eina_hash_foreach(fdata.font_hash, _font_list_fill, &names_list); + names_list = eina_list_sort(names_list, eina_list_count(names_list), + _font_sort_cb); + + EINA_LIST_FOREACH(names_list, l, font) + elm_list_item_append(flist, font, NULL, NULL, _font_names_list_sel, NULL); + + EINA_LIST_FREE(names_list, font); + + evas_object_smart_callback_add(flist, "unselected", _fnames_list_unselect_cb, + NULL); + + elm_list_go(flist); + + edje_thaw(); + evas_event_thaw(evas); +} + +static void +_status_config_fonts(Evas_Object *win, + Evas_Object *pager) +{ + Evas_Object *base, *fr, *li, *rc, *preview, *sp, *pd, *bt, *bx; + char buf[PATH_MAX]; + + _fonts_data_fill(evas_object_evas_get(win)); + + base = elm_table_add(win); + evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL); + + /* yeah, dummy rectangles are ugly as hell, but no good way yet of + fixing sizes */ + rc = evas_object_rectangle_add(evas_object_evas_get(win)); + evas_object_size_hint_min_set(rc, 70, 170); + elm_table_pack(base, rc, 1, 0, 1, 1); + + fr = elm_frame_add(win); + elm_frame_label_set(fr, "Font Class"); + elm_table_pack(base, fr, 0, 0, 1, 2); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(fr); + + /* FIXME: no multiselection for this list, for now */ + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_frame_content_set(fr, li); + evas_object_show(li); + + evas_object_data_set(win, "font_classes_list", li); + _font_classes_list_load(li); + + fr = elm_frame_add(win); + elm_frame_label_set(fr, "Font"); + elm_table_pack(base, fr, 1, 0, 1, 2); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(fr); + + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_frame_content_set(fr, li); + evas_object_show(li); + + evas_object_data_set(win, "font_names_list", li); + _font_names_list_load(li); + ELM_LIST_DISABLE(li); + + rc = evas_object_rectangle_add(evas_object_evas_get(win)); + evas_object_size_hint_min_set(rc, 70, 130); + elm_table_pack(base, rc, 1, 2, 1, 1); + + fr = elm_frame_add(win); + elm_frame_label_set(fr, "Style"); + elm_table_pack(base, fr, 0, 2, 1, 1); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(fr); + ELM_LIST_DISABLE(li); + + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_frame_content_set(fr, li); + evas_object_show(li); + + evas_object_data_set(win, "font_styles_list", li); + evas_object_smart_callback_add(li, "unselected", _fstyle_list_unselect_cb, + NULL); + + fr = elm_frame_add(win); + elm_frame_label_set(fr, "Size"); + elm_table_pack(base, fr, 1, 2, 1, 1); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(fr); + + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_frame_content_set(fr, li); + evas_object_show(li); + + evas_object_data_set(win, "font_sizes_list", li); + _font_sizes_list_load(li); + ELM_LIST_DISABLE(li); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_table_pack(base, bx, 0, 3, 2, 1); + evas_object_show(bx); + + /* FIXME: what to do here? dedicated widget? some new entry API set? */ + snprintf(buf, sizeof(buf), "%s/objects/font_preview.edj", PACKAGE_DATA_DIR); + preview = elm_layout_add(win); + elm_layout_file_set(preview, buf, "font_preview"); + elm_layout_text_set(preview, "elm.text", "Preview Text — 我真的会写中文"); + evas_object_size_hint_weight_set(preview, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(preview, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(preview); + + elm_box_pack_end(bx, preview); + evas_object_data_set(win, "font_preview", elm_layout_edje_get(preview)); + + ///////////////////////////////////////////// + sp = elm_separator_add(win); + elm_separator_horizontal_set(sp, EINA_TRUE); + evas_object_size_hint_weight_set(sp, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5); + elm_table_pack(base, sp, 0, 4, 2, 1); + evas_object_show(sp); + + pd = elm_frame_add(win); + elm_object_style_set(pd, "pad_medium"); + evas_object_size_hint_weight_set(pd, 0.0, 0.0); + evas_object_size_hint_align_set(pd, 0.5, 0.5); + elm_table_pack(base, pd, 0, 5, 2, 1); + evas_object_show(pd); + + bx = elm_box_add(win); + elm_box_horizontal_set(bx, EINA_TRUE); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(bx); + + bt = elm_button_add(win); + evas_object_smart_callback_add(bt, "clicked", _font_overlay_reset, win); + elm_button_label_set(bt, "Reset"); + evas_object_size_hint_weight_set(bt, 0.0, 0.0); + evas_object_size_hint_align_set(bt, 0.5, 0.5); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + bt = elm_button_add(win); + evas_object_smart_callback_add(bt, "clicked", _font_overlay_reset_all, win); + elm_button_label_set(bt, "Reset All"); + evas_object_size_hint_weight_set(bt, 0.0, 0.0); + evas_object_size_hint_align_set(bt, 0.5, 0.5); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + bt = elm_button_add(win); + evas_object_smart_callback_add(bt, "clicked", _font_overlay_change, win); + elm_button_label_set(bt, "Apply"); + evas_object_size_hint_weight_set(bt, 0.0, 0.0); + evas_object_size_hint_align_set(bt, 0.5, 0.5); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + elm_frame_content_set(pd, bx); + + evas_object_data_set(win, "fonts", base); + + elm_pager_content_push(pager, base); } static void @@ -1264,7 +2059,7 @@ status_win(void) win = elm_win_add(NULL, "main", ELM_WIN_BASIC); elm_win_title_set(win, "Elementary Config"); - evas_object_smart_callback_add(win, "delete,request", my_win_del, NULL); + evas_object_smart_callback_add(win, "delete,request", config_exit, NULL); bg = elm_bg_add(win); evas_object_size_hint_weight_set(bg, 1.0, 1.0); elm_win_resize_object_add(win, bg); diff --git a/legacy/elementary/src/lib/Elementary.h.in b/legacy/elementary/src/lib/Elementary.h.in index e2aa52265f..4af619597e 100644 --- a/legacy/elementary/src/lib/Elementary.h.in +++ b/legacy/elementary/src/lib/Elementary.h.in @@ -282,6 +282,41 @@ extern "C" { EAPI const char *elm_engine_current_get(void); EAPI void elm_engine_set(const char *engine); + typedef struct _Elm_Text_Class + { + const char *name; + const char *desc; + } Elm_Text_Class; + + typedef struct _Elm_Font_Overlay + { + const char *text_class; + const char *font; + Evas_Font_Size size; + } Elm_Font_Overlay; + + typedef struct _Elm_Font_Properties + { + const char *name; + Eina_List *styles; + } Elm_Font_Properties; + + EAPI const Eina_List *elm_text_classes_list_get(void); + EAPI void elm_text_classes_list_free(const Eina_List *list); + + EAPI const Eina_List *elm_font_overlay_list_get(void); + EAPI void elm_font_overlay_set(const char *text_class, const char *font, Evas_Font_Size size); + EAPI void elm_font_overlay_unset(const char *text_class); + EAPI void elm_font_overlay_apply(); + EAPI void elm_font_overlay_all_apply(); + + EAPI Elm_Font_Properties *elm_font_properties_get(const char *font); + EAPI void elm_font_properties_free(Elm_Font_Properties *efp); + EAPI const char *elm_font_fontconfig_name_get(const char *name, const char *style); + EAPI void elm_font_fontconfig_name_free(const char *name); + EAPI Eina_Hash *elm_font_available_hash_add(Eina_List *list); + EAPI void elm_font_available_hash_del(Eina_Hash *hash); + EAPI Evas_Coord elm_finger_size_get(void); EAPI void elm_finger_size_set(Evas_Coord size); EAPI void elm_finger_size_all_set(Evas_Coord size); diff --git a/legacy/elementary/src/lib/Makefile.am b/legacy/elementary/src/lib/Makefile.am index e737fd91d6..d297f27ea2 100644 --- a/legacy/elementary/src/lib/Makefile.am +++ b/legacy/elementary/src/lib/Makefile.am @@ -80,6 +80,7 @@ elm_conform.c \ elm_mapbuf.c \ elm_thumb.c \ elm_config.c \ +elm_font.c \ elm_animator.c \ elm_transit.c \ elm_calendar.c \ diff --git a/legacy/elementary/src/lib/elm_config.c b/legacy/elementary/src/lib/elm_config.c index e24ac91b23..62f970b00e 100644 --- a/legacy/elementary/src/lib/elm_config.c +++ b/legacy/elementary/src/lib/elm_config.c @@ -12,6 +12,7 @@ Elm_Config *_elm_config = NULL; char *_elm_profile = NULL; static Eet_Data_Descriptor *_config_edd = NULL; +static Eet_Data_Descriptor *_config_font_overlay_edd = NULL; const char *_elm_engines[] = { "software_x11", @@ -29,6 +30,34 @@ const char *_elm_engines[] = { NULL }; +/* whenever you want to add a new text class support into Elementary, + declare it both here and in the (default) theme */ +static const Elm_Text_Class _elm_text_classes[] = { + {"button", "Button Labels"}, + + /* FIXME: put in the right/definitive font classes */ + {"title_bar", "Title Bar"}, + {"menu_item", "Menu Item"}, + {"menu_title", "Menu Title"}, + {"tb_plain", "Textblock Plain"}, + {"tb_light", "Textblock Light"}, + {"tb_big", "Textblock Big"}, + {"move_text", "Move Text"}, + {"resize_text", "Resize Text"}, + {"winlist_title", "Winlist Title"}, + {"configure", "Settings Heading"}, + {"about_title", "About Title"}, + {"about_version", "About Version"}, + {"desklock_title", "Desklock Title"}, + {"desklock_passwd", "Desklock Password"}, + {"dialog_error", "Dialog Error"}, + {"exebuf_command", "Exebuf Command"}, + {"init_title", "Splash Title"}, + {"init_text", "Splash Text"}, + {"init_version", "Splash Version"}, + {NULL, NULL} +}; + static void _desc_init(void); static void _desc_shutdown(void); static void _profile_fetch_from_conf(void); @@ -50,7 +79,7 @@ static size_t _elm_user_dir_snprintf(char *dst, size_t size, const char *fmt, .. #ifdef HAVE_ELEMENTARY_X static Ecore_Event_Handler *_prop_change_handler = NULL; static Ecore_X_Window _root_1st = 0; -#define ATOM_COUNT 5 +#define ATOM_COUNT 6 static Ecore_X_Atom _atom[ATOM_COUNT]; static Ecore_X_Atom _atom_config = 0; static const char *_atom_names[ATOM_COUNT] = @@ -59,13 +88,15 @@ static const char *_atom_names[ATOM_COUNT] = "ENLIGHTENMENT_FINGER_SIZE", "ENLIGHTENMENT_THEME", "ENLIGHTENMENT_PROFILE", + "ENLIGHTENMENT_FONT_OVERLAY", "ENLIGHTENMENT_CONFIG" }; #define ATOM_E_SCALE 0 #define ATOM_E_FINGER_SIZE 1 #define ATOM_E_THEME 2 #define ATOM_E_PROFILE 3 -#define ATOM_E_CONFIG 4 +#define ATOM_E_FONT_OVERLAY 4 +#define ATOM_E_CONFIG 5 static Eina_Bool _prop_config_get(void); static Eina_Bool _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev); @@ -117,6 +148,7 @@ _prop_config_get(void) _config_free(); _elm_config = config_data; _config_apply(); + _elm_config_font_overlay_apply(); _elm_rescale(); return EINA_TRUE; } @@ -195,11 +227,27 @@ _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev) _config_free(); _config_load(); _config_apply(); + _elm_config_font_overlay_apply(); _elm_rescale(); } } } } + else if (event->atom == _atom[ATOM_E_FONT_OVERLAY]) + { + unsigned int val = 1000; + + if (ecore_x_window_prop_card32_get(event->win, + event->atom, + &val, 1) > 0) + { + _config_free(); + _config_load(); + _config_apply(); + _elm_config_font_overlay_apply(); + _elm_rescale(); + } + } else if (((_atom_config > 0) && (event->atom == _atom_config)) || (event->atom == _atom[ATOM_E_CONFIG])) { @@ -226,12 +274,33 @@ _desc_init(void) return; } -#define T Elm_Config -#define D _config_edd + memset(&eddc, 0, sizeof(eddc)); /* just in case... */ + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Font_Overlay); + eddc.func.str_direct_alloc = NULL; + eddc.func.str_direct_free = NULL; + + _config_font_overlay_edd = eet_data_descriptor_stream_new(&eddc); + if (!_config_font_overlay_edd) + { + printf("EEEK! eet_data_descriptor_stream_new() failed\n"); + eet_data_descriptor_free(_config_edd); + return; + } #define T_INT EET_T_INT #define T_DOUBLE EET_T_DOUBLE #define T_STRING EET_T_STRING #define T_UCHAR EET_T_UCHAR + +#define T Elm_Font_Overlay +#define D _config_font_overlay_edd + ELM_CONFIG_VAL(D, T, text_class, EET_T_STRING); + ELM_CONFIG_VAL(D, T, font, EET_T_STRING); + ELM_CONFIG_VAL(D, T, size, EET_T_INT); +#undef T +#undef D + +#define T Elm_Config +#define D _config_edd ELM_CONFIG_VAL(D, T, config_version, T_INT); ELM_CONFIG_VAL(D, T, engine, T_STRING); ELM_CONFIG_VAL(D, T, thumbscroll_enable, T_UCHAR); @@ -248,6 +317,7 @@ _desc_init(void) ELM_CONFIG_VAL(D, T, bgpixmap, T_INT); ELM_CONFIG_VAL(D, T, compositing, T_INT); /* EET_DATA_DESCRIPTOR_ADD_LIST(D, T, "font_dirs", font_dirs, sub_edd); */ + ELM_CONFIG_LIST(D, T, font_overlays, _config_font_overlay_edd); ELM_CONFIG_VAL(D, T, font_hinting, T_INT); ELM_CONFIG_VAL(D, T, image_cache, T_INT); ELM_CONFIG_VAL(D, T, font_cache, T_INT); @@ -274,9 +344,17 @@ _desc_init(void) static void _desc_shutdown(void) { - if (!_config_edd) return; - eet_data_descriptor_free(_config_edd); - _config_edd = NULL; + if (_config_edd) + { + eet_data_descriptor_free(_config_edd); + _config_edd = NULL; + } + + if (_config_font_overlay_edd) + { + eet_data_descriptor_free(_config_font_overlay_edd); + _config_font_overlay_edd = NULL; + } } static int @@ -365,6 +443,106 @@ _elm_config_profile_dir_get(const char *prof, Eina_Bool is_user) return NULL; } +Eina_List * +_elm_config_font_overlays_list(void) +{ + return _elm_config->font_overlays; +} + +void +_elm_config_font_overlay_set(const char *text_class, + const char *font, + Evas_Font_Size size) +{ + Elm_Font_Overlay *efd; + Eina_List *l; + + EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd) + { + if (strcmp(efd->text_class, text_class)) + continue; + + if (efd->font) eina_stringshare_del(efd->font); + efd->font = eina_stringshare_add(font); + efd->size = size; + _elm_config->font_overlays = + eina_list_promote_list(_elm_config->font_overlays, l); + return; + } + + /* the text class doesn't exist */ + efd = calloc(1, sizeof(Elm_Font_Overlay)); + efd->text_class = eina_stringshare_add(text_class); + efd->font = eina_stringshare_add(font); + efd->size = size; + + _elm_config->font_overlays = eina_list_prepend(_elm_config->font_overlays, + efd); +} + +void +_elm_config_font_overlay_remove(const char *text_class) +{ + Elm_Font_Overlay *efd; + Eina_List *l; + + EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd) + { + if (strcmp(efd->text_class, text_class)) + continue; + + _elm_config->font_overlays = + eina_list_remove_list(_elm_config->font_overlays, l); + if (efd->text_class) eina_stringshare_del(efd->text_class); + if (efd->font) eina_stringshare_del(efd->font); + free(efd); + + return; + } +} + +void +_elm_config_font_overlay_apply(void) +{ + Elm_Font_Overlay *efd; + Eina_List *l; + int i; + + for (i = 0; _elm_text_classes[i].desc; i++) + edje_text_class_del(_elm_text_classes[i].name); + + EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd) + edje_text_class_set(efd->text_class, efd->font, efd->size); +} + +Eina_List * +_elm_config_text_classes_get(void) +{ + Eina_List *ret = NULL; + int i; + + for (i = 0; _elm_text_classes[i].desc; i++) + { + Elm_Text_Class *tc; + tc = malloc(sizeof(*tc)); + + *tc = _elm_text_classes[i]; + + ret = eina_list_append(ret, tc); + } + + return ret; +} + +void +_elm_config_text_classes_free(Eina_List *l) +{ + Elm_Text_Class *tc; + + EINA_LIST_FREE(l, tc) + free(tc); +} + Eina_List * _elm_config_profiles_list(void) { @@ -512,6 +690,7 @@ _profile_fetch_from_conf(void) static void _config_free(void) { + Elm_Font_Overlay *fo; const char *fontdir; if (!_elm_config) return; @@ -520,6 +699,12 @@ _config_free(void) eina_stringshare_del(fontdir); } if (_elm_config->engine) eina_stringshare_del(_elm_config->engine); + EINA_LIST_FREE(_elm_config->font_overlays, fo) + { + if (fo->text_class) eina_stringshare_del(fo->text_class); + if (fo->font) eina_stringshare_del(fo->font); + free(fo); + } if (_elm_config->theme) eina_stringshare_del(_elm_config->theme); if (_elm_config->modules) eina_stringshare_del(_elm_config->modules); free(_elm_config); @@ -1040,6 +1225,7 @@ _elm_config_init(void) _config_load(); _env_get(); _config_apply(); + _elm_config_font_overlay_apply(); } void @@ -1143,6 +1329,7 @@ _elm_config_reload(void) _config_free(); _config_load(); _config_apply(); + _elm_config_font_overlay_apply(); _elm_rescale(); } @@ -1174,6 +1361,7 @@ _elm_config_profile_set(const char *profile) _config_free(); _config_load(); _config_apply(); + _elm_config_font_overlay_apply(); _elm_rescale(); } } diff --git a/legacy/elementary/src/lib/elm_font.c b/legacy/elementary/src/lib/elm_font.c new file mode 100644 index 0000000000..844fc7bdb9 --- /dev/null +++ b/legacy/elementary/src/lib/elm_font.c @@ -0,0 +1,128 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include +#include "elm_priv.h" + +Elm_Font_Properties * +_elm_font_properties_get(Eina_Hash **font_hash, + const char *font) +{ + Elm_Font_Properties *efp = NULL; + char *s1; + + s1 = strchr(font, ':'); + if (s1) + { + char *s2, *name, *style; + int len; + + len = s1 - font; + name = calloc(sizeof(char), len + 1); + strncpy(name, font, len); + + /* get subname (should be english) */ + s2 = strchr(name, ','); + if (s2) + { + len = s2 - name; + name = realloc(name, sizeof(char) * len + 1); + memset(name, 0, sizeof(char) * len + 1); + strncpy(name, font, len); + } + + if (!strncmp(s1, ELM_FONT_TOKEN_STYLE, strlen(ELM_FONT_TOKEN_STYLE))) + { + style = s1 + strlen(ELM_FONT_TOKEN_STYLE); + + if (font_hash) efp = eina_hash_find(*font_hash, name); + if (!efp) + { + efp = calloc(1, sizeof(Elm_Font_Properties)); + efp->name = eina_stringshare_add(name); + if (font_hash) + { + if (!*font_hash) + *font_hash = eina_hash_string_superfast_new(NULL); + eina_hash_add(*font_hash, name, efp); + } + } + s2 = strchr(style, ','); + if (s2) + { + char *style_old; + + len = s2 - style; + style_old = style; + style = calloc(sizeof(char), len + 1); + strncpy(style, style_old, len); + efp->styles = eina_list_append(efp->styles, + eina_stringshare_add(style)); + free(style); + } + else + efp->styles = eina_list_append(efp->styles, + eina_stringshare_add(style)); + } + free(name); + } + else + { + if (font_hash) efp = eina_hash_find(*font_hash, font); + if (!efp) + { + efp = calloc(1, sizeof(Elm_Font_Properties)); + efp->name = eina_stringshare_add(font); + if (font_hash) + { + if (!*font_hash) + *font_hash = eina_hash_string_superfast_new(NULL); + eina_hash_add(*font_hash, font, efp); + } + } + } + return efp; +} + +/* FIXME: do we really need it? */ +Eina_Hash * +_elm_font_available_hash_add(Eina_Hash *font_hash, + const char *full_name) +{ + _elm_font_properties_get(&font_hash, full_name); + return font_hash; +} + +static void +_elm_font_properties_free(Elm_Font_Properties *efp) +{ + const char *str; + + EINA_LIST_FREE(efp->styles, str) + if (str) eina_stringshare_del(str); + + if (efp->name) eina_stringshare_del(efp->name); + free(efp); +} + +static Eina_Bool +_font_hash_free_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__) +{ + Elm_Font_Properties *efp; + + efp = data; + _elm_font_properties_free(efp); + return EINA_TRUE; +} + +void +_elm_font_available_hash_del(Eina_Hash *hash) +{ + eina_hash_foreach(hash, _font_hash_free_cb, NULL); + eina_hash_free(hash); +} diff --git a/legacy/elementary/src/lib/elm_main.c b/legacy/elementary/src/lib/elm_main.c index 76d8f7db2c..4a860b79be 100644 --- a/legacy/elementary/src/lib/elm_main.c +++ b/legacy/elementary/src/lib/elm_main.c @@ -1439,6 +1439,280 @@ elm_engine_set(const char *engine) _elm_config_engine_set(engine); } +/** + * @defgroup Fonts Elementary Fonts + * + * These are functions dealing with font rendering, selection and the + * like for Elementary applications. One might fetch which system + * fonts are there to use and set custom fonts for individual classes + * of UI items containing text (text classes). + */ + +/** + * Get Elementary's list of supported text classes. + * + * @return The text classes list, with @c Elm_Text_Class blobs as data. + * @ingroup Fonts + * + * Release the list with elm_text_classes_list_free(). + */ +EAPI const Eina_List * +elm_text_classes_list_get(void) +{ + return _elm_config_text_classes_get(); +} + +/** + * Free Elementary's list of supported text classes. + * + * @ingroup Fonts + * + * @see elm_text_classes_list_get(). + */ +EAPI void +elm_text_classes_list_free(const Eina_List *list) +{ + _elm_config_text_classes_free((Eina_List *)list); +} + +/** + * Get Elementary's list of font overlays, set with + * elm_font_overlay_set(). + * + * @return The font overlays list, with @c Elm_Font_Overlay blobs as + * data. + * + * @ingroup Fonts + * + * For each text class, one can set a font overlay for it, + * overriding the default font properties for that class coming from + * the theme in use. There is no need to free this list. + * + * @see elm_font_overlay_set() and elm_font_overlay_unset(). + */ +EAPI const Eina_List * +elm_font_overlay_list_get(void) +{ + return _elm_config_font_overlays_list(); +} + +/** + * Set a font overlay for a given Elementary text class. + * + * @param text_class Text class name + * @param font Font name and style string + * @param size Font size + * + * @ingroup Fonts + * + * @p font has to be in the format returned by + * elm_font_fontconfig_name_get(). @see elm_font_overlay_list_get() + * and @elm_font_overlay_unset(). + */ +EAPI void +elm_font_overlay_set(const char *text_class, + const char *font, + Evas_Font_Size size) +{ + _elm_config_font_overlay_set(text_class, font, size); +} + +/** + * Unset a font overlay for a given Elementary text class. + * + * @param text_class Text class name + * + * @ingroup Fonts + * + * This will bring back text elements belonging to text class @p + * text_class back to their default font settings. + */ +EAPI void +elm_font_overlay_unset(const char *text_class) +{ + _elm_config_font_overlay_remove(text_class); +} + +/** + * Apply the changes made with elm_font_overlay_set() and + * elm_font_overlay_unset() on the current Elementary window. + * + * @ingroup Fonts + * + * This applies all font overlays set to all objects in the UI. + */ +EAPI void +elm_font_overlay_apply(void) +{ + _elm_config_font_overlay_apply(); +} + +/** + * Apply the changes made with elm_font_overlay_set() and + * elm_font_overlay_unset() on all Elementary application windows. + * + * @ingroup Fonts + * + * This applies all font overlays set to all objects in the UI. + */ +EAPI void +elm_font_overlay_all_apply(void) +{ +#ifdef HAVE_ELEMENTARY_X + static Ecore_X_Atom atom = 0; + unsigned int dummy = (unsigned int)(1 * 1000.0); + + if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FONT_OVERLAY"); + ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(), atom, &dummy, + 1); +#endif +} + +/** + * Translate a font (family) name string in fontconfig's font names + * syntax into an @c Elm_Font_Properties struct. + * + * @param font The font name and styles string + * @return the font properties struct + * + * @ingroup Fonts + * + * @note The reverse translation can be achived with + * elm_font_fontconfig_name_get(), for one style only (single font + * instance, not family). + */ +EAPI Elm_Font_Properties * +elm_font_properties_get(const char *font) +{ + if (!font) return NULL; + return _elm_font_properties_get(NULL, font); +} + +/** + * Free font properties return by elm_font_properties_get(). + * + * @param efp the font properties struct + * + * @ingroup Fonts + */ +EAPI void +elm_font_properties_free(Elm_Font_Properties *efp) +{ + const char *str; + + EINA_LIST_FREE(efp->styles, str) + if (str) eina_stringshare_del(str); + if (efp->name) eina_stringshare_del(efp->name); + free(efp); +} + +/** + * Translate a font name, bound to a style, into fontconfig's font names + * syntax. + * + * @param name The font (family) name + * @param style The given style (may be @c NULL) + * + * @return the font name and style string + * + * @ingroup Fonts + * + * @note The reverse translation can be achived with + * elm_font_properties_get(), for one style only (single font + * instance, not family). + */ +EAPI const char * +elm_font_fontconfig_name_get(const char *name, + const char *style) +{ + char buf[256]; + + if (!name) return NULL; + if (!style || style[0] == 0) return eina_stringshare_add(name); + snprintf(buf, 256, "%s" ELM_FONT_TOKEN_STYLE "%s", name, style); + return eina_stringshare_add(buf); +} + +/** + * Free the font string return by elm_font_fontconfig_name_get(). + * + * @param efp the font properties struct + * + * @ingroup Fonts + */ +EAPI void +elm_font_fontconfig_name_free(const char *name) +{ + eina_stringshare_del(name); +} + +/** + * Create a font hash table of available system fonts. + * + * One must call it with @p list being the return value of + * evas_font_available_list(). The hash will be indexed by font + * (family) names, being its values @c Elm_Font_Properties blobs. + * + * @param list The list of available system fonts, as returned by + * evas_font_available_list(). + * @return the font hash. + * + * @ingroup Fonts + * + * @note The user is supposed to get it populated at least with 3 + * default font families (Sans, Serif, Monospace), which should be + * present on most systems. + */ +EAPI Eina_Hash * +elm_font_available_hash_add(Eina_List *list) +{ + Eina_Hash *font_hash; + Eina_List *l; + void *key; + + font_hash = NULL; + + /* populate with default font families */ + font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Regular"); + font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Bold"); + font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Oblique"); + font_hash = _elm_font_available_hash_add(font_hash, + "Sans:style=Bold Oblique"); + + font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Regular"); + font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Bold"); + font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Oblique"); + font_hash = _elm_font_available_hash_add(font_hash, + "Serif:style=Bold Oblique"); + + font_hash = _elm_font_available_hash_add(font_hash, + "Monospace:style=Regular"); + font_hash = _elm_font_available_hash_add(font_hash, + "Monospace:style=Bold"); + font_hash = _elm_font_available_hash_add(font_hash, + "Monospace:style=Oblique"); + font_hash = _elm_font_available_hash_add(font_hash, + "Monospace:style=Bold Oblique"); + + EINA_LIST_FOREACH(list, l, key) + font_hash = _elm_font_available_hash_add(font_hash, key); + + return font_hash; +} + +/** + * Free the hash return by elm_font_available_hash_add(). + * + * @param hash the hash to be freed. + * + * @ingroup Fonts + */ +EAPI void +elm_font_available_hash_del(Eina_Hash *hash) +{ + _elm_font_available_hash_del(hash); +} + /** * @defgroup Fingers Fingers * diff --git a/legacy/elementary/src/lib/elm_priv.h b/legacy/elementary/src/lib/elm_priv.h index 526a58b429..cb39ad3993 100644 --- a/legacy/elementary/src/lib/elm_priv.h +++ b/legacy/elementary/src/lib/elm_priv.h @@ -67,6 +67,8 @@ extern const char *_elm_engines[]; #define ELM_SOFTWARE_16_SDL (_elm_engines[10]) #define ELM_OPENGL_SDL (_elm_engines[11]) +#define ELM_FONT_TOKEN_STYLE ":style=" + struct _Elm_Config { int config_version; @@ -85,6 +87,7 @@ struct _Elm_Config int bgpixmap; int compositing; Eina_List *font_dirs; + Eina_List *font_overlays; int font_hinting; int image_cache; int font_cache; @@ -156,6 +159,17 @@ void _elm_config_profile_set(const char *profile); void _elm_config_engine_set(const char *engine); +Eina_List *_elm_config_font_overlays_list(void); +void _elm_config_font_overlay_set(const char *text_class, const char *font, Evas_Font_Size size); +void _elm_config_font_overlay_remove(const char *text_class); +void _elm_config_font_overlay_apply(void); +Eina_List *_elm_config_text_classes_get(void); +void _elm_config_text_classes_free(Eina_List *l); + +Elm_Font_Properties *_elm_font_properties_get(Eina_Hash **font_hash, const char *font); +Eina_Hash *_elm_font_available_hash_add(Eina_Hash *font_hash, const char *full_name); +void _elm_font_available_hash_del(Eina_Hash *hash); + void elm_tooltip_theme(Elm_Tooltip *tt); void elm_object_sub_tooltip_content_cb_set(Evas_Object *eventarea, Evas_Object *owner, Elm_Tooltip_Content_Cb func, const void *data, Evas_Smart_Cb del_cb); void elm_cursor_theme(Elm_Cursor *cur);