aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGeoff Voelker1998-10-20 22:15:14 +0000
committerGeoff Voelker1998-10-20 22:15:14 +0000
commitcabb23bc0d39f05bcd8b2174e083cb4208ccdc85 (patch)
tree9677eb81ca26a22adafcfaca66e921ec03bff492 /src
parent4587b02635dd8a7fe39cc899b61ffb65d548f8a3 (diff)
downloademacs-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.c832
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
4This file is part of GNU Emacs. 4This 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
18Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */ 19Boston, 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
59extern unsigned int msh_mousewheel; 92extern unsigned int msh_mousewheel;
60 93
61extern void free_frame_menubar (); 94extern void free_frame_menubar ();
@@ -99,6 +132,11 @@ static int highlight;
99static int curs_x; 132static int curs_x;
100static int curs_y; 133static 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. */
138int w32_no_unicode_output;
139
102DWORD dwWindowsThreadId = 0; 140DWORD dwWindowsThreadId = 0;
103HANDLE hWindowsThread = NULL; 141HANDLE hWindowsThread = NULL;
104DWORD dwMainThreadId = 0; 142DWORD dwMainThreadId = 0;
@@ -476,6 +514,66 @@ w32_cursor_to (row, col)
476 } 514 }
477} 515}
478 516
517int
518w32_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
557BOOL
558w32_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
495static void 593static int
496dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp) 594dumpglyphs (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
4237Lisp_Object
4238x_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.");
4624When nil, the right-alt and left-ctrl key combination is\n\ 5164When nil, the right-alt and left-ctrl key combination is\n\
4625interpreted normally."); 5165interpreted 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\
5170Unicode output may prevent some third party applications for displaying\n\
5171Far-East Languages on Windows 95/98 from working properly.\n\
5172NT uses Unicode internally anyway, so this flag will probably have no\n\
5173affect on NT machines.");
5174 w32_no_unicode_output = 0;
4627} 5175}