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.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gdkprivate.h"
33 gdk_font_load (const gchar *font_name)
36 GdkFontPrivate *private;
39 g_return_val_if_fail (font_name != NULL, NULL);
41 xfont = XLoadQueryFont (gdk_display, font_name);
45 font = gdk_font_lookup (xfont->fid);
48 private = (GdkFontPrivate *) font;
49 if (xfont != private->xfont)
50 XFreeFont (gdk_display, xfont);
56 private = g_new (GdkFontPrivate, 1);
57 private->xdisplay = gdk_display;
58 private->xfont = xfont;
59 private->ref_count = 1;
61 font = (GdkFont*) private;
62 font->type = GDK_FONT_FONT;
63 font->ascent = xfont->ascent;
64 font->descent = xfont->descent;
66 gdk_xid_table_insert (&xfont->fid, font);
73 gdk_fontset_load (gchar *fontset_name)
76 GdkFontPrivate *private;
78 gint missing_charset_count;
79 gchar **missing_charset_list;
82 private = g_new (GdkFontPrivate, 1);
83 font = (GdkFont*) private;
85 private->xdisplay = gdk_display;
86 fontset = XCreateFontSet (gdk_display, fontset_name,
87 &missing_charset_list, &missing_charset_count,
90 if (missing_charset_count)
93 g_warning ("Missing charsets in FontSet creation\n");
94 for (i=0;i<missing_charset_count;i++)
95 g_warning (" %s\n", missing_charset_list[i]);
96 XFreeStringList (missing_charset_list);
99 private->ref_count = 1;
110 XFontStruct **font_structs;
113 private->xfont = fontset;
114 font->type = GDK_FONT_FONTSET;
115 num_fonts = XFontsOfFontSet (fontset, &font_structs, &font_names);
117 font->ascent = font->descent = 0;
119 for (i = 0; i < num_fonts; i++)
121 font->ascent = MAX (font->ascent, font_structs[i]->ascent);
122 font->descent = MAX (font->descent, font_structs[i]->descent);
129 gdk_font_ref (GdkFont *font)
131 GdkFontPrivate *private;
133 g_return_val_if_fail (font != NULL, NULL);
135 private = (GdkFontPrivate*) font;
136 private->ref_count += 1;
141 gdk_font_unref (GdkFont *font)
143 GdkFontPrivate *private;
145 g_return_if_fail (font != NULL);
147 private = (GdkFontPrivate*) font;
149 private->ref_count -= 1;
150 if (private->ref_count == 0)
155 gdk_xid_table_remove (((XFontStruct *) private->xfont)->fid);
156 XFreeFont (private->xdisplay, (XFontStruct *) private->xfont);
158 case GDK_FONT_FONTSET:
159 XFreeFontSet (private->xdisplay, (XFontSet) private->xfont);
162 g_error ("unknown font type.");
170 gdk_font_id (const GdkFont *font)
172 const GdkFontPrivate *font_private;
174 g_return_val_if_fail (font != NULL, 0);
176 font_private = (const GdkFontPrivate*) font;
178 if (font->type == GDK_FONT_FONT)
180 return ((XFontStruct *) font_private->xfont)->fid;
189 gdk_font_equal (const GdkFont *fonta,
190 const GdkFont *fontb)
192 const GdkFontPrivate *privatea;
193 const GdkFontPrivate *privateb;
195 g_return_val_if_fail (fonta != NULL, FALSE);
196 g_return_val_if_fail (fontb != NULL, FALSE);
198 privatea = (const GdkFontPrivate*) fonta;
199 privateb = (const GdkFontPrivate*) fontb;
201 if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
203 return (((XFontStruct *) privatea->xfont)->fid ==
204 ((XFontStruct *) privateb->xfont)->fid);
206 else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
208 /* how to compare two fontsets ?? by basename or XFontSet ?? */
209 return (((XFontSet) privatea->xfont) == ((XFontSet) privateb->xfont));
212 /* fontset != font */
217 gdk_string_width (GdkFont *font,
220 GdkFontPrivate *font_private;
225 g_return_val_if_fail (font != NULL, -1);
226 g_return_val_if_fail (string != NULL, -1);
228 font_private = (GdkFontPrivate*) font;
233 xfont = (XFontStruct *) font_private->xfont;
234 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
236 width = XTextWidth (xfont, string, strlen (string));
240 width = XTextWidth16 (xfont, (XChar2b *) string, strlen (string) / 2);
243 case GDK_FONT_FONTSET:
244 fontset = (XFontSet) font_private->xfont;
245 width = XmbTextEscapement (fontset, string, strlen(string));
255 gdk_text_width (GdkFont *font,
259 GdkFontPrivate *private;
264 g_return_val_if_fail (font != NULL, -1);
265 g_return_val_if_fail (text != NULL, -1);
267 private = (GdkFontPrivate*) font;
272 xfont = (XFontStruct *) private->xfont;
273 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
275 width = XTextWidth (xfont, text, text_length);
279 width = XTextWidth16 (xfont, (XChar2b *) text, text_length / 2);
282 case GDK_FONT_FONTSET:
283 fontset = (XFontSet) private->xfont;
284 width = XmbTextEscapement (fontset, text, text_length);
293 gdk_text_width_wc (GdkFont *font,
294 const GdkWChar *text,
297 GdkFontPrivate *private;
302 g_return_val_if_fail (font != NULL, -1);
303 g_return_val_if_fail (text != NULL, -1);
305 private = (GdkFontPrivate*) font;
310 xfont = (XFontStruct *) private->xfont;
311 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
315 text_8bit = g_new (gchar, text_length);
316 for (i=0; i<text_length; i++) text_8bit[i] = text[i];
317 width = XTextWidth (xfont, text_8bit, text_length);
325 case GDK_FONT_FONTSET:
326 if (sizeof(GdkWChar) == sizeof(wchar_t))
328 fontset = (XFontSet) private->xfont;
329 width = XwcTextEscapement (fontset, (wchar_t *)text, text_length);
335 fontset = (XFontSet) private->xfont;
336 text_wchar = g_new(wchar_t, text_length);
337 for (i=0; i<text_length; i++) text_wchar[i] = text[i];
338 width = XwcTextEscapement (fontset, text_wchar, text_length);
348 /* Problem: What if a character is a 16 bits character ?? */
350 gdk_char_width (GdkFont *font,
353 GdkFontPrivate *private;
356 guint ch = character & 0xff; /* get rid of sign-extension */
360 g_return_val_if_fail (font != NULL, -1);
362 private = (GdkFontPrivate*) font;
367 /* only 8 bits characters are considered here */
368 xfont = (XFontStruct *) private->xfont;
369 if ((xfont->min_byte1 == 0) &&
370 (xfont->max_byte1 == 0) &&
371 (ch >= xfont->min_char_or_byte2) &&
372 (ch <= xfont->max_char_or_byte2))
374 chars = xfont->per_char;
376 width = chars[ch - xfont->min_char_or_byte2].width;
378 width = xfont->min_bounds.width;
382 width = XTextWidth (xfont, &character, 1);
385 case GDK_FONT_FONTSET:
386 fontset = (XFontSet) private->xfont;
387 width = XmbTextEscapement (fontset, &character, 1) ;
396 gdk_char_width_wc (GdkFont *font,
399 GdkFontPrivate *private;
402 guint ch = character & 0xff; /* get rid of sign-extension */
406 g_return_val_if_fail (font != NULL, -1);
408 private = (GdkFontPrivate*) font;
413 /* only 8 bits characters are considered here */
414 xfont = (XFontStruct *) private->xfont;
415 if ((xfont->min_byte1 == 0) &&
416 (xfont->max_byte1 == 0) &&
417 (ch >= xfont->min_char_or_byte2) &&
418 (ch <= xfont->max_char_or_byte2))
420 chars = xfont->per_char;
422 width = chars[ch - xfont->min_char_or_byte2].width;
424 width = xfont->min_bounds.width;
428 char ch2 = character;
429 width = XTextWidth (xfont, &ch2, 1);
432 case GDK_FONT_FONTSET:
433 fontset = (XFontSet) private->xfont;
435 wchar_t char_wc = character;
436 width = XwcTextEscapement (fontset, &char_wc, 1) ;
446 gdk_string_measure (GdkFont *font,
449 g_return_val_if_fail (font != NULL, -1);
450 g_return_val_if_fail (string != NULL, -1);
452 return gdk_text_measure (font, string, strlen (string));
456 gdk_text_extents (GdkFont *font,
465 GdkFontPrivate *private;
469 XRectangle ink, logical;
474 g_return_if_fail (font != NULL);
475 g_return_if_fail (text != NULL);
477 private = (GdkFontPrivate*) font;
482 xfont = (XFontStruct *) private->xfont;
483 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
485 XTextExtents (xfont, text, text_length,
486 &direction, &font_ascent, &font_descent,
491 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
492 &direction, &font_ascent, &font_descent,
496 *lbearing = overall.lbearing;
498 *rbearing = overall.rbearing;
500 *width = overall.width;
502 *ascent = overall.ascent;
504 *descent = overall.descent;
506 case GDK_FONT_FONTSET:
507 fontset = (XFontSet) private->xfont;
508 XmbTextExtents (fontset, text, text_length, &ink, &logical);
512 *rbearing = ink.x + ink.width;
514 *width = logical.width;
518 *descent = ink.y + ink.height;
525 gdk_text_extents_wc (GdkFont *font,
526 const GdkWChar *text,
534 GdkFontPrivate *private;
538 XRectangle ink, logical;
543 g_return_if_fail (font != NULL);
544 g_return_if_fail (text != NULL);
546 private = (GdkFontPrivate*) font;
555 xfont = (XFontStruct *) private->xfont;
556 g_return_if_fail ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0));
558 text_8bit = g_new (gchar, text_length);
559 for (i=0; i<text_length; i++)
560 text_8bit[i] = text[i];
562 XTextExtents (xfont, text_8bit, text_length,
563 &direction, &font_ascent, &font_descent,
568 *lbearing = overall.lbearing;
570 *rbearing = overall.rbearing;
572 *width = overall.width;
574 *ascent = overall.ascent;
576 *descent = overall.descent;
579 case GDK_FONT_FONTSET:
580 fontset = (XFontSet) private->xfont;
581 XwcTextExtents (fontset, text, text_length, &ink, &logical);
585 *rbearing = ink.x + ink.width;
587 *width = logical.width;
591 *descent = ink.y + ink.height;
598 gdk_string_extents (GdkFont *font,
606 g_return_if_fail (font != NULL);
607 g_return_if_fail (string != NULL);
609 gdk_text_extents (font, string, strlen (string),
610 lbearing, rbearing, width, ascent, descent);
615 gdk_text_measure (GdkFont *font,
619 GdkFontPrivate *private;
629 g_return_val_if_fail (font != NULL, -1);
630 g_return_val_if_fail (text != NULL, -1);
632 private = (GdkFontPrivate*) font;
637 xfont = (XFontStruct *) private->xfont;
638 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
640 XTextExtents (xfont, text, text_length,
641 &direction, &font_ascent, &font_descent,
646 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
647 &direction, &font_ascent, &font_descent,
650 width = overall.rbearing;
652 case GDK_FONT_FONTSET:
653 fontset = (XFontSet) private->xfont;
654 XmbTextExtents (fontset, text, text_length, &ink, &log);
664 gdk_char_measure (GdkFont *font,
667 g_return_val_if_fail (font != NULL, -1);
669 return gdk_text_measure (font, &character, 1);
673 gdk_string_height (GdkFont *font,
676 g_return_val_if_fail (font != NULL, -1);
677 g_return_val_if_fail (string != NULL, -1);
679 return gdk_text_height (font, string, strlen (string));
683 gdk_text_height (GdkFont *font,
687 GdkFontPrivate *private;
697 g_return_val_if_fail (font != NULL, -1);
698 g_return_val_if_fail (text != NULL, -1);
700 private = (GdkFontPrivate*) font;
705 xfont = (XFontStruct *) private->xfont;
706 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
708 XTextExtents (xfont, text, text_length,
709 &direction, &font_ascent, &font_descent,
714 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
715 &direction, &font_ascent, &font_descent,
718 height = overall.ascent + overall.descent;
720 case GDK_FONT_FONTSET:
721 fontset = (XFontSet) private->xfont;
722 XmbTextExtents (fontset, text, text_length, &ink, &log);
732 gdk_char_height (GdkFont *font,
735 g_return_val_if_fail (font != NULL, -1);
737 return gdk_text_height (font, &character, 1);