1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser 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.
8 *
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 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser 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.
18 */
19
20 /*
21 * Modified by the GTK+ Team and others 1997-2000. 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/.
25 */
26
27 #undef GDK_DISABLE_DEPRECATED
28
29 #include "config.h"
30 #include <X11/Xlib.h>
31 #include <X11/Xos.h>
32 #include <locale.h>
33
34 #include "gdkx.h"
35 #include "gdkfont.h"
36 #include "gdkprivate-x11.h"
37 #include "gdkinternals.h"
38 #include "gdkdisplay-x11.h"
39 #include "gdkscreen-x11.h"
40 #include "gdkalias.h"
41
42 typedef struct _GdkFontPrivateX GdkFontPrivateX;
43
44 struct _GdkFontPrivateX
45 {
46 GdkFontPrivate base;
47 /* XFontStruct *xfont; */
48 /* generic pointer point to XFontStruct or XFontSet */
49 gpointer xfont;
50 GdkDisplay *display;
51
52 GSList *names;
53 XID xid;
54 };
55
56 static GHashTable *
gdk_font_name_hash_get(GdkDisplay * display)57 gdk_font_name_hash_get (GdkDisplay *display)
58 {
59 GHashTable *result;
60 static GQuark font_name_quark = 0;
61
62 if (!font_name_quark)
63 font_name_quark = g_quark_from_static_string ("gdk-font-hash");
64
65 result = g_object_get_qdata (G_OBJECT (display), font_name_quark);
66
67 if (!result)
68 {
69 result = g_hash_table_new (g_str_hash, g_str_equal);
70 g_object_set_qdata_full (G_OBJECT (display),
71 font_name_quark, result, (GDestroyNotify) g_hash_table_destroy);
72 }
73
74 return result;
75 }
76
77 static GHashTable *
gdk_fontset_name_hash_get(GdkDisplay * display)78 gdk_fontset_name_hash_get (GdkDisplay *display)
79 {
80 GHashTable *result;
81 static GQuark fontset_name_quark = 0;
82
83 if (!fontset_name_quark)
84 fontset_name_quark = g_quark_from_static_string ("gdk-fontset-hash");
85
86 result = g_object_get_qdata (G_OBJECT (display), fontset_name_quark);
87
88 if (!result)
89 {
90 result = g_hash_table_new (g_str_hash, g_str_equal);
91 g_object_set_qdata_full (G_OBJECT (display),
92 fontset_name_quark, result, (GDestroyNotify) g_hash_table_destroy);
93 }
94
95 return result;
96 }
97
98 /**
99 * gdk_font_get_display:
100 * @font: the #GdkFont.
101 *
102 * Returns the #GdkDisplay for @font.
103 *
104 * Returns: the corresponding #GdkDisplay.
105 *
106 * Since: 2.2
107 **/
108 GdkDisplay*
gdk_font_get_display(GdkFont * font)109 gdk_font_get_display (GdkFont* font)
110 {
111 return ((GdkFontPrivateX *)font)->display;
112 }
113
114 static void
gdk_font_hash_insert(GdkFontType type,GdkFont * font,const gchar * font_name)115 gdk_font_hash_insert (GdkFontType type,
116 GdkFont *font,
117 const gchar *font_name)
118 {
119 GdkFontPrivateX *private = (GdkFontPrivateX *)font;
120 GHashTable *hash = (type == GDK_FONT_FONT) ?
121 gdk_font_name_hash_get (private->display) : gdk_fontset_name_hash_get (private->display);
122
123 private->names = g_slist_prepend (private->names, g_strdup (font_name));
124 g_hash_table_insert (hash, private->names->data, font);
125 }
126
127 static void
gdk_font_hash_remove(GdkFontType type,GdkFont * font)128 gdk_font_hash_remove (GdkFontType type,
129 GdkFont *font)
130 {
131 GdkFontPrivateX *private = (GdkFontPrivateX *)font;
132 GSList *tmp_list;
133 GHashTable *hash = (type == GDK_FONT_FONT) ?
134 gdk_font_name_hash_get (private->display) : gdk_fontset_name_hash_get (private->display);
135
136 tmp_list = private->names;
137 while (tmp_list)
138 {
139 g_hash_table_remove (hash, tmp_list->data);
140 g_free (tmp_list->data);
141
142 tmp_list = tmp_list->next;
143 }
144
145 g_slist_free (private->names);
146 private->names = NULL;
147 }
148
149 static GdkFont *
gdk_font_hash_lookup(GdkDisplay * display,GdkFontType type,const gchar * font_name)150 gdk_font_hash_lookup (GdkDisplay *display,
151 GdkFontType type,
152 const gchar *font_name)
153 {
154 GdkFont *result;
155 GHashTable *hash;
156 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
157
158 hash = (type == GDK_FONT_FONT) ? gdk_font_name_hash_get (display) :
159 gdk_fontset_name_hash_get (display);
160 if (!hash)
161 return NULL;
162 else
163 {
164 result = g_hash_table_lookup (hash, font_name);
165 if (result)
166 gdk_font_ref (result);
167
168 return result;
169 }
170 }
171
172 /**
173 * gdk_font_load_for_display:
174 * @display: a #GdkDisplay
175 * @font_name: a XLFD describing the font to load.
176 * @returns: a #GdkFont, or %NULL if the font could not be loaded.
177 *
178 * Loads a font for use on @display.
179 *
180 * The font may be newly loaded or looked up the font in a cache.
181 * You should make no assumptions about the initial reference count.
182 *
183 * Since: 2.2
184 */
185 GdkFont *
gdk_font_load_for_display(GdkDisplay * display,const gchar * font_name)186 gdk_font_load_for_display (GdkDisplay *display,
187 const gchar *font_name)
188 {
189 GdkFont *font;
190 GdkFontPrivateX *private;
191 XFontStruct *xfont;
192
193 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
194 g_return_val_if_fail (font_name != NULL, NULL);
195
196 font = gdk_font_hash_lookup (display, GDK_FONT_FONT, font_name);
197 if (font)
198 return font;
199
200 xfont = XLoadQueryFont (GDK_DISPLAY_XDISPLAY (display), font_name);
201 if (xfont == NULL)
202 return NULL;
203
204 font = gdk_font_lookup_for_display (display, xfont->fid);
205 if (font != NULL)
206 {
207 private = (GdkFontPrivateX *) font;
208 if (xfont != private->xfont)
209 XFreeFont (GDK_DISPLAY_XDISPLAY (display), xfont);
210
211 gdk_font_ref (font);
212 }
213 else
214 {
215 private = g_new (GdkFontPrivateX, 1);
216 private->display = display;
217 private->xfont = xfont;
218 private->base.ref_count = 1;
219 private->names = NULL;
220 private->xid = xfont->fid | XID_FONT_BIT;
221
222 font = (GdkFont*) private;
223 font->type = GDK_FONT_FONT;
224 font->ascent = xfont->ascent;
225 font->descent = xfont->descent;
226
227 _gdk_xid_table_insert (display, &private->xid, font);
228 }
229
230 gdk_font_hash_insert (GDK_FONT_FONT, font, font_name);
231
232 return font;
233 }
234
235 /**
236 * gdk_font_from_description_for_display:
237 * @display: a #GdkDisplay
238 * @font_desc: a #PangoFontDescription.
239 *
240 * Loads a #GdkFont based on a Pango font description for use on @display.
241 * This font will only be an approximation of the Pango font, and
242 * internationalization will not be handled correctly. This function
243 * should only be used for legacy code that cannot be easily converted
244 * to use Pango. Using Pango directly will produce better results.
245 *
246 * Return value: the newly loaded font, or %NULL if the font
247 * cannot be loaded.
248 *
249 * Since: 2.2
250 */
251 GdkFont *
gdk_font_from_description_for_display(GdkDisplay * display,PangoFontDescription * font_desc)252 gdk_font_from_description_for_display (GdkDisplay *display,
253 PangoFontDescription *font_desc)
254 {
255 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
256 g_return_val_if_fail (font_desc != NULL, NULL);
257
258 return gdk_font_load_for_display (display, "fixed");
259 }
260
261 /**
262 * gdk_fontset_load_for_display:
263 * @display: a #GdkDisplay
264 * @fontset_name: a comma-separated list of XLFDs describing
265 * the component fonts of the fontset to load.
266 * @returns: a #GdkFont, or %NULL if the fontset could not be loaded.
267 *
268 * Loads a fontset for use on @display.
269 *
270 * The fontset may be newly loaded or looked up in a cache.
271 * You should make no assumptions about the initial reference count.
272 *
273 * Since: 2.2
274 */
275 GdkFont *
gdk_fontset_load_for_display(GdkDisplay * display,const gchar * fontset_name)276 gdk_fontset_load_for_display (GdkDisplay *display,
277 const gchar *fontset_name)
278 {
279 GdkFont *font;
280 GdkFontPrivateX *private;
281 XFontSet fontset;
282 gint missing_charset_count;
283 gchar **missing_charset_list;
284 gchar *def_string;
285
286 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
287
288 font = gdk_font_hash_lookup (display, GDK_FONT_FONTSET, fontset_name);
289 if (font)
290 return font;
291
292 private = g_new (GdkFontPrivateX, 1);
293 font = (GdkFont*) private;
294
295 private->display = display;
296 fontset = XCreateFontSet (GDK_DISPLAY_XDISPLAY (display), fontset_name,
297 &missing_charset_list, &missing_charset_count,
298 &def_string);
299
300 if (missing_charset_count)
301 {
302 gint i;
303 g_printerr ("The font \"%s\" does not support all the required character sets for the current locale \"%s\"\n",
304 fontset_name, setlocale (LC_ALL, NULL));
305 for (i=0;i<missing_charset_count;i++)
306 g_printerr (" (Missing character set \"%s\")\n",
307 missing_charset_list[i]);
308 XFreeStringList (missing_charset_list);
309 }
310
311 private->base.ref_count = 1;
312
313 if (!fontset)
314 {
315 g_free (font);
316 return NULL;
317 }
318 else
319 {
320 gint num_fonts;
321 gint i;
322 XFontStruct **font_structs;
323 gchar **font_names;
324
325 private->xfont = fontset;
326 font->type = GDK_FONT_FONTSET;
327 num_fonts = XFontsOfFontSet (fontset, &font_structs, &font_names);
328
329 font->ascent = font->descent = 0;
330
331 for (i = 0; i < num_fonts; i++)
332 {
333 font->ascent = MAX (font->ascent, font_structs[i]->ascent);
334 font->descent = MAX (font->descent, font_structs[i]->descent);
335 }
336
337 private->names = NULL;
338 gdk_font_hash_insert (GDK_FONT_FONTSET, font, fontset_name);
339
340 return font;
341 }
342 }
343
344 /**
345 * gdk_fontset_load:
346 * @fontset_name: a comma-separated list of XLFDs describing
347 * the component fonts of the fontset to load.
348 *
349 * Loads a fontset.
350 *
351 * The fontset may be newly loaded or looked up in a cache.
352 * You should make no assumptions about the initial reference count.
353 *
354 * Return value: a #GdkFont, or %NULL if the fontset could not be loaded.
355 **/
356 GdkFont*
gdk_fontset_load(const gchar * fontset_name)357 gdk_fontset_load (const gchar *fontset_name)
358 {
359 return gdk_fontset_load_for_display (gdk_display_get_default (), fontset_name);
360 }
361
362 void
_gdk_font_destroy(GdkFont * font)363 _gdk_font_destroy (GdkFont *font)
364 {
365 GdkFontPrivateX *private = (GdkFontPrivateX *)font;
366
367 gdk_font_hash_remove (font->type, font);
368
369 switch (font->type)
370 {
371 case GDK_FONT_FONT:
372 _gdk_xid_table_remove (private->display, private->xid);
373 XFreeFont (GDK_DISPLAY_XDISPLAY (private->display),
374 (XFontStruct *) private->xfont);
375 break;
376 case GDK_FONT_FONTSET:
377 XFreeFontSet (GDK_DISPLAY_XDISPLAY (private->display),
378 (XFontSet) private->xfont);
379 break;
380 default:
381 g_error ("unknown font type.");
382 break;
383 }
384 g_free (font);
385 }
386
387 gint
_gdk_font_strlen(GdkFont * font,const gchar * str)388 _gdk_font_strlen (GdkFont *font,
389 const gchar *str)
390 {
391 GdkFontPrivateX *font_private;
392 gint length = 0;
393
394 g_return_val_if_fail (font != NULL, -1);
395 g_return_val_if_fail (str != NULL, -1);
396
397 font_private = (GdkFontPrivateX*) font;
398
399 if (font->type == GDK_FONT_FONT)
400 {
401 XFontStruct *xfont = (XFontStruct *) font_private->xfont;
402 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
403 {
404 length = strlen (str);
405 }
406 else
407 {
408 guint16 *string_2b = (guint16 *)str;
409
410 while (*(string_2b++))
411 length++;
412 }
413 }
414 else if (font->type == GDK_FONT_FONTSET)
415 {
416 length = strlen (str);
417 }
418 else
419 g_error("undefined font type\n");
420
421 return length;
422 }
423
424 /**
425 * gdk_font_id:
426 * @font: a #GdkFont.
427 *
428 * Returns the X Font ID for the given font.
429 *
430 * Return value: the numeric X Font ID
431 **/
432 gint
gdk_font_id(const GdkFont * font)433 gdk_font_id (const GdkFont *font)
434 {
435 const GdkFontPrivateX *font_private;
436
437 g_return_val_if_fail (font != NULL, 0);
438
439 font_private = (const GdkFontPrivateX*) font;
440
441 if (font->type == GDK_FONT_FONT)
442 {
443 return ((XFontStruct *) font_private->xfont)->fid;
444 }
445 else
446 {
447 return 0;
448 }
449 }
450
451 /**
452 * gdk_font_equal:
453 * @fonta: a #GdkFont.
454 * @fontb: another #GdkFont.
455 *
456 * Compares two fonts for equality. Single fonts compare equal
457 * if they have the same X font ID. This operation does
458 * not currently work correctly for fontsets.
459 *
460 * Return value: %TRUE if the fonts are equal.
461 **/
462 gboolean
gdk_font_equal(const GdkFont * fonta,const GdkFont * fontb)463 gdk_font_equal (const GdkFont *fonta,
464 const GdkFont *fontb)
465 {
466 const GdkFontPrivateX *privatea;
467 const GdkFontPrivateX *privateb;
468
469 g_return_val_if_fail (fonta != NULL, FALSE);
470 g_return_val_if_fail (fontb != NULL, FALSE);
471
472 privatea = (const GdkFontPrivateX*) fonta;
473 privateb = (const GdkFontPrivateX*) fontb;
474
475 if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
476 {
477 return (((XFontStruct *) privatea->xfont)->fid ==
478 ((XFontStruct *) privateb->xfont)->fid);
479 }
480 else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
481 {
482 gchar *namea, *nameb;
483
484 namea = XBaseFontNameListOfFontSet((XFontSet) privatea->xfont);
485 nameb = XBaseFontNameListOfFontSet((XFontSet) privateb->xfont);
486
487 return (strcmp(namea, nameb) == 0);
488 }
489 else
490 /* fontset != font */
491 return FALSE;
492 }
493
494 /**
495 * gdk_text_width:
496 * @font: a #GdkFont
497 * @text: the text to measure.
498 * @text_length: the length of the text in bytes.
499 *
500 * Determines the width of a given string.
501 *
502 * Return value: the width of the string in pixels.
503 **/
504 gint
gdk_text_width(GdkFont * font,const gchar * text,gint text_length)505 gdk_text_width (GdkFont *font,
506 const gchar *text,
507 gint text_length)
508 {
509 GdkFontPrivateX *private;
510 gint width;
511 XFontStruct *xfont;
512 XFontSet fontset;
513
514 g_return_val_if_fail (font != NULL, -1);
515 g_return_val_if_fail (text != NULL, -1);
516
517 private = (GdkFontPrivateX*) font;
518
519 switch (font->type)
520 {
521 case GDK_FONT_FONT:
522 xfont = (XFontStruct *) private->xfont;
523 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
524 {
525 width = XTextWidth (xfont, text, text_length);
526 }
527 else
528 {
529 width = XTextWidth16 (xfont, (XChar2b *) text, text_length / 2);
530 }
531 break;
532 case GDK_FONT_FONTSET:
533 fontset = (XFontSet) private->xfont;
534 width = XmbTextEscapement (fontset, text, text_length);
535 break;
536 default:
537 width = 0;
538 }
539 return width;
540 }
541
542 /**
543 * gdk_text_width_wc:
544 * @font: a #GdkFont
545 * @text: the text to measure.
546 * @text_length: the length of the text in characters.
547 *
548 * Determines the width of a given wide-character string.
549 *
550 * Return value: the width of the string in pixels.
551 **/
552 gint
gdk_text_width_wc(GdkFont * font,const GdkWChar * text,gint text_length)553 gdk_text_width_wc (GdkFont *font,
554 const GdkWChar *text,
555 gint text_length)
556 {
557 GdkFontPrivateX *private;
558 gint width;
559 XFontStruct *xfont;
560 XFontSet fontset;
561
562 g_return_val_if_fail (font != NULL, -1);
563 g_return_val_if_fail (text != NULL, -1);
564
565 private = (GdkFontPrivateX*) font;
566
567 switch (font->type)
568 {
569 case GDK_FONT_FONT:
570 xfont = (XFontStruct *) private->xfont;
571 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
572 {
573 gchar *text_8bit;
574 gint i;
575 text_8bit = g_new (gchar, text_length);
576 for (i=0; i<text_length; i++) text_8bit[i] = text[i];
577 width = XTextWidth (xfont, text_8bit, text_length);
578 g_free (text_8bit);
579 }
580 else
581 {
582 width = 0;
583 }
584 break;
585 case GDK_FONT_FONTSET:
586 if (sizeof(GdkWChar) == sizeof(wchar_t))
587 {
588 fontset = (XFontSet) private->xfont;
589 width = XwcTextEscapement (fontset, (wchar_t *)text, text_length);
590 }
591 else
592 {
593 wchar_t *text_wchar;
594 gint i;
595 fontset = (XFontSet) private->xfont;
596 text_wchar = g_new(wchar_t, text_length);
597 for (i=0; i<text_length; i++) text_wchar[i] = text[i];
598 width = XwcTextEscapement (fontset, text_wchar, text_length);
599 g_free (text_wchar);
600 }
601 break;
602 default:
603 width = 0;
604 }
605 return width;
606 }
607
608 /**
609 * gdk_text_extents:
610 * @font: a #GdkFont
611 * @text: the text to measure
612 * @text_length: the length of the text in bytes. (If the
613 * font is a 16-bit font, this is twice the length
614 * of the text in characters.)
615 * @lbearing: the left bearing of the string.
616 * @rbearing: the right bearing of the string.
617 * @width: the width of the string.
618 * @ascent: the ascent of the string.
619 * @descent: the descent of the string.
620 *
621 * Gets the metrics of a string.
622 **/
623 void
gdk_text_extents(GdkFont * font,const gchar * text,gint text_length,gint * lbearing,gint * rbearing,gint * width,gint * ascent,gint * descent)624 gdk_text_extents (GdkFont *font,
625 const gchar *text,
626 gint text_length,
627 gint *lbearing,
628 gint *rbearing,
629 gint *width,
630 gint *ascent,
631 gint *descent)
632 {
633 GdkFontPrivateX *private;
634 XCharStruct overall;
635 XFontStruct *xfont;
636 XFontSet fontset;
637 XRectangle ink, logical;
638 int direction;
639 int font_ascent;
640 int font_descent;
641
642 g_return_if_fail (font != NULL);
643 g_return_if_fail (text != NULL);
644
645 private = (GdkFontPrivateX*) font;
646
647 switch (font->type)
648 {
649 case GDK_FONT_FONT:
650 xfont = (XFontStruct *) private->xfont;
651 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
652 {
653 XTextExtents (xfont, text, text_length,
654 &direction, &font_ascent, &font_descent,
655 &overall);
656 }
657 else
658 {
659 XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
660 &direction, &font_ascent, &font_descent,
661 &overall);
662 }
663 if (lbearing)
664 *lbearing = overall.lbearing;
665 if (rbearing)
666 *rbearing = overall.rbearing;
667 if (width)
668 *width = overall.width;
669 if (ascent)
670 *ascent = overall.ascent;
671 if (descent)
672 *descent = overall.descent;
673 break;
674 case GDK_FONT_FONTSET:
675 fontset = (XFontSet) private->xfont;
676 XmbTextExtents (fontset, text, text_length, &ink, &logical);
677 if (lbearing)
678 *lbearing = ink.x;
679 if (rbearing)
680 *rbearing = ink.x + ink.width;
681 if (width)
682 *width = logical.width;
683 if (ascent)
684 *ascent = -ink.y;
685 if (descent)
686 *descent = ink.y + ink.height;
687 break;
688 }
689
690 }
691
692 /**
693 * gdk_text_extents_wc:
694 * @font: a #GdkFont
695 * @text: the text to measure.
696 * @text_length: the length of the text in character.
697 * @lbearing: the left bearing of the string.
698 * @rbearing: the right bearing of the string.
699 * @width: the width of the string.
700 * @ascent: the ascent of the string.
701 * @descent: the descent of the string.
702 *
703 * Gets the metrics of a string of wide characters.
704 **/
705 void
gdk_text_extents_wc(GdkFont * font,const GdkWChar * text,gint text_length,gint * lbearing,gint * rbearing,gint * width,gint * ascent,gint * descent)706 gdk_text_extents_wc (GdkFont *font,
707 const GdkWChar *text,
708 gint text_length,
709 gint *lbearing,
710 gint *rbearing,
711 gint *width,
712 gint *ascent,
713 gint *descent)
714 {
715 GdkFontPrivateX *private;
716 XCharStruct overall;
717 XFontStruct *xfont;
718 XFontSet fontset;
719 XRectangle ink, logical;
720 int direction;
721 int font_ascent;
722 int font_descent;
723
724 g_return_if_fail (font != NULL);
725 g_return_if_fail (text != NULL);
726
727 private = (GdkFontPrivateX*) font;
728
729 switch (font->type)
730 {
731 case GDK_FONT_FONT:
732 {
733 gchar *text_8bit;
734 gint i;
735
736 xfont = (XFontStruct *) private->xfont;
737 g_return_if_fail ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0));
738
739 text_8bit = g_new (gchar, text_length);
740 for (i=0; i<text_length; i++)
741 text_8bit[i] = text[i];
742
743 XTextExtents (xfont, text_8bit, text_length,
744 &direction, &font_ascent, &font_descent,
745 &overall);
746 g_free (text_8bit);
747
748 if (lbearing)
749 *lbearing = overall.lbearing;
750 if (rbearing)
751 *rbearing = overall.rbearing;
752 if (width)
753 *width = overall.width;
754 if (ascent)
755 *ascent = overall.ascent;
756 if (descent)
757 *descent = overall.descent;
758 break;
759 }
760 case GDK_FONT_FONTSET:
761 fontset = (XFontSet) private->xfont;
762
763 if (sizeof(GdkWChar) == sizeof(wchar_t))
764 XwcTextExtents (fontset, (wchar_t *)text, text_length, &ink, &logical);
765 else
766 {
767 wchar_t *text_wchar;
768 gint i;
769
770 text_wchar = g_new (wchar_t, text_length);
771 for (i = 0; i < text_length; i++)
772 text_wchar[i] = text[i];
773 XwcTextExtents (fontset, text_wchar, text_length, &ink, &logical);
774 g_free (text_wchar);
775 }
776 if (lbearing)
777 *lbearing = ink.x;
778 if (rbearing)
779 *rbearing = ink.x + ink.width;
780 if (width)
781 *width = logical.width;
782 if (ascent)
783 *ascent = -ink.y;
784 if (descent)
785 *descent = ink.y + ink.height;
786 break;
787 }
788
789 }
790
791 /**
792 * gdk_x11_font_get_xdisplay:
793 * @font: a #GdkFont.
794 *
795 * Returns the display of a #GdkFont.
796 *
797 * Return value: an Xlib <type>Display*</type>.
798 **/
799 Display *
gdk_x11_font_get_xdisplay(GdkFont * font)800 gdk_x11_font_get_xdisplay (GdkFont *font)
801 {
802 g_return_val_if_fail (font != NULL, NULL);
803
804 return GDK_DISPLAY_XDISPLAY (((GdkFontPrivateX *)font)->display);
805 }
806
807 /**
808 * gdk_x11_font_get_xfont:
809 * @font: a #GdkFont.
810 *
811 * Returns the X font belonging to a #GdkFont.
812 *
813 * Return value: an Xlib <type>XFontStruct*</type> or an <type>XFontSet</type>.
814 **/
815 gpointer
gdk_x11_font_get_xfont(GdkFont * font)816 gdk_x11_font_get_xfont (GdkFont *font)
817 {
818 g_return_val_if_fail (font != NULL, NULL);
819
820 return ((GdkFontPrivateX *)font)->xfont;
821 }
822
823 /**
824 * gdk_x11_font_get_name:
825 * @font: a #GdkFont.
826 *
827 * Return the X Logical Font Description (for font->type == GDK_FONT_FONT)
828 * or comma separated list of XLFDs (for font->type == GDK_FONT_FONTSET)
829 * that was used to load the font. If the same font was loaded
830 * via multiple names, which name is returned is undefined.
831 *
832 * Return value: the name of the font. This string is owned
833 * by GDK and must not be modified or freed.
834 **/
835 const char *
gdk_x11_font_get_name(GdkFont * font)836 gdk_x11_font_get_name (GdkFont *font)
837 {
838 GdkFontPrivateX *private = (GdkFontPrivateX *)font;
839
840 g_return_val_if_fail (font != NULL, NULL);
841
842 g_assert (private->names);
843
844 return private->names->data;
845 }
846
847 #define __GDK_FONT_X11_C__
848 #include "gdkaliasdef.c"
849