Mercurial > hg > xemacs-beta
comparison src/objects-msw.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | 8626e4521993 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
47 | 47 |
48 #include "buffer.h" | 48 #include "buffer.h" |
49 #include "device.h" | 49 #include "device.h" |
50 #include "insdel.h" | 50 #include "insdel.h" |
51 | 51 |
52 #ifdef __CYGWIN32__ | 52 #if (defined(__CYGWIN32__) || defined(__MINGW32__)) && \ |
53 CYGWIN_VERSION_DLL_MAJOR < 21 | |
53 #define stricmp strcasecmp | 54 #define stricmp strcasecmp |
54 #define FONTENUMPROC FONTENUMEXPROC | 55 #define FONTENUMPROC FONTENUMEXPROC |
55 #define ntmTm ntmentm | 56 #define ntmTm ntmentm |
56 #endif | 57 #endif |
57 | 58 |
58 typedef struct colormap_t | 59 typedef struct colormap_t |
59 { | 60 { |
60 CONST char *name; | 61 const char *name; |
61 CONST COLORREF colorref; | 62 const COLORREF colorref; |
62 } colormap_t; | 63 } colormap_t; |
63 | 64 |
64 /* Colors from X11R6 "XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp" */ | 65 /* Colors from X11R6 "XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp" */ |
65 static CONST colormap_t mswindows_X_color_map[] = | 66 static const colormap_t mswindows_X_color_map[] = |
66 { | 67 { |
67 {"snow" , PALETTERGB (255, 250, 250) }, | 68 {"snow" , PALETTERGB (255, 250, 250) }, |
68 {"GhostWhite" , PALETTERGB (248, 248, 255) }, | 69 {"GhostWhite" , PALETTERGB (248, 248, 255) }, |
69 {"WhiteSmoke" , PALETTERGB (245, 245, 245) }, | 70 {"WhiteSmoke" , PALETTERGB (245, 245, 245) }, |
70 {"gainsboro" , PALETTERGB (220, 220, 220) }, | 71 {"gainsboro" , PALETTERGB (220, 220, 220) }, |
724 }; | 725 }; |
725 | 726 |
726 | 727 |
727 typedef struct fontmap_t | 728 typedef struct fontmap_t |
728 { | 729 { |
729 CONST char *name; | 730 const char *name; |
730 CONST int value; | 731 const int value; |
731 } fontmap_t; | 732 } fontmap_t; |
732 | 733 |
733 /* Default weight first, preferred names listed before synonyms */ | 734 /* Default weight first, preferred names listed before synonyms */ |
734 static CONST fontmap_t fontweight_map[] = | 735 static const fontmap_t fontweight_map[] = |
735 { | 736 { |
736 {"Regular" , FW_REGULAR}, /* The standard font weight */ | 737 {"Regular" , FW_REGULAR}, /* The standard font weight */ |
737 {"Thin" , FW_THIN}, | 738 {"Thin" , FW_THIN}, |
738 {"Extra Light" , FW_EXTRALIGHT}, | 739 {"Extra Light" , FW_EXTRALIGHT}, |
739 {"Ultra Light" , FW_ULTRALIGHT}, | 740 {"Ultra Light" , FW_ULTRALIGHT}, |
749 {"Black" , FW_BLACK} | 750 {"Black" , FW_BLACK} |
750 }; | 751 }; |
751 | 752 |
752 /* Default charset first, no synonyms allowed because these names are | 753 /* Default charset first, no synonyms allowed because these names are |
753 * matched against the names reported by win32 by match_font() */ | 754 * matched against the names reported by win32 by match_font() */ |
754 static CONST fontmap_t charset_map[] = | 755 static const fontmap_t charset_map[] = |
755 { | 756 { |
756 {"Western" , ANSI_CHARSET}, | 757 {"Western" , ANSI_CHARSET}, |
757 {"Symbol" , SYMBOL_CHARSET}, | 758 {"Symbol" , SYMBOL_CHARSET}, |
758 {"Shift JIS" , SHIFTJIS_CHARSET}, /* #### Name to be verified */ | 759 {"Shift JIS" , SHIFTJIS_CHARSET}, /* #### Name to be verified */ |
759 {"GB2312" , GB2312_CHARSET}, /* #### Name to be verified */ | 760 {"GB2312" , GB2312_CHARSET}, /* #### Name to be verified */ |
791 else | 792 else |
792 return c-'0'; | 793 return c-'0'; |
793 } | 794 } |
794 | 795 |
795 COLORREF | 796 COLORREF |
796 mswindows_string_to_color(CONST char *name) | 797 mswindows_string_to_color(const char *name) |
797 { | 798 { |
798 int i; | 799 int i; |
799 | 800 |
800 if (*name == '#') | 801 if (*name == '#') |
801 { | 802 { |
935 /************************************************************************/ | 936 /************************************************************************/ |
936 | 937 |
937 struct font_enum_t | 938 struct font_enum_t |
938 { | 939 { |
939 HDC hdc; | 940 HDC hdc; |
940 struct device *d; | 941 Lisp_Object list; |
941 }; | 942 }; |
942 | 943 |
943 static int CALLBACK | 944 static int CALLBACK |
944 font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, | 945 font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, |
945 int FontType, struct font_enum_t *font_enum) | 946 int FontType, struct font_enum_t *font_enum) |
946 { | 947 { |
947 struct mswindows_font_enum *fontlist, **fonthead; | |
948 char fontname[MSW_FONTSIZE]; | 948 char fontname[MSW_FONTSIZE]; |
949 Lisp_Object fontname_lispstr; | |
949 int i; | 950 int i; |
950 | 951 |
951 /* | 952 /* |
952 * The enumerated font weights are not to be trusted because: | 953 * The enumerated font weights are not to be trusted because: |
953 * a) lpelfe->elfStyle is only filled in for TrueType fonts. | 954 * a) lpelfe->elfStyle is only filled in for TrueType fonts. |
964 sprintf (fontname, "%s::::", lpelfe->elfLogFont.lfFaceName); | 965 sprintf (fontname, "%s::::", lpelfe->elfLogFont.lfFaceName); |
965 else | 966 else |
966 /* Formula for pointsize->height from LOGFONT docs in Platform SDK */ | 967 /* Formula for pointsize->height from LOGFONT docs in Platform SDK */ |
967 sprintf (fontname, "%s::%d::", lpelfe->elfLogFont.lfFaceName, | 968 sprintf (fontname, "%s::%d::", lpelfe->elfLogFont.lfFaceName, |
968 MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading, | 969 MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading, |
969 72, DEVICE_MSWINDOWS_LOGPIXELSY (font_enum->d))); | 970 72, GetDeviceCaps (font_enum->hdc, LOGPIXELSY))); |
970 | 971 |
971 /* | 972 /* |
972 * The enumerated font character set strings are not to be trusted because | 973 * The enumerated font character set strings are not to be trusted because |
973 * lpelfe->elfScript is returned in the host language and not in English. | 974 * lpelfe->elfScript is returned in the host language and not in English. |
974 * We can't know a priori the translations of "Western", "Central European" | 975 * We can't know a priori the translations of "Western", "Central European" |
982 break; | 983 break; |
983 } | 984 } |
984 if (i==countof (charset_map)) | 985 if (i==countof (charset_map)) |
985 strcpy (fontname, charset_map[0].name); | 986 strcpy (fontname, charset_map[0].name); |
986 | 987 |
987 /* Check that the new font is not a duplicate */ | 988 /* Add the font name to the list if not already there */ |
988 fonthead = &DEVICE_MSWINDOWS_FONTLIST (font_enum->d); | 989 fontname_lispstr = build_string (fontname); |
989 fontlist = *fonthead; | 990 if (NILP (memq_no_quit (fontname_lispstr, font_enum->list))) |
990 while (fontlist) | 991 font_enum->list = Fcons (fontname_lispstr, font_enum->list); |
991 if (!strcmp (fontname, fontlist->fontname)) | 992 |
992 return 1; /* found a duplicate */ | |
993 else | |
994 fontlist = fontlist->next; | |
995 | |
996 /* Insert entry at head */ | |
997 fontlist = *fonthead; | |
998 *fonthead = xmalloc (sizeof (struct mswindows_font_enum)); | |
999 if (*fonthead == NULL) | |
1000 { | |
1001 *fonthead = fontlist; | |
1002 return 0; | |
1003 } | |
1004 strcpy ((*fonthead)->fontname, fontname); | |
1005 (*fonthead)->next = fontlist; | |
1006 return 1; | 993 return 1; |
1007 } | 994 } |
1008 | 995 |
1009 static int CALLBACK | 996 static int CALLBACK |
1010 font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, | 997 font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, |
1016 (FONTENUMPROC) font_enum_callback_2, | 1003 (FONTENUMPROC) font_enum_callback_2, |
1017 (LPARAM) font_enum, 0); | 1004 (LPARAM) font_enum, 0); |
1018 } | 1005 } |
1019 | 1006 |
1020 /* | 1007 /* |
1021 * Enumerate the available fonts. Called by mswindows_init_device(). | 1008 * Enumerate the available on the HDC fonts and return a list of string |
1022 * Fills in the device's device-type-specfic fontlist. | 1009 * font names. |
1023 */ | 1010 */ |
1024 void | 1011 Lisp_Object |
1025 mswindows_enumerate_fonts (struct device *d) | 1012 mswindows_enumerate_fonts (HDC hdc) |
1026 { | 1013 { |
1027 HDC hdc = CreateCompatibleDC (NULL); | 1014 /* This cannot CG */ |
1028 LOGFONT logfont; | 1015 LOGFONT logfont; |
1029 struct font_enum_t font_enum; | 1016 struct font_enum_t font_enum; |
1030 | 1017 |
1031 assert (hdc!=NULL); | 1018 assert (hdc!=NULL); |
1032 logfont.lfCharSet = DEFAULT_CHARSET; | 1019 logfont.lfCharSet = DEFAULT_CHARSET; |
1033 logfont.lfFaceName[0] = '\0'; | 1020 logfont.lfFaceName[0] = '\0'; |
1034 logfont.lfPitchAndFamily = DEFAULT_PITCH; | 1021 logfont.lfPitchAndFamily = DEFAULT_PITCH; |
1035 font_enum.hdc = hdc; | 1022 font_enum.hdc = hdc; |
1036 font_enum.d = d; | 1023 font_enum.list = Qnil; |
1037 DEVICE_MSWINDOWS_FONTLIST (d) = NULL; | |
1038 EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1, | 1024 EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1, |
1039 (LPARAM) (&font_enum), 0); | 1025 (LPARAM) (&font_enum), 0); |
1040 DeleteDC (hdc); | 1026 return font_enum.list; |
1041 } | 1027 } |
1042 | 1028 |
1029 static HFONT | |
1030 mswindows_create_font_variant (Lisp_Font_Instance* f, | |
1031 int under, int strike) | |
1032 { | |
1033 /* Cannot GC */ | |
1034 | |
1035 LOGFONT lf; | |
1036 HFONT hfont; | |
1037 | |
1038 assert (FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, under, strike) == NULL); | |
1039 | |
1040 if (GetObject (FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, 0, 0), | |
1041 sizeof (lf), (void*) &lf) == 0) | |
1042 { | |
1043 hfont = MSWINDOWS_BAD_HFONT; | |
1044 } | |
1045 else | |
1046 { | |
1047 lf.lfUnderline = under; | |
1048 lf.lfStrikeOut = strike; | |
1049 | |
1050 hfont = CreateFontIndirect (&lf); | |
1051 if (hfont == NULL) | |
1052 hfont = MSWINDOWS_BAD_HFONT; | |
1053 } | |
1054 | |
1055 FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, under, strike) = hfont; | |
1056 return hfont; | |
1057 } | |
1058 | |
1059 HFONT | |
1060 mswindows_get_hfont (Lisp_Font_Instance* f, | |
1061 int under, int strike) | |
1062 { | |
1063 /* Cannot GC */ | |
1064 HFONT hfont = FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, under, strike); | |
1065 | |
1066 if (hfont == NULL) | |
1067 hfont = mswindows_create_font_variant (f, under, strike); | |
1068 | |
1069 /* If strikeout/underline variant of the font could not be | |
1070 created, then use the base version of the font */ | |
1071 if (hfont == MSWINDOWS_BAD_HFONT) | |
1072 hfont = FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, 0, 0); | |
1073 | |
1074 assert (hfont != NULL && hfont != MSWINDOWS_BAD_HFONT); | |
1075 | |
1076 return hfont; | |
1077 } | |
1043 | 1078 |
1044 /************************************************************************/ | 1079 /************************************************************************/ |
1045 /* methods */ | 1080 /* methods */ |
1046 /************************************************************************/ | 1081 /************************************************************************/ |
1047 | 1082 |
1048 static int | 1083 static int |
1049 mswindows_initialize_color_instance (struct Lisp_Color_Instance *c, Lisp_Object name, | 1084 mswindows_initialize_color_instance (Lisp_Color_Instance *c, Lisp_Object name, |
1050 Lisp_Object device, Error_behavior errb) | 1085 Lisp_Object device, Error_behavior errb) |
1051 { | 1086 { |
1052 CONST char *extname; | 1087 const char *extname; |
1053 COLORREF color; | 1088 COLORREF color; |
1054 | 1089 |
1055 GET_C_STRING_CTEXT_DATA_ALLOCA (name, extname); | 1090 TO_EXTERNAL_FORMAT (LISP_STRING, name, |
1091 C_STRING_ALLOCA, extname, | |
1092 Qctext); | |
1056 color = mswindows_string_to_color(extname); | 1093 color = mswindows_string_to_color(extname); |
1057 if (color != -1) | 1094 if (color != -1) |
1058 { | 1095 { |
1059 c->data = xnew (struct mswindows_color_instance_data); | 1096 c->data = xnew (struct mswindows_color_instance_data); |
1060 COLOR_INSTANCE_MSWINDOWS_COLOR (c) = color; | 1097 COLOR_INSTANCE_MSWINDOWS_COLOR (c) = color; |
1064 return(0); | 1101 return(0); |
1065 } | 1102 } |
1066 | 1103 |
1067 #if 0 | 1104 #if 0 |
1068 static void | 1105 static void |
1069 mswindows_mark_color_instance (struct Lisp_Color_Instance *c, | 1106 mswindows_mark_color_instance (Lisp_Color_Instance *c) |
1070 void (*markobj) (Lisp_Object)) | |
1071 { | 1107 { |
1072 } | 1108 } |
1073 #endif | 1109 #endif |
1074 | 1110 |
1075 static void | 1111 static void |
1076 mswindows_print_color_instance (struct Lisp_Color_Instance *c, | 1112 mswindows_print_color_instance (Lisp_Color_Instance *c, |
1077 Lisp_Object printcharfun, | 1113 Lisp_Object printcharfun, |
1078 int escapeflag) | 1114 int escapeflag) |
1079 { | 1115 { |
1080 char buf[32]; | 1116 char buf[32]; |
1081 COLORREF color = COLOR_INSTANCE_MSWINDOWS_COLOR (c); | 1117 COLORREF color = COLOR_INSTANCE_MSWINDOWS_COLOR (c); |
1082 sprintf (buf, " %06ld=(%04X,%04X,%04X)", color & 0xffffff, | 1118 sprintf (buf, " %06ld=(%04X,%04X,%04X)", color & 0xffffff, |
1083 GetRValue(color)*257, GetGValue(color)*257, GetBValue(color)*257); | 1119 GetRValue(color)*257, GetGValue(color)*257, GetBValue(color)*257); |
1084 write_c_string (buf, printcharfun); | 1120 write_c_string (buf, printcharfun); |
1085 } | 1121 } |
1086 | 1122 |
1087 static void | 1123 static void |
1088 mswindows_finalize_color_instance (struct Lisp_Color_Instance *c) | 1124 mswindows_finalize_color_instance (Lisp_Color_Instance *c) |
1089 { | 1125 { |
1090 if (c->data) | 1126 if (c->data) |
1091 { | 1127 { |
1092 xfree (c->data); | 1128 xfree (c->data); |
1093 c->data = 0; | 1129 c->data = 0; |
1094 } | 1130 } |
1095 } | 1131 } |
1096 | 1132 |
1097 static int | 1133 static int |
1098 mswindows_color_instance_equal (struct Lisp_Color_Instance *c1, | 1134 mswindows_color_instance_equal (Lisp_Color_Instance *c1, |
1099 struct Lisp_Color_Instance *c2, | 1135 Lisp_Color_Instance *c2, |
1100 int depth) | 1136 int depth) |
1101 { | 1137 { |
1102 return (COLOR_INSTANCE_MSWINDOWS_COLOR(c1) == COLOR_INSTANCE_MSWINDOWS_COLOR(c2)); | 1138 return (COLOR_INSTANCE_MSWINDOWS_COLOR(c1) == COLOR_INSTANCE_MSWINDOWS_COLOR(c2)); |
1103 } | 1139 } |
1104 | 1140 |
1105 static unsigned long | 1141 static unsigned long |
1106 mswindows_color_instance_hash (struct Lisp_Color_Instance *c, int depth) | 1142 mswindows_color_instance_hash (Lisp_Color_Instance *c, int depth) |
1107 { | 1143 { |
1108 return (unsigned long)(COLOR_INSTANCE_MSWINDOWS_COLOR(c)); | 1144 return (unsigned long) COLOR_INSTANCE_MSWINDOWS_COLOR(c); |
1109 } | 1145 } |
1110 | 1146 |
1111 static Lisp_Object | 1147 static Lisp_Object |
1112 mswindows_color_instance_rgb_components (struct Lisp_Color_Instance *c) | 1148 mswindows_color_instance_rgb_components (Lisp_Color_Instance *c) |
1113 { | 1149 { |
1114 COLORREF color = COLOR_INSTANCE_MSWINDOWS_COLOR (c); | 1150 COLORREF color = COLOR_INSTANCE_MSWINDOWS_COLOR (c); |
1115 return list3 (make_int (GetRValue (color) * 257), | 1151 return list3 (make_int (GetRValue (color) * 257), |
1116 make_int (GetGValue (color) * 257), | 1152 make_int (GetGValue (color) * 257), |
1117 make_int (GetBValue (color) * 257)); | 1153 make_int (GetBValue (color) * 257)); |
1118 } | 1154 } |
1119 | 1155 |
1120 static int | 1156 static int |
1121 mswindows_valid_color_name_p (struct device *d, Lisp_Object color) | 1157 mswindows_valid_color_name_p (struct device *d, Lisp_Object color) |
1122 { | 1158 { |
1123 CONST char *extname; | 1159 const char *extname; |
1124 | 1160 |
1125 GET_C_STRING_CTEXT_DATA_ALLOCA (color, extname); | 1161 TO_EXTERNAL_FORMAT (LISP_STRING, color, |
1162 C_STRING_ALLOCA, extname, | |
1163 Qctext); | |
1126 return (mswindows_string_to_color(extname)!=-1); | 1164 return (mswindows_string_to_color(extname)!=-1); |
1127 } | 1165 } |
1128 | 1166 |
1129 | 1167 |
1130 | 1168 |
1131 static void | 1169 static void |
1132 mswindows_finalize_font_instance (struct Lisp_Font_Instance *f) | 1170 mswindows_finalize_font_instance (Lisp_Font_Instance *f); |
1133 { | 1171 |
1134 if (f->data) | 1172 /* |
1135 { | 1173 * This is a work horse for both mswindows_initialize_font_instanc and |
1136 DeleteObject(f->data); | 1174 * msprinter_initialize_font_instance. |
1137 f->data=0; | 1175 */ |
1138 } | |
1139 } | |
1140 | |
1141 | |
1142 static int | 1176 static int |
1143 mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name, | 1177 initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name, |
1144 Lisp_Object device, Error_behavior errb) | 1178 Lisp_Object device_font_list, HDC hdc, |
1145 { | 1179 Error_behavior errb) |
1146 CONST char *extname; | 1180 { |
1181 const char *extname; | |
1147 LOGFONT logfont; | 1182 LOGFONT logfont; |
1148 int fields, i; | 1183 int fields, i; |
1149 int pt; | 1184 int pt; |
1150 char fontname[LF_FACESIZE], weight[LF_FACESIZE], *style, points[8]; | 1185 char fontname[LF_FACESIZE], weight[LF_FACESIZE], *style, points[8]; |
1151 char effects[LF_FACESIZE], charset[LF_FACESIZE]; | 1186 char effects[LF_FACESIZE], charset[LF_FACESIZE]; |
1152 char *c; | 1187 char *c; |
1153 HDC hdc; | 1188 HFONT hfont, hfont2; |
1154 HFONT holdfont; | |
1155 TEXTMETRIC metrics; | 1189 TEXTMETRIC metrics; |
1156 | 1190 |
1157 extname = XSTRING_DATA (name); | 1191 extname = XSTRING_DATA (name); |
1158 | 1192 |
1159 /* | 1193 /* |
1253 maybe_signal_simple_error ("Invalid font pointsize", name, Qfont, errb); | 1287 maybe_signal_simple_error ("Invalid font pointsize", name, Qfont, errb); |
1254 return (0); | 1288 return (0); |
1255 } | 1289 } |
1256 | 1290 |
1257 /* Formula for pointsize->height from LOGFONT docs in MSVC5 Platform SDK */ | 1291 /* Formula for pointsize->height from LOGFONT docs in MSVC5 Platform SDK */ |
1258 logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY (XDEVICE (device)), 72); | 1292 logfont.lfHeight = -MulDiv(pt, GetDeviceCaps (hdc, LOGPIXELSY), 72); |
1259 logfont.lfWidth = 0; | 1293 logfont.lfWidth = 0; |
1260 | 1294 |
1261 /* Effects */ | 1295 /* Effects */ |
1262 logfont.lfUnderline = FALSE; | 1296 logfont.lfUnderline = FALSE; |
1263 logfont.lfStrikeOut = FALSE; | 1297 logfont.lfStrikeOut = FALSE; |
1351 logfont.lfQuality = PROOF_QUALITY; | 1385 logfont.lfQuality = PROOF_QUALITY; |
1352 #endif | 1386 #endif |
1353 /* Default to monospaced if the specified fontname doesn't exist. */ | 1387 /* Default to monospaced if the specified fontname doesn't exist. */ |
1354 logfont.lfPitchAndFamily = FF_MODERN; | 1388 logfont.lfPitchAndFamily = FF_MODERN; |
1355 | 1389 |
1356 /* Windows will silently substitute a default font if the fontname | 1390 /* Windows will silently substitute a default font if the fontname specifies |
1357 * specifies a non-existent font. So we check the font against the device's | 1391 a non-existent font. This is bad for screen fonts because it doesn't |
1358 * list of font patterns to make sure that at least one of them matches. */ | 1392 allow higher-level code to see the error and to act appropriately. |
1359 { | 1393 For instance complex_vars_of_faces() sets up a fallback list of fonts |
1360 struct mswindows_font_enum *fontlist; | 1394 for the default face. */ |
1361 char truename[MSW_FONTSIZE]; | 1395 |
1362 int done = 0; | 1396 if (!NILP (device_font_list)) |
1363 | 1397 { |
1364 sprintf (truename, "%s:%s:%d:%s:%s", fontname, weight, pt, effects, charset); | 1398 Lisp_Object fonttail; |
1365 fontlist = DEVICE_MSWINDOWS_FONTLIST (XDEVICE (device)); | 1399 char truename[MSW_FONTSIZE]; |
1366 while (fontlist && !done) | 1400 |
1367 { | 1401 sprintf (truename, "%s:%s:%d:%s:%s", fontname, weight, pt, effects, charset); |
1368 done = match_font (fontlist->fontname, truename, NULL); | 1402 LIST_LOOP (fonttail, device_font_list) |
1369 fontlist = fontlist->next; | 1403 { |
1370 } | 1404 if (match_font (XSTRING_DATA (XCAR (fonttail)), truename, NULL)) |
1371 if (!done) | 1405 break; |
1372 { | 1406 } |
1373 maybe_signal_simple_error ("No matching font", name, Qfont, errb); | 1407 if (NILP (fonttail)) |
1374 return 0; | 1408 { |
1375 } | 1409 maybe_signal_simple_error ("No matching font", name, Qfont, errb); |
1376 } | 1410 return 0; |
1377 | 1411 } |
1378 if ((f->data = CreateFontIndirect(&logfont)) == NULL) | 1412 } |
1413 | |
1414 if ((hfont = CreateFontIndirect(&logfont)) == NULL) | |
1379 { | 1415 { |
1380 maybe_signal_simple_error ("Couldn't create font", name, Qfont, errb); | 1416 maybe_signal_simple_error ("Couldn't create font", name, Qfont, errb); |
1381 return 0; | 1417 return 0; |
1382 } | 1418 } |
1383 | 1419 |
1384 hdc = CreateCompatibleDC (NULL); | 1420 f->data = xnew_and_zero (struct mswindows_font_instance_data); |
1385 if (hdc) | 1421 FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f,0,0) = hfont; |
1386 { | 1422 |
1387 holdfont = SelectObject(hdc, f->data); | 1423 /* Some underlined fonts have the descent of one pixel more than their |
1388 if (holdfont) | 1424 non-underlined counterparts. Font variants though are assumed to have |
1425 identical metrics. So get the font metrics from the underlined variant | |
1426 of the font */ | |
1427 hfont2 = mswindows_create_font_variant (f, 1, 0); | |
1428 if (hfont2 != MSWINDOWS_BAD_HFONT) | |
1429 hfont = hfont2; | |
1430 | |
1431 hfont2 = SelectObject(hdc, hfont); | |
1432 if (!hfont2) | |
1433 { | |
1434 mswindows_finalize_font_instance (f); | |
1435 maybe_signal_simple_error ("Couldn't map font", name, Qfont, errb); | |
1436 return 0; | |
1437 } | |
1438 GetTextMetrics (hdc, &metrics); | |
1439 SelectObject(hdc, hfont2); | |
1440 | |
1441 f->width = (unsigned short) metrics.tmAveCharWidth; | |
1442 f->height = (unsigned short) metrics.tmHeight; | |
1443 f->ascent = (unsigned short) metrics.tmAscent; | |
1444 f->descent = (unsigned short) metrics.tmDescent; | |
1445 f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH); | |
1446 | |
1447 return 1; | |
1448 } | |
1449 | |
1450 static int | |
1451 mswindows_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name, | |
1452 Lisp_Object device, Error_behavior errb) | |
1453 { | |
1454 HDC hdc = CreateCompatibleDC (NULL); | |
1455 Lisp_Object font_list = DEVICE_MSWINDOWS_FONTLIST (XDEVICE (device)); | |
1456 int res = initialize_font_instance (f, name, font_list, hdc, errb); | |
1457 DeleteDC (hdc); | |
1458 return res; | |
1459 } | |
1460 | |
1461 static int | |
1462 msprinter_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name, | |
1463 Lisp_Object device, Error_behavior errb) | |
1464 { | |
1465 HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (device)); | |
1466 Lisp_Object font_list = DEVICE_MSPRINTER_FONTLIST (XDEVICE (device)); | |
1467 return initialize_font_instance (f, name, font_list, hdc, errb); | |
1468 } | |
1469 | |
1470 static void | |
1471 mswindows_finalize_font_instance (Lisp_Font_Instance *f) | |
1472 { | |
1473 int i; | |
1474 | |
1475 if (f->data) | |
1476 { | |
1477 for (i = 0; i < MSWINDOWS_NUM_FONT_VARIANTS; i++) | |
1389 { | 1478 { |
1390 GetTextMetrics (hdc, &metrics); | 1479 if (FONT_INSTANCE_MSWINDOWS_HFONT_I (f, i) != NULL |
1391 SelectObject(hdc, holdfont); | 1480 && FONT_INSTANCE_MSWINDOWS_HFONT_I (f, i) != MSWINDOWS_BAD_HFONT) |
1392 DeleteDC (hdc); | 1481 DeleteObject (FONT_INSTANCE_MSWINDOWS_HFONT_I (f, i)); |
1393 f->width = (unsigned short) metrics.tmAveCharWidth; | |
1394 f->height = (unsigned short) metrics.tmHeight; | |
1395 f->ascent = (unsigned short) metrics.tmAscent; | |
1396 f->descent = (unsigned short) metrics.tmDescent; | |
1397 f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH); | |
1398 return 1; | |
1399 } | 1482 } |
1400 DeleteDC (hdc); | 1483 |
1401 } | 1484 xfree (f->data); |
1402 mswindows_finalize_font_instance (f); | 1485 f->data = 0; |
1403 maybe_signal_simple_error ("Couldn't map font", name, Qfont, errb); | 1486 } |
1404 return 0; | |
1405 } | 1487 } |
1406 | 1488 |
1407 #if 0 | 1489 #if 0 |
1408 static void | 1490 static void |
1409 mswindows_mark_font_instance (struct Lisp_Font_Instance *f, | 1491 mswindows_mark_font_instance (Lisp_Font_Instance *f) |
1410 void (*markobj) (Lisp_Object)) | |
1411 { | 1492 { |
1412 } | 1493 } |
1413 #endif | 1494 #endif |
1414 | 1495 |
1415 static void | 1496 static void |
1416 mswindows_print_font_instance (struct Lisp_Font_Instance *f, | 1497 mswindows_print_font_instance (Lisp_Font_Instance *f, |
1417 Lisp_Object printcharfun, | 1498 Lisp_Object printcharfun, |
1418 int escapeflag) | 1499 int escapeflag) |
1419 { | 1500 { |
1501 char buf[10]; | |
1502 sprintf (buf, " 0x%lx", | |
1503 (unsigned long)FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f,0,0)); | |
1504 write_c_string (buf, printcharfun); | |
1420 } | 1505 } |
1421 | 1506 |
1422 static Lisp_Object | 1507 static Lisp_Object |
1423 mswindows_list_fonts (Lisp_Object pattern, Lisp_Object device) | 1508 mswindows_list_fonts (Lisp_Object pattern, Lisp_Object device) |
1424 { | 1509 { |
1425 Lisp_Object result = Qnil; | 1510 Lisp_Object fonttail, result = Qnil; |
1426 struct mswindows_font_enum *fontlist; | 1511 char *extpattern; |
1427 char fontname[MSW_FONTSIZE], *extpattern; | 1512 |
1428 | 1513 TO_EXTERNAL_FORMAT (LISP_STRING, pattern, |
1429 GET_C_STRING_CTEXT_DATA_ALLOCA (pattern, extpattern); | 1514 C_STRING_ALLOCA, extpattern, |
1430 fontlist = DEVICE_MSWINDOWS_FONTLIST (XDEVICE (device)); | 1515 Qctext); |
1431 while (fontlist) | 1516 |
1432 { | 1517 LIST_LOOP (fonttail, DEVICE_MSWINDOWS_FONTLIST (XDEVICE (device))) |
1433 if (match_font (fontlist->fontname, extpattern, fontname)) | 1518 { |
1434 result = Fcons (build_string (fontname), result); | 1519 if (match_font (XSTRING_DATA (XCAR (fonttail)), extpattern, NULL)) |
1435 fontlist = fontlist->next; | 1520 result = Fcons (XCAR (fonttail), result); |
1436 } | 1521 } |
1437 | 1522 |
1438 return Fnreverse (result); | 1523 return Fnreverse (result); |
1524 } | |
1525 | |
1526 /* Fill in missing parts of a font spec. This is primarily intended as a | |
1527 * helper function for the functions below. | |
1528 * mswindows fonts look like: | |
1529 * fontname[:[weight][ style][:pointsize[:effects]]][:charset] | |
1530 * A minimal mswindows font spec looks like: | |
1531 * Courier New | |
1532 * A maximal mswindows font spec looks like: | |
1533 * Courier New:Bold Italic:10:underline strikeout:Western | |
1534 * Missing parts of the font spec should be filled in with these values: | |
1535 * Courier New:Regular:10::Western */ | |
1536 static Lisp_Object | |
1537 mswindows_font_instance_truename (Lisp_Font_Instance *f, Error_behavior errb) | |
1538 { | |
1539 int nsep=0; | |
1540 char *name = (char *) XSTRING_DATA (f->name); | |
1541 char* ptr = name; | |
1542 char* extname = alloca (strlen (name) + 19); | |
1543 strcpy (extname, name); | |
1544 | |
1545 while ((ptr = strchr (ptr, ':')) != 0) | |
1546 { | |
1547 ptr++; | |
1548 nsep++; | |
1549 } | |
1550 | |
1551 switch (nsep) | |
1552 { | |
1553 case 0: | |
1554 strcat (extname, ":Regular:10::Western"); | |
1555 break; | |
1556 case 1: | |
1557 strcat (extname, ":10::Western"); | |
1558 break; | |
1559 case 2: | |
1560 strcat (extname, "::Western"); | |
1561 break; | |
1562 case 3: | |
1563 strcat (extname, ":Western"); | |
1564 break; | |
1565 default:; | |
1566 } | |
1567 | |
1568 return build_ext_string (extname, Qnative); | |
1439 } | 1569 } |
1440 | 1570 |
1441 #ifdef MULE | 1571 #ifdef MULE |
1442 | 1572 |
1443 static int | 1573 static int |
1444 mswindows_font_spec_matches_charset (struct device *d, Lisp_Object charset, | 1574 mswindows_font_spec_matches_charset (struct device *d, Lisp_Object charset, |
1445 CONST Bufbyte *nonreloc, Lisp_Object reloc, | 1575 const Bufbyte *nonreloc, Lisp_Object reloc, |
1446 Bytecount offset, Bytecount length) | 1576 Bytecount offset, Bytecount length) |
1447 { | 1577 { |
1448 /* #### Implement me */ | 1578 /* #### Implement me */ |
1449 if (UNBOUNDP (charset)) | 1579 if (UNBOUNDP (charset)) |
1450 return 1; | 1580 return 1; |
1510 | 1640 |
1511 CONSOLE_HAS_METHOD (mswindows, initialize_font_instance); | 1641 CONSOLE_HAS_METHOD (mswindows, initialize_font_instance); |
1512 /* CONSOLE_HAS_METHOD (mswindows, mark_font_instance); */ | 1642 /* CONSOLE_HAS_METHOD (mswindows, mark_font_instance); */ |
1513 CONSOLE_HAS_METHOD (mswindows, print_font_instance); | 1643 CONSOLE_HAS_METHOD (mswindows, print_font_instance); |
1514 CONSOLE_HAS_METHOD (mswindows, finalize_font_instance); | 1644 CONSOLE_HAS_METHOD (mswindows, finalize_font_instance); |
1515 /* CONSOLE_HAS_METHOD (mswindows, font_instance_truename); */ | 1645 CONSOLE_HAS_METHOD (mswindows, font_instance_truename); |
1516 CONSOLE_HAS_METHOD (mswindows, list_fonts); | 1646 CONSOLE_HAS_METHOD (mswindows, list_fonts); |
1517 #ifdef MULE | 1647 #ifdef MULE |
1518 CONSOLE_HAS_METHOD (mswindows, font_spec_matches_charset); | 1648 CONSOLE_HAS_METHOD (mswindows, font_spec_matches_charset); |
1519 CONSOLE_HAS_METHOD (mswindows, find_charset_font); | 1649 CONSOLE_HAS_METHOD (mswindows, find_charset_font); |
1520 #endif | 1650 #endif |
1651 | |
1652 /* Printer methods - delegate most to windows methods, | |
1653 since graphical objects behave the same way. */ | |
1654 | |
1655 CONSOLE_INHERITS_METHOD (msprinter, mswindows, initialize_color_instance); | |
1656 /* CONSOLE_INHERITS_METHOD (msprinter, mswindows, mark_color_instance); */ | |
1657 CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_color_instance); | |
1658 CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_color_instance); | |
1659 CONSOLE_INHERITS_METHOD (msprinter, mswindows, color_instance_equal); | |
1660 CONSOLE_INHERITS_METHOD (msprinter, mswindows, color_instance_hash); | |
1661 CONSOLE_INHERITS_METHOD (msprinter, mswindows, color_instance_rgb_components); | |
1662 CONSOLE_INHERITS_METHOD (msprinter, mswindows, valid_color_name_p); | |
1663 | |
1664 CONSOLE_HAS_METHOD (msprinter, initialize_font_instance); | |
1665 /* CONSOLE_INHERITS_METHOD (msprinter, mswindows, mark_font_instance); */ | |
1666 CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_font_instance); | |
1667 CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_font_instance); | |
1668 CONSOLE_INHERITS_METHOD (msprinter, mswindows, font_instance_truename); | |
1669 CONSOLE_INHERITS_METHOD (msprinter, mswindows, list_fonts); | |
1670 #ifdef MULE | |
1671 CONSOLE_INHERITS_METHOD (msprinter, mswindows, font_spec_matches_charset); | |
1672 CONSOLE_INHERITS_METHOD (msprinter, mswindows, find_charset_font); | |
1673 #endif | |
1521 } | 1674 } |
1522 | 1675 |
1523 void | 1676 void |
1524 vars_of_objects_mswindows (void) | 1677 vars_of_objects_mswindows (void) |
1525 { | 1678 { |