[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