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 {