Logo Search packages:      
Sourcecode: sawfish version File versions

fonts.c

/* fonts.c -- font manipulation
   $Id: fonts.c,v 1.43 2004/10/17 22:58:17 jsh Exp $

   Copyright (C) 1999 John Harper <john@dcs.warwick.ac.uk>

   This file is part of sawmill.

   sawmill is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   sawmill 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with sawmill; see the file COPYING.   If not, write to
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */

/* AIX requires this to be the first thing in the file.  */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef __GNUC__
# if HAVE_ALLOCA_H
#  include <alloca.h>
# else
#  ifdef _AIX
 #pragma alloca
#  else
#   ifndef alloca /* predefined by HP cc +Olibcalls */
   char *alloca ();
#   endif
#  endif
# endif
#endif

#include "sawmill.h"
#include <string.h>
#include <X11/Xlocale.h>
#include <ctype.h>

#ifdef HAVE_X11_XFT_XFT_H
# include <X11/Xft/Xft.h>
#else
# undef HAVE_PANGO
#endif

#ifdef HAVE_PANGO
# include <glib.h>
# define PANGO_ENABLE_BACKEND
# include <pango/pango.h>
# undef PANGO_ENABLE_BACKEND
# ifdef HAVE_PANGO_X
#  include <pango/pangox.h>
# endif
# ifdef HAVE_PANGO_XFT
#  define PANGO_ENABLE_ENGINE
#  include <pango/pangoxft.h>
#  undef PANGO_ENABLE_ENGINE
# endif
#endif

static Lisp_Font *font_list;
int font_type;

DEFSYM(default_font, "default-font");

struct Lisp_Font_Class_struct {
    const char *type;
    bool (*load) (Lisp_Font *f);
    void (*finalize) (Lisp_Font *f);
    int (*measure) (Lisp_Font *f, u_char *string, size_t length);
    void (*draw) (Lisp_Font *f, u_char *string, size_t length,
              Window id, GC gc, Lisp_Color *fg, int x, int y);
};


/* Xlib font structs */

static bool
fontstruct_load (Lisp_Font *f)
{
    XFontStruct *font_struct;

    font_struct = XLoadQueryFont (dpy, rep_STR (f->name));

    if (font_struct == 0)
      return FALSE;

    f->font = font_struct;
    f->ascent = font_struct->ascent;
    f->descent = font_struct->descent;

    return TRUE;
}

static void
fontstruct_finalize (Lisp_Font *f)
{
    XFreeFont (dpy, f->font);
}

static int
fontstruct_measure (Lisp_Font *f, u_char *string, size_t length)
{
    return XTextWidth (f->font, string, length);
}

static void
fontstruct_draw (Lisp_Font *f, u_char *string, size_t length,
             Window id, GC gc, Lisp_Color *fg, int x, int y)
{
    XFontStruct *fs;
    XGCValues gcv;

    fs = f->font;

    gcv.foreground = fg->pixel;
    gcv.font = fs->fid;
    XChangeGC (dpy, gc, GCForeground | GCFont, &gcv);

    XDrawString (dpy, id, gc, x, y, string, length);
}

static const Lisp_Font_Class fontstruct_class = {
    "xlfd",
    fontstruct_load, fontstruct_finalize,
    fontstruct_measure, fontstruct_draw,
};


/* Xlib font sets */

static char *
xlfd_get_element (const char *xlfd, int idx)
{
    const char *p = xlfd;
    while (*p != 0)
    {
      if (*p == '-' && --idx == 0)
      {
          const char *end = strchr (p + 1, '-');
          char *buf;
          size_t len;
          if (end == 0)
            end = p + strlen (p);
          len = end - (p + 1);
          buf = malloc (len);
          memcpy (buf, p + 1, len);
          buf[len] = 0;
          return buf;
      }
      p++;
    }
    return 0;
}

