diff options
| author | Geoff Voelker | 1998-10-20 22:15:14 +0000 |
|---|---|---|
| committer | Geoff Voelker | 1998-10-20 22:15:14 +0000 |
| commit | cabb23bc0d39f05bcd8b2174e083cb4208ccdc85 (patch) | |
| tree | 9677eb81ca26a22adafcfaca66e921ec03bff492 /src | |
| parent | 4587b02635dd8a7fe39cc899b61ffb65d548f8a3 (diff) | |
| download | emacs-cabb23bc0d39f05bcd8b2174e083cb4208ccdc85.tar.gz emacs-cabb23bc0d39f05bcd8b2174e083cb4208ccdc85.zip | |
Include fontset.h. Define codepage macros.
Add ENCODE_BIG5 macro from coding.c.
(w32_no_unicode_output): New variable.
(w32_codepage_for_charset, w32_use_unicode_for_codepage): New
functions.
(BUILD_WCHAR_T, BYTE1, BYTE2): New macros.
(dumpglyphs): Rewrite based on xterm.c equivalent.
(x_new_font): Use functionality provided in fontset.c.
(x_new_fontset): New function based on the one in xterm.c.
(syms_of_w32term): Add w32-no-unicode-output flag.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32term.c | 832 |
1 files changed, 690 insertions, 142 deletions
diff --git a/src/w32term.c b/src/w32term.c index b55c6c5d83d..8f5682cb934 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Implementation of GUI terminal on the Microsoft W32 API. | 1 | /* Implementation of GUI terminal on the Microsoft W32 API. |
| 2 | Copyright (C) 1989, 1993, 1994, 1995 Free Software Foundation, Inc. | 2 | Copyright (C) 1989, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -18,13 +18,12 @@ along with GNU Emacs; see the file COPYING. If not, write to the | |||
| 18 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 18 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 19 | Boston, MA 02111-1307, USA. */ | 19 | Boston, MA 02111-1307, USA. */ |
| 20 | 20 | ||
| 21 | /* Added by Kevin Gallo */ | ||
| 22 | |||
| 23 | #include <signal.h> | 21 | #include <signal.h> |
| 24 | #include <config.h> | 22 | #include <config.h> |
| 25 | #include <stdio.h> | 23 | #include <stdio.h> |
| 26 | #include "lisp.h" | 24 | #include "lisp.h" |
| 27 | #include "charset.h" | 25 | #include "charset.h" |
| 26 | #include "fontset.h" | ||
| 28 | #include "blockinput.h" | 27 | #include "blockinput.h" |
| 29 | 28 | ||
| 30 | #include "w32term.h" | 29 | #include "w32term.h" |
| @@ -56,6 +55,40 @@ Boston, MA 02111-1307, USA. */ | |||
| 56 | #define min(x, y) (((x) < (y)) ? (x) : (y)) | 55 | #define min(x, y) (((x) < (y)) ? (x) : (y)) |
| 57 | #define max(x, y) (((x) > (y)) ? (x) : (y)) | 56 | #define max(x, y) (((x) > (y)) ? (x) : (y)) |
| 58 | 57 | ||
| 58 | /* Windows libraries do not define codepages other than ANSI and | ||
| 59 | Unicode. We need all the ones for the languages that Emacs supports | ||
| 60 | if languages other than that of the current locale are to be | ||
| 61 | displayed under NT. */ | ||
| 62 | #define CP_DEFAULT 1004 | ||
| 63 | #define CP_SJIS 932 | ||
| 64 | #define CP_GB2312 936 | ||
| 65 | #define CP_BIG5 950 | ||
| 66 | #define CP_KOREAN 949 | ||
| 67 | #define CP_THAI 874 | ||
| 68 | #define CP_LATIN1 1252 | ||
| 69 | #define CP_LATIN2 1250 | ||
| 70 | #define CP_LATIN3 1254 | ||
| 71 | #define CP_LATIN4 1257 | ||
| 72 | #define CP_CYRILLIC5 1251 | ||
| 73 | #define CP_ARABIC6 1256 | ||
| 74 | #define CP_GREEK7 1253 | ||
| 75 | #define CP_HEBREW8 1255 | ||
| 76 | #define CP_LATIN9 /*1258?*/ | ||
| 77 | #define CP_VIETNAM /*???*/ | ||
| 78 | |||
| 79 | /* ENCODE_SJIS is defined in coding.h, but ENCODE_BIG5 is only in | ||
| 80 | coding.c, so need our own copy here */ | ||
| 81 | #define BIG5_SAME_ROW (0xFF - 0xA1 + 0x7F - 0x40) | ||
| 82 | #define ENCODE_BIG5(charset, c1, c2, b1, b2) \ | ||
| 83 | do { \ | ||
| 84 | unsigned int temp = (c1 - 0x21) * (0xFF - 0xA1) + (c2 - 0x21); \ | ||
| 85 | if (charset == charset_big5_2) \ | ||
| 86 | temp += BIG5_SAME_ROW * (0xC9 - 0xA1); \ | ||
| 87 | b1 = temp / BIG5_SAME_ROW + 0xA1; \ | ||
| 88 | b2 = temp % BIG5_SAME_ROW; \ | ||
| 89 | b2 += b2 < 0x3F ? 0x40 : 0x62; \ | ||
| 90 | } while (0) | ||
| 91 | |||
| 59 | extern unsigned int msh_mousewheel; | 92 | extern unsigned int msh_mousewheel; |
| 60 | 93 | ||
| 61 | extern void free_frame_menubar (); | 94 | extern void free_frame_menubar (); |
| @@ -99,6 +132,11 @@ static int highlight; | |||
| 99 | static int curs_x; | 132 | static int curs_x; |
| 100 | static int curs_y; | 133 | static int curs_y; |
| 101 | 134 | ||
| 135 | /* Flag to disable Unicode output in case users wish to use programs | ||
| 136 | like Twinbridge on '95 rather than installed system level support | ||
| 137 | for Far East languages. */ | ||
| 138 | int w32_no_unicode_output; | ||
| 139 | |||
| 102 | DWORD dwWindowsThreadId = 0; | 140 | DWORD dwWindowsThreadId = 0; |
| 103 | HANDLE hWindowsThread = NULL; | 141 | HANDLE hWindowsThread = NULL; |
| 104 | DWORD dwMainThreadId = 0; | 142 | DWORD dwMainThreadId = 0; |
| @@ -476,6 +514,66 @@ w32_cursor_to (row, col) | |||
| 476 | } | 514 | } |
| 477 | } | 515 | } |
| 478 | 516 | ||
| 517 | int | ||
| 518 | w32_codepage_for_charset (int charset) | ||
| 519 | { | ||
| 520 | /* The codepage is only used to convert to unicode, so we only need | ||
| 521 | to cover the languages that we may print via unicode. */ | ||
| 522 | if (charset == charset_latin_iso8859_1) | ||
| 523 | return CP_LATIN1; | ||
| 524 | else if (charset == charset_big5_1 || | ||
| 525 | charset == charset_big5_2) | ||
| 526 | return CP_BIG5; | ||
| 527 | else if (charset == charset_jisx0208 | ||
| 528 | || charset == charset_jisx0208_1978 | ||
| 529 | || charset == charset_katakana_jisx0201 | ||
| 530 | || charset == charset_latin_jisx0201 | ||
| 531 | || charset == charset_id_internal ("japanese-jisx0212")) | ||
| 532 | return CP_SJIS; | ||
| 533 | else if (charset == charset_id_internal ("chinese-gb2312")) | ||
| 534 | return CP_GB2312; | ||
| 535 | else if (charset == charset_id_internal ("korean-ksc5601")) | ||
| 536 | return CP_KOREAN; | ||
| 537 | else if (charset == charset_id_internal ("latin-iso8859-2")) | ||
| 538 | return CP_LATIN2; | ||
| 539 | else if (charset == charset_id_internal ("latin-iso8859-3")) | ||
| 540 | return CP_LATIN3; | ||
| 541 | else if (charset == charset_id_internal ("latin-iso8859-4")) | ||
| 542 | return CP_LATIN4; | ||
| 543 | else if (charset == charset_id_internal ("cyrillic-iso8859-5")) | ||
| 544 | return CP_CYRILLIC5; | ||
| 545 | else if (charset == charset_id_internal ("arabic-iso8859-6")) | ||
| 546 | return CP_ARABIC6; | ||
| 547 | else if (charset == charset_id_internal ("greek-iso8859-7")) | ||
| 548 | return CP_GREEK7; | ||
| 549 | else if (charset == charset_id_internal ("hebrew-iso8859-8")) | ||
| 550 | return CP_HEBREW8; | ||
| 551 | else if (charset == charset_id_internal ("thai-tis620")) | ||
| 552 | return CP_THAI; | ||
| 553 | else /* Don't care - return system default. */ | ||
| 554 | return CP_DEFAULT; | ||
| 555 | } | ||
| 556 | |||
| 557 | BOOL | ||
| 558 | w32_use_unicode_for_codepage (codepage) | ||
| 559 | { | ||
| 560 | /* If the current codepage is supported, use Unicode for output. */ | ||
| 561 | return (w32_no_unicode_output | ||
| 562 | && codepage != CP_DEFAULT && IsValidCodePage (codepage)); | ||
| 563 | } | ||
| 564 | |||
| 565 | /* Dealing with bits of wchar_t as if they were an XChar2B. */ | ||
| 566 | #define BUILD_WCHAR_T(byte1, byte2) \ | ||
| 567 | ((wchar_t)(((byte1 & 0x00ff) << 8) | (byte2 & 0x00ff))) | ||
| 568 | |||
| 569 | |||
| 570 | #define BYTE1(ch) \ | ||
| 571 | ((ch & 0xff00) >> 8) | ||
| 572 | |||
| 573 | #define BYTE2(ch) \ | ||
| 574 | (ch & 0x00ff) | ||
| 575 | |||
| 576 | |||
| 479 | /* Display a sequence of N glyphs found at GP. | 577 | /* Display a sequence of N glyphs found at GP. |
| 480 | WINDOW is the window to output to. LEFT and TOP are starting coords. | 578 | WINDOW is the window to output to. LEFT and TOP are starting coords. |
| 481 | HL is 1 if this text is highlighted, 2 if the cursor is on it, | 579 | HL is 1 if this text is highlighted, 2 if the cursor is on it, |
| @@ -492,7 +590,7 @@ w32_cursor_to (row, col) | |||
| 492 | to which we can actually apply intern_face. | 590 | to which we can actually apply intern_face. |
| 493 | Call this function with input blocked. */ | 591 | Call this function with input blocked. */ |
| 494 | 592 | ||
| 495 | static void | 593 | static int |
| 496 | dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | 594 | dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) |
| 497 | struct frame *f; | 595 | struct frame *f; |
| 498 | int left, top; | 596 | int left, top; |
| @@ -500,97 +598,135 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 500 | register int n; /* Number of glyphs to display. */ | 598 | register int n; /* Number of glyphs to display. */ |
| 501 | int hl; | 599 | int hl; |
| 502 | int just_foreground; | 600 | int just_foreground; |
| 503 | struct cmpchar_info *cmpcharp; | 601 | struct cmpchar_info *cmpcharp; |
| 504 | { | 602 | { |
| 505 | /* Holds characters to be displayed. */ | 603 | wchar_t *x_2byte_buffer |
| 506 | char *buf = (char *) alloca (f->width * sizeof (*buf)); | 604 | = (wchar_t *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*x_2byte_buffer)); |
| 507 | register char *cp; /* Steps through buf[]. */ | 605 | register wchar_t *cp; /* Steps through x_2byte_buffer[]. */ |
| 606 | |||
| 607 | /* Allocate double the window width, as this buffer may contain MBCS | ||
| 608 | characters under w32. */ | ||
| 609 | char *x_1byte_buffer | ||
| 610 | = (char *) alloca (2 * FRAME_WINDOW_WIDTH (f) * sizeof (*x_1byte_buffer)); | ||
| 611 | register char *bp; /* Steps through x_1byte_buffer[]. */ | ||
| 508 | register int tlen = GLYPH_TABLE_LENGTH; | 612 | register int tlen = GLYPH_TABLE_LENGTH; |
| 509 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | 613 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; |
| 510 | Window window = FRAME_W32_WINDOW (f); | 614 | Window window = FRAME_W32_WINDOW (f); |
| 615 | HDC hdc = get_frame_dc (f); | ||
| 511 | int orig_left = left; | 616 | int orig_left = left; |
| 512 | HDC hdc; | 617 | int gidx = 0; |
| 513 | 618 | int i; | |
| 514 | hdc = get_frame_dc (f); | ||
| 515 | 619 | ||
| 516 | while (n > 0) | 620 | while (n > 0) |
| 517 | { | 621 | { |
| 518 | /* Get the face-code of the next GLYPH. */ | 622 | /* Get the face-code of the next GLYPH. */ |
| 519 | int cf, len; | 623 | int cf, len, n_chars; |
| 520 | GLYPH g = *gp; | 624 | GLYPH g = *gp; |
| 521 | int ch, charset; | 625 | int ch, charset; |
| 626 | Lisp_Object first_ch; | ||
| 627 | /* HIGHEST and LOWEST are used while drawing a composite | ||
| 628 | character. The meanings are described later. */ | ||
| 629 | int highest, lowest; | ||
| 522 | 630 | ||
| 523 | GLYPH_FOLLOW_ALIASES (tbase, tlen, g); | 631 | GLYPH_FOLLOW_ALIASES (tbase, tlen, g); |
| 524 | cf = (cmpcharp ? cmpcharp->face_work : FAST_GLYPH_FACE (g)); | 632 | cf = (cmpcharp ? cmpcharp->face_work : FAST_GLYPH_FACE (g)); |
| 525 | ch = FAST_GLYPH_CHAR (g); | 633 | ch = FAST_GLYPH_CHAR (g); |
| 634 | if (unibyte_display_via_language_environment | ||
| 635 | && SINGLE_BYTE_CHAR_P (ch) | ||
| 636 | && ch >= 160) | ||
| 637 | ch = unibyte_char_to_multibyte (ch); | ||
| 638 | if (gidx == 0) XSETFASTINT (first_ch, ch); | ||
| 526 | charset = CHAR_CHARSET (ch); | 639 | charset = CHAR_CHARSET (ch); |
| 527 | if (charset == CHARSET_COMPOSITION) | 640 | if (charset == CHARSET_COMPOSITION) |
| 528 | { | 641 | { |
| 529 | struct face *face = FRAME_DEFAULT_FACE (f); | ||
| 530 | XFontStruct *font = FACE_FONT (face); | ||
| 531 | /* We must draw components of the composite character on the | 642 | /* We must draw components of the composite character on the |
| 532 | same column */ | 643 | same column. */ |
| 533 | cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (ch)]; | 644 | cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (ch)]; |
| 534 | 645 | ||
| 535 | /* Set the face in the slot for work. */ | 646 | /* Set the face in the slot for work. */ |
| 536 | cmpcharp->face_work = cf; | 647 | cmpcharp->face_work = cf; |
| 537 | 648 | ||
| 649 | /* We don't need the return value ... */ | ||
| 538 | dumpglyphs (f, left, top, cmpcharp->glyph, cmpcharp->glyph_len, | 650 | dumpglyphs (f, left, top, cmpcharp->glyph, cmpcharp->glyph_len, |
| 539 | hl, just_foreground, cmpcharp); | 651 | hl, just_foreground, cmpcharp); |
| 540 | left += FONT_WIDTH (font) * cmpcharp->width; | 652 | /* ... because the width of just drawn text can be |
| 653 | calculated as follows. */ | ||
| 654 | left += FONT_WIDTH (FRAME_FONT (f)) * cmpcharp->width; | ||
| 655 | |||
| 541 | ++gp, --n; | 656 | ++gp, --n; |
| 542 | while (gp && (*gp & GLYPH_MASK_PADDING)) ++gp, --n; | 657 | while (gp && (*gp & GLYPH_MASK_PADDING)) ++gp, --n; |
| 543 | cmpcharp = NULL; | 658 | cmpcharp = NULL; |
| 544 | continue; | 659 | continue; |
| 545 | } | 660 | } |
| 546 | /* Find the run of consecutive glyphs with the same face-code. | 661 | |
| 547 | Extract their character codes into BUF. */ | 662 | /* Find the run of consecutive glyphs which can be drawn with |
| 548 | cp = buf; | 663 | the same DC (i.e. the same charset and the same face-code). |
| 664 | Extract their character codes into X_2BYTE_BUFFER. | ||
| 665 | If CMPCHARP is not NULL, face-code is not checked because we | ||
| 666 | use only the face specified in `cmpcharp->face_work'. */ | ||
| 667 | cp = x_2byte_buffer; | ||
| 549 | while (n > 0) | 668 | while (n > 0) |
| 550 | { | 669 | { |
| 551 | int this_charset, c[2]; | 670 | int this_charset, c1, c2; |
| 552 | 671 | ||
| 553 | g = *gp; | 672 | g = *gp; |
| 554 | GLYPH_FOLLOW_ALIASES (tbase, tlen, g); | 673 | GLYPH_FOLLOW_ALIASES (tbase, tlen, g); |
| 555 | ch = FAST_GLYPH_CHAR (g); | 674 | ch = FAST_GLYPH_CHAR (g); |
| 556 | SPLIT_CHAR (ch, this_charset, c[0], c[1]); | 675 | if (unibyte_display_via_language_environment |
| 676 | && SINGLE_BYTE_CHAR_P (ch) | ||
| 677 | && ch >= 160) | ||
| 678 | ch = unibyte_char_to_multibyte (ch); | ||
| 679 | SPLIT_CHAR (ch, this_charset, c1, c2); | ||
| 557 | if (this_charset != charset | 680 | if (this_charset != charset |
| 558 | || (cmpcharp == NULL && FAST_GLYPH_FACE (g) != cf)) | 681 | || (cmpcharp == NULL && FAST_GLYPH_FACE (g) != cf)) |
| 559 | break; | 682 | break; |
| 560 | 683 | ||
| 561 | if ( c[1] > 0 ) | 684 | if (c2 > 0) |
| 562 | { | 685 | *cp = BUILD_WCHAR_T (c1, c2); |
| 563 | int consumed, produced; | ||
| 564 | /* Handle multibyte characters (still assuming user | ||
| 565 | selects correct font themselves for now */ | ||
| 566 | produced = encode_terminal_code(gp, cp, 1, | ||
| 567 | (f->width*sizeof(*buf))-(cp-buf), &consumed); | ||
| 568 | /* If we can't display this glyph, skip it */ | ||
| 569 | if (consumed == 0) | ||
| 570 | gp++,n--; | ||
| 571 | else | ||
| 572 | gp += consumed, n-= consumed; | ||
| 573 | cp += produced; | ||
| 574 | } | ||
| 575 | else | 686 | else |
| 576 | { | 687 | *cp = BUILD_WCHAR_T (0, c1); |
| 577 | *cp++ = c[0]; | 688 | ++cp; |
| 578 | ++gp, --n; | 689 | ++gp, --n; |
| 579 | } | ||
| 580 | while (gp && (*gp & GLYPH_MASK_PADDING)) | 690 | while (gp && (*gp & GLYPH_MASK_PADDING)) |
| 581 | ++gp, --n; | 691 | ++gp, --n; |
| 582 | } | 692 | } |
| 583 | 693 | ||
| 584 | /* LEN gets the length of the run. */ | 694 | /* LEN gets the length of the run. */ |
| 585 | len = cp - buf; | 695 | len = cp - x_2byte_buffer; |
| 586 | /* Now output this run of chars, with the font and pixel values | 696 | /* Now output this run of chars, with the font and pixel values |
| 587 | determined by the face code CF. */ | 697 | determined by the face code CF. */ |
| 588 | { | 698 | { |
| 589 | int stippled = 0; | ||
| 590 | struct face *face = FRAME_DEFAULT_FACE (f); | 699 | struct face *face = FRAME_DEFAULT_FACE (f); |
| 591 | XFontStruct *font = FACE_FONT (face); | 700 | XFontStruct *font = NULL; |
| 592 | COLORREF fg; | 701 | COLORREF fg; |
| 593 | COLORREF bg; | 702 | COLORREF bg; |
| 703 | int stippled = 0; | ||
| 704 | int line_height = FRAME_LINE_HEIGHT (f); | ||
| 705 | /* Pixel width of each glyph in this run. */ | ||
| 706 | int glyph_width | ||
| 707 | = (FONT_WIDTH (FRAME_FONT (f)) | ||
| 708 | * (cmpcharp ? cmpcharp->width : CHARSET_WIDTH (charset))); | ||
| 709 | /* Overall pixel width of this run. */ | ||
| 710 | int run_width | ||
| 711 | = (FONT_WIDTH (FRAME_FONT (f)) | ||
| 712 | * (cmpcharp ? cmpcharp->width : len * CHARSET_WIDTH (charset))); | ||
| 713 | /* A flag to tell if we have already filled background. We | ||
| 714 | fill background in advance in the following cases: | ||
| 715 | 1) A face has stipple. | ||
| 716 | 2) A height of font is shorter than LINE_HEIGHT. | ||
| 717 | 3) Drawing a composite character. | ||
| 718 | 4) Font has non-zero _MULE_BASELINE_OFFSET property. | ||
| 719 | After filling background, we draw glyphs by XDrawString16. */ | ||
| 720 | int background_filled; | ||
| 721 | /* Baseline position of a character, offset from TOP. */ | ||
| 722 | int baseline; | ||
| 723 | /* The property value of `_MULE_RELATIVE_COMPOSE' and | ||
| 724 | `_MULE_DEFAULT_ASCENT'. */ | ||
| 725 | int relative_compose = 0, default_ascent = 0; | ||
| 726 | /* 1 if we find no font or a font of inappropriate size. */ | ||
| 727 | int require_clipping; | ||
| 728 | int codepage = CP_DEFAULT; | ||
| 729 | BOOL print_via_unicode = FALSE; | ||
| 594 | 730 | ||
| 595 | /* HL = 3 means use a mouse face previously chosen. */ | 731 | /* HL = 3 means use a mouse face previously chosen. */ |
| 596 | if (hl == 3) | 732 | if (hl == 3) |
| @@ -609,7 +745,6 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 609 | face = FRAME_MODE_LINE_FACE (f); | 745 | face = FRAME_MODE_LINE_FACE (f); |
| 610 | else | 746 | else |
| 611 | face = intern_face (f, FRAME_COMPUTED_FACES (f) [cf]); | 747 | face = intern_face (f, FRAME_COMPUTED_FACES (f) [cf]); |
| 612 | font = FACE_FONT (face); | ||
| 613 | if (FACE_STIPPLE (face)) | 748 | if (FACE_STIPPLE (face)) |
| 614 | stippled = 1; | 749 | stippled = 1; |
| 615 | } | 750 | } |
| @@ -620,11 +755,162 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 620 | else if (hl == 1) | 755 | else if (hl == 1) |
| 621 | { | 756 | { |
| 622 | face = FRAME_MODE_LINE_FACE (f); | 757 | face = FRAME_MODE_LINE_FACE (f); |
| 623 | font = FACE_FONT (face); | ||
| 624 | if (FACE_STIPPLE (face)) | 758 | if (FACE_STIPPLE (face)) |
| 625 | stippled = 1; | 759 | stippled = 1; |
| 626 | } | 760 | } |
| 627 | 761 | ||
| 762 | /* Setting appropriate font and codepage for this charset. */ | ||
| 763 | if (charset != CHARSET_ASCII) | ||
| 764 | { | ||
| 765 | int font_id; | ||
| 766 | int fontset = FACE_FONTSET (face); | ||
| 767 | struct font_info *fontp; | ||
| 768 | |||
| 769 | if ((fontset < 0 && (fontset = FRAME_FONTSET (f)) < 0) | ||
| 770 | || !(fontp = FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f), | ||
| 771 | charset, NULL, fontset))) | ||
| 772 | goto font_not_found; | ||
| 773 | |||
| 774 | font = (XFontStruct *) (fontp->font); | ||
| 775 | codepage = w32_codepage_for_charset (charset); | ||
| 776 | print_via_unicode = w32_use_unicode_for_codepage (codepage); | ||
| 777 | |||
| 778 | /* tmLastChar will only exceed 255 if TEXTMETRICW is used | ||
| 779 | (ie on NT but not on 95). In this case there is no harm | ||
| 780 | in being wrong, so have a go anyway. */ | ||
| 781 | baseline = | ||
| 782 | (font->tm.tmLastChar > 255 | ||
| 783 | ? (line_height + font->tm.tmAscent - font->tm.tmDescent) / 2 | ||
| 784 | : f->output_data.w32->font_baseline - fontp->baseline_offset); | ||
| 785 | if (FONT_HEIGHT (font) <= line_height | ||
| 786 | && (font->tm.tmAscent > baseline | ||
| 787 | || font->tm.tmDescent > line_height - baseline)) | ||
| 788 | /* Adjust baseline for this font to show the whole | ||
| 789 | glyphs in a line. */ | ||
| 790 | baseline = line_height - font->tm.tmDescent; | ||
| 791 | |||
| 792 | if (cmpcharp && cmpcharp->cmp_rule == NULL) | ||
| 793 | { | ||
| 794 | relative_compose = fontp->relative_compose; | ||
| 795 | default_ascent = fontp->default_ascent; | ||
| 796 | } | ||
| 797 | |||
| 798 | /* We have to change code points in the following cases. */ | ||
| 799 | if (charset == charset_big5_1 | ||
| 800 | || charset == charset_big5_2) | ||
| 801 | { | ||
| 802 | /* Handle Big5 encoding specially rather than | ||
| 803 | requiring a CCL. */ | ||
| 804 | int big1, big2; | ||
| 805 | for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++) | ||
| 806 | { | ||
| 807 | ENCODE_BIG5 (charset, BYTE1 (*cp), BYTE2 (*cp), | ||
| 808 | big1, big2); | ||
| 809 | *cp = BUILD_WCHAR_T (big1, big2); | ||
| 810 | } | ||
| 811 | } | ||
| 812 | else if (fontp->font_encoder) | ||
| 813 | { | ||
| 814 | /* This font requires CCL program to calculate code | ||
| 815 | point of characters. */ | ||
| 816 | struct ccl_program *ccl = fontp->font_encoder; | ||
| 817 | |||
| 818 | if (CHARSET_DIMENSION (charset) == 1) | ||
| 819 | for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++) | ||
| 820 | { | ||
| 821 | ccl->reg[0] = charset; | ||
| 822 | ccl->reg[1] = BYTE2 (*cp); | ||
| 823 | ccl_driver (ccl, NULL, NULL, 0, 0, NULL); | ||
| 824 | /* We assume that MSBs are appropriately | ||
| 825 | set/reset by CCL program. */ | ||
| 826 | #if 0 /* this probably works under NT, but not under 95. */ | ||
| 827 | if (font->tm.tmLastChar < 256) /* 1-byte font */ | ||
| 828 | *cp = BUILD_WCHAR_T (0, ccl->reg[1]); | ||
| 829 | else | ||
| 830 | *cp = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]); | ||
| 831 | #else /* Assume single dimensional charsets stay so. */ | ||
| 832 | *cp = BUILD_WCHAR_T (0, ccl->reg[1]); | ||
| 833 | #endif | ||
| 834 | } | ||
| 835 | else | ||
| 836 | for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++) | ||
| 837 | { | ||
| 838 | ccl->reg[0] = charset; | ||
| 839 | ccl->reg[1] = BYTE1 (*cp) , ccl->reg[2] = BYTE2 (*cp); | ||
| 840 | ccl_driver (ccl, NULL, NULL, 0, 0, NULL); | ||
| 841 | /* We assume that MSBs are appropriately | ||
| 842 | set/reset by CCL program. */ | ||
| 843 | #if 0 /* this probably works under NT, but not under 95. */ | ||
| 844 | if (font->tm.tmLastChar < 256) /* 1-byte font */ | ||
| 845 | *cp = BUILD_WCHAR_T (0, ccl->reg[1]); | ||
| 846 | else | ||
| 847 | *cp = BUILD_WCHAR_T (ccl->reg[1],ccl->reg[2]); | ||
| 848 | #else /* Assume multidimensional charsets stay so. */ | ||
| 849 | *cp = BUILD_WCHAR_T (ccl->reg[1],ccl->reg[2]); | ||
| 850 | #endif | ||
| 851 | } | ||
| 852 | } | ||
| 853 | /* Japanese Kanji are a special case under w32, as they | ||
| 854 | must be printed in SJIS rather than EUC. */ | ||
| 855 | else if ((charset == charset_jisx0208) | ||
| 856 | || (charset == charset_jisx0208_1978) | ||
| 857 | || (charset == charset_id_internal ("japanese-jisx0212"))) | ||
| 858 | { | ||
| 859 | int sjis1, sjis2; | ||
| 860 | for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++) | ||
| 861 | { | ||
| 862 | ENCODE_SJIS (BYTE1 (*cp), BYTE2 (*cp), sjis1, sjis2); | ||
| 863 | *cp = BUILD_WCHAR_T (sjis1, sjis2); | ||
| 864 | } | ||
| 865 | } | ||
| 866 | else if (fontp->encoding[charset]) | ||
| 867 | { | ||
| 868 | int enc = fontp->encoding[charset]; | ||
| 869 | |||
| 870 | if ((enc == 1 || enc == 2) && CHARSET_DIMENSION (charset) == 2) | ||
| 871 | for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++) | ||
| 872 | *cp = BUILD_WCHAR_T (BYTE1 (*cp) | 0x80, BYTE2 (*cp)); | ||
| 873 | if (enc == 1 || enc == 3) | ||
| 874 | for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++) | ||
| 875 | *cp = BUILD_WCHAR_T (BYTE1 (*cp), BYTE2 (*cp) | 0x80); | ||
| 876 | } | ||
| 877 | } | ||
| 878 | else | ||
| 879 | { | ||
| 880 | font_not_found: | ||
| 881 | if (charset == CHARSET_ASCII || charset == charset_latin_iso8859_1) | ||
| 882 | { | ||
| 883 | font = FACE_FONT (face); | ||
| 884 | if (!font || font == (XFontStruct *) FACE_DEFAULT) | ||
| 885 | font = FRAME_FONT (f); | ||
| 886 | baseline = FONT_BASE (FRAME_FONT (f)); | ||
| 887 | if (charset == charset_latin_iso8859_1) | ||
| 888 | { | ||
| 889 | if (font->tm.tmLastChar < 0x80) | ||
| 890 | /* This font can't display Latin1 characters. */ | ||
| 891 | font = NULL; | ||
| 892 | else | ||
| 893 | { | ||
| 894 | for (cp = x_2byte_buffer; | ||
| 895 | cp < x_2byte_buffer + len; cp++) | ||
| 896 | *cp = BUILD_WCHAR_T (BYTE1 (*cp), | ||
| 897 | BYTE2 (*cp) | 0x80); | ||
| 898 | } | ||
| 899 | } | ||
| 900 | } | ||
| 901 | } | ||
| 902 | |||
| 903 | /* Convert x_2byte_buffer into a buffer of single byte | ||
| 904 | characters - possibly containing MBCS runs. */ | ||
| 905 | bp = x_1byte_buffer; | ||
| 906 | for (i = 0; i < len; i++) | ||
| 907 | { | ||
| 908 | if (BYTE1 (*(x_2byte_buffer + i))) | ||
| 909 | *bp++ = BYTE1 (*(x_2byte_buffer + i)); | ||
| 910 | *bp++ = BYTE2 (*(x_2byte_buffer + i)); | ||
| 911 | } | ||
| 912 | n_chars = bp - x_1byte_buffer; | ||
| 913 | |||
| 628 | fg = face->foreground; | 914 | fg = face->foreground; |
| 629 | bg = face->background; | 915 | bg = face->background; |
| 630 | 916 | ||
| @@ -634,11 +920,10 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 634 | /* The cursor overrides stippling. */ | 920 | /* The cursor overrides stippling. */ |
| 635 | stippled = 0; | 921 | stippled = 0; |
| 636 | 922 | ||
| 637 | if ((!face->font | 923 | if (font == FRAME_FONT (f) |
| 638 | || face->font == (XFontStruct *) FACE_DEFAULT | 924 | && face->background == FRAME_BACKGROUND_PIXEL (f) |
| 639 | || face->font == f->output_data.w32->font) | 925 | && face->foreground == FRAME_FOREGROUND_PIXEL (f) |
| 640 | && face->background == f->output_data.w32->background_pixel | 926 | && !cmpcharp) |
| 641 | && face->foreground == f->output_data.w32->foreground_pixel) | ||
| 642 | { | 927 | { |
| 643 | bg = f->output_data.w32->cursor_pixel; | 928 | bg = f->output_data.w32->cursor_pixel; |
| 644 | fg = face->background; | 929 | fg = face->background; |
| @@ -666,48 +951,322 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) | |||
| 666 | } | 951 | } |
| 667 | } | 952 | } |
| 668 | 953 | ||
| 669 | if (font == (XFontStruct *) FACE_DEFAULT) | 954 | if (font) |
| 670 | font = f->output_data.w32->font; | 955 | require_clipping = (!NILP (Vclip_large_size_font) |
| 671 | 956 | && (font->tm.tmAscent > baseline | |
| 672 | SetBkMode (hdc, just_foreground ? TRANSPARENT : OPAQUE); | 957 | || font->tm.tmDescent > |
| 958 | line_height - baseline | ||
| 959 | || (!cmpcharp | ||
| 960 | && FONT_WIDTH (font) > glyph_width))); | ||
| 961 | |||
| 962 | if (font && (just_foreground || (cmpcharp && gidx > 0))) | ||
| 963 | background_filled = 1; | ||
| 964 | |||
| 965 | /* Stippling not supported under w32. */ | ||
| 966 | |||
| 967 | else if (!font | ||
| 968 | || FONT_HEIGHT (font) < line_height | ||
| 969 | || FONT_WIDTH (font) < glyph_width | ||
| 970 | || cmpcharp) | ||
| 971 | { | ||
| 972 | /* Fill in the background for the current run. */ | ||
| 973 | w32_fill_area (f, hdc, bg, | ||
| 974 | left, | ||
| 975 | top, | ||
| 976 | run_width, | ||
| 977 | line_height); | ||
| 978 | background_filled = 1; | ||
| 979 | if (cmpcharp) | ||
| 980 | /* To assure not to fill background while drawing | ||
| 981 | remaining components. */ | ||
| 982 | just_foreground = 1; | ||
| 983 | } | ||
| 984 | else | ||
| 985 | background_filled = 0; | ||
| 673 | 986 | ||
| 987 | SetBkMode (hdc, background_filled ? TRANSPARENT : OPAQUE); | ||
| 674 | SetTextColor (hdc, fg); | 988 | SetTextColor (hdc, fg); |
| 675 | SetBkColor (hdc, bg); | 989 | SetBkColor (hdc, bg); |
| 676 | 990 | ||
| 677 | SelectObject (hdc, font->hfont); | 991 | if ( print_via_unicode ) |
| 678 | 992 | n_chars = MultiByteToWideChar | |
| 679 | TextOut (hdc, left, top, buf, len); | 993 | (codepage, 0, x_1byte_buffer, n_chars, |
| 994 | x_2byte_buffer, FRAME_WINDOW_WIDTH (f)); | ||
| 680 | 995 | ||
| 681 | if (!just_foreground) | 996 | if (font) |
| 682 | { | 997 | { |
| 683 | /* Clear the rest of the line's height. */ | 998 | SelectObject (hdc, font->hfont); |
| 684 | if (f->output_data.w32->line_height != FONT_HEIGHT (font)) | 999 | |
| 685 | w32_fill_area (f, hdc, bg, | 1000 | if (!cmpcharp) |
| 686 | left, | 1001 | { |
| 687 | top + FONT_HEIGHT (font), | 1002 | int multibyte_pos_offset = 0; |
| 688 | FONT_WIDTH (font) * len, | 1003 | if (require_clipping || FONT_WIDTH (font) != glyph_width) |
| 689 | f->output_data.w32->line_height - FONT_HEIGHT (font)); | 1004 | { |
| 1005 | RECT clip_rectangle; | ||
| 1006 | LPRECT clip_region = NULL; | ||
| 1007 | UINT fuOptions = 0; | ||
| 1008 | |||
| 1009 | for (i = 0; i < n_chars; i++) | ||
| 1010 | { | ||
| 1011 | if (require_clipping) | ||
| 1012 | { | ||
| 1013 | /* Set up a clipping rectangle for ExtTextOut */ | ||
| 1014 | fuOptions |= ETO_CLIPPED; | ||
| 1015 | clip_rectangle.left = left + i * glyph_width; | ||
| 1016 | clip_rectangle.right | ||
| 1017 | = left + (i + 1) * glyph_width; | ||
| 1018 | clip_rectangle.top = top; | ||
| 1019 | clip_rectangle.bottom = top + line_height; | ||
| 1020 | clip_region = &clip_rectangle; | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | /* baseline works differently on w32 than X, | ||
| 1024 | leave it out for now. */ | ||
| 1025 | if (print_via_unicode) | ||
| 1026 | ExtTextOutW (hdc, left + glyph_width * i, | ||
| 1027 | top /*+ baseline*/, fuOptions, | ||
| 1028 | clip_region, x_2byte_buffer + i, | ||
| 1029 | 1, NULL); | ||
| 1030 | else if (CHARSET_DIMENSION (charset) > 1) | ||
| 1031 | { | ||
| 1032 | /* Keep character together */ | ||
| 1033 | int n = CHARSET_DIMENSION (charset) ; | ||
| 1034 | ExtTextOut (hdc, left + multibyte_pos_offset, | ||
| 1035 | top /*+ baseline*/, fuOptions, | ||
| 1036 | clip_region, x_1byte_buffer + i, | ||
| 1037 | n, NULL); | ||
| 1038 | /* fiddle i. */ | ||
| 1039 | i += n - 1; | ||
| 1040 | multibyte_pos_offset += glyph_width; | ||
| 1041 | } | ||
| 1042 | else | ||
| 1043 | ExtTextOut (hdc, left + glyph_width * i, | ||
| 1044 | top /*+ baseline*/, fuOptions, | ||
| 1045 | clip_region, x_1byte_buffer + i, | ||
| 1046 | 1, NULL); | ||
| 1047 | } | ||
| 1048 | } | ||
| 1049 | else | ||
| 1050 | { | ||
| 1051 | /* Print the whole run of characters. */ | ||
| 1052 | if (print_via_unicode) | ||
| 1053 | TextOutW (hdc, left, top /*+ baseline*/, | ||
| 1054 | x_2byte_buffer, n_chars); | ||
| 1055 | else | ||
| 1056 | TextOut (hdc, left, top /*+ baseline*/, | ||
| 1057 | x_1byte_buffer, n_chars); | ||
| 1058 | } | ||
| 1059 | } | ||
| 1060 | else | ||
| 1061 | { | ||
| 1062 | /* Handle composite characters. */ | ||
| 1063 | RECT clip_rectangle; | ||
| 1064 | LPRECT clip_region = NULL; | ||
| 1065 | UINT fuOptions = 0; | ||
| 1066 | |||
| 1067 | if (require_clipping) | ||
| 1068 | { | ||
| 1069 | /* Set up a clipping rectangle for ExtTextOut */ | ||
| 1070 | fuOptions |= ETO_CLIPPED; | ||
| 1071 | clip_rectangle.left = left; | ||
| 1072 | clip_rectangle.right = left + glyph_width; | ||
| 1073 | clip_rectangle.top = top; | ||
| 1074 | clip_rectangle.bottom = top + line_height; | ||
| 1075 | clip_region = &clip_rectangle; | ||
| 1076 | } | ||
| 1077 | if ((cmpcharp->cmp_rule || relative_compose) | ||
| 1078 | && gidx == 0) | ||
| 1079 | { | ||
| 1080 | /* This is the first character. Initialize variables. | ||
| 1081 | HIGHEST is the highest position of glyphs ever | ||
| 1082 | written, LOWEST the lowest position. */ | ||
| 1083 | int x_offset = 0; | ||
| 1084 | |||
| 1085 | if (default_ascent | ||
| 1086 | && CHAR_TABLE_P (Vuse_default_ascent) | ||
| 1087 | && !NILP (Faref (Vuse_default_ascent, first_ch))) | ||
| 1088 | { | ||
| 1089 | highest = default_ascent; | ||
| 1090 | lowest = 0; | ||
| 1091 | } | ||
| 1092 | else | ||
| 1093 | { | ||
| 1094 | /* Per char metrics not supported on w32 - use | ||
| 1095 | font's metrics. */ | ||
| 1096 | highest = font->tm.tmAscent + 1; | ||
| 1097 | lowest = - font->tm.tmDescent; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | if (cmpcharp->cmp_rule) | ||
| 1101 | x_offset = (cmpcharp->col_offset[0] | ||
| 1102 | * FONT_WIDTH (FRAME_FONT (f))); | ||
| 1103 | |||
| 1104 | i = 1; | ||
| 1105 | |||
| 1106 | /* Draw the first character at the normal position. */ | ||
| 1107 | if (print_via_unicode) | ||
| 1108 | ExtTextOutW (hdc, left + x_offset, top /*+ baseline*/, | ||
| 1109 | fuOptions, clip_region, | ||
| 1110 | x_2byte_buffer, 1, NULL); | ||
| 1111 | else if (CHARSET_DIMENSION (charset) > 1) | ||
| 1112 | { | ||
| 1113 | /* Keep character together */ | ||
| 1114 | int n = CHARSET_DIMENSION (charset) ; | ||
| 1115 | ExtTextOut (hdc, left + x_offset, top /*+ baseline*/, | ||
| 1116 | fuOptions, clip_region, | ||
| 1117 | x_1byte_buffer, n, NULL); | ||
| 1118 | /* fiddle i. */ | ||
| 1119 | i += n - 1; | ||
| 1120 | } | ||
| 1121 | else | ||
| 1122 | ExtTextOut (hdc, left + x_offset, top /*+ baseline*/, | ||
| 1123 | fuOptions, clip_region, | ||
| 1124 | x_1byte_buffer, 1, NULL); | ||
| 1125 | gidx++; | ||
| 1126 | } | ||
| 1127 | else | ||
| 1128 | i = 0; | ||
| 1129 | |||
| 1130 | for (; i < n_chars; i++, gidx++) | ||
| 1131 | { | ||
| 1132 | int x_offset = 0, y_offset = 0; | ||
| 1133 | |||
| 1134 | if (relative_compose) | ||
| 1135 | { | ||
| 1136 | /* No per char metrics on w32. */ | ||
| 1137 | if (NILP (Vignore_relative_composition) | ||
| 1138 | || NILP (Faref (Vignore_relative_composition, | ||
| 1139 | make_number (cmpcharp->glyph[gidx])))) | ||
| 1140 | { | ||
| 1141 | if (- font->tm.tmDescent >= relative_compose) | ||
| 1142 | { | ||
| 1143 | /* Draw above the current glyphs. */ | ||
| 1144 | y_offset = highest + font->tm.tmDescent; | ||
| 1145 | highest += font->tm.tmAscent | ||
| 1146 | + font->tm.tmDescent; | ||
| 1147 | } | ||
| 1148 | else if (font->tm.tmAscent <= 0) | ||
| 1149 | { | ||
| 1150 | /* Draw beneath the current glyphs. */ | ||
| 1151 | y_offset = lowest - font->tm.tmAscent; | ||
| 1152 | lowest -= font->tm.tmAscent | ||
| 1153 | + font->tm.tmDescent; | ||
| 1154 | } | ||
| 1155 | } | ||
| 1156 | else | ||
| 1157 | { | ||
| 1158 | /* Draw the glyph at normal position. If | ||
| 1159 | it sticks out of HIGHEST or LOWEST, | ||
| 1160 | update them appropriately. */ | ||
| 1161 | if (font->tm.tmAscent > highest) | ||
| 1162 | highest = font->tm.tmAscent; | ||
| 1163 | else if (- font->tm.tmDescent < lowest) | ||
| 1164 | lowest = - font->tm.tmDescent; | ||
| 1165 | } | ||
| 1166 | } | ||
| 1167 | else if (cmpcharp->cmp_rule) | ||
| 1168 | { | ||
| 1169 | int gref = (cmpcharp->cmp_rule[gidx] - 0xA0) / 9; | ||
| 1170 | int nref = (cmpcharp->cmp_rule[gidx] - 0xA0) % 9; | ||
| 1171 | int bottom, top; | ||
| 1172 | |||
| 1173 | /* Re-encode GREF and NREF so that they specify | ||
| 1174 | only Y-axis information: | ||
| 1175 | 0:top, 1:base, 2:bottom, 3:center */ | ||
| 1176 | gref = gref / 3 + (gref == 4) * 2; | ||
| 1177 | nref = nref / 3 + (nref == 4) * 2; | ||
| 1178 | |||
| 1179 | /* No per char metrics on w32. */ | ||
| 1180 | bottom = ((gref == 0 ? highest : gref == 1 ? 0 | ||
| 1181 | : gref == 2 ? lowest | ||
| 1182 | : (highest + lowest) / 2) | ||
| 1183 | - (nref == 0 ? font->tm.tmAscent | ||
| 1184 | + font->tm.tmDescent | ||
| 1185 | : nref == 1 ? font->tm.tmDescent | ||
| 1186 | : nref == 2 ? 0 | ||
| 1187 | : (font->tm.tmAscent + | ||
| 1188 | font->tm.tmDescent) / 2)); | ||
| 1189 | top = bottom + (font->tm.tmAscent + | ||
| 1190 | font->tm.tmDescent); | ||
| 1191 | if (top > highest) | ||
| 1192 | highest = top; | ||
| 1193 | if (bottom < lowest) | ||
| 1194 | lowest = bottom; | ||
| 1195 | y_offset = bottom + font->tm.tmDescent; | ||
| 1196 | x_offset = (cmpcharp->col_offset[gidx] | ||
| 1197 | * FONT_WIDTH (FRAME_FONT(f))); | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | if (print_via_unicode) | ||
| 1201 | ExtTextOutW (hdc, left + x_offset, | ||
| 1202 | top /*+ baseline - y_offset*/, | ||
| 1203 | fuOptions, clip_region, | ||
| 1204 | x_2byte_buffer + i, 1, NULL); | ||
| 1205 | else if (CHARSET_DIMENSION (charset) > 1) | ||
| 1206 | { | ||
| 1207 | /* Keep character together */ | ||
| 1208 | int n = CHARSET_DIMENSION (charset) ; | ||
| 1209 | ExtTextOut (hdc, left + x_offset, | ||
| 1210 | top /*+ baseline - y_offset*/, | ||
| 1211 | fuOptions, clip_region, | ||
| 1212 | x_1byte_buffer + i, n, NULL); | ||
| 1213 | /* fiddle i. */ | ||
| 1214 | i += n - 1; | ||
| 1215 | } | ||
| 1216 | else | ||
| 1217 | ExtTextOut (hdc, left + x_offset, | ||
| 1218 | top /*+ baseline - y_offset*/, | ||
| 1219 | fuOptions, clip_region, | ||
| 1220 | x_1byte_buffer + i, 1, NULL); | ||
| 1221 | } | ||
| 1222 | } | ||
| 690 | } | 1223 | } |
| 1224 | if (!font) | ||
| 1225 | { | ||
| 1226 | /* Show rectangles to indicate that we found no font. */ | ||
| 1227 | int limit = cmpcharp ? 1 : len; | ||
| 691 | 1228 | ||
| 1229 | for (i = 0; i < limit; i++) | ||
| 1230 | Rectangle (hdc, left + glyph_width * i, top, | ||
| 1231 | left + glyph_width * (i + 1) - 1, | ||
| 1232 | top + line_height - 1); | ||
| 1233 | } | ||
| 1234 | else if (require_clipping && !NILP (Vhighlight_wrong_size_font)) | ||
| 1235 | { | ||
| 1236 | /* Indicate that we found a font of inappropriate size. */ | ||
| 1237 | int limit = cmpcharp ? 1 : len; | ||
| 1238 | |||
| 1239 | for (i = 0; i < limit; i++) | ||
| 1240 | { | ||
| 1241 | w32_fill_area (f, hdc, fg, left + glyph_width * i, | ||
| 1242 | top + line_height - 1, glyph_width, 1); | ||
| 1243 | w32_fill_area (f, hdc, fg, left + glyph_width * i, | ||
| 1244 | top + line_height - 3, 1, 2); | ||
| 1245 | } | ||
| 1246 | } | ||
| 692 | { | 1247 | { |
| 1248 | /* Setting underline position based on the metric of the | ||
| 1249 | current font results in shaky underline if it strides | ||
| 1250 | over different fonts. So, we set the position based only | ||
| 1251 | on the default font of this frame. */ | ||
| 693 | int underline_position = 1; | 1252 | int underline_position = 1; |
| 694 | 1253 | ||
| 695 | if (font->tm.tmDescent <= underline_position) | 1254 | if (FRAME_FONT (f)->tm.tmDescent <= underline_position) |
| 696 | underline_position = font->tm.tmDescent - 1; | 1255 | underline_position = FRAME_FONT (f)->tm.tmDescent - 1; |
| 697 | 1256 | ||
| 698 | if (face->underline) | 1257 | if (face->underline) |
| 699 | w32_fill_area (f, hdc, fg, | 1258 | w32_fill_area (f, hdc, fg, left, |
| 700 | left, (top | 1259 | top + FONT_BASE (font) + underline_position, |
| 701 | + FONT_BASE (font) | 1260 | run_width, 1); |
| 702 | + underline_position), | ||
| 703 | len * FONT_WIDTH (font), 1); | ||
| 704 | } | 1261 | } |
| 705 | 1262 | ||
| 706 | left += len * FONT_WIDTH (font); | 1263 | if (!cmpcharp) |
| 1264 | left += run_width; | ||
| 707 | } | 1265 | } |
| 708 | } | 1266 | } |
| 709 | |||
| 710 | release_frame_dc (f, hdc); | 1267 | release_frame_dc (f, hdc); |
| 1268 | |||
| 1269 | return (left - orig_left); | ||
| 711 | } | 1270 | } |
| 712 | 1271 | ||
| 713 | 1272 | ||
| @@ -3629,78 +4188,17 @@ x_new_font (f, fontname) | |||
| 3629 | struct frame *f; | 4188 | struct frame *f; |
| 3630 | register char *fontname; | 4189 | register char *fontname; |
| 3631 | { | 4190 | { |
| 3632 | int already_loaded; | 4191 | struct font_info *fontp |
| 3633 | int n_matching_fonts; | 4192 | = fs_load_font (f, FRAME_W32_FONT_TABLE (f), CHARSET_ASCII, |
| 3634 | XFontStruct *font_info; | 4193 | fontname, -1); |
| 3635 | char new_font_name[101]; | ||
| 3636 | |||
| 3637 | /* Get a font which matches this name */ | ||
| 3638 | { | ||
| 3639 | LOGFONT lf; | ||
| 3640 | |||
| 3641 | if (!x_to_w32_font(fontname, &lf) | ||
| 3642 | || !w32_to_x_font(&lf, new_font_name, 100)) | ||
| 3643 | { | ||
| 3644 | return Qnil; | ||
| 3645 | } | ||
| 3646 | } | ||
| 3647 | |||
| 3648 | /* See if we've already loaded a matching font. */ | ||
| 3649 | already_loaded = -1; | ||
| 3650 | |||
| 3651 | { | ||
| 3652 | int i; | ||
| 3653 | 4194 | ||
| 3654 | for (i = 0; i < FRAME_W32_DISPLAY_INFO (f)->n_fonts; i++) | 4195 | if (!fontp) |
| 3655 | if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->font_table[i].name, new_font_name)) | ||
| 3656 | { | ||
| 3657 | already_loaded = i; | ||
| 3658 | fontname = FRAME_W32_DISPLAY_INFO (f)->font_table[i].name; | ||
| 3659 | break; | ||
| 3660 | } | ||
| 3661 | } | ||
| 3662 | |||
| 3663 | /* If we have, just return it from the table. */ | ||
| 3664 | if (already_loaded >= 0) | ||
| 3665 | f->output_data.w32->font = FRAME_W32_DISPLAY_INFO (f)->font_table[already_loaded].font; | ||
| 3666 | /* Otherwise, load the font and add it to the table. */ | ||
| 3667 | else | ||
| 3668 | { | ||
| 3669 | XFontStruct *font; | ||
| 3670 | int n_fonts; | ||
| 3671 | |||
| 3672 | font = w32_load_font(FRAME_W32_DISPLAY_INFO (f), fontname); | ||
| 3673 | |||
| 3674 | if (! font) | ||
| 3675 | { | ||
| 3676 | return Qnil; | 4196 | return Qnil; |
| 3677 | } | ||
| 3678 | 4197 | ||
| 3679 | /* Do we need to create the table? */ | 4198 | FRAME_FONT (f) = (XFontStruct *) (fontp->font); |
| 3680 | if (FRAME_W32_DISPLAY_INFO (f)->font_table_size == 0) | 4199 | f->output_data.w32->font_baseline |
| 3681 | { | 4200 | = FRAME_FONT(f)->tm.tmAscent + fontp->baseline_offset; |
| 3682 | FRAME_W32_DISPLAY_INFO (f)->font_table_size = 16; | 4201 | FRAME_FONTSET (f) = -1; |
| 3683 | FRAME_W32_DISPLAY_INFO (f)->font_table | ||
| 3684 | = (struct font_info *) xmalloc (FRAME_W32_DISPLAY_INFO (f)->font_table_size | ||
| 3685 | * sizeof (struct font_info)); | ||
| 3686 | } | ||
| 3687 | /* Do we need to grow the table? */ | ||
| 3688 | else if (FRAME_W32_DISPLAY_INFO (f)->n_fonts | ||
| 3689 | >= FRAME_W32_DISPLAY_INFO (f)->font_table_size) | ||
| 3690 | { | ||
| 3691 | FRAME_W32_DISPLAY_INFO (f)->font_table_size *= 2; | ||
| 3692 | FRAME_W32_DISPLAY_INFO (f)->font_table | ||
| 3693 | = (struct font_info *) xrealloc (FRAME_W32_DISPLAY_INFO (f)->font_table, | ||
| 3694 | (FRAME_W32_DISPLAY_INFO (f)->font_table_size | ||
| 3695 | * sizeof (struct font_info))); | ||
| 3696 | } | ||
| 3697 | |||
| 3698 | n_fonts = FRAME_W32_DISPLAY_INFO (f)->n_fonts; | ||
| 3699 | FRAME_W32_DISPLAY_INFO (f)->font_table[n_fonts].name = (char *) xmalloc (strlen (fontname) + 1); | ||
| 3700 | bcopy (fontname, FRAME_W32_DISPLAY_INFO (f)->font_table[n_fonts].name, strlen (fontname) + 1); | ||
| 3701 | f->output_data.w32->font = FRAME_W32_DISPLAY_INFO (f)->font_table[n_fonts].font = font; | ||
| 3702 | FRAME_W32_DISPLAY_INFO (f)->n_fonts++; | ||
| 3703 | } | ||
| 3704 | 4202 | ||
| 3705 | /* Compute the scroll bar width in character columns. */ | 4203 | /* Compute the scroll bar width in character columns. */ |
| 3706 | if (f->scroll_bar_pixel_width > 0) | 4204 | if (f->scroll_bar_pixel_width > 0) |
| @@ -3731,6 +4229,48 @@ x_new_font (f, fontname) | |||
| 3731 | } | 4229 | } |
| 3732 | } | 4230 | } |
| 3733 | 4231 | ||
| 4232 | /* Give frame F the fontset named FONTSETNAME as its default font, and | ||
| 4233 | return the full name of that fontset. FONTSETNAME may be a wildcard | ||
| 4234 | pattern; in that case, we choose some fontset that fits the pattern. | ||
| 4235 | The return value shows which fontset we chose. */ | ||
| 4236 | |||
| 4237 | Lisp_Object | ||
| 4238 | x_new_fontset (f, fontsetname) | ||
| 4239 | struct frame *f; | ||
| 4240 | char *fontsetname; | ||
| 4241 | { | ||
| 4242 | int fontset = fs_query_fontset (f, fontsetname); | ||
| 4243 | struct fontset_info *fontsetp; | ||
| 4244 | Lisp_Object result; | ||
| 4245 | |||
| 4246 | if (fontset < 0) | ||
| 4247 | return Qnil; | ||
| 4248 | |||
| 4249 | if (FRAME_FONTSET (f) == fontset) | ||
| 4250 | /* This fontset is already set in frame F. There's nothing more | ||
| 4251 | to do. */ | ||
| 4252 | return build_string (fontsetname); | ||
| 4253 | |||
| 4254 | fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset]; | ||
| 4255 | |||
| 4256 | if (!fontsetp->fontname[CHARSET_ASCII]) | ||
| 4257 | /* This fontset doesn't contain ASCII font. */ | ||
| 4258 | return Qnil; | ||
| 4259 | |||
| 4260 | result = x_new_font (f, fontsetp->fontname[CHARSET_ASCII]); | ||
| 4261 | |||
| 4262 | if (!STRINGP (result)) | ||
| 4263 | /* Can't load ASCII font. */ | ||
| 4264 | return Qnil; | ||
| 4265 | |||
| 4266 | /* Since x_new_font doesn't update any fontset information, do it now. */ | ||
| 4267 | FRAME_FONTSET(f) = fontset; | ||
| 4268 | FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f), | ||
| 4269 | CHARSET_ASCII, XSTRING (result)->data, fontset); | ||
| 4270 | |||
| 4271 | return build_string (fontsetname); | ||
| 4272 | } | ||
| 4273 | |||
| 3734 | /* Calculate the absolute position in frame F | 4274 | /* Calculate the absolute position in frame F |
| 3735 | from its current recorded position values and gravity. */ | 4275 | from its current recorded position values and gravity. */ |
| 3736 | 4276 | ||
| @@ -3831,7 +4371,7 @@ x_set_offset (f, xoff, yoff, change_gravity) | |||
| 3831 | my_set_window_pos (FRAME_W32_WINDOW (f), | 4371 | my_set_window_pos (FRAME_W32_WINDOW (f), |
| 3832 | NULL, | 4372 | NULL, |
| 3833 | modified_left, modified_top, | 4373 | modified_left, modified_top, |
| 3834 | 0,0, | 4374 | 0, 0, |
| 3835 | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); | 4375 | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); |
| 3836 | UNBLOCK_INPUT; | 4376 | UNBLOCK_INPUT; |
| 3837 | } | 4377 | } |
| @@ -4624,4 +5164,12 @@ When nil, CapsLock only affects normal character input keys."); | |||
| 4624 | When nil, the right-alt and left-ctrl key combination is\n\ | 5164 | When nil, the right-alt and left-ctrl key combination is\n\ |
| 4625 | interpreted normally."); | 5165 | interpreted normally."); |
| 4626 | Vw32_recognize_altgr = Qt; | 5166 | Vw32_recognize_altgr = Qt; |
| 5167 | DEFVAR_BOOL ("w32-no-unicode-output", | ||
| 5168 | w32_no_unicode_output, | ||
| 5169 | "Disable the use of Unicode for text output if non-nil.\n\ | ||
| 5170 | Unicode output may prevent some third party applications for displaying\n\ | ||
| 5171 | Far-East Languages on Windows 95/98 from working properly.\n\ | ||
| 5172 | NT uses Unicode internally anyway, so this flag will probably have no\n\ | ||
| 5173 | affect on NT machines."); | ||
| 5174 | w32_no_unicode_output = 0; | ||
| 4627 | } | 5175 | } |