diff options
author | Elliot Lee <sopwith@src.gnome.org> | 1997-11-24 22:37:52 +0000 |
---|---|---|
committer | Elliot Lee <sopwith@src.gnome.org> | 1997-11-24 22:37:52 +0000 |
commit | 9508b76bd2401b6b9e289b5c8ec9fc0e08909283 (patch) | |
tree | 53c88a9e5ac09e1a027e56df33bdaa66d670901b /gdk/gdkfont.c | |
download | gdk-pixbuf-9508b76bd2401b6b9e289b5c8ec9fc0e08909283.tar.gz |
Initial revision
Diffstat (limited to 'gdk/gdkfont.c')
-rw-r--r-- | gdk/gdkfont.c | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/gdk/gdkfont.c b/gdk/gdkfont.c new file mode 100644 index 000000000..e1b1e7254 --- /dev/null +++ b/gdk/gdkfont.c @@ -0,0 +1,379 @@ +/* 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 (const 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->type = GDK_FONT_FONT; + font->ascent = ((XFontStruct *) private->xfont)->ascent; + font->descent = ((XFontStruct *) private->xfont)->descent; + } + + gdk_xid_table_insert (&((XFontStruct *) private->xfont)->fid, font); + + return font; +} + +GdkFont* +gdk_fontset_load(gchar *fontset_name) +{ + GdkFont *font; + GdkFontPrivate *private; + XFontSet fontset; + gint missing_charset_count; + gchar **missing_charset_list; + gchar *def_string; + + private = g_new (GdkFontPrivate, 1); + font = (GdkFont*) private; + + private->xdisplay = gdk_display; + fontset = XCreateFontSet (gdk_display, fontset_name, + &missing_charset_list, &missing_charset_count, + &def_string); + + if (missing_charset_count) + { + g_print ("Missing charsets in FontSet creation"); + XFreeStringList (missing_charset_list); + } + + private->ref_count = 1; + + if (!fontset) + { + g_free (font); + return NULL; + } + else + { + XFontSetExtents *extent = XExtentsOfFontSet(fontset); + + private->xfont = fontset; + font->type = GDK_FONT_FONTSET; + /* how to define ascent and descent for fontset ??? */ + font->ascent = extent->max_logical_extent.height; + font->descent = font->ascent / 4 ; + } + 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 (((XFontStruct *) private->xfont)->fid); + XFreeFont (private->xdisplay, (XFontStruct *) private->xfont); + g_free (font); + } +} + +void +gdk_fontset_free (GdkFont *font) +{ + GdkFontPrivate *private; + + g_return_if_fail (font != NULL); + + private = (GdkFontPrivate*) font; + + private->ref_count -= 1; + if (private->ref_count == 0) + { + XFreeFontSet (private->xdisplay, (XFontSet) private->xfont); + g_free (font); + } +} + +GdkFont* +gdk_font_ref (GdkFont *font) +{ + GdkFontPrivate *private; + + g_return_val_if_fail (font != NULL, NULL); + + private = (GdkFontPrivate*) font; + private->ref_count += 1; + return font; +} + +gint +gdk_font_id (GdkFont *font) +{ + GdkFontPrivate *font_private; + + g_return_val_if_fail (font != NULL, 0); + + font_private = (GdkFontPrivate*) font; + + if (font->type == GDK_FONT_FONT) + { + return ((XFontStruct *) font_private->xfont)->fid; + } + else + { + return 0; + } +} + +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; + + if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT) + { + return (((XFontStruct *) privatea->xfont)->fid == + ((XFontStruct *) privateb->xfont)->fid); + } + else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET) + { + /* how to compare two fontsets ?? by basename or XFontSet ?? */ + return (((XFontSet) privatea->xfont) == ((XFontSet) privateb->xfont)); + } + else + /* fontset != font */ + return 0; +} + +gint +gdk_string_width (GdkFont *font, + const gchar *string) +{ + GdkFontPrivate *font_private; + gint width; + XFontStruct *xfont; + XFontSet fontset; + + g_return_val_if_fail (font != NULL, -1); + g_return_val_if_fail (string != NULL, -1); + + font_private = (GdkFontPrivate*) font; + + switch (font->type) + { + case GDK_FONT_FONT: + xfont = (XFontStruct *) font_private->xfont; + if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) + { + width = XTextWidth (xfont, string, strlen (string)); + } + else + { + width = XTextWidth16 (xfont, (XChar2b *) string, strlen (string) / 2); + } + break; + case GDK_FONT_FONTSET: + fontset = (XFontSet) font_private->xfont; + width = XmbTextEscapement (fontset, string, strlen(string)); + break; + default: + width = 0; + } + + return width; +} + +gint +gdk_text_width (GdkFont *font, + const gchar *text, + gint text_length) +{ + GdkFontPrivate *private; + gint width; + XFontStruct *xfont; + XFontSet fontset; + + g_return_val_if_fail (font != NULL, -1); + g_return_val_if_fail (text != NULL, -1); + + private = (GdkFontPrivate*) font; + + switch (font->type) + { + case GDK_FONT_FONT: + xfont = (XFontStruct *) private->xfont; + if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) + { + width = XTextWidth (xfont, text, text_length); + } + else + { + width = XTextWidth16 (xfont, (XChar2b *) text, text_length / 2); + } + break; + case GDK_FONT_FONTSET: + fontset = (XFontSet) private->xfont; + width = XmbTextEscapement (fontset, text, text_length); + break; + default: + width = 0; + } + return width; +} + +/* Problem: What if a character is a 16 bits character ?? */ +gint +gdk_char_width (GdkFont *font, + gchar character) +{ + GdkFontPrivate *private; + XCharStruct *chars; + gint width; + guint ch = character & 0xff; /* get rid of sign-extension */ + XFontStruct *xfont; + XFontSet fontset; + + g_return_val_if_fail (font != NULL, -1); + + private = (GdkFontPrivate*) font; + + switch (font->type) + { + case GDK_FONT_FONT: + /* only 8 bits characters are considered here */ + xfont = (XFontStruct *) private->xfont; + if ((xfont->min_byte1 == 0) && + (xfont->max_byte1 == 0) && + (ch >= xfont->min_char_or_byte2) && + (ch <= xfont->max_char_or_byte2)) + { + chars = xfont->per_char; + if (chars) + width = chars[ch - xfont->min_char_or_byte2].width; + else + width = xfont->min_bounds.width; + } + else + { + width = XTextWidth (xfont, &character, 1); + } + break; + case GDK_FONT_FONTSET: + fontset = (XFontSet) private->xfont; + width = XmbTextEscapement (fontset, &character, 1) ; + break; + default: + width = 0; + } + return width; +} + +gint +gdk_string_measure (GdkFont *font, + const 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, + const gchar *text, + gint text_length) +{ + GdkFontPrivate *private; + XCharStruct overall; + XFontStruct *xfont; + XFontSet fontset; + XRectangle ink, log; + 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; + + switch (font->type) + { + case GDK_FONT_FONT: + xfont = (XFontStruct *) private->xfont; + if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) + { + XTextExtents (xfont, text, text_length, + &direction, &font_ascent, &font_descent, + &overall); + } + else + { + XTextExtents16 (xfont, (XChar2b *) text, text_length / 2, + &direction, &font_ascent, &font_descent, + &overall); + } + width = overall.rbearing; + break; + case GDK_FONT_FONTSET: + fontset = (XFontSet) private->xfont; + XmbTextExtents (fontset, text, text_length, &ink, &log); + width = log.width; + break; + default: + width = 0; + } + 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); +} |