static char *
generalize_xlfd (const char *xlfd)
{
    char *weight = xlfd_get_element (xlfd, 3);
    char *slant = xlfd_get_element (xlfd, 4);
    char *pxlsz = xlfd_get_element (xlfd, 7);

    char *buf;
    int len;

    if (weight == 0)
      weight = strdup ("*");
    if (slant == 0)
      slant = strdup ("*");
    if (pxlsz == 0)
      pxlsz = strdup ("*");

#define XLFD_FORMAT "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*," \
                "-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*"

    len = strlen (xlfd) + strlen (weight) + strlen (slant) +
          strlen (pxlsz) + strlen (pxlsz) + strlen (XLFD_FORMAT);
    buf = malloc (len + 1);
#ifdef HAVE_SNPRINTF
    snprintf (buf, len + 1, XLFD_FORMAT, xlfd, weight, slant, pxlsz, pxlsz);
#else
    sprintf (buf, XLFD_FORMAT, xlfd, weight, slant, pxlsz, pxlsz);
#endif

    free (pxlsz);
    free (slant);
    free (weight);

    return buf;
}

static XFontSet
x_create_fontset (char *xlfd, char ***missing,
               int *nmissing, char **def_string)
{
    XFontSet fs = XCreateFontSet (dpy, xlfd, missing, nmissing, def_string);

    if (fs != 0 && *nmissing == 0)
      return fs;

    /* for non-iso8859-1 language and iso8859-1 specification
       (this fontset is only for pattern analysis) */

    if (fs == 0)
    {
      char *old_locale, *tem;

      if (*nmissing != 0)
          XFreeStringList (*missing);

      /* Save the old LC_CTYPE locale.. */
      tem = setlocale (LC_CTYPE, 0);
      if (tem != 0)
      {
          old_locale = alloca (strlen (tem) + 1);
          strcpy (old_locale, tem);

          /* ..then create the fontset in the default locale.. */
          setlocale (LC_CTYPE, "C");
      }
      else
          old_locale = 0;

      fs = XCreateFontSet (dpy, xlfd, missing, nmissing, def_string);

      /* ..then restore the original locale */
      if (old_locale != 0)
          setlocale (LC_CTYPE, old_locale);
    }

    /* make XLFD font name for pattern analysis */
    if (fs != 0)
    {
      XFontStruct **fontstructs;
      char **fontnames;
      if (XFontsOfFontSet (fs, &fontstructs, &fontnames) > 0)
          xlfd = fontnames[0];
    }

    xlfd = generalize_xlfd (xlfd);

    if (*nmissing != 0)
      XFreeStringList (*missing);
    if (fs != 0)
      XFreeFontSet (dpy, fs);

    fs = XCreateFontSet (dpy, xlfd, missing, nmissing, def_string);

    free (xlfd);
    return fs;
}

static bool
fontset_load (Lisp_Font *f)
{
    XFontSet font_set;
    int ascent, descent;

    char **missing_charset_list, *def_string;
    int num_missing_charset_list;

    font_set = x_create_fontset (rep_STR (f->name),
                         &missing_charset_list,
                         &num_missing_charset_list,
                         &def_string);

    if (font_set != 0)
    {
      XFontStruct **fstrs;
      char **font_names;
      int i, j, num_fonts;

      f->font = font_set;

      num_fonts = XFontsOfFontSet (font_set, &fstrs, &font_names);
      ascent = descent = 0;

      for (i = 0; i < num_fonts; i++)
      {
          if (fstrs[i]->ascent > ascent)
            f->ascent = fstrs[i]->ascent;
          if (fstrs[i]->descent > descent)
            f->descent = fstrs[i]->descent;
      }

      if (num_missing_charset_list > 0)
      {
          fprintf (stderr, "Missing charsets in FontSet creation\n");
          for (j = 0; j < num_missing_charset_list; j++)
            fprintf (stderr, "\t%s\n", missing_charset_list[j]);
          XFreeStringList (missing_charset_list);
      }

      return TRUE;
    }

    return FALSE;
}

