(xfont_get_cache): Adjust the argument type.
[bpt/emacs.git] / src / w32font.c
CommitLineData
f7a84cb4
JR
1/* Font backend for the Microsoft W32 API.
2 Copyright (C) 2007 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
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
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19Boston, MA 02110-1301, USA. */
20
21#include <config.h>
22#include <windows.h>
23
24#include "lisp.h"
25#include "w32term.h"
26#include "frame.h"
27#include "dispextern.h"
28#include "character.h"
29#include "charset.h"
30#include "fontset.h"
31#include "font.h"
46fd1ded 32#include "w32font.h"
f7a84cb4 33
91583281
JR
34/* Cleartype available on Windows XP, cleartype_natural from XP SP1.
35 The latter does not try to fit cleartype smoothed fonts into the
36 same bounding box as the non-antialiased version of the font.
37 */
38#ifndef CLEARTYPE_QUALITY
39#define CLEARTYPE_QUALITY 5
40#endif
41#ifndef CLEARTYPE_NATURAL_QUALITY
42#define CLEARTYPE_NATURAL_QUALITY 6
43#endif
44
f7a84cb4
JR
45extern struct font_driver w32font_driver;
46
91583281
JR
47Lisp_Object Qgdi;
48extern Lisp_Object QCfamily; /* reuse from xfaces.c */
d205d43b
JR
49static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;
50static Lisp_Object Qscript, Qdecorative, Qraster, Qoutline, Qunknown;
51
91583281
JR
52/* antialiasing */
53extern Lisp_Object QCantialias; /* defined in font.c */
54extern Lisp_Object Qnone; /* reuse from w32fns.c */
55static Lisp_Object Qstandard, Qsubpixel, Qnatural;
56
d205d43b
JR
57/* scripts */
58static Lisp_Object Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
59static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali;
60static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu;
61static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao;
62static Lisp_Object Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic;
63static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic;
64static Lisp_Object Qkhmer, Qmongolian, Qsymbol, Qbraille, Qhan;
65static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo;
66static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol;
67static Lisp_Object Qmusical_symbol, Qmathematical;
68
69/* Font spacing symbols - defined in font.c. */
70extern Lisp_Object Qc, Qp, Qm;
f7a84cb4
JR
71
72static void fill_in_logfont P_ ((FRAME_PTR f, LOGFONT *logfont,
73 Lisp_Object font_spec));
74
91583281
JR
75static BYTE w32_antialias_type P_ ((Lisp_Object type));
76static Lisp_Object lispy_antialias_type P_ ((BYTE type));
77
d205d43b 78static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE * sig));
f7a84cb4
JR
79
80/* From old font code in w32fns.c */
81char * w32_to_x_charset P_ ((int charset, char * matching));
82
83static Lisp_Object w32_registry P_ ((LONG w32_charset));
84
85/* EnumFontFamiliesEx callbacks. */
86static int CALLBACK add_font_entity_to_list P_ ((ENUMLOGFONTEX *,
87 NEWTEXTMETRICEX *,
88 DWORD, LPARAM));
89static int CALLBACK add_one_font_entity_to_list P_ ((ENUMLOGFONTEX *,
90 NEWTEXTMETRICEX *,
91 DWORD, LPARAM));
92static int CALLBACK add_font_name_to_list P_ ((ENUMLOGFONTEX *,
93 NEWTEXTMETRICEX *,
94 DWORD, LPARAM));
95
d205d43b
JR
96/* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
97 of what we really want. */
98struct font_callback_data
99{
100 /* The logfont we are matching against. EnumFontFamiliesEx only matches
101 face name and charset, so we need to manually match everything else
102 in the callback function. */
103 LOGFONT pattern;
104 /* The original font spec or entity. */
105 Lisp_Object orig_font_spec;
106 /* The frame the font is being loaded on. */
107 Lisp_Object frame;
108 /* The list to add matches to. */
109 Lisp_Object list;
46fd1ded
JR
110 /* Whether to match only opentype fonts. */
111 int opentype_only;
d205d43b
JR
112};
113
114/* Handles the problem that EnumFontFamiliesEx will not return all
115 style variations if the font name is not specified. */
a74ddbda 116static void list_all_matching_fonts P_ ((struct font_callback_data *match));
d205d43b
JR
117
118
f7a84cb4
JR
119/* MingW headers only define this when _WIN32_WINNT >= 0x0500, but we
120 target older versions. */
a74ddbda 121#ifndef GGI_MARK_NONEXISTING_GLYPHS
f7a84cb4 122#define GGI_MARK_NONEXISTING_GLYPHS 1
a74ddbda 123#endif
f7a84cb4
JR
124
125static int
126memq_no_quit (elt, list)
127 Lisp_Object elt, list;
128{
129 while (CONSP (list) && ! EQ (XCAR (list), elt))
130 list = XCDR (list);
131 return (CONSP (list));
132}
133
134/* w32 implementation of get_cache for font backend.
135 Return a cache of font-entities on FRAME. The cache must be a
136 cons whose cdr part is the actual cache area. */
46fd1ded 137Lisp_Object
20399669
JR
138w32font_get_cache (frame)
139 Lisp_Object frame;
f7a84cb4
JR
140{
141 struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (frame));
142
143 return (dpyinfo->name_list_element);
144}
145
146/* w32 implementation of list for font backend.
147 List fonts exactly matching with FONT_SPEC on FRAME. The value
148 is a vector of font-entities. This is the sole API that
149 allocates font-entities. */
20399669
JR
150static Lisp_Object
151w32font_list (frame, font_spec)
152 Lisp_Object frame, font_spec;
f7a84cb4 153{
46fd1ded 154 return w32font_list_internal (frame, font_spec, 0);
f7a84cb4
JR
155}
156
157/* w32 implementation of match for font backend.
158 Return a font entity most closely matching with FONT_SPEC on
159 FRAME. The closeness is detemined by the font backend, thus
160 `face-font-selection-order' is ignored here. */
20399669
JR
161static Lisp_Object
162w32font_match (frame, font_spec)
163 Lisp_Object frame, font_spec;
f7a84cb4 164{
46fd1ded 165 return w32font_match_internal (frame, font_spec, 0);
f7a84cb4
JR
166}
167
f7a84cb4
JR
168/* w32 implementation of list_family for font backend.
169 List available families. The value is a list of family names
170 (symbols). */
20399669
JR
171static Lisp_Object
172w32font_list_family (frame)
173 Lisp_Object frame;
f7a84cb4
JR
174{
175 Lisp_Object list = Qnil;
176 LOGFONT font_match_pattern;
177 HDC dc;
178 FRAME_PTR f = XFRAME (frame);
179
180 bzero (&font_match_pattern, sizeof (font_match_pattern));
181
182 dc = get_frame_dc (f);
183
184 EnumFontFamiliesEx (dc, &font_match_pattern,
185 (FONTENUMPROC) add_font_name_to_list,
186 (LPARAM) &list, 0);
187 release_frame_dc (f, dc);
188
189 return list;
190}
191
192/* w32 implementation of open for font backend.
193 Open a font specified by FONT_ENTITY on frame F.
194 If the font is scalable, open it with PIXEL_SIZE. */
f0121ad2 195static struct font *
20399669
JR
196w32font_open (f, font_entity, pixel_size)
197 FRAME_PTR f;
198 Lisp_Object font_entity;
199 int pixel_size;
f7a84cb4 200{
f7a84cb4
JR
201 struct w32font_info *w32_font = xmalloc (sizeof (struct w32font_info));
202
f0121ad2 203 if (w32_font == NULL)
f7a84cb4
JR
204 return NULL;
205
f0121ad2 206 if (!w32font_open_internal (f, font_entity, pixel_size, w32_font))
f7a84cb4
JR
207 {
208 xfree (w32_font);
209 return NULL;
210 }
211
f0121ad2 212 return (struct font *) w32_font;
f7a84cb4
JR
213}
214
215/* w32 implementation of close for font_backend.
216 Close FONT on frame F. */
46fd1ded 217void
20399669
JR
218w32font_close (f, font)
219 FRAME_PTR f;
220 struct font *font;
f7a84cb4
JR
221{
222 if (font->font.font)
223 {
224 W32FontStruct *old_w32_font = (W32FontStruct *)font->font.font;
e9a15283 225 DeleteObject (old_w32_font->hfont);
f7a84cb4
JR
226 xfree (old_w32_font);
227 font->font.font = 0;
228 }
229
230 if (font->font.name)
231 xfree (font->font.name);
232 xfree (font);
233}
234
235/* w32 implementation of has_char for font backend.
236 Optional.
237 If FONT_ENTITY has a glyph for character C (Unicode code point),
238 return 1. If not, return 0. If a font must be opened to check
239 it, return -1. */
46fd1ded 240int
20399669
JR
241w32font_has_char (entity, c)
242 Lisp_Object entity;
243 int c;
f7a84cb4 244{
d205d43b 245 Lisp_Object supported_scripts, extra, script;
f7a84cb4
JR
246 DWORD mask;
247
01dbeb0b
JR
248 extra = AREF (entity, FONT_EXTRA_INDEX);
249 if (!CONSP (extra))
250 return -1;
251
d205d43b
JR
252 supported_scripts = assq_no_quit (QCscript, extra);
253 if (!CONSP (supported_scripts))
f7a84cb4
JR
254 return -1;
255
d205d43b 256 supported_scripts = XCDR (supported_scripts);
f7a84cb4 257
d205d43b 258 script = CHAR_TABLE_REF (Vchar_script_table, c);
f7a84cb4 259
d205d43b 260 return (memq_no_quit (script, supported_scripts)) ? 1 : 0;
f7a84cb4
JR
261}
262
263/* w32 implementation of encode_char for font backend.
264 Return a glyph code of FONT for characer C (Unicode code point).
265 If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */
46fd1ded 266unsigned
20399669
JR
267w32font_encode_char (font, c)
268 struct font *font;
269 int c;
f7a84cb4 270{
d205d43b
JR
271 /* Avoid unneccesary conversion - all the Win32 APIs will take a unicode
272 character. */
f7a84cb4
JR
273 return c;
274}
275
276/* w32 implementation of text_extents for font backend.
277 Perform the size computation of glyphs of FONT and fillin members
278 of METRICS. The glyphs are specified by their glyph codes in
78573c57 279 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
f7a84cb4 280 case just return the overall width. */
46fd1ded 281int
20399669
JR
282w32font_text_extents (font, code, nglyphs, metrics)
283 struct font *font;
284 unsigned *code;
285 int nglyphs;
286 struct font_metrics *metrics;
f7a84cb4
JR
287{
288 int i;
289 HFONT old_font;
46fd1ded
JR
290 HDC dc;
291 struct frame * f;
f7a84cb4 292 int total_width = 0;
f7a84cb4 293 WORD *wcode = alloca(nglyphs * sizeof (WORD));
d205d43b 294 SIZE size;
f7a84cb4 295
46fd1ded
JR
296 f = ((struct w32font_info *)font)->owning_frame;
297 dc = get_frame_dc (f);
f7a84cb4
JR
298 old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont);
299
300 if (metrics)
301 {
302 GLYPHMETRICS gm;
d205d43b 303 MAT2 transform;
d205d43b
JR
304
305 /* Set transform to the identity matrix. */
306 bzero (&transform, sizeof (transform));
307 transform.eM11.value = 1;
308 transform.eM22.value = 1;
78573c57
JR
309 metrics->width = 0;
310 metrics->ascent = 0;
311 metrics->descent = 0;
f7a84cb4
JR
312
313 for (i = 0; i < nglyphs; i++)
314 {
78573c57 315 if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
d205d43b 316 NULL, &transform) != GDI_ERROR)
f7a84cb4 317 {
78573c57
JR
318 int new_val = metrics->width + gm.gmBlackBoxX
319 + gm.gmptGlyphOrigin.x;
320
321 metrics->rbearing = max (metrics->rbearing, new_val);
322 metrics->width += gm.gmCellIncX;
323 new_val = -gm.gmptGlyphOrigin.y;
324 metrics->ascent = max (metrics->ascent, new_val);
325 new_val = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
326 metrics->descent = max (metrics->descent, new_val);
1065a502 327 }
f7a84cb4
JR
328 else
329 {
78573c57
JR
330 /* Rely on an estimate based on the overall font metrics. */
331 break;
f7a84cb4
JR
332 }
333 }
78573c57
JR
334
335 /* If we got through everything, return. */
336 if (i == nglyphs)
337 {
338 /* Restore state and release DC. */
339 SelectObject (dc, old_font);
46fd1ded 340 release_frame_dc (f, dc);
78573c57
JR
341
342 return metrics->width;
343 }
f7a84cb4 344 }
78573c57
JR
345
346 for (i = 0; i < nglyphs; i++)
f7a84cb4 347 {
78573c57
JR
348 if (code[i] < 0x10000)
349 wcode[i] = code[i];
350 else
351 {
352 /* TODO: Convert to surrogate, reallocating array if needed */
353 wcode[i] = 0xffff;
354 }
f7a84cb4
JR
355 }
356
d205d43b 357 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
f7a84cb4 358 {
d205d43b 359 total_width = size.cx;
f7a84cb4
JR
360 }
361
d205d43b 362 if (!total_width)
f7a84cb4
JR
363 {
364 RECT rect;
365 rect.top = 0; rect.bottom = font->font.height; rect.left = 0; rect.right = 1;
366 DrawTextW (dc, wcode, nglyphs, &rect,
367 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
368 total_width = rect.right;
369 }
d205d43b 370
78573c57
JR
371 if (metrics)
372 {
373 metrics->width = total_width;
374 metrics->ascent = font->ascent;
375 metrics->descent = font->descent;
376 metrics->lbearing = 0;
377 metrics->rbearing = total_width
378 + ((struct w32font_info *) font)->metrics.tmOverhang;
379 }
380
f7a84cb4
JR
381 /* Restore state and release DC. */
382 SelectObject (dc, old_font);
46fd1ded 383 release_frame_dc (f, dc);
f7a84cb4
JR
384
385 return total_width;
386}
387
388/* w32 implementation of draw for font backend.
389 Optional.
390 Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
391 position of frame F with S->FACE and S->GC. If WITH_BACKGROUND
392 is nonzero, fill the background in advance. It is assured that
a74ddbda
JR
393 WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars).
394
395 TODO: Currently this assumes that the colors and fonts are already
396 set in the DC. This seems to be true now, but maybe only due to
397 the old font code setting it up. It may be safer to resolve faces
398 and fonts in here and set them explicitly
399*/
400
46fd1ded 401int
20399669
JR
402w32font_draw (s, from, to, x, y, with_background)
403 struct glyph_string *s;
404 int from, to, x, y, with_background;
f7a84cb4
JR
405{
406 UINT options = 0;
5c2c9c79
JR
407 HRGN orig_clip;
408
409 /* Save clip region for later restoration. */
410 GetClipRgn(s->hdc, orig_clip);
411
412 if (s->num_clips > 0)
413 {
414 HRGN new_clip = CreateRectRgnIndirect (s->clip);
415
416 if (s->num_clips > 1)
417 {
418 HRGN clip2 = CreateRectRgnIndirect (s->clip + 1);
419
420 CombineRgn (new_clip, new_clip, clip2, RGN_OR);
421 DeleteObject (clip2);
422 }
423
424 SelectClipRgn (s->hdc, new_clip);
425 DeleteObject (new_clip);
426 }
f7a84cb4 427
fb3b8017
JR
428 /* Using OPAQUE background mode can clear more background than expected
429 when Cleartype is used. Draw the background manually to avoid this. */
430 SetBkMode (s->hdc, TRANSPARENT);
f7a84cb4
JR
431 if (with_background)
432 {
1065a502
JR
433 HBRUSH brush;
434 RECT rect;
fb3b8017 435 struct font *font = (struct font *) s->face->font_info;
1065a502
JR
436
437 brush = CreateSolidBrush (s->gc->background);
438 rect.left = x;
fb3b8017 439 rect.top = y - font->ascent;
1065a502 440 rect.right = x + s->width;
fb3b8017 441 rect.bottom = y + font->descent;
1065a502 442 FillRect (s->hdc, &rect, brush);
f2b25c0e 443 DeleteObject (brush);
f7a84cb4 444 }
040fe918
JR
445
446 ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, to - from, NULL);
5c2c9c79
JR
447
448 /* Restore clip region. */
449 if (s->num_clips > 0)
450 {
451 SelectClipRgn (s->hdc, orig_clip);
452 }
f7a84cb4
JR
453}
454
455/* w32 implementation of free_entity for font backend.
456 Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value).
457 Free FONT_EXTRA_INDEX field of FONT_ENTITY.
20399669
JR
458static void
459w32font_free_entity (Lisp_Object entity);
f7a84cb4
JR
460 */
461
462/* w32 implementation of prepare_face for font backend.
463 Optional (if FACE->extra is not used).
464 Prepare FACE for displaying characters by FONT on frame F by
465 storing some data in FACE->extra. If successful, return 0.
466 Otherwise, return -1.
20399669
JR
467static int
468w32font_prepare_face (FRAME_PTR f, struct face *face);
f7a84cb4
JR
469 */
470/* w32 implementation of done_face for font backend.
471 Optional.
472 Done FACE for displaying characters by FACE->font on frame F.
20399669
JR
473static void
474w32font_done_face (FRAME_PTR f, struct face *face); */
f7a84cb4
JR
475
476/* w32 implementation of get_bitmap for font backend.
477 Optional.
478 Store bitmap data for glyph-code CODE of FONT in BITMAP. It is
f2b25c0e 479 intended that this method is called from the other font-driver
f7a84cb4 480 for actual drawing.
20399669
JR
481static int
482w32font_get_bitmap (struct font *font, unsigned code,
483 struct font_bitmap *bitmap, int bits_per_pixel);
f7a84cb4
JR
484 */
485/* w32 implementation of free_bitmap for font backend.
486 Optional.
487 Free bitmap data in BITMAP.
20399669
JR
488static void
489w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap);
f7a84cb4
JR
490 */
491/* w32 implementation of get_outline for font backend.
492 Optional.
493 Return an outline data for glyph-code CODE of FONT. The format
494 of the outline data depends on the font-driver.
20399669
JR
495static void *
496w32font_get_outline (struct font *font, unsigned code);
f7a84cb4
JR
497 */
498/* w32 implementation of free_outline for font backend.
499 Optional.
500 Free OUTLINE (that is obtained by the above method).
20399669
JR
501static void
502w32font_free_outline (struct font *font, void *outline);
f7a84cb4
JR
503 */
504/* w32 implementation of anchor_point for font backend.
505 Optional.
506 Get coordinates of the INDEXth anchor point of the glyph whose
507 code is CODE. Store the coordinates in *X and *Y. Return 0 if
508 the operations was successfull. Otherwise return -1.
20399669
JR
509static int
510w32font_anchor_point (struct font *font, unsigned code,
f7a84cb4
JR
511 int index, int *x, int *y);
512 */
513/* w32 implementation of otf_capability for font backend.
514 Optional.
515 Return a list describing which scripts/languages FONT
516 supports by which GSUB/GPOS features of OpenType tables.
20399669
JR
517static Lisp_Object
518w32font_otf_capability (struct font *font);
f7a84cb4
JR
519 */
520/* w32 implementation of otf_drive for font backend.
521 Optional.
522 Apply FONT's OTF-FEATURES to the glyph string.
523
524 FEATURES specifies which OTF features to apply in this format:
525 (SCRIPT LANGSYS GSUB-FEATURE GPOS-FEATURE)
526 See the documentation of `font-drive-otf' for the detail.
527
528 This method applies the specified features to the codes in the
529 elements of GSTRING-IN (between FROMth and TOth). The output
530 codes are stored in GSTRING-OUT at the IDXth element and the
531 following elements.
532
533 Return the number of output codes. If none of the features are
534 applicable to the input data, return 0. If GSTRING-OUT is too
535 short, return -1.
20399669
JR
536static int
537w32font_otf_drive (struct font *font, Lisp_Object features,
538 Lisp_Object gstring_in, int from, int to,
539 Lisp_Object gstring_out, int idx,
540 int alternate_subst);
f7a84cb4
JR
541 */
542
46fd1ded
JR
543/* Internal implementation of w32font_list.
544 Additional parameter opentype_only restricts the returned fonts to
545 opentype fonts, which can be used with the Uniscribe backend. */
546Lisp_Object
547w32font_list_internal (frame, font_spec, opentype_only)
548 Lisp_Object frame, font_spec;
549 int opentype_only;
550{
551 struct font_callback_data match_data;
552 HDC dc;
553 FRAME_PTR f = XFRAME (frame);
554
555 match_data.orig_font_spec = font_spec;
556 match_data.list = Qnil;
557 match_data.frame = frame;
558
559 bzero (&match_data.pattern, sizeof (LOGFONT));
560 fill_in_logfont (f, &match_data.pattern, font_spec);
561
562 match_data.opentype_only = opentype_only;
563 if (opentype_only)
564 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
565
566 if (match_data.pattern.lfFaceName[0] == '\0')
567 {
568 /* EnumFontFamiliesEx does not take other fields into account if
569 font name is blank, so need to use two passes. */
570 list_all_matching_fonts (&match_data);
571 }
572 else
573 {
574 dc = get_frame_dc (f);
575
576 EnumFontFamiliesEx (dc, &match_data.pattern,
577 (FONTENUMPROC) add_font_entity_to_list,
578 (LPARAM) &match_data, 0);
579 release_frame_dc (f, dc);
580 }
581
582 return NILP (match_data.list) ? null_vector : Fvconcat (1, &match_data.list);
583}
584
585/* Internal implementation of w32font_match.
586 Additional parameter opentype_only restricts the returned fonts to
587 opentype fonts, which can be used with the Uniscribe backend. */
588Lisp_Object
589w32font_match_internal (frame, font_spec, opentype_only)
590 Lisp_Object frame, font_spec;
591 int opentype_only;
592{
593 struct font_callback_data match_data;
594 HDC dc;
595 FRAME_PTR f = XFRAME (frame);
596
597 match_data.orig_font_spec = font_spec;
598 match_data.frame = frame;
599 match_data.list = Qnil;
600
601 bzero (&match_data.pattern, sizeof (LOGFONT));
602 fill_in_logfont (f, &match_data.pattern, font_spec);
603
604 match_data.opentype_only = opentype_only;
605 if (opentype_only)
606 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
607
608 dc = get_frame_dc (f);
609
610 EnumFontFamiliesEx (dc, &match_data.pattern,
611 (FONTENUMPROC) add_one_font_entity_to_list,
612 (LPARAM) &match_data, 0);
613 release_frame_dc (f, dc);
614
615 return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
616}
617
f0121ad2
JR
618int
619w32font_open_internal (f, font_entity, pixel_size, w32_font)
620 FRAME_PTR f;
621 Lisp_Object font_entity;
622 int pixel_size;
623 struct w32font_info *w32_font;
624{
625 int len, size;
626 LOGFONT logfont;
627 HDC dc;
628 HFONT hfont, old_font;
629 Lisp_Object val, extra;
630 /* For backwards compatibility. */
631 W32FontStruct *compat_w32_font;
632
633 struct font * font = (struct font *) w32_font;
634 if (!font)
635 return 0;
636
637 bzero (&logfont, sizeof (logfont));
638 fill_in_logfont (f, &logfont, font_entity);
639
640 size = XINT (AREF (font_entity, FONT_SIZE_INDEX));
641 if (!size)
642 size = pixel_size;
643
644 logfont.lfHeight = -size;
645 hfont = CreateFontIndirect (&logfont);
646
647 if (hfont == NULL)
648 return 0;
649
650 w32_font->owning_frame = f;
651
652 /* Get the metrics for this font. */
653 dc = get_frame_dc (f);
654 old_font = SelectObject (dc, hfont);
655
656 GetTextMetrics (dc, &w32_font->metrics);
657
658 SelectObject (dc, old_font);
659 release_frame_dc (f, dc);
660 /* W32FontStruct - we should get rid of this, and use the w32font_info
661 struct for any W32 specific fields. font->font.font can then be hfont. */
662 font->font.font = xmalloc (sizeof (W32FontStruct));
663 compat_w32_font = (W32FontStruct *) font->font.font;
664 bzero (compat_w32_font, sizeof (W32FontStruct));
665 compat_w32_font->font_type = UNICODE_FONT;
666 /* Duplicate the text metrics. */
667 bcopy (&w32_font->metrics, &compat_w32_font->tm, sizeof (TEXTMETRIC));
668 compat_w32_font->hfont = hfont;
669
670 len = strlen (logfont.lfFaceName);
671 font->font.name = (char *) xmalloc (len + 1);
672 bcopy (logfont.lfFaceName, font->font.name, len);
673 font->font.name[len] = '\0';
674 font->font.full_name = font->font.name;
675 font->font.charset = 0;
676 font->font.codepage = 0;
677 font->font.size = w32_font->metrics.tmMaxCharWidth;
678 font->font.height = w32_font->metrics.tmHeight
679 + w32_font->metrics.tmExternalLeading;
680 font->font.space_width = font->font.average_width
681 = w32_font->metrics.tmAveCharWidth;
682
683 font->font.vertical_centering = 0;
684 font->font.encoding_type = 0;
685 font->font.baseline_offset = 0;
686 font->font.relative_compose = 0;
687 font->font.default_ascent = w32_font->metrics.tmAscent;
688 font->font.font_encoder = NULL;
689 font->entity = font_entity;
690 font->pixel_size = size;
691 font->driver = &w32font_driver;
692 font->format = Qgdi;
693 font->file_name = NULL;
694 font->encoding_charset = -1;
695 font->repertory_charset = -1;
696 font->min_width = 0;
697 font->ascent = w32_font->metrics.tmAscent;
698 font->descent = w32_font->metrics.tmDescent;
699 font->scalable = w32_font->metrics.tmPitchAndFamily & TMPF_VECTOR;
700
701 return 1;
702}
703
f7a84cb4
JR
704/* Callback function for EnumFontFamiliesEx.
705 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
20399669
JR
706static int CALLBACK
707add_font_name_to_list (logical_font, physical_font, font_type, list_object)
708 ENUMLOGFONTEX *logical_font;
709 NEWTEXTMETRICEX *physical_font;
710 DWORD font_type;
711 LPARAM list_object;
f7a84cb4
JR
712{
713 Lisp_Object* list = (Lisp_Object *) list_object;
20a2b756
JR
714 Lisp_Object family;
715
716 /* Skip vertical fonts (intended only for printing) */
717 if (logical_font->elfLogFont.lfFaceName[0] == '@')
718 return 1;
719
720 family = intern_downcase (logical_font->elfLogFont.lfFaceName,
721 strlen (logical_font->elfLogFont.lfFaceName));
f7a84cb4
JR
722 if (! memq_no_quit (family, *list))
723 *list = Fcons (family, *list);
724
725 return 1;
726}
727
728/* Convert an enumerated Windows font to an Emacs font entity. */
20399669 729static Lisp_Object
91583281
JR
730w32_enumfont_pattern_entity (frame, logical_font, physical_font,
731 font_type, requested_font)
d205d43b 732 Lisp_Object frame;
20399669
JR
733 ENUMLOGFONTEX *logical_font;
734 NEWTEXTMETRICEX *physical_font;
735 DWORD font_type;
91583281 736 LOGFONT *requested_font;
f7a84cb4
JR
737{
738 Lisp_Object entity, tem;
739 LOGFONT *lf = (LOGFONT*) logical_font;
740 BYTE generic_type;
741
d205d43b 742 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
f7a84cb4 743
8eac0c84 744 ASET (entity, FONT_TYPE_INDEX, Qgdi);
d205d43b 745 ASET (entity, FONT_FRAME_INDEX, frame);
f7a84cb4
JR
746 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet));
747 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
748
749 /* Foundry is difficult to get in readable form on Windows.
d205d43b
JR
750 But Emacs crashes if it is not set, so set it to something more
751 generic. Thes values make xflds compatible with Emacs 22. */
752 if (lf->lfOutPrecision == OUT_STRING_PRECIS)
753 tem = Qraster;
754 else if (lf->lfOutPrecision == OUT_STROKE_PRECIS)
755 tem = Qoutline;
756 else
757 tem = Qunknown;
758
759 ASET (entity, FONT_FOUNDRY_INDEX, tem);
760
761 /* Save the generic family in the extra info, as it is likely to be
762 useful to users looking for a close match. */
f7a84cb4
JR
763 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0;
764 if (generic_type == FF_DECORATIVE)
765 tem = Qdecorative;
766 else if (generic_type == FF_MODERN)
d205d43b 767 tem = Qmonospace;
f7a84cb4 768 else if (generic_type == FF_ROMAN)
d205d43b 769 tem = Qserif;
f7a84cb4
JR
770 else if (generic_type == FF_SCRIPT)
771 tem = Qscript;
772 else if (generic_type == FF_SWISS)
d205d43b 773 tem = Qsans_serif;
f7a84cb4 774 else
d205d43b
JR
775 tem = Qnil;
776
777 if (! NILP (tem))
778 font_put_extra (entity, QCfamily, tem);
f7a84cb4 779
d205d43b
JR
780 if (physical_font->ntmTm.tmPitchAndFamily & 0x01)
781 font_put_extra (entity, QCspacing, make_number (FONT_SPACING_PROPORTIONAL));
782 else
783 font_put_extra (entity, QCspacing, make_number (FONT_SPACING_MONO));
f7a84cb4 784
91583281
JR
785 if (requested_font->lfQuality != DEFAULT_QUALITY)
786 {
787 font_put_extra (entity, QCantialias,
788 lispy_antialias_type (requested_font->lfQuality));
789 }
f7a84cb4
JR
790 ASET (entity, FONT_FAMILY_INDEX,
791 intern_downcase (lf->lfFaceName, strlen (lf->lfFaceName)));
792
793 ASET (entity, FONT_WEIGHT_INDEX, make_number (lf->lfWeight));
794 ASET (entity, FONT_SLANT_INDEX, make_number (lf->lfItalic ? 200 : 100));
d205d43b
JR
795 /* TODO: PANOSE struct has this info, but need to call GetOutlineTextMetrics
796 to get it. */
797 ASET (entity, FONT_WIDTH_INDEX, make_number (100));
f7a84cb4 798
040fe918
JR
799 if (font_type & RASTER_FONTTYPE)
800 ASET (entity, FONT_SIZE_INDEX, make_number (physical_font->ntmTm.tmHeight));
801 else
802 ASET (entity, FONT_SIZE_INDEX, make_number (0));
f7a84cb4
JR
803
804 /* Cache unicode codepoints covered by this font, as there is no other way
805 of getting this information easily. */
040fe918 806 if (font_type & TRUETYPE_FONTTYPE)
f7a84cb4 807 {
d205d43b
JR
808 font_put_extra (entity, QCscript,
809 font_supported_scripts (&physical_font->ntmFontSig));
f7a84cb4 810 }
d205d43b 811
f7a84cb4
JR
812 return entity;
813}
814
d205d43b
JR
815
816/* Convert generic families to the family portion of lfPitchAndFamily. */
817BYTE
818w32_generic_family (Lisp_Object name)
819{
820 /* Generic families. */
821 if (EQ (name, Qmonospace) || EQ (name, Qmono))
822 return FF_MODERN;
823 else if (EQ (name, Qsans_serif) || EQ (name, Qsans__serif)
824 || EQ (name, Qsans))
825 return FF_SWISS;
826 else if (EQ (name, Qserif))
827 return FF_ROMAN;
828 else if (EQ (name, Qdecorative))
829 return FF_DECORATIVE;
830 else if (EQ (name, Qscript))
831 return FF_SCRIPT;
832 else
833 return FF_DONTCARE;
834}
835
836static int
837logfonts_match (font, pattern)
838 LOGFONT *font, *pattern;
839{
840 /* Only check height for raster fonts. */
841 if (pattern->lfHeight && font->lfOutPrecision == OUT_STRING_PRECIS
842 && font->lfHeight != pattern->lfHeight)
843 return 0;
844
845 /* Have some flexibility with weights. */
846 if (pattern->lfWeight
847 && ((font->lfWeight < (pattern->lfWeight - 150))
848 || font->lfWeight > (pattern->lfWeight + 150)))
849 return 0;
850
851 /* Charset and face should be OK. Italic has to be checked
852 against the original spec, in case we don't have any preference. */
853 return 1;
854}
855
856static int
857font_matches_spec (type, font, spec)
858 DWORD type;
859 NEWTEXTMETRICEX *font;
860 Lisp_Object spec;
861{
862 Lisp_Object extra, val;
863
864 /* Check italic. Can't check logfonts, since it is a boolean field,
865 so there is no difference between "non-italic" and "don't care". */
866 val = AREF (spec, FONT_SLANT_INDEX);
867 if (INTEGERP (val))
868 {
869 int slant = XINT (val);
870 if ((slant > 150 && !font->ntmTm.tmItalic)
871 || (slant <= 150 && font->ntmTm.tmItalic))
d205d43b 872 return 0;
d205d43b
JR
873 }
874
875 /* Check extra parameters. */
876 for (extra = AREF (spec, FONT_EXTRA_INDEX);
877 CONSP (extra); extra = XCDR (extra))
878 {
879 Lisp_Object extra_entry;
880 extra_entry = XCAR (extra);
881 if (CONSP (extra_entry))
882 {
883 Lisp_Object key = XCAR (extra_entry);
884 val = XCDR (extra_entry);
885 if (EQ (key, QCfamily))
886 {
887 /* Generic family. Most useful when there is no font name
888 specified. eg, if a script does not exist in the default
889 font, we could look for a font with the same generic family
890 that does support the script. Full PANOSE support would
891 be better, but we need to open the font to get that. */
892 BYTE w32_family = w32_generic_family (val);
893
894 /* Reject if FF_DONTCARE is returned, as it means the
895 font spec is bad. */
896 if (w32_family == FF_DONTCARE
897 || w32_family != (font->ntmTm.tmPitchAndFamily & 0xF0))
898 return 0;
899 }
900 else if (EQ (key, QCspacing))
901 {
902 int proportional;
903 if (INTEGERP (val))
904 {
905 int spacing = XINT (val);
906 proportional = (spacing < FONT_SPACING_MONO);
907 }
908 else if (EQ (val, Qp))
909 proportional = 1;
910 else if (EQ (val, Qc) || EQ (val, Qm))
911 proportional = 0;
912 else
913 return 0; /* Bad font spec. */
914
915 if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
916 || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
917 return 0;
918 }
919 else if (EQ (key, QCscript) && SYMBOLP (val))
920 {
921 /* Only truetype fonts will have information about what
922 scripts they support. This probably means the user
923 will have to force Emacs to use raster, postscript
924 or atm fonts for non-ASCII text. */
925 if (type & TRUETYPE_FONTTYPE)
926 {
927 Lisp_Object support
928 = font_supported_scripts (&font->ntmFontSig);
929 if (! memq_no_quit (val, support))
930 return 0;
931 }
932 else
933 {
934 /* Return specific matches, but play it safe. Fonts
935 that cover more than their charset would suggest
936 are likely to be truetype or opentype fonts,
937 covered above. */
938 if (EQ (val, Qlatin))
939 {
940 /* Although every charset but symbol, thai and
941 arabic contains the basic ASCII set of latin
942 characters, Emacs expects much more. */
943 if (font->ntmTm.tmCharSet != ANSI_CHARSET)
944 return 0;
945 }
946 else if (EQ (val, Qsymbol))
947 {
948 if (font->ntmTm.tmCharSet != SYMBOL_CHARSET)
949 return 0;
950 }
951 else if (EQ (val, Qcyrillic))
952 {
953 if (font->ntmTm.tmCharSet != RUSSIAN_CHARSET)
954 return 0;
955 }
956 else if (EQ (val, Qgreek))
957 {
958 if (font->ntmTm.tmCharSet != GREEK_CHARSET)
959 return 0;
960 }
961 else if (EQ (val, Qarabic))
962 {
963 if (font->ntmTm.tmCharSet != ARABIC_CHARSET)
964 return 0;
965 }
966 else if (EQ (val, Qhebrew))
967 {
968 if (font->ntmTm.tmCharSet != HEBREW_CHARSET)
969 return 0;
970 }
971 else if (EQ (val, Qthai))
972 {
973 if (font->ntmTm.tmCharSet != THAI_CHARSET)
974 return 0;
975 }
976 else if (EQ (val, Qkana))
977 {
978 if (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
979 return 0;
980 }
981 else if (EQ (val, Qbopomofo))
982 {
983 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET)
984 return 0;
985 }
986 else if (EQ (val, Qhangul))
987 {
988 if (font->ntmTm.tmCharSet != HANGUL_CHARSET
989 && font->ntmTm.tmCharSet != JOHAB_CHARSET)
990 return 0;
991 }
992 else if (EQ (val, Qhan))
993 {
994 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET
995 && font->ntmTm.tmCharSet != GB2312_CHARSET
996 && font->ntmTm.tmCharSet != HANGUL_CHARSET
997 && font->ntmTm.tmCharSet != JOHAB_CHARSET
998 && font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
999 return 0;
1000 }
1001 else
1002 /* Other scripts unlikely to be handled. */
1003 return 0;
1004 }
1005 }
1006 }
1007 }
1008 return 1;
1009}
1010
f7a84cb4 1011/* Callback function for EnumFontFamiliesEx.
d205d43b
JR
1012 * Checks if a font matches everything we are trying to check agaist,
1013 * and if so, adds it to a list. Both the data we are checking against
1014 * and the list to which the fonts are added are passed in via the
1015 * lparam argument, in the form of a font_callback_data struct. */
20399669 1016static int CALLBACK
d205d43b 1017add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
20399669
JR
1018 ENUMLOGFONTEX *logical_font;
1019 NEWTEXTMETRICEX *physical_font;
1020 DWORD font_type;
d205d43b 1021 LPARAM lParam;
f7a84cb4 1022{
d205d43b
JR
1023 struct font_callback_data *match_data
1024 = (struct font_callback_data *) lParam;
f7a84cb4 1025
46fd1ded
JR
1026 if ((!match_data->opentype_only
1027 || (physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE))
1028 && logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
d205d43b 1029 && font_matches_spec (font_type, physical_font,
46fd1ded 1030 match_data->orig_font_spec))
d205d43b
JR
1031 {
1032 Lisp_Object entity
1033 = w32_enumfont_pattern_entity (match_data->frame, logical_font,
91583281
JR
1034 physical_font, font_type,
1035 &match_data->pattern);
d205d43b
JR
1036 if (!NILP (entity))
1037 match_data->list = Fcons (entity, match_data->list);
1038 }
f7a84cb4
JR
1039 return 1;
1040}
1041
1042/* Callback function for EnumFontFamiliesEx.
d205d43b 1043 * Terminates the search once we have a match. */
20399669 1044static int CALLBACK
d205d43b 1045add_one_font_entity_to_list (logical_font, physical_font, font_type, lParam)
20399669
JR
1046 ENUMLOGFONTEX *logical_font;
1047 NEWTEXTMETRICEX *physical_font;
1048 DWORD font_type;
d205d43b 1049 LPARAM lParam;
f7a84cb4 1050{
d205d43b
JR
1051 struct font_callback_data *match_data
1052 = (struct font_callback_data *) lParam;
1053 add_font_entity_to_list (logical_font, physical_font, font_type, lParam);
1054
1055 /* If we have a font in the list, terminate the search. */
1056 return !NILP (match_data->list);
f7a84cb4
JR
1057}
1058
1059/* Convert a Lisp font registry (symbol) to a windows charset. */
20399669
JR
1060static LONG
1061registry_to_w32_charset (charset)
1062 Lisp_Object charset;
f7a84cb4
JR
1063{
1064 if (EQ (charset, Qiso10646_1) || EQ (charset, Qunicode_bmp)
1065 || EQ (charset, Qunicode_sip))
1066 return DEFAULT_CHARSET; /* UNICODE_CHARSET not defined in MingW32 */
1067 else if (EQ (charset, Qiso8859_1))
1068 return ANSI_CHARSET;
040fe918
JR
1069 else if (SYMBOLP (charset))
1070 return x_to_w32_charset (SDATA (SYMBOL_NAME (charset)));
f7a84cb4
JR
1071 else if (STRINGP (charset))
1072 return x_to_w32_charset (SDATA (charset));
1073 else
1074 return DEFAULT_CHARSET;
1075}
1076
20399669
JR
1077static Lisp_Object
1078w32_registry (w32_charset)
1079 LONG w32_charset;
f7a84cb4
JR
1080{
1081 if (w32_charset == ANSI_CHARSET)
d205d43b 1082 return Qiso10646_1;
f7a84cb4 1083 else
040fe918
JR
1084 {
1085 char * charset = w32_to_x_charset (w32_charset, NULL);
1086 return intern_downcase (charset, strlen(charset));
1087 }
f7a84cb4
JR
1088}
1089
f7a84cb4 1090/* Fill in all the available details of LOGFONT from FONT_SPEC. */
20399669
JR
1091static void
1092fill_in_logfont (f, logfont, font_spec)
1093 FRAME_PTR f;
1094 LOGFONT *logfont;
1095 Lisp_Object font_spec;
f7a84cb4 1096{
d205d43b 1097 Lisp_Object tmp, extra;
f7a84cb4
JR
1098 int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
1099
d205d43b
JR
1100 extra = AREF (font_spec, FONT_EXTRA_INDEX);
1101 /* Allow user to override dpi settings. */
1102 if (CONSP (extra))
1103 {
1104 tmp = assq_no_quit (QCdpi, extra);
1105 if (CONSP (tmp) && INTEGERP (XCDR (tmp)))
1106 {
1107 dpi = XINT (XCDR (tmp));
1108 }
1109 else if (CONSP (tmp) && FLOATP (XCDR (tmp)))
1110 {
1111 dpi = (int) (XFLOAT_DATA (XCDR (tmp)) + 0.5);
1112 }
1113 }
f7a84cb4
JR
1114
1115 /* Height */
1116 tmp = AREF (font_spec, FONT_SIZE_INDEX);
1117 if (INTEGERP (tmp))
040fe918 1118 logfont->lfHeight = -1 * XINT (tmp);
f7a84cb4 1119 else if (FLOATP (tmp))
d205d43b 1120 logfont->lfHeight = (int) (-1.0 * dpi * XFLOAT_DATA (tmp) / 72.27 + 0.5);
f7a84cb4
JR
1121
1122 /* Escapement */
1123
1124 /* Orientation */
1125
1126 /* Weight */
1127 tmp = AREF (font_spec, FONT_WEIGHT_INDEX);
1128 if (INTEGERP (tmp))
1129 logfont->lfWeight = XINT (tmp);
1130
1131 /* Italic */
1132 tmp = AREF (font_spec, FONT_SLANT_INDEX);
1133 if (INTEGERP (tmp))
1134 {
1135 int slant = XINT (tmp);
1136 logfont->lfItalic = slant > 150 ? 1 : 0;
1137 }
1138
1139 /* Underline */
1140
1141 /* Strikeout */
1142
1143 /* Charset */
1144 tmp = AREF (font_spec, FONT_REGISTRY_INDEX);
1145 if (! NILP (tmp))
d205d43b 1146 logfont->lfCharSet = registry_to_w32_charset (tmp);
f7a84cb4
JR
1147
1148 /* Out Precision */
91583281 1149
f7a84cb4 1150 /* Clip Precision */
91583281
JR
1151
1152 /* Quality */
040fe918
JR
1153 logfont->lfQuality = DEFAULT_QUALITY;
1154
d205d43b
JR
1155 /* Generic Family and Face Name */
1156 logfont->lfPitchAndFamily = FF_DONTCARE | DEFAULT_PITCH;
1157
f7a84cb4 1158 tmp = AREF (font_spec, FONT_FAMILY_INDEX);
d205d43b
JR
1159 if (! NILP (tmp))
1160 {
1161 logfont->lfPitchAndFamily = w32_generic_family (tmp) | DEFAULT_PITCH;
1162 if ((logfont->lfPitchAndFamily & 0xF0) != FF_DONTCARE)
1163 ; /* Font name was generic, don't fill in font name. */
1164 /* Font families are interned, but allow for strings also in case of
1165 user input. */
1166 else if (SYMBOLP (tmp))
1167 strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE);
1168 else if (STRINGP (tmp))
1169 strncpy (logfont->lfFaceName, SDATA (tmp), LF_FACESIZE);
1170 }
f7a84cb4 1171
d205d43b
JR
1172 /* Process EXTRA info. */
1173 for ( ; CONSP (extra); extra = XCDR (extra))
1174 {
1175 tmp = XCAR (extra);
1176 if (CONSP (tmp))
1177 {
1178 Lisp_Object key, val;
1179 key = XCAR (tmp), val = XCDR (tmp);
1180 if (EQ (key, QCfamily))
1181 {
1182 /* Override generic family. */
1183 BYTE family = w32_generic_family (val);
1184 if (family != FF_DONTCARE)
1185 logfont->lfPitchAndFamily
1186 = logfont->lfPitchAndFamily & 0x0F | family;
1187 }
1188 else if (EQ (key, QCspacing))
1189 {
1190 /* Set pitch based on the spacing property. */
1191 if (INTEGERP (val))
1192 {
1193 int spacing = XINT (val);
1194 if (spacing < FONT_SPACING_MONO)
1195 logfont->lfPitchAndFamily
1196 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
1197 else
1198 logfont->lfPitchAndFamily
1199 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
1200 }
1201 else if (EQ (val, Qp))
1202 logfont->lfPitchAndFamily
1203 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
1204 else if (EQ (val, Qc) || EQ (val, Qm))
1205 logfont->lfPitchAndFamily
1206 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
1207 }
1208 /* Only use QCscript if charset is not provided, or is unicode
1209 and a single script is specified. This is rather crude,
1210 and is only used to narrow down the fonts returned where
1211 there is a definite match. Some scripts, such as latin, han,
1212 cjk-misc match multiple lfCharSet values, so we can't pre-filter
1213 them. */
1214 else if (EQ (key, QCscript)
1215 && logfont->lfCharSet == DEFAULT_CHARSET
1216 && SYMBOLP (val))
1217 {
1218 if (EQ (val, Qgreek))
1219 logfont->lfCharSet = GREEK_CHARSET;
1220 else if (EQ (val, Qhangul))
1221 logfont->lfCharSet = HANGUL_CHARSET;
1222 else if (EQ (val, Qkana) || EQ (val, Qkanbun))
1223 logfont->lfCharSet = SHIFTJIS_CHARSET;
1224 else if (EQ (val, Qbopomofo))
1225 logfont->lfCharSet = CHINESEBIG5_CHARSET;
1226 /* GB 18030 supports tibetan, yi, mongolian,
1227 fonts that support it should show up if we ask for
1228 GB2312 fonts. */
1229 else if (EQ (val, Qtibetan) || EQ (val, Qyi)
1230 || EQ (val, Qmongolian))
1231 logfont->lfCharSet = GB2312_CHARSET;
1232 else if (EQ (val, Qhebrew))
1233 logfont->lfCharSet = HEBREW_CHARSET;
1234 else if (EQ (val, Qarabic))
1235 logfont->lfCharSet = ARABIC_CHARSET;
1236 else if (EQ (val, Qthai))
1237 logfont->lfCharSet = THAI_CHARSET;
1238 else if (EQ (val, Qsymbol))
1239 logfont->lfCharSet = SYMBOL_CHARSET;
1240 }
91583281
JR
1241 else if (EQ (key, QCantialias) && SYMBOLP (val))
1242 {
1243 logfont->lfQuality = w32_antialias_type (val);
1244 }
d205d43b
JR
1245 }
1246 }
f7a84cb4
JR
1247}
1248
20399669 1249static void
d205d43b
JR
1250list_all_matching_fonts (match_data)
1251 struct font_callback_data *match_data;
f7a84cb4
JR
1252{
1253 HDC dc;
d205d43b
JR
1254 Lisp_Object families = w32font_list_family (match_data->frame);
1255 struct frame *f = XFRAME (match_data->frame);
f7a84cb4
JR
1256
1257 dc = get_frame_dc (f);
1258
1259 while (!NILP (families))
1260 {
d205d43b
JR
1261 /* TODO: Use the Unicode versions of the W32 APIs, so we can
1262 handle non-ASCII font names. */
1263 char *name;
f7a84cb4
JR
1264 Lisp_Object family = CAR (families);
1265 families = CDR (families);
d205d43b
JR
1266 if (NILP (family))
1267 continue;
1268 else if (STRINGP (family))
1269 name = SDATA (family);
1270 else
1271 name = SDATA (SYMBOL_NAME (family));
1272
1273 strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE);
1274 match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0';
1275
1276 EnumFontFamiliesEx (dc, &match_data->pattern,
1277 (FONTENUMPROC) add_font_entity_to_list,
1278 (LPARAM) match_data, 0);
f7a84cb4
JR
1279 }
1280
1281 release_frame_dc (f, dc);
1282}
1283
91583281
JR
1284static Lisp_Object
1285lispy_antialias_type (type)
1286 BYTE type;
1287{
1288 Lisp_Object lispy;
1289
1290 switch (type)
1291 {
1292 case NONANTIALIASED_QUALITY:
1293 lispy = Qnone;
1294 break;
1295 case ANTIALIASED_QUALITY:
1296 lispy = Qstandard;
1297 break;
1298 case CLEARTYPE_QUALITY:
1299 lispy = Qsubpixel;
1300 break;
1301 case CLEARTYPE_NATURAL_QUALITY:
1302 lispy = Qnatural;
1303 break;
1304 default:
1305 lispy = Qnil;
1306 break;
1307 }
1308 return lispy;
1309}
1310
1311/* Convert antialiasing symbols to lfQuality */
1312static BYTE
1313w32_antialias_type (type)
1314 Lisp_Object type;
1315{
1316 if (EQ (type, Qnone))
1317 return NONANTIALIASED_QUALITY;
1318 else if (EQ (type, Qstandard))
1319 return ANTIALIASED_QUALITY;
1320 else if (EQ (type, Qsubpixel))
1321 return CLEARTYPE_QUALITY;
1322 else if (EQ (type, Qnatural))
1323 return CLEARTYPE_NATURAL_QUALITY;
1324 else
1325 return DEFAULT_QUALITY;
1326}
1327
d205d43b
JR
1328/* Return a list of all the scripts that the font supports. */
1329static Lisp_Object
1330font_supported_scripts (FONTSIGNATURE * sig)
f7a84cb4 1331{
d205d43b
JR
1332 DWORD * subranges = sig->fsUsb;
1333 Lisp_Object supported = Qnil;
1334
1335 /* Match a single subrange. SYM is set if bit N is set in subranges. */
1336#define SUBRANGE(n,sym) \
1337 if (subranges[(n) / 32] & (1 << ((n) % 32))) \
1338 supported = Fcons ((sym), supported)
1339
1340 /* Match multiple subranges. SYM is set if any MASK bit is set in
1341 subranges[0 - 3]. */
1342#define MASK_ANY(mask0,mask1,mask2,mask3,sym) \
1343 if ((subranges[0] & (mask0)) || (subranges[1] & (mask1)) \
1344 || (subranges[2] & (mask2)) || (subranges[3] & (mask3))) \
1345 supported = Fcons ((sym), supported)
1346
1347 SUBRANGE (0, Qlatin); /* There are many others... */
1348
1349 SUBRANGE (7, Qgreek);
1350 SUBRANGE (8, Qcoptic);
1351 SUBRANGE (9, Qcyrillic);
1352 SUBRANGE (10, Qarmenian);
1353 SUBRANGE (11, Qhebrew);
1354 SUBRANGE (13, Qarabic);
1355 SUBRANGE (14, Qnko);
1356 SUBRANGE (15, Qdevanagari);
1357 SUBRANGE (16, Qbengali);
1358 SUBRANGE (17, Qgurmukhi);
1359 SUBRANGE (18, Qgujarati);
1360 SUBRANGE (19, Qoriya);
1361 SUBRANGE (20, Qtamil);
1362 SUBRANGE (21, Qtelugu);
1363 SUBRANGE (22, Qkannada);
1364 SUBRANGE (23, Qmalayalam);
1365 SUBRANGE (24, Qthai);
1366 SUBRANGE (25, Qlao);
1367 SUBRANGE (26, Qgeorgian);
1368
1369 SUBRANGE (48, Qcjk_misc);
1370 SUBRANGE (51, Qbopomofo);
1371 SUBRANGE (54, Qkanbun); /* Is this right? */
1372 SUBRANGE (56, Qhangul);
1373
1374 SUBRANGE (59, Qhan); /* There are others, but this is the main one. */
1375 SUBRANGE (59, Qideographic_description); /* Windows lumps this in */
1376
1377 SUBRANGE (70, Qtibetan);
1378 SUBRANGE (71, Qsyriac);
1379 SUBRANGE (72, Qthaana);
1380 SUBRANGE (73, Qsinhala);
1381 SUBRANGE (74, Qmyanmar);
1382 SUBRANGE (75, Qethiopic);
1383 SUBRANGE (76, Qcherokee);
1384 SUBRANGE (77, Qcanadian_aboriginal);
1385 SUBRANGE (78, Qogham);
1386 SUBRANGE (79, Qrunic);
1387 SUBRANGE (80, Qkhmer);
1388 SUBRANGE (81, Qmongolian);
1389 SUBRANGE (82, Qbraille);
1390 SUBRANGE (83, Qyi);
1391
1392 SUBRANGE (88, Qbyzantine_musical_symbol);
1393 SUBRANGE (88, Qmusical_symbol); /* Windows doesn't distinguish these. */
1394
1395 SUBRANGE (89, Qmathematical);
1396
1397 /* Match either katakana or hiragana for kana. */
1398 MASK_ANY (0, 0x00060000, 0, 0, Qkana);
1399
1400 /* There isn't really a main symbol range, so include symbol if any
1401 relevant range is set. */
1402 MASK_ANY (0x8000000, 0x0000FFFF, 0, 0, Qsymbol);
1403
1404#undef SUBRANGE
1405#undef MASK_ANY
1406
1407 return supported;
f7a84cb4
JR
1408}
1409
1410
1411struct font_driver w32font_driver =
1412 {
8eac0c84 1413 0, /* Qgdi */
f7a84cb4
JR
1414 w32font_get_cache,
1415 w32font_list,
1416 w32font_match,
1417 w32font_list_family,
1418 NULL, /* free_entity */
1419 w32font_open,
1420 w32font_close,
1421 NULL, /* prepare_face */
1422 NULL, /* done_face */
1423 w32font_has_char,
1424 w32font_encode_char,
1425 w32font_text_extents,
1426 w32font_draw,
1427 NULL, /* get_bitmap */
1428 NULL, /* free_bitmap */
1429 NULL, /* get_outline */
1430 NULL, /* free_outline */
1431 NULL, /* anchor_point */
1432 NULL, /* otf_capability */
5b0c3446
JR
1433 NULL, /* otf_drive */
1434 NULL, /* start_for_frame */
1435 NULL, /* end_for_frame */
1436 NULL /* shape */
f7a84cb4
JR
1437 };
1438
f7a84cb4
JR
1439
1440/* Initialize state that does not change between invocations. This is only
1441 called when Emacs is dumped. */
20399669
JR
1442void
1443syms_of_w32font ()
f7a84cb4 1444{
8eac0c84 1445 DEFSYM (Qgdi, "gdi");
d205d43b
JR
1446
1447 /* Generic font families. */
1448 DEFSYM (Qmonospace, "monospace");
1449 DEFSYM (Qserif, "serif");
1450 DEFSYM (Qsans_serif, "sans-serif");
f7a84cb4 1451 DEFSYM (Qscript, "script");
d205d43b
JR
1452 DEFSYM (Qdecorative, "decorative");
1453 /* Aliases. */
1454 DEFSYM (Qsans__serif, "sans_serif");
1455 DEFSYM (Qsans, "sans");
1456 DEFSYM (Qmono, "mono");
1457
1458 /* Fake foundries. */
1459 DEFSYM (Qraster, "raster");
1460 DEFSYM (Qoutline, "outline");
f7a84cb4 1461 DEFSYM (Qunknown, "unknown");
d205d43b 1462
91583281
JR
1463 /* Antialiasing. */
1464 DEFSYM (Qstandard, "standard");
1465 DEFSYM (Qsubpixel, "subpixel");
1466 DEFSYM (Qnatural, "natural");
d205d43b
JR
1467
1468 /* Scripts */
1469 DEFSYM (Qlatin, "latin");
1470 DEFSYM (Qgreek, "greek");
1471 DEFSYM (Qcoptic, "coptic");
1472 DEFSYM (Qcyrillic, "cyrillic");
1473 DEFSYM (Qarmenian, "armenian");
1474 DEFSYM (Qhebrew, "hebrew");
1475 DEFSYM (Qarabic, "arabic");
1476 DEFSYM (Qsyriac, "syriac");
1477 DEFSYM (Qnko, "nko");
1478 DEFSYM (Qthaana, "thaana");
1479 DEFSYM (Qdevanagari, "devanagari");
1480 DEFSYM (Qbengali, "bengali");
1481 DEFSYM (Qgurmukhi, "gurmukhi");
1482 DEFSYM (Qgujarati, "gujarati");
1483 DEFSYM (Qoriya, "oriya");
1484 DEFSYM (Qtamil, "tamil");
1485 DEFSYM (Qtelugu, "telugu");
1486 DEFSYM (Qkannada, "kannada");
1487 DEFSYM (Qmalayalam, "malayalam");
1488 DEFSYM (Qsinhala, "sinhala");
1489 DEFSYM (Qthai, "thai");
1490 DEFSYM (Qlao, "lao");
1491 DEFSYM (Qtibetan, "tibetan");
1492 DEFSYM (Qmyanmar, "myanmar");
1493 DEFSYM (Qgeorgian, "georgian");
1494 DEFSYM (Qhangul, "hangul");
1495 DEFSYM (Qethiopic, "ethiopic");
1496 DEFSYM (Qcherokee, "cherokee");
1497 DEFSYM (Qcanadian_aboriginal, "canadian-aboriginal");
1498 DEFSYM (Qogham, "ogham");
1499 DEFSYM (Qrunic, "runic");
1500 DEFSYM (Qkhmer, "khmer");
1501 DEFSYM (Qmongolian, "mongolian");
1502 DEFSYM (Qsymbol, "symbol");
1503 DEFSYM (Qbraille, "braille");
1504 DEFSYM (Qhan, "han");
1505 DEFSYM (Qideographic_description, "ideographic-description");
1506 DEFSYM (Qcjk_misc, "cjk-misc");
1507 DEFSYM (Qkana, "kana");
1508 DEFSYM (Qbopomofo, "bopomofo");
1509 DEFSYM (Qkanbun, "kanbun");
1510 DEFSYM (Qyi, "yi");
1511 DEFSYM (Qbyzantine_musical_symbol, "byzantine-musical-symbol");
1512 DEFSYM (Qmusical_symbol, "musical-symbol");
1513 DEFSYM (Qmathematical, "mathematical");
1514
8eac0c84 1515 w32font_driver.type = Qgdi;
f7a84cb4
JR
1516 register_font_driver (&w32font_driver, NULL);
1517}
6d8c85b5
MB
1518
1519/* arch-tag: 65b8a3cd-46aa-4c0d-a1f3-99e75b9c07ee
1520 (do not change this comment) */