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:
parent
394286265a
commit
e52b682a99
2
CHANGES
2
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
|
||||
|
5
FL/x.H
5
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 $".
|
||||
//
|
||||
|
12
configh.in
12
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 $".
|
||||
*/
|
||||
|
12
configure.in
12
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
|
||||
|
@ -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 $".
|
||||
//
|
||||
|
11
src/Makefile
11
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 $".
|
||||
#
|
||||
|
271
src/fl_font.cxx
271
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 <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 $".
|
||||
//
|
||||
|
@ -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 $".
|
||||
//
|
||||
|
@ -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 $".
|
||||
//
|
||||
|
@ -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 $".
|
||||
//
|
||||
|
@ -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 $"
|
||||
//
|
||||
|
@ -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 $".
|
||||
//
|
||||
|
@ -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 $".
|
||||
//
|
||||
|
@ -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 $".
|
||||
//
|
||||
|
@ -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
328
src/fl_set_fonts_x.cxx
Normal 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
120
src/fl_set_fonts_xft.cxx
Normal 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 $".
|
||||
//
|
Loading…
Reference in New Issue
Block a user