Fix the MS-Windows build broken 2013-10-25T04:35:56Z!dgutov@yandex.ru.
[bpt/emacs.git] / src / w32font.c
CommitLineData
b46a6a83 1/* Font backend for the Microsoft Windows API.
ab422c4d 2 Copyright (C) 2007-2013 Free Software Foundation, Inc.
f7a84cb4
JR
3
4This file is part of GNU Emacs.
5
9ec0b715 6GNU Emacs is free software: you can redistribute it and/or modify
f7a84cb4 7it under the terms of the GNU General Public License as published by
9ec0b715
GM
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
f7a84cb4
JR
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
9ec0b715 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
f7a84cb4
JR
18
19#include <config.h>
20#include <windows.h>
0fda9b75 21#include <stdio.h>
09fe06b7 22#include <math.h>
0500dcc9 23#include <ctype.h>
6fe9826d 24#include <commdlg.h>
f7a84cb4
JR
25
26#include "lisp.h"
27#include "w32term.h"
28#include "frame.h"
29#include "dispextern.h"
30#include "character.h"
31#include "charset.h"
e6df5336 32#include "coding.h"
f7a84cb4
JR
33#include "fontset.h"
34#include "font.h"
46fd1ded 35#include "w32font.h"
f7a84cb4 36
91583281
JR
37/* Cleartype available on Windows XP, cleartype_natural from XP SP1.
38 The latter does not try to fit cleartype smoothed fonts into the
39 same bounding box as the non-antialiased version of the font.
40 */
41#ifndef CLEARTYPE_QUALITY
42#define CLEARTYPE_QUALITY 5
43#endif
44#ifndef CLEARTYPE_NATURAL_QUALITY
45#define CLEARTYPE_NATURAL_QUALITY 6
46#endif
47
57016d37
JR
48/* VIETNAMESE_CHARSET and JOHAB_CHARSET are not defined in some versions
49 of MSVC headers. */
50#ifndef VIETNAMESE_CHARSET
51#define VIETNAMESE_CHARSET 163
52#endif
53#ifndef JOHAB_CHARSET
54#define JOHAB_CHARSET 130
55#endif
56
91583281 57Lisp_Object Qgdi;
34fd2d28
JR
58Lisp_Object Quniscribe;
59static Lisp_Object QCformat;
9e1a2995
JR
60static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif;
61static Lisp_Object Qserif, Qscript, Qdecorative;
62static Lisp_Object Qraster, Qoutline, Qunknown;
d205d43b 63
91583281 64/* antialiasing */
91583281
JR
65static Lisp_Object Qstandard, Qsubpixel, Qnatural;
66
8f112d52 67/* languages */
314d66f4 68static Lisp_Object Qzh;
8f112d52 69
d205d43b 70/* scripts */
a11889ab 71static Lisp_Object Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
d205d43b
JR
72static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali;
73static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu;
74static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao;
75static Lisp_Object Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic;
76static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic;
8dc2e44a 77static Lisp_Object Qkhmer, Qmongolian, Qbraille, Qhan;
d205d43b
JR
78static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo;
79static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol;
174f1c74 80static Lisp_Object Qmusical_symbol, Qmathematical, Qcham, Qphonetic;
56df6710
JR
81/* Not defined in characters.el, but referenced in fontset.el. */
82static Lisp_Object Qbalinese, Qbuginese, Qbuhid, Qcuneiform, Qcypriot;
83static Lisp_Object Qdeseret, Qglagolitic, Qgothic, Qhanunoo, Qkharoshthi;
84static Lisp_Object Qlimbu, Qlinear_b, Qold_italic, Qold_persian, Qosmanya;
85static Lisp_Object Qphags_pa, Qphoenician, Qshavian, Qsyloti_nagri;
86static Lisp_Object Qtagalog, Qtagbanwa, Qtai_le, Qtifinagh, Qugaritic;
d205d43b 87
57016d37
JR
88/* W32 charsets: for use in Vw32_charset_info_alist. */
89static Lisp_Object Qw32_charset_ansi, Qw32_charset_default;
90static Lisp_Object Qw32_charset_symbol, Qw32_charset_shiftjis;
91static Lisp_Object Qw32_charset_hangeul, Qw32_charset_gb2312;
92static Lisp_Object Qw32_charset_chinesebig5, Qw32_charset_oem;
93static Lisp_Object Qw32_charset_easteurope, Qw32_charset_turkish;
94static Lisp_Object Qw32_charset_baltic, Qw32_charset_russian;
95static Lisp_Object Qw32_charset_arabic, Qw32_charset_greek;
96static Lisp_Object Qw32_charset_hebrew, Qw32_charset_vietnamese;
97static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac;
98
d205d43b
JR
99/* Font spacing symbols - defined in font.c. */
100extern Lisp_Object Qc, Qp, Qm;
f7a84cb4 101
a10c8269 102static void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object);
f7a84cb4 103
f57e2426
J
104static BYTE w32_antialias_type (Lisp_Object);
105static Lisp_Object lispy_antialias_type (BYTE);
91583281 106
f57e2426
J
107static Lisp_Object font_supported_scripts (FONTSIGNATURE *);
108static int w32font_full_name (LOGFONT *, Lisp_Object, int, char *, int);
109static void compute_metrics (HDC, struct w32font_info *, unsigned int,
110 struct w32_metric_cache *);
f7a84cb4 111
f57e2426 112static Lisp_Object w32_registry (LONG, DWORD);
f7a84cb4
JR
113
114/* EnumFontFamiliesEx callbacks. */
f57e2426
J
115static int CALLBACK add_font_entity_to_list (ENUMLOGFONTEX *,
116 NEWTEXTMETRICEX *,
117 DWORD, LPARAM);
118static int CALLBACK add_one_font_entity_to_list (ENUMLOGFONTEX *,
f7a84cb4 119 NEWTEXTMETRICEX *,
f57e2426
J
120 DWORD, LPARAM);
121static int CALLBACK add_font_name_to_list (ENUMLOGFONTEX *,
122 NEWTEXTMETRICEX *,
123 DWORD, LPARAM);
f7a84cb4 124
d205d43b
JR
125/* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
126 of what we really want. */
127struct font_callback_data
128{
129 /* The logfont we are matching against. EnumFontFamiliesEx only matches
130 face name and charset, so we need to manually match everything else
131 in the callback function. */
132 LOGFONT pattern;
133 /* The original font spec or entity. */
134 Lisp_Object orig_font_spec;
135 /* The frame the font is being loaded on. */
136 Lisp_Object frame;
137 /* The list to add matches to. */
138 Lisp_Object list;
46fd1ded
JR
139 /* Whether to match only opentype fonts. */
140 int opentype_only;
d205d43b
JR
141};
142
143/* Handles the problem that EnumFontFamiliesEx will not return all
144 style variations if the font name is not specified. */
f57e2426 145static void list_all_matching_fonts (struct font_callback_data *);
d205d43b 146
db4f02f2
EZ
147static BOOL g_b_init_is_w9x;
148static BOOL g_b_init_get_outline_metrics_w;
149static BOOL g_b_init_get_text_metrics_w;
150static BOOL g_b_init_get_glyph_outline_w;
151static BOOL g_b_init_get_glyph_outline_w;
152
153typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
154 HDC hdc,
155 UINT cbData,
156 LPOUTLINETEXTMETRICW lpotmw);
157typedef BOOL (WINAPI * GetTextMetricsW_Proc) (
158 HDC hdc,
159 LPTEXTMETRICW lptmw);
160typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) (
161 HDC hdc,
162 UINT uChar,
163 UINT uFormat,
164 LPGLYPHMETRICS lpgm,
165 DWORD cbBuffer,
166 LPVOID lpvBuffer,
167 const MAT2 *lpmat2);
168
169/* Several "wide" functions we use to support the font backends are
170 unavailable on Windows 9X, unless UNICOWS.DLL is installed (their
171 versions in the default libraries are non-functional stubs). On NT
172 and later systems, these functions are in GDI32.DLL. The following
173 helper function attempts to load UNICOWS.DLL on Windows 9X, and
174 refuses to let Emacs start up if that library is not found. On NT
175 and later versions, it simply loads GDI32.DLL, which should always
176 be available. */
177static HMODULE
178w32_load_unicows_or_gdi32 (void)
179{
180 static BOOL is_9x = 0;
181 OSVERSIONINFO os_ver;
182 HMODULE ret;
183 if (g_b_init_is_w9x == 0)
184 {
185 g_b_init_is_w9x = 1;
186 ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
187 os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
188 if (GetVersionEx (&os_ver))
189 is_9x = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
190 }
191 if (is_9x)
192 {
193 ret = LoadLibrary ("Unicows.dll");
194 if (!ret)
195 {
196 int button;
197
198 button = MessageBox (NULL,
199 "Emacs cannot load the UNICOWS.DLL library.\n"
200 "This library is essential for using Emacs\n"
201 "on this system. You need to install it.\n\n"
202 "However, you can still use Emacs by invoking\n"
203 "it with the '-nw' command-line option.\n\n"
204 "Emacs will exit when you click OK.",
205 "Emacs cannot load UNICOWS.DLL",
206 MB_ICONERROR | MB_TASKMODAL
207 | MB_SETFOREGROUND | MB_OK);
208 switch (button)
209 {
210 case IDOK:
211 default:
212 exit (1);
213 }
214 }
215 }
216 else
217 ret = LoadLibrary ("Gdi32.dll");
c20992f4 218 return ret;
db4f02f2
EZ
219}
220
221/* The following 3 functions call the problematic "wide" APIs via
222 function pointers, to avoid linking against the non-standard
223 libunicows on W9X. */
224static UINT WINAPI
225get_outline_metrics_w(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpotmw)
226{
227 static GetOutlineTextMetricsW_Proc s_pfn_Get_Outline_Text_MetricsW = NULL;
228 HMODULE hm_unicows = NULL;
229 if (g_b_init_get_outline_metrics_w == 0)
230 {
231 g_b_init_get_outline_metrics_w = 1;
232 hm_unicows = w32_load_unicows_or_gdi32 ();
233 if (hm_unicows)
234 s_pfn_Get_Outline_Text_MetricsW = (GetOutlineTextMetricsW_Proc)
235 GetProcAddress (hm_unicows, "GetOutlineTextMetricsW");
236 }
4e6a86c6 237 eassert (s_pfn_Get_Outline_Text_MetricsW != NULL);
db4f02f2
EZ
238 return s_pfn_Get_Outline_Text_MetricsW (hdc, cbData, lpotmw);
239}
240
241static BOOL WINAPI
242get_text_metrics_w(HDC hdc, LPTEXTMETRICW lptmw)
243{
244 static GetTextMetricsW_Proc s_pfn_Get_Text_MetricsW = NULL;
245 HMODULE hm_unicows = NULL;
246 if (g_b_init_get_text_metrics_w == 0)
247 {
248 g_b_init_get_text_metrics_w = 1;
249 hm_unicows = w32_load_unicows_or_gdi32 ();
250 if (hm_unicows)
251 s_pfn_Get_Text_MetricsW = (GetTextMetricsW_Proc)
252 GetProcAddress (hm_unicows, "GetTextMetricsW");
253 }
4e6a86c6 254 eassert (s_pfn_Get_Text_MetricsW != NULL);
db4f02f2
EZ
255 return s_pfn_Get_Text_MetricsW (hdc, lptmw);
256}
257
258static DWORD WINAPI
259get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
260 DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2)
261{
262 static GetGlyphOutlineW_Proc s_pfn_Get_Glyph_OutlineW = NULL;
263 HMODULE hm_unicows = NULL;
264 if (g_b_init_get_glyph_outline_w == 0)
265 {
266 g_b_init_get_glyph_outline_w = 1;
267 hm_unicows = w32_load_unicows_or_gdi32 ();
268 if (hm_unicows)
269 s_pfn_Get_Glyph_OutlineW = (GetGlyphOutlineW_Proc)
270 GetProcAddress (hm_unicows, "GetGlyphOutlineW");
271 }
4e6a86c6 272 eassert (s_pfn_Get_Glyph_OutlineW != NULL);
db4f02f2
EZ
273 return s_pfn_Get_Glyph_OutlineW (hdc, uChar, uFormat, lpgm, cbBuffer,
274 lpvBuffer, lpmat2);
275}
f7a84cb4
JR
276
277static int
b56ceb92 278memq_no_quit (Lisp_Object elt, Lisp_Object list)
f7a84cb4
JR
279{
280 while (CONSP (list) && ! EQ (XCAR (list), elt))
281 list = XCDR (list);
282 return (CONSP (list));
283}
284
e6df5336 285Lisp_Object
b56ceb92 286intern_font_name (char * string)
e6df5336 287{
e8df9267
DA
288 Lisp_Object str = DECODE_SYSTEM (build_string (string));
289 int len = SCHARS (str);
290 Lisp_Object obarray = check_obarray (Vobarray);
b46a6a83 291 Lisp_Object tem = oblookup (obarray, SDATA (str), len, len);
e8df9267
DA
292 /* This code is similar to intern function from lread.c. */
293 return SYMBOLP (tem) ? tem : Fintern (str, obarray);
e6df5336
JR
294}
295
f7a84cb4
JR
296/* w32 implementation of get_cache for font backend.
297 Return a cache of font-entities on FRAME. The cache must be a
298 cons whose cdr part is the actual cache area. */
46fd1ded 299Lisp_Object
a10c8269 300w32font_get_cache (struct frame *f)
f7a84cb4 301{
aad3612f 302 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
f7a84cb4
JR
303
304 return (dpyinfo->name_list_element);
305}
306
307/* w32 implementation of list for font backend.
308 List fonts exactly matching with FONT_SPEC on FRAME. The value
309 is a vector of font-entities. This is the sole API that
310 allocates font-entities. */
20399669 311static Lisp_Object
fdb396e2 312w32font_list (struct frame *f, Lisp_Object font_spec)
f7a84cb4 313{
fdb396e2 314 Lisp_Object fonts = w32font_list_internal (f, font_spec, 0);
678dca3d 315 FONT_ADD_LOG ("w32font-list", font_spec, fonts);
07d9ba9b 316 return fonts;
f7a84cb4
JR
317}
318
319/* w32 implementation of match for font backend.
320 Return a font entity most closely matching with FONT_SPEC on
4c36be58 321 FRAME. The closeness is determined by the font backend, thus
f7a84cb4 322 `face-font-selection-order' is ignored here. */
20399669 323static Lisp_Object
fdb396e2 324w32font_match (struct frame *f, Lisp_Object font_spec)
f7a84cb4 325{
fdb396e2 326 Lisp_Object entity = w32font_match_internal (f, font_spec, 0);
678dca3d 327 FONT_ADD_LOG ("w32font-match", font_spec, entity);
07d9ba9b 328 return entity;
f7a84cb4
JR
329}
330
f7a84cb4
JR
331/* w32 implementation of list_family for font backend.
332 List available families. The value is a list of family names
333 (symbols). */
20399669 334static Lisp_Object
fdb396e2 335w32font_list_family (struct frame *f)
f7a84cb4
JR
336{
337 Lisp_Object list = Qnil;
338 LOGFONT font_match_pattern;
339 HDC dc;
f7a84cb4 340
72af86bd 341 memset (&font_match_pattern, 0, sizeof (font_match_pattern));
56df6710 342 font_match_pattern.lfCharSet = DEFAULT_CHARSET;
f7a84cb4
JR
343
344 dc = get_frame_dc (f);
345
346 EnumFontFamiliesEx (dc, &font_match_pattern,
347 (FONTENUMPROC) add_font_name_to_list,
348 (LPARAM) &list, 0);
349 release_frame_dc (f, dc);
350
351 return list;
352}
353
354/* w32 implementation of open for font backend.
355 Open a font specified by FONT_ENTITY on frame F.
356 If the font is scalable, open it with PIXEL_SIZE. */
5f18d119 357static Lisp_Object
a10c8269 358w32font_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
f7a84cb4 359{
bd187c49
JR
360 Lisp_Object font_object
361 = font_make_object (VECSIZE (struct w32font_info),
362 font_entity, pixel_size);
363 struct w32font_info *w32_font
364 = (struct w32font_info *) XFONT_OBJECT (font_object);
f7a84cb4 365
4b135503 366 ASET (font_object, FONT_TYPE_INDEX, Qgdi);
f7a84cb4 367
5f18d119 368 if (!w32font_open_internal (f, font_entity, pixel_size, font_object))
f7a84cb4 369 {
5f18d119 370 return Qnil;
f7a84cb4
JR
371 }
372
bd187c49
JR
373 /* GDI backend does not use glyph indices. */
374 w32_font->glyph_idx = 0;
375
5f18d119 376 return font_object;
f7a84cb4
JR
377}
378
78e0b35c 379/* w32 implementation of close for font_backend. */
46fd1ded 380void
78e0b35c 381w32font_close (struct font *font)
f7a84cb4 382{
5f18d119 383 struct w32font_info *w32_font = (struct w32font_info *) font;
c35f9821 384
78e0b35c 385 if (w32_font->hfont)
c35f9821 386 {
78e0b35c
DA
387 /* Delete the GDI font object. */
388 DeleteObject (w32_font->hfont);
389 w32_font->hfont = NULL;
390
391 /* Free all the cached metrics. */
392 if (w32_font->cached_metrics)
393 {
6702c559
EZ
394 int i;
395
78e0b35c
DA
396 for (i = 0; i < w32_font->n_cache_blocks; i++)
397 xfree (w32_font->cached_metrics[i]);
398 xfree (w32_font->cached_metrics);
399 w32_font->cached_metrics = NULL;
400 }
c35f9821 401 }
f7a84cb4
JR
402}
403
404/* w32 implementation of has_char for font backend.
405 Optional.
406 If FONT_ENTITY has a glyph for character C (Unicode code point),
407 return 1. If not, return 0. If a font must be opened to check
408 it, return -1. */
46fd1ded 409int
b56ceb92 410w32font_has_char (Lisp_Object entity, int c)
f7a84cb4 411{
e6eee6ae
JR
412 /* We can't be certain about which characters a font will support until
413 we open it. Checking the scripts that the font supports turns out
414 to not be reliable. */
415 return -1;
416
417#if 0
d205d43b 418 Lisp_Object supported_scripts, extra, script;
f7a84cb4
JR
419 DWORD mask;
420
01dbeb0b
JR
421 extra = AREF (entity, FONT_EXTRA_INDEX);
422 if (!CONSP (extra))
423 return -1;
424
d205d43b 425 supported_scripts = assq_no_quit (QCscript, extra);
6a8082b5
JR
426 /* If font doesn't claim to support any scripts, then we can't be certain
427 until we open it. */
d205d43b 428 if (!CONSP (supported_scripts))
f7a84cb4
JR
429 return -1;
430
d205d43b 431 supported_scripts = XCDR (supported_scripts);
f7a84cb4 432
d205d43b 433 script = CHAR_TABLE_REF (Vchar_script_table, c);
f7a84cb4 434
6a8082b5
JR
435 /* If we don't know what script the character is from, then we can't be
436 certain until we open it. Also if the font claims support for the script
437 the character is from, it may only have partial coverage, so we still
438 can't be certain until we open the font. */
439 if (NILP (script) || memq_no_quit (script, supported_scripts))
440 return -1;
441
442 /* Font reports what scripts it supports, and none of them are the script
e6eee6ae
JR
443 the character is from. But we still can't be certain, as some fonts
444 will contain some/most/all of the characters in that script without
445 claiming support for it. */
446 return -1;
447#endif
f7a84cb4
JR
448}
449
450/* w32 implementation of encode_char for font backend.
51e4f4a8 451 Return a glyph code of FONT for character C (Unicode code point).
bd187c49
JR
452 If FONT doesn't have such a glyph, return FONT_INVALID_CODE.
453
fe7a3057 454 For speed, the gdi backend uses Unicode (Emacs calls encode_char
bd187c49
JR
455 far too often for it to be efficient). But we still need to detect
456 which characters are not supported by the font.
457 */
34fd2d28 458static unsigned
b56ceb92 459w32font_encode_char (struct font *font, int c)
f7a84cb4 460{
bd187c49 461 struct w32font_info * w32_font = (struct w32font_info *)font;
34fd2d28 462
bd187c49
JR
463 if (c < w32_font->metrics.tmFirstChar
464 || c > w32_font->metrics.tmLastChar)
465 return FONT_INVALID_CODE;
34fd2d28 466 else
bd187c49 467 return c;
f7a84cb4
JR
468}
469
470/* w32 implementation of text_extents for font backend.
471 Perform the size computation of glyphs of FONT and fillin members
472 of METRICS. The glyphs are specified by their glyph codes in
78573c57 473 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
f7a84cb4 474 case just return the overall width. */
46fd1ded 475int
b56ceb92
JB
476w32font_text_extents (struct font *font, unsigned *code,
477 int nglyphs, struct font_metrics *metrics)
f7a84cb4
JR
478{
479 int i;
2a36efcf
JR
480 HFONT old_font = NULL;
481 HDC dc = NULL;
46fd1ded 482 struct frame * f;
f7a84cb4 483 int total_width = 0;
f31cf550 484 WORD *wcode;
d205d43b 485 SIZE size;
f7a84cb4 486
1b5defe6
JR
487 struct w32font_info *w32_font = (struct w32font_info *) font;
488
f7a84cb4
JR
489 if (metrics)
490 {
72af86bd 491 memset (metrics, 0, sizeof (struct font_metrics));
388c38f9
JR
492 metrics->ascent = font->ascent;
493 metrics->descent = font->descent;
f7a84cb4
JR
494
495 for (i = 0; i < nglyphs; i++)
496 {
8f112d52
JR
497 struct w32_metric_cache *char_metric;
498 int block = *(code + i) / CACHE_BLOCKSIZE;
499 int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
500
501 if (block >= w32_font->n_cache_blocks)
502 {
503 if (!w32_font->cached_metrics)
504 w32_font->cached_metrics
505 = xmalloc ((block + 1)
9cac6313 506 * sizeof (struct w32_metric_cache *));
8f112d52
JR
507 else
508 w32_font->cached_metrics
509 = xrealloc (w32_font->cached_metrics,
510 (block + 1)
9cac6313 511 * sizeof (struct w32_metric_cache *));
72af86bd
AS
512 memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
513 ((block + 1 - w32_font->n_cache_blocks)
514 * sizeof (struct w32_metric_cache *)));
8f112d52
JR
515 w32_font->n_cache_blocks = block + 1;
516 }
517
518 if (!w32_font->cached_metrics[block])
519 {
520 w32_font->cached_metrics[block]
23f86fce 521 = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
8f112d52
JR
522 }
523
524 char_metric = w32_font->cached_metrics[block] + pos_in_block;
525
526 if (char_metric->status == W32METRIC_NO_ATTEMPT)
527 {
528 if (dc == NULL)
529 {
530 /* TODO: Frames can come and go, and their fonts
531 outlive them. So we can't cache the frame in the
532 font structure. Use selected_frame until the API
533 is updated to pass in a frame. */
534 f = XFRAME (selected_frame);
9c623c85 535
2a36efcf 536 dc = get_frame_dc (f);
1b5defe6 537 old_font = SelectObject (dc, w32_font->hfont);
8f112d52
JR
538 }
539 compute_metrics (dc, w32_font, *(code + i), char_metric);
540 }
78573c57 541
8f112d52
JR
542 if (char_metric->status == W32METRIC_SUCCESS)
543 {
544 metrics->lbearing = min (metrics->lbearing,
545 metrics->width + char_metric->lbearing);
546 metrics->rbearing = max (metrics->rbearing,
547 metrics->width + char_metric->rbearing);
548 metrics->width += char_metric->width;
549 }
550 else
551 /* If we couldn't get metrics for a char,
552 use alternative method. */
553 break;
554 }
78573c57
JR
555 /* If we got through everything, return. */
556 if (i == nglyphs)
557 {
2a36efcf
JR
558 if (dc != NULL)
559 {
560 /* Restore state and release DC. */
561 SelectObject (dc, old_font);
562 release_frame_dc (f, dc);
563 }
78573c57
JR
564
565 return metrics->width;
566 }
f7a84cb4 567 }
78573c57 568
56df6710
JR
569 /* For non-truetype fonts, GetGlyphOutlineW is not supported, so
570 fallback on other methods that will at least give some of the metric
571 information. */
b003e5ff 572
f31cf550
JR
573 /* Make array big enough to hold surrogates. */
574 wcode = alloca (nglyphs * sizeof (WORD) * 2);
575 for (i = 0; i < nglyphs; i++)
576 {
577 if (code[i] < 0x10000)
578 wcode[i] = code[i];
579 else
580 {
581 DWORD surrogate = code[i] - 0x10000;
582
583 /* High surrogate: U+D800 - U+DBFF. */
584 wcode[i++] = 0xD800 + ((surrogate >> 10) & 0x03FF);
585 /* Low surrogate: U+DC00 - U+DFFF. */
586 wcode[i] = 0xDC00 + (surrogate & 0x03FF);
587 /* An extra glyph. wcode is already double the size of code to
588 cope with this. */
589 nglyphs++;
590 }
591 }
592
2a36efcf
JR
593 if (dc == NULL)
594 {
8f112d52
JR
595 /* TODO: Frames can come and go, and their fonts outlive
596 them. So we can't cache the frame in the font structure. Use
597 selected_frame until the API is updated to pass in a
598 frame. */
599 f = XFRAME (selected_frame);
600
2a36efcf 601 dc = get_frame_dc (f);
1b5defe6 602 old_font = SelectObject (dc, w32_font->hfont);
2a36efcf
JR
603 }
604
d205d43b 605 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
f7a84cb4 606 {
d205d43b 607 total_width = size.cx;
f7a84cb4
JR
608 }
609
fe7a3057 610 /* On 95/98/ME, only some Unicode functions are available, so fallback
56df6710 611 on doing a dummy draw to find the total width. */
d205d43b 612 if (!total_width)
f7a84cb4
JR
613 {
614 RECT rect;
5f18d119 615 rect.top = 0; rect.bottom = font->height; rect.left = 0; rect.right = 1;
f7a84cb4
JR
616 DrawTextW (dc, wcode, nglyphs, &rect,
617 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
618 total_width = rect.right;
619 }
d205d43b 620
56df6710 621 /* Give our best estimate of the metrics, based on what we know. */
78573c57
JR
622 if (metrics)
623 {
79ca7db1 624 metrics->width = total_width - w32_font->metrics.tmOverhang;
78573c57 625 metrics->lbearing = 0;
79ca7db1 626 metrics->rbearing = total_width;
78573c57
JR
627 }
628
f7a84cb4
JR
629 /* Restore state and release DC. */
630 SelectObject (dc, old_font);
46fd1ded 631 release_frame_dc (f, dc);
f7a84cb4
JR
632
633 return total_width;
634}
635
636/* w32 implementation of draw for font backend.
637 Optional.
638 Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
a864ef14
PE
639 position of frame F with S->FACE and S->GC. If WITH_BACKGROUND,
640 fill the background in advance. It is assured that WITH_BACKGROUND
641 is false when (FROM > 0 || TO < S->nchars).
a74ddbda
JR
642
643 TODO: Currently this assumes that the colors and fonts are already
644 set in the DC. This seems to be true now, but maybe only due to
645 the old font code setting it up. It may be safer to resolve faces
646 and fonts in here and set them explicitly
647*/
648
46fd1ded 649int
b56ceb92 650w32font_draw (struct glyph_string *s, int from, int to,
a864ef14 651 int x, int y, bool with_background)
f7a84cb4 652{
34fd2d28 653 UINT options;
f70eb806 654 HRGN orig_clip = NULL;
9c88f339 655 int len = to - from;
5f18d119 656 struct w32font_info *w32font = (struct w32font_info *) s->font;
34fd2d28
JR
657
658 options = w32font->glyph_idx;
5c2c9c79 659
5c2c9c79
JR
660 if (s->num_clips > 0)
661 {
662 HRGN new_clip = CreateRectRgnIndirect (s->clip);
663
f70eb806
JR
664 /* Save clip region for later restoration. */
665 orig_clip = CreateRectRgn (0, 0, 0, 0);
ed3751c8 666 if (!GetClipRgn (s->hdc, orig_clip))
f70eb806
JR
667 {
668 DeleteObject (orig_clip);
669 orig_clip = NULL;
670 }
671
5c2c9c79
JR
672 if (s->num_clips > 1)
673 {
674 HRGN clip2 = CreateRectRgnIndirect (s->clip + 1);
675
676 CombineRgn (new_clip, new_clip, clip2, RGN_OR);
677 DeleteObject (clip2);
678 }
679
680 SelectClipRgn (s->hdc, new_clip);
681 DeleteObject (new_clip);
682 }
f7a84cb4 683
fb3b8017
JR
684 /* Using OPAQUE background mode can clear more background than expected
685 when Cleartype is used. Draw the background manually to avoid this. */
686 SetBkMode (s->hdc, TRANSPARENT);
f7a84cb4
JR
687 if (with_background)
688 {
1065a502
JR
689 HBRUSH brush;
690 RECT rect;
5f18d119 691 struct font *font = s->font;
1065a502
JR
692
693 brush = CreateSolidBrush (s->gc->background);
694 rect.left = x;
fb3b8017 695 rect.top = y - font->ascent;
1065a502 696 rect.right = x + s->width;
fb3b8017 697 rect.bottom = y + font->descent;
1065a502 698 FillRect (s->hdc, &rect, brush);
f2b25c0e 699 DeleteObject (brush);
f7a84cb4 700 }
040fe918 701
de63f07f
KH
702 if (s->padding_p)
703 {
9c88f339 704 int i;
de63f07f
KH
705
706 for (i = 0; i < len; i++)
707 ExtTextOutW (s->hdc, x + i, y, options, NULL,
8501c48b 708 s->char2b + from + i, 1, NULL);
de63f07f
KH
709 }
710 else
9c88f339 711 ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, len, NULL);
5c2c9c79
JR
712
713 /* Restore clip region. */
714 if (s->num_clips > 0)
f70eb806
JR
715 SelectClipRgn (s->hdc, orig_clip);
716
717 if (orig_clip)
718 DeleteObject (orig_clip);
9c88f339
JB
719
720 return len;
f7a84cb4
JR
721}
722
723/* w32 implementation of free_entity for font backend.
724 Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value).
725 Free FONT_EXTRA_INDEX field of FONT_ENTITY.
20399669
JR
726static void
727w32font_free_entity (Lisp_Object entity);
f7a84cb4
JR
728 */
729
730/* w32 implementation of prepare_face for font backend.
731 Optional (if FACE->extra is not used).
732 Prepare FACE for displaying characters by FONT on frame F by
733 storing some data in FACE->extra. If successful, return 0.
734 Otherwise, return -1.
20399669 735static int
a10c8269 736w32font_prepare_face (struct frame *f, struct face *face);
f7a84cb4
JR
737 */
738/* w32 implementation of done_face for font backend.
739 Optional.
740 Done FACE for displaying characters by FACE->font on frame F.
20399669 741static void
a10c8269 742w32font_done_face (struct frame *f, struct face *face); */
f7a84cb4
JR
743
744/* w32 implementation of get_bitmap for font backend.
745 Optional.
746 Store bitmap data for glyph-code CODE of FONT in BITMAP. It is
f2b25c0e 747 intended that this method is called from the other font-driver
f7a84cb4 748 for actual drawing.
20399669
JR
749static int
750w32font_get_bitmap (struct font *font, unsigned code,
751 struct font_bitmap *bitmap, int bits_per_pixel);
f7a84cb4
JR
752 */
753/* w32 implementation of free_bitmap for font backend.
754 Optional.
755 Free bitmap data in BITMAP.
20399669
JR
756static void
757w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap);
f7a84cb4
JR
758 */
759/* w32 implementation of get_outline for font backend.
760 Optional.
761 Return an outline data for glyph-code CODE of FONT. The format
762 of the outline data depends on the font-driver.
20399669
JR
763static void *
764w32font_get_outline (struct font *font, unsigned code);
f7a84cb4
JR
765 */
766/* w32 implementation of free_outline for font backend.
767 Optional.
768 Free OUTLINE (that is obtained by the above method).
20399669
JR
769static void
770w32font_free_outline (struct font *font, void *outline);
f7a84cb4
JR
771 */
772/* w32 implementation of anchor_point for font backend.
773 Optional.
774 Get coordinates of the INDEXth anchor point of the glyph whose
775 code is CODE. Store the coordinates in *X and *Y. Return 0 if
bbd240ce 776 the operations was successful. Otherwise return -1.
20399669
JR
777static int
778w32font_anchor_point (struct font *font, unsigned code,
f7a84cb4
JR
779 int index, int *x, int *y);
780 */
781/* w32 implementation of otf_capability for font backend.
782 Optional.
783 Return a list describing which scripts/languages FONT
784 supports by which GSUB/GPOS features of OpenType tables.
20399669
JR
785static Lisp_Object
786w32font_otf_capability (struct font *font);
f7a84cb4
JR
787 */
788/* w32 implementation of otf_drive for font backend.
789 Optional.
790 Apply FONT's OTF-FEATURES to the glyph string.
791
792 FEATURES specifies which OTF features to apply in this format:
793 (SCRIPT LANGSYS GSUB-FEATURE GPOS-FEATURE)
794 See the documentation of `font-drive-otf' for the detail.
795
796 This method applies the specified features to the codes in the
797 elements of GSTRING-IN (between FROMth and TOth). The output
798 codes are stored in GSTRING-OUT at the IDXth element and the
799 following elements.
800
801 Return the number of output codes. If none of the features are
802 applicable to the input data, return 0. If GSTRING-OUT is too
803 short, return -1.
20399669
JR
804static int
805w32font_otf_drive (struct font *font, Lisp_Object features,
806 Lisp_Object gstring_in, int from, int to,
807 Lisp_Object gstring_out, int idx,
a864ef14 808 bool alternate_subst);
f7a84cb4
JR
809 */
810
46fd1ded
JR
811/* Internal implementation of w32font_list.
812 Additional parameter opentype_only restricts the returned fonts to
813 opentype fonts, which can be used with the Uniscribe backend. */
814Lisp_Object
fdb396e2 815w32font_list_internal (struct frame *f, Lisp_Object font_spec, int opentype_only)
46fd1ded
JR
816{
817 struct font_callback_data match_data;
818 HDC dc;
46fd1ded
JR
819
820 match_data.orig_font_spec = font_spec;
821 match_data.list = Qnil;
fdb396e2 822 XSETFRAME (match_data.frame, f);
46fd1ded 823
72af86bd 824 memset (&match_data.pattern, 0, sizeof (LOGFONT));
46fd1ded
JR
825 fill_in_logfont (f, &match_data.pattern, font_spec);
826
19ae3e61
JR
827 /* If the charset is unrecognized, then we won't find a font, so don't
828 waste time looking for one. */
829 if (match_data.pattern.lfCharSet == DEFAULT_CHARSET)
830 {
831 Lisp_Object spec_charset = AREF (font_spec, FONT_REGISTRY_INDEX);
832 if (!NILP (spec_charset)
833 && !EQ (spec_charset, Qiso10646_1)
834 && !EQ (spec_charset, Qunicode_bmp)
835 && !EQ (spec_charset, Qunicode_sip)
836 && !EQ (spec_charset, Qunknown))
837 return Qnil;
838 }
839
46fd1ded
JR
840 match_data.opentype_only = opentype_only;
841 if (opentype_only)
842 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
843
844 if (match_data.pattern.lfFaceName[0] == '\0')
845 {
846 /* EnumFontFamiliesEx does not take other fields into account if
847 font name is blank, so need to use two passes. */
848 list_all_matching_fonts (&match_data);
849 }
850 else
851 {
852 dc = get_frame_dc (f);
853
854 EnumFontFamiliesEx (dc, &match_data.pattern,
855 (FONTENUMPROC) add_font_entity_to_list,
856 (LPARAM) &match_data, 0);
857 release_frame_dc (f, dc);
858 }
859
19ae3e61 860 return match_data.list;
46fd1ded
JR
861}
862
863/* Internal implementation of w32font_match.
864 Additional parameter opentype_only restricts the returned fonts to
865 opentype fonts, which can be used with the Uniscribe backend. */
866Lisp_Object
fdb396e2 867w32font_match_internal (struct frame *f, Lisp_Object font_spec, int opentype_only)
46fd1ded
JR
868{
869 struct font_callback_data match_data;
870 HDC dc;
46fd1ded
JR
871
872 match_data.orig_font_spec = font_spec;
fdb396e2 873 XSETFRAME (match_data.frame, f);
46fd1ded
JR
874 match_data.list = Qnil;
875
72af86bd 876 memset (&match_data.pattern, 0, sizeof (LOGFONT));
46fd1ded
JR
877 fill_in_logfont (f, &match_data.pattern, font_spec);
878
879 match_data.opentype_only = opentype_only;
880 if (opentype_only)
881 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
882
883 dc = get_frame_dc (f);
884
885 EnumFontFamiliesEx (dc, &match_data.pattern,
886 (FONTENUMPROC) add_one_font_entity_to_list,
887 (LPARAM) &match_data, 0);
888 release_frame_dc (f, dc);
889
890 return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
891}
892
f0121ad2 893int
a10c8269 894w32font_open_internal (struct frame *f, Lisp_Object font_entity,
b56ceb92 895 int pixel_size, Lisp_Object font_object)
f0121ad2 896{
9c88f339 897 int len, size;
f0121ad2
JR
898 LOGFONT logfont;
899 HDC dc;
900 HFONT hfont, old_font;
901 Lisp_Object val, extra;
5f18d119
KH
902 struct w32font_info *w32_font;
903 struct font * font;
bd187c49 904 OUTLINETEXTMETRICW* metrics = NULL;
5f18d119
KH
905
906 w32_font = (struct w32font_info *) XFONT_OBJECT (font_object);
907 font = (struct font *) w32_font;
f0121ad2 908
f0121ad2
JR
909 if (!font)
910 return 0;
911
72af86bd 912 memset (&logfont, 0, sizeof (logfont));
f0121ad2
JR
913 fill_in_logfont (f, &logfont, font_entity);
914
1519d52e
JR
915 /* Prefer truetype fonts, to avoid known problems with type1 fonts, and
916 limitations in bitmap fonts. */
917 val = AREF (font_entity, FONT_FOUNDRY_INDEX);
918 if (!EQ (val, Qraster))
919 logfont.lfOutPrecision = OUT_TT_PRECIS;
920
f0121ad2
JR
921 size = XINT (AREF (font_entity, FONT_SIZE_INDEX));
922 if (!size)
923 size = pixel_size;
924
925 logfont.lfHeight = -size;
926 hfont = CreateFontIndirect (&logfont);
927
928 if (hfont == NULL)
929 return 0;
930
f0121ad2
JR
931 /* Get the metrics for this font. */
932 dc = get_frame_dc (f);
933 old_font = SelectObject (dc, hfont);
934
5f18d119 935 /* Try getting the outline metrics (only works for truetype fonts). */
db4f02f2 936 len = get_outline_metrics_w (dc, 0, NULL);
5f18d119
KH
937 if (len)
938 {
bd187c49 939 metrics = (OUTLINETEXTMETRICW *) alloca (len);
db4f02f2 940 if (get_outline_metrics_w (dc, len, metrics))
72af86bd
AS
941 memcpy (&w32_font->metrics, &metrics->otmTextMetrics,
942 sizeof (TEXTMETRICW));
5f18d119
KH
943 else
944 metrics = NULL;
945 }
f0121ad2 946
943f2093 947 if (!metrics)
db4f02f2 948 get_text_metrics_w (dc, &w32_font->metrics);
b003e5ff 949
8f112d52
JR
950 w32_font->cached_metrics = NULL;
951 w32_font->n_cache_blocks = 0;
54efdcd1 952
f0121ad2
JR
953 SelectObject (dc, old_font);
954 release_frame_dc (f, dc);
34fd2d28 955
1b5defe6 956 w32_font->hfont = hfont;
f0121ad2 957
5ace1ec1
JR
958 {
959 char *name;
960
961 /* We don't know how much space we need for the full name, so start with
962 96 bytes and go up in steps of 32. */
963 len = 96;
c35f9821 964 name = alloca (len);
67997c79
JR
965 while (name && w32font_full_name (&logfont, font_entity, pixel_size,
966 name, len) < 0)
5ace1ec1 967 {
c35f9821
JR
968 len += 32;
969 name = alloca (len);
5ace1ec1
JR
970 }
971 if (name)
5f18d119 972 font->props[FONT_FULLNAME_INDEX]
e6df5336 973 = DECODE_SYSTEM (build_string (name));
5ace1ec1 974 else
e6df5336
JR
975 font->props[FONT_FULLNAME_INDEX]
976 = DECODE_SYSTEM (build_string (logfont.lfFaceName));
5ace1ec1 977 }
5f18d119
KH
978
979 font->max_width = w32_font->metrics.tmMaxCharWidth;
b003e5ff 980 /* Parts of Emacs display assume that height = ascent + descent...
9196133b 981 so height is defined later, after ascent and descent.
5f18d119 982 font->height = w32_font->metrics.tmHeight
f0121ad2 983 + w32_font->metrics.tmExternalLeading;
9196133b
JR
984 */
985
5f18d119
KH
986 font->space_width = font->average_width = w32_font->metrics.tmAveCharWidth;
987
988 font->vertical_centering = 0;
5f18d119
KH
989 font->baseline_offset = 0;
990 font->relative_compose = 0;
991 font->default_ascent = w32_font->metrics.tmAscent;
992 font->font_encoder = NULL;
f0121ad2
JR
993 font->pixel_size = size;
994 font->driver = &w32font_driver;
34fd2d28
JR
995 /* Use format cached during list, as the information we have access to
996 here is incomplete. */
997 extra = AREF (font_entity, FONT_EXTRA_INDEX);
998 if (CONSP (extra))
999 {
1000 val = assq_no_quit (QCformat, extra);
1001 if (CONSP (val))
5f18d119 1002 font->props[FONT_FORMAT_INDEX] = XCDR (val);
34fd2d28 1003 else
5f18d119 1004 font->props[FONT_FORMAT_INDEX] = Qunknown;
34fd2d28
JR
1005 }
1006 else
5f18d119 1007 font->props[FONT_FORMAT_INDEX] = Qunknown;
34fd2d28 1008
5f18d119 1009 font->props[FONT_FILE_INDEX] = Qnil;
f0121ad2
JR
1010 font->encoding_charset = -1;
1011 font->repertory_charset = -1;
04b65d2b 1012 /* TODO: do we really want the minimum width here, which could be negative? */
5f18d119 1013 font->min_width = font->space_width;
f0121ad2
JR
1014 font->ascent = w32_font->metrics.tmAscent;
1015 font->descent = w32_font->metrics.tmDescent;
9196133b 1016 font->height = font->ascent + font->descent;
5f18d119
KH
1017
1018 if (metrics)
1019 {
1020 font->underline_thickness = metrics->otmsUnderscoreSize;
1021 font->underline_position = -metrics->otmsUnderscorePosition;
1022 }
1023 else
1024 {
1025 font->underline_thickness = 0;
1026 font->underline_position = -1;
1027 }
f0121ad2 1028
5f18d119
KH
1029 /* For temporary compatibility with legacy code that expects the
1030 name to be usable in x-list-fonts. Eventually we expect to change
1031 x-list-fonts and other places that use fonts so that this can be
1032 an fcname or similar. */
a30e1957 1033 font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
04b65d2b 1034
f0121ad2
JR
1035 return 1;
1036}
1037
f7a84cb4
JR
1038/* Callback function for EnumFontFamiliesEx.
1039 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
20399669 1040static int CALLBACK
b56ceb92
JB
1041add_font_name_to_list (ENUMLOGFONTEX *logical_font,
1042 NEWTEXTMETRICEX *physical_font,
1043 DWORD font_type, LPARAM list_object)
f7a84cb4
JR
1044{
1045 Lisp_Object* list = (Lisp_Object *) list_object;
20a2b756
JR
1046 Lisp_Object family;
1047
1048 /* Skip vertical fonts (intended only for printing) */
1049 if (logical_font->elfLogFont.lfFaceName[0] == '@')
1050 return 1;
1051
e6df5336 1052 family = intern_font_name (logical_font->elfLogFont.lfFaceName);
f7a84cb4
JR
1053 if (! memq_no_quit (family, *list))
1054 *list = Fcons (family, *list);
1055
1056 return 1;
1057}
1058
f57e2426
J
1059static int w32_decode_weight (int);
1060static int w32_encode_weight (int);
5f18d119 1061
f7a84cb4 1062/* Convert an enumerated Windows font to an Emacs font entity. */
20399669 1063static Lisp_Object
b56ceb92
JB
1064w32_enumfont_pattern_entity (Lisp_Object frame,
1065 ENUMLOGFONTEX *logical_font,
1066 NEWTEXTMETRICEX *physical_font,
1067 DWORD font_type,
1068 LOGFONT *requested_font,
1069 Lisp_Object backend)
f7a84cb4
JR
1070{
1071 Lisp_Object entity, tem;
1072 LOGFONT *lf = (LOGFONT*) logical_font;
1073 BYTE generic_type;
56df6710 1074 DWORD full_type = physical_font->ntmTm.ntmFlags;
f7a84cb4 1075
5f18d119 1076 entity = font_make_entity ();
f7a84cb4 1077
34fd2d28 1078 ASET (entity, FONT_TYPE_INDEX, backend);
c960bff8 1079 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet, font_type));
f7a84cb4
JR
1080 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
1081
1082 /* Foundry is difficult to get in readable form on Windows.
d205d43b 1083 But Emacs crashes if it is not set, so set it to something more
9c623c85 1084 generic. These values make xlfds compatible with Emacs 22. */
d205d43b
JR
1085 if (lf->lfOutPrecision == OUT_STRING_PRECIS)
1086 tem = Qraster;
1087 else if (lf->lfOutPrecision == OUT_STROKE_PRECIS)
1088 tem = Qoutline;
1089 else
1090 tem = Qunknown;
1091
1092 ASET (entity, FONT_FOUNDRY_INDEX, tem);
1093
1094 /* Save the generic family in the extra info, as it is likely to be
1095 useful to users looking for a close match. */
f7a84cb4
JR
1096 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0;
1097 if (generic_type == FF_DECORATIVE)
1098 tem = Qdecorative;
1099 else if (generic_type == FF_MODERN)
9e1a2995 1100 tem = Qmono;
f7a84cb4 1101 else if (generic_type == FF_ROMAN)
d205d43b 1102 tem = Qserif;
f7a84cb4
JR
1103 else if (generic_type == FF_SCRIPT)
1104 tem = Qscript;
1105 else if (generic_type == FF_SWISS)
9e1a2995 1106 tem = Qsans;
f7a84cb4 1107 else
5f18d119 1108 tem = Qnil;
9e1a2995
JR
1109
1110 ASET (entity, FONT_ADSTYLE_INDEX, tem);
f7a84cb4 1111
d205d43b 1112 if (physical_font->ntmTm.tmPitchAndFamily & 0x01)
5f18d119 1113 ASET (entity, FONT_SPACING_INDEX, make_number (FONT_SPACING_PROPORTIONAL));
d205d43b 1114 else
ed18e612 1115 ASET (entity, FONT_SPACING_INDEX, make_number (FONT_SPACING_CHARCELL));
f7a84cb4 1116
91583281
JR
1117 if (requested_font->lfQuality != DEFAULT_QUALITY)
1118 {
1119 font_put_extra (entity, QCantialias,
1120 lispy_antialias_type (requested_font->lfQuality));
1121 }
f7a84cb4 1122 ASET (entity, FONT_FAMILY_INDEX,
e6df5336 1123 intern_font_name (lf->lfFaceName));
f7a84cb4 1124
5f18d119
KH
1125 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
1126 make_number (w32_decode_weight (lf->lfWeight)));
1127 FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
1128 make_number (lf->lfItalic ? 200 : 100));
d205d43b
JR
1129 /* TODO: PANOSE struct has this info, but need to call GetOutlineTextMetrics
1130 to get it. */
5f18d119 1131 FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (100));
f7a84cb4 1132
040fe918 1133 if (font_type & RASTER_FONTTYPE)
597634cb
JR
1134 ASET (entity, FONT_SIZE_INDEX,
1135 make_number (physical_font->ntmTm.tmHeight
1136 + physical_font->ntmTm.tmExternalLeading));
040fe918
JR
1137 else
1138 ASET (entity, FONT_SIZE_INDEX, make_number (0));
f7a84cb4 1139
fe7a3057 1140 /* Cache Unicode codepoints covered by this font, as there is no other way
f7a84cb4 1141 of getting this information easily. */
040fe918 1142 if (font_type & TRUETYPE_FONTTYPE)
f7a84cb4 1143 {
aee986fd
JR
1144 tem = font_supported_scripts (&physical_font->ntmFontSig);
1145 if (!NILP (tem))
1146 font_put_extra (entity, QCscript, tem);
f7a84cb4 1147 }
d205d43b 1148
34fd2d28
JR
1149 /* This information is not fully available when opening fonts, so
1150 save it here. Only Windows 2000 and later return information
1151 about opentype and type1 fonts, so need a fallback for detecting
1152 truetype so that this information is not any worse than we could
1153 have obtained later. */
56df6710
JR
1154 if (EQ (backend, Quniscribe) && (full_type & NTMFLAGS_OPENTYPE))
1155 tem = intern ("opentype");
1156 else if (font_type & TRUETYPE_FONTTYPE)
34fd2d28 1157 tem = intern ("truetype");
34fd2d28
JR
1158 else if (full_type & NTM_PS_OPENTYPE)
1159 tem = intern ("postscript");
56df6710
JR
1160 else if (full_type & NTM_TYPE1)
1161 tem = intern ("type1");
34fd2d28
JR
1162 else if (font_type & RASTER_FONTTYPE)
1163 tem = intern ("w32bitmap");
1164 else
1165 tem = intern ("w32vector");
1166
1167 font_put_extra (entity, QCformat, tem);
1168
f7a84cb4
JR
1169 return entity;
1170}
1171
d205d43b
JR
1172
1173/* Convert generic families to the family portion of lfPitchAndFamily. */
24f981c9 1174static BYTE
d205d43b
JR
1175w32_generic_family (Lisp_Object name)
1176{
1177 /* Generic families. */
1178 if (EQ (name, Qmonospace) || EQ (name, Qmono))
1179 return FF_MODERN;
9e1a2995 1180 else if (EQ (name, Qsans) || EQ (name, Qsans_serif) || EQ (name, Qsansserif))
d205d43b
JR
1181 return FF_SWISS;
1182 else if (EQ (name, Qserif))
1183 return FF_ROMAN;
1184 else if (EQ (name, Qdecorative))
1185 return FF_DECORATIVE;
1186 else if (EQ (name, Qscript))
1187 return FF_SCRIPT;
1188 else
1189 return FF_DONTCARE;
1190}
1191
1192static int
b56ceb92 1193logfonts_match (LOGFONT *font, LOGFONT *pattern)
d205d43b
JR
1194{
1195 /* Only check height for raster fonts. */
1196 if (pattern->lfHeight && font->lfOutPrecision == OUT_STRING_PRECIS
1197 && font->lfHeight != pattern->lfHeight)
1198 return 0;
1199
1200 /* Have some flexibility with weights. */
1201 if (pattern->lfWeight
1202 && ((font->lfWeight < (pattern->lfWeight - 150))
1203 || font->lfWeight > (pattern->lfWeight + 150)))
1204 return 0;
1205
1206 /* Charset and face should be OK. Italic has to be checked
1207 against the original spec, in case we don't have any preference. */
1208 return 1;
1209}
1210
4c100a01
JR
1211/* Codepage Bitfields in FONTSIGNATURE struct. */
1212#define CSB_JAPANESE (1 << 17)
1213#define CSB_KOREAN ((1 << 19) | (1 << 21))
1214#define CSB_CHINESE ((1 << 18) | (1 << 20))
1215
d205d43b 1216static int
b56ceb92
JB
1217font_matches_spec (DWORD type, NEWTEXTMETRICEX *font,
1218 Lisp_Object spec, Lisp_Object backend,
1219 LOGFONT *logfont)
d205d43b
JR
1220{
1221 Lisp_Object extra, val;
1222
1223 /* Check italic. Can't check logfonts, since it is a boolean field,
1224 so there is no difference between "non-italic" and "don't care". */
5f18d119
KH
1225 {
1226 int slant = FONT_SLANT_NUMERIC (spec);
1227
1228 if (slant >= 0
1229 && ((slant > 150 && !font->ntmTm.tmItalic)
1230 || (slant <= 150 && font->ntmTm.tmItalic)))
1231 return 0;
1232 }
d205d43b 1233
4f2a2ee2
JR
1234 /* Check adstyle against generic family. */
1235 val = AREF (spec, FONT_ADSTYLE_INDEX);
1236 if (!NILP (val))
1237 {
1238 BYTE family = w32_generic_family (val);
1239 if (family != FF_DONTCARE
1240 && family != (font->ntmTm.tmPitchAndFamily & 0xF0))
1241 return 0;
1242 }
1243
5f18d119
KH
1244 /* Check spacing */
1245 val = AREF (spec, FONT_SPACING_INDEX);
1246 if (INTEGERP (val))
1247 {
1248 int spacing = XINT (val);
1249 int proportional = (spacing < FONT_SPACING_MONO);
1250
1251 if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
1252 || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
1253 return 0;
1254 }
1255
d205d43b
JR
1256 /* Check extra parameters. */
1257 for (extra = AREF (spec, FONT_EXTRA_INDEX);
1258 CONSP (extra); extra = XCDR (extra))
1259 {
1260 Lisp_Object extra_entry;
1261 extra_entry = XCAR (extra);
1262 if (CONSP (extra_entry))
1263 {
1264 Lisp_Object key = XCAR (extra_entry);
d205d43b 1265
5f18d119
KH
1266 val = XCDR (extra_entry);
1267 if (EQ (key, QCscript) && SYMBOLP (val))
d205d43b
JR
1268 {
1269 /* Only truetype fonts will have information about what
1270 scripts they support. This probably means the user
7877f373
JB
1271 will have to force Emacs to use raster, PostScript
1272 or ATM fonts for non-ASCII text. */
d205d43b
JR
1273 if (type & TRUETYPE_FONTTYPE)
1274 {
1275 Lisp_Object support
1276 = font_supported_scripts (&font->ntmFontSig);
1277 if (! memq_no_quit (val, support))
1278 return 0;
22610910
JR
1279
1280 /* Avoid using non-Japanese fonts for Japanese, even
1281 if they claim they are capable, due to known
1282 breakage in Vista and Windows 7 fonts
1283 (bug#6029). */
1284 if (EQ (val, Qkana)
1285 && (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET
1286 || !(font->ntmFontSig.fsCsb[0] & CSB_JAPANESE)))
1287 return 0;
d205d43b
JR
1288 }
1289 else
1290 {
1291 /* Return specific matches, but play it safe. Fonts
1292 that cover more than their charset would suggest
1293 are likely to be truetype or opentype fonts,
1294 covered above. */
1295 if (EQ (val, Qlatin))
1296 {
1297 /* Although every charset but symbol, thai and
1298 arabic contains the basic ASCII set of latin
1299 characters, Emacs expects much more. */
1300 if (font->ntmTm.tmCharSet != ANSI_CHARSET)
1301 return 0;
1302 }
1303 else if (EQ (val, Qsymbol))
1304 {
1305 if (font->ntmTm.tmCharSet != SYMBOL_CHARSET)
1306 return 0;
1307 }
1308 else if (EQ (val, Qcyrillic))
1309 {
1310 if (font->ntmTm.tmCharSet != RUSSIAN_CHARSET)
1311 return 0;
1312 }
1313 else if (EQ (val, Qgreek))
1314 {
1315 if (font->ntmTm.tmCharSet != GREEK_CHARSET)
1316 return 0;
1317 }
1318 else if (EQ (val, Qarabic))
1319 {
1320 if (font->ntmTm.tmCharSet != ARABIC_CHARSET)
1321 return 0;
1322 }
1323 else if (EQ (val, Qhebrew))
1324 {
1325 if (font->ntmTm.tmCharSet != HEBREW_CHARSET)
1326 return 0;
1327 }
1328 else if (EQ (val, Qthai))
1329 {
1330 if (font->ntmTm.tmCharSet != THAI_CHARSET)
1331 return 0;
1332 }
1333 else if (EQ (val, Qkana))
1334 {
1335 if (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
1336 return 0;
1337 }
1338 else if (EQ (val, Qbopomofo))
1339 {
1340 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET)
1341 return 0;
1342 }
1343 else if (EQ (val, Qhangul))
1344 {
1345 if (font->ntmTm.tmCharSet != HANGUL_CHARSET
1346 && font->ntmTm.tmCharSet != JOHAB_CHARSET)
1347 return 0;
1348 }
1349 else if (EQ (val, Qhan))
1350 {
1351 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET
1352 && font->ntmTm.tmCharSet != GB2312_CHARSET
1353 && font->ntmTm.tmCharSet != HANGUL_CHARSET
1354 && font->ntmTm.tmCharSet != JOHAB_CHARSET
1355 && font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
1356 return 0;
1357 }
1358 else
56df6710
JR
1359 /* Other scripts unlikely to be handled by non-truetype
1360 fonts. */
d205d43b
JR
1361 return 0;
1362 }
1363 }
5f18d119 1364 else if (EQ (key, QClang) && SYMBOLP (val))
8f112d52 1365 {
4c100a01 1366 /* Just handle the CJK languages here, as the lang
8f112d52
JR
1367 parameter is used to select a font with appropriate
1368 glyphs in the cjk unified ideographs block. Other fonts
1369 support for a language can be solely determined by
1370 its character coverage. */
1371 if (EQ (val, Qja))
1372 {
4c100a01 1373 if (!(font->ntmFontSig.fsCsb[0] & CSB_JAPANESE))
8f112d52
JR
1374 return 0;
1375 }
1376 else if (EQ (val, Qko))
1377 {
4c100a01 1378 if (!(font->ntmFontSig.fsCsb[0] & CSB_KOREAN))
8f112d52
JR
1379 return 0;
1380 }
1381 else if (EQ (val, Qzh))
1382 {
4c100a01
JR
1383 if (!(font->ntmFontSig.fsCsb[0] & CSB_CHINESE))
1384 return 0;
8f112d52
JR
1385 }
1386 else
4c100a01
JR
1387 /* Any other language, we don't recognize it. Only the above
1388 currently appear in fontset.el, so it isn't worth
1389 creating a mapping table of codepages/scripts to languages
1390 or opening the font to see if there are any language tags
b46a6a83 1391 in it that the Windows API does not expose. Fontset
8f112d52
JR
1392 spec should have a fallback, as some backends do
1393 not recognize language at all. */
1394 return 0;
1395 }
56df6710
JR
1396 else if (EQ (key, QCotf) && CONSP (val))
1397 {
1398 /* OTF features only supported by the uniscribe backend. */
1399 if (EQ (backend, Quniscribe))
1400 {
1401 if (!uniscribe_check_otf (logfont, val))
1402 return 0;
1403 }
1404 else
1405 return 0;
1406 }
d205d43b
JR
1407 }
1408 }
1409 return 1;
1410}
1411
c960bff8 1412static int
b56ceb92 1413w32font_coverage_ok (FONTSIGNATURE * coverage, BYTE charset)
c960bff8
JR
1414{
1415 DWORD subrange1 = coverage->fsUsb[1];
1416
1417#define SUBRANGE1_HAN_MASK 0x08000000
1418#define SUBRANGE1_HANGEUL_MASK 0x01000000
1419#define SUBRANGE1_JAPANESE_MASK (0x00060000 | SUBRANGE1_HAN_MASK)
1420
1421 if (charset == GB2312_CHARSET || charset == CHINESEBIG5_CHARSET)
1422 {
1423 return (subrange1 & SUBRANGE1_HAN_MASK) == SUBRANGE1_HAN_MASK;
1424 }
1425 else if (charset == SHIFTJIS_CHARSET)
1426 {
1427 return (subrange1 & SUBRANGE1_JAPANESE_MASK) == SUBRANGE1_JAPANESE_MASK;
1428 }
1429 else if (charset == HANGEUL_CHARSET)
1430 {
1431 return (subrange1 & SUBRANGE1_HANGEUL_MASK) == SUBRANGE1_HANGEUL_MASK;
1432 }
1433
1434 return 1;
1435}
1436
0fda9b75
DC
1437#ifndef WINDOWSNT
1438#define _strlwr strlwr
1439#endif /* !WINDOWSNT */
b0857706
JR
1440
1441static int
b56ceb92 1442check_face_name (LOGFONT *font, char *full_name)
b0857706
JR
1443{
1444 char full_iname[LF_FULLFACESIZE+1];
1445
1446 /* Just check for names known to cause problems, since the full name
1447 can contain expanded abbreviations, prefixed foundry, postfixed
1448 style, the latter of which sometimes differs from the style indicated
1449 in the shorter name (eg Lt becomes Light or even Extra Light) */
1450
1451 /* Helvetica is mapped to Arial in Windows, but if a Type-1 Helvetica is
1452 installed, we run into problems with the Uniscribe backend which tries
1453 to avoid non-truetype fonts, and ends up mixing the Type-1 Helvetica
7877f373 1454 with Arial's characteristics, since that attempt to use TrueType works
b0857706 1455 some places, but not others. */
c285743c 1456 if (!xstrcasecmp (font->lfFaceName, "helvetica"))
b0857706
JR
1457 {
1458 strncpy (full_iname, full_name, LF_FULLFACESIZE);
1459 full_iname[LF_FULLFACESIZE] = 0;
1460 _strlwr (full_iname);
c285743c 1461 return strstr ("helvetica", full_iname) != NULL;
b0857706 1462 }
631ea4fb
JR
1463 /* Same for Helv. */
1464 if (!xstrcasecmp (font->lfFaceName, "helv"))
1465 {
1466 strncpy (full_iname, full_name, LF_FULLFACESIZE);
1467 full_iname[LF_FULLFACESIZE] = 0;
1468 _strlwr (full_iname);
1469 return strstr ("helv", full_iname) != NULL;
1470 }
c285743c
JR
1471
1472 /* Since Times is mapped to Times New Roman, a substring
1473 match is not sufficient to filter out the bogus match. */
1474 else if (!xstrcasecmp (font->lfFaceName, "times"))
1475 return xstrcasecmp (full_name, "times") == 0;
b0857706
JR
1476
1477 return 1;
1478}
1479
1480
f7a84cb4 1481/* Callback function for EnumFontFamiliesEx.
91af3942 1482 * Checks if a font matches everything we are trying to check against,
d205d43b
JR
1483 * and if so, adds it to a list. Both the data we are checking against
1484 * and the list to which the fonts are added are passed in via the
1485 * lparam argument, in the form of a font_callback_data struct. */
20399669 1486static int CALLBACK
b56ceb92
JB
1487add_font_entity_to_list (ENUMLOGFONTEX *logical_font,
1488 NEWTEXTMETRICEX *physical_font,
1489 DWORD font_type, LPARAM lParam)
f7a84cb4 1490{
d205d43b
JR
1491 struct font_callback_data *match_data
1492 = (struct font_callback_data *) lParam;
56df6710 1493 Lisp_Object backend = match_data->opentype_only ? Quniscribe : Qgdi;
19ae3e61
JR
1494 Lisp_Object entity;
1495
1496 int is_unicode = physical_font->ntmFontSig.fsUsb[3]
1497 || physical_font->ntmFontSig.fsUsb[2]
1498 || physical_font->ntmFontSig.fsUsb[1]
1499 || physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff;
1500
1501 /* Skip non matching fonts. */
1502
1503 /* For uniscribe backend, consider only truetype or opentype fonts
fe7a3057 1504 that have some Unicode coverage. */
19ae3e61 1505 if (match_data->opentype_only
22610910 1506 && ((!(physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE)
19ae3e61
JR
1507 && !(font_type & TRUETYPE_FONTTYPE))
1508 || !is_unicode))
1509 return 1;
1510
1511 /* Ensure a match. */
1512 if (!logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
1513 || !font_matches_spec (font_type, physical_font,
1514 match_data->orig_font_spec, backend,
1515 &logical_font->elfLogFont)
1516 || !w32font_coverage_ok (&physical_font->ntmFontSig,
1517 match_data->pattern.lfCharSet))
1518 return 1;
f7a84cb4 1519
19ae3e61
JR
1520 /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif)
1521 We limit this to raster fonts, because the test can catch some
1522 genuine fonts (eg the full name of DejaVu Sans Mono Light is actually
1523 DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will
1524 therefore get through this test. Since full names can be prefixed
1525 by a foundry, we accept raster fonts if the font name is found
1526 anywhere within the full name. */
1527 if ((logical_font->elfLogFont.lfOutPrecision == OUT_STRING_PRECIS
c73abf54
JR
1528 && !strstr (logical_font->elfFullName,
1529 logical_font->elfLogFont.lfFaceName))
b0857706
JR
1530 /* Check for well known substitutions that mess things up in the
1531 presence of Type-1 fonts of the same name. */
631ea4fb
JR
1532 || (!check_face_name (&logical_font->elfLogFont,
1533 logical_font->elfFullName)))
19ae3e61
JR
1534 return 1;
1535
1536 /* Make a font entity for the font. */
1537 entity = w32_enumfont_pattern_entity (match_data->frame, logical_font,
1538 physical_font, font_type,
1539 &match_data->pattern,
1540 backend);
1541
1542 if (!NILP (entity))
d205d43b 1543 {
19ae3e61
JR
1544 Lisp_Object spec_charset = AREF (match_data->orig_font_spec,
1545 FONT_REGISTRY_INDEX);
1546
fe7a3057 1547 /* iso10646-1 fonts must contain Unicode mapping tables. */
19ae3e61
JR
1548 if (EQ (spec_charset, Qiso10646_1))
1549 {
1550 if (!is_unicode)
9d32f818 1551 return 1;
19ae3e61
JR
1552 }
1553 /* unicode-bmp fonts must contain characters from the BMP. */
1554 else if (EQ (spec_charset, Qunicode_bmp))
1555 {
1556 if (!physical_font->ntmFontSig.fsUsb[3]
1557 && !(physical_font->ntmFontSig.fsUsb[2] & 0xFFFFFF9E)
1558 && !(physical_font->ntmFontSig.fsUsb[1] & 0xE81FFFFF)
1559 && !(physical_font->ntmFontSig.fsUsb[0] & 0x007F001F))
1560 return 1;
1561 }
fe7a3057 1562 /* unicode-sip fonts must contain characters in Unicode plane 2.
19ae3e61
JR
1563 so look for bit 57 (surrogates) in the Unicode subranges, plus
1564 the bits for CJK ranges that include those characters. */
1565 else if (EQ (spec_charset, Qunicode_sip))
1566 {
22610910
JR
1567 if (!(physical_font->ntmFontSig.fsUsb[1] & 0x02000000)
1568 || !(physical_font->ntmFontSig.fsUsb[1] & 0x28000000))
19ae3e61
JR
1569 return 1;
1570 }
1571
1572 /* This font matches. */
1573
1574 /* If registry was specified, ensure it is reported as the same. */
1575 if (!NILP (spec_charset))
22610910
JR
1576 {
1577 /* Avoid using non-Japanese fonts for Japanese, even if they
1578 claim they are capable, due to known breakage in Vista
1579 and Windows 7 fonts (bug#6029). */
1580 if (logical_font->elfLogFont.lfCharSet == SHIFTJIS_CHARSET
1581 && !(physical_font->ntmFontSig.fsCsb[0] & CSB_JAPANESE))
1582 return 1;
1583 else
1584 ASET (entity, FONT_REGISTRY_INDEX, spec_charset);
1585 }
19ae3e61 1586 /* Otherwise if using the uniscribe backend, report ANSI and DEFAULT
fe7a3057 1587 fonts as Unicode and skip other charsets. */
19ae3e61
JR
1588 else if (match_data->opentype_only)
1589 {
1590 if (logical_font->elfLogFont.lfCharSet == ANSI_CHARSET
1591 || logical_font->elfLogFont.lfCharSet == DEFAULT_CHARSET)
1592 ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1);
1593 else
1594 return 1;
1595 }
1596
1597 /* Add this font to the list. */
1598 match_data->list = Fcons (entity, match_data->list);
d205d43b 1599 }
f7a84cb4
JR
1600 return 1;
1601}
1602
1603/* Callback function for EnumFontFamiliesEx.
d205d43b 1604 * Terminates the search once we have a match. */
20399669 1605static int CALLBACK
b56ceb92
JB
1606add_one_font_entity_to_list (ENUMLOGFONTEX *logical_font,
1607 NEWTEXTMETRICEX *physical_font,
1608 DWORD font_type, LPARAM lParam)
f7a84cb4 1609{
d205d43b
JR
1610 struct font_callback_data *match_data
1611 = (struct font_callback_data *) lParam;
1612 add_font_entity_to_list (logical_font, physical_font, font_type, lParam);
1613
1614 /* If we have a font in the list, terminate the search. */
4624b6e3 1615 return NILP (match_data->list);
f7a84cb4
JR
1616}
1617
57016d37
JR
1618/* Old function to convert from x to w32 charset, from w32fns.c. */
1619static LONG
b56ceb92 1620x_to_w32_charset (char * lpcs)
57016d37
JR
1621{
1622 Lisp_Object this_entry, w32_charset;
1623 char *charset;
1624 int len = strlen (lpcs);
1625
1626 /* Support "*-#nnn" format for unknown charsets. */
1627 if (strncmp (lpcs, "*-#", 3) == 0)
1628 return atoi (lpcs + 3);
1629
fe7a3057 1630 /* All Windows fonts qualify as Unicode. */
57016d37
JR
1631 if (!strncmp (lpcs, "iso10646", 8))
1632 return DEFAULT_CHARSET;
1633
1634 /* Handle wildcards by ignoring them; eg. treat "big5*-*" as "big5". */
1635 charset = alloca (len + 1);
1636 strcpy (charset, lpcs);
1637 lpcs = strchr (charset, '*');
1638 if (lpcs)
1639 *lpcs = '\0';
1640
1641 /* Look through w32-charset-info-alist for the character set.
1642 Format of each entry is
1643 (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
1644 */
1645 this_entry = Fassoc (build_string (charset), Vw32_charset_info_alist);
1646
1647 if (NILP (this_entry))
1648 {
1649 /* At startup, we want iso8859-1 fonts to come up properly. */
1650 if (xstrcasecmp (charset, "iso8859-1") == 0)
1651 return ANSI_CHARSET;
1652 else
1653 return DEFAULT_CHARSET;
1654 }
1655
1656 w32_charset = Fcar (Fcdr (this_entry));
1657
1658 /* Translate Lisp symbol to number. */
1659 if (EQ (w32_charset, Qw32_charset_ansi))
1660 return ANSI_CHARSET;
1661 if (EQ (w32_charset, Qw32_charset_symbol))
1662 return SYMBOL_CHARSET;
1663 if (EQ (w32_charset, Qw32_charset_shiftjis))
1664 return SHIFTJIS_CHARSET;
1665 if (EQ (w32_charset, Qw32_charset_hangeul))
1666 return HANGEUL_CHARSET;
1667 if (EQ (w32_charset, Qw32_charset_chinesebig5))
1668 return CHINESEBIG5_CHARSET;
1669 if (EQ (w32_charset, Qw32_charset_gb2312))
1670 return GB2312_CHARSET;
1671 if (EQ (w32_charset, Qw32_charset_oem))
1672 return OEM_CHARSET;
1673 if (EQ (w32_charset, Qw32_charset_johab))
1674 return JOHAB_CHARSET;
1675 if (EQ (w32_charset, Qw32_charset_easteurope))
1676 return EASTEUROPE_CHARSET;
1677 if (EQ (w32_charset, Qw32_charset_turkish))
1678 return TURKISH_CHARSET;
1679 if (EQ (w32_charset, Qw32_charset_baltic))
1680 return BALTIC_CHARSET;
1681 if (EQ (w32_charset, Qw32_charset_russian))
1682 return RUSSIAN_CHARSET;
1683 if (EQ (w32_charset, Qw32_charset_arabic))
1684 return ARABIC_CHARSET;
1685 if (EQ (w32_charset, Qw32_charset_greek))
1686 return GREEK_CHARSET;
1687 if (EQ (w32_charset, Qw32_charset_hebrew))
1688 return HEBREW_CHARSET;
1689 if (EQ (w32_charset, Qw32_charset_vietnamese))
1690 return VIETNAMESE_CHARSET;
1691 if (EQ (w32_charset, Qw32_charset_thai))
1692 return THAI_CHARSET;
1693 if (EQ (w32_charset, Qw32_charset_mac))
1694 return MAC_CHARSET;
1695
1696 return DEFAULT_CHARSET;
1697}
1698
1699
f7a84cb4 1700/* Convert a Lisp font registry (symbol) to a windows charset. */
20399669 1701static LONG
b56ceb92 1702registry_to_w32_charset (Lisp_Object charset)
f7a84cb4
JR
1703{
1704 if (EQ (charset, Qiso10646_1) || EQ (charset, Qunicode_bmp)
1705 || EQ (charset, Qunicode_sip))
1706 return DEFAULT_CHARSET; /* UNICODE_CHARSET not defined in MingW32 */
1707 else if (EQ (charset, Qiso8859_1))
1708 return ANSI_CHARSET;
040fe918
JR
1709 else if (SYMBOLP (charset))
1710 return x_to_w32_charset (SDATA (SYMBOL_NAME (charset)));
f7a84cb4
JR
1711 else
1712 return DEFAULT_CHARSET;
1713}
1714
57016d37
JR
1715/* Old function to convert from w32 to x charset, from w32fns.c. */
1716static char *
b56ceb92 1717w32_to_x_charset (int fncharset, char *matching)
57016d37
JR
1718{
1719 static char buf[32];
1720 Lisp_Object charset_type;
1721 int match_len = 0;
1722
1723 if (matching)
1724 {
1725 /* If fully specified, accept it as it is. Otherwise use a
1726 substring match. */
1727 char *wildcard = strchr (matching, '*');
1728 if (wildcard)
1729 *wildcard = '\0';
1730 else if (strchr (matching, '-'))
1731 return matching;
1732
1733 match_len = strlen (matching);
1734 }
1735
1736 switch (fncharset)
1737 {
1738 case ANSI_CHARSET:
1739 /* Handle startup case of w32-charset-info-alist not
1740 being set up yet. */
1741 if (NILP (Vw32_charset_info_alist))
1742 return "iso8859-1";
1743 charset_type = Qw32_charset_ansi;
1744 break;
1745 case DEFAULT_CHARSET:
1746 charset_type = Qw32_charset_default;
1747 break;
1748 case SYMBOL_CHARSET:
1749 charset_type = Qw32_charset_symbol;
1750 break;
1751 case SHIFTJIS_CHARSET:
1752 charset_type = Qw32_charset_shiftjis;
1753 break;
1754 case HANGEUL_CHARSET:
1755 charset_type = Qw32_charset_hangeul;
1756 break;
1757 case GB2312_CHARSET:
1758 charset_type = Qw32_charset_gb2312;
1759 break;
1760 case CHINESEBIG5_CHARSET:
1761 charset_type = Qw32_charset_chinesebig5;
1762 break;
1763 case OEM_CHARSET:
1764 charset_type = Qw32_charset_oem;
1765 break;
1766 case EASTEUROPE_CHARSET:
1767 charset_type = Qw32_charset_easteurope;
1768 break;
1769 case TURKISH_CHARSET:
1770 charset_type = Qw32_charset_turkish;
1771 break;
1772 case BALTIC_CHARSET:
1773 charset_type = Qw32_charset_baltic;
1774 break;
1775 case RUSSIAN_CHARSET:
1776 charset_type = Qw32_charset_russian;
1777 break;
1778 case ARABIC_CHARSET:
1779 charset_type = Qw32_charset_arabic;
1780 break;
1781 case GREEK_CHARSET:
1782 charset_type = Qw32_charset_greek;
1783 break;
1784 case HEBREW_CHARSET:
1785 charset_type = Qw32_charset_hebrew;
1786 break;
1787 case VIETNAMESE_CHARSET:
1788 charset_type = Qw32_charset_vietnamese;
1789 break;
1790 case THAI_CHARSET:
1791 charset_type = Qw32_charset_thai;
1792 break;
1793 case MAC_CHARSET:
1794 charset_type = Qw32_charset_mac;
1795 break;
1796 case JOHAB_CHARSET:
1797 charset_type = Qw32_charset_johab;
1798 break;
1799
1800 default:
1801 /* Encode numerical value of unknown charset. */
1802 sprintf (buf, "*-#%u", fncharset);
1803 return buf;
1804 }
1805
1806 {
1807 Lisp_Object rest;
1808 char * best_match = NULL;
1809 int matching_found = 0;
1810
1811 /* Look through w32-charset-info-alist for the character set.
1812 Prefer ISO codepages, and prefer lower numbers in the ISO
1813 range. Only return charsets for codepages which are installed.
1814
1815 Format of each entry is
1816 (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
1817 */
1818 for (rest = Vw32_charset_info_alist; CONSP (rest); rest = XCDR (rest))
1819 {
1820 char * x_charset;
1821 Lisp_Object w32_charset;
1822 Lisp_Object codepage;
1823
1824 Lisp_Object this_entry = XCAR (rest);
1825
1826 /* Skip invalid entries in alist. */
1827 if (!CONSP (this_entry) || !STRINGP (XCAR (this_entry))
1828 || !CONSP (XCDR (this_entry))
1829 || !SYMBOLP (XCAR (XCDR (this_entry))))
1830 continue;
1831
1832 x_charset = SDATA (XCAR (this_entry));
1833 w32_charset = XCAR (XCDR (this_entry));
1834 codepage = XCDR (XCDR (this_entry));
1835
1836 /* Look for Same charset and a valid codepage (or non-int
1837 which means ignore). */
1838 if (EQ (w32_charset, charset_type)
1839 && (!INTEGERP (codepage) || XINT (codepage) == CP_DEFAULT
1840 || IsValidCodePage (XINT (codepage))))
1841 {
1842 /* If we don't have a match already, then this is the
1843 best. */
1844 if (!best_match)
1845 {
1846 best_match = x_charset;
1847 if (matching && !strnicmp (x_charset, matching, match_len))
1848 matching_found = 1;
1849 }
1850 /* If we already found a match for MATCHING, then
1851 only consider other matches. */
1852 else if (matching_found
1853 && strnicmp (x_charset, matching, match_len))
1854 continue;
1855 /* If this matches what we want, and the best so far doesn't,
1856 then this is better. */
1857 else if (!matching_found && matching
1858 && !strnicmp (x_charset, matching, match_len))
1859 {
1860 best_match = x_charset;
1861 matching_found = 1;
1862 }
1863 /* If this is fully specified, and the best so far isn't,
1864 then this is better. */
1865 else if ((!strchr (best_match, '-') && strchr (x_charset, '-'))
1866 /* If this is an ISO codepage, and the best so far isn't,
1867 then this is better, but only if it fully specifies the
1868 encoding. */
1869 || (strnicmp (best_match, "iso", 3) != 0
1870 && strnicmp (x_charset, "iso", 3) == 0
1871 && strchr (x_charset, '-')))
1872 best_match = x_charset;
1873 /* If both are ISO8859 codepages, choose the one with the
1874 lowest number in the encoding field. */
1875 else if (strnicmp (best_match, "iso8859-", 8) == 0
1876 && strnicmp (x_charset, "iso8859-", 8) == 0)
1877 {
1878 int best_enc = atoi (best_match + 8);
1879 int this_enc = atoi (x_charset + 8);
1880 if (this_enc > 0 && this_enc < best_enc)
1881 best_match = x_charset;
1882 }
1883 }
1884 }
1885
1886 /* If no match, encode the numeric value. */
1887 if (!best_match)
1888 {
1889 sprintf (buf, "*-#%u", fncharset);
1890 return buf;
1891 }
1892
1893 strncpy (buf, best_match, 31);
1894 /* If the charset is not fully specified, put -0 on the end. */
1895 if (!strchr (best_match, '-'))
1896 {
1897 int pos = strlen (best_match);
1898 /* Charset specifiers shouldn't be very long. If it is a made
1899 up one, truncating it should not do any harm since it isn't
1900 recognized anyway. */
1901 if (pos > 29)
1902 pos = 29;
1903 strcpy (buf + pos, "-0");
1904 }
1905 buf[31] = '\0';
1906 return buf;
1907 }
1908}
1909
20399669 1910static Lisp_Object
b56ceb92 1911w32_registry (LONG w32_charset, DWORD font_type)
f7a84cb4 1912{
aee986fd
JR
1913 char *charset;
1914
fe7a3057 1915 /* If charset is defaulted, charset is Unicode or unknown, depending on
aee986fd 1916 font type. */
c960bff8 1917 if (w32_charset == DEFAULT_CHARSET)
aee986fd 1918 return font_type == TRUETYPE_FONTTYPE ? Qiso10646_1 : Qunknown;
c960bff8 1919
aee986fd 1920 charset = w32_to_x_charset (w32_charset, NULL);
ed3751c8 1921 return font_intern_prop (charset, strlen (charset), 1);
f7a84cb4
JR
1922}
1923
5f18d119 1924static int
b56ceb92 1925w32_decode_weight (int fnweight)
5f18d119
KH
1926{
1927 if (fnweight >= FW_HEAVY) return 210;
1928 if (fnweight >= FW_EXTRABOLD) return 205;
1929 if (fnweight >= FW_BOLD) return 200;
1930 if (fnweight >= FW_SEMIBOLD) return 180;
1931 if (fnweight >= FW_NORMAL) return 100;
1932 if (fnweight >= FW_LIGHT) return 50;
1933 if (fnweight >= FW_EXTRALIGHT) return 40;
9d4f32e8 1934 if (fnweight > FW_THIN) return 20;
5f18d119
KH
1935 return 0;
1936}
1937
1938static int
b56ceb92 1939w32_encode_weight (int n)
5f18d119
KH
1940{
1941 if (n >= 210) return FW_HEAVY;
1942 if (n >= 205) return FW_EXTRABOLD;
1943 if (n >= 200) return FW_BOLD;
1944 if (n >= 180) return FW_SEMIBOLD;
1945 if (n >= 100) return FW_NORMAL;
1946 if (n >= 50) return FW_LIGHT;
1947 if (n >= 40) return FW_EXTRALIGHT;
9d4f32e8 1948 if (n >= 20) return FW_THIN;
5f18d119
KH
1949 return 0;
1950}
1951
3ef8c1b4
JR
1952/* Convert a Windows font weight into one of the weights supported
1953 by fontconfig (see font.c:font_parse_fcname). */
1954static Lisp_Object
b56ceb92 1955w32_to_fc_weight (int n)
3ef8c1b4
JR
1956{
1957 if (n >= FW_EXTRABOLD) return intern ("black");
9d4f32e8
JB
1958 if (n >= FW_BOLD) return intern ("bold");
1959 if (n >= FW_SEMIBOLD) return intern ("demibold");
1960 if (n >= FW_NORMAL) return intern ("medium");
3ef8c1b4
JR
1961 return intern ("light");
1962}
1963
f7a84cb4 1964/* Fill in all the available details of LOGFONT from FONT_SPEC. */
20399669 1965static void
a10c8269 1966fill_in_logfont (struct frame *f, LOGFONT *logfont, Lisp_Object font_spec)
f7a84cb4 1967{
d205d43b 1968 Lisp_Object tmp, extra;
42143acd 1969 int dpi = FRAME_RES_Y (f);
f7a84cb4 1970
5f18d119
KH
1971 tmp = AREF (font_spec, FONT_DPI_INDEX);
1972 if (INTEGERP (tmp))
d205d43b 1973 {
5f18d119
KH
1974 dpi = XINT (tmp);
1975 }
1976 else if (FLOATP (tmp))
1977 {
1978 dpi = (int) (XFLOAT_DATA (tmp) + 0.5);
d205d43b 1979 }
f7a84cb4
JR
1980
1981 /* Height */
1982 tmp = AREF (font_spec, FONT_SIZE_INDEX);
1983 if (INTEGERP (tmp))
040fe918 1984 logfont->lfHeight = -1 * XINT (tmp);
f7a84cb4 1985 else if (FLOATP (tmp))
d205d43b 1986 logfont->lfHeight = (int) (-1.0 * dpi * XFLOAT_DATA (tmp) / 72.27 + 0.5);
f7a84cb4
JR
1987
1988 /* Escapement */
1989
1990 /* Orientation */
1991
1992 /* Weight */
1993 tmp = AREF (font_spec, FONT_WEIGHT_INDEX);
1994 if (INTEGERP (tmp))
5f18d119 1995 logfont->lfWeight = w32_encode_weight (FONT_WEIGHT_NUMERIC (font_spec));
f7a84cb4
JR
1996
1997 /* Italic */
1998 tmp = AREF (font_spec, FONT_SLANT_INDEX);
1999 if (INTEGERP (tmp))
2000 {
5f18d119 2001 int slant = FONT_SLANT_NUMERIC (font_spec);
f7a84cb4
JR
2002 logfont->lfItalic = slant > 150 ? 1 : 0;
2003 }
2004
2005 /* Underline */
2006
2007 /* Strikeout */
2008
2009 /* Charset */
2010 tmp = AREF (font_spec, FONT_REGISTRY_INDEX);
2011 if (! NILP (tmp))
d205d43b 2012 logfont->lfCharSet = registry_to_w32_charset (tmp);
56df6710
JR
2013 else
2014 logfont->lfCharSet = DEFAULT_CHARSET;
f7a84cb4
JR
2015
2016 /* Out Precision */
91583281 2017
f7a84cb4 2018 /* Clip Precision */
91583281
JR
2019
2020 /* Quality */
040fe918
JR
2021 logfont->lfQuality = DEFAULT_QUALITY;
2022
d205d43b
JR
2023 /* Generic Family and Face Name */
2024 logfont->lfPitchAndFamily = FF_DONTCARE | DEFAULT_PITCH;
2025
f7a84cb4 2026 tmp = AREF (font_spec, FONT_FAMILY_INDEX);
d205d43b
JR
2027 if (! NILP (tmp))
2028 {
2029 logfont->lfPitchAndFamily = w32_generic_family (tmp) | DEFAULT_PITCH;
2030 if ((logfont->lfPitchAndFamily & 0xF0) != FF_DONTCARE)
2031 ; /* Font name was generic, don't fill in font name. */
2032 /* Font families are interned, but allow for strings also in case of
2033 user input. */
2034 else if (SYMBOLP (tmp))
bf98199c
JM
2035 {
2036 strncpy (logfont->lfFaceName,
2037 SDATA (ENCODE_SYSTEM (SYMBOL_NAME (tmp))), LF_FACESIZE);
2038 logfont->lfFaceName[LF_FACESIZE-1] = '\0';
2039 }
d205d43b 2040 }
f7a84cb4 2041
9e1a2995
JR
2042 tmp = AREF (font_spec, FONT_ADSTYLE_INDEX);
2043 if (!NILP (tmp))
2044 {
2045 /* Override generic family. */
2046 BYTE family = w32_generic_family (tmp);
2047 if (family != FF_DONTCARE)
2048 logfont->lfPitchAndFamily = family | DEFAULT_PITCH;
2049 }
2050
5f18d119
KH
2051 /* Set pitch based on the spacing property. */
2052 tmp = AREF (font_spec, FONT_SPACING_INDEX);
2053 if (INTEGERP (tmp))
2054 {
2055 int spacing = XINT (tmp);
2056 if (spacing < FONT_SPACING_MONO)
2057 logfont->lfPitchAndFamily
657d08d3 2058 = (logfont->lfPitchAndFamily & 0xF0) | VARIABLE_PITCH;
5f18d119
KH
2059 else
2060 logfont->lfPitchAndFamily
657d08d3 2061 = (logfont->lfPitchAndFamily & 0xF0) | FIXED_PITCH;
5f18d119
KH
2062 }
2063
d205d43b 2064 /* Process EXTRA info. */
5f18d119
KH
2065 for (extra = AREF (font_spec, FONT_EXTRA_INDEX);
2066 CONSP (extra); extra = XCDR (extra))
d205d43b
JR
2067 {
2068 tmp = XCAR (extra);
2069 if (CONSP (tmp))
2070 {
2071 Lisp_Object key, val;
2072 key = XCAR (tmp), val = XCDR (tmp);
fe7a3057 2073 /* Only use QCscript if charset is not provided, or is Unicode
d205d43b
JR
2074 and a single script is specified. This is rather crude,
2075 and is only used to narrow down the fonts returned where
2076 there is a definite match. Some scripts, such as latin, han,
2077 cjk-misc match multiple lfCharSet values, so we can't pre-filter
2078 them. */
5f18d119 2079 if (EQ (key, QCscript)
d205d43b
JR
2080 && logfont->lfCharSet == DEFAULT_CHARSET
2081 && SYMBOLP (val))
2082 {
2083 if (EQ (val, Qgreek))
2084 logfont->lfCharSet = GREEK_CHARSET;
2085 else if (EQ (val, Qhangul))
2086 logfont->lfCharSet = HANGUL_CHARSET;
2087 else if (EQ (val, Qkana) || EQ (val, Qkanbun))
2088 logfont->lfCharSet = SHIFTJIS_CHARSET;
2089 else if (EQ (val, Qbopomofo))
2090 logfont->lfCharSet = CHINESEBIG5_CHARSET;
2091 /* GB 18030 supports tibetan, yi, mongolian,
2092 fonts that support it should show up if we ask for
2093 GB2312 fonts. */
2094 else if (EQ (val, Qtibetan) || EQ (val, Qyi)
2095 || EQ (val, Qmongolian))
2096 logfont->lfCharSet = GB2312_CHARSET;
2097 else if (EQ (val, Qhebrew))
2098 logfont->lfCharSet = HEBREW_CHARSET;
2099 else if (EQ (val, Qarabic))
2100 logfont->lfCharSet = ARABIC_CHARSET;
2101 else if (EQ (val, Qthai))
2102 logfont->lfCharSet = THAI_CHARSET;
d205d43b 2103 }
91583281
JR
2104 else if (EQ (key, QCantialias) && SYMBOLP (val))
2105 {
2106 logfont->lfQuality = w32_antialias_type (val);
2107 }
d205d43b
JR
2108 }
2109 }
f7a84cb4
JR
2110}
2111
20399669 2112static void
b56ceb92 2113list_all_matching_fonts (struct font_callback_data *match_data)
f7a84cb4
JR
2114{
2115 HDC dc;
fdb396e2 2116 Lisp_Object families = w32font_list_family (XFRAME (match_data->frame));
d205d43b 2117 struct frame *f = XFRAME (match_data->frame);
f7a84cb4
JR
2118
2119 dc = get_frame_dc (f);
2120
2121 while (!NILP (families))
2122 {
e6df5336
JR
2123 /* Only fonts from the current locale are given localized names
2124 on Windows, so we can keep backwards compatibility with
2125 Windows 9x/ME by using non-Unicode font enumeration without
2126 sacrificing internationalization here. */
d205d43b 2127 char *name;
f7a84cb4
JR
2128 Lisp_Object family = CAR (families);
2129 families = CDR (families);
d205d43b
JR
2130 if (NILP (family))
2131 continue;
8f112d52 2132 else if (SYMBOLP (family))
e6df5336 2133 name = SDATA (ENCODE_SYSTEM (SYMBOL_NAME (family)));
8f112d52
JR
2134 else
2135 continue;
d205d43b
JR
2136
2137 strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE);
2138 match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0';
2139
2140 EnumFontFamiliesEx (dc, &match_data->pattern,
2141 (FONTENUMPROC) add_font_entity_to_list,
2142 (LPARAM) match_data, 0);
f7a84cb4
JR
2143 }
2144
2145 release_frame_dc (f, dc);
2146}
2147
91583281 2148static Lisp_Object
b56ceb92 2149lispy_antialias_type (BYTE type)
91583281
JR
2150{
2151 Lisp_Object lispy;
2152
2153 switch (type)
2154 {
2155 case NONANTIALIASED_QUALITY:
2156 lispy = Qnone;
2157 break;
2158 case ANTIALIASED_QUALITY:
2159 lispy = Qstandard;
2160 break;
2161 case CLEARTYPE_QUALITY:
2162 lispy = Qsubpixel;
2163 break;
2164 case CLEARTYPE_NATURAL_QUALITY:
2165 lispy = Qnatural;
2166 break;
2167 default:
2168 lispy = Qnil;
2169 break;
2170 }
2171 return lispy;
2172}
2173
2174/* Convert antialiasing symbols to lfQuality */
2175static BYTE
b56ceb92 2176w32_antialias_type (Lisp_Object type)
91583281
JR
2177{
2178 if (EQ (type, Qnone))
2179 return NONANTIALIASED_QUALITY;
2180 else if (EQ (type, Qstandard))
2181 return ANTIALIASED_QUALITY;
2182 else if (EQ (type, Qsubpixel))
2183 return CLEARTYPE_QUALITY;
2184 else if (EQ (type, Qnatural))
2185 return CLEARTYPE_NATURAL_QUALITY;
2186 else
2187 return DEFAULT_QUALITY;
2188}
2189
d205d43b
JR
2190/* Return a list of all the scripts that the font supports. */
2191static Lisp_Object
2192font_supported_scripts (FONTSIGNATURE * sig)
f7a84cb4 2193{
d205d43b
JR
2194 DWORD * subranges = sig->fsUsb;
2195 Lisp_Object supported = Qnil;
2196
2197 /* Match a single subrange. SYM is set if bit N is set in subranges. */
2198#define SUBRANGE(n,sym) \
2199 if (subranges[(n) / 32] & (1 << ((n) % 32))) \
2200 supported = Fcons ((sym), supported)
2201
2202 /* Match multiple subranges. SYM is set if any MASK bit is set in
2203 subranges[0 - 3]. */
2204#define MASK_ANY(mask0,mask1,mask2,mask3,sym) \
2205 if ((subranges[0] & (mask0)) || (subranges[1] & (mask1)) \
2206 || (subranges[2] & (mask2)) || (subranges[3] & (mask3))) \
2207 supported = Fcons ((sym), supported)
2208
56df6710
JR
2209 SUBRANGE (0, Qlatin);
2210 /* The following count as latin too, ASCII should be present in these fonts,
2211 so don't need to mark them separately. */
2212 /* 1: Latin-1 supplement, 2: Latin Extended A, 3: Latin Extended B. */
2213 SUBRANGE (4, Qphonetic);
dbdb7031 2214 /* 5: Spacing and tone modifiers, 6: Combining Diacritical Marks. */
d205d43b
JR
2215 SUBRANGE (7, Qgreek);
2216 SUBRANGE (8, Qcoptic);
2217 SUBRANGE (9, Qcyrillic);
2218 SUBRANGE (10, Qarmenian);
2219 SUBRANGE (11, Qhebrew);
174f1c74 2220 /* 12: Vai. */
d205d43b
JR
2221 SUBRANGE (13, Qarabic);
2222 SUBRANGE (14, Qnko);
2223 SUBRANGE (15, Qdevanagari);
2224 SUBRANGE (16, Qbengali);
2225 SUBRANGE (17, Qgurmukhi);
2226 SUBRANGE (18, Qgujarati);
2227 SUBRANGE (19, Qoriya);
2228 SUBRANGE (20, Qtamil);
2229 SUBRANGE (21, Qtelugu);
2230 SUBRANGE (22, Qkannada);
2231 SUBRANGE (23, Qmalayalam);
2232 SUBRANGE (24, Qthai);
2233 SUBRANGE (25, Qlao);
2234 SUBRANGE (26, Qgeorgian);
56df6710
JR
2235 SUBRANGE (27, Qbalinese);
2236 /* 28: Hangul Jamo. */
2237 /* 29: Latin Extended, 30: Greek Extended, 31: Punctuation. */
2238 /* 32-47: Symbols (defined below). */
d205d43b 2239 SUBRANGE (48, Qcjk_misc);
56df6710
JR
2240 /* Match either 49: katakana or 50: hiragana for kana. */
2241 MASK_ANY (0, 0x00060000, 0, 0, Qkana);
d205d43b 2242 SUBRANGE (51, Qbopomofo);
56df6710
JR
2243 /* 52: Compatibility Jamo */
2244 SUBRANGE (53, Qphags_pa);
2245 /* 54: Enclosed CJK letters and months, 55: CJK Compatibility. */
d205d43b 2246 SUBRANGE (56, Qhangul);
56df6710
JR
2247 /* 57: Surrogates. */
2248 SUBRANGE (58, Qphoenician);
d205d43b 2249 SUBRANGE (59, Qhan); /* There are others, but this is the main one. */
56df6710
JR
2250 SUBRANGE (59, Qideographic_description); /* Windows lumps this in. */
2251 SUBRANGE (59, Qkanbun); /* And this. */
2252 /* 60: Private use, 61: CJK strokes and compatibility. */
2253 /* 62: Alphabetic Presentation, 63: Arabic Presentation A. */
2254 /* 64: Combining half marks, 65: Vertical and CJK compatibility. */
2255 /* 66: Small forms, 67: Arabic Presentation B, 68: Half and Full width. */
2256 /* 69: Specials. */
d205d43b
JR
2257 SUBRANGE (70, Qtibetan);
2258 SUBRANGE (71, Qsyriac);
2259 SUBRANGE (72, Qthaana);
2260 SUBRANGE (73, Qsinhala);
2261 SUBRANGE (74, Qmyanmar);
2262 SUBRANGE (75, Qethiopic);
2263 SUBRANGE (76, Qcherokee);
2264 SUBRANGE (77, Qcanadian_aboriginal);
2265 SUBRANGE (78, Qogham);
2266 SUBRANGE (79, Qrunic);
2267 SUBRANGE (80, Qkhmer);
2268 SUBRANGE (81, Qmongolian);
2269 SUBRANGE (82, Qbraille);
2270 SUBRANGE (83, Qyi);
56df6710
JR
2271 SUBRANGE (84, Qbuhid);
2272 SUBRANGE (84, Qhanunoo);
2273 SUBRANGE (84, Qtagalog);
2274 SUBRANGE (84, Qtagbanwa);
2275 SUBRANGE (85, Qold_italic);
2276 SUBRANGE (86, Qgothic);
2277 SUBRANGE (87, Qdeseret);
d205d43b
JR
2278 SUBRANGE (88, Qbyzantine_musical_symbol);
2279 SUBRANGE (88, Qmusical_symbol); /* Windows doesn't distinguish these. */
d205d43b 2280 SUBRANGE (89, Qmathematical);
56df6710
JR
2281 /* 90: Private use, 91: Variation selectors, 92: Tags. */
2282 SUBRANGE (93, Qlimbu);
2283 SUBRANGE (94, Qtai_le);
2284 /* 95: New Tai Le */
2285 SUBRANGE (90, Qbuginese);
2286 SUBRANGE (97, Qglagolitic);
2287 SUBRANGE (98, Qtifinagh);
2288 /* 99: Yijing Hexagrams. */
2289 SUBRANGE (100, Qsyloti_nagri);
2290 SUBRANGE (101, Qlinear_b);
2291 /* 102: Ancient Greek Numbers. */
2292 SUBRANGE (103, Qugaritic);
2293 SUBRANGE (104, Qold_persian);
2294 SUBRANGE (105, Qshavian);
2295 SUBRANGE (106, Qosmanya);
2296 SUBRANGE (107, Qcypriot);
2297 SUBRANGE (108, Qkharoshthi);
2298 /* 109: Tai Xuan Jing. */
2299 SUBRANGE (110, Qcuneiform);
174f1c74
JR
2300 /* 111: Counting Rods, 112: Sundanese, 113: Lepcha, 114: Ol Chiki. */
2301 /* 115: Saurashtra, 116: Kayah Li, 117: Rejang. */
2302 SUBRANGE (118, Qcham);
2303 /* 119: Ancient symbols, 120: Phaistos Disc. */
dbdb7031 2304 /* 121: Carian, Lycian, Lydian, 122: Dominoes, Mahjong tiles. */
174f1c74 2305 /* 123-127: Reserved. */
d205d43b
JR
2306
2307 /* There isn't really a main symbol range, so include symbol if any
2308 relevant range is set. */
2309 MASK_ANY (0x8000000, 0x0000FFFF, 0, 0, Qsymbol);
2310
174f1c74 2311 /* Missing: Tai Viet (U+AA80-U+AADF). */
d205d43b
JR
2312#undef SUBRANGE
2313#undef MASK_ANY
2314
2315 return supported;
f7a84cb4
JR
2316}
2317
67997c79
JR
2318/* Generate a full name for a Windows font.
2319 The full name is in fcname format, with weight, slant and antialiasing
2320 specified if they are not "normal". */
2321static int
b56ceb92
JB
2322w32font_full_name (LOGFONT * font, Lisp_Object font_obj,
2323 int pixel_size, char *name, int nbytes)
67997c79 2324{
a823468b 2325 int len, height, outline;
67997c79
JR
2326 char *p;
2327 Lisp_Object antialiasing, weight = Qnil;
2328
a823468b
JR
2329 len = strlen (font->lfFaceName);
2330
2331 outline = EQ (AREF (font_obj, FONT_FOUNDRY_INDEX), Qoutline);
2332
2333 /* Represent size of scalable fonts by point size. But use pixelsize for
2334 raster fonts to indicate that they are exactly that size. */
2335 if (outline)
2336 len += 11; /* -SIZE */
2337 else
6fe9826d 2338 len += 21;
67997c79
JR
2339
2340 if (font->lfItalic)
2341 len += 7; /* :italic */
2342
2343 if (font->lfWeight && font->lfWeight != FW_NORMAL)
2344 {
3ef8c1b4
JR
2345 weight = w32_to_fc_weight (font->lfWeight);
2346 len += 1 + SBYTES (SYMBOL_NAME (weight)); /* :WEIGHT */
67997c79
JR
2347 }
2348
2349 antialiasing = lispy_antialias_type (font->lfQuality);
2350 if (! NILP (antialiasing))
2351 len += 11 + SBYTES (SYMBOL_NAME (antialiasing)); /* :antialias=NAME */
2352
2353 /* Check that the buffer is big enough */
2354 if (len > nbytes)
2355 return -1;
2356
2357 p = name;
2358 p += sprintf (p, "%s", font->lfFaceName);
2359
a823468b
JR
2360 height = font->lfHeight ? eabs (font->lfHeight) : pixel_size;
2361
2362 if (height > 0)
2363 {
2364 if (outline)
2365 {
2366 float pointsize = height * 72.0 / one_w32_display_info.resy;
7145be81
JR
2367 /* Round to nearest half point. floor is used, since round is not
2368 supported in MS library. */
2369 pointsize = floor (pointsize * 2 + 0.5) / 2;
a823468b
JR
2370 p += sprintf (p, "-%1.1f", pointsize);
2371 }
2372 else
2373 p += sprintf (p, ":pixelsize=%d", height);
2374 }
67997c79 2375
3ef8c1b4
JR
2376 if (SYMBOLP (weight) && ! NILP (weight))
2377 p += sprintf (p, ":%s", SDATA (SYMBOL_NAME (weight)));
2378
67997c79
JR
2379 if (font->lfItalic)
2380 p += sprintf (p, ":italic");
2381
67997c79
JR
2382 if (SYMBOLP (antialiasing) && ! NILP (antialiasing))
2383 p += sprintf (p, ":antialias=%s", SDATA (SYMBOL_NAME (antialiasing)));
2384
2385 return (p - name);
2386}
f7a84cb4 2387
6fe9826d
JR
2388/* Convert a logfont and point size into a fontconfig style font name.
2389 POINTSIZE is in tenths of points.
2390 If SIZE indicates the size of buffer FCNAME, into which the font name
2391 is written. If the buffer is not large enough to contain the name,
2392 the function returns -1, otherwise it returns the number of bytes
2393 written to FCNAME. */
b56ceb92
JB
2394static int
2395logfont_to_fcname (LOGFONT* font, int pointsize, char *fcname, int size)
6fe9826d
JR
2396{
2397 int len, height;
2398 char *p = fcname;
2399 Lisp_Object weight = Qnil;
2400
2401 len = strlen (font->lfFaceName) + 2;
2402 height = pointsize / 10;
2403 while (height /= 10)
2404 len++;
2405
2406 if (pointsize % 10)
2407 len += 2;
2408
2409 if (font->lfItalic)
2410 len += 7; /* :italic */
2411 if (font->lfWeight && font->lfWeight != FW_NORMAL)
2412 {
3ef8c1b4
JR
2413 weight = w32_to_fc_weight (font->lfWeight);
2414 len += SBYTES (SYMBOL_NAME (weight)) + 1;
6fe9826d
JR
2415 }
2416
2417 if (len > size)
2418 return -1;
2419
2420 p += sprintf (p, "%s-%d", font->lfFaceName, pointsize / 10);
2421 if (pointsize % 10)
2422 p += sprintf (p, ".%d", pointsize % 10);
2423
3ef8c1b4
JR
2424 if (SYMBOLP (weight) && !NILP (weight))
2425 p += sprintf (p, ":%s", SDATA (SYMBOL_NAME (weight)));
2426
6fe9826d
JR
2427 if (font->lfItalic)
2428 p += sprintf (p, ":italic");
2429
6fe9826d
JR
2430 return (p - fcname);
2431}
34fd2d28 2432
9c623c85 2433static void
b56ceb92
JB
2434compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
2435 struct w32_metric_cache *metrics)
34fd2d28
JR
2436{
2437 GLYPHMETRICS gm;
2438 MAT2 transform;
8f112d52
JR
2439 unsigned int options = GGO_METRICS;
2440
2441 if (w32_font->glyph_idx)
2442 options |= GGO_GLYPH_INDEX;
34fd2d28 2443
72af86bd 2444 memset (&transform, 0, sizeof (transform));
34fd2d28
JR
2445 transform.eM11.value = 1;
2446 transform.eM22.value = 1;
8f112d52 2447
db4f02f2 2448 if (get_glyph_outline_w (dc, code, options, &gm, 0, NULL, &transform)
8f112d52
JR
2449 != GDI_ERROR)
2450 {
2451 metrics->lbearing = gm.gmptGlyphOrigin.x;
2452 metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
2453 metrics->width = gm.gmCellIncX;
2454 metrics->status = W32METRIC_SUCCESS;
2455 }
9c623c85
JB
2456 else
2457 metrics->status = W32METRIC_FAIL;
34fd2d28
JR
2458}
2459
6fe9826d
JR
2460DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
2461 doc: /* Read a font name using a W32 font selection dialog.
2462Return fontconfig style font string corresponding to the selection.
2463
2464If FRAME is omitted or nil, it defaults to the selected frame.
1ada3dab 2465If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts
6fe9826d 2466in the font selection dialog. */)
5842a27b 2467 (Lisp_Object frame, Lisp_Object exclude_proportional)
6fe9826d 2468{
a10c8269 2469 struct frame *f = decode_window_system_frame (frame);
6fe9826d
JR
2470 CHOOSEFONT cf;
2471 LOGFONT lf;
2472 TEXTMETRIC tm;
2473 HDC hdc;
2474 HANDLE oldobj;
2475 char buf[100];
2476
72af86bd
AS
2477 memset (&cf, 0, sizeof (cf));
2478 memset (&lf, 0, sizeof (lf));
6fe9826d
JR
2479
2480 cf.lStructSize = sizeof (cf);
2481 cf.hwndOwner = FRAME_W32_WINDOW (f);
2482 cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS | CF_NOVERTFONTS;
2483
1ada3dab 2484 /* If exclude_proportional is non-nil, limit the selection to
6fe9826d 2485 monospaced fonts. */
1ada3dab 2486 if (!NILP (exclude_proportional))
6fe9826d
JR
2487 cf.Flags |= CF_FIXEDPITCHONLY;
2488
2489 cf.lpLogFont = &lf;
2490
2491 /* Initialize as much of the font details as we can from the current
2492 default font. */
2493 hdc = GetDC (FRAME_W32_WINDOW (f));
c35f9821 2494 oldobj = SelectObject (hdc, FONT_HANDLE (FRAME_FONT (f)));
6fe9826d
JR
2495 GetTextFace (hdc, LF_FACESIZE, lf.lfFaceName);
2496 if (GetTextMetrics (hdc, &tm))
2497 {
2498 lf.lfHeight = tm.tmInternalLeading - tm.tmHeight;
2499 lf.lfWeight = tm.tmWeight;
2500 lf.lfItalic = tm.tmItalic;
2501 lf.lfUnderline = tm.tmUnderlined;
2502 lf.lfStrikeOut = tm.tmStruckOut;
2503 lf.lfCharSet = tm.tmCharSet;
2504 cf.Flags |= CF_INITTOLOGFONTSTRUCT;
2505 }
2506 SelectObject (hdc, oldobj);
2507 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
2508
2509 if (!ChooseFont (&cf)
2510 || logfont_to_fcname (&lf, cf.iPointSize, buf, 100) < 0)
2511 return Qnil;
2512
e6df5336 2513 return DECODE_SYSTEM (build_string (buf));
6fe9826d
JR
2514}
2515
3106121c 2516static const char *const w32font_booleans [] = {
9fa82824
DP
2517 NULL,
2518};
2519
3106121c 2520static const char *const w32font_non_booleans [] = {
9fa82824
DP
2521 ":script",
2522 ":antialias",
2523 ":style",
2524 NULL,
2525};
2526
2527static void
220d91b8 2528w32font_filter_properties (Lisp_Object font, Lisp_Object alist)
9fa82824
DP
2529{
2530 font_filter_properties (font, alist, w32font_booleans, w32font_non_booleans);
2531}
2532
f7a84cb4
JR
2533struct font_driver w32font_driver =
2534 {
8eac0c84 2535 0, /* Qgdi */
5f18d119 2536 0, /* case insensitive */
f7a84cb4
JR
2537 w32font_get_cache,
2538 w32font_list,
2539 w32font_match,
2540 w32font_list_family,
2541 NULL, /* free_entity */
2542 w32font_open,
2543 w32font_close,
2544 NULL, /* prepare_face */
2545 NULL, /* done_face */
2546 w32font_has_char,
2547 w32font_encode_char,
2548 w32font_text_extents,
2549 w32font_draw,
2550 NULL, /* get_bitmap */
2551 NULL, /* free_bitmap */
2552 NULL, /* get_outline */
2553 NULL, /* free_outline */
2554 NULL, /* anchor_point */
2555 NULL, /* otf_capability */
5b0c3446
JR
2556 NULL, /* otf_drive */
2557 NULL, /* start_for_frame */
2558 NULL, /* end_for_frame */
637fa988
JD
2559 NULL, /* shape */
2560 NULL, /* check */
2561 NULL, /* get_variation_glyphs */
9fa82824 2562 w32font_filter_properties,
9c88f339 2563 NULL, /* cached_font_ok */
f7a84cb4
JR
2564 };
2565
f7a84cb4
JR
2566
2567/* Initialize state that does not change between invocations. This is only
2568 called when Emacs is dumped. */
20399669 2569void
b56ceb92 2570syms_of_w32font (void)
f7a84cb4 2571{
8eac0c84 2572 DEFSYM (Qgdi, "gdi");
34fd2d28
JR
2573 DEFSYM (Quniscribe, "uniscribe");
2574 DEFSYM (QCformat, ":format");
d205d43b
JR
2575
2576 /* Generic font families. */
2577 DEFSYM (Qmonospace, "monospace");
2578 DEFSYM (Qserif, "serif");
9e1a2995 2579 DEFSYM (Qsansserif, "sansserif");
f7a84cb4 2580 DEFSYM (Qscript, "script");
d205d43b
JR
2581 DEFSYM (Qdecorative, "decorative");
2582 /* Aliases. */
9e1a2995 2583 DEFSYM (Qsans_serif, "sans_serif");
d205d43b
JR
2584 DEFSYM (Qsans, "sans");
2585 DEFSYM (Qmono, "mono");
2586
2587 /* Fake foundries. */
2588 DEFSYM (Qraster, "raster");
2589 DEFSYM (Qoutline, "outline");
f7a84cb4 2590 DEFSYM (Qunknown, "unknown");
d205d43b 2591
91583281
JR
2592 /* Antialiasing. */
2593 DEFSYM (Qstandard, "standard");
2594 DEFSYM (Qsubpixel, "subpixel");
2595 DEFSYM (Qnatural, "natural");
d205d43b 2596
8f112d52 2597 /* Languages */
8f112d52
JR
2598 DEFSYM (Qzh, "zh");
2599
d205d43b
JR
2600 /* Scripts */
2601 DEFSYM (Qlatin, "latin");
2602 DEFSYM (Qgreek, "greek");
2603 DEFSYM (Qcoptic, "coptic");
2604 DEFSYM (Qcyrillic, "cyrillic");
2605 DEFSYM (Qarmenian, "armenian");
2606 DEFSYM (Qhebrew, "hebrew");
2607 DEFSYM (Qarabic, "arabic");
2608 DEFSYM (Qsyriac, "syriac");
2609 DEFSYM (Qnko, "nko");
2610 DEFSYM (Qthaana, "thaana");
2611 DEFSYM (Qdevanagari, "devanagari");
2612 DEFSYM (Qbengali, "bengali");
2613 DEFSYM (Qgurmukhi, "gurmukhi");
2614 DEFSYM (Qgujarati, "gujarati");
2615 DEFSYM (Qoriya, "oriya");
2616 DEFSYM (Qtamil, "tamil");
2617 DEFSYM (Qtelugu, "telugu");
2618 DEFSYM (Qkannada, "kannada");
2619 DEFSYM (Qmalayalam, "malayalam");
2620 DEFSYM (Qsinhala, "sinhala");
2621 DEFSYM (Qthai, "thai");
2622 DEFSYM (Qlao, "lao");
2623 DEFSYM (Qtibetan, "tibetan");
2624 DEFSYM (Qmyanmar, "myanmar");
2625 DEFSYM (Qgeorgian, "georgian");
2626 DEFSYM (Qhangul, "hangul");
2627 DEFSYM (Qethiopic, "ethiopic");
2628 DEFSYM (Qcherokee, "cherokee");
2629 DEFSYM (Qcanadian_aboriginal, "canadian-aboriginal");
2630 DEFSYM (Qogham, "ogham");
2631 DEFSYM (Qrunic, "runic");
2632 DEFSYM (Qkhmer, "khmer");
2633 DEFSYM (Qmongolian, "mongolian");
d205d43b
JR
2634 DEFSYM (Qbraille, "braille");
2635 DEFSYM (Qhan, "han");
2636 DEFSYM (Qideographic_description, "ideographic-description");
2637 DEFSYM (Qcjk_misc, "cjk-misc");
2638 DEFSYM (Qkana, "kana");
2639 DEFSYM (Qbopomofo, "bopomofo");
2640 DEFSYM (Qkanbun, "kanbun");
2641 DEFSYM (Qyi, "yi");
2642 DEFSYM (Qbyzantine_musical_symbol, "byzantine-musical-symbol");
2643 DEFSYM (Qmusical_symbol, "musical-symbol");
2644 DEFSYM (Qmathematical, "mathematical");
174f1c74 2645 DEFSYM (Qcham, "cham");
56df6710
JR
2646 DEFSYM (Qphonetic, "phonetic");
2647 DEFSYM (Qbalinese, "balinese");
2648 DEFSYM (Qbuginese, "buginese");
2649 DEFSYM (Qbuhid, "buhid");
2650 DEFSYM (Qcuneiform, "cuneiform");
2651 DEFSYM (Qcypriot, "cypriot");
2652 DEFSYM (Qdeseret, "deseret");
2653 DEFSYM (Qglagolitic, "glagolitic");
2654 DEFSYM (Qgothic, "gothic");
2655 DEFSYM (Qhanunoo, "hanunoo");
2656 DEFSYM (Qkharoshthi, "kharoshthi");
2657 DEFSYM (Qlimbu, "limbu");
2658 DEFSYM (Qlinear_b, "linear_b");
2659 DEFSYM (Qold_italic, "old_italic");
2660 DEFSYM (Qold_persian, "old_persian");
2661 DEFSYM (Qosmanya, "osmanya");
2662 DEFSYM (Qphags_pa, "phags-pa");
2663 DEFSYM (Qphoenician, "phoenician");
2664 DEFSYM (Qshavian, "shavian");
2665 DEFSYM (Qsyloti_nagri, "syloti_nagri");
2666 DEFSYM (Qtagalog, "tagalog");
2667 DEFSYM (Qtagbanwa, "tagbanwa");
2668 DEFSYM (Qtai_le, "tai_le");
2669 DEFSYM (Qtifinagh, "tifinagh");
2670 DEFSYM (Qugaritic, "ugaritic");
d205d43b 2671
57016d37
JR
2672 /* W32 font encodings. */
2673 DEFVAR_LISP ("w32-charset-info-alist",
29208e82 2674 Vw32_charset_info_alist,
57016d37
JR
2675 doc: /* Alist linking Emacs character sets to Windows fonts and codepages.
2676Each entry should be of the form:
2677
2678 (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE))
2679
2680where CHARSET_NAME is a string used in font names to identify the charset,
2681WINDOWS_CHARSET is a symbol that can be one of:
2682
2683 w32-charset-ansi, w32-charset-default, w32-charset-symbol,
2684 w32-charset-shiftjis, w32-charset-hangeul, w32-charset-gb2312,
2685 w32-charset-chinesebig5, w32-charset-johab, w32-charset-hebrew,
2686 w32-charset-arabic, w32-charset-greek, w32-charset-turkish,
2687 w32-charset-vietnamese, w32-charset-thai, w32-charset-easteurope,
2688 w32-charset-russian, w32-charset-mac, w32-charset-baltic,
2689 or w32-charset-oem.
2690
2691CODEPAGE should be an integer specifying the codepage that should be used
2692to display the character set, t to do no translation and output as Unicode,
2693or nil to do no translation and output as 8 bit (or multibyte on far-east
2694versions of Windows) characters. */);
2695 Vw32_charset_info_alist = Qnil;
2696
2697 DEFSYM (Qw32_charset_ansi, "w32-charset-ansi");
2698 DEFSYM (Qw32_charset_symbol, "w32-charset-symbol");
2699 DEFSYM (Qw32_charset_default, "w32-charset-default");
2700 DEFSYM (Qw32_charset_shiftjis, "w32-charset-shiftjis");
2701 DEFSYM (Qw32_charset_hangeul, "w32-charset-hangeul");
2702 DEFSYM (Qw32_charset_chinesebig5, "w32-charset-chinesebig5");
2703 DEFSYM (Qw32_charset_gb2312, "w32-charset-gb2312");
2704 DEFSYM (Qw32_charset_oem, "w32-charset-oem");
2705 DEFSYM (Qw32_charset_johab, "w32-charset-johab");
2706 DEFSYM (Qw32_charset_easteurope, "w32-charset-easteurope");
2707 DEFSYM (Qw32_charset_turkish, "w32-charset-turkish");
2708 DEFSYM (Qw32_charset_baltic, "w32-charset-baltic");
2709 DEFSYM (Qw32_charset_russian, "w32-charset-russian");
2710 DEFSYM (Qw32_charset_arabic, "w32-charset-arabic");
2711 DEFSYM (Qw32_charset_greek, "w32-charset-greek");
2712 DEFSYM (Qw32_charset_hebrew, "w32-charset-hebrew");
2713 DEFSYM (Qw32_charset_vietnamese, "w32-charset-vietnamese");
2714 DEFSYM (Qw32_charset_thai, "w32-charset-thai");
2715 DEFSYM (Qw32_charset_mac, "w32-charset-mac");
2716
6fe9826d
JR
2717 defsubr (&Sx_select_font);
2718
8eac0c84 2719 w32font_driver.type = Qgdi;
f7a84cb4
JR
2720 register_font_driver (&w32font_driver, NULL);
2721}
db4f02f2
EZ
2722
2723void
2724globals_of_w32font (void)
2725{
2726 g_b_init_is_w9x = 0;
2727 g_b_init_get_outline_metrics_w = 0;
2728 g_b_init_get_text_metrics_w = 0;
2729 g_b_init_get_glyph_outline_w = 0;
2730}