1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-2002 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #include <pango/pangowin32.h>
35 #include "gdkpango.h" /* gdk_pango_context_get() */
36 #include "gdkdisplay.h"
37 #include "gdkprivate-win32.h"
39 static GHashTable *font_name_hash = NULL;
40 static GHashTable *fontset_name_hash = NULL;
43 gdk_font_hash_insert (GdkFontType type,
45 const gchar *font_name)
47 GdkFontPrivateWin32 *private = (GdkFontPrivateWin32 *) font;
48 GHashTable **hashp = (type == GDK_FONT_FONT) ?
49 &font_name_hash : &fontset_name_hash;
52 *hashp = g_hash_table_new (g_str_hash, g_str_equal);
54 private->names = g_slist_prepend (private->names, g_strdup (font_name));
55 g_hash_table_insert (*hashp, private->names->data, font);
59 gdk_font_hash_remove (GdkFontType type,
62 GdkFontPrivateWin32 *private = (GdkFontPrivateWin32 *) font;
64 GHashTable *hash = (type == GDK_FONT_FONT) ?
65 font_name_hash : fontset_name_hash;
67 tmp_list = private->names;
70 g_hash_table_remove (hash, tmp_list->data);
71 g_free (tmp_list->data);
73 tmp_list = tmp_list->next;
76 g_slist_free (private->names);
77 private->names = NULL;
81 gdk_font_hash_lookup (GdkFontType type,
82 const gchar *font_name)
85 GHashTable *hash = (type == GDK_FONT_FONT) ?
86 font_name_hash : fontset_name_hash;
92 result = g_hash_table_lookup (hash, font_name);
94 gdk_font_ref (result);
101 charset_name (DWORD charset)
105 case ANSI_CHARSET: return "ansi";
106 case DEFAULT_CHARSET: return "default";
107 case SYMBOL_CHARSET: return "symbol";
108 case SHIFTJIS_CHARSET: return "shiftjis";
109 case HANGEUL_CHARSET: return "hangeul";
110 case GB2312_CHARSET: return "gb2312";
111 case CHINESEBIG5_CHARSET: return "big5";
112 case JOHAB_CHARSET: return "johab";
113 case HEBREW_CHARSET: return "hebrew";
114 case ARABIC_CHARSET: return "arabic";
115 case GREEK_CHARSET: return "greek";
116 case TURKISH_CHARSET: return "turkish";
117 case VIETNAMESE_CHARSET: return "vietnamese";
118 case THAI_CHARSET: return "thai";
119 case EASTEUROPE_CHARSET: return "easteurope";
120 case RUSSIAN_CHARSET: return "russian";
121 case MAC_CHARSET: return "mac";
122 case BALTIC_CHARSET: return "baltic";
127 static gint num_fonts;
128 static gint font_names_size;
129 static gchar **xfontnames;
132 logfont_to_xlfd (const LOGFONT *lfp,
138 const gchar *registry, *encoding;
140 static int logpixelsy = 0;
141 gchar facename[LF_FACESIZE*5];
142 gchar *utf8_facename;
148 logpixelsy = GetDeviceCaps (gdk_display_hdc, LOGPIXELSY);
151 if (lfp->lfWeight >= FW_HEAVY)
153 else if (lfp->lfWeight >= FW_EXTRABOLD)
154 weight = "extrabold";
155 else if (lfp->lfWeight >= FW_BOLD)
158 else if (lfp->lfWeight >= FW_DEMIBOLD)
161 else if (lfp->lfWeight >= FW_MEDIUM)
163 else if (lfp->lfWeight >= FW_NORMAL)
165 else if (lfp->lfWeight >= FW_LIGHT)
167 else if (lfp->lfWeight >= FW_EXTRALIGHT)
168 weight = "extralight";
169 else if (lfp->lfWeight >= FW_THIN)
174 switch (lfp->lfCharSet)
177 registry = "iso8859";
180 case SHIFTJIS_CHARSET:
181 registry = "jisx0208.1983";
184 case HANGEUL_CHARSET:
185 registry = "ksc5601.1987";
189 registry = "gb2312.1980";
192 case CHINESEBIG5_CHARSET:
197 registry = "iso8859";
200 case TURKISH_CHARSET:
201 registry = "iso8859";
204 #if 0 /* Not a good idea, I think, to use ISO8859-8 and -6 for the Windows
205 * hebrew and arabic codepages, they differ too much.
208 registry = "iso8859";
212 registry = "iso8859";
217 registry = "microsoft";
218 encoding = charset_name (lfp->lfCharSet);
221 point_size = (int) (((double) size/logpixelsy) * 720.);
226 /* Convert the facename Windows fives us from the locale-dependent
229 utf8_facename = g_filename_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
231 /* Replace characters illegal in an XLFD with hex escapes. */
236 if (*q == '-' || *q == '*' || *q == '?' || *q == '%')
237 p += sprintf (p, "%%%.02x", *q);
243 g_free (utf8_facename);
245 return g_strdup_printf
246 ("-%s-%s-%s-%s-%s-%s-%d-%d-%d-%d-%s-%d-%s-%s",
251 ((lfp->lfPitchAndFamily & 0xF0) == FF_ROMAN
252 || (lfp->lfPitchAndFamily & 0xF0) == FF_SCRIPT ?
260 ((lfp->lfPitchAndFamily & 0x03) == FIXED_PITCH ? "m" : "p"),
266 gdk_font_full_name_get (GdkFont *font)
268 GdkFontPrivateWin32 *private;
269 GdkWin32SingleFont *singlefont;
276 g_return_val_if_fail (font != NULL, NULL);
278 private = (GdkFontPrivateWin32 *) font;
280 list = private->fonts;
281 string = g_string_new ("");
285 singlefont = (GdkWin32SingleFont *) list->data;
287 if (GetObject (singlefont->hfont, sizeof (LOGFONT), &logfont) == 0)
289 WIN32_GDI_FAILED ("GetObject");
293 xlfd = logfont_to_xlfd (&logfont, logfont.lfHeight, -1, 0);
294 string = g_string_append (string, xlfd);
298 string = g_string_append_c (string, ',');
300 result = string->str;
301 g_string_free (string, FALSE);
306 gdk_font_full_name_free (gchar *name)
312 pattern_match (const gchar *pattern,
315 const gchar *p = pattern, *n = string;
318 /* Common case first */
319 if ((pattern[0] == '*'
320 && pattern[1] == '\0')
321 || (pattern[0] == '-'
323 && pattern[2] == '\0'))
326 while ((c = *p++) != '\0')
338 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
339 if (c == '?' && *n == '\0')
346 for (--p; *n != '\0'; ++n)
347 if (tolower (*n) == c1
348 && pattern_match (p, n))
353 if (c != tolower (*n))
367 InnerEnumFontFamExProc (const LOGFONT *lfp,
368 const TEXTMETRIC *metrics,
375 if (fontType == TRUETYPE_FONTTYPE)
381 size = lfp->lfHeight;
384 xlfd = logfont_to_xlfd (lfp, size, 0, 0);
386 if (!pattern_match ((gchar *) lParam, xlfd))
393 if (num_fonts == font_names_size)
395 font_names_size *= 2;
396 xfontnames = g_realloc (xfontnames, font_names_size * sizeof (gchar *));
398 xfontnames[num_fonts-1] = xlfd;
404 EnumFontFamExProc (const LOGFONT *lfp,
405 const TEXTMETRIC *metrics,
409 if (fontType == TRUETYPE_FONTTYPE)
415 EnumFontFamiliesEx (gdk_display_hdc, &lf, InnerEnumFontFamExProc, lParam, 0);
418 InnerEnumFontFamExProc (lfp, metrics, fontType, lParam);
424 gdk_font_list_new (const gchar *font_pattern,
431 font_names_size = 100;
432 xfontnames = g_new (gchar *, font_names_size);
433 memset (&logfont, 0, sizeof (logfont));
434 logfont.lfCharSet = DEFAULT_CHARSET;
435 EnumFontFamiliesEx (gdk_display_hdc, &logfont, EnumFontFamExProc,
436 (LPARAM) font_pattern, 0);
438 result = g_new (gchar *, num_fonts + 1);
439 memmove (result, xfontnames, num_fonts * sizeof (gchar *));
440 result[num_fonts] = NULL;
443 *n_returned = num_fonts;
448 gdk_font_list_free (gchar **font_list)
450 g_strfreev (font_list);
453 /* This table classifies Unicode characters according to the Microsoft
454 * Unicode subset numbering. This is based on the table in "Developing
455 * International Software for Windows 95 and Windows NT". This is almost,
456 * but not quite, the same as the official Unicode block table in
457 * Blocks.txt from ftp.unicode.org. The bit number field is the bitfield
458 * number as in the FONTSIGNATURE struct's fsUsb field.
459 * There are some grave bugs in the table in the books. For instance
460 * it claims there are Hangul at U+3400..U+4DFF while this range in
461 * fact contains CJK Unified Ideographs Extension A. Also, the whole
462 * block of Hangul Syllables U+AC00..U+D7A3 is missing from the book.
468 U_LATIN_1_SUPPLEMENT = 1,
469 U_LATIN_EXTENDED_A = 2,
470 U_LATIN_EXTENDED_B = 3,
471 U_IPA_EXTENSIONS = 4,
472 U_SPACING_MODIFIER_LETTERS = 5,
473 U_COMBINING_DIACRITICAL_MARKS = 6,
475 U_GREEK_SYMBOLS_AND_COPTIC = 8,
478 U_HEBREW_EXTENDED = 12,
481 U_ARABIC_EXTENDED = 14,
493 U_GEORGIAN_EXTENDED = 27,
494 U_BASIC_GEORGIAN = 26,
496 U_LATIN_EXTENDED_ADDITIONAL = 29,
497 U_GREEK_EXTENDED = 30,
498 U_GENERAL_PUNCTUATION = 31,
499 U_SUPERSCRIPTS_AND_SUBSCRIPTS = 32,
500 U_CURRENCY_SYMBOLS = 33,
501 U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS = 34,
502 U_LETTERLIKE_SYMBOLS = 35,
505 U_MATHEMATICAL_OPERATORS = 38,
506 U_MISCELLANEOUS_TECHNICAL = 39,
507 U_CONTROL_PICTURES = 40,
508 U_OPTICAL_CHARACTER_RECOGNITION = 41,
509 U_ENCLOSED_ALPHANUMERICS = 42,
511 U_BLOCK_ELEMENTS = 44,
512 U_GEOMETRIC_SHAPES = 45,
513 U_MISCELLANEOUS_SYMBOLS = 46,
515 U_CJK_SYMBOLS_AND_PUNCTUATION = 48,
519 U_HANGUL_COMPATIBILITY_JAMO = 52,
520 U_CJK_MISCELLANEOUS = 53,
522 U_CJK_COMPATIBILITY = 55,
524 U_HANGUL_SUPPLEMENTARY_A = 57,
525 U_HANGUL_SUPPLEMENTARY_B = 58,
526 U_CJK_UNIFIED_IDEOGRAPHS = 59,
527 U_PRIVATE_USE_AREA = 60,
528 U_CJK_COMPATIBILITY_IDEOGRAPHS = 61,
529 U_ALPHABETIC_PRESENTATION_FORMS = 62,
530 U_ARABIC_PRESENTATION_FORMS_A = 63,
531 U_COMBINING_HALF_MARKS = 64,
532 U_CJK_COMPATIBILITY_FORMS = 65,
533 U_SMALL_FORM_VARIANTS = 66,
534 U_ARABIC_PRESENTATION_FORMS_B = 67,
536 U_HALFWIDTH_AND_FULLWIDTH_FORMS = 68,
547 U_BASIC_LATIN, "Basic Latin" },
549 U_LATIN_1_SUPPLEMENT, "Latin-1 Supplement" },
551 U_LATIN_EXTENDED_A, "Latin Extended-A" },
553 U_LATIN_EXTENDED_B, "Latin Extended-B" },
555 U_IPA_EXTENSIONS, "IPA Extensions" },
557 U_SPACING_MODIFIER_LETTERS, "Spacing Modifier Letters" },
559 U_COMBINING_DIACRITICAL_MARKS, "Combining Diacritical Marks" },
561 U_BASIC_GREEK, "Basic Greek" },
563 U_GREEK_SYMBOLS_AND_COPTIC, "Greek Symbols and Coptic" },
565 U_CYRILLIC, "Cyrillic" },
567 U_ARMENIAN, "Armenian" },
569 U_HEBREW_EXTENDED, "Hebrew Extended" },
571 U_BASIC_HEBREW, "Basic Hebrew" },
573 U_BASIC_ARABIC, "Basic Arabic" },
575 U_ARABIC_EXTENDED, "Arabic Extended" },
577 U_DEVANAGARI, "Devanagari" },
579 U_BENGALI, "Bengali" },
581 U_GURMUKHI, "Gurmukhi" },
583 U_GUJARATI, "Gujarati" },
589 U_TELUGU, "Telugu" },
591 U_KANNADA, "Kannada" },
593 U_MALAYALAM, "Malayalam" },
599 U_GEORGIAN_EXTENDED, "Georgian Extended" },
601 U_BASIC_GEORGIAN, "Basic Georgian" },
603 U_HANGUL_JAMO, "Hangul Jamo" },
605 U_LATIN_EXTENDED_ADDITIONAL, "Latin Extended Additional" },
607 U_GREEK_EXTENDED, "Greek Extended" },
609 U_GENERAL_PUNCTUATION, "General Punctuation" },
611 U_SUPERSCRIPTS_AND_SUBSCRIPTS, "Superscripts and Subscripts" },
613 U_CURRENCY_SYMBOLS, "Currency Symbols" },
615 U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS, "Combining Diacritical Marks for Symbols" },
617 U_LETTERLIKE_SYMBOLS, "Letterlike Symbols" },
619 U_NUMBER_FORMS, "Number Forms" },
621 U_ARROWS, "Arrows" },
623 U_MATHEMATICAL_OPERATORS, "Mathematical Operators" },
625 U_MISCELLANEOUS_TECHNICAL, "Miscellaneous Technical" },
627 U_CONTROL_PICTURES, "Control Pictures" },
629 U_OPTICAL_CHARACTER_RECOGNITION, "Optical Character Recognition" },
631 U_ENCLOSED_ALPHANUMERICS, "Enclosed Alphanumerics" },
633 U_BOX_DRAWING, "Box Drawing" },
635 U_BLOCK_ELEMENTS, "Block Elements" },
637 U_GEOMETRIC_SHAPES, "Geometric Shapes" },
639 U_MISCELLANEOUS_SYMBOLS, "Miscellaneous Symbols" },
641 U_DINGBATS, "Dingbats" },
643 U_CJK_SYMBOLS_AND_PUNCTUATION, "CJK Symbols and Punctuation" },
645 U_HIRAGANA, "Hiragana" },
647 U_KATAKANA, "Katakana" },
649 U_BOPOMOFO, "Bopomofo" },
651 U_HANGUL_COMPATIBILITY_JAMO, "Hangul Compatibility Jamo" },
653 U_CJK_MISCELLANEOUS, "CJK Miscellaneous" },
655 U_ENCLOSED_CJK, "Enclosed CJK" },
657 U_CJK_COMPATIBILITY, "CJK Compatibility" },
659 * U+3400..U+3D2D = Hangul
660 * U+3D2E..U+44B7 = Hangul Supplementary A
661 * U+44B8..U+4DFF = Hangul Supplementary B
662 * but actually in Unicode
663 * U+3400..U+4DB5 = CJK Unified Ideographs Extension A
666 U_CJK_UNIFIED_IDEOGRAPHS, "CJK Unified Ideographs Extension A" },
668 U_CJK_UNIFIED_IDEOGRAPHS, "CJK Unified Ideographs" },
669 /* This was missing completely from the book's table. */
671 U_HANGUL, "Hangul Syllables" },
673 U_PRIVATE_USE_AREA, "Private Use Area" },
675 U_CJK_COMPATIBILITY_IDEOGRAPHS, "CJK Compatibility Ideographs" },
677 U_ALPHABETIC_PRESENTATION_FORMS, "Alphabetic Presentation Forms" },
679 U_ARABIC_PRESENTATION_FORMS_A, "Arabic Presentation Forms-A" },
681 U_COMBINING_HALF_MARKS, "Combining Half Marks" },
683 U_CJK_COMPATIBILITY_FORMS, "CJK Compatibility Forms" },
685 U_SMALL_FORM_VARIANTS, "Small Form Variants" },
687 U_ARABIC_PRESENTATION_FORMS_B, "Arabic Presentation Forms-B" },
689 U_SPECIALS, "Specials" },
691 U_HALFWIDTH_AND_FULLWIDTH_FORMS, "Halfwidth and Fullwidth Forms" },
693 U_SPECIALS, "Specials" }
697 print_unicode_subranges (FONTSIGNATURE *fsp)
700 gboolean checked[G_N_ELEMENTS (utab)];
701 gboolean need_comma = FALSE;
703 memset (checked, 0, sizeof (checked));
705 for (i = 0; i < G_N_ELEMENTS (utab); i++)
707 && (fsp->fsUsb[utab[i].bit/32] & (1 << (utab[i].bit % 32))))
709 g_print ("%s %s", (need_comma ? "," : ""), utab[i].name);
719 check_unicode_subranges (UINT charset,
723 gboolean retval = FALSE;
725 /* If the fsUsb bit array has at least one of the bits set, trust it */
726 for (i = 0; i < U_LAST_PLUS_ONE; i++)
727 if (i != U_PRIVATE_USE_AREA && (fsp->fsUsb[i/32] & (1 << (i % 32))))
730 /* Otherwise, guess what subranges there should be in the font */
731 fsp->fsUsb[0] = fsp->fsUsb[1] = fsp->fsUsb[2] = fsp->fsUsb[3] = 0;
733 #define set_bit(bitno) (fsp->fsUsb[(bitno)/32] |= (1 << ((bitno) % 32)))
735 /* Set Unicode subrange bits based on code pages supported.
736 * This is mostly just guesswork.
739 #define check_cp(bit) (fsp->fsCsb[0] & (bit))
741 if (check_cp(FS_LATIN1))
743 set_bit (U_BASIC_LATIN);
744 set_bit (U_LATIN_1_SUPPLEMENT);
745 set_bit (U_CURRENCY_SYMBOLS);
748 if (check_cp (FS_LATIN2))
750 set_bit (U_BASIC_LATIN);
751 set_bit (U_LATIN_1_SUPPLEMENT);
752 set_bit (U_LATIN_EXTENDED_A);
753 set_bit (U_CURRENCY_SYMBOLS);
756 if (check_cp (FS_CYRILLIC))
758 set_bit (U_BASIC_LATIN);
759 set_bit (U_CYRILLIC);
762 if (check_cp (FS_GREEK))
764 set_bit (U_BASIC_LATIN);
765 set_bit (U_BASIC_GREEK);
768 if (check_cp (FS_TURKISH))
770 set_bit (U_BASIC_LATIN);
771 set_bit (U_LATIN_1_SUPPLEMENT);
772 set_bit (U_LATIN_EXTENDED_A);
773 set_bit (U_CURRENCY_SYMBOLS);
776 if (check_cp (FS_HEBREW))
778 set_bit (U_BASIC_LATIN);
779 set_bit (U_CURRENCY_SYMBOLS);
780 set_bit (U_BASIC_HEBREW);
781 set_bit (U_HEBREW_EXTENDED);
784 if (check_cp (FS_ARABIC))
786 set_bit (U_BASIC_LATIN);
787 set_bit (U_CURRENCY_SYMBOLS);
788 set_bit (U_BASIC_ARABIC);
789 set_bit (U_ARABIC_EXTENDED);
792 if (check_cp (FS_BALTIC))
794 set_bit (U_BASIC_LATIN);
795 set_bit (U_LATIN_1_SUPPLEMENT);
796 set_bit (U_CURRENCY_SYMBOLS);
797 set_bit (U_LATIN_EXTENDED_A);
798 set_bit (U_LATIN_EXTENDED_B);
801 if (check_cp (FS_VIETNAMESE))
804 set_bit (U_BASIC_LATIN);
807 if (check_cp (FS_THAI))
809 set_bit (U_BASIC_LATIN);
813 if (check_cp (FS_JISJAPAN))
815 /* Based on MS Gothic */
816 set_bit (U_BASIC_LATIN);
817 set_bit (U_CJK_SYMBOLS_AND_PUNCTUATION);
818 set_bit (U_HIRAGANA);
819 set_bit (U_KATAKANA);
820 set_bit (U_CJK_UNIFIED_IDEOGRAPHS);
821 set_bit (U_HALFWIDTH_AND_FULLWIDTH_FORMS);
824 if (check_cp (FS_CHINESESIMP))
826 /* Based on MS Hei */
827 set_bit (U_BASIC_LATIN);
828 set_bit (U_HIRAGANA);
829 set_bit (U_KATAKANA);
830 set_bit (U_BOPOMOFO);
831 set_bit (U_CJK_UNIFIED_IDEOGRAPHS);
834 if (check_cp (FS_WANSUNG)
835 || check_cp (FS_JOHAB)) /* ??? */
837 /* Based on GulimChe. I wonder if all Korean fonts
838 * really support this large range of Unicode subranges?
840 set_bit (U_BASIC_LATIN);
841 set_bit (U_LATIN_1_SUPPLEMENT);
842 set_bit (U_LATIN_EXTENDED_A);
843 set_bit (U_SPACING_MODIFIER_LETTERS);
844 set_bit (U_BASIC_GREEK);
845 set_bit (U_CYRILLIC);
846 set_bit (U_HANGUL_JAMO);
847 set_bit (U_GENERAL_PUNCTUATION);
848 set_bit (U_SUPERSCRIPTS_AND_SUBSCRIPTS);
849 set_bit (U_CURRENCY_SYMBOLS);
850 set_bit (U_LETTERLIKE_SYMBOLS);
851 set_bit (U_NUMBER_FORMS);
853 set_bit (U_MATHEMATICAL_OPERATORS);
854 set_bit (U_MISCELLANEOUS_TECHNICAL);
855 set_bit (U_ENCLOSED_ALPHANUMERICS);
856 set_bit (U_BOX_DRAWING);
857 set_bit (U_BLOCK_ELEMENTS);
858 set_bit (U_GEOMETRIC_SHAPES);
859 set_bit (U_MISCELLANEOUS_SYMBOLS);
860 set_bit (U_CJK_SYMBOLS_AND_PUNCTUATION);
861 set_bit (U_HIRAGANA);
862 set_bit (U_KATAKANA);
863 set_bit (U_HANGUL_COMPATIBILITY_JAMO);
864 set_bit (U_ENCLOSED_CJK);
865 set_bit (U_CJK_COMPATIBILITY_FORMS);
867 set_bit (U_CJK_UNIFIED_IDEOGRAPHS);
868 set_bit (U_CJK_COMPATIBILITY_IDEOGRAPHS);
869 set_bit (U_HALFWIDTH_AND_FULLWIDTH_FORMS);
872 if (check_cp (FS_CHINESETRAD))
874 /* Based on MingLiU */
875 set_bit (U_BASIC_LATIN);
876 set_bit (U_GENERAL_PUNCTUATION);
877 set_bit (U_BOX_DRAWING);
878 set_bit (U_BLOCK_ELEMENTS);
879 set_bit (U_CJK_SYMBOLS_AND_PUNCTUATION);
880 set_bit (U_BOPOMOFO);
881 set_bit (U_CJK_UNIFIED_IDEOGRAPHS);
882 set_bit (U_CJK_COMPATIBILITY_IDEOGRAPHS);
883 set_bit (U_SMALL_FORM_VARIANTS);
884 set_bit (U_HALFWIDTH_AND_FULLWIDTH_FORMS);
887 if (check_cp (FS_SYMBOL) || charset == MAC_CHARSET)
889 /* Non-Unicode encoding, I guess. Pretend it covers
890 * the single-byte range of values.
892 set_bit (U_BASIC_LATIN);
893 set_bit (U_LATIN_1_SUPPLEMENT);
900 GDK_NOTE (MISC, g_print ("... No code page bits set!\n"));
902 /* Sigh. Not even any code page bits were set. Guess based on
903 * charset, then. These somewhat optimistic guesses are based on the
904 * table in Appendix M in the book "Developing ..." mentioned
910 set_bit (U_BASIC_LATIN);
911 set_bit (U_LATIN_1_SUPPLEMENT);
912 set_bit (U_LATIN_EXTENDED_A);
913 set_bit (U_LATIN_EXTENDED_B);
914 set_bit (U_SPACING_MODIFIER_LETTERS);
915 set_bit (U_COMBINING_DIACRITICAL_MARKS);
916 set_bit (U_GENERAL_PUNCTUATION);
917 set_bit (U_SUPERSCRIPTS_AND_SUBSCRIPTS);
918 set_bit (U_CURRENCY_SYMBOLS);
919 #if 0 /* I find this too hard to believe... */
920 set_bit (U_BASIC_GREEK);
921 set_bit (U_CYRILLIC);
922 set_bit (U_BASIC_HEBREW);
923 set_bit (U_HEBREW_EXTENDED);
924 set_bit (U_BASIC_ARABIC);
925 set_bit (U_ARABIC_EXTENDED);
926 set_bit (U_LETTERLIKE_SYMBOLS);
927 set_bit (U_NUMBER_FORMS);
929 set_bit (U_MATHEMATICAL_OPERATORS);
930 set_bit (U_MISCELLANEOUS_TECHNICAL);
931 set_bit (U_ENCLOSED_ALPHANUMERICS);
932 set_bit (U_BOX_DRAWING);
933 set_bit (U_BLOCK_ELEMENTS);
934 set_bit (U_GEOMETRIC_SHAPES);
935 set_bit (U_MISCELLANEOUS_SYMBOLS);
936 set_bit (U_HIRAGANA);
937 set_bit (U_KATAKANA);
938 set_bit (U_BOPOMOFO);
939 set_bit (U_HANGUL_COMPATIBILITY_JAMO);
940 set_bit (U_CJK_MISCELLANEOUS);
941 set_bit (U_CJK_COMPATIBILITY);
943 set_bit (U_HANGUL_SUPPLEMENTARY_A);
944 set_bit (U_CJK_COMPATIBILITY_IDEOGRAPHS);
945 set_bit (U_ALPHABETIC_PRESENTATION_FORMS);
946 set_bit (U_SMALL_FORM_VARIANTS);
947 set_bit (U_ARABIC_PRESENTATION_FORMS_B);
948 set_bit (U_HALFWIDTH_AND_FULLWIDTH_FORMS);
949 set_bit (U_SPECIALS);
955 set_bit (U_BASIC_LATIN);
956 set_bit (U_LATIN_1_SUPPLEMENT);
959 case SHIFTJIS_CHARSET:
960 case HANGEUL_CHARSET:
962 case CHINESEBIG5_CHARSET:
964 /* The table really does claim these "locales" (it doesn't
965 * talk about charsets per se) cover the same Unicode
968 set_bit (U_BASIC_LATIN);
969 set_bit (U_LATIN_1_SUPPLEMENT);
970 set_bit (U_LATIN_EXTENDED_A);
971 set_bit (U_LATIN_EXTENDED_B);
972 set_bit (U_SPACING_MODIFIER_LETTERS);
973 set_bit (U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS);
974 set_bit (U_BASIC_GREEK);
975 set_bit (U_CYRILLIC);
976 set_bit (U_HANGUL_JAMO);
977 set_bit (U_GENERAL_PUNCTUATION);
978 set_bit (U_SUPERSCRIPTS_AND_SUBSCRIPTS);
979 set_bit (U_CURRENCY_SYMBOLS);
980 set_bit (U_LETTERLIKE_SYMBOLS);
981 set_bit (U_NUMBER_FORMS);
983 set_bit (U_MATHEMATICAL_OPERATORS);
984 set_bit (U_MISCELLANEOUS_TECHNICAL);
985 set_bit (U_ENCLOSED_ALPHANUMERICS);
986 set_bit (U_BOX_DRAWING);
987 set_bit (U_BLOCK_ELEMENTS);
988 set_bit (U_GEOMETRIC_SHAPES);
989 set_bit (U_MISCELLANEOUS_SYMBOLS);
990 set_bit (U_CJK_SYMBOLS_AND_PUNCTUATION);
991 set_bit (U_HIRAGANA);
992 set_bit (U_KATAKANA);
993 set_bit (U_BOPOMOFO);
994 set_bit (U_HANGUL_COMPATIBILITY_JAMO);
995 set_bit (U_CJK_MISCELLANEOUS);
996 set_bit (U_CJK_COMPATIBILITY);
998 set_bit (U_HANGUL_SUPPLEMENTARY_A);
999 set_bit (U_CJK_UNIFIED_IDEOGRAPHS);
1000 set_bit (U_CJK_COMPATIBILITY_IDEOGRAPHS);
1001 set_bit (U_ALPHABETIC_PRESENTATION_FORMS);
1002 set_bit (U_SMALL_FORM_VARIANTS);
1003 set_bit (U_ARABIC_PRESENTATION_FORMS_B);
1004 set_bit (U_SPECIALS);
1007 case HEBREW_CHARSET:
1008 set_bit (U_BASIC_LATIN);
1009 set_bit (U_LATIN_1_SUPPLEMENT);
1010 set_bit (U_LATIN_EXTENDED_B);
1011 set_bit (U_SPACING_MODIFIER_LETTERS);
1012 set_bit (U_BASIC_HEBREW);
1013 set_bit (U_HEBREW_EXTENDED);
1014 set_bit (U_GENERAL_PUNCTUATION);
1015 set_bit (U_LETTERLIKE_SYMBOLS);
1018 case ARABIC_CHARSET:
1019 set_bit (U_BASIC_LATIN);
1020 set_bit (U_LATIN_1_SUPPLEMENT);
1021 set_bit (U_LATIN_EXTENDED_A);
1022 set_bit (U_LATIN_EXTENDED_B);
1023 set_bit (U_SPACING_MODIFIER_LETTERS);
1024 set_bit (U_BASIC_GREEK);
1025 set_bit (U_BASIC_ARABIC);
1026 set_bit (U_ARABIC_EXTENDED);
1027 set_bit (U_GENERAL_PUNCTUATION);
1028 set_bit (U_LETTERLIKE_SYMBOLS);
1030 set_bit (U_MATHEMATICAL_OPERATORS);
1031 set_bit (U_MISCELLANEOUS_TECHNICAL);
1032 set_bit (U_BOX_DRAWING);
1033 set_bit (U_BLOCK_ELEMENTS);
1034 set_bit (U_GEOMETRIC_SHAPES);
1035 set_bit (U_MISCELLANEOUS_SYMBOLS);
1036 set_bit (U_HALFWIDTH_AND_FULLWIDTH_FORMS);
1040 set_bit (U_BASIC_LATIN);
1041 set_bit (U_LATIN_1_SUPPLEMENT);
1042 set_bit (U_LATIN_EXTENDED_B);
1043 set_bit (U_BASIC_GREEK);
1044 set_bit (U_GENERAL_PUNCTUATION);
1045 set_bit (U_SUPERSCRIPTS_AND_SUBSCRIPTS);
1046 set_bit (U_LETTERLIKE_SYMBOLS);
1048 set_bit (U_MATHEMATICAL_OPERATORS);
1049 set_bit (U_MISCELLANEOUS_TECHNICAL);
1050 set_bit (U_BOX_DRAWING);
1051 set_bit (U_BLOCK_ELEMENTS);
1052 set_bit (U_GEOMETRIC_SHAPES);
1053 set_bit (U_MISCELLANEOUS_SYMBOLS);
1056 case TURKISH_CHARSET:
1057 set_bit (U_BASIC_LATIN);
1058 set_bit (U_LATIN_1_SUPPLEMENT);
1059 set_bit (U_LATIN_EXTENDED_A);
1060 set_bit (U_LATIN_EXTENDED_B);
1061 set_bit (U_SPACING_MODIFIER_LETTERS);
1062 set_bit (U_BASIC_GREEK);
1063 set_bit (U_GENERAL_PUNCTUATION);
1064 set_bit (U_SUPERSCRIPTS_AND_SUBSCRIPTS);
1065 set_bit (U_CURRENCY_SYMBOLS);
1066 set_bit (U_LETTERLIKE_SYMBOLS);
1068 set_bit (U_MATHEMATICAL_OPERATORS);
1069 set_bit (U_MISCELLANEOUS_TECHNICAL);
1070 set_bit (U_BOX_DRAWING);
1071 set_bit (U_BLOCK_ELEMENTS);
1072 set_bit (U_GEOMETRIC_SHAPES);
1073 set_bit (U_MISCELLANEOUS_SYMBOLS);
1076 case VIETNAMESE_CHARSET:
1078 /* These are not in the table, so I have no idea */
1080 case BALTIC_CHARSET:
1081 set_bit (U_BASIC_LATIN);
1082 set_bit (U_LATIN_1_SUPPLEMENT);
1083 set_bit (U_LATIN_EXTENDED_A);
1084 set_bit (U_LATIN_EXTENDED_B);
1085 set_bit (U_SPACING_MODIFIER_LETTERS);
1086 set_bit (U_BASIC_GREEK);
1087 set_bit (U_GENERAL_PUNCTUATION);
1088 set_bit (U_SUPERSCRIPTS_AND_SUBSCRIPTS);
1089 set_bit (U_CURRENCY_SYMBOLS);
1090 set_bit (U_LETTERLIKE_SYMBOLS);
1092 set_bit (U_MATHEMATICAL_OPERATORS);
1093 set_bit (U_MISCELLANEOUS_TECHNICAL);
1094 set_bit (U_BOX_DRAWING);
1095 set_bit (U_BLOCK_ELEMENTS);
1096 set_bit (U_GEOMETRIC_SHAPES);
1097 set_bit (U_MISCELLANEOUS_SYMBOLS);
1100 case EASTEUROPE_CHARSET:
1101 set_bit (U_BASIC_LATIN);
1102 set_bit (U_LATIN_1_SUPPLEMENT);
1103 set_bit (U_LATIN_EXTENDED_A);
1104 set_bit (U_LATIN_EXTENDED_B);
1105 set_bit (U_SPACING_MODIFIER_LETTERS);
1106 set_bit (U_BASIC_GREEK);
1107 set_bit (U_GENERAL_PUNCTUATION);
1108 set_bit (U_SUPERSCRIPTS_AND_SUBSCRIPTS);
1109 set_bit (U_CURRENCY_SYMBOLS);
1110 set_bit (U_LETTERLIKE_SYMBOLS);
1112 set_bit (U_MATHEMATICAL_OPERATORS);
1113 set_bit (U_MISCELLANEOUS_TECHNICAL);
1114 set_bit (U_BOX_DRAWING);
1115 set_bit (U_BLOCK_ELEMENTS);
1116 set_bit (U_GEOMETRIC_SHAPES);
1117 set_bit (U_MISCELLANEOUS_SYMBOLS);
1120 case RUSSIAN_CHARSET:
1121 set_bit (U_BASIC_LATIN);
1122 set_bit (U_LATIN_1_SUPPLEMENT);
1123 set_bit (U_CYRILLIC);
1124 set_bit (U_GENERAL_PUNCTUATION);
1125 set_bit (U_LETTERLIKE_SYMBOLS);
1127 set_bit (U_MATHEMATICAL_OPERATORS);
1128 set_bit (U_MISCELLANEOUS_TECHNICAL);
1129 set_bit (U_BOX_DRAWING);
1130 set_bit (U_BLOCK_ELEMENTS);
1131 set_bit (U_GEOMETRIC_SHAPES);
1132 set_bit (U_MISCELLANEOUS_SYMBOLS);
1141 static GdkWin32SingleFont *
1142 gdk_font_load_logfont (LOGFONT *lfp)
1144 GdkWin32SingleFont *singlefont;
1152 for (tries = 0; ; tries++)
1154 GDK_NOTE (MISC, g_print ("... trying %ld,%ld,%ld,%ld,"
1157 "%d,%#.02x,\"%s\"\n",
1158 lfp->lfHeight, lfp->lfWidth,
1159 lfp->lfEscapement, lfp->lfOrientation,
1160 lfp->lfWeight, lfp->lfItalic,
1161 lfp->lfUnderline, lfp->lfStrikeOut,
1163 lfp->lfOutPrecision, lfp->lfClipPrecision,
1164 lfp->lfQuality, lfp->lfPitchAndFamily,
1166 hfont = CreateFontIndirect (lfp);
1171 /* If we fail, try some similar fonts often found on Windows. */
1174 if (g_strcasecmp (lfp->lfFaceName, "helvetica") == 0)
1175 strcpy (lfp->lfFaceName, "arial");
1176 else if (g_strcasecmp (lfp->lfFaceName, "new century schoolbook") == 0)
1177 strcpy (lfp->lfFaceName, "century schoolbook");
1178 else if (g_strcasecmp (lfp->lfFaceName, "courier") == 0)
1179 strcpy (lfp->lfFaceName, "courier new");
1180 else if (g_strcasecmp (lfp->lfFaceName, "lucida") == 0)
1181 strcpy (lfp->lfFaceName, "lucida sans unicode");
1182 else if (g_strcasecmp (lfp->lfFaceName, "lucidatypewriter") == 0)
1183 strcpy (lfp->lfFaceName, "lucida console");
1184 else if (g_strcasecmp (lfp->lfFaceName, "times") == 0)
1185 strcpy (lfp->lfFaceName, "times new roman");
1187 else if (tries == 1)
1189 if (g_strcasecmp (lfp->lfFaceName, "courier") == 0)
1191 strcpy (lfp->lfFaceName, "");
1192 lfp->lfPitchAndFamily |= FF_MODERN;
1194 else if (g_strcasecmp (lfp->lfFaceName, "times new roman") == 0)
1196 strcpy (lfp->lfFaceName, "");
1197 lfp->lfPitchAndFamily |= FF_ROMAN;
1199 else if (g_strcasecmp (lfp->lfFaceName, "helvetica") == 0
1200 || g_strcasecmp (lfp->lfFaceName, "lucida") == 0)
1202 strcpy (lfp->lfFaceName, "");
1203 lfp->lfPitchAndFamily |= FF_SWISS;
1207 strcpy (lfp->lfFaceName, "");
1208 lfp->lfPitchAndFamily = (lfp->lfPitchAndFamily & 0x0F) | FF_DONTCARE;
1219 singlefont = g_new (GdkWin32SingleFont, 1);
1220 singlefont->hfont = hfont;
1221 GetObject (singlefont->hfont, sizeof (logfont), &logfont);
1222 oldfont = SelectObject (gdk_display_hdc, singlefont->hfont);
1223 memset (&singlefont->fs, 0, sizeof (singlefont->fs));
1224 singlefont->charset = GetTextCharsetInfo (gdk_display_hdc, &singlefont->fs, 0);
1225 GetTextFace (gdk_display_hdc, sizeof (face), face);
1226 SelectObject (gdk_display_hdc, oldfont);
1227 if (TranslateCharsetInfo ((DWORD *) singlefont->charset, &csi,
1229 && singlefont->charset != MAC_CHARSET)
1230 singlefont->codepage = csi.ciACP;
1232 singlefont->codepage = 0;
1234 GDK_NOTE (MISC, (g_print ("... = %#x %s cs %s cp%d\n",
1235 (guint) singlefont->hfont, face,
1236 charset_name (singlefont->charset),
1237 singlefont->codepage),
1238 g_print ("... Unicode subranges:"),
1239 print_unicode_subranges (&singlefont->fs)));
1240 if (check_unicode_subranges (singlefont->charset, &singlefont->fs))
1241 GDK_NOTE (MISC, (g_print ("... Guesstimated Unicode subranges:"),
1242 print_unicode_subranges (&singlefont->fs)));
1247 static GdkWin32SingleFont *
1248 gdk_font_load_internal (const gchar *font_name)
1253 int numfields, n1, n2;
1254 char foundry[32], family[100], weight[32], slant[32], set_width[32],
1255 spacing[32], registry[32], encoding[32];
1256 char pixel_size[10], point_size[10], res_x[10], res_y[10], avg_width[10];
1261 g_return_val_if_fail (font_name != NULL, NULL);
1263 GDK_NOTE (MISC, g_print ("gdk_font_load_internal: %s\n", font_name));
1265 numfields = sscanf (font_name,
1266 "-%30[^-]-%100[^-]-%30[^-]-%30[^-]-%30[^-]-%n",
1275 /* Probably a plain Windows font name */
1276 logfont.lfHeight = 0;
1277 logfont.lfWidth = 0;
1278 logfont.lfEscapement = 0;
1279 logfont.lfOrientation = 0;
1280 logfont.lfWeight = FW_DONTCARE;
1281 logfont.lfItalic = FALSE;
1282 logfont.lfUnderline = FALSE;
1283 logfont.lfStrikeOut = FALSE;
1284 logfont.lfCharSet = ANSI_CHARSET;
1285 logfont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
1286 logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1287 logfont.lfQuality = PROOF_QUALITY;
1288 logfont.lfPitchAndFamily = DEFAULT_PITCH;
1289 fn = g_filename_from_utf8 (font_name, -1, NULL, NULL, NULL);
1290 strcpy (logfont.lfFaceName, fn);
1293 else if (numfields != 5)
1295 g_warning ("gdk_font_load: font name %s illegal", font_name);
1300 /* It must be a XLFD name */
1302 /* Check for hex escapes in the font family,
1303 * put in there by logfont_to_xlfd. Convert them in-place.
1308 if (*p == '%' && isxdigit (p[1]) && isxdigit (p[2]))
1310 sscanf (p+1, "%2x", &c);
1317 /* Skip add_style which often is empty in the requested font name */
1318 while (font_name[n1] && font_name[n1] != '-')
1322 numfields += sscanf (font_name + n1,
1323 "-%8[^-]-%8[^-]-%8[^-]-%8[^-]-%30[^-]-%8[^-]-%30[^-]-%30[^-]%n",
1334 if (numfields != 14 || font_name[n1 + n2] != '\0')
1336 g_warning ("gdk_font_load: font name %s illegal", font_name);
1340 logpixelsy = GetDeviceCaps (gdk_display_hdc, LOGPIXELSY);
1342 if (strcmp (pixel_size, "*") == 0)
1343 if (strcmp (point_size, "*") == 0)
1344 logfont.lfHeight = 0;
1346 logfont.lfHeight = (int) (((double) atoi (point_size))/720.*logpixelsy);
1348 logfont.lfHeight = atoi (pixel_size);
1350 logfont.lfWidth = 0;
1351 logfont.lfEscapement = 0;
1352 logfont.lfOrientation = 0;
1354 if (g_strcasecmp (weight, "thin") == 0)
1355 logfont.lfWeight = FW_THIN;
1356 else if (g_strcasecmp (weight, "extralight") == 0)
1357 logfont.lfWeight = FW_EXTRALIGHT;
1358 else if (g_strcasecmp (weight, "ultralight") == 0)
1359 #ifdef FW_ULTRALIGHT
1360 logfont.lfWeight = FW_ULTRALIGHT;
1362 logfont.lfWeight = FW_EXTRALIGHT; /* In fact, FW_ULTRALIGHT really is
1363 * defined as FW_EXTRALIGHT anyway.
1366 else if (g_strcasecmp (weight, "light") == 0)
1367 logfont.lfWeight = FW_LIGHT;
1368 else if (g_strcasecmp (weight, "normal") == 0)
1369 logfont.lfWeight = FW_NORMAL;
1370 else if (g_strcasecmp (weight, "regular") == 0)
1371 logfont.lfWeight = FW_REGULAR;
1372 else if (g_strcasecmp (weight, "medium") == 0)
1373 logfont.lfWeight = FW_MEDIUM;
1374 else if (g_strcasecmp (weight, "semibold") == 0)
1375 logfont.lfWeight = FW_SEMIBOLD;
1376 else if (g_strcasecmp (weight, "demibold") == 0)
1378 logfont.lfWeight = FW_DEMIBOLD;
1380 logfont.lfWeight = FW_SEMIBOLD; /* As above */
1382 else if (g_strcasecmp (weight, "bold") == 0)
1383 logfont.lfWeight = FW_BOLD;
1384 else if (g_strcasecmp (weight, "extrabold") == 0)
1385 logfont.lfWeight = FW_EXTRABOLD;
1386 else if (g_strcasecmp (weight, "ultrabold") == 0)
1388 logfont.lfWeight = FW_ULTRABOLD;
1390 logfont.lfWeight = FW_EXTRABOLD; /* As above */
1392 else if (g_strcasecmp (weight, "heavy") == 0)
1393 logfont.lfWeight = FW_HEAVY;
1394 else if (g_strcasecmp (weight, "black") == 0)
1396 logfont.lfWeight = FW_BLACK;
1398 logfont.lfWeight = FW_HEAVY; /* As above */
1401 logfont.lfWeight = FW_DONTCARE;
1403 if (g_strcasecmp (slant, "italic") == 0
1404 || g_strcasecmp (slant, "oblique") == 0
1405 || g_strcasecmp (slant, "i") == 0
1406 || g_strcasecmp (slant, "o") == 0)
1407 logfont.lfItalic = TRUE;
1409 logfont.lfItalic = FALSE;
1410 logfont.lfUnderline = FALSE;
1411 logfont.lfStrikeOut = FALSE;
1412 if (g_strcasecmp (registry, "iso8859") == 0)
1413 if (strcmp (encoding, "1") == 0)
1414 logfont.lfCharSet = ANSI_CHARSET;
1415 else if (strcmp (encoding, "2") == 0)
1416 logfont.lfCharSet = EASTEUROPE_CHARSET;
1417 else if (strcmp (encoding, "7") == 0)
1418 logfont.lfCharSet = GREEK_CHARSET;
1419 else if (strcmp (encoding, "8") == 0)
1420 logfont.lfCharSet = HEBREW_CHARSET;
1421 else if (strcmp (encoding, "9") == 0)
1422 logfont.lfCharSet = TURKISH_CHARSET;
1424 logfont.lfCharSet = ANSI_CHARSET; /* XXX ??? */
1425 else if (g_strcasecmp (registry, "jisx0208.1983") == 0)
1426 logfont.lfCharSet = SHIFTJIS_CHARSET;
1427 else if (g_strcasecmp (registry, "ksc5601.1987") == 0)
1428 logfont.lfCharSet = HANGEUL_CHARSET;
1429 else if (g_strcasecmp (registry, "gb2312.1980") == 0)
1430 logfont.lfCharSet = GB2312_CHARSET;
1431 else if (g_strcasecmp (registry, "big5") == 0)
1432 logfont.lfCharSet = CHINESEBIG5_CHARSET;
1433 else if (g_strcasecmp (registry, "windows") == 0
1434 || g_strcasecmp (registry, "microsoft") == 0)
1435 if (g_strcasecmp (encoding, "symbol") == 0)
1436 logfont.lfCharSet = SYMBOL_CHARSET;
1437 else if (g_strcasecmp (encoding, "shiftjis") == 0)
1438 logfont.lfCharSet = SHIFTJIS_CHARSET;
1439 else if (g_strcasecmp (encoding, "gb2312") == 0)
1440 logfont.lfCharSet = GB2312_CHARSET;
1441 else if (g_strcasecmp (encoding, "hangeul") == 0)
1442 logfont.lfCharSet = HANGEUL_CHARSET;
1443 else if (g_strcasecmp (encoding, "big5") == 0)
1444 logfont.lfCharSet = CHINESEBIG5_CHARSET;
1445 else if (g_strcasecmp (encoding, "johab") == 0)
1446 logfont.lfCharSet = JOHAB_CHARSET;
1447 else if (g_strcasecmp (encoding, "hebrew") == 0)
1448 logfont.lfCharSet = HEBREW_CHARSET;
1449 else if (g_strcasecmp (encoding, "arabic") == 0)
1450 logfont.lfCharSet = ARABIC_CHARSET;
1451 else if (g_strcasecmp (encoding, "greek") == 0)
1452 logfont.lfCharSet = GREEK_CHARSET;
1453 else if (g_strcasecmp (encoding, "turkish") == 0)
1454 logfont.lfCharSet = TURKISH_CHARSET;
1455 else if (g_strcasecmp (encoding, "easteurope") == 0)
1456 logfont.lfCharSet = EASTEUROPE_CHARSET;
1457 else if (g_strcasecmp (encoding, "russian") == 0)
1458 logfont.lfCharSet = RUSSIAN_CHARSET;
1459 else if (g_strcasecmp (encoding, "mac") == 0)
1460 logfont.lfCharSet = MAC_CHARSET;
1461 else if (g_strcasecmp (encoding, "baltic") == 0)
1462 logfont.lfCharSet = BALTIC_CHARSET;
1463 else if (g_strcasecmp (encoding, "cp1251") == 0)
1464 logfont.lfCharSet = RUSSIAN_CHARSET;
1466 logfont.lfCharSet = ANSI_CHARSET; /* XXX ??? */
1468 logfont.lfCharSet = ANSI_CHARSET; /* XXX ??? */
1469 logfont.lfOutPrecision = OUT_TT_PRECIS;
1470 logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1471 logfont.lfQuality = PROOF_QUALITY;
1472 if (g_strcasecmp (spacing, "m") == 0)
1473 logfont.lfPitchAndFamily = FIXED_PITCH;
1474 else if (g_strcasecmp (spacing, "p") == 0)
1475 logfont.lfPitchAndFamily = VARIABLE_PITCH;
1477 logfont.lfPitchAndFamily = DEFAULT_PITCH;
1478 fn = g_filename_from_utf8 (family, -1, NULL, NULL, NULL);
1479 strcpy (logfont.lfFaceName, fn);
1483 return gdk_font_load_logfont (&logfont);
1487 gdk_font_from_one_singlefont (GdkWin32SingleFont *singlefont)
1490 GdkFontPrivateWin32 *private;
1492 TEXTMETRIC textmetric;
1494 private = g_new (GdkFontPrivateWin32, 1);
1495 font = (GdkFont*) private;
1497 private->base.ref_count = 1;
1498 private->names = NULL;
1499 private->fonts = g_slist_append (NULL, singlefont);
1501 /* Pretend all fonts are fontsets... Gtktext and gtkentry work better
1502 * that way, they use wide chars, which is necessary for non-ASCII
1503 * chars to work. (Yes, even Latin-1, as we use Unicode internally.)
1505 font->type = GDK_FONT_FONTSET;
1506 oldfont = SelectObject (gdk_display_hdc, singlefont->hfont);
1507 GetTextMetrics (gdk_display_hdc, &textmetric);
1508 SelectObject (gdk_display_hdc, oldfont);
1509 font->ascent = textmetric.tmAscent;
1510 font->descent = textmetric.tmDescent;
1512 GDK_NOTE (MISC, g_print ("... asc %d desc %d\n",
1513 font->ascent, font->descent));
1519 gdk_font_load_for_display (GdkDisplay *display,
1520 const gchar *font_name)
1523 GdkFontPrivateWin32 *private;
1524 GdkWin32SingleFont *singlefont;
1526 TEXTMETRIC textmetric;
1528 g_return_val_if_fail (font_name != NULL, NULL);
1529 g_return_val_if_fail (display == gdk_display_get_default (), NULL);
1531 font = gdk_font_hash_lookup (GDK_FONT_FONTSET, font_name);
1535 private = g_new (GdkFontPrivateWin32, 1);
1536 font = (GdkFont*) private;
1538 singlefont = gdk_font_load_internal (font_name);
1540 private->base.ref_count = 1;
1541 private->names = NULL;
1542 private->fonts = g_slist_append (NULL, singlefont);
1544 /* Pretend all fonts are fontsets... Gtktext and gtkentry work better
1545 * that way, they use wide chars, which is necessary for non-ASCII
1546 * chars to work. (Yes, even Latin-1, as we use Unicode internally.)
1548 font->type = GDK_FONT_FONTSET;
1549 oldfont = SelectObject (gdk_display_hdc, singlefont->hfont);
1550 GetTextMetrics (gdk_display_hdc, &textmetric);
1551 SelectObject (gdk_display_hdc, oldfont);
1552 font->ascent = textmetric.tmAscent;
1553 font->descent = textmetric.tmDescent;
1555 GDK_NOTE (MISC, g_print ("... asc %d desc %d\n",
1556 font->ascent, font->descent));
1558 gdk_font_hash_insert (GDK_FONT_FONTSET, font, font_name);
1560 return gdk_font_from_one_singlefont (gdk_font_load_internal (font_name));
1564 * gdk_font_from_description:
1565 * @font_desc: a #PangoFontDescription.
1567 * Load a #GdkFont based on a Pango font description. This font will
1568 * only be an approximation of the Pango font, and
1569 * internationalization will not be handled correctly. This function
1570 * should only be used for legacy code that cannot be easily converted
1571 * to use Pango. Using Pango directly will produce better results.
1573 * Return value: the newly loaded font, or %NULL if the font
1577 gdk_font_from_description_for_display (GdkDisplay *display,
1578 PangoFontDescription *font_desc)
1580 PangoFontMap *font_map;
1582 GdkFont *result = NULL;
1584 g_return_val_if_fail (font_desc != NULL, NULL);
1585 g_return_val_if_fail (display == gdk_display_get_default (), NULL);
1587 font_map = pango_win32_font_map_for_display ();
1588 font = pango_font_map_load_font (font_map, gdk_pango_context_get (), font_desc);
1593 pango_win32_font_logfont (font);
1594 result = gdk_font_from_one_singlefont (gdk_font_load_logfont (lfp));
1597 g_object_unref (G_OBJECT (font));
1604 gdk_fontset_load (const gchar *fontset_name)
1607 GdkFontPrivateWin32 *private;
1608 GdkWin32SingleFont *singlefont;
1610 TEXTMETRIC textmetric;
1614 g_return_val_if_fail (fontset_name != NULL, NULL);
1616 font = gdk_font_hash_lookup (GDK_FONT_FONTSET, fontset_name);
1620 s = fs = g_strdup (fontset_name);
1621 while (*s && isspace (*s))
1624 g_return_val_if_fail (*s, NULL);
1626 private = g_new (GdkFontPrivateWin32, 1);
1627 font = (GdkFont*) private;
1629 private->base.ref_count = 1;
1630 private->names = NULL;
1631 private->fonts = NULL;
1633 font->type = GDK_FONT_FONTSET;
1639 if ((p = strchr (s, ',')) != NULL)
1644 while (isspace (b[-1]))
1647 singlefont = gdk_font_load_internal (s);
1650 private->fonts = g_slist_append (private->fonts, singlefont);
1651 oldfont = SelectObject (gdk_display_hdc, singlefont->hfont);
1652 GetTextMetrics (gdk_display_hdc, &textmetric);
1653 SelectObject (gdk_display_hdc, oldfont);
1654 font->ascent = MAX (font->ascent, textmetric.tmAscent);
1655 font->descent = MAX (font->descent, textmetric.tmDescent);
1660 while (*s && isspace (*s))
1671 gdk_font_hash_insert (GDK_FONT_FONTSET, font, fontset_name);
1677 _gdk_font_destroy (GdkFont *font)
1679 GdkFontPrivateWin32 *private = (GdkFontPrivateWin32 *) font;
1680 GdkWin32SingleFont *singlefont;
1683 singlefont = (GdkWin32SingleFont *) private->fonts->data;
1684 GDK_NOTE (MISC, g_print ("_gdk_font_destroy %#x\n",
1685 (guint)singlefont->hfont));
1687 gdk_font_hash_remove (font->type, font);
1692 DeleteObject (singlefont->hfont);
1695 case GDK_FONT_FONTSET:
1696 list = private->fonts;
1699 singlefont = (GdkWin32SingleFont *) list->data;
1700 DeleteObject (singlefont->hfont);
1704 g_slist_free (private->fonts);
1711 _gdk_font_strlen (GdkFont *font,
1714 g_return_val_if_fail (font != NULL, -1);
1715 g_return_val_if_fail (str != NULL, -1);
1717 return strlen (str);
1721 gdk_font_id (const GdkFont *font)
1723 const GdkFontPrivateWin32 *private;
1725 g_return_val_if_fail (font != NULL, 0);
1727 private = (const GdkFontPrivateWin32 *) font;
1729 if (font->type == GDK_FONT_FONT)
1730 return (gint) ((GdkWin32SingleFont *) private->fonts->data)->hfont;
1736 gdk_font_equal (const GdkFont *fonta,
1737 const GdkFont *fontb)
1739 const GdkFontPrivateWin32 *privatea;
1740 const GdkFontPrivateWin32 *privateb;
1742 g_return_val_if_fail (fonta != NULL, FALSE);
1743 g_return_val_if_fail (fontb != NULL, FALSE);
1745 privatea = (const GdkFontPrivateWin32 *) fonta;
1746 privateb = (const GdkFontPrivateWin32 *) fontb;
1748 if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
1749 return (((GdkWin32SingleFont *) privatea->fonts->data)->hfont
1750 == ((GdkWin32SingleFont *) privateb->fonts->data)->hfont);
1751 else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
1753 GSList *lista = privatea->fonts;
1754 GSList *listb = privateb->fonts;
1756 while (lista && listb)
1758 if (((GdkWin32SingleFont *) lista->data)->hfont
1759 != ((GdkWin32SingleFont *) listb->data)->hfont)
1761 lista = lista->next;
1762 listb = listb->next;
1773 /* Return the Unicode Subset bitfield number for a Unicode character */
1776 unicode_classify (wchar_t wc)
1779 int max = G_N_ELEMENTS (utab) - 1;
1784 mid = (min + max) / 2;
1785 if (utab[mid].high < wc)
1787 else if (wc < utab[mid].low)
1789 else if (utab[mid].low <= wc && wc <= utab[mid].high)
1790 return utab[mid].bit;
1794 /* Fallback... returning -1 might cause problems. Returning
1795 * U_BASIC_LATIN won't help handling strange characters, but won't
1798 return U_BASIC_LATIN;
1802 _gdk_wchar_text_handle (GdkFont *font,
1803 const wchar_t *wcstr,
1805 void (*handler)(GdkWin32SingleFont *,
1811 GdkFontPrivateWin32 *private;
1812 GdkWin32SingleFont *singlefont;
1815 const wchar_t *start, *end, *wcp;
1819 private = (GdkFontPrivateWin32 *) font;
1821 g_assert (private->base.ref_count > 0);
1823 GDK_NOTE (MISC, g_print ("_gdk_wchar_text_handle: "));
1827 /* Split Unicode string into pieces of the same class */
1829 block = unicode_classify (*wcp);
1830 while (wcp + 1 < end && unicode_classify (wcp[1]) == block)
1833 /* Find a font in the fontset that can handle this class */
1834 list = private->fonts;
1837 singlefont = (GdkWin32SingleFont *) list->data;
1839 if (singlefont->fs.fsUsb[block/32] & (1 << (block % 32)))
1848 GDK_NOTE (MISC, g_print ("%d:%d:%d:%#x ",
1849 start-wcstr, wcp-wcstr, block,
1850 (singlefont ? (guint) singlefont->hfont : 0)));
1852 /* Call the callback function */
1853 (*handler) (singlefont, start, wcp+1 - start, arg);
1856 GDK_NOTE (MISC, g_print ("\n"));
1862 } gdk_text_size_arg;
1865 gdk_text_size_handler (GdkWin32SingleFont *singlefont,
1866 const wchar_t *wcstr,
1872 gdk_text_size_arg *arg = (gdk_text_size_arg *) argp;
1877 if ((oldfont = SelectObject (gdk_display_hdc, singlefont->hfont)) == NULL)
1879 WIN32_GDI_FAILED ("SelectObject");
1882 GetTextExtentPoint32W (gdk_display_hdc, wcstr, wclen, &this_size);
1883 SelectObject (gdk_display_hdc, oldfont);
1885 arg->total.cx += this_size.cx;
1886 arg->total.cy = MAX (arg->total.cy, this_size.cy);
1890 gdk_text_size (GdkFont *font,
1893 gdk_text_size_arg *arg)
1898 g_return_val_if_fail (font != NULL, FALSE);
1899 g_return_val_if_fail (text != NULL, FALSE);
1901 if (text_length == 0)
1904 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
1906 wcstr = g_new (wchar_t, text_length);
1907 if (text_length == 1)
1909 /* For single characters, don't try to interpret as UTF-8.
1911 wcstr[0] = (guchar) text[0];
1912 _gdk_wchar_text_handle (font, wcstr, 1, gdk_text_size_handler, arg);
1916 if ((wlen = _gdk_utf8_to_ucs2 (wcstr, text, text_length, text_length)) == -1)
1917 g_warning ("gdk_text_size: _gdk_utf8_to_ucs2 failed");
1919 _gdk_wchar_text_handle (font, wcstr, wlen, gdk_text_size_handler, arg);
1928 gdk_text_width (GdkFont *font,
1932 gdk_text_size_arg arg;
1934 arg.total.cx = arg.total.cy = 0;
1936 if (!gdk_text_size (font, text, text_length, &arg))
1939 return arg.total.cx;
1943 gdk_text_width_wc (GdkFont *font,
1944 const GdkWChar *text,
1947 gdk_text_size_arg arg;
1951 g_return_val_if_fail (font != NULL, -1);
1952 g_return_val_if_fail (text != NULL, -1);
1954 if (text_length == 0)
1957 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
1959 if (sizeof (wchar_t) != sizeof (GdkWChar))
1961 wcstr = g_new (wchar_t, text_length);
1962 for (i = 0; i < text_length; i++)
1966 wcstr = (wchar_t *) text;
1968 arg.total.cx = arg.total.cy = 0;
1970 _gdk_wchar_text_handle (font, wcstr, text_length,
1971 gdk_text_size_handler, &arg);
1973 if (sizeof (wchar_t) != sizeof (GdkWChar))
1976 return arg.total.cx;
1980 gdk_text_extents (GdkFont *font,
1989 gdk_text_size_arg arg;
1993 g_return_if_fail (font != NULL);
1994 g_return_if_fail (text != NULL);
1996 if (text_length == 0)
2011 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
2013 arg.total.cx = arg.total.cy = 0;
2015 wcstr = g_new (wchar_t, text_length);
2016 if (text_length == 1)
2018 wcstr[0] = (guchar) text[0];
2019 _gdk_wchar_text_handle (font, wcstr, 1, gdk_text_size_handler, &arg);
2023 if ((wlen = _gdk_utf8_to_ucs2 (wcstr, text, text_length, text_length)) == -1)
2024 g_warning ("gdk_text_extents: _gdk_utf8_to_ucs2 failed");
2026 _gdk_wchar_text_handle (font, wcstr, wlen, gdk_text_size_handler, &arg);
2031 /* XXX This is quite bogus */
2035 *rbearing = arg.total.cx;
2036 /* What should be the difference between width and rbearing? */
2038 *width = arg.total.cx;
2040 *ascent = arg.total.cy + 1;
2042 *descent = font->descent + 1;
2046 gdk_text_extents_wc (GdkFont *font,
2047 const GdkWChar *text,
2055 gdk_text_size_arg arg;
2059 g_return_if_fail (font != NULL);
2060 g_return_if_fail (text != NULL);
2062 if (text_length == 0)
2077 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
2079 if (sizeof (wchar_t) != sizeof (GdkWChar))
2081 wcstr = g_new (wchar_t, text_length);
2082 for (i = 0; i < text_length; i++)
2086 wcstr = (wchar_t *) text;
2088 arg.total.cx = arg.total.cy = 0;
2090 _gdk_wchar_text_handle (font, wcstr, text_length,
2091 gdk_text_size_handler, &arg);
2093 if (sizeof (wchar_t) != sizeof (GdkWChar))
2096 /* XXX This is quite bogus */
2100 *rbearing = arg.total.cx;
2102 *width = arg.total.cx;
2104 *ascent = arg.total.cy + 1;
2106 *descent = font->descent + 1;