#include #include #include #include #include "xwchar.h" #include "fonts.h" /* フォント一覧表の取得 */ static char ** GetFontList(Display *dpy, char *name, int *num) { char **fonts; int nnames, available; for (nnames=1000,available=nnames+1;;) { fonts = XListFonts(dpy, name, nnames, &available); if (fonts == NULL || available < nnames) break; XFreeFontNames(fonts); nnames = available * 2; } if (fonts == NULL) return NULL; *num = available; return fonts; } static FontFace * fontface_new(void) { FontFace *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("fontface_new"); exit(1); } p->points = NULL; p->scale_ok = 0; p->scalable = 0; p->next = NULL; return p; } static FontInfo * fontinfo_new(int point) { FontInfo *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("fontinfo_new"); exit(1); } p->point = point; p->count = 0; p->fs = NULL; return p; } static FontInfo * fontface_addpoint(FontFace *face, int point) { FontInfo *f = face->points; while (f != NULL) { if (f->point == point) break; f = f->next; } if (f == NULL) { f = fontinfo_new(point); f->parent = face; f->next = face->points; face->points = f; } return f; } void fontface_show(FontFace *p) { char buf[1024]; sprintf(buf, "-%s-%s-%s-%s---*-*-*-*-%s-*-%s", XrmQuarkToString(p->foundry), XrmQuarkToString(p->name), XrmQuarkToString(p->weight), XrmQuarkToString(p->slant), XrmQuarkToString(p->spacing), XrmQuarkToString(p->encoding)); fprintf(stderr,"%s\n", buf); { FontInfo *f = p->points; while (f != NULL) { fprintf(stderr,"%d ",f->point); f = f->next; } } fprintf(stderr,": scaleok[%d] scalable[%d]\n", p->scale_ok, p->scalable); } typedef struct FontList { char *name; } FontList; static int compare_font(const void *a, const void *b) { char *p1 = ((FontList*)a)->name, *p2 = ((FontList*)b)->name; while (*p1 && *p2 && *p1 == *p2) p1++, p2++; return(*p1 - *p2); } /* 特定のエンコーディングの全フォントの情報を得る */ FontFaceList GetFontFaces(Display *dpy, char *encoding) { char buf[1024]; char **fonts; int fnum; int i; XrmQuark qencoding = XrmStringToQuark(encoding); FontFace *facelist = NULL; FontFace *face; FontList *fl; /* get font list and sort */ sprintf(buf,"-*-*-*-*-*--*-*-*-*-*-*-%s", encoding); if ((fonts = GetFontList(dpy, buf, &fnum)) == NULL) goto end; if ((fl = malloc(sizeof(*fl) * fnum)) == NULL) goto end; for (i=0;ifoundry != qfoundry || face->name != qname || face->weight != qweight || face->slant != qslant || face->spacing != qspacing) { FontFace *new = fontface_new(); new->dpy = dpy; new->foundry = qfoundry; new->name = qname; new->weight = qweight; new->slant = qslant; new->spacing = qspacing; new->encoding = qencoding; new->next = face->next; face->next = new; face = new; } if (size == 0) { if (pt == 0 && resx == 0 && resy == 0) face->scalable = 1; /* true scalable font */ else face->scale_ok = 1; /* scaling ok */ } else fontface_addpoint(face, pt); } #if 1 face = face->next; while (face != NULL) { fontface_show(face); face = face->next; } #endif free(fl); end: XFreeFontNames(fonts); return facelist; } static FontFaceTable * fontfacetable_new(void) { FontFaceTable *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("fontfacetable_new"); exit(1); } p->head = 0; p->next = NULL; return p; } /* 各エンコーディングの全フォントの情報を得る */ FontFaceTableList MakeFontFaceTable(Display *dpy, FontEncodeTable *f) { FontFaceTableList ftl; FontFaceTable *p, *new; ftl = p = fontfacetable_new(); while (f->head != 0) { FontFaceList faces; if ((faces = GetFontFaces(dpy, f->encoding)) != NULL) { new = fontfacetable_new(); new->head = f->head; new->faces = faces; new->next = p->next; p->next = new; p = new; } f++; } #if 0 p = ftl->next; while (p != NULL) { fprintf(stderr,"[%08x]:[%p]\n",p->head,p->faces); p = p->next; } #endif return ftl; } /* フォントの比較 */ static int fontface_compare(FontFace *p, XrmQuark foundry, XrmQuark name, XrmQuark weight, XrmQuark slant, XrmQuark spacing, int scok) { if (!scok && p->points == NULL) return -1; if (foundry != None && p->foundry != foundry) return -1; if (name != None && p->name != name) return -1; if (weight != None && p->weight != weight) return -1; if (slant != None && p->slant != slant) return -1; if (spacing != None && p->spacing != spacing) return -1; return 0; } static FontFace* fontface_compare2(FontFaceList l, XrmQuark foundry, XrmQuark name, XrmQuark weight, XrmQuark slant, XrmQuark spacing, int scok) { FontFace *p = l->next; while (p != NULL) { if (!fontface_compare(p,foundry,name,weight,slant,spacing,scok)) return p; p = p->next; } return NULL; } /* 目的のスタイルのフォントを探す */ FontFace * FindFontFace(FontFaceList faces, XrmQuark foundry, XrmQuark name, XrmQuark weight, XrmQuark slant, XrmQuark spacing, int scok) { FontFace *p; /* どんどん条件をゆるめていく... */ if ((p = fontface_compare2(faces,foundry,name,weight,slant,spacing,scok))) return p; if ((p = fontface_compare2(faces,foundry,name,weight,None,spacing,scok))) return p; if ((p = fontface_compare2(faces,foundry,name,None,None,spacing,scok))) return p; if ((p = fontface_compare2(faces,foundry,name,None,None,None,scok))) return p; if ((p = fontface_compare2(faces,None,name,None,None,None,scok))) return p; if ((p = fontface_compare2(faces,None,None,None,None,None,scok))) return p; return NULL; /* ありえないはずっす */ } /* 指定サイズのフォントの取得 */ FontInfo * FindFontInfo(FontFace *face, int point, int scale_ok) { FontInfo *f = face->points; FontInfo *r = NULL; int a, min = 99999; /* scalable */ if ((scale_ok && face->scale_ok) || face->scalable) r = fontface_addpoint(face, point); else { /* 一番近いサイズのものを探す */ while (f != NULL) { if ((a = abs(f->point - point)) == 0) { r = f; break; } else if (a < min) { min = a; r = f; } f = f->next; } } if (r) r->count++; return r; }