struct _Fndat
{
- const char *name;
+ Evas_Font_Description *fdesc;
const char *source;
- int size;
+ Evas_Font_Size size;
Evas_Font_Set *font;
int ref;
Font_Rend_Flags wanted_rend;
EINA_LIST_FREE(fonts_zero, fd)
{
- if (fd->name) eina_stringshare_del(fd->name);
+ if (fd->fdesc) evas_font_desc_unref(fd->fdesc);
if (fd->source) eina_stringshare_del(fd->source);
evas->engine.func->font_free(evas->engine.data.output, fd->font);
#ifdef HAVE_FONTCONFIG
if (fd->ref != 0) break;
fonts_zero = eina_list_remove_list(fonts_zero, fonts_zero);
- if (fd->name) eina_stringshare_del(fd->name);
+ if (fd->fdesc) evas_font_desc_unref(fd->fdesc);
if (fd->source) eina_stringshare_del(fd->source);
evas->engine.func->font_free(evas->engine.data.output, fd->font);
#ifdef HAVE_FONTCONFIG
if (fd->ref != 0) break;
fonts_zero = eina_list_remove_list(fonts_zero, fonts_zero);
- if (fd->name) eina_stringshare_del(fd->name);
+ if (fd->fdesc) evas_font_desc_unref(fd->fdesc);
if (fd->source) eina_stringshare_del(fd->source);
evas->engine.func->font_free(evas->engine.data.output, fd->font);
#ifdef HAVE_FONTCONFIG
}
#endif
-static Eina_Bool
-_font_style_name_match(const char *font_name, const char *style_name)
+struct _FcPattern {
+ int num;
+ int size;
+ intptr_t elts_offset;
+ int ref;
+};
+
+#ifdef HAVE_FONTCONFIG
+/* In sync with Evas_Font_Style, Evas_Font_Weight and Evas_Font_Width */
+static int _fc_slant_map[] =
+{
+ FC_SLANT_ROMAN,
+ FC_SLANT_OBLIQUE,
+ FC_SLANT_ITALIC
+};
+
+static int _fc_weight_map[] =
+{
+ FC_WEIGHT_NORMAL,
+ FC_WEIGHT_THIN,
+ FC_WEIGHT_ULTRALIGHT,
+ FC_WEIGHT_LIGHT,
+ FC_WEIGHT_BOOK,
+ FC_WEIGHT_MEDIUM,
+ FC_WEIGHT_SEMIBOLD,
+ FC_WEIGHT_BOLD,
+ FC_WEIGHT_ULTRABOLD,
+ FC_WEIGHT_BLACK,
+ FC_WEIGHT_EXTRABLACK
+};
+
+# ifdef FC_WIDTH
+static int _fc_width_map[] =
+{
+ FC_WIDTH_NORMAL,
+ FC_WIDTH_ULTRACONDENSED,
+ FC_WIDTH_EXTRACONDENSED,
+ FC_WIDTH_CONDENSED,
+ FC_WIDTH_SEMICONDENSED,
+ FC_WIDTH_SEMIEXPANDED,
+ FC_WIDTH_EXPANDED,
+ FC_WIDTH_EXTRAEXPANDED,
+ FC_WIDTH_ULTRAEXPANDED
+};
+# endif
+
+#endif
+
+struct _Style_Map
+{
+ const char *name;
+ int type;
+};
+typedef struct _Style_Map Style_Map;
+
+static Style_Map _style_width_map[] =
+{
+ {"normal", EVAS_FONT_WIDTH_NORMAL},
+ {"ultracondensed", EVAS_FONT_WIDTH_ULTRACONDENSED},
+ {"extracondensed", EVAS_FONT_WIDTH_EXTRACONDENSED},
+ {"condensed", EVAS_FONT_WIDTH_CONDENSED},
+ {"semicondensed", EVAS_FONT_WIDTH_SEMICONDENSED},
+ {"semiexpanded", EVAS_FONT_WIDTH_SEMIEXPANDED},
+ {"expanded", EVAS_FONT_WIDTH_EXPANDED},
+ {"extraexpanded", EVAS_FONT_WIDTH_EXTRAEXPANDED},
+ {"ultraexpanded", EVAS_FONT_WIDTH_ULTRAEXPANDED},
+};
+
+static Style_Map _style_weight_map[] =
{
- char *style_key = NULL;
+ {"normal", EVAS_FONT_WEIGHT_NORMAL},
+ {"thin", EVAS_FONT_WEIGHT_THIN},
+ {"ultralight", EVAS_FONT_WEIGHT_ULTRALIGHT},
+ {"light", EVAS_FONT_WEIGHT_LIGHT},
+ {"book", EVAS_FONT_WEIGHT_BOOK},
+ {"medium", EVAS_FONT_WEIGHT_MEDIUM},
+ {"semibold", EVAS_FONT_WEIGHT_SEMIBOLD},
+ {"bold", EVAS_FONT_WEIGHT_BOLD},
+ {"ultrabold", EVAS_FONT_WEIGHT_ULTRABOLD},
+ {"black", EVAS_FONT_WEIGHT_BLACK},
+ {"extrablack", EVAS_FONT_WEIGHT_EXTRABLACK}
+};
- style_key = strchr(font_name, ':');
- if (!style_key) return EINA_FALSE;
- if (strlen(style_key) > 2) style_key++;
- if (strstr(style_key, "style="))
+static Style_Map _style_slant_map[] =
+{
+ {"normal", EVAS_FONT_SLANT_NORMAL},
+ {"oblique", EVAS_FONT_SLANT_OBLIQUE},
+ {"italic", EVAS_FONT_SLANT_ITALIC}
+};
+
+#define _STYLE_MAP_LEN(x) (sizeof(x) / sizeof(*(x)))
+/**
+ * @internal
+ * Find a certain attribute from the map in the style.
+ * @return the index of the found one.
+ */
+static int
+_evas_font_style_find_internal(const char *style, const char *style_end,
+ Style_Map _map[], size_t map_len)
+{
+ size_t i;
+ while (style < style_end)
{
- if (!strcmp(style_name, "Italic"))
+ for (i = 0 ; i < map_len ; i++)
{
- if (strstr(style_key, "Italic")
- || strstr(style_key, "italic")
- || strstr(style_key, "Cursiva")
- || strstr(style_key, "cursiva")
- || strstr(style_key, "Oblique")
- || strstr(style_key, "oblique"))
- return EINA_TRUE;
- else
- return EINA_FALSE;
+ size_t len;
+ const char *cur = _map[i].name;
+ len = strlen(cur);
+ if (!strncasecmp(style, cur, len) &&
+ (!cur[len] || (cur[len] == ' ')))
+ {
+ return _map[i].type;
+ }
}
- else if (!strcmp(style_name, "Bold"))
+ style = strchr(style, ' ');
+ if (!style)
+ break;
+
+ while (*style && (*style == ' '))
+ style++;
+ }
+ return 0;
+}
+
+int
+evas_font_style_find(const char *start, const char *end,
+ Evas_Font_Style style)
+{
+#define _RET_STYLE(x) \
+ return _evas_font_style_find_internal(start, end, \
+ _style_##x##_map, _STYLE_MAP_LEN(_style_##x##_map));
+ switch (style)
+ {
+ case EVAS_FONT_STYLE_SLANT:
+ _RET_STYLE(slant);
+ case EVAS_FONT_STYLE_WEIGHT:
+ _RET_STYLE(weight);
+ case EVAS_FONT_STYLE_WIDTH:
+ _RET_STYLE(width);
+ default:
+ return 0;
+ }
+#undef _RET_STYLE
+}
+
+void
+evas_font_desc_unref(Evas_Font_Description *fdesc)
+{
+ if (--(fdesc->ref) == 0)
+ {
+ eina_stringshare_del(fdesc->name);
+ free(fdesc);
+ }
+}
+
+Evas_Font_Description *
+evas_font_desc_ref(Evas_Font_Description *fdesc)
+{
+ fdesc->ref++;
+ return fdesc;
+}
+
+Evas_Font_Description *
+evas_font_desc_new(void)
+{
+ Evas_Font_Description *fdesc;
+ fdesc = calloc(1, sizeof(*fdesc));
+ fdesc->ref = 1;
+ fdesc->new = EINA_TRUE;
+
+ return fdesc;
+}
+
+Evas_Font_Description *
+evas_font_desc_dup(const Evas_Font_Description *fdesc)
+{
+ Evas_Font_Description *new;
+ new = evas_font_desc_new();
+ memcpy(new, fdesc, sizeof(*new));
+ new->ref = 1;
+ new->new = EINA_TRUE;
+ new->name = eina_stringshare_ref(new->name);
+
+ return new;
+}
+
+int
+evas_font_desc_cmp(const Evas_Font_Description *a,
+ const Evas_Font_Description *b)
+{
+ /* FIXME: Do actual comparison, i.e less than and bigger than. */
+ return !((a->name == b->name) && (a->weight == b->weight) &&
+ (a->slant == b->slant) && (a->width == b->width) &&
+ (a->lang == b->lang));
+}
+
+void
+evas_font_name_parse(Evas_Font_Description *fdesc, const char *name)
+{
+ const char *end;
+
+ end = strchr(name, ':');
+ if (!end)
+ fdesc->name = eina_stringshare_add(name);
+ else
+ fdesc->name = eina_stringshare_add_length(name, end - name);
+
+ while (end)
+ {
+ const char *tend;
+ name = end;
+ end = strchr(end + 1, ':');
+ if (!end)
+ tend = name + strlen(name);
+ else
+ tend = end;
+
+ if (!strncmp(name, ":style=", 7))
{
- if (strstr(style_key, "Bold")
- || strstr(style_key, "bold")
- || strstr(style_key, "Negreta")
- || strstr(style_key, "negreta"))
- return EINA_TRUE;
- else
- return EINA_FALSE;
+#define _SET_STYLE(x) \
+ fdesc->x = _evas_font_style_find_internal(name + 7, tend, \
+ _style_##x##_map, _STYLE_MAP_LEN(_style_##x##_map));
+ _SET_STYLE(slant);
+ _SET_STYLE(weight);
+ _SET_STYLE(width);
+#undef _SET_STYLE
+ }
+ else if (!strncmp(name, ":lang=", 6))
+ {
+ /* FIXME: handle lang. */
}
- else
- return EINA_FALSE;
}
- else
- return EINA_FALSE;
}
-struct _FcPattern {
- int num;
- int size;
- intptr_t elts_offset;
- int ref;
-};
-
void *
-evas_font_load(Evas *evas, const char *name, const char *source, int size)
+evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Evas_Font_Size size)
{
#ifdef HAVE_FONTCONFIG
FcPattern *p_nm = NULL;
char *nm;
Font_Rend_Flags wanted_rend = 0;
- if (!name) return NULL;
- if (name[0] == 0) return NULL;
+ if (!fdesc) return NULL;
+ fdesc->new = EINA_FALSE;
- if (_font_style_name_match(name, "Italic"))
+ if (fdesc->slant != EVAS_FONT_SLANT_NORMAL)
wanted_rend |= FONT_REND_ITALIC;
- if (_font_style_name_match(name, "Bold"))
+ if (fdesc->weight == EVAS_FONT_WEIGHT_BOLD)
wanted_rend |= FONT_REND_BOLD;
evas_font_init();
EINA_LIST_FOREACH(fonts_cache, l, fd)
{
- if (!strcmp(name, fd->name))
+ if (!evas_font_desc_cmp(fdesc, fd->fdesc))
{
if (((!source) && (!fd->source)) ||
((source) && (fd->source) && (!strcmp(source, fd->source))))
{
- if ((size == fd->size) && (wanted_rend == fd->wanted_rend))
+ if ((size == fd->size) &&
+ (wanted_rend == fd->wanted_rend))
{
fonts_cache = eina_list_promote_list(fonts_cache, l);
fd->ref++;
EINA_LIST_FOREACH(fonts_zero, l, fd)
{
- if (!strcmp(name, fd->name))
+ if (!evas_font_desc_cmp(fdesc, fd->fdesc))
{
if (((!source) && (!fd->source)) ||
((source) && (fd->source) && (!strcmp(source, fd->source))))
{
- if ((size == fd->size) && (wanted_rend == fd->wanted_rend))
+ if ((size == fd->size) &&
+ (wanted_rend == fd->wanted_rend))
{
fonts_zero = eina_list_remove_list(fonts_zero, l);
fonts_cache = eina_list_prepend(fonts_cache, fd);
}
}
- fonts = evas_font_set_get(name);
+ fonts = evas_font_set_get(fdesc->name);
EINA_LIST_FOREACH(fonts, l, nm) /* Load each font in append */
{
if (l == fonts || !font) /* First iteration OR no font */
{
FcResult res;
- p_nm = FcNameParse((FcChar8 *)name);
+ p_nm = FcPatternBuild (NULL,
+ FC_WEIGHT, FcTypeInteger, _fc_weight_map[fdesc->weight],
+ FC_SLANT, FcTypeInteger, _fc_slant_map[fdesc->slant],
+#ifdef FC_WIDTH
+ FC_WIDTH, FcTypeInteger, _fc_width_map[fdesc->width],
+#endif
+ NULL);
+ /* FIXME: Handle font fallbacks!!! */
+ FcPatternAddString (p_nm, FC_FAMILY, (FcChar8*) fdesc->name);
+
FcConfigSubstitute(NULL, p_nm, FcMatchPattern);
FcDefaultSubstitute(p_nm);
set = FcFontSort(NULL, p_nm, FcTrue, NULL, &res);
if (!set)
{
- ERR("No fontconfig font matches '%s'. It was the last resource, no font found!", name);
+ ERR("No fontconfig font matches '%s'. It was the last resource, no font found!", fdesc->name);
FcPatternDestroy(p_nm);
p_nm = NULL;
}
else
{
- // FIXME: this i think is a bugfix for a rare bug... but i'm
- // not sure 100%. it seems that way from fc. if trim is set
- // to FcTrue...
- // ok - not a bugfix... but there is something going on somewhere that's weird?
-// FcPatternReference(p_nm); /* we have to reference count the pat */
font = evas_load_fontconfig(evas, set, size, wanted_rend);
}
}
fd = calloc(1, sizeof(Fndat));
if (fd)
{
- fd->name = eina_stringshare_add(name);
+ fd->fdesc = evas_font_desc_ref(fdesc);
if (source) fd->source = eina_stringshare_add(source);
- fd->size = size;
fd->font = font;
fd->wanted_rend = wanted_rend;
fd->ref = 1;
struct {
const char *utf8_text; /* The text exposed to the API */
const char *font;
+ Evas_Font_Description *fdesc;
const char *source;
Evas_Font_Size size;
struct {
{
Evas_Object_Text *o;
int is, was = 0, pass = 0;
- int same_font = 0;
+ Evas_Font_Description *fdesc;
if ((!font) || (size <= 0)) return;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return;
MAGIC_CHECK_END();
- if ((o->cur.font) && (font) && (!strcmp(o->cur.font, font)))
+ fdesc = evas_font_desc_new();
+ evas_font_name_parse(fdesc, font);
+ if (o->cur.fdesc && !evas_font_desc_cmp(fdesc, o->cur.fdesc) &&
+ (size == o->cur.size))
{
- same_font = 1;
- if (size == o->cur.size) return;
+ evas_font_desc_unref(fdesc);
+ return;
}
+
+ if (o->cur.fdesc) evas_font_desc_unref(o->cur.fdesc);
+ o->cur.fdesc = fdesc;
+
+ o->cur.size = size;
+ eina_stringshare_replace(&o->cur.font, font);
+ o->prev.font = NULL;
+
if (obj->layer->evas->events_frozen <= 0)
{
pass = evas_event_passes_through(obj);
evas_font_free(obj->layer->evas, o->font);
o->font = NULL;
}
- if (!same_font)
- {
- /*
- if (o->cur.font) eina_stringshare_del(o->cur.font);
- if (font) o->cur.font = eina_stringshare_add(font);
- else o->cur.font = NULL;
- */
- eina_stringshare_replace(&o->cur.font, font);
- o->prev.font = NULL;
- }
- o->cur.size = size;
- o->font = evas_font_load(obj->layer->evas, o->cur.font, o->cur.source,
- (int)(((double)o->cur.size) * obj->cur.scale));
+
+ o->font = evas_font_load(obj->layer->evas, o->cur.fdesc, o->cur.source,
+ (int)(((double) o->cur.size) * obj->cur.scale));
if (o->font)
{
o->ascent = ENFN->font_ascent_get(ENDT, o->font);
if (o->items) _evas_object_text_items_clear(o);
if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
if (o->cur.font) eina_stringshare_del(o->cur.font);
+ if (o->cur.fdesc) evas_font_desc_unref(o->cur.fdesc);
if (o->cur.source) eina_stringshare_del(o->cur.source);
if (o->font) evas_font_free(obj->layer->evas, o->font);
#ifdef BIDI_SUPPORT
double halign;
double valign;
struct {
- const char *name;
+ Evas_Font_Description *fdesc;
const char *source;
const char *fallbacks;
Evas_Font_Set *font;
- int size;
+ Evas_Font_Size size;
} font;
struct {
struct {
{
fmt->ref--;
if (fmt->ref > 0) return;
- if (fmt->font.name) eina_stringshare_del(fmt->font.name);
+ if (fmt->font.fdesc) evas_font_desc_unref(fmt->font.fdesc);
if (fmt->font.fallbacks) eina_stringshare_del(fmt->font.fallbacks);
if (fmt->font.source) eina_stringshare_del(fmt->font.source);
evas_font_free(obj->layer->evas, fmt->font.font);
*ds = 0;
}
-static const char *_style_weight_map[] = { "ultralight", "light", "bold",
- "ultrabold", "black", "normal" };
-#define _STYLE_WEIGHT_MAP_LEN (sizeof(_style_weight_map) / sizeof(_style_weight_map[0]))
-
-static const char *_style_style_map[] = { "normal", "oblique", "italic" };
-#define _STYLE_STYLE_MAP_LEN (sizeof(_style_style_map) / sizeof(_style_style_map[0]))
-/**
- * @internal
- * Find a certain attribute from the map in the style.
- * @return true if found, false otherwise.
- */
-static Eina_Bool
-_format_font_style_find(const char *style, const char *style_end,
- const char **start, const char **end, const char *_map[], size_t map_len)
-{
- size_t i;
- while (style < style_end)
- {
- for (i = 0 ; i < map_len ; i++)
- {
- size_t len;
- const char *cur = _map[i];
- len = strlen(cur);
- if (!strncasecmp(style, cur, len) &&
- (!cur[len] || (cur[len] == ' ')))
- {
- *start = style;
- *end = *start + len;
- return EINA_TRUE;
- }
- }
- style = strchr(style, ' ');
- if (!style)
- break;
-
- while (*style && _is_white(*style))
- style++;
- }
- return EINA_FALSE;
-}
-
-static void
-_format_command_parse_font_weight_style(Evas_Object_Textblock_Format *fmt,
- const char *param, const char *_map[], size_t map_len)
-{
- size_t flen = eina_stringshare_strlen(fmt->font.name);
- const char *style = strstr(fmt->font.name, ":style=");
- if (style)
- {
- Eina_Strbuf *buf;
- const char *found_start, *found_end;
- const char *style_end = strchr(style + 7, ':');
- /* Point to the end, either it be the next attribute,
- * or the terminating 0 */
- if (!style_end)
- style_end = fmt->font.name + flen;
-
- buf = eina_strbuf_new();
- eina_strbuf_append_length(buf, fmt->font.name, flen);
-
- if (_format_font_style_find(style + 7, style_end,
- &found_start, &found_end, _map, map_len))
- {
- eina_strbuf_remove(buf, found_start - fmt->font.name,
- found_end - fmt->font.name);
- }
- else
- {
- found_start = style + 7; /* + 7 for :style= */
- eina_strbuf_insert_char(buf, ' ', found_start - fmt->font.name);
- }
- eina_strbuf_insert(buf, param, found_start - fmt->font.name);
- if (fmt->font.name) eina_stringshare_del(fmt->font.name);
- fmt->font.name = eina_stringshare_add(eina_strbuf_string_get(buf));
- eina_strbuf_free(buf);
- }
- else
- {
- /* Make a buffer big enough to hold whatever we do.
- * 7 == len(:style=). */
- char *tmpres = alloca(flen + strlen(param) + 7 + 1);
- /* Handle font.name == NULL */
- memcpy(tmpres, fmt->font.name, flen);
- sprintf(tmpres + flen, ":style=%s", param);
- if (fmt->font.name) eina_stringshare_del(fmt->font.name);
- fmt->font.name = eina_stringshare_add(tmpres);
- }
-}
-
/**
* @internal
* Parses the cmd and parameter and adds the parsed format to fmt.
static void
_format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char *cmd, const char *param)
{
- int new_font = 0;
int len;
char *tmp_param;
tmp_param = alloca(len + 1);
_format_clean_param(tmp_param, param);
- if (cmd == fontstr)
+
+ /* If we are changing the font, create the fdesc. */
+ if ((cmd == font_weightstr) || (cmd == font_stylestr) || (cmd == fontstr))
{
- if ((!fmt->font.name) ||
- ((fmt->font.name) && (strcmp(fmt->font.name, tmp_param))))
+ if (!fmt->font.fdesc)
{
- if (fmt->font.name) eina_stringshare_del(fmt->font.name);
- fmt->font.name = eina_stringshare_add(tmp_param);
- new_font = 1;
+ fmt->font.fdesc = evas_font_desc_new();
}
+ else if (!fmt->font.fdesc->new)
+ {
+ Evas_Font_Description *old = fmt->font.fdesc;
+ fmt->font.fdesc = evas_font_desc_dup(fmt->font.fdesc);
+ if (old) evas_font_desc_unref(old);
+ }
+ }
+
+
+ if (cmd == fontstr)
+ {
+ evas_font_name_parse(fmt->font.fdesc, tmp_param);
}
else if (cmd == font_fallbacksstr)
{
*/
if (fmt->font.fallbacks) eina_stringshare_del(fmt->font.fallbacks);
fmt->font.fallbacks = eina_stringshare_add(tmp_param);
- new_font = 1;
}
}
else if (cmd == font_sizestr)
if (v != fmt->font.size)
{
fmt->font.size = v;
- new_font = 1;
}
}
else if (cmd == font_sourcestr)
{
if (fmt->font.source) eina_stringshare_del(fmt->font.source);
fmt->font.source = eina_stringshare_add(tmp_param);
- new_font = 1;
}
}
if (cmd == font_weightstr)
{
- _format_command_parse_font_weight_style(fmt, tmp_param,
- _style_weight_map, _STYLE_WEIGHT_MAP_LEN);
- new_font = 1;
+ fmt->font.fdesc->weight = evas_font_style_find(tmp_param,
+ tmp_param + strlen(tmp_param), EVAS_FONT_STYLE_WEIGHT);
}
if (cmd == font_stylestr)
{
- _format_command_parse_font_weight_style(fmt, tmp_param,
- _style_style_map, _STYLE_STYLE_MAP_LEN);
- new_font = 1;
+ fmt->font.fdesc->slant = evas_font_style_find(tmp_param,
+ tmp_param + strlen(tmp_param), EVAS_FONT_STYLE_SLANT);
}
else if (cmd == colorstr)
_format_color_parse(tmp_param,
else if (!strcmp(tmp_param, "on"))
fmt->password = 1;
}
-
- if (new_font)
- {
- void *of;
- char *buf = NULL;
-
- of = fmt->font.font;
- if ((fmt->font.name) && (fmt->font.fallbacks))
- {
- buf = malloc(strlen(fmt->font.name) + 1 + strlen(fmt->font.fallbacks) + 1);
- strcpy(buf, fmt->font.name);
- strcat(buf, ",");
- strcat(buf, fmt->font.fallbacks);
- }
- else if (fmt->font.name)
- buf = strdup(fmt->font.name);
-
- fmt->font.font = evas_font_load(obj->layer->evas,
- buf, fmt->font.source,
- (int)(((double)fmt->font.size) * obj->cur.scale));
- if (buf) free(buf);
- if (of) evas_font_free(obj->layer->evas, of);
- }
}
/**
fmt2 = calloc(1, sizeof(Evas_Object_Textblock_Format));
memcpy(fmt2, fmt, sizeof(Evas_Object_Textblock_Format));
fmt2->ref = 1;
- if (fmt->font.name) fmt2->font.name = eina_stringshare_add(fmt->font.name);
+ fmt2->font.fdesc = evas_font_desc_ref(fmt->font.fdesc);
+
if (fmt->font.fallbacks) fmt2->font.fallbacks = eina_stringshare_add(fmt->font.fallbacks);
if (fmt->font.source) fmt2->font.source = eina_stringshare_add(fmt->font.source);
- if ((fmt2->font.name) && (fmt2->font.fallbacks))
- {
- buf = malloc(strlen(fmt2->font.name) + 1 + strlen(fmt2->font.fallbacks) + 1);
- strcpy(buf, fmt2->font.name);
- strcat(buf, ",");
- strcat(buf, fmt2->font.fallbacks);
- }
- else if (fmt2->font.name)
- buf = strdup(fmt2->font.name);
- fmt2->font.font = evas_font_load(obj->layer->evas,
- buf, fmt2->font.source,
- (int)(((double)fmt2->font.size) * obj->cur.scale));
+ /* FIXME: just ref the font here... */
+ fmt2->font.font = evas_font_load(obj->layer->evas, fmt2->font.fdesc,
+ fmt2->font.source, (int)(((double) fmt2->font.size) * obj->cur.scale));
if (buf) free(buf);
return fmt2;
}
/**
* @internal
+ * Should be call after we finish filling a format.
+ * FIXME: doc.
+ */
+static void
+_format_finalize(Evas_Object *obj, Evas_Object_Textblock_Format *fmt)
+{
+ void *of;
+
+ of = fmt->font.font;
+
+ fmt->font.font = evas_font_load(obj->layer->evas, fmt->font.fdesc,
+ fmt->font.source, (int)(((double) fmt->font.size) * obj->cur.scale));
+ if (of) evas_font_free(obj->layer->evas, of);
+}
+
+/**
+ * @internal
* Returns true if the item is a tab
* @def _IS_TAB(item)
*/
}
}
}
+ _format_finalize(c->obj, fmt);
}
{
{
c->fmt = _layout_format_push(c, NULL, NULL);
_format_fill(c->obj, c->fmt, c->o->style->default_tag);
+ _format_finalize(c->obj, c->fmt);
}
if (!c->fmt)
{
typedef struct _Evas_Font_Dir Evas_Font_Dir;
typedef struct _Evas_Font Evas_Font;
typedef struct _Evas_Font_Alias Evas_Font_Alias;
+typedef struct _Evas_Font_Description Evas_Font_Description;
typedef struct _Evas_Data_Node Evas_Data_Node;
typedef struct _Evas_Func_Node Evas_Func_Node;
typedef RGBA_Image_Loadopts Evas_Image_Load_Opts;
typedef struct _Evas_Smart_Cb_Description_Array Evas_Smart_Cb_Description_Array;
typedef struct _Evas_Post_Callback Evas_Post_Callback;
+typedef enum _Evas_Font_Style Evas_Font_Style;
+typedef enum _Evas_Font_Slant Evas_Font_Slant;
+typedef enum _Evas_Font_Weight Evas_Font_Weight;
+typedef enum _Evas_Font_Width Evas_Font_Width;
+
/* General types - used for script type chceking */
#define OPAQUE_TYPE(type) struct __##type { int a; }; \
typedef struct __##type type
Evas_Font *fn;
};
+enum _Evas_Font_Style
+{
+ EVAS_FONT_STYLE_SLANT,
+ EVAS_FONT_STYLE_WEIGHT,
+ EVAS_FONT_STYLE_WIDTH
+};
+
+enum _Evas_Font_Slant
+{
+ EVAS_FONT_SLANT_NORMAL,
+ EVAS_FONT_SLANT_OBLIQUE,
+ EVAS_FONT_SLANT_ITALIC
+};
+
+enum _Evas_Font_Weight
+{
+ EVAS_FONT_WEIGHT_NORMAL,
+ EVAS_FONT_WEIGHT_THIN,
+ EVAS_FONT_WEIGHT_ULTRALIGHT,
+ EVAS_FONT_WEIGHT_LIGHT,
+ EVAS_FONT_WEIGHT_BOOK,
+ EVAS_FONT_WEIGHT_MEDIUM,
+ EVAS_FONT_WEIGHT_SEMIBOLD,
+ EVAS_FONT_WEIGHT_BOLD,
+ EVAS_FONT_WEIGHT_ULTRABOLD,
+ EVAS_FONT_WEIGHT_BLACK,
+ EVAS_FONT_WEIGHT_EXTRABLACK
+};
+
+enum _Evas_Font_Width
+{
+ EVAS_FONT_WIDTH_NORMAL,
+ EVAS_FONT_WIDTH_ULTRACONDENSED,
+ EVAS_FONT_WIDTH_EXTRACONDENSED,
+ EVAS_FONT_WIDTH_CONDENSED,
+ EVAS_FONT_WIDTH_SEMICONDENSED,
+ EVAS_FONT_WIDTH_SEMIEXPANDED,
+ EVAS_FONT_WIDTH_EXPANDED,
+ EVAS_FONT_WIDTH_EXTRAEXPANDED,
+ EVAS_FONT_WIDTH_ULTRAEXPANDED
+};
+
+struct _Evas_Font_Description
+{
+ int ref;
+ /* We assume everywhere this is stringshared */
+ const char *name;
+
+ Evas_Font_Slant slant;
+ Evas_Font_Weight weight;
+ Evas_Font_Width width;
+
+ Eina_Bool new : 1;
+};
+
struct _Evas_Object_Func
{
void (*free) (Evas_Object *obj);
void evas_font_free(Evas *evas, void *font);
void evas_fonts_zero_free(Evas *evas);
void evas_fonts_zero_presure(Evas *evas);
-void *evas_font_load(Evas *evas, const char *name, const char *source, int size);
+void evas_font_name_parse(Evas_Font_Description *fdesc, const char *name);
+int evas_font_style_find(const char *start, const char *end, Evas_Font_Style style);
+Evas_Font_Description *evas_font_desc_new(void);
+Evas_Font_Description *evas_font_desc_dup(const Evas_Font_Description *fdesc);
+void evas_font_desc_unref(Evas_Font_Description *fdesc);
+int evas_font_desc_cmp(const Evas_Font_Description *a, const Evas_Font_Description *b);
+Evas_Font_Description *evas_font_desc_ref(Evas_Font_Description *fdesc);
+void * evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Evas_Font_Size size);
void evas_font_load_hinting_set(Evas *evas, void *font, int hinting);
void evas_object_smart_member_cache_invalidate(Evas_Object *obj);
void evas_text_style_pad_get(Evas_Text_Style_Type style, int *l, int *r, int *t, int *b);