static void
fontset_finalize (Lisp_Font *f)
{
    XFreeFontSet (dpy, f->font);
}

static int
fontset_measure (Lisp_Font *f, u_char *string, size_t length)
{
    return XmbTextEscapement (f->font, string, length);
}

static void
fontset_draw (Lisp_Font *f, u_char *string, size_t length,
            Window id, GC gc, Lisp_Color *fg, int x, int y)
{
    XGCValues gcv;

    gcv.foreground = fg->pixel;
    XChangeGC (dpy, gc, GCForeground, &gcv);

    XmbDrawString (dpy, id, f->font, gc, x, y, string, length);
}

static const Lisp_Font_Class fontset_class = {
    "xlfd",
    fontset_load, fontset_finalize,
    fontset_measure, fontset_draw,
};


/* Xft fonts */

#ifdef HAVE_X11_XFT_XFT_H

static bool
xft_load (Lisp_Font *f)
{
    XftFont *xft_font;

    xft_font = XftFontOpenName (dpy, screen_num, rep_STR (f->name));

    if (xft_font == 0)
      return FALSE;

    f->font = xft_font;
    f->ascent = xft_font->ascent;
    f->descent = xft_font->descent;

    return TRUE;
}

static void
xft_finalize (Lisp_Font *f)
{
    XftFontClose (dpy, f->font);
}

static int
xft_measure (Lisp_Font *f, u_char *string, size_t length)
{
    XGlyphInfo info;

    XftTextExtents8 (dpy, f->font, string, length, &info);

    return info.xOff; 
}

static void
xft_draw (Lisp_Font *f, u_char *string, size_t length,
        Window id, GC gc, Lisp_Color *fg, int x, int y)
{
    static XftDraw *draw;

    XftColor xft_color;

    if (draw == 0)
      draw = XftDrawCreate (dpy, id, image_visual, image_cmap);
    else
      XftDrawChange (draw, id);

    xft_color.pixel = fg->pixel;
    xft_color.color.red = fg->red;
    xft_color.color.green = fg->green;
    xft_color.color.blue = fg->blue;
    xft_color.color.alpha = fg->alpha;

    XftDrawString8 (draw, &xft_color, f->font,
                x, y, string, length);
}

static const Lisp_Font_Class xft_class = {
    "Xft",
    xft_load, xft_finalize,
    xft_measure, xft_draw,
};

#endif /* HAVE_X11_XFT_XFT_H */


/* Pango fonts */

#ifdef HAVE_PANGO

static PangoContext *pango_context;

static bool
pango_load (Lisp_Font *f)
{
    PangoLanguage *language;
    PangoFontDescription *fontdesc;
    PangoFont *font;
    PangoFontMetrics *metrics;

    if (pango_context)
    {
      language = pango_context_get_language (pango_context);
    }
    else
    {
      char *langname, *p;

#ifdef HAVE_PANGO_XFT
      pango_context = pango_xft_get_context (dpy, screen_num);
#else
      pango_context = pango_x_get_context (dpy, screen_num);
#endif

      langname = g_strdup (setlocale (LC_CTYPE, NULL));
      p = strchr (langname, '.');
      if (p)
          *p = 0;
      p = strchr (langname, '@');
      if (p)
          *p = 0;
      language = pango_language_from_string (langname);
      pango_context_set_language (pango_context, language);
      g_free (langname);
    }

    fontdesc = pango_font_description_from_string (rep_STR (f->name));

    if (!pango_font_description_get_family (fontdesc))
      pango_font_description_set_family (fontdesc, "Sans");
    if (pango_font_description_get_size (fontdesc) <= 0)
      pango_font_description_set_size (fontdesc, 12 * PANGO_SCALE);

    pango_context_set_font_description (pango_context, fontdesc);
    font = pango_context_load_font (pango_context, fontdesc);

    if (!font)
      return FALSE;

    metrics = pango_font_get_metrics (font, language);

    f->font = font;
    f->ascent = metrics->ascent / PANGO_SCALE;
    f->descent = metrics->descent / PANGO_SCALE;

    pango_font_metrics_unref (metrics);

    return TRUE;
}

