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