2002-02-25 12:00:23 +03:00
|
|
|
//
|
2002-06-08 17:07:19 +04:00
|
|
|
// "$Id: fl_font_xft.cxx,v 1.4.2.7 2002/06/08 13:07:19 easysw Exp $"
|
2002-02-25 12:00:23 +03:00
|
|
|
//
|
2002-03-06 21:11:01 +03:00
|
|
|
// Xft font code for the Fast Light Tool Kit (FLTK).
|
|
|
|
//
|
|
|
|
// Copyright 2001-2002 Bill Spitzak and others.
|
2002-02-25 12:00:23 +03:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//
|
2002-03-06 21:11:01 +03:00
|
|
|
// Please report all bugs and problems to "fltk-bugs@fltk.org".
|
2002-02-25 12:00:23 +03:00
|
|
|
//
|
|
|
|
|
|
|
|
//
|
2002-03-06 21:11:01 +03:00
|
|
|
// 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.
|
2002-02-25 12:00:23 +03:00
|
|
|
//
|
2002-03-06 21:11:01 +03:00
|
|
|
// 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
|
2002-02-25 12:00:23 +03:00
|
|
|
// 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
|
2002-03-06 21:11:01 +03:00
|
|
|
// 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.
|
2002-02-25 12:00:23 +03:00
|
|
|
//
|
|
|
|
// To actually get antialiasing you need the following:
|
|
|
|
//
|
2002-03-06 21:11:01 +03:00
|
|
|
// 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
|
2002-02-25 12:00:23 +03:00
|
|
|
//
|
|
|
|
// Distributions that have XFree86 4.0.3 or later should have all of this...
|
|
|
|
//
|
|
|
|
// Unlike some other Xft packages, I tried to keep this simple and not
|
|
|
|
// to work around the current problems in Xft by making the "patterns"
|
|
|
|
// 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.
|
2002-03-06 21:11:01 +03:00
|
|
|
//
|
2002-02-25 12:00:23 +03:00
|
|
|
|
|
|
|
#include <X11/Xft/Xft.h>
|
|
|
|
|
2002-03-06 21:11:01 +03:00
|
|
|
// 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"},
|
2002-02-25 12:00:23 +03:00
|
|
|
};
|
|
|
|
|
2002-03-06 21:11:01 +03:00
|
|
|
Fl_Fontdesc* fl_fonts = built_in_table;
|
|
|
|
|
2002-02-25 12:00:23 +03:00
|
|
|
#define current_font (fl_fontsize->font)
|
|
|
|
|
2002-06-08 17:07:19 +04:00
|
|
|
int fl_font_ = 0;
|
|
|
|
int fl_size_ = 0;
|
|
|
|
XFontStruct* fl_xfont = 0;
|
2002-03-06 21:11:01 +03:00
|
|
|
const char* fl_encoding_ = "iso8859-1";
|
2002-06-08 17:07:19 +04:00
|
|
|
Fl_FontSize* fl_fontsize = 0;
|
2002-03-06 21:11:01 +03:00
|
|
|
|
|
|
|
void fl_font(int fnum, int size) {
|
|
|
|
if (fnum == fl_font_ && size == fl_size_ &&
|
2002-02-25 12:00:23 +03:00
|
|
|
!strcasecmp(fl_fontsize->encoding, fl_encoding_))
|
|
|
|
return;
|
2002-03-06 21:11:01 +03:00
|
|
|
fl_font_ = fnum; fl_size_ = size;
|
|
|
|
Fl_Fontdesc *font = fl_fonts + fnum;
|
2002-02-25 12:00:23 +03:00
|
|
|
Fl_FontSize* f;
|
|
|
|
// search the fontsizes we have generated already
|
|
|
|
for (f = font->first; f; f = f->next) {
|
|
|
|
if (f->size == size && !strcasecmp(f->encoding, fl_encoding_))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!f) {
|
2002-03-06 21:11:01 +03:00
|
|
|
f = new Fl_FontSize(font->name);
|
2002-02-25 12:00:23 +03:00
|
|
|
f->next = font->first;
|
2002-03-06 21:11:01 +03:00
|
|
|
font->first = f;
|
2002-02-25 12:00:23 +03:00
|
|
|
}
|
|
|
|
fl_fontsize = f;
|
2002-03-06 21:11:01 +03:00
|
|
|
fl_xfont = f->font->u.core.font;
|
2002-02-25 12:00:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static XftFont* fontopen(const char* name, bool core) {
|
2002-03-06 21:11:01 +03:00
|
|
|
fl_open_display();
|
2002-02-25 12:00:23 +03:00
|
|
|
int slant = XFT_SLANT_ROMAN;
|
|
|
|
int weight = XFT_WEIGHT_MEDIUM;
|
|
|
|
// may be efficient, but this is non-obvious
|
|
|
|
switch (*name++) {
|
|
|
|
case 'I': slant = XFT_SLANT_ITALIC; break;
|
|
|
|
case 'P': slant = XFT_SLANT_ITALIC;
|
|
|
|
case 'B': weight = XFT_WEIGHT_BOLD; break;
|
|
|
|
case ' ': break;
|
|
|
|
default: name--;
|
|
|
|
}
|
|
|
|
// this call is extremely slow...
|
|
|
|
return XftFontOpen(fl_display, fl_screen,
|
|
|
|
XFT_FAMILY, XftTypeString, name,
|
|
|
|
XFT_WEIGHT, XftTypeInteger, weight,
|
|
|
|
XFT_SLANT, XftTypeInteger, slant,
|
|
|
|
XFT_ENCODING, XftTypeString, fl_encoding_,
|
|
|
|
XFT_PIXEL_SIZE, XftTypeDouble, (double)fl_size_,
|
|
|
|
core ? XFT_CORE : 0, XftTypeBool, true,
|
|
|
|
XFT_RENDER, XftTypeBool, false,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Fl_FontSize::Fl_FontSize(const char* name) {
|
|
|
|
encoding = fl_encoding_;
|
|
|
|
size = fl_size_;
|
|
|
|
font = fontopen(name, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
Fl_FontSize::~Fl_FontSize() {
|
|
|
|
if (this == fl_fontsize) fl_fontsize = 0;
|
2002-03-06 21:11:01 +03:00
|
|
|
// XftFontClose(fl_display, font);
|
2002-02-25 12:00:23 +03:00
|
|
|
}
|
|
|
|
|
2002-03-06 21:11:01 +03:00
|
|
|
int fl_height() { return current_font->ascent + current_font->descent; }
|
2002-02-25 12:00:23 +03:00
|
|
|
int fl_descent() { return current_font->descent; }
|
|
|
|
|
2002-03-06 21:11:01 +03:00
|
|
|
double fl_width(const char *str, int n) {
|
2002-02-25 12:00:23 +03:00
|
|
|
XGlyphInfo i;
|
|
|
|
XftTextExtents8(fl_display, current_font, (XftChar8 *)str, n, &i);
|
|
|
|
return i.xOff;
|
|
|
|
}
|
|
|
|
|
2002-03-06 21:11:01 +03:00
|
|
|
double fl_width(uchar c) {
|
|
|
|
return fl_width((const char *)(&c), 1);
|
|
|
|
}
|
|
|
|
|
2002-02-25 12:00:23 +03:00
|
|
|
#if USE_OVERLAY
|
|
|
|
// Currently Xft does not work with colormapped visuals, so this probably
|
|
|
|
// does not work unless you have a true-color overlay.
|
|
|
|
extern bool fl_overlay;
|
|
|
|
extern Colormap fl_overlay_colormap;
|
|
|
|
extern XVisualInfo* fl_overlay_visual;
|
|
|
|
#endif
|
|
|
|
|
2002-03-10 00:33:54 +03:00
|
|
|
// For some reason Xft produces errors if you destroy a window whose id
|
|
|
|
// still exists in an XftDraw structure. It would be nice if this is not
|
|
|
|
// true, a lot of junk is needed to try to stop this:
|
|
|
|
|
|
|
|
static XftDraw* draw;
|
|
|
|
static Window draw_window;
|
|
|
|
#if USE_OVERLAY
|
|
|
|
static XftDraw* draw_overlay;
|
|
|
|
static Window draw_overlay_window;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void fl_destroy_xft_draw(Window id) {
|
|
|
|
if (id == draw_window)
|
|
|
|
XftDrawChange(draw, draw_window = fl_message_window);
|
|
|
|
#if USE_OVERLAY
|
|
|
|
if (id == draw_overlay_window)
|
|
|
|
XftDrawChange(draw_overlay, draw_overlay_window = fl_message_window);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2002-02-25 12:00:23 +03:00
|
|
|
void fl_draw(const char *str, int n, int x, int y) {
|
|
|
|
#if USE_OVERLAY
|
2002-03-10 00:33:54 +03:00
|
|
|
XftDraw*& draw = fl_overlay ? draw_overlay : ::draw;
|
|
|
|
if (fl_overlay) {
|
|
|
|
if (!draw)
|
|
|
|
draw = XftDrawCreate(fl_display, draw_overlay_window = fl_window,
|
|
|
|
fl_overlay_visual->visual, fl_overlay_colormap);
|
|
|
|
else //if (draw_overlay_window != fl_window)
|
|
|
|
XftDrawChange(draw, draw_overlay_window = fl_window);
|
|
|
|
} else
|
2002-02-25 12:00:23 +03:00
|
|
|
#endif
|
2002-03-10 00:33:54 +03:00
|
|
|
if (!draw)
|
|
|
|
draw = XftDrawCreate(fl_display, draw_window = fl_window,
|
|
|
|
fl_visual->visual, fl_colormap);
|
|
|
|
else //if (draw_window != fl_window)
|
|
|
|
XftDrawChange(draw, draw_window = fl_window);
|
2002-03-06 21:11:01 +03:00
|
|
|
|
2002-02-25 12:00:23 +03:00
|
|
|
Region region = fl_clip_region();
|
|
|
|
if (region) {
|
|
|
|
if (XEmptyRegion(region)) return;
|
|
|
|
XftDrawSetClip(draw, region);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use fltk's color allocator, copy the results to match what
|
|
|
|
// XftCollorAllocValue returns:
|
|
|
|
XftColor color;
|
2002-03-06 21:11:01 +03:00
|
|
|
color.pixel = fl_xpixel(fl_color_);
|
|
|
|
uchar r,g,b; Fl::get_color(fl_color_, r,g,b);
|
2002-05-16 06:16:17 +04:00
|
|
|
color.color.red = ((int)r)*0x101;
|
|
|
|
color.color.green = ((int)g)*0x101;
|
|
|
|
color.color.blue = ((int)b)*0x101;
|
2002-02-25 12:00:23 +03:00
|
|
|
color.color.alpha = 0xffff;
|
|
|
|
|
2002-03-06 21:11:01 +03:00
|
|
|
XftDrawString8(draw, &color, current_font, x, y, (XftChar8 *)str, n);
|
2002-02-25 12:00:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2002-06-08 17:07:19 +04:00
|
|
|
// End of "$Id: fl_font_xft.cxx,v 1.4.2.7 2002/06/08 13:07:19 easysw Exp $"
|
2002-02-25 12:00:23 +03:00
|
|
|
//
|