[teklib-general] changeset in /hg/teklib/current: added documentation and parsing...

Franciska Schulze fschulze at neoscientists.org
Mon Nov 26 16:22:52 CET 2007


changeset 14134e30e27d in /hg/teklib/current
details: http://teklib.org:8001/hg/teklib/current?cmd=changeset;node=14134e30e27d
description:
	added documentation and parsing of fontnames

diffs (truncated from 1008 to 300 lines):

diff -r 11c0320856f0 -r 14134e30e27d src/visual/posix/visual_font.c
--- a/src/visual/posix/visual_font.c	Tue Sep 11 19:09:44 2007 +0200
+++ b/src/visual/posix/visual_font.c	Thu Sep 13 19:16:42 2007 +0200
@@ -15,6 +15,368 @@
 #include "visual_font.h"
 
 /*****************************************************************************/
+/* extract a substring from an x11 font
+** m should refer to the position of a '-' and fstring should be
+** something like "-*-fname-medium-r-*-*-xxx-*-*-*-*-*-iso8859-1"
+*/
+LOCAL TSTRPTR
+fnt_getsubstring(TMOD_VIS *mod, TSTRPTR fstring, TINT m)
+{
+	TINT i, p = 0;
+	TINT mcount = 0;
+	TSTRPTR substr = TNULL;
+	TAPTR exec = TGetExecBase(mod);
+
+	/* match '-' at pos m and m+1 */
+	for (i = 0; i < strlen(fstring); i++)
+	{
+		if (fstring[i] == '-')
+		{
+			mcount++;
+			if (mcount == m)
+				p = i;
+			if (mcount == m+1)
+				break;
+		}
+	}
+
+	/* extract substring */
+	substr = TExecAlloc0(exec, mod->vis_MMU, i-p);
+	if (substr)
+	{
+		TExecCopyMem(exec, fstring+p+1, substr, i-p-1);
+		TDBPRINTF(2, ("extracted = '%s'\n", substr));
+	}
+	else
+		TDBPRINTF(20, ("out of memory :(\n"));
+
+	return substr;
+}
+
+/*****************************************************************************/
+/* extract properties from an x11 font string and convert
+** them to our own taglist based properties system
+*/
+LOCAL TVOID
+fnt_getattr(TMOD_VIS *mod, TTAGITEM *tag, TSTRPTR fstring)
+{
+	TAPTR exec = TGetExecBase(mod);
+
+	/* "-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s" */
+	switch (tag->tti_Tag)
+	{
+		case TVisual_FontName:
+		{
+			/* extract name -> 2th and 3th '-' */
+			tag->tti_Value = (TTAG)fnt_getsubstring(mod, fstring, 2);
+			break;
+		}
+		case TVisual_FontPxSize:
+		{
+			/* extract pixel size -> 7th and 8th '-' */
+			TSTRPTR pxsize = fnt_getsubstring(mod, fstring, 7);
+			if (pxsize)
+			{
+				tag->tti_Value = (TTAG)atoi(pxsize);
+				TExecFree(exec, pxsize);
+			}
+			break;
+		}
+		case TVisual_FontItalic:
+		{
+			/* extract slant -> 4th and 5th '-' */
+			TSTRPTR slant = fnt_getsubstring(mod, fstring, 4);
+			if (slant)
+			{
+				/* italic attribute set? */
+				if (strncmp(FNT_SLANT_I, slant, strlen(FNT_SLANT_I)) == 0)
+					tag->tti_Value = (TTAG)TTRUE;
+				TExecFree(exec, slant);
+			}
+			break;
+		}
+		case TVisual_FontBold:
+		{
+			/* extract weight -> 3th and 4th '-' */
+			TSTRPTR weight = fnt_getsubstring(mod, fstring, 3);
+			if (weight)
+			{
+				/* bold attribute set? */
+				if (strncmp(FNT_WGHT_BOLD, weight, strlen(FNT_WGHT_BOLD)) == 0)
+					tag->tti_Value = (TTAG)TTRUE;
+				TExecFree(exec, weight);
+			}
+			break;
+		}
+		default:
+			break;
+	}
+}
+
+/*****************************************************************************/
+/* FontQueryHandle destructor
+** free all memory associated with a fontqueryhandle including
+** all fontquerynodes, a fontqueryhandle is obtained by calling
+** vis_hostqueryfonts()
+*/
+THOOKENTRY TTAG
+fqhdestroy(struct THook *hook, TAPTR obj, TTAG msg)
+{
+	if (msg == TMSG_DESTROY)
+	{
+		struct FontQueryHandle *fqh = obj;
+		TMOD_VIS *mod = fqh->handle.thn_Owner;
+		TAPTR exec = TGetExecBase(mod);
+		struct TNode *node, *next;
+
+		node = fqh->reslist.tlh_Head;
+		for (; (next = node->tln_Succ); node = next)
+		{
+			struct FontQueryNode *fqn = (struct FontQueryNode *)node;
+
+			/* remove from resultlist */
+			TRemove(&fqn->node);
+
+			/* destroy fontname */
+			if (fqn->tags[0].tti_Value)
+				TExecFree(exec, (TAPTR)fqn->tags[0].tti_Value);
+
+			/* destroy node */
+			TExecFree(exec, fqn);
+		}
+
+		/* destroy queryhandle */
+		TExecFree(exec, fqh);
+	}
+
+	return 0;
+}
+
+/*****************************************************************************/
+LOCAL struct FontQueryNode *
+fnt_getfqnode(TMOD_VIS *mod, TSTRPTR fontname)
+{
+	TAPTR exec = TGetExecBase(mod);
+	struct FontQueryNode *fqnode = TNULL;
+
+	/* allocate fquery node */
+	fqnode = TExecAlloc0(exec, mod->vis_MMU, sizeof(struct FontQueryNode));
+	if (fqnode)
+	{
+		/* fquerynode ready - fill in attributes */
+		fqnode->tags[0].tti_Tag = TVisual_FontName;
+		fnt_getattr(mod, &fqnode->tags[0], fontname);
+
+		if (fqnode->tags[0].tti_Value)
+		{
+			fqnode->tags[1].tti_Tag = TVisual_FontPxSize;
+			fnt_getattr(mod, &fqnode->tags[1], fontname);
+
+			fqnode->tags[2].tti_Tag = TVisual_FontItalic;
+			fnt_getattr(mod, &fqnode->tags[2], fontname);
+
+			fqnode->tags[3].tti_Tag = TVisual_FontBold;
+			fnt_getattr(mod, &fqnode->tags[3], fontname);
+
+			/* TODO: not yet implemented */
+			fqnode->tags[4].tti_Tag = TVisual_FontScaleable;
+			fqnode->tags[4].tti_Value = (TTAG) TFALSE;
+
+			fqnode->tags[5].tti_Tag = TTAG_DONE;
+		}
+		else
+		{
+			TExecFree(exec, fqnode);
+			fqnode = TNULL;
+		}
+	}
+	else
+		TDBPRINTF(20, ("out of memory :(\n"));
+
+	return fqnode;
+}
+
+/*****************************************************************************/
+/* check if a font with similar properties is already contained
+** in our resultlist, also fonts with pxsize = 0 are filtered
+*/
+LOCAL TBOOL
+fnt_checkfqnode(struct TList *rlist, struct FontQueryNode *fqnode)
+{
+	TUINT8 flags;
+	TBOOL match = TFALSE;
+	struct TNode *node, *next;
+
+	TSTRPTR newfname = (TSTRPTR)fqnode->tags[0].tti_Value;
+	TINT newpxsize = (TINT)fqnode->tags[1].tti_Value;
+	TBOOL newslant = (TBOOL)fqnode->tags[2].tti_Value;
+	TBOOL newweight = (TBOOL)fqnode->tags[3].tti_Value;
+	TINT flen = strlen(newfname);
+
+	/* filter out fonts with pxsize = 0 to keep our api consistent */
+	if (newpxsize == 0)
+		return TTRUE;
+
+	node = rlist->tlh_Head;
+	for (; (next = node->tln_Succ); node = next)
+	{
+		struct FontQueryNode *fqn = (struct FontQueryNode *)node;
+		flags = 0;
+
+		if (strlen((TSTRPTR)fqn->tags[0].tti_Value) == flen)
+		{
+			if (strncmp((TSTRPTR)fqn->tags[0].tti_Value, newfname, flen) == 0)
+				flags = FNT_MATCH_NAME;
+		}
+
+		if ((TINT)fqn->tags[1].tti_Value == newpxsize)
+			flags |= FNT_MATCH_SIZE;
+
+		if ((TBOOL)fqn->tags[2].tti_Value == newslant)
+			flags |= FNT_MATCH_SLANT;
+
+		if ((TBOOL)fqn->tags[3].tti_Value == newweight)
+			flags |= FNT_MATCH_WEIGHT;
+
+		if (flags == FNT_MATCH_ALL)
+		{
+			/* fqnode is not unique */
+			match = TTRUE;
+			break;
+		}
+	}
+
+	return match;
+}
+
+/*****************************************************************************/
+/* dump properties of a fontquerynode
+*/
+LOCAL TVOID
+fnt_dumpnode(struct FontQueryNode *fqn)
+{
+	TDBPRINTF(10, ("-----------------------------------------------\n"));
+	TDBPRINTF(10, ("dumping fontquerynode @ %p\n", fqn));
+	TDBPRINTF(10, (" * FontName: %s\n", (TSTRPTR)fqn->tags[0].tti_Value));
+	TDBPRINTF(10, (" * PxSize:   %d\n", (TINT)fqn->tags[1].tti_Value));
+	TDBPRINTF(10, (" * Italic:   %s\n", (TBOOL)fqn->tags[2].tti_Value ? "on" : "off"));
+	TDBPRINTF(10, (" * Bold:     %s\n", (TBOOL)fqn->tags[3].tti_Value ? "on" : "off"));
+	TDBPRINTF(10, ("-----------------------------------------------\n"));
+}
+
+/*****************************************************************************/
+/* dump all fontquerynodes of a (result-)list
+*/
+LOCAL TVOID
+fnt_dumplist(struct TList *rlist)
+{
+	struct TNode *node, *next;
+	node = rlist->tlh_Head;
+	for (; (next = node->tln_Succ); node = next)
+	{
+		struct FontQueryNode *fqn = (struct FontQueryNode *)node;
+		fnt_dumpnode(fqn);
+	}
+}
+
+/*****************************************************************************/
+/* parses a single fontname or a comma seperated list of fontnames
+** and returns a list of fontnames, spaces are NOT filtered, so
+** "helvetica, fixed" will result in "helvetica" and " fixed"
+*/
+LOCAL TVOID
+fnt_getfnnodes(TMOD_VIS *mod, struct TList *fnlist, TSTRPTR fname)
+{
+	TINT i, p = 0;
+	TBOOL lastrun = TFALSE;
+	TINT fnlen = strlen(fname);
+	TAPTR exec = TGetExecBase(mod);
+
+	for (i = 0; i < fnlen; i++)
+	{
+		if (i == fnlen-1) lastrun = TTRUE;
+
+		if (fname[i] == ',' || lastrun)
+		{
+			TSTRPTR ts;
+			TINT len = (i > p) ? (lastrun ? (i-p+1) : (i-p)) : fnlen+1;
+
+			TDBPRINTF(10, ("i = %d, p = %d, size = %d\n", i, p, len));
+			ts = TExecAlloc0(exec, mod->vis_MMU, len+1);
+			if (ts)
+			{
+				struct FnNode *fnn;
+
+				TExecCopyMem(exec, fname+p, ts, len);


More information about the teklib-general mailing list