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
This commit is contained in:
Michael R Sweet 2002-03-06 18:11:01 +00:00
parent 394286265a
commit e52b682a99
17 changed files with 788 additions and 1052 deletions

View File

@ -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

5
FL/x.H
View File

@ -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 $".
//

View File

@ -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 $".
*/

View File

@ -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

View File

@ -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 $".
//

View File

@ -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 $".
#

View File

@ -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 <config.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include "Fl_Font.H"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 <config.h>
# include <FL/Fl.H>
# include <FL/fl_draw.H>
# include <FL/x.H>
# include "Fl_Font.H"
# include <ctype.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
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 $".
//

View File

@ -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 <config.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/mac.H>
#include "Fl_Font.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
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 $".
//

View File

@ -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 <config.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/win32.H>
#include "Fl_Font.H"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
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 $".
//

View File

@ -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 <fltk/Fl.h>
#include <fltk/Fl_Font.h>
#include <fltk/x.h>
#include <fltk/fl_draw.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
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 $".
//

View File

@ -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 <fltk/Fl.h>
#include <fltk/Fl_Font.h>
#include <fltk/fl_draw.h>
#include <fltk/x.h>
#include <X11/Xft/Xft.h>
#include <string.h>
#include <stdlib.h>
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 $"
//

View File

@ -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 $".
//

View File

@ -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 $".
//

View File

@ -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 <FL/Fl.H>
#include <FL/mac.H>
#include "Fl_Font.H"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
// 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 $".
//

View File

@ -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 <FL/Fl.H>
#include <FL/win32.H>
#include "Fl_Font.H"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
// 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 $".
//

328
src/fl_set_fonts_x.cxx Normal file
View File

@ -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<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
//
// End of "$Id: fl_set_fonts_x.cxx,v 1.1.2.1 2002/03/06 18:11:01 easysw Exp $".
//

120
src/fl_set_fonts_xft.cxx Normal file
View File

@ -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 <X11/Xft/Xft.h>
// 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 $".
//