source: trunk/third/gtk/gdk/gdkfont.c @ 17071

Revision 17071, 19.8 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17070, which included commits to RCS files with non-trunk default branches.
Line 
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 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.
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 * Library General Public License for more details.
13 *
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.
18 */
19
20/*
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/.
25 */
26
27#include <X11/Xlib.h>
28#include <X11/Xos.h>
29#include "gdk.h"
30#include "gdkprivate.h"
31
32#if HAVE_CONFIG_H
33#  include <config.h>
34#  if STDC_HEADERS
35#    include <string.h>
36#  endif
37#endif
38
39#ifdef USE_NATIVE_LOCALE
40#include <stdlib.h>
41#endif
42
43static GHashTable *font_name_hash = NULL;
44static GHashTable *fontset_name_hash = NULL;
45
46#define FONT_XFONT(private)  ((XFontStruct *)(private)->xfont)
47#define FONT_IS_8BIT(private) ((FONT_XFONT(private)->min_byte1 == 0) && \
48                               (FONT_XFONT(private)->max_byte1 == 0))
49
50static void
51gdk_font_hash_insert (GdkFontType type, GdkFont *font, const gchar *font_name)
52{
53  GdkFontPrivate *private = (GdkFontPrivate *)font;
54  GHashTable **hashp = (type == GDK_FONT_FONT) ?
55    &font_name_hash : &fontset_name_hash;
56
57  if (!*hashp)
58    *hashp = g_hash_table_new (g_str_hash, g_str_equal);
59
60  private->names = g_slist_prepend (private->names, g_strdup (font_name));
61  g_hash_table_insert (*hashp, private->names->data, font);
62}
63
64static void
65gdk_font_hash_remove (GdkFontType type, GdkFont *font)
66{
67  GdkFontPrivate *private = (GdkFontPrivate *)font;
68  GSList *tmp_list;
69  GHashTable *hash = (type == GDK_FONT_FONT) ?
70    font_name_hash : fontset_name_hash;
71
72  tmp_list = private->names;
73  while (tmp_list)
74    {
75      g_hash_table_remove (hash, tmp_list->data);
76      g_free (tmp_list->data);
77     
78      tmp_list = tmp_list->next;
79    }
80
81  g_slist_free (private->names);
82  private->names = NULL;
83}
84
85static GdkFont *
86gdk_font_hash_lookup (GdkFontType type, const gchar *font_name)
87{
88  GdkFont *result;
89  GHashTable *hash = (type == GDK_FONT_FONT) ?
90    font_name_hash : fontset_name_hash;
91
92  if (!hash)
93    return NULL;
94  else
95    {
96      result = g_hash_table_lookup (hash, font_name);
97      if (result)
98        gdk_font_ref (result);
99     
100      return result;
101    }
102}
103
104GdkFont*
105gdk_font_load (const gchar *font_name)
106{
107  GdkFont *font;
108  GdkFontPrivate *private;
109  XFontStruct *xfont;
110
111  g_return_val_if_fail (font_name != NULL, NULL);
112
113  font = gdk_font_hash_lookup (GDK_FONT_FONT, font_name);
114  if (font)
115    return font;
116
117  xfont = XLoadQueryFont (gdk_display, font_name);
118  if (xfont == NULL)
119    return NULL;
120
121  font = gdk_font_lookup (xfont->fid);
122  if (font != NULL)
123    {
124      private = (GdkFontPrivate *) font;
125      if (xfont != private->xfont)
126        XFreeFont (gdk_display, xfont);
127
128      gdk_font_ref (font);
129    }
130  else
131    {
132      private = g_new (GdkFontPrivate, 1);
133      private->xdisplay = gdk_display;
134      private->xfont = xfont;
135      private->ref_count = 1;
136      private->names = NULL;
137 
138      font = (GdkFont*) private;
139      font->type = GDK_FONT_FONT;
140      font->ascent =  xfont->ascent;
141      font->descent = xfont->descent;
142
143      gdk_xid_table_insert (&xfont->fid, font);
144    }
145
146  gdk_font_hash_insert (GDK_FONT_FONT, font, font_name);
147
148  return font;
149}
150
151GdkFont*
152gdk_fontset_load (const gchar *fontset_name)
153{
154  GdkFont *font;
155  GdkFontPrivate *private;
156  XFontSet fontset;
157  gint  missing_charset_count;
158  gchar **missing_charset_list;
159  gchar *def_string;
160
161  font = gdk_font_hash_lookup (GDK_FONT_FONTSET, fontset_name);
162  if (font)
163    return font;
164
165  private = g_new (GdkFontPrivate, 1);
166  font = (GdkFont*) private;
167
168  private->xdisplay = gdk_display;
169  fontset = XCreateFontSet (gdk_display, fontset_name,
170                            &missing_charset_list, &missing_charset_count,
171                            &def_string);
172
173  if (missing_charset_count)
174    {
175      gint i;
176      g_warning ("Missing charsets in FontSet creation\n");
177      for (i=0;i<missing_charset_count;i++)
178        g_warning ("    %s\n", missing_charset_list[i]);
179      XFreeStringList (missing_charset_list);
180    }
181
182  private->ref_count = 1;
183
184  if (!fontset)
185    {
186      g_free (font);
187      return NULL;
188    }
189  else
190    {
191      gint num_fonts;
192      gint i;
193      XFontStruct **font_structs;
194      gchar **font_names;
195     
196      private->xfont = fontset;
197      font->type = GDK_FONT_FONTSET;
198      num_fonts = XFontsOfFontSet (fontset, &font_structs, &font_names);
199
200      font->ascent = font->descent = 0;
201     
202      for (i = 0; i < num_fonts; i++)
203        {
204          font->ascent = MAX (font->ascent, font_structs[i]->ascent);
205          font->descent = MAX (font->descent, font_structs[i]->descent);
206        }
207
208      private->names = NULL;
209      gdk_font_hash_insert (GDK_FONT_FONTSET, font, fontset_name);
210     
211      return font;
212    }
213}
214
215GdkFont*
216gdk_font_ref (GdkFont *font)
217{
218  GdkFontPrivate *private;
219
220  g_return_val_if_fail (font != NULL, NULL);
221
222  private = (GdkFontPrivate*) font;
223  private->ref_count += 1;
224  return font;
225}
226
227void
228gdk_font_unref (GdkFont *font)
229{
230  GdkFontPrivate *private;
231  private = (GdkFontPrivate*) font;
232
233  g_return_if_fail (font != NULL);
234  g_return_if_fail (private->ref_count > 0);
235
236  private->ref_count -= 1;
237  if (private->ref_count == 0)
238    {
239      gdk_font_hash_remove (font->type, font);
240     
241      switch (font->type)
242        {
243        case GDK_FONT_FONT:
244          gdk_xid_table_remove (((XFontStruct *) private->xfont)->fid);
245          XFreeFont (private->xdisplay, (XFontStruct *) private->xfont);
246          break;
247        case GDK_FONT_FONTSET:
248          XFreeFontSet (private->xdisplay, (XFontSet) private->xfont);
249          break;
250        default:
251          g_error ("unknown font type.");
252          break;
253        }
254      g_free (font);
255    }
256}
257
258gint
259gdk_font_id (const GdkFont *font)
260{
261  const GdkFontPrivate *font_private;
262
263  g_return_val_if_fail (font != NULL, 0);
264
265  font_private = (const GdkFontPrivate*) font;
266
267  if (font->type == GDK_FONT_FONT)
268    {
269      return ((XFontStruct *) font_private->xfont)->fid;
270    }
271  else
272    {
273      return 0;
274    }
275}
276
277gboolean
278gdk_font_equal (const GdkFont *fonta,
279                const GdkFont *fontb)
280{
281  const GdkFontPrivate *privatea;
282  const GdkFontPrivate *privateb;
283
284  g_return_val_if_fail (fonta != NULL, FALSE);
285  g_return_val_if_fail (fontb != NULL, FALSE);
286
287  privatea = (const GdkFontPrivate*) fonta;
288  privateb = (const GdkFontPrivate*) fontb;
289
290  if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
291    {
292      return (((XFontStruct *) privatea->xfont)->fid ==
293              ((XFontStruct *) privateb->xfont)->fid);
294    }
295  else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
296    {
297      gchar *namea, *nameb;
298
299      namea = XBaseFontNameListOfFontSet((XFontSet) privatea->xfont);
300      nameb = XBaseFontNameListOfFontSet((XFontSet) privateb->xfont);
301     
302      return (strcmp(namea, nameb) == 0);
303    }
304  else
305    /* fontset != font */
306    return FALSE;
307}
308
309gint
310gdk_string_width (GdkFont     *font,
311                  const gchar *string)
312{
313  GdkFontPrivate *font_private;
314  gint width;
315  XFontStruct *xfont;
316  XFontSet fontset;
317
318  g_return_val_if_fail (font != NULL, -1);
319  g_return_val_if_fail (string != NULL, -1);
320
321  font_private = (GdkFontPrivate*) font;
322
323  switch (font->type)
324    {
325    case GDK_FONT_FONT:
326      xfont = (XFontStruct *) font_private->xfont;
327      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
328        {
329          width = XTextWidth (xfont, string, strlen (string));
330        }
331      else
332        {
333          width = XTextWidth16 (xfont, (XChar2b *) string, strlen (string) / 2);
334        }
335      break;
336    case GDK_FONT_FONTSET:
337      fontset = (XFontSet) font_private->xfont;
338      width = XmbTextEscapement (fontset, string, strlen(string));
339      break;
340    default:
341      width = 0;
342    }
343
344  return width;
345}
346
347gint
348gdk_text_width (GdkFont      *font,
349                const gchar  *text,
350                gint          text_length)
351{
352  GdkFontPrivate *private;
353  gint width;
354  XFontStruct *xfont;
355  XFontSet fontset;
356
357  g_return_val_if_fail (font != NULL, -1);
358  g_return_val_if_fail (text != NULL, -1);
359
360  private = (GdkFontPrivate*) font;
361
362  switch (font->type)
363    {
364    case GDK_FONT_FONT:
365      xfont = (XFontStruct *) private->xfont;
366      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
367        {
368          width = XTextWidth (xfont, text, text_length);
369        }
370      else
371        {
372          width = XTextWidth16 (xfont, (XChar2b *) text, text_length / 2);
373        }
374      break;
375    case GDK_FONT_FONTSET:
376      fontset = (XFontSet) private->xfont;
377      width = XmbTextEscapement (fontset, text, text_length);
378      break;
379    default:
380      width = 0;
381    }
382  return width;
383}
384
385gint
386gdk_text_width_wc (GdkFont        *font,
387                   const GdkWChar *text,
388                   gint            text_length)
389{
390  GdkFontPrivate *private;
391  gint width;
392  XFontSet fontset;
393
394  g_return_val_if_fail (font != NULL, -1);
395  g_return_val_if_fail (text != NULL, -1);
396
397  private = (GdkFontPrivate*) font;
398
399  switch (font->type)
400    {
401    case GDK_FONT_FONT:
402      {
403        gchar *glyphs;
404        int glyphs_len;
405
406        if (_gdk_font_wc_to_glyphs (font, text, text_length,
407                                    &glyphs, &glyphs_len))
408          {
409            width = gdk_text_width (font, glyphs, glyphs_len);
410            g_free (glyphs);
411          }
412        else
413          width = 0;
414
415        break;
416      }
417    case GDK_FONT_FONTSET:
418      if (sizeof(GdkWChar) == sizeof(wchar_t))
419        {
420          fontset = (XFontSet) private->xfont;
421          width = XwcTextEscapement (fontset, (wchar_t *)text, text_length);
422        }
423      else
424        {
425          wchar_t *text_wchar;
426          gint i;
427          fontset = (XFontSet) private->xfont;
428          text_wchar = g_new(wchar_t, text_length);
429          for (i=0; i<text_length; i++) text_wchar[i] = text[i];
430          width = XwcTextEscapement (fontset, text_wchar, text_length);
431          g_free (text_wchar);
432        }
433      break;
434    default:
435      width = 0;
436    }
437  return width;
438}
439
440/* Problem: What if a character is a 16 bits character ?? */
441gint
442gdk_char_width (GdkFont *font,
443                gchar    character)
444{
445  GdkFontPrivate *private;
446  XCharStruct *chars;
447  gint width;
448  guint ch = character & 0xff;  /* get rid of sign-extension */
449  XFontStruct *xfont;
450  XFontSet fontset;
451
452  g_return_val_if_fail (font != NULL, -1);
453
454  private = (GdkFontPrivate*) font;
455
456  switch (font->type)
457    {
458    case GDK_FONT_FONT:
459      /* only 8 bits characters are considered here */
460      xfont = (XFontStruct *) private->xfont;
461      if ((xfont->min_byte1 == 0) &&
462          (xfont->max_byte1 == 0) &&
463          (ch >= xfont->min_char_or_byte2) &&
464          (ch <= xfont->max_char_or_byte2))
465        {
466          chars = xfont->per_char;
467          if (chars)
468            width = chars[ch - xfont->min_char_or_byte2].width;
469          else
470            width = xfont->min_bounds.width;
471        }
472      else
473        {
474          width = XTextWidth (xfont, &character, 1);
475        }
476      break;
477    case GDK_FONT_FONTSET:
478      fontset = (XFontSet) private->xfont;
479      width = XmbTextEscapement (fontset, &character, 1) ;
480      break;
481    default:
482      width = 0;
483    }
484  return width;
485}
486
487gint
488gdk_char_width_wc (GdkFont *font,
489                   GdkWChar character)
490{
491  GdkFontPrivate *private;
492  gint width;
493  XFontSet fontset;
494
495  g_return_val_if_fail (font != NULL, -1);
496
497  private = (GdkFontPrivate*) font;
498
499  switch (font->type)
500    {
501    case GDK_FONT_FONT:
502#ifdef USE_NATIVE_LOCALE
503      if (MB_CUR_MAX == 1 && FONT_IS_8BIT(private))
504        {
505          char c;
506          g_assert (wctomb(&c,character) == 1);
507
508          return gdk_char_width (font, c);
509        }
510      else
511#endif /* USE_NATIVE_LOCALE */
512        {
513          gchar *glyphs;
514          int glyphs_len;
515
516          if (_gdk_font_wc_to_glyphs (font, &character, 1, &glyphs, &glyphs_len))
517            {
518              width = gdk_text_width (font, glyphs, glyphs_len);
519              g_free (glyphs);
520            }
521          else
522            width = 0;
523         
524          break;
525        }
526    case GDK_FONT_FONTSET:
527      fontset = (XFontSet) private->xfont;
528      {
529        wchar_t char_wc = character;
530        width = XwcTextEscapement (fontset, &char_wc, 1) ;
531      }
532      break;
533    default:
534      width = 0;
535    }
536  return width;
537}
538
539gint
540gdk_string_measure (GdkFont     *font,
541                    const gchar *string)
542{
543  g_return_val_if_fail (font != NULL, -1);
544  g_return_val_if_fail (string != NULL, -1);
545
546  return gdk_text_measure (font, string, strlen (string));
547}
548
549void
550gdk_text_extents (GdkFont     *font,
551                  const gchar *text,
552                  gint         text_length,
553                  gint        *lbearing,
554                  gint        *rbearing,
555                  gint        *width,
556                  gint        *ascent,
557                  gint        *descent)
558{
559  GdkFontPrivate *private;
560  XCharStruct overall;
561  XFontStruct *xfont;
562  XFontSet    fontset;
563  XRectangle  ink, logical;
564  int direction;
565  int font_ascent;
566  int font_descent;
567
568  g_return_if_fail (font != NULL);
569  g_return_if_fail (text != NULL);
570
571  private = (GdkFontPrivate*) font;
572
573  switch (font->type)
574    {
575    case GDK_FONT_FONT:
576      xfont = (XFontStruct *) private->xfont;
577      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
578        {
579          XTextExtents (xfont, text, text_length,
580                        &direction, &font_ascent, &font_descent,
581                        &overall);
582        }
583      else
584        {
585          XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
586                          &direction, &font_ascent, &font_descent,
587                          &overall);
588        }
589      if (lbearing)
590        *lbearing = overall.lbearing;
591      if (rbearing)
592        *rbearing = overall.rbearing;
593      if (width)
594        *width = overall.width;
595      if (ascent)
596        *ascent = overall.ascent;
597      if (descent)
598        *descent = overall.descent;
599      break;
600    case GDK_FONT_FONTSET:
601      fontset = (XFontSet) private->xfont;
602      XmbTextExtents (fontset, text, text_length, &ink, &logical);
603      if (lbearing)
604        *lbearing = ink.x;
605      if (rbearing)
606        *rbearing = ink.x + ink.width;
607      if (width)
608        *width = logical.width;
609      if (ascent)
610        *ascent = -ink.y;
611      if (descent)
612        *descent = ink.y + ink.height;
613      break;
614    }
615
616}
617
618void
619gdk_text_extents_wc (GdkFont        *font,
620                     const GdkWChar *text,
621                     gint            text_length,
622                     gint           *lbearing,
623                     gint           *rbearing,
624                     gint           *width,
625                     gint           *ascent,
626                     gint           *descent)
627{
628  GdkFontPrivate *private;
629  XFontSet    fontset;
630  XRectangle  ink, logical;
631
632  g_return_if_fail (font != NULL);
633  g_return_if_fail (text != NULL);
634
635  private = (GdkFontPrivate*) font;
636
637  switch (font->type)
638    {
639    case GDK_FONT_FONT:
640      {
641        gchar *glyphs;
642        int glyphs_len;
643
644        if (_gdk_font_wc_to_glyphs (font, text, text_length,
645                                    &glyphs, &glyphs_len))
646          {
647            gdk_text_extents (font, glyphs, glyphs_len,
648                              lbearing, rbearing, width, ascent, descent);
649            g_free (glyphs);
650          }
651        else
652          {
653            if (lbearing)
654              *lbearing = 0;
655            if (rbearing)
656              *rbearing = 0;
657            if (width)
658              *width = 0;
659            if (ascent)
660              *ascent = 0;
661            if (descent)
662              *descent = 0;
663          }
664
665        break;
666      }
667    case GDK_FONT_FONTSET:
668      fontset = (XFontSet) private->xfont;
669
670      if (sizeof(GdkWChar) == sizeof(wchar_t))
671        XwcTextExtents (fontset, (wchar_t *)text, text_length, &ink, &logical);
672      else
673        {
674          wchar_t *text_wchar;
675          gint i;
676         
677          text_wchar = g_new (wchar_t, text_length);
678          for (i = 0; i < text_length; i++)
679            text_wchar[i] = text[i];
680          XwcTextExtents (fontset, text_wchar, text_length, &ink, &logical);
681          g_free (text_wchar);
682        }
683      if (lbearing)
684        *lbearing = ink.x;
685      if (rbearing)
686        *rbearing = ink.x + ink.width;
687      if (width)
688        *width = logical.width;
689      if (ascent)
690        *ascent = -ink.y;
691      if (descent)
692        *descent = ink.y + ink.height;
693      break;
694    }
695
696}
697
698void
699gdk_string_extents (GdkFont     *font,
700                    const gchar *string,
701                    gint        *lbearing,
702                    gint        *rbearing,
703                    gint        *width,
704                    gint        *ascent,
705                    gint        *descent)
706{
707  g_return_if_fail (font != NULL);
708  g_return_if_fail (string != NULL);
709
710  gdk_text_extents (font, string, strlen (string),
711                    lbearing, rbearing, width, ascent, descent);
712}
713
714
715gint
716gdk_text_measure (GdkFont     *font,
717                  const gchar *text,
718                  gint         text_length)
719{
720  GdkFontPrivate *private;
721  XCharStruct overall;
722  XFontStruct *xfont;
723  XFontSet    fontset;
724  XRectangle  ink, log;
725  int direction;
726  int font_ascent;
727  int font_descent;
728  gint width;
729
730  g_return_val_if_fail (font != NULL, -1);
731  g_return_val_if_fail (text != NULL, -1);
732
733  private = (GdkFontPrivate*) font;
734
735  switch (font->type)
736    {
737    case GDK_FONT_FONT:
738      xfont = (XFontStruct *) private->xfont;
739      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
740        {
741          XTextExtents (xfont, text, text_length,
742                        &direction, &font_ascent, &font_descent,
743                        &overall);
744        }
745      else
746        {
747          XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
748                          &direction, &font_ascent, &font_descent,
749                          &overall);
750        }
751      width = overall.rbearing;
752      break;
753    case GDK_FONT_FONTSET:
754      fontset = (XFontSet) private->xfont;
755      XmbTextExtents (fontset, text, text_length, &ink, &log);
756      width = ink.x + ink.width;
757      break;
758    default:
759      width = 0;
760    }
761  return width;
762}
763
764gint
765gdk_char_measure (GdkFont *font,
766                  gchar    character)
767{
768  g_return_val_if_fail (font != NULL, -1);
769
770  return gdk_text_measure (font, &character, 1);
771}
772
773gint
774gdk_string_height (GdkFont     *font,
775                   const gchar *string)
776{
777  g_return_val_if_fail (font != NULL, -1);
778  g_return_val_if_fail (string != NULL, -1);
779
780  return gdk_text_height (font, string, strlen (string));
781}
782
783gint
784gdk_text_height (GdkFont     *font,
785                 const gchar *text,
786                 gint         text_length)
787{
788  GdkFontPrivate *private;
789  XCharStruct overall;
790  XFontStruct *xfont;
791  XFontSet    fontset;
792  XRectangle  ink, log;
793  int direction;
794  int font_ascent;
795  int font_descent;
796  gint height;
797
798  g_return_val_if_fail (font != NULL, -1);
799  g_return_val_if_fail (text != NULL, -1);
800
801  private = (GdkFontPrivate*) font;
802
803  switch (font->type)
804    {
805    case GDK_FONT_FONT:
806      xfont = (XFontStruct *) private->xfont;
807      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
808        {
809          XTextExtents (xfont, text, text_length,
810                        &direction, &font_ascent, &font_descent,
811                        &overall);
812        }
813      else
814        {
815          XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
816                          &direction, &font_ascent, &font_descent,
817                          &overall);
818        }
819      height = overall.ascent + overall.descent;
820      break;
821    case GDK_FONT_FONTSET:
822      fontset = (XFontSet) private->xfont;
823      XmbTextExtents (fontset, text, text_length, &ink, &log);
824      height = log.height;
825      break;
826    default:
827      height = 0;
828    }
829  return height;
830}
831
832gint
833gdk_char_height (GdkFont *font,
834                 gchar    character)
835{
836  g_return_val_if_fail (font != NULL, -1);
837
838  return gdk_text_height (font, &character, 1);
839}
840
841gboolean
842_gdk_font_wc_to_glyphs (GdkFont        *font,
843                        const GdkWChar *text,
844                        gint            text_length,
845                        gchar         **result,
846                        gint           *result_length)
847{
848  XFontStruct *xfont;
849  GdkFontPrivate *font_private = (GdkFontPrivate*) font;
850
851  g_return_val_if_fail (font != NULL, FALSE);
852  g_return_val_if_fail (font->type == GDK_FONT_FONT, FALSE);
853
854  xfont = (XFontStruct *) font_private->xfont;
855
856  if (FONT_IS_8BIT (font_private))
857    {
858      /* 8-bit font, assume that we are in a 8-bit locale,
859       * and convert to bytes using wcstombs.
860       */
861      char *mbstr = _gdk_wcstombs_len (text, text_length);
862
863      if (result_length)
864        *result_length = mbstr ? strlen (mbstr) : 0;
865
866      if (result)
867        *result = mbstr;
868      else
869        g_free (mbstr);
870
871      return mbstr != NULL;
872    }
873  else
874    {
875      /* 16-bit font. Who knows what was intended? Make a random
876       * guess.
877       */
878      XChar2b *result2b = g_new (XChar2b, text_length + 1);
879      gint i;
880
881      for (i = 0; i < text_length; i++)
882        {
883          result2b[i].byte1 = text[i] / 256;
884          result2b[i].byte2 = text[i] % 256;
885        }
886
887      result2b[i].byte1 = result2b[i].byte2 = 0;
888
889      if (result)
890        *result = (gchar *)result2b;
891
892      if (result_length)
893        *result_length = text_length;
894
895      return TRUE;
896    }
897}
Note: See TracBrowser for help on using the repository browser.