Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/src/objects-msw.c Mon Aug 13 11:01:58 2007 +0200 +++ b/src/objects-msw.c Mon Aug 13 11:03:08 2007 +0200 @@ -49,16 +49,14 @@ #include "device.h" #include "insdel.h" -#if defined (__CYGWIN32__) && CYGWIN_VERSION_DLL_MAJOR < 21 +#ifdef __CYGWIN32__ #define stricmp strcasecmp -#define FONTENUMPROC FONTENUMEXPROC -#define ntmTm ntmentm #endif typedef struct colormap_t { - CONST char *name; - CONST COLORREF colorref; + char *name; + COLORREF colorref; } colormap_t; /* Colors from X11R6 "XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp" */ @@ -723,58 +721,6 @@ {"LightGreen" , PALETTERGB (144, 238, 144) } }; - -typedef struct fontmap_t -{ - CONST char *name; - CONST int value; -} fontmap_t; - -/* Default weight first, preferred names listed before synonyms */ -static CONST fontmap_t fontweight_map[] = -{ - {"Regular" , FW_REGULAR}, /* The standard font weight */ - {"Thin" , FW_THIN}, - {"Extra Light" , FW_EXTRALIGHT}, - {"Ultra Light" , FW_ULTRALIGHT}, - {"Light" , FW_LIGHT}, - {"Normal" , FW_NORMAL}, - {"Medium" , FW_MEDIUM}, - {"Semi Bold" , FW_SEMIBOLD}, - {"Demi Bold" , FW_DEMIBOLD}, - {"Bold" , FW_BOLD}, /* The standard bold font weight */ - {"Extra Bold" , FW_EXTRABOLD}, - {"Ultra Bold" , FW_ULTRABOLD}, - {"Heavy" , FW_HEAVY}, - {"Black" , FW_BLACK} -}; - -/* Default charset first, no synonyms allowed because these names are - * matched against the names reported by win32 by match_font() */ -static CONST fontmap_t charset_map[] = -{ - {"Western" , ANSI_CHARSET}, - {"Symbol" , SYMBOL_CHARSET}, - {"Shift JIS" , SHIFTJIS_CHARSET}, /* #### Name to be verified */ - {"GB2312" , GB2312_CHARSET}, /* #### Name to be verified */ - {"Hanguel" , HANGEUL_CHARSET}, - {"Chinese Big 5" , CHINESEBIG5_CHARSET}, /* #### Name to be verified */ -#if (WINVER >= 0x0400) - {"Johab" , JOHAB_CHARSET}, /* #### Name to be verified */ - {"Hebrew" , HEBREW_CHARSET}, /* #### Name to be verified */ - {"Arabic" , ARABIC_CHARSET}, /* #### Name to be verified */ - {"Greek" , GREEK_CHARSET}, - {"Turkish" , TURKISH_CHARSET}, - {"Vietnamese" , VIETNAMESE_CHARSET}, /* #### Name to be verified */ - {"Thai" , THAI_CHARSET}, /* #### Name to be verified */ - {"Central European" , EASTEUROPE_CHARSET}, - {"Cyrillic" , RUSSIAN_CHARSET}, - {"Mac" , MAC_CHARSET}, - {"Baltic" , BALTIC_CHARSET}, -#endif - {"OEM/DOS" , OEM_CHARSET} -}; - /************************************************************************/ /* helpers */ @@ -926,120 +872,6 @@ return 1; } - - - - -/************************************************************************/ -/* exports */ -/************************************************************************/ - -struct font_enum_t -{ - HDC hdc; - struct device *d; -}; - -static int CALLBACK -font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, - int FontType, struct font_enum_t *font_enum) -{ - struct mswindows_font_enum *fontlist, **fonthead; - char fontname[MSW_FONTSIZE]; - int i; - - /* - * The enumerated font weights are not to be trusted because: - * a) lpelfe->elfStyle is only filled in for TrueType fonts. - * b) Not all Bold and Italic styles of all fonts (inluding some Vector, - * Truetype and Raster fonts) are enumerated. - * I guess that fonts for which Bold and Italic styles are generated - * 'on-the-fly' are not enumerated. It would be overly restrictive to - * disallow Bold And Italic weights for these fonts, so we just leave - * weights unspecified. This means that we have to weed out duplicates of - * those fonts that do get enumerated with different weights. - */ - if (FontType == 0 /*vector*/ || FontType == TRUETYPE_FONTTYPE) - /* Scalable, so leave pointsize blank */ - sprintf (fontname, "%s::::", lpelfe->elfLogFont.lfFaceName); - else - /* Formula for pointsize->height from LOGFONT docs in Platform SDK */ - sprintf (fontname, "%s::%d::", lpelfe->elfLogFont.lfFaceName, - MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading, - 72, DEVICE_MSWINDOWS_LOGPIXELSY (font_enum->d))); - - /* - * The enumerated font character set strings are not to be trusted because - * lpelfe->elfScript is returned in the host language and not in English. - * We can't know a priori the translations of "Western", "Central European" - * etc into the host language, so we must use English. The same argument - * applies to the font weight string when matching fonts. - */ - for (i=0; i<countof (charset_map); i++) - if (lpelfe->elfLogFont.lfCharSet == charset_map[i].value) - { - strcat (fontname, charset_map[i].name); - break; - } - if (i==countof (charset_map)) - strcpy (fontname, charset_map[0].name); - - /* Check that the new font is not a duplicate */ - fonthead = &DEVICE_MSWINDOWS_FONTLIST (font_enum->d); - fontlist = *fonthead; - while (fontlist) - if (!strcmp (fontname, fontlist->fontname)) - return 1; /* found a duplicate */ - else - fontlist = fontlist->next; - - /* Insert entry at head */ - fontlist = *fonthead; - *fonthead = xmalloc (sizeof (struct mswindows_font_enum)); - if (*fonthead == NULL) - { - *fonthead = fontlist; - return 0; - } - strcpy ((*fonthead)->fontname, fontname); - (*fonthead)->next = fontlist; - return 1; -} - -static int CALLBACK -font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, - int FontType, struct font_enum_t *font_enum) -{ - /* This function gets called once per facename per character set. - * We call a second callback to enumerate the fonts in each facename */ - return EnumFontFamiliesEx (font_enum->hdc, &lpelfe->elfLogFont, - (FONTENUMPROC) font_enum_callback_2, - (LPARAM) font_enum, 0); -} - -/* - * Enumerate the available fonts. Called by mswindows_init_device(). - * Fills in the device's device-type-specfic fontlist. - */ -void -mswindows_enumerate_fonts (struct device *d) -{ - HDC hdc = CreateCompatibleDC (NULL); - LOGFONT logfont; - struct font_enum_t font_enum; - - assert (hdc!=NULL); - logfont.lfCharSet = DEFAULT_CHARSET; - logfont.lfFaceName[0] = '\0'; - logfont.lfPitchAndFamily = DEFAULT_PITCH; - font_enum.hdc = hdc; - font_enum.d = d; - DEVICE_MSWINDOWS_FONTLIST (d) = NULL; - EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1, - (LPARAM) (&font_enum), 0); - DeleteDC (hdc); -} - /************************************************************************/ /* methods */ @@ -1138,23 +970,19 @@ } } - static int mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name, Lisp_Object device, Error_behavior errb) { CONST char *extname; LOGFONT logfont; - int fields, i; + int fields; int pt; char fontname[LF_FACESIZE], weight[LF_FACESIZE], *style, points[8]; char effects[LF_FACESIZE], charset[LF_FACESIZE]; char *c; - HDC hdc; - HFONT holdfont; - TEXTMETRIC metrics; - - extname = XSTRING_DATA (name); + + GET_C_STRING_CTEXT_DATA_ALLOCA (f->name, extname); /* * mswindows fonts look like: @@ -1175,12 +1003,12 @@ /* This function is implemented in a fairly ad-hoc manner. * The general idea is to validate and canonicalize each of the above fields * at the same time as we build up the win32 LOGFONT structure. This enables - * us to use match_font() on a canonicalized font string to check the + * us to use math_font() on a canonicalized font string to check the * availability of the requested font */ - if (fields < 0) + if (fields<0) { - maybe_signal_simple_error ("Invalid font", name, Qfont, errb); + maybe_signal_simple_error ("Invalid font", f->name, Qfont, errb); return (0); } @@ -1191,13 +1019,13 @@ } else { - maybe_signal_simple_error ("Must specify a font name", name, Qfont, errb); + maybe_signal_simple_error ("Must specify a font name", f->name, Qfont, errb); return (0); } /* weight */ if (fields < 2) - strcpy (weight, fontweight_map[0].name); + strcpy (weight, "Regular"); /* Maybe split weight into weight and style */ if ((c=strchr(weight, ' '))) @@ -1208,25 +1036,36 @@ else style = NULL; - for (i=0; i<countof (fontweight_map); i++) - if (!stricmp (weight, fontweight_map[i].name)) - { - logfont.lfWeight = fontweight_map[i].value; - break; - } - if (i == countof (fontweight_map)) /* No matching weight */ +#define FROB(wgt) \ + if (stricmp (weight, #wgt) == 0) \ + logfont.lfWeight = FW_##wgt + + FROB (REGULAR); + else FROB (THIN); + else FROB (EXTRALIGHT); + else FROB (ULTRALIGHT); + else FROB (LIGHT); + else FROB (NORMAL); + else FROB (MEDIUM); + else FROB (SEMIBOLD); + else FROB (DEMIBOLD); + else FROB (BOLD); + else FROB (EXTRABOLD); + else FROB (ULTRABOLD); + else FROB (HEAVY); + else FROB (BLACK); + else if (!style) { - if (!style) - { - logfont.lfWeight = FW_REGULAR; - style = weight; /* May have specified style without weight */ - } - else - { - maybe_signal_simple_error ("Invalid font weight", name, Qfont, errb); - return (0); - } + logfont.lfWeight = FW_REGULAR; + style = weight; /* May have specified style without weight */ } + else + { + maybe_signal_simple_error ("Invalid font weight", f->name, Qfont, errb); + return (0); + } + +#undef FROB if (style) { @@ -1235,7 +1074,7 @@ logfont.lfItalic = TRUE; else { - maybe_signal_simple_error ("Invalid font weight or style", name, Qfont, errb); + maybe_signal_simple_error ("Invalid font weight or style", f->name, Qfont, errb); return (0); } @@ -1250,12 +1089,12 @@ pt = 10; /* #### Should we reject strings that don't specify a size? */ else if ((pt=atoi(points)) == 0) { - maybe_signal_simple_error ("Invalid font pointsize", name, Qfont, errb); + maybe_signal_simple_error ("Invalid font pointsize", f->name, Qfont, errb); return (0); } /* Formula for pointsize->height from LOGFONT docs in MSVC5 Platform SDK */ - logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY (XDEVICE (device)), 72); + logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY(XDEVICE (device)), 72); logfont.lfWidth = 0; /* Effects */ @@ -1280,7 +1119,8 @@ logfont.lfStrikeOut = TRUE; else { - maybe_signal_simple_error ("Invalid font effect", name, Qfont, errb); + maybe_signal_simple_error ("Invalid font effect", f->name, + Qfont, errb); return (0); } @@ -1292,7 +1132,7 @@ logfont.lfStrikeOut = TRUE; else { - maybe_signal_simple_error ("Invalid font effect", name, + maybe_signal_simple_error ("Invalid font effect", f->name, Qfont, errb); return (0); } @@ -1312,50 +1152,63 @@ else effects[0] = '\0'; - /* Charset */ +#define FROB(cs) \ + else if (stricmp (charset, #cs) == 0) \ + logfont.lfCharSet = cs##_CHARSET + + /* Charset aliases. Hangeul = Hangul is defined in windows.h. + We do not use the name "russian", only "cyrillic", as it is + the common name of this charset, used in other languages + than Russian. */ +#define CYRILLIC_CHARSET RUSSIAN_CHARSET +#define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET +#define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET + /* charset can be specified even if earlier fields havn't been */ - if (fields < 5) + if ((fields < 5) && (c=strchr (extname, ':')) && (c=strchr (c+1, ':')) && + (c=strchr (c+1, ':')) && (c=strchr (c+1, ':'))) + { + strncpy (charset, c+1, LF_FACESIZE); + charset[LF_FACESIZE-1] = '\0'; + } + else + charset[0] = '\0'; + + if (charset[0] == '\0' || (stricmp (charset, "ansi") == 0) || + (stricmp (charset, "western") == 0)) { - if ((c=strchr (extname, ':')) && (c=strchr (c+1, ':')) && - (c=strchr (c+1, ':')) && (c=strchr (c+1, ':'))) - { - strncpy (charset, c+1, LF_FACESIZE); - charset[LF_FACESIZE-1] = '\0'; - } - else - strcpy (charset, charset_map[0].name); + logfont.lfCharSet = ANSI_CHARSET; + strcpy (charset, "western"); } - - for (i=0; i<countof (charset_map); i++) - if (!stricmp (charset, charset_map[i].name)) - { - logfont.lfCharSet = charset_map[i].value; - break; - } - - if (i == countof (charset_map)) /* No matching charset */ + FROB (SYMBOL); + FROB (SHIFTJIS); + FROB (GB2312); + FROB (HANGEUL); + FROB (CHINESEBIG5); + FROB (JOHAB); + FROB (HEBREW); + FROB (ARABIC); + FROB (GREEK); + FROB (TURKISH); + FROB (THAI); + FROB (EASTEUROPE); + FROB (CENTRALEUROPEAN); + FROB (CYRILLIC); + FROB (MAC); + FROB (BALTIC); + else if (stricmp (charset, "oem/dos") == 0) + logfont.lfCharSet = OEM_CHARSET; + else { - maybe_signal_simple_error ("Invalid charset", name, Qfont, errb); + maybe_signal_simple_error ("Invalid charset", f->name, Qfont, errb); return 0; } - /* Misc crud */ - logfont.lfEscapement = logfont.lfOrientation = 0; -#if 1 - logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; - logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; - logfont.lfQuality = DEFAULT_QUALITY; -#else - logfont.lfOutPrecision = OUT_STROKE_PRECIS; - logfont.lfClipPrecision = CLIP_STROKE_PRECIS; - logfont.lfQuality = PROOF_QUALITY; -#endif - /* Default to monospaced if the specified fontname doesn't exist. */ - logfont.lfPitchAndFamily = FF_MODERN; +#undef FROB /* Windows will silently substitute a default font if the fontname * specifies a non-existent font. So we check the font against the device's - * list of font patterns to make sure that at least one of them matches. */ + * list of font patterns to make sure that at least one of them matches */ { struct mswindows_font_enum *fontlist; char truename[MSW_FONTSIZE]; @@ -1370,37 +1223,58 @@ } if (!done) { - maybe_signal_simple_error ("No matching font", name, Qfont, errb); + maybe_signal_simple_error ("No matching font", f->name, Qfont, errb); return 0; } } + /* Misc crud */ + logfont.lfEscapement = logfont.lfOrientation = 0; +#if 1 + logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; + logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logfont.lfQuality = DEFAULT_QUALITY; +#else + logfont.lfOutPrecision = OUT_STROKE_PRECIS; + logfont.lfClipPrecision = CLIP_STROKE_PRECIS; + logfont.lfQuality = PROOF_QUALITY; +#endif + /* Default to monospaced if the specified fontname doesn't exist. + * The match_font calls above should mean that this can't happen. */ + logfont.lfPitchAndFamily = FF_MODERN; + if ((f->data = CreateFontIndirect(&logfont)) == NULL) { - maybe_signal_simple_error ("Couldn't create font", name, Qfont, errb); + maybe_signal_simple_error ("Couldn't create font", f->name, Qfont, errb); return 0; } - hdc = CreateCompatibleDC (NULL); - if (hdc) - { - holdfont = SelectObject(hdc, f->data); - if (holdfont) - { - GetTextMetrics (hdc, &metrics); - SelectObject(hdc, holdfont); - DeleteDC (hdc); - f->width = (unsigned short) metrics.tmAveCharWidth; - f->height = (unsigned short) metrics.tmHeight; - f->ascent = (unsigned short) metrics.tmAscent; - f->descent = (unsigned short) metrics.tmDescent; - f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH); - return 1; - } - DeleteDC (hdc); - } - mswindows_finalize_font_instance (f); - maybe_signal_simple_error ("Couldn't map font", name, Qfont, errb); + { + HDC hdc; + HFONT holdfont; + TEXTMETRIC metrics; + + hdc = CreateCompatibleDC (NULL); + if (hdc) + { + holdfont = SelectObject(hdc, f->data); + if (holdfont) + { + GetTextMetrics (hdc, &metrics); + SelectObject(hdc, holdfont); + DeleteDC (hdc); + f->width = (unsigned short) metrics.tmAveCharWidth; + f->height = (unsigned short) metrics.tmHeight; + f->ascent = (unsigned short) metrics.tmAscent; + f->descent = (unsigned short) metrics.tmDescent; + f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH); + return 1; + } + DeleteDC (hdc); + } + mswindows_finalize_font_instance (f); + maybe_signal_simple_error ("Couldn't map font", f->name, Qfont, errb); + } return 0; } @@ -1464,92 +1338,6 @@ #endif /* MULE */ -DEFUN ("mswindows-shell-execute", Fmswindows_shell_execute, 2, 4, 0, /* -Get Windows to perform OPERATION on DOCUMENT. -This is a wrapper around the ShellExecute system function, which -invokes the application registered to handle OPERATION for DOCUMENT. -OPERATION is typically \"open\", \"print\" or \"explore\" (but can be -nil for the default action), and DOCUMENT is typically the name of a -document file or URL, but can also be a program executable to run or -a directory to open in the Windows Explorer. - -If DOCUMENT is a program executable, PARAMETERS can be a string -containing command line parameters, but otherwise should be nil. - -SHOW-FLAG can be used to control whether the invoked application is hidden -or minimized. If SHOW-FLAG is nil, the application is displayed normally, -otherwise it is an integer representing a ShowWindow flag: - - 0 - start hidden - 1 - start normally - 3 - start maximized - 6 - start minimized -*/ - (operation, document, parameters, show_flag)) -{ - /* Encode filename and current directory. */ - Lisp_Object current_dir = Ffile_name_directory (document); - char* path = NULL; - char* doc = NULL; - Extbyte* f=0; - int ret; - struct gcpro gcpro1, gcpro2; - - CHECK_STRING (document); - - if (NILP (current_dir)) - current_dir = current_buffer->directory; - - GCPRO2 (current_dir, document); - - /* Use mule and cygwin-safe APIs top get at file data. */ - if (STRINGP (current_dir)) - { - GET_C_STRING_FILENAME_DATA_ALLOCA (current_dir, f); -#ifdef __CYGWIN32__ - CYGWIN_WIN32_PATH (f, path); -#else - path = f; -#endif - } - - if (STRINGP (document)) - { - GET_C_STRING_FILENAME_DATA_ALLOCA (document, f); -#ifdef __CYGWIN32__ - CYGWIN_WIN32_PATH (f, doc); -#else - doc = f; -#endif - } - - UNGCPRO; - - ret = (int) ShellExecute (NULL, - (STRINGP (operation) ? - XSTRING_DATA (operation) : NULL), - doc, - (STRINGP (parameters) ? - XSTRING_DATA (parameters) : NULL), - path, - (INTP (show_flag) ? - XINT (show_flag) : SW_SHOWDEFAULT)); - - if (ret > 32) - return Qt; - - if (ret == ERROR_FILE_NOT_FOUND) - signal_simple_error ("file not found", document); - else if (ret == ERROR_PATH_NOT_FOUND) - signal_simple_error ("path not found", current_dir); - else if (ret == ERROR_BAD_FORMAT) - signal_simple_error ("bad executable format", document); - else - error ("internal error"); - - return Qnil; -} - /************************************************************************/ /* non-methods */ @@ -1579,7 +1367,6 @@ syms_of_objects_mswindows (void) { DEFSUBR (Fmswindows_color_list); - DEFSUBR (Fmswindows_shell_execute); } void