diff --git a/CHANGES b/CHANGES index 6d8254cca..5b64db261 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ CHANGES IN FLTK 1.1.0b12 + - Added support for Xft library to support anti-aliased + text on X11. - Fl_Help_View didn't keep track of the background color of cells properly. - Fl_Browser::item_width() didn't compute the width of diff --git a/FL/x.H b/FL/x.H index 84b5de6be..467f5f1f3 100644 --- a/FL/x.H +++ b/FL/x.H @@ -1,5 +1,5 @@ // -// "$Id: x.H,v 1.10.2.8.2.5 2002/01/01 15:11:28 easysw Exp $" +// "$Id: x.H,v 1.10.2.8.2.6 2002/03/06 18:11:00 easysw Exp $" // // X11 header file for the Fast Light Tool Kit (FLTK). // @@ -69,6 +69,7 @@ extern FL_EXPORT XFontStruct* fl_xfont; FL_EXPORT ulong fl_xpixel(Fl_Color i); FL_EXPORT ulong fl_xpixel(uchar r, uchar g, uchar b); FL_EXPORT void fl_clip_region(Fl_Region); +FL_EXPORT Fl_Region fl_clip_region(); FL_EXPORT Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx // feed events into fltk: @@ -135,5 +136,5 @@ extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) #endif // -// End of "$Id: x.H,v 1.10.2.8.2.5 2002/01/01 15:11:28 easysw Exp $". +// End of "$Id: x.H,v 1.10.2.8.2.6 2002/03/06 18:11:00 easysw Exp $". // diff --git a/configh.in b/configh.in index 1d9114347..e87c463e9 100644 --- a/configh.in +++ b/configh.in @@ -1,5 +1,5 @@ /* - * "$Id: configh.in,v 1.11.2.11.2.7 2002/01/01 15:11:27 easysw Exp $" + * "$Id: configh.in,v 1.11.2.11.2.8 2002/03/06 18:11:00 easysw Exp $" * * Configuration file for the Fast Light Tool Kit (FLTK). * @configure_input@ @@ -74,6 +74,14 @@ #define USE_COLORMAP 1 +/* + * USE_XFT + * + * Use the new Xft library to draw anti-aliased text. + */ + +#define USE_XFT 0 + /* * HAVE_XDBE: * @@ -209,5 +217,5 @@ /* - * End of "$Id: configh.in,v 1.11.2.11.2.7 2002/01/01 15:11:27 easysw Exp $". + * End of "$Id: configh.in,v 1.11.2.11.2.8 2002/03/06 18:11:00 easysw Exp $". */ diff --git a/configure.in b/configure.in index 3b5757ce3..e3e1dac81 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ dnl -*- sh -*- dnl the "configure" script is made from this by running GNU "autoconf" dnl -dnl "$Id: configure.in,v 1.33.2.31.2.51 2002/02/15 18:15:45 easysw Exp $" +dnl "$Id: configure.in,v 1.33.2.31.2.52 2002/03/06 18:11:00 easysw Exp $" dnl dnl Configuration script for the Fast Light Tool Kit (FLTK). dnl @@ -420,8 +420,14 @@ case $uname in GLDEMOS="" fi + dnl Check for the Xft library... + AC_CHECK_HEADER(X11/Xft/Xft.h, + AC_CHECK_LIB(Xft, XftDrawCreate, + AC_DEFINE(USE_XFT) + LIBS="-lXft $LIBS")) + dnl Check for the Xdbe extension... - AC_CHECK_HEADER(X11/extensions/Xdbe.h, \ + AC_CHECK_HEADER(X11/extensions/Xdbe.h, if test "$uname" != "SunOS"; then AC_DEFINE(HAVE_XDBE) fi) @@ -683,5 +689,5 @@ dnl Make sure the fltk-config script is executable... chmod +x fltk-config dnl -dnl End of "$Id: configure.in,v 1.33.2.31.2.51 2002/02/15 18:15:45 easysw Exp $". +dnl End of "$Id: configure.in,v 1.33.2.31.2.52 2002/03/06 18:11:00 easysw Exp $". dnl diff --git a/src/Fl_Font.H b/src/Fl_Font.H index 3652c4a1e..80cab8254 100644 --- a/src/Fl_Font.H +++ b/src/Fl_Font.H @@ -1,9 +1,9 @@ // -// "$Id: Fl_Font.H,v 1.6.2.3.2.1 2001/11/27 17:44:06 easysw Exp $" +// "$Id: Fl_Font.H,v 1.6.2.3.2.2 2002/03/06 18:11:01 easysw Exp $" // // Font definitions for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2001 by Bill Spitzak and others. +// Copyright 1998-2002 by Bill Spitzak and others. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -36,29 +36,38 @@ #ifndef FL_FONT_ #define FL_FONT_ +# if USE_XFT +typedef struct _XftFont XftFont; +# endif // USE_XFT + class Fl_FontSize { public: Fl_FontSize *next; // linked list for this Fl_Fontdesc -#ifdef WIN32 +# ifdef WIN32 HFONT fid; int width[256]; TEXTMETRIC metr; FL_EXPORT Fl_FontSize(const char* fontname, int size); -#elif defined(__APPLE__) +# elif defined(__APPLE__) FL_EXPORT Fl_FontSize(const char* fontname, int size); short font, face, size; short ascent, descent; short width[256]; bool knowMetrics; -#else +# elif USE_XFT + XftFont* font; + const char* encoding; + int size; + FL_EXPORT Fl_FontSize(const char* xfontname); +# else XFontStruct* font; // X font information FL_EXPORT Fl_FontSize(const char* xfontname); -#endif +# endif int minsize; // smallest point size that should use this int maxsize; // largest point size that should use this -#if HAVE_GL +# if HAVE_GL unsigned int listbase;// base of display list, 0 = none -#endif +# endif FL_EXPORT ~Fl_FontSize(); }; @@ -67,22 +76,22 @@ extern FL_EXPORT Fl_FontSize *fl_fontsize; // the currently selected one struct Fl_Fontdesc { const char *name; Fl_FontSize *first; // linked list of sizes of this style -#ifndef WIN32 +# ifndef WIN32 char **xlist; // matched X font names int n; // size of xlist, negative = don't free xlist! -#endif +# endif }; extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table -#ifndef WIN32 +# ifndef WIN32 // functions for parsing X font names: FL_EXPORT const char* fl_font_word(const char *p, int n); FL_EXPORT char *fl_find_fontsize(char *name); -#endif +# endif #endif // -// End of "$Id: Fl_Font.H,v 1.6.2.3.2.1 2001/11/27 17:44:06 easysw Exp $". +// End of "$Id: Fl_Font.H,v 1.6.2.3.2.2 2002/03/06 18:11:01 easysw Exp $". // diff --git a/src/Makefile b/src/Makefile index e3488c1c2..3ca2ecfca 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.18.2.14.2.34 2002/02/26 00:34:55 matthiaswm Exp $" +# "$Id: Makefile,v 1.18.2.14.2.35 2002/03/06 18:11:01 easysw Exp $" # # Library makefile for the Fast Light Tool Kit (FLTK). # @@ -232,9 +232,10 @@ Fl_cutpaste.o: Fl_cutpaste_mac.cxx Fl_cutpaste_win32.cxx Fl_get_key.o: Fl_get_key_mac.cxx Fl_get_key_win32.cxx Fl_x.o: Fl_mac.cxx Fl_win32.cxx fl_color.o: fl_color_mac.cxx fl_color_win32.cxx -fl_draw_image.o: fl_draw_image_mac.cxx fl_draw_image_win32.cxx -fl_font.o: fl_font_mac.cxx fl_font_win32.cxx -fl_set_fonts.o: fl_set_fonts_mac.cxx fl_set_fonts_win32.cxx +fl_draw_image.o: fl_draw_image_mac.cxx fl_draw_image_win32.cxx +fl_font.o: fl_font_mac.cxx fl_font_x.cxx fl_font_xft.cxx fl_font_win32.cxx +fl_set_fonts.o: fl_set_fonts_mac.cxx fl_set_fonts_x.cxx \ + fl_set_fonts_xft.cxx fl_set_fonts_win32.cxx fl_arci.o: ../FL/mac.H ../FL/win32.H Fl_arg.o: ../FL/mac.H ../FL/win32.H @@ -353,5 +354,5 @@ uninstall: # -# End of "$Id: Makefile,v 1.18.2.14.2.34 2002/02/26 00:34:55 matthiaswm Exp $". +# End of "$Id: Makefile,v 1.18.2.14.2.35 2002/03/06 18:11:01 easysw Exp $". # diff --git a/src/fl_font.cxx b/src/fl_font.cxx index 434741b99..c8ceab378 100644 --- a/src/fl_font.cxx +++ b/src/fl_font.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font.cxx,v 1.9.2.5.2.3 2002/01/01 15:11:32 easysw Exp $" +// "$Id: fl_font.cxx,v 1.9.2.5.2.4 2002/03/06 18:11:01 easysw Exp $" // // Font selection code for the Fast Light Tool Kit (FLTK). // @@ -23,271 +23,38 @@ // Please report all bugs and problems to "fltk-bugs@fltk.org". // -// Select fonts from the fltk font table. +// Select fonts from the FLTK font table. +#include +#include +#include +#include +#include "Fl_Font.H" + +#include +#include +#include +#include #ifdef WIN32 # include "fl_font_win32.cxx" #elif defined(__APPLE__) # include "fl_font_mac.cxx" +#elif USE_XFT +# include "fl_font_xft.cxx" #else +# include "fl_font_x.cxx" +#endif // WIN32 -# include -# include -# include -# include -# include "Fl_Font.H" - -# include -# include -# include -# include - -Fl_FontSize::Fl_FontSize(const char* name) { - font = XLoadQueryFont(fl_display, name); - if (!font) { - Fl::warning("bad font: %s", name); - font = XLoadQueryFont(fl_display, "fixed"); // if fixed fails we crash - } -# if HAVE_GL - listbase = 0; -# endif -} - -Fl_FontSize* fl_fontsize; - -Fl_FontSize::~Fl_FontSize() { -# if HAVE_GL -// Delete list created by gl_draw(). This is not done by this code -// as it will link in GL unnecessarily. There should be some kind -// of "free" routine pointer, or a subclass? -// if (listbase) { -// int base = font->min_char_or_byte2; -// int size = font->max_char_or_byte2-base+1; -// int base = 0; int size = 256; -// glDeleteLists(listbase+base,size); -// } -# endif - if (this == fl_fontsize) fl_fontsize = 0; - XFreeFont(fl_display, font); -} - -//////////////////////////////////////////////////////////////// - -// WARNING: if you add to this table, you must redefine FL_FREE_FONT -// in Enumerations.H & recompile!! -static Fl_Fontdesc built_in_table[] = { -{"-*-helvetica-medium-r-normal--*"}, -{"-*-helvetica-bold-r-normal--*"}, -{"-*-helvetica-medium-o-normal--*"}, -{"-*-helvetica-bold-o-normal--*"}, -{"-*-courier-medium-r-normal--*"}, -{"-*-courier-bold-r-normal--*"}, -{"-*-courier-medium-o-normal--*"}, -{"-*-courier-bold-o-normal--*"}, -{"-*-times-medium-r-normal--*"}, -{"-*-times-bold-r-normal--*"}, -{"-*-times-medium-i-normal--*"}, -{"-*-times-bold-i-normal--*"}, -{"-*-symbol-*"}, -{"-*-lucidatypewriter-medium-r-normal-sans-*"}, -{"-*-lucidatypewriter-bold-r-normal-sans-*"}, -{"-*-*zapf dingbats-*"} -}; - -Fl_Fontdesc* fl_fonts = built_in_table; - -#define MAXSIZE 32767 - -// return dash number N, or pointer to ending null if none: -const char* fl_font_word(const char* p, int n) { - while (*p) {if (*p=='-') {if (!--n) break;} p++;} - return p; -} - -// return a pointer to a number we think is "point size": -char* fl_find_fontsize(char* name) { - char* c = name; - // for standard x font names, try after 7th dash: - if (*c == '-') { - c = (char*)fl_font_word(c,7); - if (*c++ && isdigit(*c)) return c; - return 0; // malformed x font name? - } - char* r = 0; - // find last set of digits: - for (c++;* c; c++) - if (isdigit(*c) && !isdigit(*(c-1))) r = c; - return r; -} - -const char* fl_encoding = "iso8859-1"; - -// return true if this matches fl_encoding: -int fl_correct_encoding(const char* name) { - if (*name != '-') return 0; - const char* c = fl_font_word(name,13); - return (*c++ && !strcmp(c,fl_encoding)); -} - -// locate or create an Fl_FontSize for a given Fl_Fontdesc and size: -static Fl_FontSize* find(int fnum, int size) { - Fl_Fontdesc* s = fl_fonts+fnum; - if (!s->name) s = fl_fonts; // use font 0 if still undefined - Fl_FontSize* f; - for (f = s->first; f; f = f->next) - if (f->minsize <= size && f->maxsize >= size) return f; - fl_open_display(); - if (!s->xlist) { - s->xlist = XListFonts(fl_display, s->name, 100, &(s->n)); - if (!s->xlist) { // use fixed if no matching font... - s->first = new Fl_FontSize("fixed"); - s->first->minsize = 0; - s->first->maxsize = 32767; - return s->first; - } - } - // search for largest <= font size: - char* name = s->xlist[0]; int ptsize = 0; // best one found so far - int matchedlength = 32767; - char namebuffer[1024]; // holds scalable font name - int found_encoding = 0; - int m = s->n; if (m<0) m = -m; - for (int n=0; n < m; n++) { - - char* thisname = s->xlist[n]; - if (fl_correct_encoding(thisname)) { - if (!found_encoding) ptsize = 0; // force it to choose this - found_encoding = 1; - } else { - if (found_encoding) continue; - } - char* c = fl_find_fontsize(thisname); - int thissize = c ? atoi(c) : MAXSIZE; - int thislength = strlen(thisname); - if (thissize == size && thislength < matchedlength) { - // exact match, use it: - name = thisname; - ptsize = size; - matchedlength = thislength; - } else if (!thissize && ptsize!=size) { - // whoa! A scalable font! Use unless exact match found: - int l = c-thisname; - memcpy(namebuffer,thisname,l); - l += sprintf(namebuffer+l,"%d",size); - while (*c == '0') c++; - strcpy(namebuffer+l,c); - name = namebuffer; - ptsize = size; - } else if (!ptsize || // no fonts yet - thissize < ptsize && ptsize > size || // current font too big - thissize > ptsize && thissize <= size // current too small - ) { - name = thisname; ptsize = thissize; - matchedlength = thislength; - } - } - - if (ptsize != size) { // see if we already found this unscalable font: - for (f = s->first; f; f = f->next) { - if (f->minsize <= ptsize && f->maxsize >= ptsize) { - if (f->minsize > size) f->minsize = size; - if (f->maxsize < size) f->maxsize = size; - return f; - } - } - } - - // okay, we definately have some name, make the font: - f = new Fl_FontSize(name); - if (ptsize < size) {f->minsize = ptsize; f->maxsize = size;} - else {f->minsize = size; f->maxsize = ptsize;} - f->next = s->first; - s->first = f; - return f; - -} - -//////////////////////////////////////////////////////////////// -// Public interface: - -int fl_font_; -int fl_size_; -XFontStruct* fl_xfont; -static GC font_gc; - -void fl_font(int fnum, int size) { - if (fnum == fl_font_ && size == fl_size_) return; - fl_font_ = fnum; fl_size_ = size; - Fl_FontSize* f = find(fnum, size); - if (f != fl_fontsize) { - fl_fontsize = f; - fl_xfont = f->font; - font_gc = 0; - } -} - -int fl_height() { - return (fl_xfont->ascent + fl_xfont->descent); -} - -int fl_descent() { - return fl_xfont->descent; -} double fl_width(const char* c) { - XCharStruct* p = fl_xfont->per_char; - if (!p) return strlen(c)*fl_xfont->min_bounds.width; - int a = fl_xfont->min_char_or_byte2; - int b = fl_xfont->max_char_or_byte2 - a; - int w = 0; - while (*c) { - int x = *(uchar*)c++ - a; - if (x >= 0 && x <= b) w += p[x].width; - else w += fl_xfont->min_bounds.width; - } - return w; -} - -double fl_width(const char* c, int n) { - XCharStruct* p = fl_xfont->per_char; - if (!p) return n*fl_xfont->min_bounds.width; - int a = fl_xfont->min_char_or_byte2; - int b = fl_xfont->max_char_or_byte2 - a; - int w = 0; - while (n--) { - int x = *(uchar*)c++ - a; - if (x >= 0 && x <= b) w += p[x].width; - else w += fl_xfont->min_bounds.width; - } - return w; -} - -double fl_width(uchar c) { - XCharStruct* p = fl_xfont->per_char; - if (p) { - int a = fl_xfont->min_char_or_byte2; - int b = fl_xfont->max_char_or_byte2 - a; - int x = c-a; - if (x >= 0 && x <= b) return p[x].width; - } - return fl_xfont->min_bounds.width; -} - -void fl_draw(const char* str, int n, int x, int y) { - if (font_gc != fl_gc) { - if (!fl_xfont) fl_font(FL_HELVETICA, 14); - font_gc = fl_gc; - XSetFont(fl_display, fl_gc, fl_xfont->fid); - } - XDrawString(fl_display, fl_window, fl_gc, x, y, str, n); + if (c) return fl_width(c, strlen(c)); + else return 0.0f; } void fl_draw(const char* str, int x, int y) { fl_draw(str, strlen(str), x, y); } -#endif - // -// End of "$Id: fl_font.cxx,v 1.9.2.5.2.3 2002/01/01 15:11:32 easysw Exp $". +// End of "$Id: fl_font.cxx,v 1.9.2.5.2.4 2002/03/06 18:11:01 easysw Exp $". // diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx index c8e4c5442..80808e8b0 100644 --- a/src/fl_font_mac.cxx +++ b/src/fl_font_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font_mac.cxx,v 1.1.2.4 2002/01/01 15:11:32 easysw Exp $" +// "$Id: fl_font_mac.cxx,v 1.1.2.5 2002/03/06 18:11:01 easysw Exp $" // // MacOS font selection routines for the Fast Light Tool Kit (FLTK). // @@ -28,17 +28,6 @@ //: GetFNum (theName: Str255; VAR familyID: Integer); //: FUNCTION FMSwapFont (inRec: FMInput): FMOutPtr; - -#include -#include -#include -#include -#include "Fl_Font.h" - -#include -#include -#include - Fl_FontSize::Fl_FontSize(const char* name, int Size) { knowMetrics = 0; switch (*name++) { @@ -149,11 +138,6 @@ int fl_descent() { return fl_fontsize->descent; } -double fl_width(const char* c) { - int n = strlen( c ); - return (double)TextWidth( c, 0, n ); -} - double fl_width(const char* c, int n) { return (double)TextWidth( c, 0, n ); } @@ -167,10 +151,6 @@ void fl_draw(const char* str, int n, int x, int y) { DrawText(str, 0, n); } -void fl_draw(const char* str, int x, int y) { - fl_draw(str, strlen(str), x, y); -} - // -// End of "$Id: fl_font_mac.cxx,v 1.1.2.4 2002/01/01 15:11:32 easysw Exp $". +// End of "$Id: fl_font_mac.cxx,v 1.1.2.5 2002/03/06 18:11:01 easysw Exp $". // diff --git a/src/fl_font_win32.cxx b/src/fl_font_win32.cxx index 6c5799776..11decaf94 100644 --- a/src/fl_font_win32.cxx +++ b/src/fl_font_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font_win32.cxx,v 1.9.2.3.2.2 2002/01/01 15:11:32 easysw Exp $" +// "$Id: fl_font_win32.cxx,v 1.9.2.3.2.3 2002/03/06 18:11:01 easysw Exp $" // // WIN32 font selection routines for the Fast Light Tool Kit (FLTK). // @@ -23,16 +23,6 @@ // Please report all bugs and problems to "fltk-bugs@fltk.org". // -#include -#include -#include -#include -#include "Fl_Font.H" - -#include -#include -#include - Fl_FontSize::Fl_FontSize(const char* name, int size) { int weight = FW_NORMAL; int italic = 0; @@ -147,12 +137,6 @@ int fl_descent() { return fl_fontsize->metr.tmDescent; } -double fl_width(const char* c) { - double w = 0.0; - while (*c) w += fl_fontsize->width[uchar(*c++)]; - return w; -} - double fl_width(const char* c, int n) { double w = 0.0; while (n--) w += fl_fontsize->width[uchar(*c++)]; @@ -170,10 +154,7 @@ void fl_draw(const char* str, int n, int x, int y) { SetTextColor(fl_gc, oldColor); } -void fl_draw(const char* str, int x, int y) { - fl_draw(str, strlen(str), x, y); -} // -// End of "$Id: fl_font_win32.cxx,v 1.9.2.3.2.2 2002/01/01 15:11:32 easysw Exp $". +// End of "$Id: fl_font_win32.cxx,v 1.9.2.3.2.3 2002/03/06 18:11:01 easysw Exp $". // diff --git a/src/fl_font_x.cxx b/src/fl_font_x.cxx index 186303726..50688a52a 100644 --- a/src/fl_font_x.cxx +++ b/src/fl_font_x.cxx @@ -1,9 +1,9 @@ // -// "$Id: fl_font_x.cxx,v 1.10 2002/02/25 09:00:22 spitzak Exp $" +// "$Id: fl_font_x.cxx,v 1.10.2.1 2002/03/06 18:11:01 easysw Exp $" // -// Font selection code for the Fast Light Tool Kit (FLTK). +// Standard X11 font selection code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2001 by Bill Spitzak and others. +// Copyright 1998-2002 by Bill Spitzak and others. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -20,245 +20,235 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@easysw.com". +// Please report all bugs and problems to "fltk-bugs@fltk.org". // -#include -#include -#include -#include -#include -#include -#include - -class Fl_FontSize { -public: - Fl_FontSize* next; // linked list for a single Fl_Font_ - XFontStruct* font; - const char* encoding; - Fl_FontSize(const char* xfontname); - unsigned minsize; // smallest point size that should use this - unsigned maxsize; // largest point size that should use this - // ~Fl_FontSize(); -}; - -static Fl_FontSize *fl_fontsize; - -static GC font_gc; // which gc the font was set in last time - -static void -set_current_fontsize(Fl_FontSize* f) { - if (f != fl_fontsize) { - fl_fontsize = f; - font_gc = 0; - } -} - -#define current_font (fl_fontsize->font) -XFontStruct* fl_xfont() {return current_font;} - Fl_FontSize::Fl_FontSize(const char* name) { font = XLoadQueryFont(fl_display, name); if (!font) { Fl::warning("bad font: %s", name); font = XLoadQueryFont(fl_display, "fixed"); // if fixed fails we crash } - encoding = 0; +# if HAVE_GL + listbase = 0; +# endif } -#if 0 // this is never called! +Fl_FontSize* fl_fontsize; + Fl_FontSize::~Fl_FontSize() { +# if HAVE_GL +// Delete list created by gl_draw(). This is not done by this code +// as it will link in GL unnecessarily. There should be some kind +// of "free" routine pointer, or a subclass? +// if (listbase) { +// int base = font->min_char_or_byte2; +// int size = font->max_char_or_byte2-base+1; +// int base = 0; int size = 256; +// glDeleteLists(listbase+base,size); +// } +# endif if (this == fl_fontsize) fl_fontsize = 0; XFreeFont(fl_display, font); } -#endif //////////////////////////////////////////////////////////////// -// Things you can do once the font+size has been selected: -void fl_draw(const char *str, int n, int x, int y) { - if (font_gc != fl_gc) { - // I removed this, the user MUST set the font before drawing: (was) - // if (!fl_fontsize) fl_font(FL_HELVETICA, FL_NORMAL_SIZE); - font_gc = fl_gc; - XSetFont(fl_display, fl_gc, current_font->fid); - } - XDrawString(fl_display, fl_window, fl_gc, x+fl_x_, y+fl_y_, str, n); -} +// WARNING: if you add to this table, you must redefine FL_FREE_FONT +// in Enumerations.H & recompile!! +static Fl_Fontdesc built_in_table[] = { +{"-*-helvetica-medium-r-normal--*"}, +{"-*-helvetica-bold-r-normal--*"}, +{"-*-helvetica-medium-o-normal--*"}, +{"-*-helvetica-bold-o-normal--*"}, +{"-*-courier-medium-r-normal--*"}, +{"-*-courier-bold-r-normal--*"}, +{"-*-courier-medium-o-normal--*"}, +{"-*-courier-bold-o-normal--*"}, +{"-*-times-medium-r-normal--*"}, +{"-*-times-bold-r-normal--*"}, +{"-*-times-medium-i-normal--*"}, +{"-*-times-bold-i-normal--*"}, +{"-*-symbol-*"}, +{"-*-lucidatypewriter-medium-r-normal-sans-*"}, +{"-*-lucidatypewriter-bold-r-normal-sans-*"}, +{"-*-*zapf dingbats-*"} +}; -int fl_height() { - return (current_font->ascent + current_font->descent); -} +Fl_Fontdesc* fl_fonts = built_in_table; -int fl_descent() { return current_font->descent; } - -int fl_width(const char *c, int n) { - return XTextWidth(current_font, c, n); -} - -//////////////////////////////////////////////////////////////// -// The rest of this file is the enormous amount of crap you have to -// do to get a font & size out of X. To select a font+size, all -// matchine X fonts are listed with XListFonts, and then the first -// of the following is found and used: -// -// pixelsize == size -// pixelsize == 0 (which indicates a scalable font) -// the largest pixelsize < size -// the smallest pixelsize > size -// -// If any fonts match the fl_encoding() then the search is limited -// to those matching fonts. Otherwise all fonts are searched and thus -// a random encoding is chosen. -// -// I have not been able to find any other method than a search -// that will reliably return a bitmap version of the font if one is -// available at the correct size. This is because X will not use a -// bitmap font unless all the extra fields are filled in correctly. -// -// Fltk uses pixelsize, not "pointsize". This is what everybody wants! +#define MAXSIZE 32767 // return dash number N, or pointer to ending null if none: -static const char * -font_word(const char* p, int n) { +const char* fl_font_word(const char* p, int n) { while (*p) {if (*p=='-') {if (!--n) break;} p++;} return p; } -void fl_font(Fl_Font font, unsigned size) { - Fl_FontSize* f = fl_fontsize; +// return a pointer to a number we think is "point size": +char* fl_find_fontsize(char* name) { + char* c = name; + // for standard x font names, try after 7th dash: + if (*c == '-') { + c = (char*)fl_font_word(c,7); + if (*c++ && isdigit(*c)) return c; + return 0; // malformed x font name? + } + char* r = 0; + // find last set of digits: + for (c++;* c; c++) + if (isdigit(*c) && !isdigit(*(c-1))) r = c; + return r; +} - // See if the current font is correct: - if (font == fl_font_ && size == fl_size_ && - (f->encoding==fl_encoding_ || !strcmp(f->encoding, fl_encoding_))) - return; - fl_font_ = font; fl_size_ = size; +const char* fl_encoding_ = "iso8859-1"; - // search the FontSize we have generated already: - for (f = font->first; f; f = f->next) - if (f->minsize <= size && f->maxsize >= size - && (f->encoding==fl_encoding_ || - !f->encoding || !strcmp(f->encoding, fl_encoding_))) { - set_current_fontsize(f); return; - } +// return true if this matches fl_encoding: +int fl_correct_encoding(const char* name) { + if (*name != '-') return 0; + const char* c = fl_font_word(name,13); + return (*c++ && !strcmp(c,fl_encoding_)); +} - // now search the XListFonts results: - if (!font->xlist) { - fl_open_display(); - Fl_Font_* t = (Fl_Font_*)font; // cast away const - t->xlist = XListFonts(fl_display, t->name_, 100, &(t->n)); - if (!t->xlist || t->n<=0) { // use variable if no matching font... - t->first = f = new Fl_FontSize("variable"); - f->minsize = 0; - f->maxsize = 32767; - set_current_fontsize(f); return; +// locate or create an Fl_FontSize for a given Fl_Fontdesc and size: +static Fl_FontSize* find(int fnum, int size) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use font 0 if still undefined + Fl_FontSize* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size) return f; + fl_open_display(); + if (!s->xlist) { + s->xlist = XListFonts(fl_display, s->name, 100, &(s->n)); + if (!s->xlist) { // use fixed if no matching font... + s->first = new Fl_FontSize("fixed"); + s->first->minsize = 0; + s->first->maxsize = 32767; + return s->first; } } - - char* name = font->xlist[0]; - unsigned ptsize = 0; // best one found so far + // search for largest <= font size: + char* name = s->xlist[0]; int ptsize = 0; // best one found so far + int matchedlength = 32767; char namebuffer[1024]; // holds scalable font name - bool found_encoding = false; - int m = font->n; if (m<0) m = -m; - + int found_encoding = 0; + int m = s->n; if (m<0) m = -m; for (int n=0; n < m; n++) { - char* thisname = font->xlist[n]; - // get the encoding field: - const char* this_encoding = font_word(thisname, 13); - if (*this_encoding++ && !strcmp(this_encoding, fl_encoding_)) { - // forget any wrong encodings when we find a correct one: - if (!found_encoding) ptsize = 0; - found_encoding = true; + char* thisname = s->xlist[n]; + if (fl_correct_encoding(thisname)) { + if (!found_encoding) ptsize = 0; // force it to choose this + found_encoding = 1; } else { - // ignore later wrong encodings after we find a correct one: if (found_encoding) continue; } - // get the pixelsize field: - const char* c = font_word(thisname,7); - unsigned thissize = *c ? atoi(++c) : 32767; - if (thissize == size) { - // Use an exact match: + char* c = fl_find_fontsize(thisname); + int thissize = c ? atoi(c) : MAXSIZE; + int thislength = strlen(thisname); + if (thissize == size && thislength < matchedlength) { + // exact match, use it: name = thisname; ptsize = size; - if (found_encoding) break; + matchedlength = thislength; } else if (!thissize && ptsize!=size) { - // Use a scalable font if no exact match found: + // whoa! A scalable font! Use unless exact match found: int l = c-thisname; memcpy(namebuffer,thisname,l); - // print the pointsize into it: - if (size>=100) namebuffer[l++] = size/100+'0'; - if (size>=10) namebuffer[l++] = (size/10)%10+'0'; - namebuffer[l++] = (size%10)+'0'; + l += sprintf(namebuffer+l,"%d",size); while (*c == '0') c++; strcpy(namebuffer+l,c); name = namebuffer; ptsize = size; } else if (!ptsize || // no fonts yet - thissize < ptsize && ptsize > size || // current font too big - thissize > ptsize && thissize <= size // current too small + thissize < ptsize && ptsize > size || // current font too big + thissize > ptsize && thissize <= size // current too small ) { - // Use the nearest fixed size font: - name = thisname; - ptsize = thissize; + name = thisname; ptsize = thissize; + matchedlength = thislength; } } - // If we didn't find an exact match, search the list to see if we already - // found this font: - if (ptsize != size || !found_encoding) { - for (f = font->first; f; f = f->next) { - if (f->minsize <= ptsize && f->maxsize >= ptsize && - (!found_encoding || !strcmp(f->encoding, fl_encoding_))) { + if (ptsize != size) { // see if we already found this unscalable font: + for (f = s->first; f; f = f->next) { + if (f->minsize <= ptsize && f->maxsize >= ptsize) { if (f->minsize > size) f->minsize = size; if (f->maxsize < size) f->maxsize = size; - set_current_fontsize(f); return; + return f; } } } // okay, we definately have some name, make the font: f = new Fl_FontSize(name); - // we pretend it has the current encoding even if it does not, so that - // it is quickly matched when searching for it again with the same - // encoding: - f->encoding = fl_encoding_; if (ptsize < size) {f->minsize = ptsize; f->maxsize = size;} else {f->minsize = size; f->maxsize = ptsize;} - f->next = font->first; - ((Fl_Font_*)font)->first = f; - set_current_fontsize(f); + f->next = s->first; + s->first = f; + return f; } -// Change the encoding to use for the next font selection. -void fl_encoding(const char* f) { - fl_encoding_ = f; -} - //////////////////////////////////////////////////////////////// +// Public interface: -// The predefined fonts that fltk has: bold: italic: -Fl_Font_ -fl_fonts[] = { -{"-*-helvetica-medium-r-normal--*", fl_fonts+1, fl_fonts+2}, -{"-*-helvetica-bold-r-normal--*", fl_fonts+1, fl_fonts+3}, -{"-*-helvetica-medium-o-normal--*", fl_fonts+3, fl_fonts+2}, -{"-*-helvetica-bold-o-normal--*", fl_fonts+3, fl_fonts+3}, -{"-*-courier-medium-r-normal--*", fl_fonts+5, fl_fonts+6}, -{"-*-courier-bold-r-normal--*", fl_fonts+5, fl_fonts+7}, -{"-*-courier-medium-o-normal--*", fl_fonts+7, fl_fonts+6}, -{"-*-courier-bold-o-normal--*", fl_fonts+7, fl_fonts+7}, -{"-*-times-medium-r-normal--*", fl_fonts+9, fl_fonts+10}, -{"-*-times-bold-r-normal--*", fl_fonts+9, fl_fonts+11}, -{"-*-times-medium-i-normal--*", fl_fonts+11,fl_fonts+10}, -{"-*-times-bold-i-normal--*", fl_fonts+11,fl_fonts+11}, -{"-*-symbol-*", fl_fonts+12,fl_fonts+12}, -{"-*-lucidatypewriter-medium-r-normal-sans-*", fl_fonts+14,fl_fonts+14}, -{"-*-lucidatypewriter-bold-r-normal-sans-*", fl_fonts+14,fl_fonts+14}, -{"-*-*zapf dingbats-*", fl_fonts+15,fl_fonts+15}, -}; +int fl_font_; +int fl_size_; +XFontStruct* fl_xfont; +static GC font_gc; + +void fl_font(int fnum, int size) { + if (fnum == fl_font_ && size == fl_size_) return; + fl_font_ = fnum; fl_size_ = size; + Fl_FontSize* f = find(fnum, size); + if (f != fl_fontsize) { + fl_fontsize = f; + fl_xfont = f->font; + font_gc = 0; + } +} + +int fl_height() { + return (fl_xfont->ascent + fl_xfont->descent); +} + +int fl_descent() { + return fl_xfont->descent; +} + +double fl_width(const char* c, int n) { + XCharStruct* p = fl_xfont->per_char; + if (!p) return n*fl_xfont->min_bounds.width; + int a = fl_xfont->min_char_or_byte2; + int b = fl_xfont->max_char_or_byte2 - a; + int w = 0; + while (n--) { + int x = *(uchar*)c++ - a; + if (x >= 0 && x <= b) w += p[x].width; + else w += fl_xfont->min_bounds.width; + } + return w; +} + +double fl_width(uchar c) { + XCharStruct* p = fl_xfont->per_char; + if (p) { + int a = fl_xfont->min_char_or_byte2; + int b = fl_xfont->max_char_or_byte2 - a; + int x = c-a; + if (x >= 0 && x <= b) return p[x].width; + } + return fl_xfont->min_bounds.width; +} + +void fl_draw(const char* str, int n, int x, int y) { + if (font_gc != fl_gc) { + if (!fl_xfont) fl_font(FL_HELVETICA, 14); + font_gc = fl_gc; + XSetFont(fl_display, fl_gc, fl_xfont->fid); + } + XDrawString(fl_display, fl_window, fl_gc, x, y, str, n); +} // -// End of "$Id: fl_font_x.cxx,v 1.10 2002/02/25 09:00:22 spitzak Exp $" +// End of "$Id: fl_font_x.cxx,v 1.10.2.1 2002/03/06 18:11:01 easysw Exp $". // diff --git a/src/fl_font_xft.cxx b/src/fl_font_xft.cxx index a34fbd15c..27a1c817b 100644 --- a/src/fl_font_xft.cxx +++ b/src/fl_font_xft.cxx @@ -1,7 +1,9 @@ // -// "$Id: fl_font_xft.cxx,v 1.4 2001/12/16 22:32:03 spitzak Exp $" +// "$Id: fl_font_xft.cxx,v 1.4.2.1 2002/03/06 18:11:01 easysw Exp $" // -// Copyright 2001 Bill Spitzak and others. +// Xft font code for the Fast Light Tool Kit (FLTK). +// +// Copyright 2001-2002 Bill Spitzak and others. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -18,35 +20,36 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@easysw.com". +// Please report all bugs and problems to "fltk-bugs@fltk.org". // -// Draw fonts using Keith Packard's Xft and Xrender extension. Yow! +// +// Draw fonts using Keith Packard's Xft library to provide anti- +// aliased text. Yow! +// // Many thanks to Carl for making the original version of this. // -// This code is included in fltk if it is compiled with -DUSE_XFT=1 -// It should also be possible to compile this file as a seperate -// shared library, and by using LD_PRELOAD you can insert it between -// any fltk program and the fltk shared library. -// -// This plugin only requires libXft to work. Contrary to popular -// belief there is no need to have freetype, or the Xrender extension -// available to use this code. You will just get normal Xlib fonts -// (Xft calls them "core" fonts) The Xft algorithims for choosing -// these is about as good as the fltk ones (I hope to fix it so it is +// This font code only requires libXft to work. Contrary to popular +// belief there is no need to have FreeType, or the Xrender extension +// available to use this code. You will just get normal Xlib fonts +// (Xft calls them "core" fonts) The Xft algorithms for choosing +// these is about as good as the FLTK ones (I hope to fix it so it is // exactly as good...), plus it can cache it's results and share them // between programs, so using this should be a win in all cases. Also // it should be obvious by comparing this file and fl_font_x.cxx that -// it is a lot easier to program to Xft than to Xlib. +// it is a lot easier to program with Xft than with Xlib. +// +// Also, Xft supports UTF-8 text rendering directly, which will allow +// us to support UTF-8 on all platforms more easily. // // To actually get antialiasing you need the following: // -// 1. You have XFree86 4 -// 2. You have the XRender extension -// 3. Your X device driver supports the render extension -// 4. You have libXft -// 5. Your libXft has freetype2 support compiled in -// 6. You have the freetype2 library +// 1. You have XFree86 4 +// 2. You have the XRender extension +// 3. Your X device driver supports the render extension +// 4. You have libXft +// 5. Your libXft has FreeType2 support compiled in +// 6. You have the FreeType2 library // // Distributions that have XFree86 4.0.3 or later should have all of this... // @@ -55,38 +58,46 @@ // complicated. I belive doing this defeats our ability to improve Xft // itself. You should edit the ~/.xftconfig file to "fix" things, there // are several web pages of information on how to do this. +// -#include -#include -#include -#include #include -#include -#include -class Fl_FontSize { -public: - Fl_FontSize *next; // linked list for this Fl_Fontdesc - XftFont* font; - const char* encoding; - Fl_FontSize(const char* xfontname); - unsigned size; - //~Fl_FontSize(); +// The predefined fonts that FLTK has: +static Fl_Fontdesc built_in_table[] = { +{" sans"}, +{"Bsans"}, +{"Isans"}, +{"Psans"}, +{" mono"}, +{"Bmono"}, +{"Imono"}, +{"Pmono"}, +{" serif"}, +{"Bserif"}, +{"Iserif"}, +{"Pserif"}, +{" symbol"}, +{" screen"}, +{"Bscreen"}, +{" dingbats"}, }; -static Fl_FontSize *fl_fontsize; -#define current_font (fl_fontsize->font) - -// Change the encoding to use for the next font selection. -void fl_encoding(const char* f) { - fl_encoding_ = f; -} +Fl_Fontdesc* fl_fonts = built_in_table; -void fl_font(Fl_Font font, unsigned size) { - if (font == fl_font_ && size == fl_size_ && +#define current_font (fl_fontsize->font) + +int fl_font_; +int fl_size_; +XFontStruct* fl_xfont; +const char* fl_encoding_ = "iso8859-1"; +Fl_FontSize* fl_fontsize; + +void fl_font(int fnum, int size) { + if (fnum == fl_font_ && size == fl_size_ && !strcasecmp(fl_fontsize->encoding, fl_encoding_)) return; - fl_font_ = font; fl_size_ = size; + fl_font_ = fnum; fl_size_ = size; + Fl_Fontdesc *font = fl_fonts + fnum; Fl_FontSize* f; // search the fontsizes we have generated already for (f = font->first; f; f = f->next) { @@ -94,14 +105,16 @@ void fl_font(Fl_Font font, unsigned size) { break; } if (!f) { - f = new Fl_FontSize(font->name_); + f = new Fl_FontSize(font->name); f->next = font->first; - ((Fl_Font_*)font)->first = f; + font->first = f; } fl_fontsize = f; + fl_xfont = f->font->u.core.font; } static XftFont* fontopen(const char* name, bool core) { + fl_open_display(); int slant = XFT_SLANT_ROMAN; int weight = XFT_WEIGHT_MEDIUM; // may be efficient, but this is non-obvious @@ -130,38 +143,32 @@ Fl_FontSize::Fl_FontSize(const char* name) { font = fontopen(name, false); } -// This call is used by opengl to get a bitmapped font. Xft actually does -// a pretty good job of selecting X fonts... -XFontStruct* fl_xfont() { - if (current_font->core) return current_font->u.core.font; - static XftFont* xftfont; - if (xftfont) XftFontClose (fl_display, xftfont); - xftfont = fontopen(fl_font_->name_, true); - return xftfont->u.core.font; -} - -#if 0 // this is never called! Fl_FontSize::~Fl_FontSize() { if (this == fl_fontsize) fl_fontsize = 0; - XftFontClose(fl_display, font); +// XftFontClose(fl_display, font); } -#endif #if 1 // Some of the line spacings these return are insanely big! -int fl_height() { return current_font->height; } +//int fl_height() { return current_font->height; } +int fl_height() { return current_font->ascent + current_font->descent; } int fl_descent() { return current_font->descent; } #else int fl_height() { return fl_size_;} int fl_descent() { return fl_size_/4;} #endif -int fl_width(const char *str, int n) { +double fl_width(const char *str, int n) { XGlyphInfo i; XftTextExtents8(fl_display, current_font, (XftChar8 *)str, n, &i); return i.xOff; } +double fl_width(uchar c) { + return fl_width((const char *)(&c), 1); +} + + #if USE_OVERLAY // Currently Xft does not work with colormapped visuals, so this probably // does not work unless you have a true-color overlay. @@ -187,6 +194,7 @@ void fl_draw(const char *str, int n, int x, int y) { else XftDrawChange(draw, fl_window); #endif + Region region = fl_clip_region(); if (region) { if (XEmptyRegion(region)) return; @@ -196,177 +204,16 @@ void fl_draw(const char *str, int n, int x, int y) { // Use fltk's color allocator, copy the results to match what // XftCollorAllocValue returns: XftColor color; - color.pixel = fl_pixel; - uchar r,g,b; fl_get_color(fl_color_, r,g,b); + color.pixel = fl_xpixel(fl_color_); + uchar r,g,b; Fl::get_color(fl_color_, r,g,b); color.color.red = r*0x101; color.color.green = g*0x101; color.color.blue = b*0x101; color.color.alpha = 0xffff; - XftDrawString8(draw, &color, current_font, x+fl_x_, y+fl_y_, - (XftChar8 *)str, n); -} - -//////////////////////////////////////////////////////////////// - -// The predefined fonts that fltk has: bold: italic: -Fl_Font_ -fl_fonts[] = { -{" sans", fl_fonts+1, fl_fonts+2}, -{"Bsans", fl_fonts+1, fl_fonts+3}, -{"Isans", fl_fonts+3, fl_fonts+2}, -{"Psans", fl_fonts+3, fl_fonts+3}, -{" mono", fl_fonts+5, fl_fonts+6}, -{"Bmono", fl_fonts+5, fl_fonts+7}, -{"Imono", fl_fonts+7, fl_fonts+6}, -{"Pmono", fl_fonts+7, fl_fonts+7}, -{" serif", fl_fonts+9, fl_fonts+10}, -{"Bserif", fl_fonts+9, fl_fonts+11}, -{"Iserif", fl_fonts+11,fl_fonts+10}, -{"Pserif", fl_fonts+11,fl_fonts+11}, -{" symbol", fl_fonts+12,fl_fonts+12}, -{" screen", fl_fonts+14,fl_fonts+14}, -{"Bscreen", fl_fonts+14,fl_fonts+14}, -{" dingbats", fl_fonts+15,fl_fonts+15}, -}; - -//////////////////////////////////////////////////////////////// -// The rest of this is for listing fonts: - -// turn a stored font name into a pretty name: -const char* Fl_Font_::name(int* ap) const { - int type; - switch (name_[0]) { - case 'B': type = FL_BOLD; break; - case 'I': type = FL_ITALIC; break; - case 'P': type = FL_BOLD | FL_ITALIC; break; - default: type = 0; break; - } - if (ap) {*ap = type; return name_+1;} - if (!type) {return name_+1;} - static char *buffer = new char[128]; - strcpy(buffer, name_+1); - if (type & FL_BOLD) strcat(buffer, " bold"); - if (type & FL_ITALIC) strcat(buffer, " italic"); - return buffer; -} - -extern "C" { -static int sort_function(const void *aa, const void *bb) { - const char* name_a = (*(Fl_Font_**)aa)->name_; - const char* name_b = (*(Fl_Font_**)bb)->name_; - int ret = strcasecmp(name_a+1, name_b+1); if (ret) return ret; - return name_a[0]-name_b[0]; // sort by attribute -} -} - -static Fl_Font_* make_a_font(char attrib, const char* name) { - Fl_Font_* newfont = new Fl_Font_; - char *n = new char[strlen(name)+2]; - n[0] = attrib; - strcpy(n+1, name); - newfont->name_ = n; - newfont->bold_ = newfont; - newfont->italic_ = newfont; - newfont->first = 0; - return newfont; -} - -int fl_list_fonts(Fl_Font*& arrayp) { - static Fl_Font *font_array = 0; - static int num_fonts = 0; - - if (font_array) { arrayp = font_array; return num_fonts; } - - XftFontSet *fs; - char *name; - fl_open_display(); - fs = XftListFonts(fl_display, fl_screen, 0, XFT_FAMILY, 0); - num_fonts = fs->nfont; - font_array = (Fl_Font *)calloc(num_fonts, sizeof(Fl_Font *)); - for (int i = 0; i < num_fonts; i++) { - if (XftPatternGetString(fs->fonts[i], XFT_FAMILY, 0, &name) == XftResultMatch) { - Fl_Font_* base = make_a_font(' ', name); - base->italic_ = make_a_font('I', name); - //if (bNeedBold) { - base->bold_ = make_a_font('B', name); - base->italic_->bold_ = base->bold_->italic_ = make_a_font('P', name); - //} - font_array[i] = base; - } - } - XftFontSetDestroy(fs); - - qsort(font_array, num_fonts, sizeof(Fl_Font), sort_function); - - arrayp = font_array; - return num_fonts; -} - -extern "C" { -static int int_sort(const void *aa, const void *bb) { - return (*(int*)aa)-(*(int*)bb); -} -} - -//////////////////////////////////////////////////////////////// - -// Return all the point sizes supported by this font: -// Suprisingly enough Xft works exactly like fltk does and returns -// the same list. Except there is no way to tell if the font is scalable. -int Fl_Font_::sizes(int*& sizep) const { - fl_open_display(); - XftFontSet* fs = XftListFonts(fl_display, fl_screen, - XFT_FAMILY, XftTypeString, name_+1, 0, - XFT_PIXEL_SIZE, 0); - static int* array = 0; - static int array_size = 0; - if (fs->nfont >= array_size) { - delete[] array; - array = new int[array_size = fs->nfont+1]; - } - array[0] = 0; int j = 1; // claim all fonts are scalable - for (int i = 0; i < fs->nfont; i++) { - double v; - if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) { - array[j++] = int(v); - } - } - qsort(array+1, j-1, sizeof(int), int_sort); - XftFontSetDestroy(fs); - sizep = array; - return j; -} - -//////////////////////////////////////////////////////////////// -// Return all the encodings for this font: - -int Fl_Font_::encodings(const char**& arrayp) const { - fl_open_display(); - // we need to keep the previous return value around so the strings are - // not destroyed. - static XftFontSet* fs; - if (fs) XftFontSetDestroy(fs); - fs = XftListFonts(fl_display, fl_screen, - XFT_FAMILY, XftTypeString, name_+1, 0, - XFT_ENCODING, 0); - static const char** array = 0; - static int array_size = 0; - if (fs->nfont > array_size) { - delete[] array; - array = new (const char*)[array_size = fs->nfont]; - } - int j = 0; - for (int i = 0; i < fs->nfont; i++) { - char* v; - if (XftPatternGetString(fs->fonts[i], XFT_ENCODING, 0, &v) == XftResultMatch) { - array[j++] = v; - } - } - arrayp = array; - return j; + XftDrawString8(draw, &color, current_font, x, y, (XftChar8 *)str, n); } // -// End of "$Id: fl_font_xft.cxx,v 1.4 2001/12/16 22:32:03 spitzak Exp $" +// End of "$Id: fl_font_xft.cxx,v 1.4.2.1 2002/03/06 18:11:01 easysw Exp $" // diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx index 251efc3ef..20ca1563a 100644 --- a/src/fl_rect.cxx +++ b/src/fl_rect.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_rect.cxx,v 1.10.2.4.2.7 2002/01/01 15:11:32 easysw Exp $" +// "$Id: fl_rect.cxx,v 1.10.2.4.2.8 2002/03/06 18:11:01 easysw Exp $" // // Rectangle drawing routines for the Fast Light Tool Kit (FLTK). // @@ -373,6 +373,11 @@ void fl_clip_region(Fl_Region r) { fl_restore_clip(); } +// Return the current clip region... +Fl_Region fl_clip_region() { + return rstack[rstackptr]; +} + // Intersect & push a new clip rectangle: void fl_clip(int x, int y, int w, int h) { Fl_Region r; @@ -503,5 +508,5 @@ int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ } // -// End of "$Id: fl_rect.cxx,v 1.10.2.4.2.7 2002/01/01 15:11:32 easysw Exp $". +// End of "$Id: fl_rect.cxx,v 1.10.2.4.2.8 2002/03/06 18:11:01 easysw Exp $". // 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 +#include +#include +#include "Fl_Font.H" +#include +#include +#include #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 -# include -# include "Fl_Font.H" -# include -# include -# include - -// 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= 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 $". // diff --git a/src/fl_set_fonts_mac.cxx b/src/fl_set_fonts_mac.cxx index 6100620e4..fe08805e1 100644 --- a/src/fl_set_fonts_mac.cxx +++ b/src/fl_set_fonts_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_set_fonts_mac.cxx,v 1.1.2.3 2002/01/01 15:11:32 easysw Exp $" +// "$Id: fl_set_fonts_mac.cxx,v 1.1.2.4 2002/03/06 18:11:01 easysw Exp $" // // MacOS font utilities for the Fast Light Tool Kit (FLTK). // @@ -28,13 +28,6 @@ // and to sort them so the first 4 in a family are normal, bold, italic, // and bold italic. -#include -#include -#include "Fl_Font.H" -#include -#include -#include - // turn a stored font name into a pretty name: const char* Fl::get_font_name(Fl_Font fnum, int* ap) { const char* p = fl_fonts[fnum].name; @@ -146,5 +139,5 @@ int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { } // -// End of "$Id: fl_set_fonts_mac.cxx,v 1.1.2.3 2002/01/01 15:11:32 easysw Exp $". +// End of "$Id: fl_set_fonts_mac.cxx,v 1.1.2.4 2002/03/06 18:11:01 easysw Exp $". // diff --git a/src/fl_set_fonts_win32.cxx b/src/fl_set_fonts_win32.cxx index fd319b040..0f5b17dbb 100755 --- a/src/fl_set_fonts_win32.cxx +++ b/src/fl_set_fonts_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_set_fonts_win32.cxx,v 1.5.2.5.2.4 2002/01/01 15:11:32 easysw Exp $" +// "$Id: fl_set_fonts_win32.cxx,v 1.5.2.5.2.5 2002/03/06 18:11:01 easysw Exp $" // // WIN32 font utilities for the Fast Light Tool Kit (FLTK). // @@ -28,13 +28,6 @@ // and to sort them so the first 4 in a family are normal, bold, italic, // and bold italic. -#include -#include -#include "Fl_Font.H" -#include -#include -#include - // turn a stored font name into a pretty name: const char* Fl::get_font_name(Fl_Font fnum, int* ap) { const char* p = fl_fonts[fnum].name; @@ -142,5 +135,5 @@ Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { // -// End of "$Id: fl_set_fonts_win32.cxx,v 1.5.2.5.2.4 2002/01/01 15:11:32 easysw Exp $". +// End of "$Id: fl_set_fonts_win32.cxx,v 1.5.2.5.2.5 2002/03/06 18:11:01 easysw Exp $". // diff --git a/src/fl_set_fonts_x.cxx b/src/fl_set_fonts_x.cxx new file mode 100644 index 000000000..f301ffcbe --- /dev/null +++ b/src/fl_set_fonts_x.cxx @@ -0,0 +1,328 @@ +// +// "$Id: fl_set_fonts_x.cxx,v 1.1.2.1 2002/03/06 18:11:01 easysw Exp $" +// +// X11 font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2002 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// 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. + +// 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. + +// 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= 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 + +// +// End of "$Id: fl_set_fonts_x.cxx,v 1.1.2.1 2002/03/06 18:11:01 easysw Exp $". +// diff --git a/src/fl_set_fonts_xft.cxx b/src/fl_set_fonts_xft.cxx new file mode 100644 index 000000000..34d764aaa --- /dev/null +++ b/src/fl_set_fonts_xft.cxx @@ -0,0 +1,120 @@ +// +// "$Id: fl_set_fonts_xft.cxx,v 1.1.2.1 2002/03/06 18:11:01 easysw Exp $" +// +// More font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2002 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +#include + +// 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. + +// turn a stored font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + const char* p = fl_fonts[fnum].name; + int type; + switch (p[0]) { + case 'B': type = FL_BOLD; break; + case 'I': type = FL_ITALIC; break; + case 'P': type = FL_BOLD | FL_ITALIC; break; + default: type = 0; break; + } + if (ap) {*ap = type; return p+1;} + if (!type) {return p+1;} + static char *buffer = new char[128]; + strcpy(buffer, p+1); + if (type & FL_BOLD) strcat(buffer, " bold"); + if (type & FL_ITALIC) strcat(buffer, " italic"); + return buffer; +} + +#if 0 +extern "C" { +static int sort_function(const void *aa, const void *bb) { + const char* name_a = (*(Fl_Fontdesc**)aa)->name; + const char* name_b = (*(Fl_Fontdesc**)bb)->name; + int ret = strcasecmp(name_a+1, name_b+1); if (ret) return ret; + return name_a[0]-name_b[0]; // sort by attribute +} +} + +static Fl_Fontdesc* make_a_font(char attrib, const char* name) { + Fl_Fontdesc* newfont = new Fl_Fontdesc; + char *n = new char[strlen(name)+2]; + n[0] = attrib; + strcpy(n+1, name); + newfont->name = n; + newfont->first = 0; + return newfont; +} +#endif // 0 + + +Fl_Font Fl::set_fonts(const char* xstarname) { + // TODO: implement this for Xft... + return FL_FREE_FONT; +} + + +extern "C" { +static int int_sort(const void *aa, const void *bb) { + return (*(int*)aa)-(*(int*)bb); +} +} + +//////////////////////////////////////////////////////////////// + +// Return all the point sizes supported by this font: +// Suprisingly enough Xft works exactly like fltk does and returns +// the same list. Except there is no way to tell if the font is scalable. +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 + + fl_open_display(); + XftFontSet* fs = XftListFonts(fl_display, fl_screen, + XFT_FAMILY, XftTypeString, s->name+1, 0, + XFT_PIXEL_SIZE, 0); + static int* array = 0; + static int array_size = 0; + if (fs->nfont >= array_size) { + delete[] array; + array = new int[array_size = fs->nfont+1]; + } + array[0] = 0; int j = 1; // claim all fonts are scalable + for (int i = 0; i < fs->nfont; i++) { + double v; + if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) { + array[j++] = int(v); + } + } + qsort(array+1, j-1, sizeof(int), int_sort); + XftFontSetDestroy(fs); + sizep = array; + return j; +} + +// +// End of "$Id: fl_set_fonts_xft.cxx,v 1.1.2.1 2002/03/06 18:11:01 easysw Exp $". +//