static void
pango_finalize (Lisp_Font *f)
{
    g_object_unref (f->font);
}

static int
pango_measure (Lisp_Font *f, u_char *string, size_t length)
{
    gsize r, w;
    u_char *utf8str;
    PangoLayout *layout;
    PangoRectangle rect;

    utf8str = g_locale_to_utf8 (string, length, &r, &w, NULL);
    if (utf8str != NULL)
    {
      string = utf8str;
      length = w;
    }

    layout = pango_layout_new (pango_context);
    pango_layout_set_text (layout, string, length);

    pango_layout_get_extents (layout, NULL, &rect);

    g_free (utf8str);
    g_object_unref (layout);
 
    return rect.width / PANGO_SCALE;
}

static void
pango_draw_line (XftDraw *draw, Window id, GC gc, XftColor *xft_color,
             PangoLayoutLine *line, int x, int y)
{
    GSList *p;

    for (p = line->runs; p != NULL; p = p->next)
    {
      PangoLayoutRun *run = p->data;
      PangoFont *font = run->item->analysis.font;
      PangoGlyphString *glyphs = run->glyphs;
      PangoRectangle rect;

      pango_glyph_string_extents (glyphs, font, NULL, &rect);
#ifdef HAVE_PANGO_XFT
      if (PANGO_XFT_IS_FONT (font))
          pango_xft_render (draw, xft_color, font, glyphs, x, y);
      else
#endif
          pango_x_render (dpy, id, gc, font, glyphs, x, y);

      x += rect.width / PANGO_SCALE;
    }
}

static void
pango_draw (Lisp_Font *f, u_char *string, size_t length,
          Window id, GC gc, Lisp_Color *fg, int x, int y)
{
    static XftDraw *draw;
    XftColor xft_color;
    gsize r, w;
    u_char *utf8str;
    PangoLayout *layout;
    PangoLayoutIter *iter;

    if (draw == 0)
      draw = XftDrawCreate (dpy, id, image_visual, image_cmap);
    else
      XftDrawChange (draw, id);

    xft_color.pixel = fg->pixel;
    xft_color.color.red = fg->red;
    xft_color.color.green = fg->green;
    xft_color.color.blue = fg->blue;
    xft_color.color.alpha = fg->alpha;

    utf8str = g_locale_to_utf8 (string, length, &r, &w, NULL);
    if (utf8str != NULL)
    {
      string = utf8str;
      length = w;
    }

    layout = pango_layout_new (pango_context);
    pango_layout_set_text (layout, string, length);
    iter = pango_layout_get_iter (layout);

    do {
      PangoLayoutLine *line = pango_layout_iter_get_line (iter);
      PangoRectangle rect;

      pango_layout_iter_get_line_extents (iter, NULL, &rect);
      pango_draw_line (draw, id, gc, &xft_color,
                   line, x + rect.x / PANGO_SCALE, y);
    } while (pango_layout_iter_next_line (iter));

    g_free (utf8str);
    g_object_unref (layout);
    pango_layout_iter_free (iter);
}

static const Lisp_Font_Class pango_class = {
    "pango",
    pango_load, pango_finalize,
    pango_measure, pango_draw,
};

#endif /* HAVE_PANGO */


/* All classes */

static const Lisp_Font_Class *classes[] = {
    &fontstruct_class,
    &fontset_class,
#ifdef HAVE_X11_XFT_XFT_H
    &xft_class,
#endif
#ifdef HAVE_PANGO
    &pango_class,
#endif
    0,
};


/* Entry points */

