/* GDK - The GIMP Drawing Kit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <X11/Xlib.h>
#include <X11/Xos.h>
#include "gdk.h"
#include "gdkprivate.h"


GdkFont*
gdk_font_load (gchar *font_name)
{
  GdkFont *font;
  GdkFontPrivate *private;

  private = g_new (GdkFontPrivate, 1);
  font = (GdkFont*) private;

  private->xdisplay = gdk_display;
  private->xfont = XLoadQueryFont (private->xdisplay, font_name);
  private->ref_count = 1;

  if (!private->xfont)
    {
      g_free (font);
      return NULL;
    }
  else
    {
      font->ascent = private->xfont->ascent;
      font->descent = private->xfont->descent;
    }

  gdk_xid_table_insert (&private->xfont->fid, font);

  return font;
}

void
gdk_font_free (GdkFont *font)
{
  GdkFontPrivate *private;

  g_return_if_fail (font != NULL);

  private = (GdkFontPrivate*) font;

  private->ref_count -= 1;
  if (private->ref_count == 0)
    {
      gdk_xid_table_remove (private->xfont->fid);
      XFreeFont (private->xdisplay, private->xfont);
      g_free (font);
    }
}

void
gdk_font_ref (GdkFont *font)
{
  GdkFontPrivate *private;

  g_return_if_fail (font != NULL);

  private = (GdkFontPrivate*) font;
  private->ref_count += 1;
}

gint
gdk_font_id (GdkFont *font)
{
  g_return_val_if_fail (font != NULL, 0);

  return ((GdkFontPrivate*) font)->xfont->fid;
}

gint
gdk_font_equal (GdkFont *fonta,
                GdkFont *fontb)
{
  GdkFontPrivate *privatea;
  GdkFontPrivate *privateb;

  g_return_val_if_fail (fonta != NULL, FALSE);
  g_return_val_if_fail (fontb != NULL, FALSE);

  privatea = (GdkFontPrivate*) fonta;
  privateb = (GdkFontPrivate*) fontb;

  return (privatea->xfont->fid == privateb->xfont->fid);
}

gint
gdk_string_width (GdkFont *font,
		  gchar   *string)
{
  GdkFontPrivate *private;
  gint width;

  g_return_val_if_fail (font != NULL, -1);
  g_return_val_if_fail (string != NULL, -1);

  private = (GdkFontPrivate*) font;
  width = XTextWidth (private->xfont, string, strlen (string));

  return width;
}

gint
gdk_text_width (GdkFont  *font,
		gchar    *text,
		gint      text_length)
{
  GdkFontPrivate *private;
  gint width;

  g_return_val_if_fail (font != NULL, -1);
  g_return_val_if_fail (text != NULL, -1);

  private = (GdkFontPrivate*) font;
  width = XTextWidth (private->xfont, text, text_length);

  return width;
}

gint
gdk_char_width (GdkFont *font,
		gchar    character)
{
  GdkFontPrivate *private;
  XCharStruct *chars;
  gint width;

  g_return_val_if_fail (font != NULL, -1);

  private = (GdkFontPrivate*) font;

  if ((private->xfont->min_byte1 == 0) &&
      (private->xfont->max_byte1 == 0) &&
      (character >= private->xfont->min_char_or_byte2) &&
      (character <= private->xfont->max_char_or_byte2))
    {
      chars = private->xfont->per_char;
      if (chars)
	width = chars[character - private->xfont->min_char_or_byte2].width;
      else
	width = private->xfont->min_bounds.width;
    }
  else
    {
      width = XTextWidth (private->xfont, &character, 1);
    }

  return width;
}

gint
gdk_string_measure (GdkFont *font,
                    gchar   *string)
{
  g_return_val_if_fail (font != NULL, -1);
  g_return_val_if_fail (string != NULL, -1);

  return gdk_text_measure (font, string, strlen (string));
}

gint
gdk_text_measure (GdkFont *font,
                  gchar   *text,
                  gint     text_length)
{
  GdkFontPrivate *private;
  XCharStruct overall;
  int direction;
  int font_ascent;
  int font_descent;
  gint width;

  g_return_val_if_fail (font != NULL, -1);
  g_return_val_if_fail (text != NULL, -1);

  private = (GdkFontPrivate*) font;

  XTextExtents (private->xfont, text, text_length,
                &direction, &font_ascent, &font_descent,
                &overall);

  width = overall.rbearing;

  return width;
}

gint
gdk_char_measure (GdkFont *font,
                  gchar    character)
{
  g_return_val_if_fail (font != NULL, -1);

  return gdk_text_measure (font, &character, 1);
}
