Mercurial > hg > xemacs-beta
comparison src/objects-msw.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | 7347b34c275b |
children | 6240c7796c7a |
comparison
equal
deleted
inserted
replaced
370:bd866891f083 | 371:cc15677e0335 |
---|---|
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 #if defined (__CYGWIN32__) && CYGWIN_VERSION_DLL_MAJOR < 21 | 52 #ifdef __CYGWIN32__ |
53 #define stricmp strcasecmp | 53 #define stricmp strcasecmp |
54 #define FONTENUMPROC FONTENUMEXPROC | |
55 #define ntmTm ntmentm | |
56 #endif | 54 #endif |
57 | 55 |
58 typedef struct colormap_t | 56 typedef struct colormap_t |
59 { | 57 { |
60 CONST char *name; | 58 char *name; |
61 CONST COLORREF colorref; | 59 COLORREF colorref; |
62 } colormap_t; | 60 } colormap_t; |
63 | 61 |
64 /* Colors from X11R6 "XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp" */ | 62 /* 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[] = | 63 static CONST colormap_t mswindows_X_color_map[] = |
66 { | 64 { |
721 {"DarkMagenta" , PALETTERGB (139, 0, 139) }, | 719 {"DarkMagenta" , PALETTERGB (139, 0, 139) }, |
722 {"DarkRed" , PALETTERGB (139, 0, 0) }, | 720 {"DarkRed" , PALETTERGB (139, 0, 0) }, |
723 {"LightGreen" , PALETTERGB (144, 238, 144) } | 721 {"LightGreen" , PALETTERGB (144, 238, 144) } |
724 }; | 722 }; |
725 | 723 |
726 | |
727 typedef struct fontmap_t | |
728 { | |
729 CONST char *name; | |
730 CONST int value; | |
731 } fontmap_t; | |
732 | |
733 /* Default weight first, preferred names listed before synonyms */ | |
734 static CONST fontmap_t fontweight_map[] = | |
735 { | |
736 {"Regular" , FW_REGULAR}, /* The standard font weight */ | |
737 {"Thin" , FW_THIN}, | |
738 {"Extra Light" , FW_EXTRALIGHT}, | |
739 {"Ultra Light" , FW_ULTRALIGHT}, | |
740 {"Light" , FW_LIGHT}, | |
741 {"Normal" , FW_NORMAL}, | |
742 {"Medium" , FW_MEDIUM}, | |
743 {"Semi Bold" , FW_SEMIBOLD}, | |
744 {"Demi Bold" , FW_DEMIBOLD}, | |
745 {"Bold" , FW_BOLD}, /* The standard bold font weight */ | |
746 {"Extra Bold" , FW_EXTRABOLD}, | |
747 {"Ultra Bold" , FW_ULTRABOLD}, | |
748 {"Heavy" , FW_HEAVY}, | |
749 {"Black" , FW_BLACK} | |
750 }; | |
751 | |
752 /* Default charset first, no synonyms allowed because these names are | |
753 * matched against the names reported by win32 by match_font() */ | |
754 static CONST fontmap_t charset_map[] = | |
755 { | |
756 {"Western" , ANSI_CHARSET}, | |
757 {"Symbol" , SYMBOL_CHARSET}, | |
758 {"Shift JIS" , SHIFTJIS_CHARSET}, /* #### Name to be verified */ | |
759 {"GB2312" , GB2312_CHARSET}, /* #### Name to be verified */ | |
760 {"Hanguel" , HANGEUL_CHARSET}, | |
761 {"Chinese Big 5" , CHINESEBIG5_CHARSET}, /* #### Name to be verified */ | |
762 #if (WINVER >= 0x0400) | |
763 {"Johab" , JOHAB_CHARSET}, /* #### Name to be verified */ | |
764 {"Hebrew" , HEBREW_CHARSET}, /* #### Name to be verified */ | |
765 {"Arabic" , ARABIC_CHARSET}, /* #### Name to be verified */ | |
766 {"Greek" , GREEK_CHARSET}, | |
767 {"Turkish" , TURKISH_CHARSET}, | |
768 {"Vietnamese" , VIETNAMESE_CHARSET}, /* #### Name to be verified */ | |
769 {"Thai" , THAI_CHARSET}, /* #### Name to be verified */ | |
770 {"Central European" , EASTEUROPE_CHARSET}, | |
771 {"Cyrillic" , RUSSIAN_CHARSET}, | |
772 {"Mac" , MAC_CHARSET}, | |
773 {"Baltic" , BALTIC_CHARSET}, | |
774 #endif | |
775 {"OEM/DOS" , OEM_CHARSET} | |
776 }; | |
777 | |
778 | 724 |
779 /************************************************************************/ | 725 /************************************************************************/ |
780 /* helpers */ | 726 /* helpers */ |
781 /************************************************************************/ | 727 /************************************************************************/ |
782 | 728 |
924 if (fontname) | 870 if (fontname) |
925 fontname[strlen (fontname) - 1] = '\0'; /* Trim trailing ':' */ | 871 fontname[strlen (fontname) - 1] = '\0'; /* Trim trailing ':' */ |
926 return 1; | 872 return 1; |
927 } | 873 } |
928 | 874 |
929 | |
930 | |
931 | |
932 | |
933 /************************************************************************/ | |
934 /* exports */ | |
935 /************************************************************************/ | |
936 | |
937 struct font_enum_t | |
938 { | |
939 HDC hdc; | |
940 struct device *d; | |
941 }; | |
942 | |
943 static int CALLBACK | |
944 font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, | |
945 int FontType, struct font_enum_t *font_enum) | |
946 { | |
947 struct mswindows_font_enum *fontlist, **fonthead; | |
948 char fontname[MSW_FONTSIZE]; | |
949 int i; | |
950 | |
951 /* | |
952 * The enumerated font weights are not to be trusted because: | |
953 * a) lpelfe->elfStyle is only filled in for TrueType fonts. | |
954 * b) Not all Bold and Italic styles of all fonts (inluding some Vector, | |
955 * Truetype and Raster fonts) are enumerated. | |
956 * I guess that fonts for which Bold and Italic styles are generated | |
957 * 'on-the-fly' are not enumerated. It would be overly restrictive to | |
958 * disallow Bold And Italic weights for these fonts, so we just leave | |
959 * weights unspecified. This means that we have to weed out duplicates of | |
960 * those fonts that do get enumerated with different weights. | |
961 */ | |
962 if (FontType == 0 /*vector*/ || FontType == TRUETYPE_FONTTYPE) | |
963 /* Scalable, so leave pointsize blank */ | |
964 sprintf (fontname, "%s::::", lpelfe->elfLogFont.lfFaceName); | |
965 else | |
966 /* Formula for pointsize->height from LOGFONT docs in Platform SDK */ | |
967 sprintf (fontname, "%s::%d::", lpelfe->elfLogFont.lfFaceName, | |
968 MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading, | |
969 72, DEVICE_MSWINDOWS_LOGPIXELSY (font_enum->d))); | |
970 | |
971 /* | |
972 * 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 * We can't know a priori the translations of "Western", "Central European" | |
975 * etc into the host language, so we must use English. The same argument | |
976 * applies to the font weight string when matching fonts. | |
977 */ | |
978 for (i=0; i<countof (charset_map); i++) | |
979 if (lpelfe->elfLogFont.lfCharSet == charset_map[i].value) | |
980 { | |
981 strcat (fontname, charset_map[i].name); | |
982 break; | |
983 } | |
984 if (i==countof (charset_map)) | |
985 strcpy (fontname, charset_map[0].name); | |
986 | |
987 /* Check that the new font is not a duplicate */ | |
988 fonthead = &DEVICE_MSWINDOWS_FONTLIST (font_enum->d); | |
989 fontlist = *fonthead; | |
990 while (fontlist) | |
991 if (!strcmp (fontname, fontlist->fontname)) | |
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; | |
1007 } | |
1008 | |
1009 static int CALLBACK | |
1010 font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, | |
1011 int FontType, struct font_enum_t *font_enum) | |
1012 { | |
1013 /* This function gets called once per facename per character set. | |
1014 * We call a second callback to enumerate the fonts in each facename */ | |
1015 return EnumFontFamiliesEx (font_enum->hdc, &lpelfe->elfLogFont, | |
1016 (FONTENUMPROC) font_enum_callback_2, | |
1017 (LPARAM) font_enum, 0); | |
1018 } | |
1019 | |
1020 /* | |
1021 * Enumerate the available fonts. Called by mswindows_init_device(). | |
1022 * Fills in the device's device-type-specfic fontlist. | |
1023 */ | |
1024 void | |
1025 mswindows_enumerate_fonts (struct device *d) | |
1026 { | |
1027 HDC hdc = CreateCompatibleDC (NULL); | |
1028 LOGFONT logfont; | |
1029 struct font_enum_t font_enum; | |
1030 | |
1031 assert (hdc!=NULL); | |
1032 logfont.lfCharSet = DEFAULT_CHARSET; | |
1033 logfont.lfFaceName[0] = '\0'; | |
1034 logfont.lfPitchAndFamily = DEFAULT_PITCH; | |
1035 font_enum.hdc = hdc; | |
1036 font_enum.d = d; | |
1037 DEVICE_MSWINDOWS_FONTLIST (d) = NULL; | |
1038 EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1, | |
1039 (LPARAM) (&font_enum), 0); | |
1040 DeleteDC (hdc); | |
1041 } | |
1042 | |
1043 | 875 |
1044 /************************************************************************/ | 876 /************************************************************************/ |
1045 /* methods */ | 877 /* methods */ |
1046 /************************************************************************/ | 878 /************************************************************************/ |
1047 | 879 |
1136 DeleteObject(f->data); | 968 DeleteObject(f->data); |
1137 f->data=0; | 969 f->data=0; |
1138 } | 970 } |
1139 } | 971 } |
1140 | 972 |
1141 | |
1142 static int | 973 static int |
1143 mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name, | 974 mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name, |
1144 Lisp_Object device, Error_behavior errb) | 975 Lisp_Object device, Error_behavior errb) |
1145 { | 976 { |
1146 CONST char *extname; | 977 CONST char *extname; |
1147 LOGFONT logfont; | 978 LOGFONT logfont; |
1148 int fields, i; | 979 int fields; |
1149 int pt; | 980 int pt; |
1150 char fontname[LF_FACESIZE], weight[LF_FACESIZE], *style, points[8]; | 981 char fontname[LF_FACESIZE], weight[LF_FACESIZE], *style, points[8]; |
1151 char effects[LF_FACESIZE], charset[LF_FACESIZE]; | 982 char effects[LF_FACESIZE], charset[LF_FACESIZE]; |
1152 char *c; | 983 char *c; |
1153 HDC hdc; | 984 |
1154 HFONT holdfont; | 985 GET_C_STRING_CTEXT_DATA_ALLOCA (f->name, extname); |
1155 TEXTMETRIC metrics; | |
1156 | |
1157 extname = XSTRING_DATA (name); | |
1158 | 986 |
1159 /* | 987 /* |
1160 * mswindows fonts look like: | 988 * mswindows fonts look like: |
1161 * fontname[:[weight ][style][:pointsize[:effects]]][:charset] | 989 * fontname[:[weight ][style][:pointsize[:effects]]][:charset] |
1162 * The font name field shouldn't be empty. | 990 * The font name field shouldn't be empty. |
1173 fontname, weight, points, effects, charset); | 1001 fontname, weight, points, effects, charset); |
1174 | 1002 |
1175 /* This function is implemented in a fairly ad-hoc manner. | 1003 /* This function is implemented in a fairly ad-hoc manner. |
1176 * The general idea is to validate and canonicalize each of the above fields | 1004 * The general idea is to validate and canonicalize each of the above fields |
1177 * at the same time as we build up the win32 LOGFONT structure. This enables | 1005 * at the same time as we build up the win32 LOGFONT structure. This enables |
1178 * us to use match_font() on a canonicalized font string to check the | 1006 * us to use math_font() on a canonicalized font string to check the |
1179 * availability of the requested font */ | 1007 * availability of the requested font */ |
1180 | 1008 |
1181 if (fields < 0) | 1009 if (fields<0) |
1182 { | 1010 { |
1183 maybe_signal_simple_error ("Invalid font", name, Qfont, errb); | 1011 maybe_signal_simple_error ("Invalid font", f->name, Qfont, errb); |
1184 return (0); | 1012 return (0); |
1185 } | 1013 } |
1186 | 1014 |
1187 if (fields>0 && strlen(fontname)) | 1015 if (fields>0 && strlen(fontname)) |
1188 { | 1016 { |
1189 strncpy (logfont.lfFaceName, fontname, LF_FACESIZE); | 1017 strncpy (logfont.lfFaceName, fontname, LF_FACESIZE); |
1190 logfont.lfFaceName[LF_FACESIZE-1] = 0; | 1018 logfont.lfFaceName[LF_FACESIZE-1] = 0; |
1191 } | 1019 } |
1192 else | 1020 else |
1193 { | 1021 { |
1194 maybe_signal_simple_error ("Must specify a font name", name, Qfont, errb); | 1022 maybe_signal_simple_error ("Must specify a font name", f->name, Qfont, errb); |
1195 return (0); | 1023 return (0); |
1196 } | 1024 } |
1197 | 1025 |
1198 /* weight */ | 1026 /* weight */ |
1199 if (fields < 2) | 1027 if (fields < 2) |
1200 strcpy (weight, fontweight_map[0].name); | 1028 strcpy (weight, "Regular"); |
1201 | 1029 |
1202 /* Maybe split weight into weight and style */ | 1030 /* Maybe split weight into weight and style */ |
1203 if ((c=strchr(weight, ' '))) | 1031 if ((c=strchr(weight, ' '))) |
1204 { | 1032 { |
1205 *c = '\0'; | 1033 *c = '\0'; |
1206 style = c+1; | 1034 style = c+1; |
1207 } | 1035 } |
1208 else | 1036 else |
1209 style = NULL; | 1037 style = NULL; |
1210 | 1038 |
1211 for (i=0; i<countof (fontweight_map); i++) | 1039 #define FROB(wgt) \ |
1212 if (!stricmp (weight, fontweight_map[i].name)) | 1040 if (stricmp (weight, #wgt) == 0) \ |
1213 { | 1041 logfont.lfWeight = FW_##wgt |
1214 logfont.lfWeight = fontweight_map[i].value; | 1042 |
1215 break; | 1043 FROB (REGULAR); |
1216 } | 1044 else FROB (THIN); |
1217 if (i == countof (fontweight_map)) /* No matching weight */ | 1045 else FROB (EXTRALIGHT); |
1218 { | 1046 else FROB (ULTRALIGHT); |
1219 if (!style) | 1047 else FROB (LIGHT); |
1220 { | 1048 else FROB (NORMAL); |
1221 logfont.lfWeight = FW_REGULAR; | 1049 else FROB (MEDIUM); |
1222 style = weight; /* May have specified style without weight */ | 1050 else FROB (SEMIBOLD); |
1223 } | 1051 else FROB (DEMIBOLD); |
1224 else | 1052 else FROB (BOLD); |
1225 { | 1053 else FROB (EXTRABOLD); |
1226 maybe_signal_simple_error ("Invalid font weight", name, Qfont, errb); | 1054 else FROB (ULTRABOLD); |
1227 return (0); | 1055 else FROB (HEAVY); |
1228 } | 1056 else FROB (BLACK); |
1229 } | 1057 else if (!style) |
1058 { | |
1059 logfont.lfWeight = FW_REGULAR; | |
1060 style = weight; /* May have specified style without weight */ | |
1061 } | |
1062 else | |
1063 { | |
1064 maybe_signal_simple_error ("Invalid font weight", f->name, Qfont, errb); | |
1065 return (0); | |
1066 } | |
1067 | |
1068 #undef FROB | |
1230 | 1069 |
1231 if (style) | 1070 if (style) |
1232 { | 1071 { |
1233 /* #### what about oblique? */ | 1072 /* #### what about oblique? */ |
1234 if (stricmp (style,"italic") == 0) | 1073 if (stricmp (style,"italic") == 0) |
1235 logfont.lfItalic = TRUE; | 1074 logfont.lfItalic = TRUE; |
1236 else | 1075 else |
1237 { | 1076 { |
1238 maybe_signal_simple_error ("Invalid font weight or style", name, Qfont, errb); | 1077 maybe_signal_simple_error ("Invalid font weight or style", f->name, Qfont, errb); |
1239 return (0); | 1078 return (0); |
1240 } | 1079 } |
1241 | 1080 |
1242 /* Glue weight and style together again */ | 1081 /* Glue weight and style together again */ |
1243 if (weight != style) | 1082 if (weight != style) |
1248 | 1087 |
1249 if (fields < 3) | 1088 if (fields < 3) |
1250 pt = 10; /* #### Should we reject strings that don't specify a size? */ | 1089 pt = 10; /* #### Should we reject strings that don't specify a size? */ |
1251 else if ((pt=atoi(points)) == 0) | 1090 else if ((pt=atoi(points)) == 0) |
1252 { | 1091 { |
1253 maybe_signal_simple_error ("Invalid font pointsize", name, Qfont, errb); | 1092 maybe_signal_simple_error ("Invalid font pointsize", f->name, Qfont, errb); |
1254 return (0); | 1093 return (0); |
1255 } | 1094 } |
1256 | 1095 |
1257 /* Formula for pointsize->height from LOGFONT docs in MSVC5 Platform SDK */ | 1096 /* Formula for pointsize->height from LOGFONT docs in MSVC5 Platform SDK */ |
1258 logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY (XDEVICE (device)), 72); | 1097 logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY(XDEVICE (device)), 72); |
1259 logfont.lfWidth = 0; | 1098 logfont.lfWidth = 0; |
1260 | 1099 |
1261 /* Effects */ | 1100 /* Effects */ |
1262 logfont.lfUnderline = FALSE; | 1101 logfont.lfUnderline = FALSE; |
1263 logfont.lfStrikeOut = FALSE; | 1102 logfont.lfStrikeOut = FALSE; |
1278 logfont.lfUnderline = TRUE; | 1117 logfont.lfUnderline = TRUE; |
1279 else if (stricmp (effects, "strikeout") == 0) | 1118 else if (stricmp (effects, "strikeout") == 0) |
1280 logfont.lfStrikeOut = TRUE; | 1119 logfont.lfStrikeOut = TRUE; |
1281 else | 1120 else |
1282 { | 1121 { |
1283 maybe_signal_simple_error ("Invalid font effect", name, Qfont, errb); | 1122 maybe_signal_simple_error ("Invalid font effect", f->name, |
1123 Qfont, errb); | |
1284 return (0); | 1124 return (0); |
1285 } | 1125 } |
1286 | 1126 |
1287 if (effects2 && effects2[0] != '\0') | 1127 if (effects2 && effects2[0] != '\0') |
1288 { | 1128 { |
1290 logfont.lfUnderline = TRUE; | 1130 logfont.lfUnderline = TRUE; |
1291 else if (stricmp (effects2, "strikeout") == 0) | 1131 else if (stricmp (effects2, "strikeout") == 0) |
1292 logfont.lfStrikeOut = TRUE; | 1132 logfont.lfStrikeOut = TRUE; |
1293 else | 1133 else |
1294 { | 1134 { |
1295 maybe_signal_simple_error ("Invalid font effect", name, | 1135 maybe_signal_simple_error ("Invalid font effect", f->name, |
1296 Qfont, errb); | 1136 Qfont, errb); |
1297 return (0); | 1137 return (0); |
1298 } | 1138 } |
1299 } | 1139 } |
1300 | 1140 |
1310 strcpy (effects, "strikeout"); | 1150 strcpy (effects, "strikeout"); |
1311 } | 1151 } |
1312 else | 1152 else |
1313 effects[0] = '\0'; | 1153 effects[0] = '\0'; |
1314 | 1154 |
1315 /* Charset */ | 1155 #define FROB(cs) \ |
1156 else if (stricmp (charset, #cs) == 0) \ | |
1157 logfont.lfCharSet = cs##_CHARSET | |
1158 | |
1159 /* Charset aliases. Hangeul = Hangul is defined in windows.h. | |
1160 We do not use the name "russian", only "cyrillic", as it is | |
1161 the common name of this charset, used in other languages | |
1162 than Russian. */ | |
1163 #define CYRILLIC_CHARSET RUSSIAN_CHARSET | |
1164 #define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET | |
1165 #define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET | |
1166 | |
1316 /* charset can be specified even if earlier fields havn't been */ | 1167 /* charset can be specified even if earlier fields havn't been */ |
1317 if (fields < 5) | 1168 if ((fields < 5) && (c=strchr (extname, ':')) && (c=strchr (c+1, ':')) && |
1318 { | 1169 (c=strchr (c+1, ':')) && (c=strchr (c+1, ':'))) |
1319 if ((c=strchr (extname, ':')) && (c=strchr (c+1, ':')) && | 1170 { |
1320 (c=strchr (c+1, ':')) && (c=strchr (c+1, ':'))) | 1171 strncpy (charset, c+1, LF_FACESIZE); |
1321 { | 1172 charset[LF_FACESIZE-1] = '\0'; |
1322 strncpy (charset, c+1, LF_FACESIZE); | 1173 } |
1323 charset[LF_FACESIZE-1] = '\0'; | 1174 else |
1324 } | 1175 charset[0] = '\0'; |
1325 else | 1176 |
1326 strcpy (charset, charset_map[0].name); | 1177 if (charset[0] == '\0' || (stricmp (charset, "ansi") == 0) || |
1327 } | 1178 (stricmp (charset, "western") == 0)) |
1328 | 1179 { |
1329 for (i=0; i<countof (charset_map); i++) | 1180 logfont.lfCharSet = ANSI_CHARSET; |
1330 if (!stricmp (charset, charset_map[i].name)) | 1181 strcpy (charset, "western"); |
1331 { | 1182 } |
1332 logfont.lfCharSet = charset_map[i].value; | 1183 FROB (SYMBOL); |
1333 break; | 1184 FROB (SHIFTJIS); |
1334 } | 1185 FROB (GB2312); |
1335 | 1186 FROB (HANGEUL); |
1336 if (i == countof (charset_map)) /* No matching charset */ | 1187 FROB (CHINESEBIG5); |
1337 { | 1188 FROB (JOHAB); |
1338 maybe_signal_simple_error ("Invalid charset", name, Qfont, errb); | 1189 FROB (HEBREW); |
1190 FROB (ARABIC); | |
1191 FROB (GREEK); | |
1192 FROB (TURKISH); | |
1193 FROB (THAI); | |
1194 FROB (EASTEUROPE); | |
1195 FROB (CENTRALEUROPEAN); | |
1196 FROB (CYRILLIC); | |
1197 FROB (MAC); | |
1198 FROB (BALTIC); | |
1199 else if (stricmp (charset, "oem/dos") == 0) | |
1200 logfont.lfCharSet = OEM_CHARSET; | |
1201 else | |
1202 { | |
1203 maybe_signal_simple_error ("Invalid charset", f->name, Qfont, errb); | |
1339 return 0; | 1204 return 0; |
1340 } | 1205 } |
1341 | 1206 |
1342 /* Misc crud */ | 1207 #undef FROB |
1343 logfont.lfEscapement = logfont.lfOrientation = 0; | |
1344 #if 1 | |
1345 logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; | |
1346 logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; | |
1347 logfont.lfQuality = DEFAULT_QUALITY; | |
1348 #else | |
1349 logfont.lfOutPrecision = OUT_STROKE_PRECIS; | |
1350 logfont.lfClipPrecision = CLIP_STROKE_PRECIS; | |
1351 logfont.lfQuality = PROOF_QUALITY; | |
1352 #endif | |
1353 /* Default to monospaced if the specified fontname doesn't exist. */ | |
1354 logfont.lfPitchAndFamily = FF_MODERN; | |
1355 | 1208 |
1356 /* Windows will silently substitute a default font if the fontname | 1209 /* Windows will silently substitute a default font if the fontname |
1357 * specifies a non-existent font. So we check the font against the device's | 1210 * specifies a non-existent font. So we check the font against the device's |
1358 * list of font patterns to make sure that at least one of them matches. */ | 1211 * list of font patterns to make sure that at least one of them matches */ |
1359 { | 1212 { |
1360 struct mswindows_font_enum *fontlist; | 1213 struct mswindows_font_enum *fontlist; |
1361 char truename[MSW_FONTSIZE]; | 1214 char truename[MSW_FONTSIZE]; |
1362 int done = 0; | 1215 int done = 0; |
1363 | 1216 |
1368 done = match_font (fontlist->fontname, truename, NULL); | 1221 done = match_font (fontlist->fontname, truename, NULL); |
1369 fontlist = fontlist->next; | 1222 fontlist = fontlist->next; |
1370 } | 1223 } |
1371 if (!done) | 1224 if (!done) |
1372 { | 1225 { |
1373 maybe_signal_simple_error ("No matching font", name, Qfont, errb); | 1226 maybe_signal_simple_error ("No matching font", f->name, Qfont, errb); |
1374 return 0; | 1227 return 0; |
1375 } | 1228 } |
1376 } | 1229 } |
1377 | 1230 |
1231 /* Misc crud */ | |
1232 logfont.lfEscapement = logfont.lfOrientation = 0; | |
1233 #if 1 | |
1234 logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; | |
1235 logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; | |
1236 logfont.lfQuality = DEFAULT_QUALITY; | |
1237 #else | |
1238 logfont.lfOutPrecision = OUT_STROKE_PRECIS; | |
1239 logfont.lfClipPrecision = CLIP_STROKE_PRECIS; | |
1240 logfont.lfQuality = PROOF_QUALITY; | |
1241 #endif | |
1242 /* Default to monospaced if the specified fontname doesn't exist. | |
1243 * The match_font calls above should mean that this can't happen. */ | |
1244 logfont.lfPitchAndFamily = FF_MODERN; | |
1245 | |
1378 if ((f->data = CreateFontIndirect(&logfont)) == NULL) | 1246 if ((f->data = CreateFontIndirect(&logfont)) == NULL) |
1379 { | 1247 { |
1380 maybe_signal_simple_error ("Couldn't create font", name, Qfont, errb); | 1248 maybe_signal_simple_error ("Couldn't create font", f->name, Qfont, errb); |
1381 return 0; | 1249 return 0; |
1382 } | 1250 } |
1383 | 1251 |
1384 hdc = CreateCompatibleDC (NULL); | 1252 { |
1385 if (hdc) | 1253 HDC hdc; |
1386 { | 1254 HFONT holdfont; |
1387 holdfont = SelectObject(hdc, f->data); | 1255 TEXTMETRIC metrics; |
1388 if (holdfont) | 1256 |
1389 { | 1257 hdc = CreateCompatibleDC (NULL); |
1390 GetTextMetrics (hdc, &metrics); | 1258 if (hdc) |
1391 SelectObject(hdc, holdfont); | 1259 { |
1392 DeleteDC (hdc); | 1260 holdfont = SelectObject(hdc, f->data); |
1393 f->width = (unsigned short) metrics.tmAveCharWidth; | 1261 if (holdfont) |
1394 f->height = (unsigned short) metrics.tmHeight; | 1262 { |
1395 f->ascent = (unsigned short) metrics.tmAscent; | 1263 GetTextMetrics (hdc, &metrics); |
1396 f->descent = (unsigned short) metrics.tmDescent; | 1264 SelectObject(hdc, holdfont); |
1397 f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH); | 1265 DeleteDC (hdc); |
1398 return 1; | 1266 f->width = (unsigned short) metrics.tmAveCharWidth; |
1399 } | 1267 f->height = (unsigned short) metrics.tmHeight; |
1400 DeleteDC (hdc); | 1268 f->ascent = (unsigned short) metrics.tmAscent; |
1401 } | 1269 f->descent = (unsigned short) metrics.tmDescent; |
1402 mswindows_finalize_font_instance (f); | 1270 f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH); |
1403 maybe_signal_simple_error ("Couldn't map font", name, Qfont, errb); | 1271 return 1; |
1272 } | |
1273 DeleteDC (hdc); | |
1274 } | |
1275 mswindows_finalize_font_instance (f); | |
1276 maybe_signal_simple_error ("Couldn't map font", f->name, Qfont, errb); | |
1277 } | |
1404 return 0; | 1278 return 0; |
1405 } | 1279 } |
1406 | 1280 |
1407 #if 0 | 1281 #if 0 |
1408 static void | 1282 static void |
1462 return build_string ("Courier New:Regular:10"); | 1336 return build_string ("Courier New:Regular:10"); |
1463 } | 1337 } |
1464 | 1338 |
1465 #endif /* MULE */ | 1339 #endif /* MULE */ |
1466 | 1340 |
1467 DEFUN ("mswindows-shell-execute", Fmswindows_shell_execute, 2, 4, 0, /* | |
1468 Get Windows to perform OPERATION on DOCUMENT. | |
1469 This is a wrapper around the ShellExecute system function, which | |
1470 invokes the application registered to handle OPERATION for DOCUMENT. | |
1471 OPERATION is typically \"open\", \"print\" or \"explore\" (but can be | |
1472 nil for the default action), and DOCUMENT is typically the name of a | |
1473 document file or URL, but can also be a program executable to run or | |
1474 a directory to open in the Windows Explorer. | |
1475 | |
1476 If DOCUMENT is a program executable, PARAMETERS can be a string | |
1477 containing command line parameters, but otherwise should be nil. | |
1478 | |
1479 SHOW-FLAG can be used to control whether the invoked application is hidden | |
1480 or minimized. If SHOW-FLAG is nil, the application is displayed normally, | |
1481 otherwise it is an integer representing a ShowWindow flag: | |
1482 | |
1483 0 - start hidden | |
1484 1 - start normally | |
1485 3 - start maximized | |
1486 6 - start minimized | |
1487 */ | |
1488 (operation, document, parameters, show_flag)) | |
1489 { | |
1490 /* Encode filename and current directory. */ | |
1491 Lisp_Object current_dir = Ffile_name_directory (document); | |
1492 char* path = NULL; | |
1493 char* doc = NULL; | |
1494 Extbyte* f=0; | |
1495 int ret; | |
1496 struct gcpro gcpro1, gcpro2; | |
1497 | |
1498 CHECK_STRING (document); | |
1499 | |
1500 if (NILP (current_dir)) | |
1501 current_dir = current_buffer->directory; | |
1502 | |
1503 GCPRO2 (current_dir, document); | |
1504 | |
1505 /* Use mule and cygwin-safe APIs top get at file data. */ | |
1506 if (STRINGP (current_dir)) | |
1507 { | |
1508 GET_C_STRING_FILENAME_DATA_ALLOCA (current_dir, f); | |
1509 #ifdef __CYGWIN32__ | |
1510 CYGWIN_WIN32_PATH (f, path); | |
1511 #else | |
1512 path = f; | |
1513 #endif | |
1514 } | |
1515 | |
1516 if (STRINGP (document)) | |
1517 { | |
1518 GET_C_STRING_FILENAME_DATA_ALLOCA (document, f); | |
1519 #ifdef __CYGWIN32__ | |
1520 CYGWIN_WIN32_PATH (f, doc); | |
1521 #else | |
1522 doc = f; | |
1523 #endif | |
1524 } | |
1525 | |
1526 UNGCPRO; | |
1527 | |
1528 ret = (int) ShellExecute (NULL, | |
1529 (STRINGP (operation) ? | |
1530 XSTRING_DATA (operation) : NULL), | |
1531 doc, | |
1532 (STRINGP (parameters) ? | |
1533 XSTRING_DATA (parameters) : NULL), | |
1534 path, | |
1535 (INTP (show_flag) ? | |
1536 XINT (show_flag) : SW_SHOWDEFAULT)); | |
1537 | |
1538 if (ret > 32) | |
1539 return Qt; | |
1540 | |
1541 if (ret == ERROR_FILE_NOT_FOUND) | |
1542 signal_simple_error ("file not found", document); | |
1543 else if (ret == ERROR_PATH_NOT_FOUND) | |
1544 signal_simple_error ("path not found", current_dir); | |
1545 else if (ret == ERROR_BAD_FORMAT) | |
1546 signal_simple_error ("bad executable format", document); | |
1547 else | |
1548 error ("internal error"); | |
1549 | |
1550 return Qnil; | |
1551 } | |
1552 | |
1553 | 1341 |
1554 /************************************************************************/ | 1342 /************************************************************************/ |
1555 /* non-methods */ | 1343 /* non-methods */ |
1556 /************************************************************************/ | 1344 /************************************************************************/ |
1557 | 1345 |
1577 | 1365 |
1578 void | 1366 void |
1579 syms_of_objects_mswindows (void) | 1367 syms_of_objects_mswindows (void) |
1580 { | 1368 { |
1581 DEFSUBR (Fmswindows_color_list); | 1369 DEFSUBR (Fmswindows_color_list); |
1582 DEFSUBR (Fmswindows_shell_execute); | |
1583 } | 1370 } |
1584 | 1371 |
1585 void | 1372 void |
1586 console_type_create_objects_mswindows (void) | 1373 console_type_create_objects_mswindows (void) |
1587 { | 1374 { |