1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gdkprivate.h"
25 gdk_font_load (const gchar *font_name)
28 GdkFontPrivate *private;
30 private = g_new (GdkFontPrivate, 1);
31 font = (GdkFont*) private;
33 private->xdisplay = gdk_display;
34 private->xfont = XLoadQueryFont (private->xdisplay, font_name);
35 private->ref_count = 1;
44 font->type = GDK_FONT_FONT;
45 font->ascent = ((XFontStruct *) private->xfont)->ascent;
46 font->descent = ((XFontStruct *) private->xfont)->descent;
49 gdk_xid_table_insert (&((XFontStruct *) private->xfont)->fid, font);
55 gdk_fontset_load (gchar *fontset_name)
58 GdkFontPrivate *private;
60 gint missing_charset_count;
61 gchar **missing_charset_list;
64 private = g_new (GdkFontPrivate, 1);
65 font = (GdkFont*) private;
67 private->xdisplay = gdk_display;
68 fontset = XCreateFontSet (gdk_display, fontset_name,
69 &missing_charset_list, &missing_charset_count,
72 if (missing_charset_count)
75 g_message ("Missing charsets in FontSet creation\n");
76 for (i=0;i<missing_charset_count;i++)
77 g_message (" %s\n", missing_charset_list[i]);
78 XFreeStringList (missing_charset_list);
81 private->ref_count = 1;
92 XFontStruct **font_structs;
95 private->xfont = fontset;
96 font->type = GDK_FONT_FONTSET;
97 num_fonts = XFontsOfFontSet (fontset, &font_structs, &font_names);
99 font->ascent = font->descent = 0;
101 for (i = 0; i < num_fonts; i++)
103 font->ascent = MAX (font->ascent, font_structs[i]->ascent);
104 font->descent = MAX (font->descent, font_structs[i]->descent);
111 gdk_font_ref (GdkFont *font)
113 GdkFontPrivate *private;
115 g_return_val_if_fail (font != NULL, NULL);
117 private = (GdkFontPrivate*) font;
118 private->ref_count += 1;
123 gdk_font_unref (GdkFont *font)
125 GdkFontPrivate *private;
127 g_return_if_fail (font != NULL);
129 private = (GdkFontPrivate*) font;
131 private->ref_count -= 1;
132 if (private->ref_count == 0)
137 gdk_xid_table_remove (((XFontStruct *) private->xfont)->fid);
138 XFreeFont (private->xdisplay, (XFontStruct *) private->xfont);
140 case GDK_FONT_FONTSET:
141 XFreeFontSet (private->xdisplay, (XFontSet) private->xfont);
144 g_error ("unknown font type.");
152 gdk_font_id (const GdkFont *font)
154 const GdkFontPrivate *font_private;
156 g_return_val_if_fail (font != NULL, 0);
158 font_private = (const GdkFontPrivate*) font;
160 if (font->type == GDK_FONT_FONT)
162 return ((XFontStruct *) font_private->xfont)->fid;
171 gdk_font_equal (const GdkFont *fonta,
172 const GdkFont *fontb)
174 const GdkFontPrivate *privatea;
175 const GdkFontPrivate *privateb;
177 g_return_val_if_fail (fonta != NULL, FALSE);
178 g_return_val_if_fail (fontb != NULL, FALSE);
180 privatea = (const GdkFontPrivate*) fonta;
181 privateb = (const GdkFontPrivate*) fontb;
183 if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
185 return (((XFontStruct *) privatea->xfont)->fid ==
186 ((XFontStruct *) privateb->xfont)->fid);
188 else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
190 /* how to compare two fontsets ?? by basename or XFontSet ?? */
191 return (((XFontSet) privatea->xfont) == ((XFontSet) privateb->xfont));
194 /* fontset != font */
199 gdk_string_width (GdkFont *font,
202 GdkFontPrivate *font_private;
207 g_return_val_if_fail (font != NULL, -1);
208 g_return_val_if_fail (string != NULL, -1);
210 font_private = (GdkFontPrivate*) font;
215 xfont = (XFontStruct *) font_private->xfont;
216 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
218 width = XTextWidth (xfont, string, strlen (string));
222 width = XTextWidth16 (xfont, (XChar2b *) string, strlen (string) / 2);
225 case GDK_FONT_FONTSET:
226 fontset = (XFontSet) font_private->xfont;
227 width = XmbTextEscapement (fontset, string, strlen(string));
237 gdk_text_width (GdkFont *font,
241 GdkFontPrivate *private;
246 g_return_val_if_fail (font != NULL, -1);
247 g_return_val_if_fail (text != NULL, -1);
249 private = (GdkFontPrivate*) font;
254 xfont = (XFontStruct *) private->xfont;
255 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
257 width = XTextWidth (xfont, text, text_length);
261 width = XTextWidth16 (xfont, (XChar2b *) text, text_length / 2);
264 case GDK_FONT_FONTSET:
265 fontset = (XFontSet) private->xfont;
266 width = XmbTextEscapement (fontset, text, text_length);
274 /* Problem: What if a character is a 16 bits character ?? */
276 gdk_char_width (GdkFont *font,
279 GdkFontPrivate *private;
282 guint ch = character & 0xff; /* get rid of sign-extension */
286 g_return_val_if_fail (font != NULL, -1);
288 private = (GdkFontPrivate*) font;
293 /* only 8 bits characters are considered here */
294 xfont = (XFontStruct *) private->xfont;
295 if ((xfont->min_byte1 == 0) &&
296 (xfont->max_byte1 == 0) &&
297 (ch >= xfont->min_char_or_byte2) &&
298 (ch <= xfont->max_char_or_byte2))
300 chars = xfont->per_char;
302 width = chars[ch - xfont->min_char_or_byte2].width;
304 width = xfont->min_bounds.width;
308 width = XTextWidth (xfont, &character, 1);
311 case GDK_FONT_FONTSET:
312 fontset = (XFontSet) private->xfont;
313 width = XmbTextEscapement (fontset, &character, 1) ;
322 gdk_string_measure (GdkFont *font,
325 g_return_val_if_fail (font != NULL, -1);
326 g_return_val_if_fail (string != NULL, -1);
328 return gdk_text_measure (font, string, strlen (string));
332 gdk_text_extents (GdkFont *font,
341 GdkFontPrivate *private;
345 XRectangle ink, logical;
350 g_return_if_fail (font != NULL);
351 g_return_if_fail (text != NULL);
353 private = (GdkFontPrivate*) font;
358 xfont = (XFontStruct *) private->xfont;
359 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
361 XTextExtents (xfont, text, text_length,
362 &direction, &font_ascent, &font_descent,
367 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
368 &direction, &font_ascent, &font_descent,
372 *lbearing = overall.lbearing;
374 *rbearing = overall.rbearing;
376 *width = overall.width;
378 *ascent = overall.ascent;
380 *descent = overall.descent;
382 case GDK_FONT_FONTSET:
383 fontset = (XFontSet) private->xfont;
384 XmbTextExtents (fontset, text, text_length, &ink, &logical);
390 *width = logical.width;
392 *ascent = ink.height;
401 gdk_string_extents (GdkFont *font,
409 g_return_if_fail (font != NULL);
410 g_return_if_fail (string != NULL);
412 gdk_text_extents (font, string, strlen (string),
413 lbearing, rbearing, width, ascent, descent);
418 gdk_text_measure (GdkFont *font,
422 GdkFontPrivate *private;
432 g_return_val_if_fail (font != NULL, -1);
433 g_return_val_if_fail (text != NULL, -1);
435 private = (GdkFontPrivate*) font;
440 xfont = (XFontStruct *) private->xfont;
441 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
443 XTextExtents (xfont, text, text_length,
444 &direction, &font_ascent, &font_descent,
449 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
450 &direction, &font_ascent, &font_descent,
453 width = overall.rbearing;
455 case GDK_FONT_FONTSET:
456 fontset = (XFontSet) private->xfont;
457 XmbTextExtents (fontset, text, text_length, &ink, &log);
467 gdk_char_measure (GdkFont *font,
470 g_return_val_if_fail (font != NULL, -1);
472 return gdk_text_measure (font, &character, 1);
476 gdk_string_height (GdkFont *font,
479 g_return_val_if_fail (font != NULL, -1);
480 g_return_val_if_fail (string != NULL, -1);
482 return gdk_text_height (font, string, strlen (string));
486 gdk_text_height (GdkFont *font,
490 GdkFontPrivate *private;
500 g_return_val_if_fail (font != NULL, -1);
501 g_return_val_if_fail (text != NULL, -1);
503 private = (GdkFontPrivate*) font;
508 xfont = (XFontStruct *) private->xfont;
509 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
511 XTextExtents (xfont, text, text_length,
512 &direction, &font_ascent, &font_descent,
517 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
518 &direction, &font_ascent, &font_descent,
521 height = overall.ascent + overall.descent;
523 case GDK_FONT_FONTSET:
524 fontset = (XFontSet) private->xfont;
525 XmbTextExtents (fontset, text, text_length, &ink, &log);
535 gdk_char_height (GdkFont *font,
538 g_return_val_if_fail (font != NULL, -1);
540 return gdk_text_height (font, &character, 1);