aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32font.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32font.c')
-rw-r--r--src/w32font.c149
1 files changed, 145 insertions, 4 deletions
diff --git a/src/w32font.c b/src/w32font.c
index f47b7a46b1e..6c1b4d0bc20 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -145,6 +145,138 @@ struct font_callback_data
145 style variations if the font name is not specified. */ 145 style variations if the font name is not specified. */
146static void list_all_matching_fonts (struct font_callback_data *); 146static void list_all_matching_fonts (struct font_callback_data *);
147 147
148static BOOL g_b_init_is_w9x;
149static BOOL g_b_init_get_outline_metrics_w;
150static BOOL g_b_init_get_text_metrics_w;
151static BOOL g_b_init_get_glyph_outline_w;
152static BOOL g_b_init_get_glyph_outline_w;
153
154typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
155 HDC hdc,
156 UINT cbData,
157 LPOUTLINETEXTMETRICW lpotmw);
158typedef BOOL (WINAPI * GetTextMetricsW_Proc) (
159 HDC hdc,
160 LPTEXTMETRICW lptmw);
161typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) (
162 HDC hdc,
163 UINT uChar,
164 UINT uFormat,
165 LPGLYPHMETRICS lpgm,
166 DWORD cbBuffer,
167 LPVOID lpvBuffer,
168 const MAT2 *lpmat2);
169
170/* Several "wide" functions we use to support the font backends are
171 unavailable on Windows 9X, unless UNICOWS.DLL is installed (their
172 versions in the default libraries are non-functional stubs). On NT
173 and later systems, these functions are in GDI32.DLL. The following
174 helper function attempts to load UNICOWS.DLL on Windows 9X, and
175 refuses to let Emacs start up if that library is not found. On NT
176 and later versions, it simply loads GDI32.DLL, which should always
177 be available. */
178static HMODULE
179w32_load_unicows_or_gdi32 (void)
180{
181 static BOOL is_9x = 0;
182 OSVERSIONINFO os_ver;
183 HMODULE ret;
184 if (g_b_init_is_w9x == 0)
185 {
186 g_b_init_is_w9x = 1;
187 ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
188 os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
189 if (GetVersionEx (&os_ver))
190 is_9x = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
191 }
192 if (is_9x)
193 {
194 ret = LoadLibrary ("Unicows.dll");
195 if (!ret)
196 {
197 int button;
198
199 button = MessageBox (NULL,
200 "Emacs cannot load the UNICOWS.DLL library.\n"
201 "This library is essential for using Emacs\n"
202 "on this system. You need to install it.\n\n"
203 "However, you can still use Emacs by invoking\n"
204 "it with the '-nw' command-line option.\n\n"
205 "Emacs will exit when you click OK.",
206 "Emacs cannot load UNICOWS.DLL",
207 MB_ICONERROR | MB_TASKMODAL
208 | MB_SETFOREGROUND | MB_OK);
209 switch (button)
210 {
211 case IDOK:
212 default:
213 exit (1);
214 }
215 }
216 }
217 else
218 ret = LoadLibrary ("Gdi32.dll");
219 return ret;
220}
221
222/* The following 3 functions call the problematic "wide" APIs via
223 function pointers, to avoid linking against the non-standard
224 libunicows on W9X. */
225static UINT WINAPI
226get_outline_metrics_w(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpotmw)
227{
228 static GetOutlineTextMetricsW_Proc s_pfn_Get_Outline_Text_MetricsW = NULL;
229 HMODULE hm_unicows = NULL;
230 if (g_b_init_get_outline_metrics_w == 0)
231 {
232 g_b_init_get_outline_metrics_w = 1;
233 hm_unicows = w32_load_unicows_or_gdi32 ();
234 if (hm_unicows)
235 s_pfn_Get_Outline_Text_MetricsW = (GetOutlineTextMetricsW_Proc)
236 GetProcAddress (hm_unicows, "GetOutlineTextMetricsW");
237 }
238 if (s_pfn_Get_Outline_Text_MetricsW == NULL)
239 abort (); /* cannot happen */
240 return s_pfn_Get_Outline_Text_MetricsW (hdc, cbData, lpotmw);
241}
242
243static BOOL WINAPI
244get_text_metrics_w(HDC hdc, LPTEXTMETRICW lptmw)
245{
246 static GetTextMetricsW_Proc s_pfn_Get_Text_MetricsW = NULL;
247 HMODULE hm_unicows = NULL;
248 if (g_b_init_get_text_metrics_w == 0)
249 {
250 g_b_init_get_text_metrics_w = 1;
251 hm_unicows = w32_load_unicows_or_gdi32 ();
252 if (hm_unicows)
253 s_pfn_Get_Text_MetricsW = (GetTextMetricsW_Proc)
254 GetProcAddress (hm_unicows, "GetTextMetricsW");
255 }
256 if (s_pfn_Get_Text_MetricsW == NULL)
257 abort (); /* cannot happen */
258 return s_pfn_Get_Text_MetricsW (hdc, lptmw);
259}
260
261static DWORD WINAPI
262get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
263 DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2)
264{
265 static GetGlyphOutlineW_Proc s_pfn_Get_Glyph_OutlineW = NULL;
266 HMODULE hm_unicows = NULL;
267 if (g_b_init_get_glyph_outline_w == 0)
268 {
269 g_b_init_get_glyph_outline_w = 1;
270 hm_unicows = w32_load_unicows_or_gdi32 ();
271 if (hm_unicows)
272 s_pfn_Get_Glyph_OutlineW = (GetGlyphOutlineW_Proc)
273 GetProcAddress (hm_unicows, "GetGlyphOutlineW");
274 }
275 if (s_pfn_Get_Glyph_OutlineW == NULL)
276 abort (); /* cannot happen */
277 return s_pfn_Get_Glyph_OutlineW (hdc, uChar, uFormat, lpgm, cbBuffer,
278 lpvBuffer, lpmat2);
279}
148 280
149static int 281static int
150memq_no_quit (Lisp_Object elt, Lisp_Object list) 282memq_no_quit (Lisp_Object elt, Lisp_Object list)
@@ -816,11 +948,11 @@ w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity,
816 old_font = SelectObject (dc, hfont); 948 old_font = SelectObject (dc, hfont);
817 949
818 /* Try getting the outline metrics (only works for truetype fonts). */ 950 /* Try getting the outline metrics (only works for truetype fonts). */
819 len = GetOutlineTextMetricsW (dc, 0, NULL); 951 len = get_outline_metrics_w (dc, 0, NULL);
820 if (len) 952 if (len)
821 { 953 {
822 metrics = (OUTLINETEXTMETRICW *) alloca (len); 954 metrics = (OUTLINETEXTMETRICW *) alloca (len);
823 if (GetOutlineTextMetricsW (dc, len, metrics)) 955 if (get_outline_metrics_w (dc, len, metrics))
824 memcpy (&w32_font->metrics, &metrics->otmTextMetrics, 956 memcpy (&w32_font->metrics, &metrics->otmTextMetrics,
825 sizeof (TEXTMETRICW)); 957 sizeof (TEXTMETRICW));
826 else 958 else
@@ -828,7 +960,7 @@ w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity,
828 } 960 }
829 961
830 if (!metrics) 962 if (!metrics)
831 GetTextMetricsW (dc, &w32_font->metrics); 963 get_text_metrics_w (dc, &w32_font->metrics);
832 964
833 w32_font->cached_metrics = NULL; 965 w32_font->cached_metrics = NULL;
834 w32_font->n_cache_blocks = 0; 966 w32_font->n_cache_blocks = 0;
@@ -2306,7 +2438,7 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
2306 transform.eM11.value = 1; 2438 transform.eM11.value = 1;
2307 transform.eM22.value = 1; 2439 transform.eM22.value = 1;
2308 2440
2309 if (GetGlyphOutlineW (dc, code, options, &gm, 0, NULL, &transform) 2441 if (get_glyph_outline_w (dc, code, options, &gm, 0, NULL, &transform)
2310 != GDI_ERROR) 2442 != GDI_ERROR)
2311 { 2443 {
2312 metrics->lbearing = gm.gmptGlyphOrigin.x; 2444 metrics->lbearing = gm.gmptGlyphOrigin.x;
@@ -2581,3 +2713,12 @@ versions of Windows) characters. */);
2581 w32font_driver.type = Qgdi; 2713 w32font_driver.type = Qgdi;
2582 register_font_driver (&w32font_driver, NULL); 2714 register_font_driver (&w32font_driver, NULL);
2583} 2715}
2716
2717void
2718globals_of_w32font (void)
2719{
2720 g_b_init_is_w9x = 0;
2721 g_b_init_get_outline_metrics_w = 0;
2722 g_b_init_get_text_metrics_w = 0;
2723 g_b_init_get_glyph_outline_w = 0;
2724}