00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028
00029 #include <stdio.h>
00030 #include <ctype.h>
00031
00032 #include "gdkfont.h"
00033 #include "gdkwin32.h"
00034
00035 static GHashTable *font_name_hash = NULL;
00036 static GHashTable *fontset_name_hash = NULL;
00037
00038 static float gfont_angle = 0.0;
00039
00040 static void
00041 gdk_font_hash_insert(GdkFontType type,
00042 GdkFont * font, const gchar * font_name)
00043 {
00044 GdkFontPrivateWin32 *private = (GdkFontPrivateWin32 *) font;
00045 GHashTable **hashp = (type == GDK_FONT_FONT) ?
00046 &font_name_hash : &fontset_name_hash;
00047
00048 if (!*hashp)
00049 *hashp = g_hash_table_new(g_str_hash, g_str_equal);
00050
00051 private->names = g_slist_prepend(private->names, g_strdup(font_name));
00052 g_hash_table_insert(*hashp, private->names->data, font);
00053 }
00054
00055 static void gdk_font_hash_remove(GdkFontType type, GdkFont * font)
00056 {
00057 GdkFontPrivateWin32 *private = (GdkFontPrivateWin32 *) font;
00058 GSList *tmp_list;
00059 GHashTable *hash = (type == GDK_FONT_FONT) ?
00060 font_name_hash : fontset_name_hash;
00061
00062 tmp_list = private->names;
00063 while (tmp_list) {
00064 g_hash_table_remove(hash, tmp_list->data);
00065 g_free(tmp_list->data);
00066
00067 tmp_list = tmp_list->next;
00068 }
00069
00070 g_slist_free(private->names);
00071 private->names = NULL;
00072 }
00073
00074 static GdkFont *gdk_font_hash_lookup(GdkFontType type,
00075 const gchar * font_name)
00076 {
00077 GdkFont *result;
00078 GHashTable *hash = (type == GDK_FONT_FONT) ?
00079 font_name_hash : fontset_name_hash;
00080
00081 if (!hash)
00082 return NULL;
00083 else {
00084 result = g_hash_table_lookup(hash, font_name);
00085 if (result)
00086 gdk_font_ref(result);
00087
00088 return result;
00089 }
00090 }
00091
00092 static const char *charset_name(DWORD charset)
00093 {
00094 switch (charset) {
00095 case ANSI_CHARSET:
00096 return "ansi";
00097 case DEFAULT_CHARSET:
00098 return "default";
00099 case SYMBOL_CHARSET:
00100 return "symbol";
00101 case SHIFTJIS_CHARSET:
00102 return "shiftjis";
00103 case HANGEUL_CHARSET:
00104 return "hangeul";
00105 case GB2312_CHARSET:
00106 return "gb2312";
00107 case CHINESEBIG5_CHARSET:
00108 return "big5";
00109 case JOHAB_CHARSET:
00110 return "johab";
00111 case HEBREW_CHARSET:
00112 return "hebrew";
00113 case ARABIC_CHARSET:
00114 return "arabic";
00115 case GREEK_CHARSET:
00116 return "greek";
00117 case TURKISH_CHARSET:
00118 return "turkish";
00119 case VIETNAMESE_CHARSET:
00120 return "vietnamese";
00121 case THAI_CHARSET:
00122 return "thai";
00123 case EASTEUROPE_CHARSET:
00124 return "easteurope";
00125 case RUSSIAN_CHARSET:
00126 return "russian";
00127 case MAC_CHARSET:
00128 return "mac";
00129 case BALTIC_CHARSET:
00130 return "baltic";
00131 }
00132 return "unknown";
00133 }
00134
00135 static gint num_fonts;
00136 static gint font_names_size;
00137 static gchar **xfontnames;
00138
00139 static gchar *logfont_to_xlfd(const LOGFONT * lfp,
00140 int size, int res, int avg_width)
00141 {
00142 const gchar *weight;
00143 const gchar *registry, *encoding;
00144 int point_size;
00145 static int logpixelsy = 0;
00146 gchar facename[LF_FACESIZE * 5];
00147 gchar *utf8_facename;
00148 gchar *p;
00149 const gchar *q;
00150
00151 if (logpixelsy == 0) {
00152 logpixelsy = GetDeviceCaps(gdk_DC, LOGPIXELSY);
00153 }
00154
00155 if (lfp->lfWeight >= FW_HEAVY)
00156 weight = "heavy";
00157 else if (lfp->lfWeight >= FW_EXTRABOLD)
00158 weight = "extrabold";
00159 else if (lfp->lfWeight >= FW_BOLD)
00160 weight = "bold";
00161 #ifdef FW_DEMIBOLD
00162 else if (lfp->lfWeight >= FW_DEMIBOLD)
00163 weight = "demibold";
00164 #endif
00165 else if (lfp->lfWeight >= FW_MEDIUM)
00166 weight = "medium";
00167 else if (lfp->lfWeight >= FW_NORMAL)
00168 weight = "normal";
00169 else if (lfp->lfWeight >= FW_LIGHT)
00170 weight = "light";
00171 else if (lfp->lfWeight >= FW_EXTRALIGHT)
00172 weight = "extralight";
00173 else if (lfp->lfWeight >= FW_THIN)
00174 weight = "thin";
00175 else
00176 weight = "regular";
00177
00178 switch (lfp->lfCharSet) {
00179 case ANSI_CHARSET:
00180 registry = "iso8859";
00181 encoding = "1";
00182 break;
00183 case SHIFTJIS_CHARSET:
00184 registry = "jisx0208.1983";
00185 encoding = "0";
00186 break;
00187 case HANGEUL_CHARSET:
00188 registry = "ksc5601.1987";
00189 encoding = "0";
00190 break;
00191 case GB2312_CHARSET:
00192 registry = "gb2312.1980";
00193 encoding = "0";
00194 break;
00195 case CHINESEBIG5_CHARSET:
00196 registry = "big5";
00197 encoding = "0";
00198 break;
00199 case GREEK_CHARSET:
00200 registry = "iso8859";
00201 encoding = "7";
00202 break;
00203 case TURKISH_CHARSET:
00204 registry = "iso8859";
00205 encoding = "9";
00206 break;
00207 #if 0
00208
00209
00210 case HEBREW_CHARSET:
00211 registry = "iso8859";
00212 encoding = "8";
00213 break;
00214 case ARABIC_CHARSET:
00215 registry = "iso8859";
00216 encoding = "6";
00217 break;
00218 #endif
00219 default:
00220 registry = "microsoft";
00221 encoding = charset_name(lfp->lfCharSet);
00222 }
00223
00224 point_size = (int) (((double) size / logpixelsy) * 720.);
00225
00226 if (res == -1)
00227 res = logpixelsy;
00228
00229
00230
00231
00232 utf8_facename = g_filename_to_utf8(lfp->lfFaceName, NULL);
00233
00234
00235 p = facename;
00236 q = utf8_facename;
00237 while (*q) {
00238 if (*q == '-' || *q == '*' || *q == '?' || *q == '%')
00239 p += sprintf(p, "%%%.02x", *q);
00240 else
00241 *p++ = *q;
00242 q++;
00243 }
00244 *p = '\0';
00245 g_free(utf8_facename);
00246
00247 return g_strdup_printf
00248 ("-%s-%s-%s-%s-%s-%s-%d-%d-%d-%d-%s-%d-%s-%s",
00249 "unknown",
00250 facename,
00251 weight,
00252 (lfp->lfItalic ?
00253 ((lfp->lfPitchAndFamily & 0xF0) == FF_ROMAN
00254 || (lfp->lfPitchAndFamily & 0xF0) == FF_SCRIPT ?
00255 "i" : "o") : "r"),
00256 "normal",
00257 "",
00258 size,
00259 point_size,
00260 res,
00261 res,
00262 ((lfp->lfPitchAndFamily & 0x03) == FIXED_PITCH ? "m" : "p"),
00263 avg_width, registry, encoding);
00264 }
00265
00266 gchar *gdk_font_full_name_get(GdkFont * font)
00267 {
00268 GdkFontPrivateWin32 *private;
00269 GdkWin32SingleFont *singlefont;
00270 GSList *list;
00271 GString *string;
00272 gchar *result;
00273 gchar *xlfd;
00274 LOGFONT logfont;
00275
00276 g_return_val_if_fail(font != NULL, NULL);
00277
00278 private = (GdkFontPrivateWin32 *) font;
00279
00280 list = private->fonts;
00281 string = g_string_new("");
00282
00283 while (list) {
00284 singlefont = (GdkWin32SingleFont *) list->data;
00285
00286 if (GetObject(singlefont->xfont, sizeof(LOGFONT), &logfont) == 0) {
00287 WIN32_GDI_FAILED("GetObject");
00288 return NULL;
00289 }
00290
00291 xlfd = logfont_to_xlfd(&logfont, logfont.lfHeight, -1, 0);
00292 string = g_string_append(string, xlfd);
00293 g_free(xlfd);
00294 list = list->next;
00295 if (list)
00296 string = g_string_append_c(string, ',');
00297 }
00298 result = string->str;
00299 g_string_free(string, FALSE);
00300 return result;
00301 }
00302
00303 void gdk_font_full_name_free(gchar * name)
00304 {
00305 g_free(name);
00306 }
00307
00308 static gboolean pattern_match(const gchar * pattern, const gchar * string)
00309 {
00310 const gchar *p = pattern, *n = string;
00311 gchar c, c1;
00312
00313
00314 if ((pattern[0] == '*' && pattern[1] == '\0')
00315 || (pattern[0] == '-' && pattern[1] == '*' && pattern[2] == '\0'))
00316 return TRUE;
00317
00318 while ((c = *p++) != '\0') {
00319 c = tolower(c);
00320
00321 switch (c) {
00322 case '?':
00323 if (*n == '\0')
00324 return FALSE;
00325 break;
00326
00327 case '*':
00328 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
00329 if (c == '?' && *n == '\0')
00330 return FALSE;
00331
00332 if (c == '\0')
00333 return TRUE;
00334
00335 c1 = tolower(c);
00336 for (--p; *n != '\0'; ++n)
00337 if (tolower(*n) == c1 && pattern_match(p, n))
00338 return TRUE;
00339 return FALSE;
00340
00341 default:
00342 if (c != tolower(*n))
00343 return FALSE;
00344 }
00345
00346 ++n;
00347 }
00348
00349 if (*n == '\0')
00350 return TRUE;
00351
00352 return FALSE;
00353 }
00354
00355 static int CALLBACK
00356 InnerEnumFontFamExProc(const LOGFONT * lfp,
00357 const TEXTMETRIC * metrics,
00358 DWORD fontType, LPARAM lParam)
00359 {
00360 int size;
00361 gchar *xlfd;
00362
00363 if (fontType == TRUETYPE_FONTTYPE) {
00364 size = 0;
00365 } else {
00366 size = lfp->lfHeight;
00367 }
00368
00369 xlfd = logfont_to_xlfd(lfp, size, 0, 0);
00370
00371 if (!pattern_match((gchar *) lParam, xlfd)) {
00372 g_free(xlfd);
00373 return 1;
00374 }
00375
00376 num_fonts++;
00377 if (num_fonts == font_names_size) {
00378 font_names_size *= 2;
00379 xfontnames =
00380 g_realloc(xfontnames, font_names_size * sizeof(gchar *));
00381 }
00382 xfontnames[num_fonts - 1] = xlfd;
00383
00384 return 1;
00385 }
00386
00387 static int CALLBACK
00388 EnumFontFamExProc(const LOGFONT * lfp,
00389 const TEXTMETRIC * metrics,
00390 DWORD fontType, LPARAM lParam)
00391 {
00392 if (fontType == TRUETYPE_FONTTYPE) {
00393 LOGFONT lf;
00394
00395 lf = *lfp;
00396
00397 EnumFontFamiliesEx(gdk_DC, &lf, InnerEnumFontFamExProc, lParam, 0);
00398 } else
00399 InnerEnumFontFamExProc(lfp, metrics, fontType, lParam);
00400
00401 return 1;
00402 }
00403
00404 gchar **gdk_font_list_new(const gchar * font_pattern, gint * n_returned)
00405 {
00406 LOGFONT logfont;
00407 gchar **result;
00408
00409 num_fonts = 0;
00410 font_names_size = 100;
00411 xfontnames = g_new(gchar *, font_names_size);
00412 memset(&logfont, 0, sizeof(logfont));
00413 logfont.lfCharSet = DEFAULT_CHARSET;
00414 EnumFontFamiliesEx(gdk_DC, &logfont, EnumFontFamExProc,
00415 (LPARAM) font_pattern, 0);
00416
00417 result = g_new(gchar *, num_fonts + 1);
00418 memmove(result, xfontnames, num_fonts * sizeof(gchar *));
00419 result[num_fonts] = NULL;
00420 g_free(xfontnames);
00421
00422 *n_returned = num_fonts;
00423 return result;
00424 }
00425
00426 void gdk_font_list_free(gchar ** font_list)
00427 {
00428 g_strfreev(font_list);
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 typedef enum {
00444 U_BASIC_LATIN = 0,
00445 U_LATIN_1_SUPPLEMENT = 1,
00446 U_LATIN_EXTENDED_A = 2,
00447 U_LATIN_EXTENDED_B = 3,
00448 U_IPA_EXTENSIONS = 4,
00449 U_SPACING_MODIFIER_LETTERS = 5,
00450 U_COMBINING_DIACRITICAL_MARKS = 6,
00451 U_BASIC_GREEK = 7,
00452 U_GREEK_SYMBOLS_AND_COPTIC = 8,
00453 U_CYRILLIC = 9,
00454 U_ARMENIAN = 10,
00455 U_HEBREW_EXTENDED = 12,
00456 U_BASIC_HEBREW = 11,
00457 U_BASIC_ARABIC = 13,
00458 U_ARABIC_EXTENDED = 14,
00459 U_DEVANAGARI = 15,
00460 U_BENGALI = 16,
00461 U_GURMUKHI = 17,
00462 U_GUJARATI = 18,
00463 U_ORIYA = 19,
00464 U_TAMIL = 20,
00465 U_TELUGU = 21,
00466 U_KANNADA = 22,
00467 U_MALAYALAM = 23,
00468 U_THAI = 24,
00469 U_LAO = 25,
00470 U_GEORGIAN_EXTENDED = 27,
00471 U_BASIC_GEORGIAN = 26,
00472 U_HANGUL_JAMO = 28,
00473 U_LATIN_EXTENDED_ADDITIONAL = 29,
00474 U_GREEK_EXTENDED = 30,
00475 U_GENERAL_PUNCTUATION = 31,
00476 U_SUPERSCRIPTS_AND_SUBSCRIPTS = 32,
00477 U_CURRENCY_SYMBOLS = 33,
00478 U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS = 34,
00479 U_LETTERLIKE_SYMBOLS = 35,
00480 U_NUMBER_FORMS = 36,
00481 U_ARROWS = 37,
00482 U_MATHEMATICAL_OPERATORS = 38,
00483 U_MISCELLANEOUS_TECHNICAL = 39,
00484 U_CONTROL_PICTURES = 40,
00485 U_OPTICAL_CHARACTER_RECOGNITION = 41,
00486 U_ENCLOSED_ALPHANUMERICS = 42,
00487 U_BOX_DRAWING = 43,
00488 U_BLOCK_ELEMENTS = 44,
00489 U_GEOMETRIC_SHAPES = 45,
00490 U_MISCELLANEOUS_SYMBOLS = 46,
00491 U_DINGBATS = 47,
00492 U_CJK_SYMBOLS_AND_PUNCTUATION = 48,
00493 U_HIRAGANA = 49,
00494 U_KATAKANA = 50,
00495 U_BOPOMOFO = 51,
00496 U_HANGUL_COMPATIBILITY_JAMO = 52,
00497 U_CJK_MISCELLANEOUS = 53,
00498 U_ENCLOSED_CJK = 54,
00499 U_CJK_COMPATIBILITY = 55,
00500 U_HANGUL = 56,
00501 U_HANGUL_SUPPLEMENTARY_A = 57,
00502 U_HANGUL_SUPPLEMENTARY_B = 58,
00503 U_CJK_UNIFIED_IDEOGRAPHS = 59,
00504 U_PRIVATE_USE_AREA = 60,
00505 U_CJK_COMPATIBILITY_IDEOGRAPHS = 61,
00506 U_ALPHABETIC_PRESENTATION_FORMS = 62,
00507 U_ARABIC_PRESENTATION_FORMS_A = 63,
00508 U_COMBINING_HALF_MARKS = 64,
00509 U_CJK_COMPATIBILITY_FORMS = 65,
00510 U_SMALL_FORM_VARIANTS = 66,
00511 U_ARABIC_PRESENTATION_FORMS_B = 67,
00512 U_SPECIALS = 69,
00513 U_HALFWIDTH_AND_FULLWIDTH_FORMS = 68,
00514 U_LAST_PLUS_ONE
00515 } unicode_subset;
00516
00517 static struct {
00518 wchar_t low, high;
00519 unicode_subset bit;
00520 gchar *name;
00521 } utab[] = {
00522 {
00523 0x0000, 0x007E, U_BASIC_LATIN, "Basic Latin"}, {
00524 0x00A0, 0x00FF, U_LATIN_1_SUPPLEMENT, "Latin-1 Supplement"}, {
00525 0x0100, 0x017F, U_LATIN_EXTENDED_A, "Latin Extended-A"}, {
00526 0x0180, 0x024F, U_LATIN_EXTENDED_B, "Latin Extended-B"}, {
00527 0x0250, 0x02AF, U_IPA_EXTENSIONS, "IPA Extensions"}, {
00528 0x02B0, 0x02FF,
00529 U_SPACING_MODIFIER_LETTERS, "Spacing Modifier Letters"}, {
00530 0x0300, 0x036F,
00531 U_COMBINING_DIACRITICAL_MARKS, "Combining Diacritical Marks"}, {
00532 0x0370, 0x03CF, U_BASIC_GREEK, "Basic Greek"}, {
00533 0x03D0, 0x03FF,
00534 U_GREEK_SYMBOLS_AND_COPTIC, "Greek Symbols and Coptic"}, {
00535 0x0400, 0x04FF, U_CYRILLIC, "Cyrillic"}, {
00536 0x0530, 0x058F, U_ARMENIAN, "Armenian"}, {
00537 0x0590, 0x05CF, U_HEBREW_EXTENDED, "Hebrew Extended"}, {
00538 0x05D0, 0x05FF, U_BASIC_HEBREW, "Basic Hebrew"}, {
00539 0x0600, 0x0652, U_BASIC_ARABIC, "Basic Arabic"}, {
00540 0x0653, 0x06FF, U_ARABIC_EXTENDED, "Arabic Extended"}, {
00541 0x0900, 0x097F, U_DEVANAGARI, "Devanagari"}, {
00542 0x0980, 0x09FF, U_BENGALI, "Bengali"}, {
00543 0x0A00, 0x0A7F, U_GURMUKHI, "Gurmukhi"}, {
00544 0x0A80, 0x0AFF, U_GUJARATI, "Gujarati"}, {
00545 0x0B00, 0x0B7F, U_ORIYA, "Oriya"}, {
00546 0x0B80, 0x0BFF, U_TAMIL, "Tamil"}, {
00547 0x0C00, 0x0C7F, U_TELUGU, "Telugu"}, {
00548 0x0C80, 0x0CFF, U_KANNADA, "Kannada"}, {
00549 0x0D00, 0x0D7F, U_MALAYALAM, "Malayalam"}, {
00550 0x0E00, 0x0E7F, U_THAI, "Thai"}, {
00551 0x0E80, 0x0EFF, U_LAO, "Lao"}, {
00552 0x10A0, 0x10CF, U_GEORGIAN_EXTENDED, "Georgian Extended"}, {
00553 0x10D0, 0x10FF, U_BASIC_GEORGIAN, "Basic Georgian"}, {
00554 0x1100, 0x11FF, U_HANGUL_JAMO, "Hangul Jamo"}, {
00555 0x1E00, 0x1EFF,
00556 U_LATIN_EXTENDED_ADDITIONAL, "Latin Extended Additional"}, {
00557 0x1F00, 0x1FFF, U_GREEK_EXTENDED, "Greek Extended"}, {
00558 0x2000, 0x206F, U_GENERAL_PUNCTUATION, "General Punctuation"}, {
00559 0x2070, 0x209F,
00560 U_SUPERSCRIPTS_AND_SUBSCRIPTS, "Superscripts and Subscripts"}, {
00561 0x20A0, 0x20CF, U_CURRENCY_SYMBOLS, "Currency Symbols"}, {
00562 0x20D0, 0x20FF,
00563 U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS,
00564 "Combining Diacritical Marks for Symbols"}, {
00565 0x2100, 0x214F, U_LETTERLIKE_SYMBOLS, "Letterlike Symbols"}, {
00566 0x2150, 0x218F, U_NUMBER_FORMS, "Number Forms"}, {
00567 0x2190, 0x21FF, U_ARROWS, "Arrows"}, {
00568 0x2200, 0x22FF, U_MATHEMATICAL_OPERATORS, "Mathematical Operators"}, {
00569 0x2300, 0x23FF, U_MISCELLANEOUS_TECHNICAL, "Miscellaneous Technical"}, {
00570 0x2400, 0x243F, U_CONTROL_PICTURES, "Control Pictures"}, {
00571 0x2440, 0x245F,
00572 U_OPTICAL_CHARACTER_RECOGNITION,
00573 "Optical Character Recognition"}, {
00574 0x2460, 0x24FF, U_ENCLOSED_ALPHANUMERICS, "Enclosed Alphanumerics"}, {
00575 0x2500, 0x257F, U_BOX_DRAWING, "Box Drawing"}, {
00576 0x2580, 0x259F, U_BLOCK_ELEMENTS, "Block Elements"}, {
00577 0x25A0, 0x25FF, U_GEOMETRIC_SHAPES, "Geometric Shapes"}, {
00578 0x2600, 0x26FF, U_MISCELLANEOUS_SYMBOLS, "Miscellaneous Symbols"}, {
00579 0x2700, 0x27BF, U_DINGBATS, "Dingbats"}, {
00580 0x3000, 0x303F,
00581 U_CJK_SYMBOLS_AND_PUNCTUATION, "CJK Symbols and Punctuation"}, {
00582 0x3040, 0x309F, U_HIRAGANA, "Hiragana"}, {
00583 0x30A0, 0x30FF, U_KATAKANA, "Katakana"}, {
00584 0x3100, 0x312F, U_BOPOMOFO, "Bopomofo"}, {
00585 0x3130, 0x318F,
00586 U_HANGUL_COMPATIBILITY_JAMO, "Hangul Compatibility Jamo"}, {
00587 0x3190, 0x319F, U_CJK_MISCELLANEOUS, "CJK Miscellaneous"}, {
00588 0x3200, 0x32FF, U_ENCLOSED_CJK, "Enclosed CJK"}, {
00589 0x3300, 0x33FF, U_CJK_COMPATIBILITY, "CJK Compatibility"},
00590
00591
00592
00593
00594
00595
00596
00597 {
00598 0x3400, 0x4DB5,
00599 U_CJK_UNIFIED_IDEOGRAPHS, "CJK Unified Ideographs Extension A"},
00600 {
00601 0x4E00, 0x9FFF, U_CJK_UNIFIED_IDEOGRAPHS, "CJK Unified Ideographs"},
00602
00603 {
00604 0xAC00, 0xD7A3, U_HANGUL, "Hangul Syllables"}, {
00605 0xE000, 0xF8FF, U_PRIVATE_USE_AREA, "Private Use Area"}, {
00606 0xF900, 0xFAFF,
00607 U_CJK_COMPATIBILITY_IDEOGRAPHS, "CJK Compatibility Ideographs"},
00608 {
00609 0xFB00, 0xFB4F,
00610 U_ALPHABETIC_PRESENTATION_FORMS,
00611 "Alphabetic Presentation Forms"}, {
00612 0xFB50, 0xFDFF, U_ARABIC_PRESENTATION_FORMS_A,
00613 "Arabic Presentation Forms-A"}, {
00614 0xFE20, 0xFE2F, U_COMBINING_HALF_MARKS, "Combining Half Marks"}, {
00615 0xFE30, 0xFE4F, U_CJK_COMPATIBILITY_FORMS, "CJK Compatibility Forms"}, {
00616 0xFE50, 0xFE6F, U_SMALL_FORM_VARIANTS, "Small Form Variants"}, {
00617 0xFE70, 0xFEFE,
00618 U_ARABIC_PRESENTATION_FORMS_B, "Arabic Presentation Forms-B"}, {
00619 0xFEFF, 0xFEFF, U_SPECIALS, "Specials"}, {
00620 0xFF00, 0xFFEF,
00621 U_HALFWIDTH_AND_FULLWIDTH_FORMS,
00622 "Halfwidth and Fullwidth Forms"}, {
00623 0xFFF0, 0xFFFD, U_SPECIALS, "Specials"}
00624 };
00625
00626 static void print_unicode_subranges(FONTSIGNATURE * fsp)
00627 {
00628 int i;
00629 gboolean checked[sizeof(utab) / sizeof(utab[0])];
00630 gboolean need_comma = FALSE;
00631
00632 memset(checked, 0, sizeof(checked));
00633
00634 for (i = 0; i < sizeof(utab) / sizeof(utab[0]); i++)
00635 if (!checked[i]
00636 && (fsp->fsUsb[utab[i].bit / 32] & (1 << (utab[i].bit % 32)))) {
00637 g_print("%s %s", (need_comma ? "," : ""), utab[i].name);
00638 need_comma = TRUE;
00639 checked[i] = TRUE;
00640 }
00641 if (!need_comma)
00642 g_print(" none!");
00643 g_print("\n");
00644 }
00645
00646 static gboolean check_unicode_subranges(UINT charset, FONTSIGNATURE * fsp)
00647 {
00648 gint i;
00649 gboolean retval = FALSE;
00650
00651
00652 for (i = 0; i < U_LAST_PLUS_ONE; i++)
00653 if (i != U_PRIVATE_USE_AREA
00654 && (fsp->fsUsb[i / 32] & (1 << (i % 32))))
00655 return FALSE;
00656
00657
00658 fsp->fsUsb[0] = fsp->fsUsb[1] = fsp->fsUsb[2] = fsp->fsUsb[3] = 0;
00659
00660 #define set_bit(bitno) (fsp->fsUsb[(bitno)/32] |= (1 << ((bitno) % 32)))
00661
00662
00663
00664
00665
00666 #define check_cp(bit) (fsp->fsCsb[0] & (bit))
00667
00668 if (check_cp(FS_LATIN1)) {
00669 set_bit(U_BASIC_LATIN);
00670 set_bit(U_LATIN_1_SUPPLEMENT);
00671 set_bit(U_CURRENCY_SYMBOLS);
00672 retval = TRUE;
00673 }
00674 if (check_cp(FS_LATIN2)) {
00675 set_bit(U_BASIC_LATIN);
00676 set_bit(U_LATIN_1_SUPPLEMENT);
00677 set_bit(U_LATIN_EXTENDED_A);
00678 set_bit(U_CURRENCY_SYMBOLS);
00679 retval = TRUE;
00680 }
00681 if (check_cp(FS_CYRILLIC)) {
00682 set_bit(U_BASIC_LATIN);
00683 set_bit(U_CYRILLIC);
00684 retval = TRUE;
00685 }
00686 if (check_cp(FS_GREEK)) {
00687 set_bit(U_BASIC_LATIN);
00688 set_bit(U_BASIC_GREEK);
00689 retval = TRUE;
00690 }
00691 if (check_cp(FS_TURKISH)) {
00692 set_bit(U_BASIC_LATIN);
00693 set_bit(U_LATIN_1_SUPPLEMENT);
00694 set_bit(U_LATIN_EXTENDED_A);
00695 set_bit(U_CURRENCY_SYMBOLS);
00696 retval = TRUE;
00697 }
00698 if (check_cp(FS_HEBREW)) {
00699 set_bit(U_BASIC_LATIN);
00700 set_bit(U_CURRENCY_SYMBOLS);
00701 set_bit(U_BASIC_HEBREW);
00702 set_bit(U_HEBREW_EXTENDED);
00703 retval = TRUE;
00704 }
00705 if (check_cp(FS_ARABIC)) {
00706 set_bit(U_BASIC_LATIN);
00707 set_bit(U_CURRENCY_SYMBOLS);
00708 set_bit(U_BASIC_ARABIC);
00709 set_bit(U_ARABIC_EXTENDED);
00710 retval = TRUE;
00711 }
00712 if (check_cp(FS_BALTIC)) {
00713 set_bit(U_BASIC_LATIN);
00714 set_bit(U_LATIN_1_SUPPLEMENT);
00715 set_bit(U_CURRENCY_SYMBOLS);
00716 set_bit(U_LATIN_EXTENDED_A);
00717 set_bit(U_LATIN_EXTENDED_B);
00718 retval = TRUE;
00719 }
00720 if (check_cp(FS_VIETNAMESE)) {
00721
00722 set_bit(U_BASIC_LATIN);
00723 set_bit(U_LATIN_1_SUPPLEMENT);
00724 set_bit(U_CURRENCY_SYMBOLS);
00725 set_bit(U_LATIN_EXTENDED_A);
00726 set_bit(U_LATIN_EXTENDED_B);
00727 set_bit(U_LATIN_EXTENDED_ADDITIONAL);
00728 retval = TRUE;
00729 }
00730 if (check_cp(FS_THAI)) {
00731 set_bit(U_BASIC_LATIN);
00732 set_bit(U_THAI);
00733 retval = TRUE;
00734 }
00735 if (check_cp(FS_JISJAPAN)) {
00736
00737 set_bit(U_BASIC_LATIN);
00738 set_bit(U_CJK_SYMBOLS_AND_PUNCTUATION);
00739 set_bit(U_HIRAGANA);
00740 set_bit(U_KATAKANA);
00741 set_bit(U_CJK_UNIFIED_IDEOGRAPHS);
00742 set_bit(U_HALFWIDTH_AND_FULLWIDTH_FORMS);
00743 retval = TRUE;
00744 }
00745 if (check_cp(FS_CHINESESIMP)) {
00746
00747 set_bit(U_BASIC_LATIN);
00748 set_bit(U_HIRAGANA);
00749 set_bit(U_KATAKANA);
00750 set_bit(U_BOPOMOFO);
00751 set_bit(U_CJK_UNIFIED_IDEOGRAPHS);
00752 retval = TRUE;
00753 }
00754 if (check_cp(FS_WANSUNG)
00755 || check_cp(FS_JOHAB)) {
00756
00757
00758
00759 set_bit(U_BASIC_LATIN);
00760 set_bit(U_LATIN_1_SUPPLEMENT);
00761 set_bit(U_LATIN_EXTENDED_A);
00762 set_bit(U_SPACING_MODIFIER_LETTERS);
00763 set_bit(U_BASIC_GREEK);
00764 set_bit(U_CYRILLIC);
00765 set_bit(U_HANGUL_JAMO);
00766 set_bit(U_GENERAL_PUNCTUATION);
00767 set_bit(U_SUPERSCRIPTS_AND_SUBSCRIPTS);
00768 set_bit(U_CURRENCY_SYMBOLS);
00769 set_bit(U_LETTERLIKE_SYMBOLS);
00770 set_bit(U_NUMBER_FORMS);
00771 set_bit(U_ARROWS);
00772 set_bit(U_MATHEMATICAL_OPERATORS);
00773 set_bit(U_MISCELLANEOUS_TECHNICAL);
00774 set_bit(U_ENCLOSED_ALPHANUMERICS);
00775 set_bit(U_BOX_DRAWING);
00776 set_bit(U_BLOCK_ELEMENTS);
00777 set_bit(U_GEOMETRIC_SHAPES);
00778 set_bit(U_MISCELLANEOUS_SYMBOLS);
00779 set_bit(U_CJK_SYMBOLS_AND_PUNCTUATION);
00780 set_bit(U_HIRAGANA);
00781 set_bit(U_KATAKANA);
00782 set_bit(U_HANGUL_COMPATIBILITY_JAMO);
00783 set_bit(U_ENCLOSED_CJK);
00784 set_bit(U_CJK_COMPATIBILITY_FORMS);
00785 set_bit(U_HANGUL);
00786 set_bit(U_CJK_UNIFIED_IDEOGRAPHS);
00787 set_bit(U_CJK_COMPATIBILITY_IDEOGRAPHS);
00788 set_bit(U_HALFWIDTH_AND_FULLWIDTH_FORMS);
00789 retval = TRUE;
00790 }
00791 if (check_cp(FS_CHINESETRAD)) {
00792
00793 set_bit(U_BASIC_LATIN);
00794 set_bit(U_GENERAL_PUNCTUATION);
00795 set_bit(U_BOX_DRAWING);
00796 set_bit(U_BLOCK_ELEMENTS);
00797 set_bit(U_CJK_SYMBOLS_AND_PUNCTUATION);
00798 set_bit(U_BOPOMOFO);
00799 set_bit(U_CJK_UNIFIED_IDEOGRAPHS);
00800 set_bit(U_CJK_COMPATIBILITY_IDEOGRAPHS);
00801 set_bit(U_SMALL_FORM_VARIANTS);
00802 set_bit(U_HALFWIDTH_AND_FULLWIDTH_FORMS);
00803 retval = TRUE;
00804 }
00805 if (check_cp(FS_SYMBOL) || charset == MAC_CHARSET) {
00806
00807
00808
00809 set_bit(U_BASIC_LATIN);
00810 set_bit(U_LATIN_1_SUPPLEMENT);
00811 retval = TRUE;
00812 }
00813
00814 if (retval)
00815 return TRUE;
00816
00817 GDK_NOTE(MISC, g_print("... No code page bits set!\n"));
00818
00819
00820
00821
00822
00823
00824 switch (charset) {
00825 case ANSI_CHARSET:
00826 set_bit(U_BASIC_LATIN);
00827 set_bit(U_LATIN_1_SUPPLEMENT);
00828 set_bit(U_LATIN_EXTENDED_A);
00829 set_bit(U_LATIN_EXTENDED_B);
00830 set_bit(U_SPACING_MODIFIER_LETTERS);
00831 set_bit(U_COMBINING_DIACRITICAL_MARKS);
00832 set_bit(U_GENERAL_PUNCTUATION);
00833 set_bit(U_SUPERSCRIPTS_AND_SUBSCRIPTS);
00834 set_bit(U_CURRENCY_SYMBOLS);
00835 #if 0
00836 set_bit(U_BASIC_GREEK);
00837 set_bit(U_CYRILLIC);
00838 set_bit(U_BASIC_HEBREW);
00839 set_bit(U_HEBREW_EXTENDED);
00840 set_bit(U_BASIC_ARABIC);
00841 set_bit(U_ARABIC_EXTENDED);
00842 set_bit(U_LETTERLIKE_SYMBOLS);
00843 set_bit(U_NUMBER_FORMS);
00844 set_bit(U_ARROWS);
00845 set_bit(U_MATHEMATICAL_OPERATORS);
00846 set_bit(U_MISCELLANEOUS_TECHNICAL);
00847 set_bit(U_ENCLOSED_ALPHANUMERICS);
00848 set_bit(U_BOX_DRAWING);
00849 set_bit(U_BLOCK_ELEMENTS);
00850 set_bit(U_GEOMETRIC_SHAPES);
00851 set_bit(U_MISCELLANEOUS_SYMBOLS);
00852 set_bit(U_HIRAGANA);
00853 set_bit(U_KATAKANA);
00854 set_bit(U_BOPOMOFO);
00855 set_bit(U_HANGUL_COMPATIBILITY_JAMO);
00856 set_bit(U_CJK_MISCELLANEOUS);
00857 set_bit(U_CJK_COMPATIBILITY);
00858 set_bit(U_HANGUL);
00859 set_bit(U_HANGUL_SUPPLEMENTARY_A);
00860 set_bit(U_CJK_COMPATIBILITY_IDEOGRAPHS);
00861 set_bit(U_ALPHABETIC_PRESENTATION_FORMS);
00862 set_bit(U_SMALL_FORM_VARIANTS);
00863 set_bit(U_ARABIC_PRESENTATION_FORMS_B);
00864 set_bit(U_HALFWIDTH_AND_FULLWIDTH_FORMS);
00865 set_bit(U_SPECIALS);
00866 #endif
00867 retval = TRUE;
00868 break;
00869 case SYMBOL_CHARSET:
00870
00871 set_bit(U_BASIC_LATIN);
00872 set_bit(U_LATIN_1_SUPPLEMENT);
00873 retval = TRUE;
00874 break;
00875 case SHIFTJIS_CHARSET:
00876 case HANGEUL_CHARSET:
00877 case GB2312_CHARSET:
00878 case CHINESEBIG5_CHARSET:
00879 case JOHAB_CHARSET:
00880
00881
00882
00883
00884 set_bit(U_BASIC_LATIN);
00885 set_bit(U_LATIN_1_SUPPLEMENT);
00886 set_bit(U_LATIN_EXTENDED_A);
00887 set_bit(U_LATIN_EXTENDED_B);
00888 set_bit(U_SPACING_MODIFIER_LETTERS);
00889 set_bit(U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS);
00890 set_bit(U_BASIC_GREEK);
00891 set_bit(U_CYRILLIC);
00892 set_bit(U_HANGUL_JAMO);
00893 set_bit(U_GENERAL_PUNCTUATION);
00894 set_bit(U_SUPERSCRIPTS_AND_SUBSCRIPTS);
00895 set_bit(U_CURRENCY_SYMBOLS);
00896 set_bit(U_LETTERLIKE_SYMBOLS);
00897 set_bit(U_NUMBER_FORMS);
00898 set_bit(U_ARROWS);
00899 set_bit(U_MATHEMATICAL_OPERATORS);
00900 set_bit(U_MISCELLANEOUS_TECHNICAL);
00901 set_bit(U_ENCLOSED_ALPHANUMERICS);
00902 set_bit(U_BOX_DRAWING);
00903 set_bit(U_BLOCK_ELEMENTS);
00904 set_bit(U_GEOMETRIC_SHAPES);
00905 set_bit(U_MISCELLANEOUS_SYMBOLS);
00906 set_bit(U_CJK_SYMBOLS_AND_PUNCTUATION);
00907 set_bit(U_HIRAGANA);
00908 set_bit(U_KATAKANA);
00909 set_bit(U_BOPOMOFO);
00910 set_bit(U_HANGUL_COMPATIBILITY_JAMO);
00911 set_bit(U_CJK_MISCELLANEOUS);
00912 set_bit(U_CJK_COMPATIBILITY);
00913 set_bit(U_HANGUL);
00914 set_bit(U_HANGUL_SUPPLEMENTARY_A);
00915 set_bit(U_CJK_UNIFIED_IDEOGRAPHS);
00916 set_bit(U_CJK_COMPATIBILITY_IDEOGRAPHS);
00917 set_bit(U_ALPHABETIC_PRESENTATION_FORMS);
00918 set_bit(U_SMALL_FORM_VARIANTS);
00919 set_bit(U_ARABIC_PRESENTATION_FORMS_B);
00920 set_bit(U_SPECIALS);
00921 retval = TRUE;
00922 break;
00923 case HEBREW_CHARSET:
00924 set_bit(U_BASIC_LATIN);
00925 set_bit(U_LATIN_1_SUPPLEMENT);
00926 set_bit(U_LATIN_EXTENDED_B);
00927 set_bit(U_SPACING_MODIFIER_LETTERS);
00928 set_bit(U_BASIC_HEBREW);
00929 set_bit(U_HEBREW_EXTENDED);
00930 set_bit(U_GENERAL_PUNCTUATION);
00931 set_bit(U_LETTERLIKE_SYMBOLS);
00932 retval = TRUE;
00933 break;
00934 case ARABIC_CHARSET:
00935 set_bit(U_BASIC_LATIN);
00936 set_bit(U_LATIN_1_SUPPLEMENT);
00937 set_bit(U_LATIN_EXTENDED_A);
00938 set_bit(U_LATIN_EXTENDED_B);
00939 set_bit(U_SPACING_MODIFIER_LETTERS);
00940 set_bit(U_BASIC_GREEK);
00941 set_bit(U_BASIC_ARABIC);
00942 set_bit(U_ARABIC_EXTENDED);
00943 set_bit(U_GENERAL_PUNCTUATION);
00944 set_bit(U_LETTERLIKE_SYMBOLS);
00945 set_bit(U_ARROWS);
00946 set_bit(U_MATHEMATICAL_OPERATORS);
00947 set_bit(U_MISCELLANEOUS_TECHNICAL);
00948 set_bit(U_BOX_DRAWING);
00949 set_bit(U_BLOCK_ELEMENTS);
00950 set_bit(U_GEOMETRIC_SHAPES);
00951 set_bit(U_MISCELLANEOUS_SYMBOLS);
00952 set_bit(U_HALFWIDTH_AND_FULLWIDTH_FORMS);
00953 retval = TRUE;
00954 break;
00955 case GREEK_CHARSET:
00956 set_bit(U_BASIC_LATIN);
00957 set_bit(U_LATIN_1_SUPPLEMENT);
00958 set_bit(U_LATIN_EXTENDED_B);
00959 set_bit(U_BASIC_GREEK);
00960 set_bit(U_GENERAL_PUNCTUATION);
00961 set_bit(U_SUPERSCRIPTS_AND_SUBSCRIPTS);
00962 set_bit(U_LETTERLIKE_SYMBOLS);
00963 set_bit(U_ARROWS);
00964 set_bit(U_MATHEMATICAL_OPERATORS);
00965 set_bit(U_MISCELLANEOUS_TECHNICAL);
00966 set_bit(U_BOX_DRAWING);
00967 set_bit(U_BLOCK_ELEMENTS);
00968 set_bit(U_GEOMETRIC_SHAPES);
00969 set_bit(U_MISCELLANEOUS_SYMBOLS);
00970 retval = TRUE;
00971 break;
00972 case TURKISH_CHARSET:
00973 set_bit(U_BASIC_LATIN);
00974 set_bit(U_LATIN_1_SUPPLEMENT);
00975 set_bit(U_LATIN_EXTENDED_A);
00976 set_bit(U_LATIN_EXTENDED_B);
00977 set_bit(U_SPACING_MODIFIER_LETTERS);
00978 set_bit(U_BASIC_GREEK);
00979 set_bit(U_GENERAL_PUNCTUATION);
00980 set_bit(U_SUPERSCRIPTS_AND_SUBSCRIPTS);
00981 set_bit(U_CURRENCY_SYMBOLS);
00982 set_bit(U_LETTERLIKE_SYMBOLS);
00983 set_bit(U_ARROWS);
00984 set_bit(U_MATHEMATICAL_OPERATORS);
00985 set_bit(U_MISCELLANEOUS_TECHNICAL);
00986 set_bit(U_BOX_DRAWING);
00987 set_bit(U_BLOCK_ELEMENTS);
00988 set_bit(U_GEOMETRIC_SHAPES);
00989 set_bit(U_MISCELLANEOUS_SYMBOLS);
00990 retval = TRUE;
00991 break;
00992 case VIETNAMESE_CHARSET:
00993 case THAI_CHARSET:
00994
00995 break;
00996 case BALTIC_CHARSET:
00997 set_bit(U_BASIC_LATIN);
00998 set_bit(U_LATIN_1_SUPPLEMENT);
00999 set_bit(U_LATIN_EXTENDED_A);
01000 set_bit(U_LATIN_EXTENDED_B);
01001 set_bit(U_SPACING_MODIFIER_LETTERS);
01002 set_bit(U_BASIC_GREEK);
01003 set_bit(U_GENERAL_PUNCTUATION);
01004 set_bit(U_SUPERSCRIPTS_AND_SUBSCRIPTS);
01005 set_bit(U_CURRENCY_SYMBOLS);
01006 set_bit(U_LETTERLIKE_SYMBOLS);
01007 set_bit(U_ARROWS);
01008 set_bit(U_MATHEMATICAL_OPERATORS);
01009 set_bit(U_MISCELLANEOUS_TECHNICAL);
01010 set_bit(U_BOX_DRAWING);
01011 set_bit(U_BLOCK_ELEMENTS);
01012 set_bit(U_GEOMETRIC_SHAPES);
01013 set_bit(U_MISCELLANEOUS_SYMBOLS);
01014 retval = TRUE;
01015 break;
01016 case EASTEUROPE_CHARSET:
01017 set_bit(U_BASIC_LATIN);
01018 set_bit(U_LATIN_1_SUPPLEMENT);
01019 set_bit(U_LATIN_EXTENDED_A);
01020 set_bit(U_LATIN_EXTENDED_B);
01021 set_bit(U_SPACING_MODIFIER_LETTERS);
01022 set_bit(U_BASIC_GREEK);
01023 set_bit(U_GENERAL_PUNCTUATION);
01024 set_bit(U_SUPERSCRIPTS_AND_SUBSCRIPTS);
01025 set_bit(U_CURRENCY_SYMBOLS);
01026 set_bit(U_LETTERLIKE_SYMBOLS);
01027 set_bit(U_ARROWS);
01028 set_bit(U_MATHEMATICAL_OPERATORS);
01029 set_bit(U_MISCELLANEOUS_TECHNICAL);
01030 set_bit(U_BOX_DRAWING);
01031 set_bit(U_BLOCK_ELEMENTS);
01032 set_bit(U_GEOMETRIC_SHAPES);
01033 set_bit(U_MISCELLANEOUS_SYMBOLS);
01034 retval = TRUE;
01035 break;
01036 case RUSSIAN_CHARSET:
01037 set_bit(U_BASIC_LATIN);
01038 set_bit(U_LATIN_1_SUPPLEMENT);
01039 set_bit(U_CYRILLIC);
01040 set_bit(U_GENERAL_PUNCTUATION);
01041 set_bit(U_LETTERLIKE_SYMBOLS);
01042 set_bit(U_ARROWS);
01043 set_bit(U_MATHEMATICAL_OPERATORS);
01044 set_bit(U_MISCELLANEOUS_TECHNICAL);
01045 set_bit(U_BOX_DRAWING);
01046 set_bit(U_BLOCK_ELEMENTS);
01047 set_bit(U_GEOMETRIC_SHAPES);
01048 set_bit(U_MISCELLANEOUS_SYMBOLS);
01049 retval = TRUE;
01050 break;
01051 }
01052
01053 #undef set_bit
01054 return retval;
01055 }
01056
01057
01058
01059 GdkWin32SingleFont *gdk_font_load_internal(const gchar * font_name)
01060 {
01061 GdkWin32SingleFont *singlefont;
01062 HFONT hfont;
01063 LOGFONT logfont;
01064 CHARSETINFO csi;
01065 DWORD fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
01066 fdwOutputPrecision, fdwClipPrecision, fdwQuality, fdwPitchAndFamily;
01067 HGDIOBJ oldfont;
01068 char *lpszFace;
01069 gchar face[100];
01070
01071 int numfields, n1, n2, tries;
01072 char foundry[32], family[100], weight[32], slant[32], set_width[32],
01073 spacing[32], registry[32], encoding[32];
01074 char pixel_size[10], point_size[10], res_x[10], res_y[10],
01075 avg_width[10];
01076 int c;
01077 char *p;
01078 int nHeight, nWidth, nEscapement, nOrientation, fnWeight;
01079 int logpixelsy;
01080
01081 g_return_val_if_fail(font_name != NULL, NULL);
01082
01083 GDK_NOTE(MISC, g_print("gdk_font_load_internal: %s\n", font_name));
01084
01085 numfields = sscanf(font_name,
01086 "-%30[^-]-%100[^-]-%30[^-]-%30[^-]-%30[^-]-%n",
01087 foundry, family, weight, slant, set_width, &n1);
01088 if (numfields == 0) {
01089
01090 nHeight = 0;
01091 nWidth = 0;
01092
01093
01094 gfont_angle = atoi(set_width);
01095 nOrientation = (int) gfont_angle;
01096 nEscapement = (int) gfont_angle;
01097 fnWeight = FW_DONTCARE;
01098 fdwItalic = FALSE;
01099 fdwUnderline = FALSE;
01100 fdwStrikeOut = FALSE;
01101 fdwCharSet = ANSI_CHARSET;
01102 fdwOutputPrecision = OUT_TT_PRECIS;
01103 fdwClipPrecision = CLIP_DEFAULT_PRECIS;
01104 fdwQuality = PROOF_QUALITY;
01105 fdwPitchAndFamily = DEFAULT_PITCH;
01106 lpszFace = g_filename_from_utf8(font_name, NULL);
01107 } else if (numfields != 5) {
01108 g_warning("gdk_font_load: font name %s illegal", font_name);
01109 return NULL;
01110 } else {
01111
01112
01113
01114
01115
01116 p = family;
01117 while (*p) {
01118 if (*p == '%' && isxdigit(p[1]) && isxdigit(p[2])) {
01119 sscanf(p + 1, "%2x", &c);
01120 *p = c;
01121 strcpy(p + 1, p + 3);
01122 }
01123 p++;
01124 }
01125
01126
01127 while (font_name[n1] && font_name[n1] != '-')
01128 n1++;
01129 numfields++;
01130
01131 numfields += sscanf(font_name + n1,
01132 "-%8[^-]-%8[^-]-%8[^-]-%8[^-]-%30[^-]-%8[^-]-%30[^-]-%30[^-]%n",
01133 pixel_size,
01134 point_size,
01135 res_x,
01136 res_y,
01137 spacing, avg_width, registry, encoding, &n2);
01138
01139 if (numfields != 14 || font_name[n1 + n2] != '\0') {
01140 g_warning("gdk_font_load: font name %s illegal", font_name);
01141 return NULL;
01142 }
01143
01144 logpixelsy = GetDeviceCaps(gdk_DC, LOGPIXELSY);
01145
01146 if (strcmp(pixel_size, "*") == 0) {
01147 if (strcmp(point_size, "*") == 0) {
01148 nHeight = 0;
01149 }
01150 else {
01151 nHeight = -MulDiv(atoi(point_size), GetDeviceCaps(gdk_DC, LOGPIXELSY), 72);
01152
01153 }
01154 }
01155 else {
01156 nHeight = -1 * atoi(pixel_size);
01157 }
01158
01159 nWidth = 0;
01160
01161
01162 gfont_angle = atoi(avg_width);
01163 nOrientation = (int) gfont_angle;
01164 nEscapement = (int) gfont_angle;
01165
01166 if (g_strcasecmp(weight, "thin") == 0)
01167 fnWeight = FW_THIN;
01168 else if (g_strcasecmp(weight, "extralight") == 0)
01169 fnWeight = FW_EXTRALIGHT;
01170 else if (g_strcasecmp(weight, "ultralight") == 0)
01171 #ifdef FW_ULTRALIGHT
01172 fnWeight = FW_ULTRALIGHT;
01173 #else
01174 fnWeight = FW_EXTRALIGHT;
01175
01176
01177 #endif
01178 else if (g_strcasecmp(weight, "light") == 0)
01179 fnWeight = FW_LIGHT;
01180 else if (g_strcasecmp(weight, "normal") == 0)
01181 fnWeight = FW_NORMAL;
01182 else if (g_strcasecmp(weight, "regular") == 0)
01183 fnWeight = FW_REGULAR;
01184 else if (g_strcasecmp(weight, "medium") == 0)
01185 fnWeight = FW_MEDIUM;
01186 else if (g_strcasecmp(weight, "semibold") == 0)
01187 fnWeight = FW_SEMIBOLD;
01188 else if (g_strcasecmp(weight, "demibold") == 0)
01189 #ifdef FW_DEMIBOLD
01190 fnWeight = FW_DEMIBOLD;
01191 #else
01192 fnWeight = FW_SEMIBOLD;
01193 #endif
01194 else if (g_strcasecmp(weight, "bold") == 0)
01195 fnWeight = FW_BOLD;
01196 else if (g_strcasecmp(weight, "extrabold") == 0)
01197 fnWeight = FW_EXTRABOLD;
01198 else if (g_strcasecmp(weight, "ultrabold") == 0)
01199 #ifdef FW_ULTRABOLD
01200 fnWeight = FW_ULTRABOLD;
01201 #else
01202 fnWeight = FW_EXTRABOLD;
01203 #endif
01204 else if (g_strcasecmp(weight, "heavy") == 0)
01205 fnWeight = FW_HEAVY;
01206 else if (g_strcasecmp(weight, "black") == 0)
01207 #ifdef FW_BLACK
01208 fnWeight = FW_BLACK;
01209 #else
01210 fnWeight = FW_HEAVY;
01211 #endif
01212 else
01213 fnWeight = FW_DONTCARE;
01214
01215 if (g_strcasecmp(slant, "italic") == 0
01216 || g_strcasecmp(slant, "oblique") == 0
01217 || g_strcasecmp(slant, "i") == 0
01218 || g_strcasecmp(slant, "o") == 0)
01219 fdwItalic = TRUE;
01220 else
01221 fdwItalic = FALSE;
01222 fdwUnderline = FALSE;
01223 fdwStrikeOut = FALSE;
01224 if (g_strcasecmp(registry, "iso8859") == 0)
01225 if (strcmp(encoding, "1") == 0)
01226 fdwCharSet = ANSI_CHARSET;
01227 else if (strcmp(encoding, "2") == 0)
01228 fdwCharSet = EASTEUROPE_CHARSET;
01229 else if (strcmp(encoding, "7") == 0)
01230 fdwCharSet = GREEK_CHARSET;
01231 else if (strcmp(encoding, "8") == 0)
01232 fdwCharSet = HEBREW_CHARSET;
01233 else if (strcmp(encoding, "9") == 0)
01234 fdwCharSet = TURKISH_CHARSET;
01235 else
01236 fdwCharSet = ANSI_CHARSET;
01237 else if (g_strcasecmp(registry, "jisx0208.1983") == 0)
01238 fdwCharSet = SHIFTJIS_CHARSET;
01239 else if (g_strcasecmp(registry, "ksc5601.1987") == 0)
01240 fdwCharSet = HANGEUL_CHARSET;
01241 else if (g_strcasecmp(registry, "gb2312.1980") == 0)
01242 fdwCharSet = GB2312_CHARSET;
01243 else if (g_strcasecmp(registry, "big5") == 0)
01244 fdwCharSet = CHINESEBIG5_CHARSET;
01245 else if (g_strcasecmp(registry, "windows") == 0
01246 || g_strcasecmp(registry, "microsoft") == 0)
01247 if (g_strcasecmp(encoding, "symbol") == 0)
01248 fdwCharSet = SYMBOL_CHARSET;
01249 else if (g_strcasecmp(encoding, "shiftjis") == 0)
01250 fdwCharSet = SHIFTJIS_CHARSET;
01251 else if (g_strcasecmp(encoding, "gb2312") == 0)
01252 fdwCharSet = GB2312_CHARSET;
01253 else if (g_strcasecmp(encoding, "hangeul") == 0)
01254 fdwCharSet = HANGEUL_CHARSET;
01255 else if (g_strcasecmp(encoding, "big5") == 0)
01256 fdwCharSet = CHINESEBIG5_CHARSET;
01257 else if (g_strcasecmp(encoding, "johab") == 0)
01258 fdwCharSet = JOHAB_CHARSET;
01259 else if (g_strcasecmp(encoding, "hebrew") == 0)
01260 fdwCharSet = HEBREW_CHARSET;
01261 else if (g_strcasecmp(encoding, "arabic") == 0)
01262 fdwCharSet = ARABIC_CHARSET;
01263 else if (g_strcasecmp(encoding, "greek") == 0)
01264 fdwCharSet = GREEK_CHARSET;
01265 else if (g_strcasecmp(encoding, "turkish") == 0)
01266 fdwCharSet = TURKISH_CHARSET;
01267 else if (g_strcasecmp(encoding, "easteurope") == 0)
01268 fdwCharSet = EASTEUROPE_CHARSET;
01269 else if (g_strcasecmp(encoding, "russian") == 0)
01270 fdwCharSet = RUSSIAN_CHARSET;
01271 else if (g_strcasecmp(encoding, "mac") == 0)
01272 fdwCharSet = MAC_CHARSET;
01273 else if (g_strcasecmp(encoding, "baltic") == 0)
01274 fdwCharSet = BALTIC_CHARSET;
01275 else if (g_strcasecmp(encoding, "cp1251") == 0)
01276 fdwCharSet = RUSSIAN_CHARSET;
01277 else
01278 fdwCharSet = ANSI_CHARSET;
01279 else
01280 fdwCharSet = ANSI_CHARSET;
01281 fdwOutputPrecision = OUT_TT_PRECIS;
01282 fdwClipPrecision = CLIP_DEFAULT_PRECIS;
01283 fdwQuality = PROOF_QUALITY;
01284 if (g_strcasecmp(spacing, "m") == 0)
01285 fdwPitchAndFamily = FIXED_PITCH;
01286 else if (g_strcasecmp(spacing, "p") == 0)
01287 fdwPitchAndFamily = VARIABLE_PITCH;
01288 else
01289 fdwPitchAndFamily = DEFAULT_PITCH;
01290 lpszFace = g_filename_from_utf8(family, NULL);
01291 }
01292
01293 for (tries = 0;; tries++) {
01294 GDK_NOTE(MISC, g_print("... trying CreateFont(%d,%d,%d,%d,"
01295 "%d,%d,%d,%d,"
01296 "%d,%d,%d,"
01297 "%d,%#.02x,\"%s\")\n",
01298 nHeight, nWidth, nEscapement, nOrientation,
01299 fnWeight, fdwItalic, fdwUnderline,
01300 fdwStrikeOut, fdwCharSet, fdwOutputPrecision,
01301 fdwClipPrecision, fdwQuality,
01302 fdwPitchAndFamily, lpszFace));
01303 hfont =
01304 CreateFont(nHeight, nWidth, nEscapement, nOrientation, fnWeight,
01305 fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
01306 fdwOutputPrecision, fdwClipPrecision, fdwQuality,
01307 fdwPitchAndFamily, lpszFace);
01308
01309
01310
01311 if (tries == 0)
01312 g_free(lpszFace);
01313
01314 if (hfont != NULL)
01315 break;
01316
01317
01318 if (tries == 0) {
01319 if (g_strcasecmp(family, "helvetica") == 0)
01320 lpszFace = "arial";
01321 else if (g_strcasecmp(family, "new century schoolbook") == 0)
01322 lpszFace = "century schoolbook";
01323 else if (g_strcasecmp(family, "courier") == 0)
01324 lpszFace = "courier new";
01325 else if (g_strcasecmp(family, "lucida") == 0)
01326 lpszFace = "lucida sans unicode";
01327 else if (g_strcasecmp(family, "lucidatypewriter") == 0)
01328 lpszFace = "lucida console";
01329 else if (g_strcasecmp(family, "times") == 0)
01330 lpszFace = "times new roman";
01331 } else if (tries == 1) {
01332 if (g_strcasecmp(family, "courier") == 0) {
01333 lpszFace = "";
01334 fdwPitchAndFamily |= FF_MODERN;
01335 } else if (g_strcasecmp(family, "times new roman") == 0) {
01336 lpszFace = "";
01337 fdwPitchAndFamily |= FF_ROMAN;
01338 } else if (g_strcasecmp(family, "helvetica") == 0
01339 || g_strcasecmp(family, "lucida") == 0) {
01340 lpszFace = "";
01341 fdwPitchAndFamily |= FF_SWISS;
01342 } else {
01343 lpszFace = "";
01344 fdwPitchAndFamily = (fdwPitchAndFamily & 0x0F) | FF_DONTCARE;
01345 }
01346 } else
01347 break;
01348 tries++;
01349 }
01350
01351 if (!hfont)
01352 return NULL;
01353
01354 singlefont = g_new(GdkWin32SingleFont, 1);
01355 singlefont->xfont = hfont;
01356 GetObject(singlefont->xfont, sizeof(logfont), &logfont);
01357 oldfont = SelectObject(gdk_DC, singlefont->xfont);
01358 memset(&singlefont->fs, 0, sizeof(singlefont->fs));
01359 singlefont->charset = GetTextCharsetInfo(gdk_DC, &singlefont->fs, 0);
01360 GetTextFace(gdk_DC, sizeof(face), face);
01361 SelectObject(gdk_DC, oldfont);
01362 if (TranslateCharsetInfo((DWORD *) singlefont->charset, &csi,
01363 TCI_SRCCHARSET)
01364 && singlefont->charset != MAC_CHARSET)
01365 singlefont->codepage = csi.ciACP;
01366 else
01367 singlefont->codepage = 0;
01368
01369 GDK_NOTE(MISC, (g_print("... = %#x %s cs %s cp%d\n",
01370 singlefont->xfont, face,
01371 charset_name(singlefont->charset),
01372 singlefont->codepage),
01373 g_print("... Unicode subranges:"),
01374 print_unicode_subranges(&singlefont->fs)));
01375 if (check_unicode_subranges(singlefont->charset, &singlefont->fs))
01376 GDK_NOTE(MISC, (g_print("... Guesstimated Unicode subranges:"),
01377 print_unicode_subranges(&singlefont->fs)));
01378
01379 return singlefont;
01380 }
01381
01382 GdkFont *gdk_font_load(const gchar * font_name)
01383 {
01384 GdkFont *font;
01385 GdkFontPrivateWin32 *private;
01386 GdkWin32SingleFont *singlefont;
01387 HGDIOBJ oldfont;
01388 HANDLE *f;
01389 TEXTMETRIC textmetric;
01390
01391 g_return_val_if_fail(font_name != NULL, NULL);
01392
01393 font = gdk_font_hash_lookup(GDK_FONT_FONTSET, font_name);
01394 if (font)
01395 return font;
01396
01397 singlefont = gdk_font_load_internal(font_name);
01398
01399 private = g_new(GdkFontPrivateWin32, 1);
01400 font = (GdkFont *) private;
01401
01402 private->base.ref_count = 1;
01403 private->names = NULL;
01404 private->fonts = g_slist_append(NULL, singlefont);
01405
01406
01407
01408
01409
01410 font->type = GDK_FONT_FONTSET;
01411 oldfont = SelectObject(gdk_DC, singlefont->xfont);
01412 GetTextMetrics(gdk_DC, &textmetric);
01413 SelectObject(gdk_DC, oldfont);
01414 font->ascent = textmetric.tmAscent;
01415 font->descent = textmetric.tmDescent;
01416
01417 GDK_NOTE(MISC, g_print("... asc %d desc %d\n",
01418 font->ascent, font->descent));
01419
01420 gdk_font_hash_insert(GDK_FONT_FONTSET, font, font_name);
01421
01422 return font;
01423 }
01424
01425 GdkFont *gdk_fontset_load(const gchar * fontset_name)
01426 {
01427 GdkFont *font;
01428 GdkFontPrivateWin32 *private;
01429 GdkWin32SingleFont *singlefont;
01430 HGDIOBJ oldfont;
01431 HANDLE *f;
01432 TEXTMETRIC textmetric;
01433 GSList *base_font_list = NULL;
01434 gchar *fs;
01435 gchar *b, *p, *s;
01436
01437 g_return_val_if_fail(fontset_name != NULL, NULL);
01438
01439 font = gdk_font_hash_lookup(GDK_FONT_FONTSET, fontset_name);
01440 if (font)
01441 return font;
01442
01443 s = fs = g_strdup(fontset_name);
01444 while (*s && isspace(*s))
01445 s++;
01446
01447 g_return_val_if_fail(*s, NULL);
01448
01449 private = g_new(GdkFontPrivateWin32, 1);
01450 font = (GdkFont *) private;
01451
01452 private->base.ref_count = 1;
01453 private->names = NULL;
01454 private->fonts = NULL;
01455
01456 font->type = GDK_FONT_FONTSET;
01457 font->ascent = 0;
01458 font->descent = 0;
01459
01460 while (TRUE) {
01461 if ((p = strchr(s, ',')) != NULL)
01462 b = p;
01463 else
01464 b = s + strlen(s);
01465
01466 while (isspace(b[-1]))
01467 b--;
01468 *b = '\0';
01469 singlefont = gdk_font_load_internal(s);
01470 if (singlefont) {
01471 private->fonts = g_slist_append(private->fonts, singlefont);
01472 oldfont = SelectObject(gdk_DC, singlefont->xfont);
01473 GetTextMetrics(gdk_DC, &textmetric);
01474 SelectObject(gdk_DC, oldfont);
01475 font->ascent = MAX(font->ascent, textmetric.tmAscent);
01476 font->descent = MAX(font->descent, textmetric.tmDescent);
01477 }
01478 if (p) {
01479 s = p + 1;
01480 while (*s && isspace(*s))
01481 s++;
01482 } else
01483 break;
01484 if (!*s)
01485 break;
01486 }
01487
01488 g_free(fs);
01489
01490 gdk_font_hash_insert(GDK_FONT_FONTSET, font, fontset_name);
01491
01492 return font;
01493 }
01494
01495 void _gdk_font_destroy(GdkFont * font)
01496 {
01497 GdkFontPrivateWin32 *private = (GdkFontPrivateWin32 *) font;
01498 GdkWin32SingleFont *singlefont;
01499 GSList *list;
01500
01501 singlefont = (GdkWin32SingleFont *) private->fonts->data;
01502 GDK_NOTE(MISC, g_print("_gdk_font_destroy %#x\n", singlefont->xfont));
01503
01504 gdk_font_hash_remove(font->type, font);
01505
01506 switch (font->type) {
01507 case GDK_FONT_FONT:
01508 DeleteObject(singlefont->xfont);
01509 break;
01510
01511 case GDK_FONT_FONTSET:
01512 list = private->fonts;
01513 while (list) {
01514 singlefont = (GdkWin32SingleFont *) list->data;
01515 DeleteObject(singlefont->xfont);
01516
01517 list = list->next;
01518 }
01519 g_slist_free(private->fonts);
01520 break;
01521 }
01522 g_free(font);
01523 }
01524
01525 gint _gdk_font_strlen(GdkFont * font, const gchar * str)
01526 {
01527 g_return_val_if_fail(font != NULL, -1);
01528 g_return_val_if_fail(str != NULL, -1);
01529
01530 return strlen(str);
01531 }
01532
01533 gint gdk_font_id(const GdkFont * font)
01534 {
01535 const GdkFontPrivateWin32 *private;
01536
01537 g_return_val_if_fail(font != NULL, 0);
01538
01539 private = (const GdkFontPrivateWin32 *) font;
01540
01541 if (font->type == GDK_FONT_FONT)
01542 return (gint) ((GdkWin32SingleFont *) private->fonts->data)->xfont;
01543 else
01544 return 0;
01545 }
01546
01547 gint gdk_font_equal(const GdkFont * fonta, const GdkFont * fontb)
01548 {
01549 const GdkFontPrivateWin32 *privatea;
01550 const GdkFontPrivateWin32 *privateb;
01551
01552 g_return_val_if_fail(fonta != NULL, FALSE);
01553 g_return_val_if_fail(fontb != NULL, FALSE);
01554
01555 privatea = (const GdkFontPrivateWin32 *) fonta;
01556 privateb = (const GdkFontPrivateWin32 *) fontb;
01557
01558 if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
01559 return (((GdkWin32SingleFont *) privatea->fonts->data)->xfont
01560 == ((GdkWin32SingleFont *) privateb->fonts->data)->xfont);
01561 else if (fonta->type == GDK_FONT_FONTSET
01562 && fontb->type == GDK_FONT_FONTSET) {
01563 GSList *lista = privatea->fonts;
01564 GSList *listb = privateb->fonts;
01565
01566 while (lista && listb) {
01567 if (((GdkWin32SingleFont *) lista->data)->xfont
01568 != ((GdkWin32SingleFont *) listb->data)->xfont)
01569 return 0;
01570 lista = lista->next;
01571 listb = listb->next;
01572 }
01573 if (lista || listb)
01574 return 0;
01575 else
01576 return 1;
01577 } else
01578 return 0;
01579 }
01580
01581
01582
01583 static int unicode_classify(wchar_t wc)
01584 {
01585 int min = 0;
01586 int max = sizeof(utab) / sizeof(utab[0]) - 1;
01587 int mid;
01588
01589 while (max >= min) {
01590 mid = (min + max) / 2;
01591 if (utab[mid].high < wc)
01592 min = mid + 1;
01593 else if (wc < utab[mid].low)
01594 max = mid - 1;
01595 else if (utab[mid].low <= wc && wc <= utab[mid].high)
01596 return utab[mid].bit;
01597 else
01598 return -1;
01599 }
01600 return -1;
01601 }
01602
01603 void
01604 gdk_wchar_text_handle(GdkFont * font,
01605 const wchar_t * wcstr,
01606 int wclen,
01607 void (*handler) (GdkWin32SingleFont *,
01608 const wchar_t *,
01609 int, void *), void *arg)
01610 {
01611 GdkFontPrivateWin32 *private;
01612 GdkWin32SingleFont *singlefont;
01613 GSList *list;
01614 int i, block;
01615 const wchar_t *start, *end, *wcp;
01616
01617 wcp = wcstr;
01618 end = wcp + wclen;
01619 private = (GdkFontPrivateWin32 *) font;
01620
01621 g_assert(private->base.ref_count > 0);
01622
01623 GDK_NOTE(MISC, g_print("gdk_wchar_text_handle: "));
01624
01625 while (wcp < end) {
01626
01627 start = wcp;
01628 block = unicode_classify(*wcp);
01629 while (wcp + 1 < end && unicode_classify(wcp[1]) == block)
01630 wcp++;
01631
01632
01633 list = private->fonts;
01634 while (list) {
01635 singlefont = (GdkWin32SingleFont *) list->data;
01636
01637 if (singlefont->fs.fsUsb[block / 32] & (1 << (block % 32)))
01638 break;
01639
01640 list = list->next;
01641 }
01642
01643 if (!list)
01644 singlefont = NULL;
01645
01646 GDK_NOTE(MISC,
01647 g_print("%d:%d:%d ", start - wcstr, wcp - wcstr, block));
01648
01649
01650 (*handler) (singlefont, start, wcp + 1 - start, arg);
01651 wcp++;
01652 }
01653 GDK_NOTE(MISC, g_print("\n"));
01654 }
01655
01656 typedef struct {
01657 SIZE total;
01658 } gdk_text_size_arg;
01659
01660 static void
01661 gdk_text_size_handler(GdkWin32SingleFont * singlefont,
01662 const wchar_t * wcstr, int wclen, void *argp)
01663 {
01664 SIZE this_size;
01665 HGDIOBJ oldfont;
01666 gdk_text_size_arg *arg = (gdk_text_size_arg *) argp;
01667
01668 if (!singlefont)
01669 return;
01670
01671 if ((oldfont = SelectObject(gdk_DC, singlefont->xfont)) == NULL) {
01672 WIN32_GDI_FAILED("SelectObject");
01673 return;
01674 }
01675 GetTextExtentPoint32W(gdk_DC, wcstr, wclen, &this_size);
01676 SelectObject(gdk_DC, oldfont);
01677
01678 arg->total.cx += this_size.cx;
01679 arg->total.cy = MAX(arg->total.cy, this_size.cy);
01680 }
01681
01682 static gboolean
01683 gdk_text_size(GdkFont * font,
01684 const gchar * text,
01685 gint text_length, gdk_text_size_arg * arg)
01686 {
01687 gint wlen;
01688 wchar_t *wcstr;
01689
01690 g_return_val_if_fail(font != NULL, FALSE);
01691 g_return_val_if_fail(text != NULL, FALSE);
01692
01693 if (text_length == 0)
01694 return 0;
01695
01696 g_assert(font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
01697
01698 wcstr = g_new(wchar_t, text_length);
01699 if (text_length == 1) {
01700
01701
01702 wcstr[0] = (guchar) text[0];
01703 gdk_wchar_text_handle(font, wcstr, 1, gdk_text_size_handler, arg);
01704 } else {
01705 if ((wlen =
01706 gdk_nmbstowchar_ts(wcstr, text, text_length,
01707 text_length)) == -1)
01708 g_warning("gdk_text_size: gdk_nmbstowchar_ts failed");
01709 else
01710 gdk_wchar_text_handle(font, wcstr, wlen, gdk_text_size_handler,
01711 arg);
01712 }
01713
01714 g_free(wcstr);
01715
01716 return TRUE;
01717 }
01718
01719 gint gdk_text_width(GdkFont * font, const gchar * text, gint text_length)
01720 {
01721 gdk_text_size_arg arg;
01722
01723 arg.total.cx = arg.total.cy = 0;
01724
01725 if (!gdk_text_size(font, text, text_length, &arg))
01726 return -1;
01727
01728 return arg.total.cx;
01729 }
01730
01731 gint
01732 gdk_text_width_wc(GdkFont * font, const GdkWChar * text, gint text_length)
01733 {
01734 gdk_text_size_arg arg;
01735 wchar_t *wcstr;
01736 gint i;
01737
01738 g_return_val_if_fail(font != NULL, -1);
01739 g_return_val_if_fail(text != NULL, -1);
01740
01741 if (text_length == 0)
01742 return 0;
01743
01744 g_assert(font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
01745
01746 if (sizeof(wchar_t) != sizeof(GdkWChar)) {
01747 wcstr = g_new(wchar_t, text_length);
01748 for (i = 0; i < text_length; i++)
01749 wcstr[i] = text[i];
01750 } else
01751 wcstr = (wchar_t *) text;
01752
01753 arg.total.cx = arg.total.cy = 0;
01754
01755 gdk_wchar_text_handle(font, wcstr, text_length,
01756 gdk_text_size_handler, &arg);
01757
01758 if (sizeof(wchar_t) != sizeof(GdkWChar))
01759 g_free(wcstr);
01760
01761 return arg.total.cx;
01762 }
01763
01764 void
01765 gdk_text_extents(GdkFont * font,
01766 const gchar * text,
01767 gint text_length,
01768 gint * lbearing,
01769 gint * rbearing,
01770 gint * width, gint * ascent, gint * descent)
01771 {
01772 gdk_text_size_arg arg;
01773 gint wlen;
01774 wchar_t *wcstr;
01775
01776 g_return_if_fail(font != NULL);
01777 g_return_if_fail(text != NULL);
01778
01779 if (text_length == 0) {
01780 if (lbearing)
01781 *lbearing = 0;
01782 if (rbearing)
01783 *rbearing = 0;
01784 if (width)
01785 *width = 0;
01786 if (ascent)
01787 *ascent = 0;
01788 if (descent)
01789 *descent = 0;
01790 return;
01791 }
01792
01793 g_assert(font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
01794
01795 arg.total.cx = arg.total.cy = 0;
01796
01797 wcstr = g_new(wchar_t, text_length);
01798 if (text_length == 1) {
01799 wcstr[0] = (guchar) text[0];
01800 gdk_wchar_text_handle(font, wcstr, 1, gdk_text_size_handler, &arg);
01801 } else {
01802 if ((wlen =
01803 gdk_nmbstowchar_ts(wcstr, text, text_length,
01804 text_length)) == -1)
01805 g_warning("gdk_text_extents: gdk_nmbstowchar_ts failed");
01806 else
01807 gdk_wchar_text_handle(font, wcstr, wlen, gdk_text_size_handler,
01808 &arg);
01809 }
01810
01811 g_free(wcstr);
01812
01813
01814 if (lbearing)
01815 *lbearing = 0;
01816 if (rbearing)
01817 *rbearing = arg.total.cx;
01818
01819 if (width)
01820 *width = arg.total.cx;
01821 if (ascent)
01822 *ascent = arg.total.cy + 1;
01823 if (descent)
01824 *descent = font->descent + 1;
01825 }
01826
01827 void
01828 gdk_text_extents_wc(GdkFont * font,
01829 const GdkWChar * text,
01830 gint text_length,
01831 gint * lbearing,
01832 gint * rbearing,
01833 gint * width, gint * ascent, gint * descent)
01834 {
01835 gdk_text_size_arg arg;
01836 wchar_t *wcstr;
01837 gint i;
01838
01839 g_return_if_fail(font != NULL);
01840 g_return_if_fail(text != NULL);
01841
01842 if (text_length == 0) {
01843 if (lbearing)
01844 *lbearing = 0;
01845 if (rbearing)
01846 *rbearing = 0;
01847 if (width)
01848 *width = 0;
01849 if (ascent)
01850 *ascent = 0;
01851 if (descent)
01852 *descent = 0;
01853 return;
01854 }
01855
01856 g_assert(font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
01857
01858 if (sizeof(wchar_t) != sizeof(GdkWChar)) {
01859 wcstr = g_new(wchar_t, text_length);
01860 for (i = 0; i < text_length; i++)
01861 wcstr[i] = text[i];
01862 } else
01863 wcstr = (wchar_t *) text;
01864
01865 arg.total.cx = arg.total.cy = 0;
01866
01867 gdk_wchar_text_handle(font, wcstr, text_length,
01868 gdk_text_size_handler, &arg);
01869
01870 if (sizeof(wchar_t) != sizeof(GdkWChar))
01871 g_free(wcstr);
01872
01873
01874 if (lbearing)
01875 *lbearing = 0;
01876 if (rbearing)
01877 *rbearing = arg.total.cx;
01878 if (width)
01879 *width = arg.total.cx;
01880 if (ascent)
01881 *ascent = arg.total.cy + 1;
01882 if (descent)
01883 *descent = font->descent + 1;
01884 }