(uniscribe_font_driver) [WINDOWSNT]: Declare for w32fns.c.
[bpt/emacs.git] / src / w32font.c
CommitLineData
f7a84cb4 1/* Font backend for the Microsoft W32 API.
7e14d905 2 Copyright (C) 2007, 2008 Free Software Foundation, Inc.
f7a84cb4
JR
3
4This file is part of GNU Emacs.
5
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
7e14d905 8the Free Software Foundation; either version 3, or (at your option)
f7a84cb4
JR
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
c6900278
JR
21#ifdef USE_FONT_BACKEND
22
f7a84cb4
JR
23#include <config.h>
24#include <windows.h>
09fe06b7 25#include <math.h>
f7a84cb4
JR
26
27#include "lisp.h"
28#include "w32term.h"
29#include "frame.h"
30#include "dispextern.h"
31#include "character.h"
32#include "charset.h"
33#include "fontset.h"
34#include "font.h"
46fd1ded 35#include "w32font.h"
f7a84cb4 36
91583281
JR
37/* Cleartype available on Windows XP, cleartype_natural from XP SP1.
38 The latter does not try to fit cleartype smoothed fonts into the
39 same bounding box as the non-antialiased version of the font.
40 */
41#ifndef CLEARTYPE_QUALITY
42#define CLEARTYPE_QUALITY 5
43#endif
44#ifndef CLEARTYPE_NATURAL_QUALITY
45#define CLEARTYPE_NATURAL_QUALITY 6
46#endif
47
f7a84cb4
JR
48extern struct font_driver w32font_driver;
49
91583281 50Lisp_Object Qgdi;
34fd2d28
JR
51Lisp_Object Quniscribe;
52static Lisp_Object QCformat;
9e1a2995
JR
53static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif;
54static Lisp_Object Qserif, Qscript, Qdecorative;
55static Lisp_Object Qraster, Qoutline, Qunknown;
d205d43b 56
91583281
JR
57/* antialiasing */
58extern Lisp_Object QCantialias; /* defined in font.c */
59extern Lisp_Object Qnone; /* reuse from w32fns.c */
60static Lisp_Object Qstandard, Qsubpixel, Qnatural;
61
d205d43b
JR
62/* scripts */
63static Lisp_Object Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
64static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali;
65static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu;
66static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao;
67static Lisp_Object Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic;
68static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic;
69static Lisp_Object Qkhmer, Qmongolian, Qsymbol, Qbraille, Qhan;
70static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo;
71static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol;
72static Lisp_Object Qmusical_symbol, Qmathematical;
73
74/* Font spacing symbols - defined in font.c. */
75extern Lisp_Object Qc, Qp, Qm;
f7a84cb4
JR
76
77static void fill_in_logfont P_ ((FRAME_PTR f, LOGFONT *logfont,
78 Lisp_Object font_spec));
79
91583281
JR
80static BYTE w32_antialias_type P_ ((Lisp_Object type));
81static Lisp_Object lispy_antialias_type P_ ((BYTE type));
82
d205d43b 83static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE * sig));
67997c79
JR
84static int w32font_full_name P_ ((LOGFONT * font, Lisp_Object font_obj,
85 int pixel_size, char *name, int nbytes));
54efdcd1 86static void recompute_cached_metrics P_ ((HDC dc, struct w32font_info * font));
f7a84cb4 87
c960bff8 88static Lisp_Object w32_registry P_ ((LONG w32_charset, DWORD font_type));
f7a84cb4
JR
89
90/* EnumFontFamiliesEx callbacks. */
91static int CALLBACK add_font_entity_to_list P_ ((ENUMLOGFONTEX *,
92 NEWTEXTMETRICEX *,
93 DWORD, LPARAM));
94static int CALLBACK add_one_font_entity_to_list P_ ((ENUMLOGFONTEX *,
95 NEWTEXTMETRICEX *,
96 DWORD, LPARAM));
97static int CALLBACK add_font_name_to_list P_ ((ENUMLOGFONTEX *,
98 NEWTEXTMETRICEX *,
99 DWORD, LPARAM));
100
d205d43b
JR
101/* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
102 of what we really want. */
103struct font_callback_data
104{
105 /* The logfont we are matching against. EnumFontFamiliesEx only matches
106 face name and charset, so we need to manually match everything else
107 in the callback function. */
108 LOGFONT pattern;
109 /* The original font spec or entity. */
110 Lisp_Object orig_font_spec;
111 /* The frame the font is being loaded on. */
112 Lisp_Object frame;
113 /* The list to add matches to. */
114 Lisp_Object list;
46fd1ded
JR
115 /* Whether to match only opentype fonts. */
116 int opentype_only;
d205d43b
JR
117};
118
119/* Handles the problem that EnumFontFamiliesEx will not return all
120 style variations if the font name is not specified. */
a74ddbda 121static void list_all_matching_fonts P_ ((struct font_callback_data *match));
d205d43b 122
34fd2d28
JR
123/* From old font code in w32fns.c */
124char * w32_to_x_charset P_ ((int charset, char * matching));
d205d43b 125
f7a84cb4
JR
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. */
46fd1ded 139Lisp_Object
a4c71909
KH
140w32font_get_cache (f)
141 FRAME_PTR f;
f7a84cb4 142{
a4c71909 143 struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
f7a84cb4
JR
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{
46fd1ded 156 return w32font_list_internal (frame, font_spec, 0);
f7a84cb4
JR
157}
158
159/* w32 implementation of match for font backend.
160 Return a font entity most closely matching with FONT_SPEC on
161 FRAME. The closeness is detemined by the font backend, thus
162 `face-font-selection-order' is ignored here. */
20399669
JR
163static Lisp_Object
164w32font_match (frame, font_spec)
165 Lisp_Object frame, font_spec;
f7a84cb4 166{
46fd1ded 167 return w32font_match_internal (frame, font_spec, 0);
f7a84cb4
JR
168}
169
f7a84cb4
JR
170/* w32 implementation of list_family for font backend.
171 List available families. The value is a list of family names
172 (symbols). */
20399669
JR
173static Lisp_Object
174w32font_list_family (frame)
175 Lisp_Object frame;
f7a84cb4
JR
176{
177 Lisp_Object list = Qnil;
178 LOGFONT font_match_pattern;
179 HDC dc;
180 FRAME_PTR f = XFRAME (frame);
181
182 bzero (&font_match_pattern, sizeof (font_match_pattern));
183
184 dc = get_frame_dc (f);
185
186 EnumFontFamiliesEx (dc, &font_match_pattern,
187 (FONTENUMPROC) add_font_name_to_list,
188 (LPARAM) &list, 0);
189 release_frame_dc (f, dc);
190
191 return list;
192}
193
194/* w32 implementation of open for font backend.
195 Open a font specified by FONT_ENTITY on frame F.
196 If the font is scalable, open it with PIXEL_SIZE. */
f0121ad2 197static struct font *
20399669
JR
198w32font_open (f, font_entity, pixel_size)
199 FRAME_PTR f;
200 Lisp_Object font_entity;
201 int pixel_size;
f7a84cb4 202{
f7a84cb4
JR
203 struct w32font_info *w32_font = xmalloc (sizeof (struct w32font_info));
204
f0121ad2 205 if (w32_font == NULL)
f7a84cb4
JR
206 return NULL;
207
f0121ad2 208 if (!w32font_open_internal (f, font_entity, pixel_size, w32_font))
f7a84cb4
JR
209 {
210 xfree (w32_font);
211 return NULL;
212 }
213
f0121ad2 214 return (struct font *) w32_font;
f7a84cb4
JR
215}
216
217/* w32 implementation of close for font_backend.
218 Close FONT on frame F. */
46fd1ded 219void
20399669
JR
220w32font_close (f, font)
221 FRAME_PTR f;
222 struct font *font;
f7a84cb4
JR
223{
224 if (font->font.font)
225 {
226 W32FontStruct *old_w32_font = (W32FontStruct *)font->font.font;
e9a15283 227 DeleteObject (old_w32_font->hfont);
f7a84cb4
JR
228 xfree (old_w32_font);
229 font->font.font = 0;
230 }
231
5ace1ec1
JR
232 if (font->font.full_name && font->font.full_name != font->font.name)
233 xfree (font->font.full_name);
234
f7a84cb4
JR
235 if (font->font.name)
236 xfree (font->font.name);
5ace1ec1 237
f7a84cb4
JR
238 xfree (font);
239}
240
241/* w32 implementation of has_char for font backend.
242 Optional.
243 If FONT_ENTITY has a glyph for character C (Unicode code point),
244 return 1. If not, return 0. If a font must be opened to check
245 it, return -1. */
46fd1ded 246int
20399669
JR
247w32font_has_char (entity, c)
248 Lisp_Object entity;
249 int c;
f7a84cb4 250{
d205d43b 251 Lisp_Object supported_scripts, extra, script;
f7a84cb4
JR
252 DWORD mask;
253
01dbeb0b
JR
254 extra = AREF (entity, FONT_EXTRA_INDEX);
255 if (!CONSP (extra))
256 return -1;
257
d205d43b
JR
258 supported_scripts = assq_no_quit (QCscript, extra);
259 if (!CONSP (supported_scripts))
f7a84cb4
JR
260 return -1;
261
d205d43b 262 supported_scripts = XCDR (supported_scripts);
f7a84cb4 263
d205d43b 264 script = CHAR_TABLE_REF (Vchar_script_table, c);
f7a84cb4 265
34fd2d28 266 return (memq_no_quit (script, supported_scripts)) ? -1 : 0;
f7a84cb4
JR
267}
268
269/* w32 implementation of encode_char for font backend.
270 Return a glyph code of FONT for characer C (Unicode code point).
271 If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */
34fd2d28 272static unsigned
20399669
JR
273w32font_encode_char (font, c)
274 struct font *font;
275 int c;
f7a84cb4 276{
34fd2d28
JR
277 struct frame *f;
278 HDC dc;
279 HFONT old_font;
280 DWORD retval;
281 GCP_RESULTSW result;
282 wchar_t in[2];
283 wchar_t out[2];
284 int len;
285 struct w32font_info *w32_font = (struct w32font_info *) font;
286
287 /* If glyph indexing is not working for this font, just return the
288 unicode code-point. */
289 if (!w32_font->glyph_idx)
290 return c;
291
292 if (c > 0xFFFF)
293 {
294 /* TODO: Encode as surrogate pair and lookup the glyph. */
295 return FONT_INVALID_CODE;
296 }
297 else
298 {
299 in[0] = (wchar_t) c;
300 len = 1;
301 }
302
303 bzero (&result, sizeof (result));
304 result.lStructSize = sizeof (result);
305 result.lpGlyphs = out;
306 result.nGlyphs = 2;
307
308 f = XFRAME (selected_frame);
309
310 dc = get_frame_dc (f);
311 old_font = SelectObject (dc, ((W32FontStruct *) (font->font.font))->hfont);
312
313 retval = GetCharacterPlacementW (dc, in, len, 0, &result, 0);
314
315 SelectObject (dc, old_font);
316 release_frame_dc (f, dc);
317
318 if (retval)
319 {
320 if (result.nGlyphs != 1 || !result.lpGlyphs[0])
321 return FONT_INVALID_CODE;
322 return result.lpGlyphs[0];
323 }
324 else
325 {
326 int i;
327 /* Mark this font as not supporting glyph indices. This can happen
328 on Windows9x, and maybe with non-Truetype fonts on NT etc. */
329 w32_font->glyph_idx = 0;
54efdcd1 330 recompute_cached_metrics (dc, w32_font);
34fd2d28
JR
331
332 return c;
333 }
f7a84cb4
JR
334}
335
336/* w32 implementation of text_extents for font backend.
337 Perform the size computation of glyphs of FONT and fillin members
338 of METRICS. The glyphs are specified by their glyph codes in
78573c57 339 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
f7a84cb4 340 case just return the overall width. */
46fd1ded 341int
20399669
JR
342w32font_text_extents (font, code, nglyphs, metrics)
343 struct font *font;
344 unsigned *code;
345 int nglyphs;
346 struct font_metrics *metrics;
f7a84cb4
JR
347{
348 int i;
2a36efcf
JR
349 HFONT old_font = NULL;
350 HDC dc = NULL;
46fd1ded 351 struct frame * f;
f7a84cb4 352 int total_width = 0;
f7a84cb4 353 WORD *wcode = alloca(nglyphs * sizeof (WORD));
d205d43b 354 SIZE size;
f7a84cb4 355
46a923ac
JR
356 /* TODO: Frames can come and go, and their fonts outlive them. So we
357 can't cache the frame in the font structure. Use selected_frame
358 until the API is updated to pass in a frame. */
9e1a2995 359 f = XFRAME (selected_frame);
859a9fdf 360
f7a84cb4
JR
361 if (metrics)
362 {
363 GLYPHMETRICS gm;
d205d43b 364 MAT2 transform;
34fd2d28 365 struct w32font_info *w32_font = (struct w32font_info *) font;
d205d43b
JR
366
367 /* Set transform to the identity matrix. */
368 bzero (&transform, sizeof (transform));
369 transform.eM11.value = 1;
370 transform.eM22.value = 1;
78573c57
JR
371 metrics->width = 0;
372 metrics->ascent = 0;
373 metrics->descent = 0;
46a923ac 374 metrics->lbearing = 0;
f7a84cb4
JR
375
376 for (i = 0; i < nglyphs; i++)
377 {
34fd2d28 378 if (*(code + i) < 128)
46a923ac
JR
379 {
380 /* Use cached metrics for ASCII. */
381 struct font_metrics *char_metric
34fd2d28 382 = &w32_font->ascii_metrics[*(code+i)];
46a923ac
JR
383
384 /* If we couldn't get metrics when caching, use fallback. */
385 if (char_metric->width == 0)
386 break;
387
388 metrics->lbearing = max (metrics->lbearing,
389 char_metric->lbearing - metrics->width);
390 metrics->rbearing = max (metrics->rbearing,
391 metrics->width + char_metric->rbearing);
392 metrics->width += char_metric->width;
393 metrics->ascent = max (metrics->ascent, char_metric->ascent);
394 metrics->descent = max (metrics->descent, char_metric->descent);
395 }
f7a84cb4
JR
396 else
397 {
2a36efcf
JR
398 if (dc == NULL)
399 {
400 dc = get_frame_dc (f);
401 old_font = SelectObject (dc, ((W32FontStruct *)
402 (font->font.font))->hfont);
403 }
34fd2d28
JR
404 if (GetGlyphOutlineW (dc, *(code + i),
405 GGO_METRICS
406 | w32_font->glyph_idx
407 ? GGO_GLYPH_INDEX : 0,
408 &gm, 0, NULL, &transform) != GDI_ERROR)
2a36efcf
JR
409 {
410 int new_val = metrics->width + gm.gmBlackBoxX
411 + gm.gmptGlyphOrigin.x;
412 metrics->rbearing = max (metrics->rbearing, new_val);
413 new_val = -gm.gmptGlyphOrigin.x - metrics->width;
414 metrics->lbearing = max (metrics->lbearing, new_val);
415 metrics->width += gm.gmCellIncX;
416 new_val = -gm.gmptGlyphOrigin.y;
417 metrics->ascent = max (metrics->ascent, new_val);
418 new_val = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
419 metrics->descent = max (metrics->descent, new_val);
420 }
421 else
422 {
34fd2d28
JR
423 if (w32_font->glyph_idx)
424 {
425 /* Disable glyph indexing for this font, as we can't
426 handle the metrics. Abort this run, our recovery
427 strategies rely on having unicode code points here.
428 This will cause a glitch in display, but in practice,
429 any problems should be caught when initialising the
430 metrics cache. */
431 w32_font->glyph_idx = 0;
54efdcd1 432 recompute_cached_metrics (dc, w32_font);
34fd2d28
JR
433 SelectObject (dc, old_font);
434 release_frame_dc (f, dc);
435 return 0;
436 }
2a36efcf
JR
437 /* Rely on an estimate based on the overall font metrics. */
438 break;
439 }
f7a84cb4
JR
440 }
441 }
78573c57
JR
442
443 /* If we got through everything, return. */
444 if (i == nglyphs)
445 {
2a36efcf
JR
446 if (dc != NULL)
447 {
448 /* Restore state and release DC. */
449 SelectObject (dc, old_font);
450 release_frame_dc (f, dc);
451 }
78573c57
JR
452
453 return metrics->width;
454 }
f7a84cb4 455 }
78573c57
JR
456
457 for (i = 0; i < nglyphs; i++)
f7a84cb4 458 {
78573c57
JR
459 if (code[i] < 0x10000)
460 wcode[i] = code[i];
461 else
462 {
463 /* TODO: Convert to surrogate, reallocating array if needed */
464 wcode[i] = 0xffff;
465 }
f7a84cb4
JR
466 }
467
2a36efcf
JR
468 if (dc == NULL)
469 {
470 dc = get_frame_dc (f);
471 old_font = SelectObject (dc, ((W32FontStruct *)
472 (font->font.font))->hfont);
473 }
474
d205d43b 475 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
f7a84cb4 476 {
d205d43b 477 total_width = size.cx;
f7a84cb4
JR
478 }
479
d205d43b 480 if (!total_width)
f7a84cb4
JR
481 {
482 RECT rect;
483 rect.top = 0; rect.bottom = font->font.height; rect.left = 0; rect.right = 1;
484 DrawTextW (dc, wcode, nglyphs, &rect,
485 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
486 total_width = rect.right;
487 }
d205d43b 488
78573c57
JR
489 if (metrics)
490 {
491 metrics->width = total_width;
492 metrics->ascent = font->ascent;
493 metrics->descent = font->descent;
494 metrics->lbearing = 0;
495 metrics->rbearing = total_width
496 + ((struct w32font_info *) font)->metrics.tmOverhang;
497 }
498
f7a84cb4
JR
499 /* Restore state and release DC. */
500 SelectObject (dc, old_font);
46fd1ded 501 release_frame_dc (f, dc);
f7a84cb4
JR
502
503 return total_width;
504}
505
506/* w32 implementation of draw for font backend.
507 Optional.
508 Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
509 position of frame F with S->FACE and S->GC. If WITH_BACKGROUND
510 is nonzero, fill the background in advance. It is assured that
a74ddbda
JR
511 WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars).
512
513 TODO: Currently this assumes that the colors and fonts are already
514 set in the DC. This seems to be true now, but maybe only due to
515 the old font code setting it up. It may be safer to resolve faces
516 and fonts in here and set them explicitly
517*/
518
46fd1ded 519int
20399669
JR
520w32font_draw (s, from, to, x, y, with_background)
521 struct glyph_string *s;
522 int from, to, x, y, with_background;
f7a84cb4 523{
34fd2d28 524 UINT options;
5c2c9c79 525 HRGN orig_clip;
34fd2d28
JR
526 struct w32font_info *w32font = (struct w32font_info *) s->face->font_info;
527
528 options = w32font->glyph_idx;
5c2c9c79
JR
529
530 /* Save clip region for later restoration. */
531 GetClipRgn(s->hdc, orig_clip);
532
533 if (s->num_clips > 0)
534 {
535 HRGN new_clip = CreateRectRgnIndirect (s->clip);
536
537 if (s->num_clips > 1)
538 {
539 HRGN clip2 = CreateRectRgnIndirect (s->clip + 1);
540
541 CombineRgn (new_clip, new_clip, clip2, RGN_OR);
542 DeleteObject (clip2);
543 }
544
545 SelectClipRgn (s->hdc, new_clip);
546 DeleteObject (new_clip);
547 }
f7a84cb4 548
fb3b8017
JR
549 /* Using OPAQUE background mode can clear more background than expected
550 when Cleartype is used. Draw the background manually to avoid this. */
551 SetBkMode (s->hdc, TRANSPARENT);
f7a84cb4
JR
552 if (with_background)
553 {
1065a502
JR
554 HBRUSH brush;
555 RECT rect;
fb3b8017 556 struct font *font = (struct font *) s->face->font_info;
1065a502
JR
557
558 brush = CreateSolidBrush (s->gc->background);
559 rect.left = x;
fb3b8017 560 rect.top = y - font->ascent;
1065a502 561 rect.right = x + s->width;
fb3b8017 562 rect.bottom = y + font->descent;
1065a502 563 FillRect (s->hdc, &rect, brush);
f2b25c0e 564 DeleteObject (brush);
f7a84cb4 565 }
040fe918 566
de63f07f
KH
567 if (s->padding_p)
568 {
569 int len = to - from, i;
570
571 for (i = 0; i < len; i++)
572 ExtTextOutW (s->hdc, x + i, y, options, NULL,
8501c48b 573 s->char2b + from + i, 1, NULL);
de63f07f
KH
574 }
575 else
576 ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, to - from, NULL);
5c2c9c79
JR
577
578 /* Restore clip region. */
579 if (s->num_clips > 0)
580 {
581 SelectClipRgn (s->hdc, orig_clip);
582 }
f7a84cb4
JR
583}
584
585/* w32 implementation of free_entity for font backend.
586 Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value).
587 Free FONT_EXTRA_INDEX field of FONT_ENTITY.
20399669
JR
588static void
589w32font_free_entity (Lisp_Object entity);
f7a84cb4
JR
590 */
591
592/* w32 implementation of prepare_face for font backend.
593 Optional (if FACE->extra is not used).
594 Prepare FACE for displaying characters by FONT on frame F by
595 storing some data in FACE->extra. If successful, return 0.
596 Otherwise, return -1.
20399669
JR
597static int
598w32font_prepare_face (FRAME_PTR f, struct face *face);
f7a84cb4
JR
599 */
600/* w32 implementation of done_face for font backend.
601 Optional.
602 Done FACE for displaying characters by FACE->font on frame F.
20399669
JR
603static void
604w32font_done_face (FRAME_PTR f, struct face *face); */
f7a84cb4
JR
605
606/* w32 implementation of get_bitmap for font backend.
607 Optional.
608 Store bitmap data for glyph-code CODE of FONT in BITMAP. It is
f2b25c0e 609 intended that this method is called from the other font-driver
f7a84cb4 610 for actual drawing.
20399669
JR
611static int
612w32font_get_bitmap (struct font *font, unsigned code,
613 struct font_bitmap *bitmap, int bits_per_pixel);
f7a84cb4
JR
614 */
615/* w32 implementation of free_bitmap for font backend.
616 Optional.
617 Free bitmap data in BITMAP.
20399669
JR
618static void
619w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap);
f7a84cb4
JR
620 */
621/* w32 implementation of get_outline for font backend.
622 Optional.
623 Return an outline data for glyph-code CODE of FONT. The format
624 of the outline data depends on the font-driver.
20399669
JR
625static void *
626w32font_get_outline (struct font *font, unsigned code);
f7a84cb4
JR
627 */
628/* w32 implementation of free_outline for font backend.
629 Optional.
630 Free OUTLINE (that is obtained by the above method).
20399669
JR
631static void
632w32font_free_outline (struct font *font, void *outline);
f7a84cb4
JR
633 */
634/* w32 implementation of anchor_point for font backend.
635 Optional.
636 Get coordinates of the INDEXth anchor point of the glyph whose
637 code is CODE. Store the coordinates in *X and *Y. Return 0 if
638 the operations was successfull. Otherwise return -1.
20399669
JR
639static int
640w32font_anchor_point (struct font *font, unsigned code,
f7a84cb4
JR
641 int index, int *x, int *y);
642 */
643/* w32 implementation of otf_capability for font backend.
644 Optional.
645 Return a list describing which scripts/languages FONT
646 supports by which GSUB/GPOS features of OpenType tables.
20399669
JR
647static Lisp_Object
648w32font_otf_capability (struct font *font);
f7a84cb4
JR
649 */
650/* w32 implementation of otf_drive for font backend.
651 Optional.
652 Apply FONT's OTF-FEATURES to the glyph string.
653
654 FEATURES specifies which OTF features to apply in this format:
655 (SCRIPT LANGSYS GSUB-FEATURE GPOS-FEATURE)
656 See the documentation of `font-drive-otf' for the detail.
657
658 This method applies the specified features to the codes in the
659 elements of GSTRING-IN (between FROMth and TOth). The output
660 codes are stored in GSTRING-OUT at the IDXth element and the
661 following elements.
662
663 Return the number of output codes. If none of the features are
664 applicable to the input data, return 0. If GSTRING-OUT is too
665 short, return -1.
20399669
JR
666static int
667w32font_otf_drive (struct font *font, Lisp_Object features,
668 Lisp_Object gstring_in, int from, int to,
669 Lisp_Object gstring_out, int idx,
670 int alternate_subst);
f7a84cb4
JR
671 */
672
46fd1ded
JR
673/* Internal implementation of w32font_list.
674 Additional parameter opentype_only restricts the returned fonts to
675 opentype fonts, which can be used with the Uniscribe backend. */
676Lisp_Object
677w32font_list_internal (frame, font_spec, opentype_only)
678 Lisp_Object frame, font_spec;
679 int opentype_only;
680{
681 struct font_callback_data match_data;
682 HDC dc;
683 FRAME_PTR f = XFRAME (frame);
684
685 match_data.orig_font_spec = font_spec;
686 match_data.list = Qnil;
687 match_data.frame = frame;
688
689 bzero (&match_data.pattern, sizeof (LOGFONT));
690 fill_in_logfont (f, &match_data.pattern, font_spec);
691
692 match_data.opentype_only = opentype_only;
693 if (opentype_only)
694 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
695
696 if (match_data.pattern.lfFaceName[0] == '\0')
697 {
698 /* EnumFontFamiliesEx does not take other fields into account if
699 font name is blank, so need to use two passes. */
700 list_all_matching_fonts (&match_data);
701 }
702 else
703 {
704 dc = get_frame_dc (f);
705
706 EnumFontFamiliesEx (dc, &match_data.pattern,
707 (FONTENUMPROC) add_font_entity_to_list,
708 (LPARAM) &match_data, 0);
709 release_frame_dc (f, dc);
710 }
711
712 return NILP (match_data.list) ? null_vector : Fvconcat (1, &match_data.list);
713}
714
715/* Internal implementation of w32font_match.
716 Additional parameter opentype_only restricts the returned fonts to
717 opentype fonts, which can be used with the Uniscribe backend. */
718Lisp_Object
719w32font_match_internal (frame, font_spec, opentype_only)
720 Lisp_Object frame, font_spec;
721 int opentype_only;
722{
723 struct font_callback_data match_data;
724 HDC dc;
725 FRAME_PTR f = XFRAME (frame);
726
727 match_data.orig_font_spec = font_spec;
728 match_data.frame = frame;
729 match_data.list = Qnil;
730
731 bzero (&match_data.pattern, sizeof (LOGFONT));
732 fill_in_logfont (f, &match_data.pattern, font_spec);
733
734 match_data.opentype_only = opentype_only;
735 if (opentype_only)
736 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
737
738 dc = get_frame_dc (f);
739
740 EnumFontFamiliesEx (dc, &match_data.pattern,
741 (FONTENUMPROC) add_one_font_entity_to_list,
742 (LPARAM) &match_data, 0);
743 release_frame_dc (f, dc);
744
745 return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
746}
747
f0121ad2
JR
748int
749w32font_open_internal (f, font_entity, pixel_size, w32_font)
750 FRAME_PTR f;
751 Lisp_Object font_entity;
752 int pixel_size;
753 struct w32font_info *w32_font;
754{
755 int len, size;
756 LOGFONT logfont;
757 HDC dc;
758 HFONT hfont, old_font;
759 Lisp_Object val, extra;
760 /* For backwards compatibility. */
761 W32FontStruct *compat_w32_font;
762
763 struct font * font = (struct font *) w32_font;
764 if (!font)
765 return 0;
766
767 bzero (&logfont, sizeof (logfont));
768 fill_in_logfont (f, &logfont, font_entity);
769
770 size = XINT (AREF (font_entity, FONT_SIZE_INDEX));
771 if (!size)
772 size = pixel_size;
773
774 logfont.lfHeight = -size;
775 hfont = CreateFontIndirect (&logfont);
776
777 if (hfont == NULL)
778 return 0;
779
f0121ad2
JR
780 /* Get the metrics for this font. */
781 dc = get_frame_dc (f);
782 old_font = SelectObject (dc, hfont);
783
784 GetTextMetrics (dc, &w32_font->metrics);
785
54efdcd1 786 w32_font->glyph_idx = ETO_GLYPH_INDEX;
7145be81
JR
787
788 /* Cache ASCII metrics. */
54efdcd1
JR
789 recompute_cached_metrics (dc, w32_font);
790
f0121ad2
JR
791 SelectObject (dc, old_font);
792 release_frame_dc (f, dc);
34fd2d28 793
f0121ad2
JR
794 /* W32FontStruct - we should get rid of this, and use the w32font_info
795 struct for any W32 specific fields. font->font.font can then be hfont. */
796 font->font.font = xmalloc (sizeof (W32FontStruct));
797 compat_w32_font = (W32FontStruct *) font->font.font;
798 bzero (compat_w32_font, sizeof (W32FontStruct));
799 compat_w32_font->font_type = UNICODE_FONT;
800 /* Duplicate the text metrics. */
801 bcopy (&w32_font->metrics, &compat_w32_font->tm, sizeof (TEXTMETRIC));
802 compat_w32_font->hfont = hfont;
803
804 len = strlen (logfont.lfFaceName);
805 font->font.name = (char *) xmalloc (len + 1);
806 bcopy (logfont.lfFaceName, font->font.name, len);
807 font->font.name[len] = '\0';
5ace1ec1
JR
808
809 {
810 char *name;
811
812 /* We don't know how much space we need for the full name, so start with
813 96 bytes and go up in steps of 32. */
814 len = 96;
e3a77b22 815 name = xmalloc (len);
67997c79
JR
816 while (name && w32font_full_name (&logfont, font_entity, pixel_size,
817 name, len) < 0)
5ace1ec1 818 {
e3a77b22 819 char *new = xrealloc (name, len += 32);
5ace1ec1
JR
820
821 if (! new)
e3a77b22 822 xfree (name);
5ace1ec1
JR
823 name = new;
824 }
825 if (name)
826 font->font.full_name = name;
827 else
828 font->font.full_name = font->font.name;
829 }
f0121ad2
JR
830 font->font.charset = 0;
831 font->font.codepage = 0;
832 font->font.size = w32_font->metrics.tmMaxCharWidth;
833 font->font.height = w32_font->metrics.tmHeight
834 + w32_font->metrics.tmExternalLeading;
835 font->font.space_width = font->font.average_width
836 = w32_font->metrics.tmAveCharWidth;
837
838 font->font.vertical_centering = 0;
839 font->font.encoding_type = 0;
840 font->font.baseline_offset = 0;
841 font->font.relative_compose = 0;
842 font->font.default_ascent = w32_font->metrics.tmAscent;
843 font->font.font_encoder = NULL;
844 font->entity = font_entity;
845 font->pixel_size = size;
846 font->driver = &w32font_driver;
34fd2d28
JR
847 /* Use format cached during list, as the information we have access to
848 here is incomplete. */
849 extra = AREF (font_entity, FONT_EXTRA_INDEX);
850 if (CONSP (extra))
851 {
852 val = assq_no_quit (QCformat, extra);
853 if (CONSP (val))
854 font->format = XCDR (val);
855 else
856 font->format = Qunknown;
857 }
858 else
859 font->format = Qunknown;
860
f0121ad2
JR
861 font->file_name = NULL;
862 font->encoding_charset = -1;
863 font->repertory_charset = -1;
04b65d2b
JR
864 /* TODO: do we really want the minimum width here, which could be negative? */
865 font->min_width = font->font.space_width;
f0121ad2
JR
866 font->ascent = w32_font->metrics.tmAscent;
867 font->descent = w32_font->metrics.tmDescent;
868 font->scalable = w32_font->metrics.tmPitchAndFamily & TMPF_VECTOR;
869
04b65d2b
JR
870 /* Set global flag fonts_changed_p to non-zero if the font loaded
871 has a character with a smaller width than any other character
872 before, or if the font loaded has a smaller height than any other
873 font loaded before. If this happens, it will make a glyph matrix
874 reallocation necessary. */
875 {
876 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
877 dpyinfo->n_fonts++;
878
879 if (dpyinfo->n_fonts == 1)
880 {
881 dpyinfo->smallest_font_height = font->font.height;
882 dpyinfo->smallest_char_width = font->min_width;
883 }
884 else
885 {
886 if (dpyinfo->smallest_font_height > font->font.height)
887 {
888 dpyinfo->smallest_font_height = font->font.height;
889 fonts_changed_p |= 1;
890 }
891 if (dpyinfo->smallest_char_width > font->min_width)
892 {
893 dpyinfo->smallest_char_width = font->min_width;
894 fonts_changed_p |= 1;
895 }
896 }
897 }
898
f0121ad2
JR
899 return 1;
900}
901
f7a84cb4
JR
902/* Callback function for EnumFontFamiliesEx.
903 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
20399669
JR
904static int CALLBACK
905add_font_name_to_list (logical_font, physical_font, font_type, list_object)
906 ENUMLOGFONTEX *logical_font;
907 NEWTEXTMETRICEX *physical_font;
908 DWORD font_type;
909 LPARAM list_object;
f7a84cb4
JR
910{
911 Lisp_Object* list = (Lisp_Object *) list_object;
20a2b756
JR
912 Lisp_Object family;
913
914 /* Skip vertical fonts (intended only for printing) */
915 if (logical_font->elfLogFont.lfFaceName[0] == '@')
916 return 1;
917
918 family = intern_downcase (logical_font->elfLogFont.lfFaceName,
919 strlen (logical_font->elfLogFont.lfFaceName));
f7a84cb4
JR
920 if (! memq_no_quit (family, *list))
921 *list = Fcons (family, *list);
922
923 return 1;
924}
925
926/* Convert an enumerated Windows font to an Emacs font entity. */
20399669 927static Lisp_Object
91583281 928w32_enumfont_pattern_entity (frame, logical_font, physical_font,
34fd2d28 929 font_type, requested_font, backend)
d205d43b 930 Lisp_Object frame;
20399669
JR
931 ENUMLOGFONTEX *logical_font;
932 NEWTEXTMETRICEX *physical_font;
933 DWORD font_type;
91583281 934 LOGFONT *requested_font;
34fd2d28 935 Lisp_Object backend;
f7a84cb4
JR
936{
937 Lisp_Object entity, tem;
938 LOGFONT *lf = (LOGFONT*) logical_font;
939 BYTE generic_type;
34fd2d28 940 BYTE full_type = physical_font->ntmTm.ntmFlags;
f7a84cb4 941
d205d43b 942 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
f7a84cb4 943
34fd2d28 944 ASET (entity, FONT_TYPE_INDEX, backend);
d205d43b 945 ASET (entity, FONT_FRAME_INDEX, frame);
c960bff8 946 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet, font_type));
f7a84cb4
JR
947 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
948
949 /* Foundry is difficult to get in readable form on Windows.
d205d43b
JR
950 But Emacs crashes if it is not set, so set it to something more
951 generic. Thes values make xflds compatible with Emacs 22. */
952 if (lf->lfOutPrecision == OUT_STRING_PRECIS)
953 tem = Qraster;
954 else if (lf->lfOutPrecision == OUT_STROKE_PRECIS)
955 tem = Qoutline;
956 else
957 tem = Qunknown;
958
959 ASET (entity, FONT_FOUNDRY_INDEX, tem);
960
961 /* Save the generic family in the extra info, as it is likely to be
962 useful to users looking for a close match. */
f7a84cb4
JR
963 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0;
964 if (generic_type == FF_DECORATIVE)
965 tem = Qdecorative;
966 else if (generic_type == FF_MODERN)
9e1a2995 967 tem = Qmono;
f7a84cb4 968 else if (generic_type == FF_ROMAN)
d205d43b 969 tem = Qserif;
f7a84cb4
JR
970 else if (generic_type == FF_SCRIPT)
971 tem = Qscript;
972 else if (generic_type == FF_SWISS)
9e1a2995 973 tem = Qsans;
f7a84cb4 974 else
9e1a2995
JR
975 tem = null_string;
976
977 ASET (entity, FONT_ADSTYLE_INDEX, tem);
f7a84cb4 978
d205d43b
JR
979 if (physical_font->ntmTm.tmPitchAndFamily & 0x01)
980 font_put_extra (entity, QCspacing, make_number (FONT_SPACING_PROPORTIONAL));
981 else
982 font_put_extra (entity, QCspacing, make_number (FONT_SPACING_MONO));
f7a84cb4 983
91583281
JR
984 if (requested_font->lfQuality != DEFAULT_QUALITY)
985 {
986 font_put_extra (entity, QCantialias,
987 lispy_antialias_type (requested_font->lfQuality));
988 }
f7a84cb4
JR
989 ASET (entity, FONT_FAMILY_INDEX,
990 intern_downcase (lf->lfFaceName, strlen (lf->lfFaceName)));
991
992 ASET (entity, FONT_WEIGHT_INDEX, make_number (lf->lfWeight));
993 ASET (entity, FONT_SLANT_INDEX, make_number (lf->lfItalic ? 200 : 100));
d205d43b
JR
994 /* TODO: PANOSE struct has this info, but need to call GetOutlineTextMetrics
995 to get it. */
996 ASET (entity, FONT_WIDTH_INDEX, make_number (100));
f7a84cb4 997
040fe918
JR
998 if (font_type & RASTER_FONTTYPE)
999 ASET (entity, FONT_SIZE_INDEX, make_number (physical_font->ntmTm.tmHeight));
1000 else
1001 ASET (entity, FONT_SIZE_INDEX, make_number (0));
f7a84cb4
JR
1002
1003 /* Cache unicode codepoints covered by this font, as there is no other way
1004 of getting this information easily. */
040fe918 1005 if (font_type & TRUETYPE_FONTTYPE)
f7a84cb4 1006 {
d205d43b
JR
1007 font_put_extra (entity, QCscript,
1008 font_supported_scripts (&physical_font->ntmFontSig));
f7a84cb4 1009 }
d205d43b 1010
34fd2d28
JR
1011 /* This information is not fully available when opening fonts, so
1012 save it here. Only Windows 2000 and later return information
1013 about opentype and type1 fonts, so need a fallback for detecting
1014 truetype so that this information is not any worse than we could
1015 have obtained later. */
1016 if (full_type & NTM_TT_OPENTYPE || font_type & TRUETYPE_FONTTYPE)
1017 tem = intern ("truetype");
1018 else if (full_type & NTM_TYPE1)
1019 tem = intern ("type1");
1020 else if (full_type & NTM_PS_OPENTYPE)
1021 tem = intern ("postscript");
1022 else if (font_type & RASTER_FONTTYPE)
1023 tem = intern ("w32bitmap");
1024 else
1025 tem = intern ("w32vector");
1026
1027 font_put_extra (entity, QCformat, tem);
1028
f7a84cb4
JR
1029 return entity;
1030}
1031
d205d43b
JR
1032
1033/* Convert generic families to the family portion of lfPitchAndFamily. */
1034BYTE
1035w32_generic_family (Lisp_Object name)
1036{
1037 /* Generic families. */
1038 if (EQ (name, Qmonospace) || EQ (name, Qmono))
1039 return FF_MODERN;
9e1a2995 1040 else if (EQ (name, Qsans) || EQ (name, Qsans_serif) || EQ (name, Qsansserif))
d205d43b
JR
1041 return FF_SWISS;
1042 else if (EQ (name, Qserif))
1043 return FF_ROMAN;
1044 else if (EQ (name, Qdecorative))
1045 return FF_DECORATIVE;
1046 else if (EQ (name, Qscript))
1047 return FF_SCRIPT;
1048 else
1049 return FF_DONTCARE;
1050}
1051
1052static int
1053logfonts_match (font, pattern)
1054 LOGFONT *font, *pattern;
1055{
1056 /* Only check height for raster fonts. */
1057 if (pattern->lfHeight && font->lfOutPrecision == OUT_STRING_PRECIS
1058 && font->lfHeight != pattern->lfHeight)
1059 return 0;
1060
1061 /* Have some flexibility with weights. */
1062 if (pattern->lfWeight
1063 && ((font->lfWeight < (pattern->lfWeight - 150))
1064 || font->lfWeight > (pattern->lfWeight + 150)))
1065 return 0;
1066
1067 /* Charset and face should be OK. Italic has to be checked
1068 against the original spec, in case we don't have any preference. */
1069 return 1;
1070}
1071
1072static int
1073font_matches_spec (type, font, spec)
1074 DWORD type;
1075 NEWTEXTMETRICEX *font;
1076 Lisp_Object spec;
1077{
1078 Lisp_Object extra, val;
1079
1080 /* Check italic. Can't check logfonts, since it is a boolean field,
1081 so there is no difference between "non-italic" and "don't care". */
1082 val = AREF (spec, FONT_SLANT_INDEX);
1083 if (INTEGERP (val))
1084 {
1085 int slant = XINT (val);
1086 if ((slant > 150 && !font->ntmTm.tmItalic)
1087 || (slant <= 150 && font->ntmTm.tmItalic))
d205d43b 1088 return 0;
d205d43b
JR
1089 }
1090
4f2a2ee2
JR
1091 /* Check adstyle against generic family. */
1092 val = AREF (spec, FONT_ADSTYLE_INDEX);
1093 if (!NILP (val))
1094 {
1095 BYTE family = w32_generic_family (val);
1096 if (family != FF_DONTCARE
1097 && family != (font->ntmTm.tmPitchAndFamily & 0xF0))
1098 return 0;
1099 }
1100
d205d43b
JR
1101 /* Check extra parameters. */
1102 for (extra = AREF (spec, FONT_EXTRA_INDEX);
1103 CONSP (extra); extra = XCDR (extra))
1104 {
1105 Lisp_Object extra_entry;
1106 extra_entry = XCAR (extra);
1107 if (CONSP (extra_entry))
1108 {
1109 Lisp_Object key = XCAR (extra_entry);
1110 val = XCDR (extra_entry);
9e1a2995 1111 if (EQ (key, QCspacing))
d205d43b
JR
1112 {
1113 int proportional;
1114 if (INTEGERP (val))
1115 {
1116 int spacing = XINT (val);
1117 proportional = (spacing < FONT_SPACING_MONO);
1118 }
1119 else if (EQ (val, Qp))
1120 proportional = 1;
1121 else if (EQ (val, Qc) || EQ (val, Qm))
1122 proportional = 0;
1123 else
1124 return 0; /* Bad font spec. */
1125
1126 if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
1127 || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
1128 return 0;
1129 }
1130 else if (EQ (key, QCscript) && SYMBOLP (val))
1131 {
1132 /* Only truetype fonts will have information about what
1133 scripts they support. This probably means the user
1134 will have to force Emacs to use raster, postscript
1135 or atm fonts for non-ASCII text. */
1136 if (type & TRUETYPE_FONTTYPE)
1137 {
1138 Lisp_Object support
1139 = font_supported_scripts (&font->ntmFontSig);
1140 if (! memq_no_quit (val, support))
1141 return 0;
1142 }
1143 else
1144 {
1145 /* Return specific matches, but play it safe. Fonts
1146 that cover more than their charset would suggest
1147 are likely to be truetype or opentype fonts,
1148 covered above. */
1149 if (EQ (val, Qlatin))
1150 {
1151 /* Although every charset but symbol, thai and
1152 arabic contains the basic ASCII set of latin
1153 characters, Emacs expects much more. */
1154 if (font->ntmTm.tmCharSet != ANSI_CHARSET)
1155 return 0;
1156 }
1157 else if (EQ (val, Qsymbol))
1158 {
1159 if (font->ntmTm.tmCharSet != SYMBOL_CHARSET)
1160 return 0;
1161 }
1162 else if (EQ (val, Qcyrillic))
1163 {
1164 if (font->ntmTm.tmCharSet != RUSSIAN_CHARSET)
1165 return 0;
1166 }
1167 else if (EQ (val, Qgreek))
1168 {
1169 if (font->ntmTm.tmCharSet != GREEK_CHARSET)
1170 return 0;
1171 }
1172 else if (EQ (val, Qarabic))
1173 {
1174 if (font->ntmTm.tmCharSet != ARABIC_CHARSET)
1175 return 0;
1176 }
1177 else if (EQ (val, Qhebrew))
1178 {
1179 if (font->ntmTm.tmCharSet != HEBREW_CHARSET)
1180 return 0;
1181 }
1182 else if (EQ (val, Qthai))
1183 {
1184 if (font->ntmTm.tmCharSet != THAI_CHARSET)
1185 return 0;
1186 }
1187 else if (EQ (val, Qkana))
1188 {
1189 if (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
1190 return 0;
1191 }
1192 else if (EQ (val, Qbopomofo))
1193 {
1194 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET)
1195 return 0;
1196 }
1197 else if (EQ (val, Qhangul))
1198 {
1199 if (font->ntmTm.tmCharSet != HANGUL_CHARSET
1200 && font->ntmTm.tmCharSet != JOHAB_CHARSET)
1201 return 0;
1202 }
1203 else if (EQ (val, Qhan))
1204 {
1205 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET
1206 && font->ntmTm.tmCharSet != GB2312_CHARSET
1207 && font->ntmTm.tmCharSet != HANGUL_CHARSET
1208 && font->ntmTm.tmCharSet != JOHAB_CHARSET
1209 && font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
1210 return 0;
1211 }
1212 else
1213 /* Other scripts unlikely to be handled. */
1214 return 0;
1215 }
1216 }
1217 }
1218 }
1219 return 1;
1220}
1221
c960bff8
JR
1222static int
1223w32font_coverage_ok (coverage, charset)
1224 FONTSIGNATURE * coverage;
1225 BYTE charset;
1226{
1227 DWORD subrange1 = coverage->fsUsb[1];
1228
1229#define SUBRANGE1_HAN_MASK 0x08000000
1230#define SUBRANGE1_HANGEUL_MASK 0x01000000
1231#define SUBRANGE1_JAPANESE_MASK (0x00060000 | SUBRANGE1_HAN_MASK)
1232
1233 if (charset == GB2312_CHARSET || charset == CHINESEBIG5_CHARSET)
1234 {
1235 return (subrange1 & SUBRANGE1_HAN_MASK) == SUBRANGE1_HAN_MASK;
1236 }
1237 else if (charset == SHIFTJIS_CHARSET)
1238 {
1239 return (subrange1 & SUBRANGE1_JAPANESE_MASK) == SUBRANGE1_JAPANESE_MASK;
1240 }
1241 else if (charset == HANGEUL_CHARSET)
1242 {
1243 return (subrange1 & SUBRANGE1_HANGEUL_MASK) == SUBRANGE1_HANGEUL_MASK;
1244 }
1245
1246 return 1;
1247}
1248
f7a84cb4 1249/* Callback function for EnumFontFamiliesEx.
d205d43b
JR
1250 * Checks if a font matches everything we are trying to check agaist,
1251 * and if so, adds it to a list. Both the data we are checking against
1252 * and the list to which the fonts are added are passed in via the
1253 * lparam argument, in the form of a font_callback_data struct. */
20399669 1254static int CALLBACK
d205d43b 1255add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
20399669
JR
1256 ENUMLOGFONTEX *logical_font;
1257 NEWTEXTMETRICEX *physical_font;
1258 DWORD font_type;
d205d43b 1259 LPARAM lParam;
f7a84cb4 1260{
d205d43b
JR
1261 struct font_callback_data *match_data
1262 = (struct font_callback_data *) lParam;
f7a84cb4 1263
46fd1ded
JR
1264 if ((!match_data->opentype_only
1265 || (physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE))
1266 && logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
d205d43b 1267 && font_matches_spec (font_type, physical_font,
4f2a2ee2 1268 match_data->orig_font_spec)
c960bff8
JR
1269 && w32font_coverage_ok (&physical_font->ntmFontSig,
1270 match_data->pattern.lfCharSet)
4f2a2ee2
JR
1271 /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif)
1272 We limit this to raster fonts, because the test can catch some
1273 genuine fonts (eg the full name of DejaVu Sans Mono Light is actually
1274 DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will
1275 therefore get through this test. Since full names can be prefixed
1276 by a foundry, we accept raster fonts if the font name is found
1277 anywhere within the full name. */
1278 && (logical_font->elfLogFont.lfOutPrecision != OUT_STRING_PRECIS
1279 || strstr (logical_font->elfFullName,
1280 logical_font->elfLogFont.lfFaceName)))
d205d43b
JR
1281 {
1282 Lisp_Object entity
1283 = w32_enumfont_pattern_entity (match_data->frame, logical_font,
91583281 1284 physical_font, font_type,
34fd2d28
JR
1285 &match_data->pattern,
1286 match_data->opentype_only
1287 ? Quniscribe : Qgdi);
d205d43b
JR
1288 if (!NILP (entity))
1289 match_data->list = Fcons (entity, match_data->list);
1290 }
f7a84cb4
JR
1291 return 1;
1292}
1293
1294/* Callback function for EnumFontFamiliesEx.
d205d43b 1295 * Terminates the search once we have a match. */
20399669 1296static int CALLBACK
d205d43b 1297add_one_font_entity_to_list (logical_font, physical_font, font_type, lParam)
20399669
JR
1298 ENUMLOGFONTEX *logical_font;
1299 NEWTEXTMETRICEX *physical_font;
1300 DWORD font_type;
d205d43b 1301 LPARAM lParam;
f7a84cb4 1302{
d205d43b
JR
1303 struct font_callback_data *match_data
1304 = (struct font_callback_data *) lParam;
1305 add_font_entity_to_list (logical_font, physical_font, font_type, lParam);
1306
1307 /* If we have a font in the list, terminate the search. */
1308 return !NILP (match_data->list);
f7a84cb4
JR
1309}
1310
1311/* Convert a Lisp font registry (symbol) to a windows charset. */
20399669
JR
1312static LONG
1313registry_to_w32_charset (charset)
1314 Lisp_Object charset;
f7a84cb4
JR
1315{
1316 if (EQ (charset, Qiso10646_1) || EQ (charset, Qunicode_bmp)
1317 || EQ (charset, Qunicode_sip))
1318 return DEFAULT_CHARSET; /* UNICODE_CHARSET not defined in MingW32 */
1319 else if (EQ (charset, Qiso8859_1))
1320 return ANSI_CHARSET;
040fe918
JR
1321 else if (SYMBOLP (charset))
1322 return x_to_w32_charset (SDATA (SYMBOL_NAME (charset)));
f7a84cb4
JR
1323 else if (STRINGP (charset))
1324 return x_to_w32_charset (SDATA (charset));
1325 else
1326 return DEFAULT_CHARSET;
1327}
1328
20399669 1329static Lisp_Object
c960bff8 1330w32_registry (w32_charset, font_type)
20399669 1331 LONG w32_charset;
c960bff8 1332 DWORD font_type;
f7a84cb4 1333{
c960bff8
JR
1334 /* If charset is defaulted, use ANSI (unicode for truetype fonts). */
1335 if (w32_charset == DEFAULT_CHARSET)
1336 w32_charset = ANSI_CHARSET;
1337
1338 if (font_type == TRUETYPE_FONTTYPE && w32_charset == ANSI_CHARSET)
d205d43b 1339 return Qiso10646_1;
f7a84cb4 1340 else
040fe918
JR
1341 {
1342 char * charset = w32_to_x_charset (w32_charset, NULL);
1343 return intern_downcase (charset, strlen(charset));
1344 }
f7a84cb4
JR
1345}
1346
f7a84cb4 1347/* Fill in all the available details of LOGFONT from FONT_SPEC. */
20399669
JR
1348static void
1349fill_in_logfont (f, logfont, font_spec)
1350 FRAME_PTR f;
1351 LOGFONT *logfont;
1352 Lisp_Object font_spec;
f7a84cb4 1353{
d205d43b 1354 Lisp_Object tmp, extra;
f7a84cb4
JR
1355 int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
1356
d205d43b
JR
1357 extra = AREF (font_spec, FONT_EXTRA_INDEX);
1358 /* Allow user to override dpi settings. */
1359 if (CONSP (extra))
1360 {
1361 tmp = assq_no_quit (QCdpi, extra);
1362 if (CONSP (tmp) && INTEGERP (XCDR (tmp)))
1363 {
1364 dpi = XINT (XCDR (tmp));
1365 }
1366 else if (CONSP (tmp) && FLOATP (XCDR (tmp)))
1367 {
1368 dpi = (int) (XFLOAT_DATA (XCDR (tmp)) + 0.5);
1369 }
1370 }
f7a84cb4
JR
1371
1372 /* Height */
1373 tmp = AREF (font_spec, FONT_SIZE_INDEX);
1374 if (INTEGERP (tmp))
040fe918 1375 logfont->lfHeight = -1 * XINT (tmp);
f7a84cb4 1376 else if (FLOATP (tmp))
d205d43b 1377 logfont->lfHeight = (int) (-1.0 * dpi * XFLOAT_DATA (tmp) / 72.27 + 0.5);
f7a84cb4
JR
1378
1379 /* Escapement */
1380
1381 /* Orientation */
1382
1383 /* Weight */
1384 tmp = AREF (font_spec, FONT_WEIGHT_INDEX);
1385 if (INTEGERP (tmp))
1386 logfont->lfWeight = XINT (tmp);
1387
1388 /* Italic */
1389 tmp = AREF (font_spec, FONT_SLANT_INDEX);
1390 if (INTEGERP (tmp))
1391 {
1392 int slant = XINT (tmp);
1393 logfont->lfItalic = slant > 150 ? 1 : 0;
1394 }
1395
1396 /* Underline */
1397
1398 /* Strikeout */
1399
1400 /* Charset */
1401 tmp = AREF (font_spec, FONT_REGISTRY_INDEX);
1402 if (! NILP (tmp))
d205d43b 1403 logfont->lfCharSet = registry_to_w32_charset (tmp);
f7a84cb4
JR
1404
1405 /* Out Precision */
91583281 1406
f7a84cb4 1407 /* Clip Precision */
91583281
JR
1408
1409 /* Quality */
040fe918
JR
1410 logfont->lfQuality = DEFAULT_QUALITY;
1411
d205d43b
JR
1412 /* Generic Family and Face Name */
1413 logfont->lfPitchAndFamily = FF_DONTCARE | DEFAULT_PITCH;
1414
f7a84cb4 1415 tmp = AREF (font_spec, FONT_FAMILY_INDEX);
d205d43b
JR
1416 if (! NILP (tmp))
1417 {
1418 logfont->lfPitchAndFamily = w32_generic_family (tmp) | DEFAULT_PITCH;
1419 if ((logfont->lfPitchAndFamily & 0xF0) != FF_DONTCARE)
1420 ; /* Font name was generic, don't fill in font name. */
1421 /* Font families are interned, but allow for strings also in case of
1422 user input. */
1423 else if (SYMBOLP (tmp))
1424 strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE);
1425 else if (STRINGP (tmp))
1426 strncpy (logfont->lfFaceName, SDATA (tmp), LF_FACESIZE);
1427 }
f7a84cb4 1428
9e1a2995
JR
1429 tmp = AREF (font_spec, FONT_ADSTYLE_INDEX);
1430 if (!NILP (tmp))
1431 {
1432 /* Override generic family. */
1433 BYTE family = w32_generic_family (tmp);
1434 if (family != FF_DONTCARE)
1435 logfont->lfPitchAndFamily = family | DEFAULT_PITCH;
1436 }
1437
d205d43b
JR
1438 /* Process EXTRA info. */
1439 for ( ; CONSP (extra); extra = XCDR (extra))
1440 {
1441 tmp = XCAR (extra);
1442 if (CONSP (tmp))
1443 {
1444 Lisp_Object key, val;
1445 key = XCAR (tmp), val = XCDR (tmp);
9e1a2995 1446 if (EQ (key, QCspacing))
d205d43b
JR
1447 {
1448 /* Set pitch based on the spacing property. */
1449 if (INTEGERP (val))
1450 {
1451 int spacing = XINT (val);
1452 if (spacing < FONT_SPACING_MONO)
1453 logfont->lfPitchAndFamily
1454 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
1455 else
1456 logfont->lfPitchAndFamily
1457 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
1458 }
1459 else if (EQ (val, Qp))
1460 logfont->lfPitchAndFamily
1461 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
1462 else if (EQ (val, Qc) || EQ (val, Qm))
1463 logfont->lfPitchAndFamily
1464 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
1465 }
1466 /* Only use QCscript if charset is not provided, or is unicode
1467 and a single script is specified. This is rather crude,
1468 and is only used to narrow down the fonts returned where
1469 there is a definite match. Some scripts, such as latin, han,
1470 cjk-misc match multiple lfCharSet values, so we can't pre-filter
1471 them. */
1472 else if (EQ (key, QCscript)
1473 && logfont->lfCharSet == DEFAULT_CHARSET
1474 && SYMBOLP (val))
1475 {
1476 if (EQ (val, Qgreek))
1477 logfont->lfCharSet = GREEK_CHARSET;
1478 else if (EQ (val, Qhangul))
1479 logfont->lfCharSet = HANGUL_CHARSET;
1480 else if (EQ (val, Qkana) || EQ (val, Qkanbun))
1481 logfont->lfCharSet = SHIFTJIS_CHARSET;
1482 else if (EQ (val, Qbopomofo))
1483 logfont->lfCharSet = CHINESEBIG5_CHARSET;
1484 /* GB 18030 supports tibetan, yi, mongolian,
1485 fonts that support it should show up if we ask for
1486 GB2312 fonts. */
1487 else if (EQ (val, Qtibetan) || EQ (val, Qyi)
1488 || EQ (val, Qmongolian))
1489 logfont->lfCharSet = GB2312_CHARSET;
1490 else if (EQ (val, Qhebrew))
1491 logfont->lfCharSet = HEBREW_CHARSET;
1492 else if (EQ (val, Qarabic))
1493 logfont->lfCharSet = ARABIC_CHARSET;
1494 else if (EQ (val, Qthai))
1495 logfont->lfCharSet = THAI_CHARSET;
1496 else if (EQ (val, Qsymbol))
1497 logfont->lfCharSet = SYMBOL_CHARSET;
1498 }
91583281
JR
1499 else if (EQ (key, QCantialias) && SYMBOLP (val))
1500 {
1501 logfont->lfQuality = w32_antialias_type (val);
1502 }
d205d43b
JR
1503 }
1504 }
f7a84cb4
JR
1505}
1506
20399669 1507static void
d205d43b
JR
1508list_all_matching_fonts (match_data)
1509 struct font_callback_data *match_data;
f7a84cb4
JR
1510{
1511 HDC dc;
d205d43b
JR
1512 Lisp_Object families = w32font_list_family (match_data->frame);
1513 struct frame *f = XFRAME (match_data->frame);
f7a84cb4
JR
1514
1515 dc = get_frame_dc (f);
1516
1517 while (!NILP (families))
1518 {
d205d43b
JR
1519 /* TODO: Use the Unicode versions of the W32 APIs, so we can
1520 handle non-ASCII font names. */
1521 char *name;
f7a84cb4
JR
1522 Lisp_Object family = CAR (families);
1523 families = CDR (families);
d205d43b
JR
1524 if (NILP (family))
1525 continue;
1526 else if (STRINGP (family))
1527 name = SDATA (family);
1528 else
1529 name = SDATA (SYMBOL_NAME (family));
1530
1531 strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE);
1532 match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0';
1533
1534 EnumFontFamiliesEx (dc, &match_data->pattern,
1535 (FONTENUMPROC) add_font_entity_to_list,
1536 (LPARAM) match_data, 0);
f7a84cb4
JR
1537 }
1538
1539 release_frame_dc (f, dc);
1540}
1541
91583281
JR
1542static Lisp_Object
1543lispy_antialias_type (type)
1544 BYTE type;
1545{
1546 Lisp_Object lispy;
1547
1548 switch (type)
1549 {
1550 case NONANTIALIASED_QUALITY:
1551 lispy = Qnone;
1552 break;
1553 case ANTIALIASED_QUALITY:
1554 lispy = Qstandard;
1555 break;
1556 case CLEARTYPE_QUALITY:
1557 lispy = Qsubpixel;
1558 break;
1559 case CLEARTYPE_NATURAL_QUALITY:
1560 lispy = Qnatural;
1561 break;
1562 default:
1563 lispy = Qnil;
1564 break;
1565 }
1566 return lispy;
1567}
1568
1569/* Convert antialiasing symbols to lfQuality */
1570static BYTE
1571w32_antialias_type (type)
1572 Lisp_Object type;
1573{
1574 if (EQ (type, Qnone))
1575 return NONANTIALIASED_QUALITY;
1576 else if (EQ (type, Qstandard))
1577 return ANTIALIASED_QUALITY;
1578 else if (EQ (type, Qsubpixel))
1579 return CLEARTYPE_QUALITY;
1580 else if (EQ (type, Qnatural))
1581 return CLEARTYPE_NATURAL_QUALITY;
1582 else
1583 return DEFAULT_QUALITY;
1584}
1585
d205d43b
JR
1586/* Return a list of all the scripts that the font supports. */
1587static Lisp_Object
1588font_supported_scripts (FONTSIGNATURE * sig)
f7a84cb4 1589{
d205d43b
JR
1590 DWORD * subranges = sig->fsUsb;
1591 Lisp_Object supported = Qnil;
1592
1593 /* Match a single subrange. SYM is set if bit N is set in subranges. */
1594#define SUBRANGE(n,sym) \
1595 if (subranges[(n) / 32] & (1 << ((n) % 32))) \
1596 supported = Fcons ((sym), supported)
1597
1598 /* Match multiple subranges. SYM is set if any MASK bit is set in
1599 subranges[0 - 3]. */
1600#define MASK_ANY(mask0,mask1,mask2,mask3,sym) \
1601 if ((subranges[0] & (mask0)) || (subranges[1] & (mask1)) \
1602 || (subranges[2] & (mask2)) || (subranges[3] & (mask3))) \
1603 supported = Fcons ((sym), supported)
1604
1605 SUBRANGE (0, Qlatin); /* There are many others... */
1606
1607 SUBRANGE (7, Qgreek);
1608 SUBRANGE (8, Qcoptic);
1609 SUBRANGE (9, Qcyrillic);
1610 SUBRANGE (10, Qarmenian);
1611 SUBRANGE (11, Qhebrew);
1612 SUBRANGE (13, Qarabic);
1613 SUBRANGE (14, Qnko);
1614 SUBRANGE (15, Qdevanagari);
1615 SUBRANGE (16, Qbengali);
1616 SUBRANGE (17, Qgurmukhi);
1617 SUBRANGE (18, Qgujarati);
1618 SUBRANGE (19, Qoriya);
1619 SUBRANGE (20, Qtamil);
1620 SUBRANGE (21, Qtelugu);
1621 SUBRANGE (22, Qkannada);
1622 SUBRANGE (23, Qmalayalam);
1623 SUBRANGE (24, Qthai);
1624 SUBRANGE (25, Qlao);
1625 SUBRANGE (26, Qgeorgian);
1626
1627 SUBRANGE (48, Qcjk_misc);
1628 SUBRANGE (51, Qbopomofo);
1629 SUBRANGE (54, Qkanbun); /* Is this right? */
1630 SUBRANGE (56, Qhangul);
1631
1632 SUBRANGE (59, Qhan); /* There are others, but this is the main one. */
1633 SUBRANGE (59, Qideographic_description); /* Windows lumps this in */
1634
1635 SUBRANGE (70, Qtibetan);
1636 SUBRANGE (71, Qsyriac);
1637 SUBRANGE (72, Qthaana);
1638 SUBRANGE (73, Qsinhala);
1639 SUBRANGE (74, Qmyanmar);
1640 SUBRANGE (75, Qethiopic);
1641 SUBRANGE (76, Qcherokee);
1642 SUBRANGE (77, Qcanadian_aboriginal);
1643 SUBRANGE (78, Qogham);
1644 SUBRANGE (79, Qrunic);
1645 SUBRANGE (80, Qkhmer);
1646 SUBRANGE (81, Qmongolian);
1647 SUBRANGE (82, Qbraille);
1648 SUBRANGE (83, Qyi);
1649
1650 SUBRANGE (88, Qbyzantine_musical_symbol);
1651 SUBRANGE (88, Qmusical_symbol); /* Windows doesn't distinguish these. */
1652
1653 SUBRANGE (89, Qmathematical);
1654
1655 /* Match either katakana or hiragana for kana. */
1656 MASK_ANY (0, 0x00060000, 0, 0, Qkana);
1657
1658 /* There isn't really a main symbol range, so include symbol if any
1659 relevant range is set. */
1660 MASK_ANY (0x8000000, 0x0000FFFF, 0, 0, Qsymbol);
1661
1662#undef SUBRANGE
1663#undef MASK_ANY
1664
1665 return supported;
f7a84cb4
JR
1666}
1667
67997c79
JR
1668/* Generate a full name for a Windows font.
1669 The full name is in fcname format, with weight, slant and antialiasing
1670 specified if they are not "normal". */
1671static int
1672w32font_full_name (font, font_obj, pixel_size, name, nbytes)
1673 LOGFONT * font;
1674 Lisp_Object font_obj;
1675 int pixel_size;
1676 char *name;
1677 int nbytes;
1678{
a823468b 1679 int len, height, outline;
67997c79
JR
1680 char *p;
1681 Lisp_Object antialiasing, weight = Qnil;
1682
a823468b
JR
1683 len = strlen (font->lfFaceName);
1684
1685 outline = EQ (AREF (font_obj, FONT_FOUNDRY_INDEX), Qoutline);
1686
1687 /* Represent size of scalable fonts by point size. But use pixelsize for
1688 raster fonts to indicate that they are exactly that size. */
1689 if (outline)
1690 len += 11; /* -SIZE */
1691 else
1692 len = strlen (font->lfFaceName) + 21;
67997c79
JR
1693
1694 if (font->lfItalic)
1695 len += 7; /* :italic */
1696
1697 if (font->lfWeight && font->lfWeight != FW_NORMAL)
1698 {
1699 weight = font_symbolic_weight (font_obj);
1700 len += 8 + SBYTES (SYMBOL_NAME (weight)); /* :weight=NAME */
1701 }
1702
1703 antialiasing = lispy_antialias_type (font->lfQuality);
1704 if (! NILP (antialiasing))
1705 len += 11 + SBYTES (SYMBOL_NAME (antialiasing)); /* :antialias=NAME */
1706
1707 /* Check that the buffer is big enough */
1708 if (len > nbytes)
1709 return -1;
1710
1711 p = name;
1712 p += sprintf (p, "%s", font->lfFaceName);
1713
a823468b
JR
1714 height = font->lfHeight ? eabs (font->lfHeight) : pixel_size;
1715
1716 if (height > 0)
1717 {
1718 if (outline)
1719 {
1720 float pointsize = height * 72.0 / one_w32_display_info.resy;
7145be81
JR
1721 /* Round to nearest half point. floor is used, since round is not
1722 supported in MS library. */
1723 pointsize = floor (pointsize * 2 + 0.5) / 2;
a823468b
JR
1724 p += sprintf (p, "-%1.1f", pointsize);
1725 }
1726 else
1727 p += sprintf (p, ":pixelsize=%d", height);
1728 }
67997c79
JR
1729
1730 if (font->lfItalic)
1731 p += sprintf (p, ":italic");
1732
1733 if (SYMBOLP (weight) && ! NILP (weight))
1734 p += sprintf (p, ":weight=%s", SDATA (SYMBOL_NAME (weight)));
1735
1736 if (SYMBOLP (antialiasing) && ! NILP (antialiasing))
1737 p += sprintf (p, ":antialias=%s", SDATA (SYMBOL_NAME (antialiasing)));
1738
1739 return (p - name);
1740}
f7a84cb4 1741
34fd2d28
JR
1742
1743static void
54efdcd1 1744recompute_cached_metrics (dc, w32_font)
34fd2d28 1745 HDC dc;
54efdcd1 1746 struct w32font_info *w32_font;
34fd2d28
JR
1747{
1748 GLYPHMETRICS gm;
1749 MAT2 transform;
54efdcd1 1750 unsigned int i;
34fd2d28
JR
1751
1752 bzero (&transform, sizeof (transform));
1753 transform.eM11.value = 1;
1754 transform.eM22.value = 1;
1755
1756 for (i = 0; i < 128; i++)
1757 {
1758 struct font_metrics* char_metric = &w32_font->ascii_metrics[i];
54efdcd1
JR
1759 unsigned int options = GGO_METRICS;
1760 if (w32_font->glyph_idx)
1761 options |= GGO_GLYPH_INDEX;
34fd2d28 1762
54efdcd1
JR
1763 if (GetGlyphOutlineW (dc, i, options, &gm, 0, NULL, &transform)
1764 != GDI_ERROR)
34fd2d28
JR
1765 {
1766 char_metric->lbearing = -gm.gmptGlyphOrigin.x;
1767 char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x;
1768 char_metric->width = gm.gmCellIncX;
1769 char_metric->ascent = -gm.gmptGlyphOrigin.y;
1770 char_metric->descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
1771 }
1772 else
1773 char_metric->width = 0;
1774 }
1775}
1776
f7a84cb4
JR
1777struct font_driver w32font_driver =
1778 {
8eac0c84 1779 0, /* Qgdi */
f7a84cb4
JR
1780 w32font_get_cache,
1781 w32font_list,
1782 w32font_match,
1783 w32font_list_family,
1784 NULL, /* free_entity */
1785 w32font_open,
1786 w32font_close,
1787 NULL, /* prepare_face */
1788 NULL, /* done_face */
1789 w32font_has_char,
1790 w32font_encode_char,
1791 w32font_text_extents,
1792 w32font_draw,
1793 NULL, /* get_bitmap */
1794 NULL, /* free_bitmap */
1795 NULL, /* get_outline */
1796 NULL, /* free_outline */
1797 NULL, /* anchor_point */
1798 NULL, /* otf_capability */
5b0c3446
JR
1799 NULL, /* otf_drive */
1800 NULL, /* start_for_frame */
1801 NULL, /* end_for_frame */
1802 NULL /* shape */
f7a84cb4
JR
1803 };
1804
f7a84cb4
JR
1805
1806/* Initialize state that does not change between invocations. This is only
1807 called when Emacs is dumped. */
20399669
JR
1808void
1809syms_of_w32font ()
f7a84cb4 1810{
8eac0c84 1811 DEFSYM (Qgdi, "gdi");
34fd2d28
JR
1812 DEFSYM (Quniscribe, "uniscribe");
1813 DEFSYM (QCformat, ":format");
d205d43b
JR
1814
1815 /* Generic font families. */
1816 DEFSYM (Qmonospace, "monospace");
1817 DEFSYM (Qserif, "serif");
9e1a2995 1818 DEFSYM (Qsansserif, "sansserif");
f7a84cb4 1819 DEFSYM (Qscript, "script");
d205d43b
JR
1820 DEFSYM (Qdecorative, "decorative");
1821 /* Aliases. */
9e1a2995 1822 DEFSYM (Qsans_serif, "sans_serif");
d205d43b
JR
1823 DEFSYM (Qsans, "sans");
1824 DEFSYM (Qmono, "mono");
1825
1826 /* Fake foundries. */
1827 DEFSYM (Qraster, "raster");
1828 DEFSYM (Qoutline, "outline");
f7a84cb4 1829 DEFSYM (Qunknown, "unknown");
d205d43b 1830
91583281
JR
1831 /* Antialiasing. */
1832 DEFSYM (Qstandard, "standard");
1833 DEFSYM (Qsubpixel, "subpixel");
1834 DEFSYM (Qnatural, "natural");
d205d43b
JR
1835
1836 /* Scripts */
1837 DEFSYM (Qlatin, "latin");
1838 DEFSYM (Qgreek, "greek");
1839 DEFSYM (Qcoptic, "coptic");
1840 DEFSYM (Qcyrillic, "cyrillic");
1841 DEFSYM (Qarmenian, "armenian");
1842 DEFSYM (Qhebrew, "hebrew");
1843 DEFSYM (Qarabic, "arabic");
1844 DEFSYM (Qsyriac, "syriac");
1845 DEFSYM (Qnko, "nko");
1846 DEFSYM (Qthaana, "thaana");
1847 DEFSYM (Qdevanagari, "devanagari");
1848 DEFSYM (Qbengali, "bengali");
1849 DEFSYM (Qgurmukhi, "gurmukhi");
1850 DEFSYM (Qgujarati, "gujarati");
1851 DEFSYM (Qoriya, "oriya");
1852 DEFSYM (Qtamil, "tamil");
1853 DEFSYM (Qtelugu, "telugu");
1854 DEFSYM (Qkannada, "kannada");
1855 DEFSYM (Qmalayalam, "malayalam");
1856 DEFSYM (Qsinhala, "sinhala");
1857 DEFSYM (Qthai, "thai");
1858 DEFSYM (Qlao, "lao");
1859 DEFSYM (Qtibetan, "tibetan");
1860 DEFSYM (Qmyanmar, "myanmar");
1861 DEFSYM (Qgeorgian, "georgian");
1862 DEFSYM (Qhangul, "hangul");
1863 DEFSYM (Qethiopic, "ethiopic");
1864 DEFSYM (Qcherokee, "cherokee");
1865 DEFSYM (Qcanadian_aboriginal, "canadian-aboriginal");
1866 DEFSYM (Qogham, "ogham");
1867 DEFSYM (Qrunic, "runic");
1868 DEFSYM (Qkhmer, "khmer");
1869 DEFSYM (Qmongolian, "mongolian");
1870 DEFSYM (Qsymbol, "symbol");
1871 DEFSYM (Qbraille, "braille");
1872 DEFSYM (Qhan, "han");
1873 DEFSYM (Qideographic_description, "ideographic-description");
1874 DEFSYM (Qcjk_misc, "cjk-misc");
1875 DEFSYM (Qkana, "kana");
1876 DEFSYM (Qbopomofo, "bopomofo");
1877 DEFSYM (Qkanbun, "kanbun");
1878 DEFSYM (Qyi, "yi");
1879 DEFSYM (Qbyzantine_musical_symbol, "byzantine-musical-symbol");
1880 DEFSYM (Qmusical_symbol, "musical-symbol");
1881 DEFSYM (Qmathematical, "mathematical");
1882
8eac0c84 1883 w32font_driver.type = Qgdi;
f7a84cb4
JR
1884 register_font_driver (&w32font_driver, NULL);
1885}
c6900278 1886#endif /* USE_FONT_BACKEND */
6d8c85b5
MB
1887
1888/* arch-tag: 65b8a3cd-46aa-4c0d-a1f3-99e75b9c07ee
1889 (do not change this comment) */