X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/a9faac5c6333bcbfb30a00debf3de7a44e430e49..db4f02f208c551982a54f6ea1fdf3d5577572ca3:/src/w32font.c diff --git a/src/w32font.c b/src/w32font.c index 46add9094f..fb41989caa 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -1,5 +1,5 @@ /* Font backend for the Microsoft W32 API. - Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2007-2011 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -54,8 +54,6 @@ along with GNU Emacs. If not, see . */ #define JOHAB_CHARSET 130 #endif -extern struct font_driver w32font_driver; - Lisp_Object Qgdi; Lisp_Object Quniscribe; static Lisp_Object QCformat; @@ -64,7 +62,6 @@ static Lisp_Object Qserif, Qscript, Qdecorative; static Lisp_Object Qraster, Qoutline, Qunknown; /* antialiasing */ -extern Lisp_Object QCantialias, QCotf, QClang; /* defined in font.c */ extern Lisp_Object Qnone; /* reuse from w32fns.c */ static Lisp_Object Qstandard, Qsubpixel, Qnatural; @@ -100,9 +97,6 @@ static Lisp_Object Qw32_charset_arabic, Qw32_charset_greek; static Lisp_Object Qw32_charset_hebrew, Qw32_charset_vietnamese; static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac; -/* Associative list linking character set strings to Windows codepages. */ -static Lisp_Object Vw32_charset_info_alist; - /* Font spacing symbols - defined in font.c. */ extern Lisp_Object Qc, Qp, Qm; @@ -151,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) @@ -171,7 +296,7 @@ intern_font_name (char * string) /* The following code is copied from the function intern (in lread.c). */ obarray = Vobarray; - if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0) + if (!VECTORP (obarray) || ASIZE (obarray) == 0) obarray = check_obarray (obarray); tem = oblookup (obarray, SDATA (str), len, len); if (SYMBOLP (tem)) @@ -539,6 +664,7 @@ w32font_draw (struct glyph_string *s, int from, int to, { UINT options; HRGN orig_clip = NULL; + int len = to - from; struct w32font_info *w32font = (struct w32font_info *) s->font; options = w32font->glyph_idx; @@ -587,14 +713,14 @@ w32font_draw (struct glyph_string *s, int from, int to, if (s->padding_p) { - int len = to - from, i; + int i; for (i = 0; i < len; i++) ExtTextOutW (s->hdc, x + i, y, options, NULL, s->char2b + from + i, 1, NULL); } else - ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, to - from, NULL); + ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, len, NULL); /* Restore clip region. */ if (s->num_clips > 0) @@ -602,6 +728,8 @@ w32font_draw (struct glyph_string *s, int from, int to, if (orig_clip) DeleteObject (orig_clip); + + return len; } /* w32 implementation of free_entity for font backend. @@ -780,7 +908,7 @@ int w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity, int pixel_size, Lisp_Object font_object) { - int len, size, i; + int len, size; LOGFONT logfont; HDC dc; HFONT hfont, old_font; @@ -819,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 @@ -831,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; @@ -1919,10 +2047,10 @@ fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec) int spacing = XINT (tmp); if (spacing < FONT_SPACING_MONO) logfont->lfPitchAndFamily - = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH; + = (logfont->lfPitchAndFamily & 0xF0) | VARIABLE_PITCH; else logfont->lfPitchAndFamily - = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH; + = (logfont->lfPitchAndFamily & 0xF0) | FIXED_PITCH; } /* Process EXTRA info. */ @@ -2309,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; @@ -2424,6 +2552,7 @@ struct font_driver w32font_driver = NULL, /* check */ NULL, /* get_variation_glyphs */ w32font_filter_properties, + NULL, /* cached_font_ok */ }; @@ -2535,7 +2664,7 @@ syms_of_w32font (void) /* W32 font encodings. */ DEFVAR_LISP ("w32-charset-info-alist", - &Vw32_charset_info_alist, + Vw32_charset_info_alist, doc: /* Alist linking Emacs character sets to Windows fonts and codepages. Each entry should be of the form: @@ -2584,3 +2713,12 @@ versions of Windows) characters. */); 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; +} +