Commits

Akira TAGOH committed 2ebfbcd

Store the font properties configuration

Comments (0)

Files changed (3)

libeasyfc/ezfc-config.c

 	gpointer            data;
 	ezfc_destroy_func_t data_finalizer;
 } ezfc_container_t;
-
+typedef struct _ezfc_xml_const_t {
+	gchar *name;
+	gint   val;
+} ezfc_xml_const_t;
 typedef enum {
 	EZFC_NODE_TYPE_PREFER = 0,
 	EZFC_NODE_TYPE_ACCEPT,
 			"hintfull",
 			NULL
 		};
+		static const gchar *rgba[] = {
+			"unknown",
+			"rgb",
+			"bgr",
+			"vrgb",
+			"vbgr",
+			"none",
+			NULL
+		};
 
 		if (i == 0 || i >= EZFC_FONT_MASK_END)
 			goto bail;
 				       (const xmlChar *)"embeddedbitmap");
 			    f = ezfc_font_get_embedded_bitmap(font);
 			    break;
+		    case EZFC_FONT_MASK_RGBA:
+			    xmlNewProp(edit,
+				       (const xmlChar *)"name",
+				       (const xmlChar *)"rgba");
+			    xmlNewProp(edit,
+				       (const xmlChar *)"mode",
+				       (const xmlChar *)"assign");
+			    xmlNewChild(edit, NULL,
+					(const xmlChar *)"const",
+					(const xmlChar *)rgba[ezfc_font_get_rgba(font)]);
+			    goto bail;
 		    case EZFC_FONT_MASK_HINTSTYLE:
 			    xmlNewProp(edit,
 				       (const xmlChar *)"name",
 }
 
 static gboolean
+_ezfc_config_parse_bool_node(xmlNodePtr node)
+{
+	gboolean retval = FALSE;
+	xmlChar *s;
+	gchar *ss;
+
+	while (node != NULL) {
+		if (node->type == XML_COMMENT_NODE || node->type == XML_TEXT_NODE)
+			node = node->next;
+		if (node->type == XML_ELEMENT_NODE &&
+		    xmlStrcmp(node->name, (const xmlChar *)"bool") == 0) {
+			s = xmlNodeGetContent(node);
+			ss = g_ascii_strdown((const gchar *)s, -1);
+			xmlFree(s);
+			if (ss[0] == 't' || ss[0] == 'y' || ss[0] == '1')
+				retval = TRUE;
+			break;
+		} else {
+			g_warning("Unexpected node: type = %d, name = %s",
+				  node->type, node->name);
+			break;
+		}
+	}
+
+	return retval;
+}
+
+static gboolean
+_ezfc_config_parse_const_node(xmlNodePtr        node,
+			      ezfc_xml_const_t *list,
+			      gint             *ret)
+{
+	gboolean retval = FALSE;
+	xmlChar *s;
+	ezfc_xml_const_t *c;
+
+	while (node != NULL) {
+		if (node->type == XML_COMMENT_NODE || node->type == XML_TEXT_NODE)
+			node = node->next;
+		if (node->type == XML_ELEMENT_NODE &&
+		    xmlStrcmp(node->name, (const xmlChar *)"const") == 0) {
+			s = xmlNodeGetContent(node);
+			for (c = list; c != NULL; c++) {
+				if (g_ascii_strcasecmp(c->name, (const gchar *)s) == 0) {
+					*ret = c->val;
+					retval = TRUE;
+					break;
+				}
+			}
+			xmlFree(s);
+			break;
+		} else {
+			g_warning("Unexpected node: type = %d, name = %s",
+				  node->type, node->name);
+			break;
+		}
+	}
+
+	return retval;
+}
+
+static gboolean
 _ezfc_config_from_xml(ezfc_config_t  *config,
 		      const gchar    *conffile,
 		      GError        **error)
 			break;
 	}
 
+	xobj = xmlXPathEvalExpression((const xmlChar *)"/fontconfig/match[@target = \"font\" and (test[@name = \"family\"] and test/string/text())]", xctxt);
+	if (!xobj) {
+		g_set_error(&err, EZFC_ERROR, EZFC_ERR_FAIL_ON_XML,
+			    "No valid elements for targeting fonts can be proceeded in this library.");
+		retval = FALSE;
+		goto bail;
+	}
+
+	n = xmlXPathNodeSetGetLength(xobj->nodesetval);
+
+	for (i = 0; i < n; i++) {
+		xmlNodePtr match = xmlXPathNodeSetItem(xobj->nodesetval, i);
+		xmlNodePtr node;
+		xmlChar *attr, *s;
+		ezfc_font_t *f = NULL;
+
+		node = match->children;
+		while (node != NULL) {
+			if (node->type == XML_TEXT_NODE) {
+				/* ignore the text node here */
+				goto bail3;
+			}
+			if (xmlStrcmp(node->name, (const xmlChar *)"test") == 0) {
+				attr = xmlGetProp(node, (const xmlChar *)"name");
+				if (xmlStrcmp(attr, (const xmlChar *)"family") == 0) {
+					f = ezfc_font_new();
+					s = _ezfc_config_parse_string_node(node->children);
+					ezfc_font_set_family(f, (const gchar *)s, &err);
+				}
+				xmlFree(attr);
+			} else if (xmlStrcmp(node->name, (const xmlChar *)"edit") == 0) {
+				attr = xmlGetProp(node, (const xmlChar *)"mode");
+				if (xmlStrcmp(attr, (const xmlChar *)"assign") != 0) {
+					g_warning("Unexpected mode for <match target=\"font\"><edit>: %s",
+						  attr);
+					xmlFree(attr);
+					ezfc_font_unref(f);
+					goto bail4;
+				} else {
+					xmlFree(attr);
+					attr = xmlGetProp(node, (const xmlChar *)"name");
+					if (xmlStrcmp(attr, (const xmlChar *)"antialias") == 0) {
+						ezfc_font_set_antialiasing(f, _ezfc_config_parse_bool_node(node->children));
+					} else if (xmlStrcmp(attr, (const xmlChar *)"autohint") == 0) {
+						ezfc_font_set_autohinting(f, _ezfc_config_parse_bool_node(node->children));
+					} else if (xmlStrcmp(attr, (const xmlChar *)"hinting") == 0) {
+						ezfc_font_set_hinting(f, _ezfc_config_parse_bool_node(node->children));
+					} else if (xmlStrcmp(attr, (const xmlChar *)"hintstyle") == 0) {
+						ezfc_xml_const_t hintstyle[] = {
+							{"hintnone", EZFC_FONT_HINTSTYLE_NONE},
+							{"hintslight", EZFC_FONT_HINTSTYLE_SLIGHT},
+							{"hintmedium", EZFC_FONT_HINTSTYLE_MEDIUM},
+							{"hintfull", EZFC_FONT_HINTSTYLE_FULL},
+							{NULL, 0}
+						};
+						gint ret;
+
+						if (!_ezfc_config_parse_const_node(node->children, hintstyle, &ret)) {
+							ret = EZFC_FONT_HINTSTYLE_UNKNOWN;
+						}
+						ezfc_font_set_hintstyle(f, ret);
+					} else if (xmlStrcmp(attr, (const xmlChar *)"rgba") == 0) {
+						ezfc_xml_const_t rgba[] = {
+							{"unknown", FC_RGBA_UNKNOWN},
+							{"rgb", FC_RGBA_RGB},
+							{"bgr", FC_RGBA_BGR},
+							{"vrgb", FC_RGBA_VRGB},
+							{"vbgr", FC_RGBA_VBGR},
+							{"none", FC_RGBA_NONE},
+							{NULL, 0}
+						};
+						gint ret;
+
+						if (!_ezfc_config_parse_const_node(node->children, rgba, &ret)) {
+							ret = FC_RGBA_UNKNOWN;
+						}
+						ezfc_font_set_rgba(f, ret);
+					} else {
+						g_warning("Unexpected value in the name attribute: %s",
+							  attr);
+					}
+					xmlFree(attr);
+				}
+			} else {
+				g_warning("Unexpected element in <match target=\"font\">: %s\n", node->name);
+			}
+		  bail3:
+			node = node->next;
+		}
+		if (f)
+			ezfc_config_add_font(config, f);
+		ezfc_font_unref(f);
+	  bail4:
+		if (err)
+			break;
+	}
   bail:
 	if (err) {
 		if (error)

libeasyfc/ezfc-font-private.h

 	EZFC_FONT_MASK_AUTOHINT        = 1 << 1,
 	EZFC_FONT_MASK_ANTIALIAS       = 1 << 2,
 	EZFC_FONT_MASK_EMBEDDED_BITMAP = 1 << 3,
-	EZFC_FONT_MASK_HINTSTYLE       = 1 << 4,
+	EZFC_FONT_MASK_RGBA            = 1 << 4,
+	EZFC_FONT_MASK_HINTSTYLE       = 1 << 5,
 	EZFC_FONT_MASK_END
 } ezfc_font_mask_t;
 

libeasyfc/ezfc-font.c

 
 	g_return_if_fail (font != NULL);
 
+	priv->masks |= EZFC_FONT_MASK_RGBA;
 	priv->rgba = val;
 }