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);
275 gdk_text_width_wc (GdkFont *font,
276 const GdkWChar *text,
279 GdkFontPrivate *private;
284 g_return_val_if_fail (font != NULL, -1);
285 g_return_val_if_fail (text != NULL, -1);
287 private = (GdkFontPrivate*) font;
292 xfont = (XFontStruct *) private->xfont;
293 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
297 text_8bit = g_new (gchar, text_length);
298 for (i=0; i<text_length; i++) text_8bit[i] = text[i];
299 width = XTextWidth (xfont, text_8bit, text_length);
307 case GDK_FONT_FONTSET:
308 if (sizeof(GdkWChar) == sizeof(wchar_t))
310 fontset = (XFontSet) private->xfont;
311 width = XwcTextEscapement (fontset, (wchar_t *)text, text_length);
317 fontset = (XFontSet) private->xfont;
318 text_wchar = g_new(wchar_t, text_length);
319 for (i=0; i<text_length; i++) text_wchar[i] = text[i];
320 width = XwcTextEscapement (fontset, text_wchar, text_length);
330 /* Problem: What if a character is a 16 bits character ?? */
332 gdk_char_width (GdkFont *font,
335 GdkFontPrivate *private;
338 guint ch = character & 0xff; /* get rid of sign-extension */
342 g_return_val_if_fail (font != NULL, -1);
344 private = (GdkFontPrivate*) font;
349 /* only 8 bits characters are considered here */
350 xfont = (XFontStruct *) private->xfont;
351 if ((xfont->min_byte1 == 0) &&
352 (xfont->max_byte1 == 0) &&
353 (ch >= xfont->min_char_or_byte2) &&
354 (ch <= xfont->max_char_or_byte2))
356 chars = xfont->per_char;
358 width = chars[ch - xfont->min_char_or_byte2].width;
360 width = xfont->min_bounds.width;
364 width = XTextWidth (xfont, &character, 1);
367 case GDK_FONT_FONTSET:
368 fontset = (XFontSet) private->xfont;
369 width = XmbTextEscapement (fontset, &character, 1) ;
378 gdk_char_width_wc (GdkFont *font,
381 GdkFontPrivate *private;
384 guint ch = character & 0xff; /* get rid of sign-extension */
388 g_return_val_if_fail (font != NULL, -1);
390 private = (GdkFontPrivate*) font;
395 /* only 8 bits characters are considered here */
396 xfont = (XFontStruct *) private->xfont;
397 if ((xfont->min_byte1 == 0) &&
398 (xfont->max_byte1 == 0) &&
399 (ch >= xfont->min_char_or_byte2) &&
400 (ch <= xfont->max_char_or_byte2))
402 chars = xfont->per_char;
404 width = chars[ch - xfont->min_char_or_byte2].width;
406 width = xfont->min_bounds.width;
410 char ch2 = character;
411 width = XTextWidth (xfont, &ch2, 1);
414 case GDK_FONT_FONTSET:
415 fontset = (XFontSet) private->xfont;
417 wchar_t char_wc = character;
418 width = XwcTextEscapement (fontset, &char_wc, 1) ;
428 gdk_string_measure (GdkFont *font,
431 g_return_val_if_fail (font != NULL, -1);
432 g_return_val_if_fail (string != NULL, -1);
434 return gdk_text_measure (font, string, strlen (string));
438 gdk_text_extents (GdkFont *font,
447 GdkFontPrivate *private;
451 XRectangle ink, logical;
456 g_return_if_fail (font != NULL);
457 g_return_if_fail (text != NULL);
459 private = (GdkFontPrivate*) font;
464 xfont = (XFontStruct *) private->xfont;
465 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
467 XTextExtents (xfont, text, text_length,
468 &direction, &font_ascent, &font_descent,
473 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
474 &direction, &font_ascent, &font_descent,
478 *lbearing = overall.lbearing;
480 *rbearing = overall.rbearing;
482 *width = overall.width;
484 *ascent = overall.ascent;
486 *descent = overall.descent;
488 case GDK_FONT_FONTSET:
489 fontset = (XFontSet) private->xfont;
490 XmbTextExtents (fontset, text, text_length, &ink, &logical);
494 *rbearing = ink.x + ink.width;
496 *width = logical.width;
500 *descent = ink.y + ink.height;
507 gdk_text_extents_wc (GdkFont *font,
508 const GdkWChar *text,
516 GdkFontPrivate *private;
520 XRectangle ink, logical;
526 g_return_if_fail (font != NULL);
527 g_return_if_fail (text != NULL);
529 private = (GdkFontPrivate*) font;
538 xfont = (XFontStruct *) private->xfont;
539 g_return_if_fail ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0));
541 text_8bit = g_new (gchar, text_length);
542 for (i=0; i<text_length; i++)
543 text_8bit[i] = text[i];
545 XTextExtents (xfont, text_8bit, text_length,
546 &direction, &font_ascent, &font_descent,
551 *lbearing = overall.lbearing;
553 *rbearing = overall.rbearing;
555 *width = overall.width;
557 *ascent = overall.ascent;
559 *descent = overall.descent;
562 case GDK_FONT_FONTSET:
563 fontset = (XFontSet) private->xfont;
564 XwcTextExtents (fontset, text, text_length, &ink, &logical);
568 *rbearing = ink.x + ink.width;
570 *width = logical.width;
574 *descent = ink.y + ink.height;
581 gdk_string_extents (GdkFont *font,
589 g_return_if_fail (font != NULL);
590 g_return_if_fail (string != NULL);
592 gdk_text_extents (font, string, strlen (string),
593 lbearing, rbearing, width, ascent, descent);
598 gdk_text_measure (GdkFont *font,
602 GdkFontPrivate *private;
612 g_return_val_if_fail (font != NULL, -1);
613 g_return_val_if_fail (text != NULL, -1);
615 private = (GdkFontPrivate*) font;
620 xfont = (XFontStruct *) private->xfont;
621 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
623 XTextExtents (xfont, text, text_length,
624 &direction, &font_ascent, &font_descent,
629 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
630 &direction, &font_ascent, &font_descent,
633 width = overall.rbearing;
635 case GDK_FONT_FONTSET:
636 fontset = (XFontSet) private->xfont;
637 XmbTextExtents (fontset, text, text_length, &ink, &log);
647 gdk_char_measure (GdkFont *font,
650 g_return_val_if_fail (font != NULL, -1);
652 return gdk_text_measure (font, &character, 1);
656 gdk_string_height (GdkFont *font,
659 g_return_val_if_fail (font != NULL, -1);
660 g_return_val_if_fail (string != NULL, -1);
662 return gdk_text_height (font, string, strlen (string));
666 gdk_text_height (GdkFont *font,
670 GdkFontPrivate *private;
680 g_return_val_if_fail (font != NULL, -1);
681 g_return_val_if_fail (text != NULL, -1);
683 private = (GdkFontPrivate*) font;
688 xfont = (XFontStruct *) private->xfont;
689 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
691 XTextExtents (xfont, text, text_length,
692 &direction, &font_ascent, &font_descent,
697 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
698 &direction, &font_ascent, &font_descent,
701 height = overall.ascent + overall.descent;
703 case GDK_FONT_FONTSET:
704 fontset = (XFontSet) private->xfont;
705 XmbTextExtents (fontset, text, text_length, &ink, &log);
715 gdk_char_height (GdkFont *font,
718 g_return_val_if_fail (font != NULL, -1);
720 return gdk_text_height (font, &character, 1);