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