DEFUN ("font-type-exists-p", Ffont_type_exists_p,
       Sfont_type_exists_p, (repv type), rep_Subr1) /*
::doc:sawfish.wm.fonts#font-type-exists-p::
font-type-exists-p TYPE

Returns true if fonts with the type described by the string TYPE can be
loaded.
::end:: */
{
    int i;

    rep_DECLARE1 (type, rep_STRINGP);

    for (i = 0; classes[i] != 0; i++)
    {
      if (strcasecmp (rep_STR (type), classes[i]->type) == 0)
          return Qt;
    }

    return Qnil;
}

DEFUN("get-font-typed", Fget_font_typed, Sget_font_typed,
      (repv type, repv name), rep_Subr2) /*
::doc:sawfish.wm.fonts#get-font-typed::
get-font-typed TYPE NAME

Return the font object representing the font named NAME. NAME is
interpreted based on the value of the string TYPE.
::end:: */
{
    Lisp_Font *f;
    const Lisp_Font_Class *class;
    repv tem;
    int i;

    rep_DECLARE1(name, rep_STRINGP);
    rep_DECLARE2(type, rep_STRINGP);

    if (dpy == 0)
      return Qnil;

    for (f = font_list; f != NULL; f = f->next)
    {
      if (strcmp (rep_STR(name), rep_STR(f->name)) == 0
          && strcmp (rep_STR (type), rep_STR (f->type)) == 0)
      {
          return rep_VAL (f);
      }
    }

    class = 0;

    if (strcasecmp (rep_STR (type), "xlfd") == 0)
    {
      /* Boring old X core fonts */

      tem = global_symbol_value (Qfonts_are_fontsets);
      if (tem != Qnil)
          class = &fontset_class;
      else
          class = &fontstruct_class;
    }
    else
    {
      for (i = 0; classes[i] != 0; i++)
      {
          if (strcasecmp (rep_STR (type), classes[i]->type) == 0)
          {
            class = classes[i];
            break;
          }
      }
    }

    if (class == 0)
    {
      DEFSTRING (err, "unknown font type");
      return Fsignal (Qerror, rep_list_2 (rep_VAL (&err), type));
    }
      
    f = rep_ALLOC_CELL(sizeof(Lisp_Font));

    f->car = font_type;
    f->class = class;
    f->type = type;
    f->name = name;
    f->plist = Qnil;

    if (!(*class->load) (f))
    {
      DEFSTRING (err, "unknown font");

      rep_FREE_CELL (f);
      return Fsignal (Qerror, rep_list_2 (rep_VAL (&err), name));
    }

    rep_data_after_gc += sizeof (Lisp_Font);

    f->next = font_list;
    font_list = f;

    return rep_VAL (f);
}

DEFUN("get-font", Fget_font, Sget_font, (repv name), rep_Subr1) /*
::doc:sawfish.wm.fonts#get-font::
get-font NAME

Return the font object representing the font named NAME (a standard X
font specifier string).
::end:: */
{
    DEFSTRING (type, "xlfd");

    return Fget_font_typed (rep_VAL (&type), name);
}

DEFUN("font-get", Ffont_get, Sfont_get, (repv win, repv prop), rep_Subr2) /*
::doc:sawfish.wm.fonts#font-get::
font-get FONT PROPERTY

Return the property PROPERTY (a symbol) associated with FONT.
::end:: */
{
    repv plist;
    rep_DECLARE1(win, FONTP);
    plist = VFONT(win)->plist;
    while (rep_CONSP(plist) && rep_CONSP(rep_CDR(plist)))
    {
      if (rep_CAR(plist) == prop
          || (!rep_SYMBOLP(prop)
            && rep_value_cmp (rep_CAR(plist), prop) == 0))
      {
          return rep_CAR(rep_CDR(plist));
      }
      plist = rep_CDR(rep_CDR(plist));
    }
    return Qnil;
}

