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 {