diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 2002-03-06 18:11:01 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 2002-03-06 18:11:01 +0000 |
| commit | e52b682a995fe2d7662b3f10730420996ccbb146 (patch) | |
| tree | d7bbbd4de9e9728191bb2407e763437366806b00 /src/fl_set_fonts.cxx | |
| parent | 394286265a96aa27fbedc0cd58c5bb33366123b3 (diff) | |
Add Xft support to 1.1.x.
TODO: Fl::set_fonts() should add all of the fonts returned by Xft;
right now it is a no-op.
BUG: Getting X messages like "XRequest.155: 202 0x260002b" for some
reason on my system.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@1987 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/fl_set_fonts.cxx')
| -rw-r--r-- | src/fl_set_fonts.cxx | 321 |
1 files changed, 13 insertions, 308 deletions
diff --git a/src/fl_set_fonts.cxx b/src/fl_set_fonts.cxx index d9c9ccae1..e84465fc3 100644 --- a/src/fl_set_fonts.cxx +++ b/src/fl_set_fonts.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_set_fonts.cxx,v 1.6.2.5.2.3 2002/01/01 15:11:32 easysw Exp $" +// "$Id: fl_set_fonts.cxx,v 1.6.2.5.2.4 2002/03/06 18:11:01 easysw Exp $" // // More font utilities for the Fast Light Tool Kit (FLTK). // @@ -23,319 +23,24 @@ // Please report all bugs and problems to "fltk-bugs@fltk.org". // -// This function fills in the fltk font table with all the fonts that -// are found on the X server. It tries to place the fonts into families -// and to sort them so the first 4 in a family are normal, bold, italic, -// and bold italic. +#include <config.h> +#include <FL/Fl.H> +#include <FL/x.H> +#include "Fl_Font.H" +#include <ctype.h> +#include <string.h> +#include <stdlib.h> #ifdef WIN32 # include "fl_set_fonts_win32.cxx" #elif defined(__APPLE__) # include "fl_set_fonts_mac.cxx" +#elif USE_XFT +# include "fl_set_fonts_xft.cxx" #else - -// Standard X fonts are matched by a pattern that is always of -// this form, and this pattern is put in the table: -// "-*-family-weight-slant-width1-style-*-registry-encoding" - -// Non-standard font names (those not starting with '-') are matched -// by a pattern of the form "prefix*suffix", where the '*' is where -// fltk thinks the point size is, or by the actual font name if no -// point size is found. - -// Fltk knows how to pull an "attribute" out of a font name, such as -// bold or italic, by matching known x font field values. All words -// that don't match a known attribute are combined into the "name" -// of the font. Names are compared before attributes for sorting, this -// makes the bold and plain version of a font come out next to each -// other despite the poor X font naming scheme. - -// By default fl_set_fonts() only does iso8859-1 encoded fonts. You can -// do all normal X fonts by passing "-*" or every possible font with "*". - -// Fl::set_font will take strings other than the ones this stores -// and can identify any font on X that way. You may want to write your -// own system of font management and not use this code. - -# include <FL/Fl.H> -# include <FL/x.H> -# include "Fl_Font.H" -# include <ctype.h> -# include <string.h> -# include <stdlib.h> - -// turn word N of a X font name into either some attribute bits -// (right now 0, FL_BOLD, or FL_ITALIC), or into -1 indicating that -// the word should be put into the name: - -static int attribute(int n, const char *p) { - // don't put blank things into name: - if (!*p || *p=='-' || *p=='*') return 0; - if (n == 3) { // weight - if (!strncmp(p,"normal",6) || - !strncmp(p,"light",5) || - !strncmp(p,"medium",6) || - !strncmp(p,"book",4)) return 0; - if (!strncmp(p,"bold",4) || !strncmp(p,"demi",4)) return FL_BOLD; - } else if (n == 4) { // slant - if (*p == 'r') return 0; - if (*p == 'i' || *p == 'o') return FL_ITALIC; - } else if (n == 5) { // sWidth - if (!strncmp(p,"normal",6)) return 0; - } - return -1; -} - -// return non-zero if the registry-encoding should be used: -extern const char* fl_encoding; -static int use_registry(const char *p) { - return *p && *p!='*' && strcmp(p,fl_encoding); -} - -// turn a stored (with *'s) X font name into a pretty name: -const char* Fl::get_font_name(Fl_Font fnum, int* ap) { - const char* p = fl_fonts[fnum].name; - if (!p) { - if (ap) *ap = 0; - return ""; - } - static char *buffer; if (!buffer) buffer = new char[128]; - char *o = buffer; - - if (*p != '-') { // non-standard font, just replace * with spaces: - if (ap) { - int type = 0; - if (strstr(p,"bold")) type = FL_BOLD; - if (strstr(p,"ital")) type |= FL_ITALIC; - *ap = type; - } - for (;*p; p++) { - if (*p == '*' || *p == ' ' || *p == '-') { - do p++; while (*p == '*' || *p == ' ' || *p == '-'); - if (!*p) break; - *o++ = ' '; - } - *o++ = *p; - } - *o = 0; - return buffer; - } - - // get the family: - const char *x = fl_font_word(p,2); if (*x) x++; if (*x=='*') x++; - if (!*x) { - if (ap) *ap = 0; - return p; - } - const char *e = fl_font_word(x,1); - strncpy(o,x,e-x); o += e-x; - - // collect all the attribute words: - int type = 0; - for (int n = 3; n <= 6; n++) { - // get the next word: - if (*e) e++; x = e; e = fl_font_word(x,1); - int t = attribute(n,x); - if (t < 0) {*o++ = ' '; strncpy(o,x,e-x); o += e-x;} - else type |= t; - } - - // skip over the '*' for the size and get the registry-encoding: - x = fl_font_word(e,2); - if (*x) {x++; *o++ = '('; while (*x) *o++ = *x++; *o++ = ')';} - - *o = 0; - if (type & FL_BOLD) {strcpy(o, " bold"); o += 5;} - if (type & FL_ITALIC) {strcpy(o, " italic"); o += 7;} - - if (ap) *ap = type; - - return buffer; -} - -extern "C" { -// sort raw (non-'*') X font names into perfect order: - -static int ultrasort(const void *aa, const void *bb) { - const char *a = *(char **)aa; - const char *b = *(char **)bb; - - // sort all non x-fonts at the end: - if (*a != '-') { - if (*b == '-') return 1; - // 2 non-x fonts are matched by "numeric sort" - int ret = 0; - for (;;) { - if (isdigit(*a) && isdigit(*b)) { - int na = strtol(a, (char **)&a, 10); - int nb = strtol(b, (char **)&b, 10); - if (!ret) ret = na-nb; - } else if (*a != *b) { - return (*a-*b); - } else if (!*a) { - return ret; - } else { - a++; b++; - } - } - } else { - if (*b != '-') return -1; - } - - // skip the foundry (assumme equal): - for (a++; *a && *a++!='-';); - for (b++; *b && *b++!='-';); - - // compare the family and all the attribute words: - int atype = 0; - int btype = 0; - for (int n = 2; n <= 6; n++) { - int at = attribute(n,a); - int bt = attribute(n,b); - if (at < 0) { - if (bt >= 0) return 1; - for (;;) {if (*a!=*b) return *a-*b; b++; if (!*a || *a++=='-') break;} - } else { - if (bt < 0) return -1; - a = fl_font_word(a,1); if (*a) a++; - b = fl_font_word(b,1); if (*b) b++; - atype |= at; btype |= bt; - } - } - - // remember the pixel size: - int asize = atoi(a); - int bsize = atoi(b); - - // compare the registry/encoding: - a = fl_font_word(a,6); if (*a) a++; - b = fl_font_word(b,6); if (*b) b++; - if (use_registry(a)) { - if (!use_registry(b)) return 1; - int r = strcmp(a,b); if (r) return r; - } else { - if (use_registry(b)) return -1; - } - - if (atype != btype) return atype-btype; - if (asize != bsize) return asize-bsize; - - // something wrong, just do a string compare... - return strcmp(*(char**)aa, *(char**)bb); -} -} - -// converts a X font name to a standard starname, returns point size: -static int to_canonical(char *to, const char *from) { - char* c = fl_find_fontsize((char*)from); - if (!c) return -1; // no point size found... - const char* endptr; - int size = strtol(c,(char**)&endptr,10); - if (from[0] == '-') { - // replace the "foundry" with -*-: - *to++ = '-'; *to++ = '*'; - for (from++; *from && *from != '-'; from++); - // skip to the registry-encoding: - endptr = (char*)fl_font_word(endptr,6); - if (*endptr && !use_registry(endptr+1)) endptr = ""; - } - int n = c-from; - strncpy(to,from,n); - to[n++] = '*'; - strcpy(to+n,endptr); - return size; -} - -static int fl_free_font = FL_FREE_FONT; - -Fl_Font Fl::set_fonts(const char* xstarname) { - if (fl_free_font > FL_FREE_FONT) // already been here - return (Fl_Font)fl_free_font; - fl_open_display(); - int xlistsize; - char buf[20]; - if (!xstarname) { - strcpy(buf,"-*-"); strcpy(buf+3,fl_encoding); - xstarname = buf; - } - char **xlist = XListFonts(fl_display, xstarname, 10000, &xlistsize); - if (!xlist) return (Fl_Font)fl_free_font; - qsort(xlist, xlistsize, sizeof(*xlist), ultrasort); - int used_xlist = 0; - for (int i=0; i<xlistsize;) { - int first_xlist = i; - const char *p = xlist[i++]; - char canon[1024]; - int size = to_canonical(canon, p); - if (size >= 0) { - for (;;) { // find all matching fonts: - if (i >= xlistsize) break; - const char *q = xlist[i]; - char this_canon[1024]; - if (to_canonical(this_canon, q) < 0) break; - if (strcmp(canon, this_canon)) break; - i++; - } - /*if (*p=='-' || i > first_xlist+1)*/ p = canon; - } - int j; - for (j = 0;; j++) { - if (j < FL_FREE_FONT) { - // see if it is one of our built-in fonts: - // if so, set the list of x fonts, since we have it anyway - if (fl_fonts[j].name && !strcmp(fl_fonts[j].name, p)) break; - } else { - j = fl_free_font++; - if (p == canon) p = strdup(p); else used_xlist = 1; - Fl::set_font((Fl_Font)j, p); - break; - } - } - if (!fl_fonts[j].xlist) { - fl_fonts[j].xlist = xlist+first_xlist; - fl_fonts[j].n = -(i-first_xlist); - used_xlist = 1; - } - } - if (!used_xlist) XFreeFontNames(xlist); - return (Fl_Font)fl_free_font; -} - -int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { - Fl_Fontdesc *s = fl_fonts+fnum; - if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 - if (!s->xlist) { - fl_open_display(); - s->xlist = XListFonts(fl_display, s->name, 100, &(s->n)); - if (!s->xlist) return 0; - } - int listsize = s->n; if (listsize<0) listsize = -listsize; - static int sizes[128]; - int numsizes = 0; - for (int i = 0; i < listsize; i++) { - char *q = s->xlist[i]; - char *d = fl_find_fontsize(q); - if (!d) continue; - int s = strtol(d,0,10); - if (!numsizes || sizes[numsizes-1] < s) { - sizes[numsizes++] = s; - } else { - // insert-sort the new size into list: - int n; - for (n = numsizes-1; n > 0; n--) if (sizes[n-1] < s) break; - if (sizes[n] != s) { - for (int m = numsizes; m > n; m--) sizes[m] = sizes[m-1]; - sizes[n] = s; - numsizes++; - } - } - } - sizep = sizes; - return numsizes; -} - -#endif +# include "fl_set_fonts_x.cxx" +#endif // WIN32 // -// End of "$Id: fl_set_fonts.cxx,v 1.6.2.5.2.3 2002/01/01 15:11:32 easysw Exp $". +// End of "$Id: fl_set_fonts.cxx,v 1.6.2.5.2.4 2002/03/06 18:11:01 easysw Exp $". // |