DEFUN("font-put", Ffont_put, Sfont_put, (repv win, repv prop, repv val), rep_Subr3) /*
::doc:sawfish.wm.fonts#font-put::
font-put FONT PROPERTY VALUE

Set the property PROPERTY (a symbol) associated with FONT to VALUE.
::end:: */
{
    repv plist;
    rep_DECLARE1(win, FONTP);
    plist = VFONT(win)->plist;
    while (rep_CONSP(plist) && rep_CONSP(rep_CDR(plist)))
    {
      if (rep_CAR(plist) == prop
          || (!rep_SYMBOLP(prop)
            && rep_value_cmp (rep_CAR(plist), prop) == 0))
      {
          rep_CAR(rep_CDR(plist)) = val;
          return val;
      }
      plist = rep_CDR(rep_CDR(plist));
    }
    plist = Fcons(prop, Fcons(val, VFONT(win)->plist));
    if (plist != rep_NULL)
      VFONT(win)->plist = plist;
    return val;
}

DEFUN("font-type", Ffont_type, Sfont_type, (repv font), rep_Subr1) /*
::doc:sawfish.wm.fonts#font-type::
font-type FONT

Return the type of the font represented by the font object FONT.
::end:: */
{
    rep_DECLARE1(font, FONTP);
    return VFONT(font)->type;
}

DEFUN("font-name", Ffont_name, Sfont_name, (repv font), rep_Subr1) /*
::doc:sawfish.wm.fonts#font-name::
font-name FONT

Return the name of the font represented by the font object FONT.
::end:: */
{
    rep_DECLARE1(font, FONTP);
    return VFONT(font)->name;
}

DEFUN("fontp", Ffontp, Sfontp, (repv win), rep_Subr1) /*
::doc:sawfish.wm.fonts#fontp::
fontp ARG

Return t if ARG is a font object.
::end:: */
{
    return FONTP(win) ? Qt : Qnil;
}

int
x_text_width (repv font, u_char *string, size_t len)
{
    return (*VFONT (font)->class->measure) (VFONT (font), string, len);
}

/* The foreground pixel of GC is undefined after this function returns. */
void
x_draw_string (Window id, repv font, GC gc, Lisp_Color *fg_color,
             int x, int y, u_char *string, size_t len)
{
    (*VFONT (font)->class->draw) (VFONT (font), string, len,
                          id, gc, fg_color, x, y);
}

DEFUN("text-width", Ftext_width, Stext_width, (repv string, repv font), rep_Subr2) /*
::doc:sawfish.wm.fonts#text-width::
text-width STRING [FONT]

Return the number of horizontal pixels that would be required to display
the text STRING using font object FONT (or the default-font).
::end:: */
{
    rep_DECLARE1(string, rep_STRINGP);
    if (font == Qnil)
      font = global_symbol_value (Qdefault_font);
    rep_DECLARE2(font, FONTP);
    return rep_MAKE_INT (x_text_width (font, rep_STR(string),
                               rep_STRING_LEN(string)));
}

DEFUN("font-height", Ffont_height, Sfont_height, (repv font), rep_Subr1) /*
::doc:sawfish.wm.fonts#font-height::
font-height [FONT]

Return the bounding height of glyphs rendered using FONT (or the
default-font).
::end:: */
{
    if (font == Qnil)
      font = global_symbol_value (Qdefault_font);
    rep_DECLARE1(font, FONTP);
    return rep_MAKE_INT(VFONT(font)->ascent + VFONT(font)->descent);
}

DEFUN("font-ascent", Ffont_ascent, Sfont_ascent, (repv font), rep_Subr1) /*
::doc:sawfish.wm.fonts#font-ascent::
font-ascent [FONT]

Return the ascent of glyphs rendered using FONT (or the
default-font).
::end:: */
{
    if (font == Qnil)
      font = global_symbol_value (Qdefault_font);
    rep_DECLARE1(font, FONTP);
    return rep_MAKE_INT(VFONT(font)->ascent);
}

