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