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