DEFUN("font-descent", Ffont_descent, Sfont_descent, (repv font), rep_Subr1) /*
::doc:sawfish.wm.fonts#font-descent::
font-descent [FONT]

Return the descent of glyphs rendered using FONT (or the
default-font).
::end:: */
{
    if (font == Qnil)
      font = global_symbol_value (Qdefault_font);
    rep_DECLARE1(font, FONTP);
    return rep_MAKE_INT(VFONT(font)->descent);
}


/* type hooks */

static int
font_cmp (repv w1, repv w2)
{
    return w1 != w2;
}

static void
font_prin (repv stream, repv obj)
{
    char buf[256];
    sprintf (buf, "#<font %s:%s>",
           rep_STR(VFONT(obj)->type), rep_STR(VFONT(obj)->name));
    rep_stream_puts (stream, buf, -1, FALSE);
}

static void
font_mark (repv obj)
{
    rep_MARKVAL(VFONT(obj)->type);
    rep_MARKVAL(VFONT(obj)->name);
    rep_MARKVAL(VFONT(obj)->plist);
}

static void
font_sweep (void)
{
    Lisp_Font *w = font_list;
    font_list = 0;
    while (w != 0)
    {
      Lisp_Font *next = w->next;

      if (!rep_GC_CELL_MARKEDP(rep_VAL(w)))
      {
          (*w->class->finalize) (w);
          rep_FREE_CELL(w);
      }
      else
      {
          rep_GC_CLR_CELL(rep_VAL(w));
          w->next = font_list;
          font_list = w;
      }
      w = next;
    }
}

static int
use_xft (void)
{
    char *val = getenv ("GDK_USE_XFT");

    return val == NULL || strcmp (val, "0") != 0;
}


/* initialisation */

void
fonts_init (void)
{
    repv tem = rep_push_structure ("sawfish.wm.fonts");
    font_type = rep_register_new_type ("font", font_cmp, font_prin, font_prin,
                               font_sweep, font_mark,
                               0, 0, 0, 0, 0, 0, 0);

    rep_ADD_SUBR(Sfont_type_exists_p);
    rep_ADD_SUBR(Sget_font_typed);
    rep_ADD_SUBR(Sget_font);
    rep_ADD_SUBR(Sfont_get);
    rep_ADD_SUBR(Sfont_put);
    rep_ADD_SUBR(Sfont_type);
    rep_ADD_SUBR(Sfont_name);
    rep_ADD_SUBR(Sfontp);
    rep_ADD_SUBR(Stext_width);
    rep_ADD_SUBR(Sfont_height);
    rep_ADD_SUBR(Sfont_ascent);
    rep_ADD_SUBR(Sfont_descent);

    rep_INTERN_SPECIAL(default_font);
    if (!batch_mode_p ())
    {
      DEFSTRING (xlfd_type, "xlfd");
      DEFSTRING (xlfd_name, "fixed");
      DEFSTRING (xft_type, "Xft");
      DEFSTRING (xft_name, "Sans");
      DEFSTRING (pango_type, "Pango");
      DEFSTRING (pango_name, "Sans");

      repv font = Qnil;

      if (use_xft ())
      {
#ifdef HAVE_PANGO
          font = Fget_font_typed (rep_VAL (&pango_type),
                            rep_VAL (&pango_name));
          if (font == rep_NULL || !FONTP (font))
#endif
          {
            font = Fget_font_typed (rep_VAL (&xft_type),
                              rep_VAL (&xft_name));
          }
      }

      if (font == rep_NULL || !FONTP (font))
      {
          font = Fget_font_typed (rep_VAL (&xlfd_type),
                            rep_VAL (&xlfd_name));
      }

      if (font == rep_NULL || !FONTP(font))
      {
          fputs ("can't load default font during initialisation", stderr);
          rep_throw_value = rep_NULL;
          font = Qnil;
      }

      Fset (Qdefault_font, font);
    }
    rep_pop_structure (tem);
}

void
fonts_kill (void)
{
}

Generated by  Doxygen 1.6.0   Back to index