diff options
| -rw-r--r-- | src/ChangeLog | 16 | ||||
| -rw-r--r-- | src/xfont.c | 131 |
2 files changed, 119 insertions, 28 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 897ec30b719..53654f413f5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,19 @@ | |||
| 1 | 2008-12-19 Kenichi Handa <handa@m17n.org> | ||
| 2 | |||
| 3 | * xfont.c (xfont_decode_coding_xlfd): New function. | ||
| 4 | (xfont_encode_coding_xlfd): New function. | ||
| 5 | (xfont_list_pattern): Decode XLFD by iso-8859-1. | ||
| 6 | (xfont_list): Decode and encode XLFD by iso-8859-1. | ||
| 7 | (xfont_match): Likewise. | ||
| 8 | (xfont_list_family): Likewise. | ||
| 9 | (xfont_open): Likewise. | ||
| 10 | |||
| 11 | * ftfont.c (ftfont_open): Genarate a multibyte string if given | ||
| 12 | names are utf-8. | ||
| 13 | |||
| 14 | * xftfont.c (xftfont_open): Genarate a multibyte string if given | ||
| 15 | names are utf-8. | ||
| 16 | |||
| 1 | 2008-12-18 Jan Djärv <jan.h.d@swipnet.se> | 17 | 2008-12-18 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 18 | ||
| 3 | * gtkutil.c (xg_frame_resized): Remove check if rows/columns have | 19 | * gtkutil.c (xg_frame_resized): Remove check if rows/columns have |
diff --git a/src/xfont.c b/src/xfont.c index 67cb6e50664..9e23b0abdfc 100644 --- a/src/xfont.c +++ b/src/xfont.c | |||
| @@ -210,6 +210,52 @@ compare_font_names (const void *name1, const void *name2) | |||
| 210 | *(const unsigned char **) name2); | 210 | *(const unsigned char **) name2); |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length | ||
| 214 | of the decoding result. LEN is the byte length of XLFD, or -1 if | ||
| 215 | XLFD is NULL terminated. The caller must assure that OUTPUT is at | ||
| 216 | least twice (plus 1) as large as XLFD. */ | ||
| 217 | |||
| 218 | static int | ||
| 219 | xfont_decode_coding_xlfd (char *xlfd, int len, char *output) | ||
| 220 | { | ||
| 221 | char *p0 = xlfd, *p1 = output; | ||
| 222 | int c; | ||
| 223 | |||
| 224 | while (*p0) | ||
| 225 | { | ||
| 226 | c = *(unsigned char *) p0++; | ||
| 227 | p1 += CHAR_STRING (c, p1); | ||
| 228 | if (--len == 0) | ||
| 229 | break; | ||
| 230 | } | ||
| 231 | *p1 = 0; | ||
| 232 | return (p1 - output); | ||
| 233 | } | ||
| 234 | |||
| 235 | /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the | ||
| 236 | resulting byte length. If XLFD contains unencodable character, | ||
| 237 | return -1. */ | ||
| 238 | |||
| 239 | static int | ||
| 240 | xfont_encode_coding_xlfd (char *xlfd) | ||
| 241 | { | ||
| 242 | const unsigned char *p0 = (unsigned char *) xlfd; | ||
| 243 | unsigned char *p1 = (unsigned char *) xlfd; | ||
| 244 | int len = 0; | ||
| 245 | |||
| 246 | while (*p0) | ||
| 247 | { | ||
| 248 | int c = STRING_CHAR_ADVANCE (p0); | ||
| 249 | |||
| 250 | if (c >= 0x100) | ||
| 251 | return -1; | ||
| 252 | *p1++ = c; | ||
| 253 | len++; | ||
| 254 | } | ||
| 255 | *p1 = 0; | ||
| 256 | return len; | ||
| 257 | } | ||
| 258 | |||
| 213 | static Lisp_Object xfont_list_pattern P_ ((Lisp_Object, Display *, char *)); | 259 | static Lisp_Object xfont_list_pattern P_ ((Lisp_Object, Display *, char *)); |
| 214 | 260 | ||
| 215 | static Lisp_Object | 261 | static Lisp_Object |
| @@ -221,6 +267,8 @@ xfont_list_pattern (frame, display, pattern) | |||
| 221 | Lisp_Object list = Qnil; | 267 | Lisp_Object list = Qnil; |
| 222 | int i, limit, num_fonts; | 268 | int i, limit, num_fonts; |
| 223 | char **names; | 269 | char **names; |
| 270 | /* Large enough to decode the longest XLFD (255 bytes). */ | ||
| 271 | char buf[512]; | ||
| 224 | 272 | ||
| 225 | BLOCK_INPUT; | 273 | BLOCK_INPUT; |
| 226 | x_catch_errors (display); | 274 | x_catch_errors (display); |
| @@ -253,14 +301,15 @@ xfont_list_pattern (frame, display, pattern) | |||
| 253 | { | 301 | { |
| 254 | Lisp_Object entity; | 302 | Lisp_Object entity; |
| 255 | int result; | 303 | int result; |
| 304 | char *p; | ||
| 256 | 305 | ||
| 257 | if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0) | 306 | if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0) |
| 258 | continue; | 307 | continue; |
| 259 | 308 | ||
| 260 | entity = font_make_entity (); | 309 | entity = font_make_entity (); |
| 261 | ASET (entity, FONT_TYPE_INDEX, Qx); | 310 | ASET (entity, FONT_TYPE_INDEX, Qx); |
| 262 | 311 | xfont_decode_coding_xlfd (indices[i], -1, buf); | |
| 263 | result = font_parse_xlfd (indices[i], entity); | 312 | result = font_parse_xlfd (buf, entity); |
| 264 | if (result < 0) | 313 | if (result < 0) |
| 265 | { | 314 | { |
| 266 | /* This may be an alias name. Try to get the full XLFD name | 315 | /* This may be an alias name. Try to get the full XLFD name |
| @@ -279,7 +328,10 @@ xfont_list_pattern (frame, display, pattern) | |||
| 279 | Ver.3.7 is running, XGetAtomName will return null | 328 | Ver.3.7 is running, XGetAtomName will return null |
| 280 | string. We must avoid such a name. */ | 329 | string. We must avoid such a name. */ |
| 281 | if (len > 0) | 330 | if (len > 0) |
| 282 | result = font_parse_xlfd (name, entity); | 331 | { |
| 332 | xfont_decode_coding_xlfd (indices[i], -1, buf); | ||
| 333 | result = font_parse_xlfd (buf, entity); | ||
| 334 | } | ||
| 283 | XFree (name); | 335 | XFree (name); |
| 284 | } | 336 | } |
| 285 | XFreeFont (display, font); | 337 | XFreeFont (display, font); |
| @@ -309,7 +361,8 @@ xfont_list (frame, spec) | |||
| 309 | Display *display = FRAME_X_DISPLAY_INFO (f)->display; | 361 | Display *display = FRAME_X_DISPLAY_INFO (f)->display; |
| 310 | Lisp_Object registry, list, val, extra; | 362 | Lisp_Object registry, list, val, extra; |
| 311 | int len; | 363 | int len; |
| 312 | char name[256]; | 364 | /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */ |
| 365 | char name[512]; | ||
| 313 | 366 | ||
| 314 | extra = AREF (spec, FONT_EXTRA_INDEX); | 367 | extra = AREF (spec, FONT_EXTRA_INDEX); |
| 315 | if (CONSP (extra)) | 368 | if (CONSP (extra)) |
| @@ -326,10 +379,10 @@ xfont_list (frame, spec) | |||
| 326 | } | 379 | } |
| 327 | 380 | ||
| 328 | registry = AREF (spec, FONT_REGISTRY_INDEX); | 381 | registry = AREF (spec, FONT_REGISTRY_INDEX); |
| 329 | len = font_unparse_xlfd (spec, 0, name, 256); | 382 | len = font_unparse_xlfd (spec, 0, name, 512); |
| 330 | ASET (spec, FONT_REGISTRY_INDEX, registry); | 383 | if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0) |
| 331 | if (len < 0) | ||
| 332 | return Qnil; | 384 | return Qnil; |
| 385 | ASET (spec, FONT_REGISTRY_INDEX, registry); | ||
| 333 | list = xfont_list_pattern (frame, display, name); | 386 | list = xfont_list_pattern (frame, display, name); |
| 334 | if (NILP (list) && NILP (registry)) | 387 | if (NILP (list) && NILP (registry)) |
| 335 | { | 388 | { |
| @@ -369,8 +422,13 @@ xfont_list (frame, spec) | |||
| 369 | { | 422 | { |
| 370 | /* Try alias. */ | 423 | /* Try alias. */ |
| 371 | val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX)); | 424 | val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX)); |
| 372 | if (CONSP (val) && STRINGP (XCDR (val))) | 425 | if (CONSP (val) && STRINGP (XCDR (val)) && SBYTES (XCDR (val)) < 512) |
| 373 | list = xfont_list_pattern (frame, display, (char *) SDATA (XCDR (val))); | 426 | { |
| 427 | bcopy (SDATA (XCDR (val)), name, SBYTES (XCDR (val)) + 1); | ||
| 428 | if (xfont_encode_coding_xlfd (name) < 0) | ||
| 429 | return Qnil; | ||
| 430 | list = xfont_list_pattern (frame, display, name); | ||
| 431 | } | ||
| 374 | } | 432 | } |
| 375 | 433 | ||
| 376 | return list; | 434 | return list; |
| @@ -383,7 +441,7 @@ xfont_match (frame, spec) | |||
| 383 | FRAME_PTR f = XFRAME (frame); | 441 | FRAME_PTR f = XFRAME (frame); |
| 384 | Display *display = FRAME_X_DISPLAY_INFO (f)->display; | 442 | Display *display = FRAME_X_DISPLAY_INFO (f)->display; |
| 385 | Lisp_Object extra, val, entity; | 443 | Lisp_Object extra, val, entity; |
| 386 | char buf[256], *name; | 444 | char name[512]; |
| 387 | XFontStruct *xfont; | 445 | XFontStruct *xfont; |
| 388 | unsigned long value; | 446 | unsigned long value; |
| 389 | 447 | ||
| @@ -391,12 +449,15 @@ xfont_match (frame, spec) | |||
| 391 | val = assq_no_quit (QCname, extra); | 449 | val = assq_no_quit (QCname, extra); |
| 392 | if (! CONSP (val) || ! STRINGP (XCDR (val))) | 450 | if (! CONSP (val) || ! STRINGP (XCDR (val))) |
| 393 | { | 451 | { |
| 394 | if (font_unparse_xlfd (spec, 0, buf, 256) < 0) | 452 | if (font_unparse_xlfd (spec, 0, name, 512) < 0) |
| 395 | return Qnil; | 453 | return Qnil; |
| 396 | name = buf; | ||
| 397 | } | 454 | } |
| 455 | else if (SBYTES (XCDR (val)) < 512) | ||
| 456 | bcopy (SDATA (XCDR (val)), name, SBYTES (XCDR (val)) + 1); | ||
| 398 | else | 457 | else |
| 399 | name = (char *) SDATA (XCDR (val)); | 458 | return Qnil; |
| 459 | if (xfont_encode_coding_xlfd (name) < 0) | ||
| 460 | return Qnil; | ||
| 400 | 461 | ||
| 401 | BLOCK_INPUT; | 462 | BLOCK_INPUT; |
| 402 | entity = Qnil; | 463 | entity = Qnil; |
| @@ -406,9 +467,10 @@ xfont_match (frame, spec) | |||
| 406 | if (XGetFontProperty (xfont, XA_FONT, &value)) | 467 | if (XGetFontProperty (xfont, XA_FONT, &value)) |
| 407 | { | 468 | { |
| 408 | int len; | 469 | int len; |
| 470 | char *s; | ||
| 409 | 471 | ||
| 410 | name = (char *) XGetAtomName (display, (Atom) value); | 472 | s = (char *) XGetAtomName (display, (Atom) value); |
| 411 | len = strlen (name); | 473 | len = strlen (s); |
| 412 | 474 | ||
| 413 | /* If DXPC (a Differential X Protocol Compressor) | 475 | /* If DXPC (a Differential X Protocol Compressor) |
| 414 | Ver.3.7 is running, XGetAtomName will return null | 476 | Ver.3.7 is running, XGetAtomName will return null |
| @@ -417,10 +479,11 @@ xfont_match (frame, spec) | |||
| 417 | { | 479 | { |
| 418 | entity = font_make_entity (); | 480 | entity = font_make_entity (); |
| 419 | ASET (entity, FONT_TYPE_INDEX, Qx); | 481 | ASET (entity, FONT_TYPE_INDEX, Qx); |
| 482 | xfont_decode_coding_xlfd (s, -1, name); | ||
| 420 | if (font_parse_xlfd (name, entity) < 0) | 483 | if (font_parse_xlfd (name, entity) < 0) |
| 421 | entity = Qnil; | 484 | entity = Qnil; |
| 422 | } | 485 | } |
| 423 | XFree (name); | 486 | XFree (s); |
| 424 | } | 487 | } |
| 425 | XFreeFont (display, xfont); | 488 | XFreeFont (display, xfont); |
| 426 | } | 489 | } |
| @@ -457,8 +520,9 @@ xfont_list_family (frame) | |||
| 457 | list = Qnil; | 520 | list = Qnil; |
| 458 | for (i = 0, last_len = 0; i < num_fonts; i++) | 521 | for (i = 0, last_len = 0; i < num_fonts; i++) |
| 459 | { | 522 | { |
| 460 | char *p0 = names[i], *p1; | 523 | char *p0 = names[i], *p1, buf[512]; |
| 461 | Lisp_Object family; | 524 | Lisp_Object family; |
| 525 | int decoded_len; | ||
| 462 | 526 | ||
| 463 | p0++; /* skip the leading '-' */ | 527 | p0++; /* skip the leading '-' */ |
| 464 | while (*p0 && *p0 != '-') p0++; /* skip foundry */ | 528 | while (*p0 && *p0 != '-') p0++; /* skip foundry */ |
| @@ -473,7 +537,9 @@ xfont_list_family (frame) | |||
| 473 | continue; | 537 | continue; |
| 474 | last_len = p1 - p0; | 538 | last_len = p1 - p0; |
| 475 | last_family = p0; | 539 | last_family = p0; |
| 476 | family = font_intern_prop (p0, last_len, 1); | 540 | |
| 541 | decoded_len = xfont_decode_coding_xlfd (p0, last_len, buf); | ||
| 542 | family = font_intern_prop (p0, decoded_len, 1); | ||
| 477 | if (NILP (assq_no_quit (family, list))) | 543 | if (NILP (assq_no_quit (family, list))) |
| 478 | list = Fcons (family, list); | 544 | list = Fcons (family, list); |
| 479 | } | 545 | } |
| @@ -495,7 +561,7 @@ xfont_open (f, entity, pixel_size) | |||
| 495 | { | 561 | { |
| 496 | Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | 562 | Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); |
| 497 | Display *display = dpyinfo->display; | 563 | Display *display = dpyinfo->display; |
| 498 | char name[256]; | 564 | char name[512]; |
| 499 | int len; | 565 | int len; |
| 500 | unsigned long value; | 566 | unsigned long value; |
| 501 | Lisp_Object registry; | 567 | Lisp_Object registry; |
| @@ -523,8 +589,8 @@ xfont_open (f, entity, pixel_size) | |||
| 523 | else | 589 | else |
| 524 | pixel_size = 14; | 590 | pixel_size = 14; |
| 525 | } | 591 | } |
| 526 | len = font_unparse_xlfd (entity, pixel_size, name, 256); | 592 | len = font_unparse_xlfd (entity, pixel_size, name, 512); |
| 527 | if (len <= 0) | 593 | if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0) |
| 528 | { | 594 | { |
| 529 | font_add_log (" x:unparse failed", entity, Qnil); | 595 | font_add_log (" x:unparse failed", entity, Qnil); |
| 530 | return Qnil; | 596 | return Qnil; |
| @@ -554,8 +620,8 @@ xfont_open (f, entity, pixel_size) | |||
| 554 | 620 | ||
| 555 | temp = Fcopy_font_spec (entity); | 621 | temp = Fcopy_font_spec (entity); |
| 556 | ASET (temp, FONT_DPI_INDEX, Qnil); | 622 | ASET (temp, FONT_DPI_INDEX, Qnil); |
| 557 | len = font_unparse_xlfd (temp, pixel_size, name, 256); | 623 | len = font_unparse_xlfd (temp, pixel_size, name, 512); |
| 558 | if (len <= 0) | 624 | if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0) |
| 559 | { | 625 | { |
| 560 | font_add_log (" x:unparse failed", temp, Qnil); | 626 | font_add_log (" x:unparse failed", temp, Qnil); |
| 561 | return Qnil; | 627 | return Qnil; |
| @@ -590,7 +656,10 @@ xfont_open (f, entity, pixel_size) | |||
| 590 | } | 656 | } |
| 591 | 657 | ||
| 592 | if (dashes >= 13) | 658 | if (dashes >= 13) |
| 593 | fullname = Fdowncase (make_unibyte_string (p0, p - p0)); | 659 | { |
| 660 | len = xfont_decode_coding_xlfd (p0, -1, name); | ||
| 661 | fullname = Fdowncase (make_string (name, len)); | ||
| 662 | } | ||
| 594 | XFree (p0); | 663 | XFree (p0); |
| 595 | } | 664 | } |
| 596 | x_uncatch_errors (); | 665 | x_uncatch_errors (); |
| @@ -606,11 +675,17 @@ xfont_open (f, entity, pixel_size) | |||
| 606 | entity, pixel_size); | 675 | entity, pixel_size); |
| 607 | ASET (font_object, FONT_TYPE_INDEX, Qx); | 676 | ASET (font_object, FONT_TYPE_INDEX, Qx); |
| 608 | if (STRINGP (fullname)) | 677 | if (STRINGP (fullname)) |
| 609 | font_parse_xlfd ((char *) SDATA (fullname), font_object); | 678 | { |
| 610 | if (STRINGP (fullname)) | 679 | font_parse_xlfd ((char *) SDATA (fullname), font_object); |
| 611 | ASET (font_object, FONT_NAME_INDEX, fullname); | 680 | ASET (font_object, FONT_NAME_INDEX, fullname); |
| 681 | } | ||
| 612 | else | 682 | else |
| 613 | ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len)); | 683 | { |
| 684 | char buf[512]; | ||
| 685 | |||
| 686 | len = xfont_decode_coding_xlfd (name, -1, buf); | ||
| 687 | ASET (font_object, FONT_NAME_INDEX, make_string (buf, len)); | ||
| 688 | } | ||
| 614 | ASET (font_object, FONT_FULLNAME_INDEX, fullname); | 689 | ASET (font_object, FONT_FULLNAME_INDEX, fullname); |
| 615 | ASET (font_object, FONT_FILE_INDEX, Qnil); | 690 | ASET (font_object, FONT_FILE_INDEX, Qnil); |
| 616 | ASET (font_object, FONT_FORMAT_INDEX, Qx); | 691 | ASET (font_object, FONT_FORMAT_INDEX, Qx); |