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