mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-08 04:30:45 -08:00
Fix bug #8562 with Emacs display on Windows 9X.
Thanks to oslsachem <oslsachem@gmail.com> for helping to debug this. src/w32font.c (g_b_init_is_w9x, g_b_init_get_outline_metrics_w) (g_b_init_get_text_metrics_w, g_b_init_get_glyph_outline_w) (g_b_init_get_glyph_outline_w): New static variables. (GetOutlineTextMetricsW_Proc, GetTextMetricsW_Proc) (GetGlyphOutlineW_Proc): New typedefs. (w32_load_unicows_or_gdi32, get_outline_metrics_w) (get_text_metrics_w, get_glyph_outline_w, globals_of_w32font): New functions. (w32font_open_internal, compute_metrics): Call get_outline_metrics_w, get_text_metrics_w, and get_glyph_outline_w instead of calling the "wide" APIs directly. src/emacs.c (main) [HAVE_NTGUI]: Call globals_of_w32font. src/w32.h (syms_of_w32font): Add prototype.
This commit is contained in:
parent
7a6c094174
commit
db4f02f208
4 changed files with 168 additions and 4 deletions
|
|
@ -1,3 +1,24 @@
|
|||
2011-10-28 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
Fix Emacs on Windows 9X (bug#8562). Thanks to oslsachem
|
||||
<oslsachem@gmail.com> for helping to debug this.
|
||||
|
||||
* w32font.c (g_b_init_is_w9x, g_b_init_get_outline_metrics_w)
|
||||
(g_b_init_get_text_metrics_w, g_b_init_get_glyph_outline_w)
|
||||
(g_b_init_get_glyph_outline_w): New static variables.
|
||||
(GetOutlineTextMetricsW_Proc, GetTextMetricsW_Proc)
|
||||
(GetGlyphOutlineW_Proc): New typedefs.
|
||||
(w32_load_unicows_or_gdi32, get_outline_metrics_w)
|
||||
(get_text_metrics_w, get_glyph_outline_w, globals_of_w32font): New
|
||||
functions.
|
||||
(w32font_open_internal, compute_metrics): Call
|
||||
get_outline_metrics_w, get_text_metrics_w, and get_glyph_outline_w
|
||||
instead of calling the "wide" APIs directly.
|
||||
|
||||
* emacs.c (main) [HAVE_NTGUI]: Call globals_of_w32font.
|
||||
|
||||
* w32.h (syms_of_w32font): Add prototype.
|
||||
|
||||
2011-10-27 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* window.c (Fframe_root_window, Fframe_first_window, Fwindow_end)
|
||||
|
|
|
|||
|
|
@ -1591,6 +1591,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
/* Initialization that must be done even if the global variable
|
||||
initialized is non zero. */
|
||||
#ifdef HAVE_NTGUI
|
||||
globals_of_w32font ();
|
||||
globals_of_w32fns ();
|
||||
globals_of_w32menu ();
|
||||
globals_of_w32select ();
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ extern void term_w32select (void);
|
|||
extern void syms_of_w32menu (void);
|
||||
extern void globals_of_w32menu (void);
|
||||
extern void syms_of_fontset (void);
|
||||
extern void syms_of_w32font (void);
|
||||
|
||||
extern int _sys_read_ahead (int fd);
|
||||
extern int _sys_wait_accept (int fd);
|
||||
|
|
|
|||
149
src/w32font.c
149
src/w32font.c
|
|
@ -145,6 +145,137 @@ struct font_callback_data
|
|||
style variations if the font name is not specified. */
|
||||
static void list_all_matching_fonts (struct font_callback_data *);
|
||||
|
||||
static BOOL g_b_init_is_w9x;
|
||||
static BOOL g_b_init_get_outline_metrics_w;
|
||||
static BOOL g_b_init_get_text_metrics_w;
|
||||
static BOOL g_b_init_get_glyph_outline_w;
|
||||
static BOOL g_b_init_get_glyph_outline_w;
|
||||
|
||||
typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
|
||||
HDC hdc,
|
||||
UINT cbData,
|
||||
LPOUTLINETEXTMETRICW lpotmw);
|
||||
typedef BOOL (WINAPI * GetTextMetricsW_Proc) (
|
||||
HDC hdc,
|
||||
LPTEXTMETRICW lptmw);
|
||||
typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) (
|
||||
HDC hdc,
|
||||
UINT uChar,
|
||||
UINT uFormat,
|
||||
LPGLYPHMETRICS lpgm,
|
||||
DWORD cbBuffer,
|
||||
LPVOID lpvBuffer,
|
||||
const MAT2 *lpmat2);
|
||||
|
||||
/* Several "wide" functions we use to support the font backends are
|
||||
unavailable on Windows 9X, unless UNICOWS.DLL is installed (their
|
||||
versions in the default libraries are non-functional stubs). On NT
|
||||
and later systems, these functions are in GDI32.DLL. The following
|
||||
helper function attempts to load UNICOWS.DLL on Windows 9X, and
|
||||
refuses to let Emacs start up if that library is not found. On NT
|
||||
and later versions, it simply loads GDI32.DLL, which should always
|
||||
be available. */
|
||||
static HMODULE
|
||||
w32_load_unicows_or_gdi32 (void)
|
||||
{
|
||||
static BOOL is_9x = 0;
|
||||
OSVERSIONINFO os_ver;
|
||||
HMODULE ret;
|
||||
if (g_b_init_is_w9x == 0)
|
||||
{
|
||||
g_b_init_is_w9x = 1;
|
||||
ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
|
||||
os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
|
||||
if (GetVersionEx (&os_ver))
|
||||
is_9x = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
|
||||
}
|
||||
if (is_9x)
|
||||
{
|
||||
ret = LoadLibrary ("Unicows.dll");
|
||||
if (!ret)
|
||||
{
|
||||
int button;
|
||||
|
||||
button = MessageBox (NULL,
|
||||
"Emacs cannot load the UNICOWS.DLL library.\n"
|
||||
"This library is essential for using Emacs\n"
|
||||
"on this system. You need to install it.\n\n"
|
||||
"However, you can still use Emacs by invoking\n"
|
||||
"it with the '-nw' command-line option.\n\n"
|
||||
"Emacs will exit when you click OK.",
|
||||
"Emacs cannot load UNICOWS.DLL",
|
||||
MB_ICONERROR | MB_TASKMODAL
|
||||
| MB_SETFOREGROUND | MB_OK);
|
||||
switch (button)
|
||||
{
|
||||
case IDOK:
|
||||
default:
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = LoadLibrary ("Gdi32.dll");
|
||||
}
|
||||
|
||||
/* The following 3 functions call the problematic "wide" APIs via
|
||||
function pointers, to avoid linking against the non-standard
|
||||
libunicows on W9X. */
|
||||
static UINT WINAPI
|
||||
get_outline_metrics_w(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpotmw)
|
||||
{
|
||||
static GetOutlineTextMetricsW_Proc s_pfn_Get_Outline_Text_MetricsW = NULL;
|
||||
HMODULE hm_unicows = NULL;
|
||||
if (g_b_init_get_outline_metrics_w == 0)
|
||||
{
|
||||
g_b_init_get_outline_metrics_w = 1;
|
||||
hm_unicows = w32_load_unicows_or_gdi32 ();
|
||||
if (hm_unicows)
|
||||
s_pfn_Get_Outline_Text_MetricsW = (GetOutlineTextMetricsW_Proc)
|
||||
GetProcAddress (hm_unicows, "GetOutlineTextMetricsW");
|
||||
}
|
||||
if (s_pfn_Get_Outline_Text_MetricsW == NULL)
|
||||
abort (); /* cannot happen */
|
||||
return s_pfn_Get_Outline_Text_MetricsW (hdc, cbData, lpotmw);
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
get_text_metrics_w(HDC hdc, LPTEXTMETRICW lptmw)
|
||||
{
|
||||
static GetTextMetricsW_Proc s_pfn_Get_Text_MetricsW = NULL;
|
||||
HMODULE hm_unicows = NULL;
|
||||
if (g_b_init_get_text_metrics_w == 0)
|
||||
{
|
||||
g_b_init_get_text_metrics_w = 1;
|
||||
hm_unicows = w32_load_unicows_or_gdi32 ();
|
||||
if (hm_unicows)
|
||||
s_pfn_Get_Text_MetricsW = (GetTextMetricsW_Proc)
|
||||
GetProcAddress (hm_unicows, "GetTextMetricsW");
|
||||
}
|
||||
if (s_pfn_Get_Text_MetricsW == NULL)
|
||||
abort (); /* cannot happen */
|
||||
return s_pfn_Get_Text_MetricsW (hdc, lptmw);
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
|
||||
DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2)
|
||||
{
|
||||
static GetGlyphOutlineW_Proc s_pfn_Get_Glyph_OutlineW = NULL;
|
||||
HMODULE hm_unicows = NULL;
|
||||
if (g_b_init_get_glyph_outline_w == 0)
|
||||
{
|
||||
g_b_init_get_glyph_outline_w = 1;
|
||||
hm_unicows = w32_load_unicows_or_gdi32 ();
|
||||
if (hm_unicows)
|
||||
s_pfn_Get_Glyph_OutlineW = (GetGlyphOutlineW_Proc)
|
||||
GetProcAddress (hm_unicows, "GetGlyphOutlineW");
|
||||
}
|
||||
if (s_pfn_Get_Glyph_OutlineW == NULL)
|
||||
abort (); /* cannot happen */
|
||||
return s_pfn_Get_Glyph_OutlineW (hdc, uChar, uFormat, lpgm, cbBuffer,
|
||||
lpvBuffer, lpmat2);
|
||||
}
|
||||
|
||||
static int
|
||||
memq_no_quit (Lisp_Object elt, Lisp_Object list)
|
||||
|
|
@ -816,11 +947,11 @@ w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity,
|
|||
old_font = SelectObject (dc, hfont);
|
||||
|
||||
/* Try getting the outline metrics (only works for truetype fonts). */
|
||||
len = GetOutlineTextMetricsW (dc, 0, NULL);
|
||||
len = get_outline_metrics_w (dc, 0, NULL);
|
||||
if (len)
|
||||
{
|
||||
metrics = (OUTLINETEXTMETRICW *) alloca (len);
|
||||
if (GetOutlineTextMetricsW (dc, len, metrics))
|
||||
if (get_outline_metrics_w (dc, len, metrics))
|
||||
memcpy (&w32_font->metrics, &metrics->otmTextMetrics,
|
||||
sizeof (TEXTMETRICW));
|
||||
else
|
||||
|
|
@ -828,7 +959,7 @@ w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity,
|
|||
}
|
||||
|
||||
if (!metrics)
|
||||
GetTextMetricsW (dc, &w32_font->metrics);
|
||||
get_text_metrics_w (dc, &w32_font->metrics);
|
||||
|
||||
w32_font->cached_metrics = NULL;
|
||||
w32_font->n_cache_blocks = 0;
|
||||
|
|
@ -2306,7 +2437,7 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
|
|||
transform.eM11.value = 1;
|
||||
transform.eM22.value = 1;
|
||||
|
||||
if (GetGlyphOutlineW (dc, code, options, &gm, 0, NULL, &transform)
|
||||
if (get_glyph_outline_w (dc, code, options, &gm, 0, NULL, &transform)
|
||||
!= GDI_ERROR)
|
||||
{
|
||||
metrics->lbearing = gm.gmptGlyphOrigin.x;
|
||||
|
|
@ -2581,3 +2712,13 @@ versions of Windows) characters. */);
|
|||
w32font_driver.type = Qgdi;
|
||||
register_font_driver (&w32font_driver, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
globals_of_w32font (void)
|
||||
{
|
||||
g_b_init_is_w9x = 0;
|
||||
g_b_init_get_outline_metrics_w = 0;
|
||||
g_b_init_get_text_metrics_w = 0;
|
||||
g_b_init_get_glyph_outline_w = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue