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