Fix copyright years and license notices.
[emacs.git] / src / w32font.c
blob74c74ee0750ed9822efe20ddec197df52e32c845
1 /* Font backend for the Microsoft W32 API.
2 Copyright (C) 2007, 2008 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 #include <config.h>
20 #include <windows.h>
21 #include <math.h>
22 #include <ctype.h>
23 #include <commdlg.h>
25 #include "lisp.h"
26 #include "w32term.h"
27 #include "frame.h"
28 #include "dispextern.h"
29 #include "character.h"
30 #include "charset.h"
31 #include "fontset.h"
32 #include "font.h"
33 #include "w32font.h"
35 /* Cleartype available on Windows XP, cleartype_natural from XP SP1.
36 The latter does not try to fit cleartype smoothed fonts into the
37 same bounding box as the non-antialiased version of the font.
39 #ifndef CLEARTYPE_QUALITY
40 #define CLEARTYPE_QUALITY 5
41 #endif
42 #ifndef CLEARTYPE_NATURAL_QUALITY
43 #define CLEARTYPE_NATURAL_QUALITY 6
44 #endif
46 /* VIETNAMESE_CHARSET and JOHAB_CHARSET are not defined in some versions
47 of MSVC headers. */
48 #ifndef VIETNAMESE_CHARSET
49 #define VIETNAMESE_CHARSET 163
50 #endif
51 #ifndef JOHAB_CHARSET
52 #define JOHAB_CHARSET 130
53 #endif
55 extern struct font_driver w32font_driver;
57 Lisp_Object Qgdi;
58 Lisp_Object Quniscribe;
59 static Lisp_Object QCformat;
60 static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif;
61 static Lisp_Object Qserif, Qscript, Qdecorative;
62 static Lisp_Object Qraster, Qoutline, Qunknown;
64 /* antialiasing */
65 extern Lisp_Object QCantialias, QCotf, QClang; /* defined in font.c */
66 extern Lisp_Object Qnone; /* reuse from w32fns.c */
67 static Lisp_Object Qstandard, Qsubpixel, Qnatural;
69 /* languages */
70 static Lisp_Object Qja, Qko, Qzh;
72 /* scripts */
73 static Lisp_Object Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
74 static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali;
75 static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu;
76 static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao;
77 static Lisp_Object Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic;
78 static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic;
79 static Lisp_Object Qkhmer, Qmongolian, Qsymbol, Qbraille, Qhan;
80 static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo;
81 static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol;
82 static Lisp_Object Qmusical_symbol, Qmathematical;
83 /* Not defined in characters.el, but referenced in fontset.el. */
84 static Lisp_Object Qbalinese, Qbuginese, Qbuhid, Qcuneiform, Qcypriot;
85 static Lisp_Object Qdeseret, Qglagolitic, Qgothic, Qhanunoo, Qkharoshthi;
86 static Lisp_Object Qlimbu, Qlinear_b, Qold_italic, Qold_persian, Qosmanya;
87 static Lisp_Object Qphags_pa, Qphoenician, Qshavian, Qsyloti_nagri;
88 static Lisp_Object Qtagalog, Qtagbanwa, Qtai_le, Qtifinagh, Qugaritic;
89 /* Only defined here, but useful for distinguishing IPA capable fonts. */
90 static Lisp_Object Qphonetic;
92 /* W32 charsets: for use in Vw32_charset_info_alist. */
93 static Lisp_Object Qw32_charset_ansi, Qw32_charset_default;
94 static Lisp_Object Qw32_charset_symbol, Qw32_charset_shiftjis;
95 static Lisp_Object Qw32_charset_hangeul, Qw32_charset_gb2312;
96 static Lisp_Object Qw32_charset_chinesebig5, Qw32_charset_oem;
97 static Lisp_Object Qw32_charset_easteurope, Qw32_charset_turkish;
98 static Lisp_Object Qw32_charset_baltic, Qw32_charset_russian;
99 static Lisp_Object Qw32_charset_arabic, Qw32_charset_greek;
100 static Lisp_Object Qw32_charset_hebrew, Qw32_charset_vietnamese;
101 static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac;
103 /* Associative list linking character set strings to Windows codepages. */
104 static Lisp_Object Vw32_charset_info_alist;
106 /* Font spacing symbols - defined in font.c. */
107 extern Lisp_Object Qc, Qp, Qm;
109 static void fill_in_logfont P_ ((FRAME_PTR, LOGFONT *, Lisp_Object));
111 static BYTE w32_antialias_type P_ ((Lisp_Object));
112 static Lisp_Object lispy_antialias_type P_ ((BYTE));
114 static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE *));
115 static int w32font_full_name P_ ((LOGFONT *, Lisp_Object, int, char *, int));
116 static void compute_metrics P_ ((HDC, struct w32font_info *, unsigned int,
117 struct w32_metric_cache *));
118 static void clear_cached_metrics P_ ((struct w32font_info *));
120 static Lisp_Object w32_registry P_ ((LONG, DWORD));
122 /* EnumFontFamiliesEx callbacks. */
123 static int CALLBACK add_font_entity_to_list P_ ((ENUMLOGFONTEX *,
124 NEWTEXTMETRICEX *,
125 DWORD, LPARAM));
126 static int CALLBACK add_one_font_entity_to_list P_ ((ENUMLOGFONTEX *,
127 NEWTEXTMETRICEX *,
128 DWORD, LPARAM));
129 static int CALLBACK add_font_name_to_list P_ ((ENUMLOGFONTEX *,
130 NEWTEXTMETRICEX *,
131 DWORD, LPARAM));
133 /* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
134 of what we really want. */
135 struct font_callback_data
137 /* The logfont we are matching against. EnumFontFamiliesEx only matches
138 face name and charset, so we need to manually match everything else
139 in the callback function. */
140 LOGFONT pattern;
141 /* The original font spec or entity. */
142 Lisp_Object orig_font_spec;
143 /* The frame the font is being loaded on. */
144 Lisp_Object frame;
145 /* The list to add matches to. */
146 Lisp_Object list;
147 /* Whether to match only opentype fonts. */
148 int opentype_only;
151 /* Handles the problem that EnumFontFamiliesEx will not return all
152 style variations if the font name is not specified. */
153 static void list_all_matching_fonts P_ ((struct font_callback_data *));
156 static int
157 memq_no_quit (elt, list)
158 Lisp_Object elt, list;
160 while (CONSP (list) && ! EQ (XCAR (list), elt))
161 list = XCDR (list);
162 return (CONSP (list));
165 /* w32 implementation of get_cache for font backend.
166 Return a cache of font-entities on FRAME. The cache must be a
167 cons whose cdr part is the actual cache area. */
168 Lisp_Object
169 w32font_get_cache (f)
170 FRAME_PTR f;
172 struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
174 return (dpyinfo->name_list_element);
177 /* w32 implementation of list for font backend.
178 List fonts exactly matching with FONT_SPEC on FRAME. The value
179 is a vector of font-entities. This is the sole API that
180 allocates font-entities. */
181 static Lisp_Object
182 w32font_list (frame, font_spec)
183 Lisp_Object frame, font_spec;
185 Lisp_Object fonts = w32font_list_internal (frame, font_spec, 0);
186 font_add_log ("w32font-list", font_spec, fonts);
187 return fonts;
190 /* w32 implementation of match for font backend.
191 Return a font entity most closely matching with FONT_SPEC on
192 FRAME. The closeness is detemined by the font backend, thus
193 `face-font-selection-order' is ignored here. */
194 static Lisp_Object
195 w32font_match (frame, font_spec)
196 Lisp_Object frame, font_spec;
198 Lisp_Object entity = w32font_match_internal (frame, font_spec, 0);
199 font_add_log ("w32font-match", font_spec, entity);
200 return entity;
203 /* w32 implementation of list_family for font backend.
204 List available families. The value is a list of family names
205 (symbols). */
206 static Lisp_Object
207 w32font_list_family (frame)
208 Lisp_Object frame;
210 Lisp_Object list = Qnil;
211 LOGFONT font_match_pattern;
212 HDC dc;
213 FRAME_PTR f = XFRAME (frame);
215 bzero (&font_match_pattern, sizeof (font_match_pattern));
216 font_match_pattern.lfCharSet = DEFAULT_CHARSET;
218 dc = get_frame_dc (f);
220 EnumFontFamiliesEx (dc, &font_match_pattern,
221 (FONTENUMPROC) add_font_name_to_list,
222 (LPARAM) &list, 0);
223 release_frame_dc (f, dc);
225 return list;
228 /* w32 implementation of open for font backend.
229 Open a font specified by FONT_ENTITY on frame F.
230 If the font is scalable, open it with PIXEL_SIZE. */
231 static Lisp_Object
232 w32font_open (f, font_entity, pixel_size)
233 FRAME_PTR f;
234 Lisp_Object font_entity;
235 int pixel_size;
237 Lisp_Object font_object
238 = font_make_object (VECSIZE (struct w32font_info),
239 font_entity, pixel_size);
240 struct w32font_info *w32_font
241 = (struct w32font_info *) XFONT_OBJECT (font_object);
243 ASET (font_object, FONT_TYPE_INDEX, Qgdi);
245 if (!w32font_open_internal (f, font_entity, pixel_size, font_object))
247 return Qnil;
250 /* GDI backend does not use glyph indices. */
251 w32_font->glyph_idx = 0;
253 return font_object;
256 /* w32 implementation of close for font_backend.
257 Close FONT on frame F. */
258 void
259 w32font_close (f, font)
260 FRAME_PTR f;
261 struct font *font;
263 int i;
264 struct w32font_info *w32_font = (struct w32font_info *) font;
266 /* Delete the GDI font object. */
267 DeleteObject (w32_font->hfont);
269 /* Free all the cached metrics. */
270 if (w32_font->cached_metrics)
272 for (i = 0; i < w32_font->n_cache_blocks; i++)
274 if (w32_font->cached_metrics[i])
275 xfree (w32_font->cached_metrics[i]);
277 xfree (w32_font->cached_metrics);
278 w32_font->cached_metrics = NULL;
282 /* w32 implementation of has_char for font backend.
283 Optional.
284 If FONT_ENTITY has a glyph for character C (Unicode code point),
285 return 1. If not, return 0. If a font must be opened to check
286 it, return -1. */
288 w32font_has_char (entity, c)
289 Lisp_Object entity;
290 int c;
292 Lisp_Object supported_scripts, extra, script;
293 DWORD mask;
295 extra = AREF (entity, FONT_EXTRA_INDEX);
296 if (!CONSP (extra))
297 return -1;
299 supported_scripts = assq_no_quit (QCscript, extra);
300 /* If font doesn't claim to support any scripts, then we can't be certain
301 until we open it. */
302 if (!CONSP (supported_scripts))
303 return -1;
305 supported_scripts = XCDR (supported_scripts);
307 script = CHAR_TABLE_REF (Vchar_script_table, c);
309 /* If we don't know what script the character is from, then we can't be
310 certain until we open it. Also if the font claims support for the script
311 the character is from, it may only have partial coverage, so we still
312 can't be certain until we open the font. */
313 if (NILP (script) || memq_no_quit (script, supported_scripts))
314 return -1;
316 /* Font reports what scripts it supports, and none of them are the script
317 the character is from, so it is a definite no. */
318 return 0;
321 /* w32 implementation of encode_char for font backend.
322 Return a glyph code of FONT for characer C (Unicode code point).
323 If FONT doesn't have such a glyph, return FONT_INVALID_CODE.
325 For speed, the gdi backend uses unicode (Emacs calls encode_char
326 far too often for it to be efficient). But we still need to detect
327 which characters are not supported by the font.
329 static unsigned
330 w32font_encode_char (font, c)
331 struct font *font;
332 int c;
334 struct w32font_info * w32_font = (struct w32font_info *)font;
336 if (c < w32_font->metrics.tmFirstChar
337 || c > w32_font->metrics.tmLastChar)
338 return FONT_INVALID_CODE;
339 else
340 return c;
343 /* w32 implementation of text_extents for font backend.
344 Perform the size computation of glyphs of FONT and fillin members
345 of METRICS. The glyphs are specified by their glyph codes in
346 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
347 case just return the overall width. */
349 w32font_text_extents (font, code, nglyphs, metrics)
350 struct font *font;
351 unsigned *code;
352 int nglyphs;
353 struct font_metrics *metrics;
355 int i;
356 HFONT old_font = NULL;
357 HDC dc = NULL;
358 struct frame * f;
359 int total_width = 0;
360 WORD *wcode;
361 SIZE size;
363 struct w32font_info *w32_font = (struct w32font_info *) font;
365 if (metrics)
367 bzero (metrics, sizeof (struct font_metrics));
368 metrics->ascent = font->ascent;
369 metrics->descent = font->descent;
371 for (i = 0; i < nglyphs; i++)
373 struct w32_metric_cache *char_metric;
374 int block = *(code + i) / CACHE_BLOCKSIZE;
375 int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
377 if (block >= w32_font->n_cache_blocks)
379 if (!w32_font->cached_metrics)
380 w32_font->cached_metrics
381 = xmalloc ((block + 1)
382 * sizeof (struct w32_metric_cache *));
383 else
384 w32_font->cached_metrics
385 = xrealloc (w32_font->cached_metrics,
386 (block + 1)
387 * sizeof (struct w32_metric_cache *));
388 bzero (w32_font->cached_metrics + w32_font->n_cache_blocks,
389 ((block + 1 - w32_font->n_cache_blocks)
390 * sizeof (struct w32_metric_cache *)));
391 w32_font->n_cache_blocks = block + 1;
394 if (!w32_font->cached_metrics[block])
396 w32_font->cached_metrics[block]
397 = xmalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
398 bzero (w32_font->cached_metrics[block],
399 CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
402 char_metric = w32_font->cached_metrics[block] + pos_in_block;
404 if (char_metric->status == W32METRIC_NO_ATTEMPT)
406 if (dc == NULL)
408 /* TODO: Frames can come and go, and their fonts
409 outlive them. So we can't cache the frame in the
410 font structure. Use selected_frame until the API
411 is updated to pass in a frame. */
412 f = XFRAME (selected_frame);
414 dc = get_frame_dc (f);
415 old_font = SelectObject (dc, w32_font->hfont);
417 compute_metrics (dc, w32_font, *(code + i), char_metric);
420 if (char_metric->status == W32METRIC_SUCCESS)
422 metrics->lbearing = min (metrics->lbearing,
423 metrics->width + char_metric->lbearing);
424 metrics->rbearing = max (metrics->rbearing,
425 metrics->width + char_metric->rbearing);
426 metrics->width += char_metric->width;
428 else
429 /* If we couldn't get metrics for a char,
430 use alternative method. */
431 break;
433 /* If we got through everything, return. */
434 if (i == nglyphs)
436 if (dc != NULL)
438 /* Restore state and release DC. */
439 SelectObject (dc, old_font);
440 release_frame_dc (f, dc);
443 return metrics->width;
447 /* For non-truetype fonts, GetGlyphOutlineW is not supported, so
448 fallback on other methods that will at least give some of the metric
449 information. */
451 /* Make array big enough to hold surrogates. */
452 wcode = alloca (nglyphs * sizeof (WORD) * 2);
453 for (i = 0; i < nglyphs; i++)
455 if (code[i] < 0x10000)
456 wcode[i] = code[i];
457 else
459 DWORD surrogate = code[i] - 0x10000;
461 /* High surrogate: U+D800 - U+DBFF. */
462 wcode[i++] = 0xD800 + ((surrogate >> 10) & 0x03FF);
463 /* Low surrogate: U+DC00 - U+DFFF. */
464 wcode[i] = 0xDC00 + (surrogate & 0x03FF);
465 /* An extra glyph. wcode is already double the size of code to
466 cope with this. */
467 nglyphs++;
471 if (dc == NULL)
473 /* TODO: Frames can come and go, and their fonts outlive
474 them. So we can't cache the frame in the font structure. Use
475 selected_frame until the API is updated to pass in a
476 frame. */
477 f = XFRAME (selected_frame);
479 dc = get_frame_dc (f);
480 old_font = SelectObject (dc, w32_font->hfont);
483 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
485 total_width = size.cx;
488 /* On 95/98/ME, only some unicode functions are available, so fallback
489 on doing a dummy draw to find the total width. */
490 if (!total_width)
492 RECT rect;
493 rect.top = 0; rect.bottom = font->height; rect.left = 0; rect.right = 1;
494 DrawTextW (dc, wcode, nglyphs, &rect,
495 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
496 total_width = rect.right;
499 /* Give our best estimate of the metrics, based on what we know. */
500 if (metrics)
502 metrics->width = total_width - w32_font->metrics.tmOverhang;
503 metrics->lbearing = 0;
504 metrics->rbearing = total_width;
507 /* Restore state and release DC. */
508 SelectObject (dc, old_font);
509 release_frame_dc (f, dc);
511 return total_width;
514 /* w32 implementation of draw for font backend.
515 Optional.
516 Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
517 position of frame F with S->FACE and S->GC. If WITH_BACKGROUND
518 is nonzero, fill the background in advance. It is assured that
519 WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars).
521 TODO: Currently this assumes that the colors and fonts are already
522 set in the DC. This seems to be true now, but maybe only due to
523 the old font code setting it up. It may be safer to resolve faces
524 and fonts in here and set them explicitly
528 w32font_draw (s, from, to, x, y, with_background)
529 struct glyph_string *s;
530 int from, to, x, y, with_background;
532 UINT options;
533 HRGN orig_clip;
534 struct w32font_info *w32font = (struct w32font_info *) s->font;
536 options = w32font->glyph_idx;
538 /* Save clip region for later restoration. */
539 GetClipRgn(s->hdc, orig_clip);
541 if (s->num_clips > 0)
543 HRGN new_clip = CreateRectRgnIndirect (s->clip);
545 if (s->num_clips > 1)
547 HRGN clip2 = CreateRectRgnIndirect (s->clip + 1);
549 CombineRgn (new_clip, new_clip, clip2, RGN_OR);
550 DeleteObject (clip2);
553 SelectClipRgn (s->hdc, new_clip);
554 DeleteObject (new_clip);
557 /* Using OPAQUE background mode can clear more background than expected
558 when Cleartype is used. Draw the background manually to avoid this. */
559 SetBkMode (s->hdc, TRANSPARENT);
560 if (with_background)
562 HBRUSH brush;
563 RECT rect;
564 struct font *font = s->font;
566 brush = CreateSolidBrush (s->gc->background);
567 rect.left = x;
568 rect.top = y - font->ascent;
569 rect.right = x + s->width;
570 rect.bottom = y + font->descent;
571 FillRect (s->hdc, &rect, brush);
572 DeleteObject (brush);
575 if (s->padding_p)
577 int len = to - from, i;
579 for (i = 0; i < len; i++)
580 ExtTextOutW (s->hdc, x + i, y, options, NULL,
581 s->char2b + from + i, 1, NULL);
583 else
584 ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, to - from, NULL);
586 /* Restore clip region. */
587 if (s->num_clips > 0)
589 SelectClipRgn (s->hdc, orig_clip);
593 /* w32 implementation of free_entity for font backend.
594 Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value).
595 Free FONT_EXTRA_INDEX field of FONT_ENTITY.
596 static void
597 w32font_free_entity (Lisp_Object entity);
600 /* w32 implementation of prepare_face for font backend.
601 Optional (if FACE->extra is not used).
602 Prepare FACE for displaying characters by FONT on frame F by
603 storing some data in FACE->extra. If successful, return 0.
604 Otherwise, return -1.
605 static int
606 w32font_prepare_face (FRAME_PTR f, struct face *face);
608 /* w32 implementation of done_face for font backend.
609 Optional.
610 Done FACE for displaying characters by FACE->font on frame F.
611 static void
612 w32font_done_face (FRAME_PTR f, struct face *face); */
614 /* w32 implementation of get_bitmap for font backend.
615 Optional.
616 Store bitmap data for glyph-code CODE of FONT in BITMAP. It is
617 intended that this method is called from the other font-driver
618 for actual drawing.
619 static int
620 w32font_get_bitmap (struct font *font, unsigned code,
621 struct font_bitmap *bitmap, int bits_per_pixel);
623 /* w32 implementation of free_bitmap for font backend.
624 Optional.
625 Free bitmap data in BITMAP.
626 static void
627 w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap);
629 /* w32 implementation of get_outline for font backend.
630 Optional.
631 Return an outline data for glyph-code CODE of FONT. The format
632 of the outline data depends on the font-driver.
633 static void *
634 w32font_get_outline (struct font *font, unsigned code);
636 /* w32 implementation of free_outline for font backend.
637 Optional.
638 Free OUTLINE (that is obtained by the above method).
639 static void
640 w32font_free_outline (struct font *font, void *outline);
642 /* w32 implementation of anchor_point for font backend.
643 Optional.
644 Get coordinates of the INDEXth anchor point of the glyph whose
645 code is CODE. Store the coordinates in *X and *Y. Return 0 if
646 the operations was successfull. Otherwise return -1.
647 static int
648 w32font_anchor_point (struct font *font, unsigned code,
649 int index, int *x, int *y);
651 /* w32 implementation of otf_capability for font backend.
652 Optional.
653 Return a list describing which scripts/languages FONT
654 supports by which GSUB/GPOS features of OpenType tables.
655 static Lisp_Object
656 w32font_otf_capability (struct font *font);
658 /* w32 implementation of otf_drive for font backend.
659 Optional.
660 Apply FONT's OTF-FEATURES to the glyph string.
662 FEATURES specifies which OTF features to apply in this format:
663 (SCRIPT LANGSYS GSUB-FEATURE GPOS-FEATURE)
664 See the documentation of `font-drive-otf' for the detail.
666 This method applies the specified features to the codes in the
667 elements of GSTRING-IN (between FROMth and TOth). The output
668 codes are stored in GSTRING-OUT at the IDXth element and the
669 following elements.
671 Return the number of output codes. If none of the features are
672 applicable to the input data, return 0. If GSTRING-OUT is too
673 short, return -1.
674 static int
675 w32font_otf_drive (struct font *font, Lisp_Object features,
676 Lisp_Object gstring_in, int from, int to,
677 Lisp_Object gstring_out, int idx,
678 int alternate_subst);
681 /* Internal implementation of w32font_list.
682 Additional parameter opentype_only restricts the returned fonts to
683 opentype fonts, which can be used with the Uniscribe backend. */
684 Lisp_Object
685 w32font_list_internal (frame, font_spec, opentype_only)
686 Lisp_Object frame, font_spec;
687 int opentype_only;
689 struct font_callback_data match_data;
690 HDC dc;
691 FRAME_PTR f = XFRAME (frame);
693 match_data.orig_font_spec = font_spec;
694 match_data.list = Qnil;
695 match_data.frame = frame;
697 bzero (&match_data.pattern, sizeof (LOGFONT));
698 fill_in_logfont (f, &match_data.pattern, font_spec);
700 match_data.opentype_only = opentype_only;
701 if (opentype_only)
702 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
704 if (match_data.pattern.lfFaceName[0] == '\0')
706 /* EnumFontFamiliesEx does not take other fields into account if
707 font name is blank, so need to use two passes. */
708 list_all_matching_fonts (&match_data);
710 else
712 dc = get_frame_dc (f);
714 EnumFontFamiliesEx (dc, &match_data.pattern,
715 (FONTENUMPROC) add_font_entity_to_list,
716 (LPARAM) &match_data, 0);
717 release_frame_dc (f, dc);
720 return NILP (match_data.list) ? Qnil : match_data.list;
723 /* Internal implementation of w32font_match.
724 Additional parameter opentype_only restricts the returned fonts to
725 opentype fonts, which can be used with the Uniscribe backend. */
726 Lisp_Object
727 w32font_match_internal (frame, font_spec, opentype_only)
728 Lisp_Object frame, font_spec;
729 int opentype_only;
731 struct font_callback_data match_data;
732 HDC dc;
733 FRAME_PTR f = XFRAME (frame);
735 match_data.orig_font_spec = font_spec;
736 match_data.frame = frame;
737 match_data.list = Qnil;
739 bzero (&match_data.pattern, sizeof (LOGFONT));
740 fill_in_logfont (f, &match_data.pattern, font_spec);
742 match_data.opentype_only = opentype_only;
743 if (opentype_only)
744 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
746 dc = get_frame_dc (f);
748 EnumFontFamiliesEx (dc, &match_data.pattern,
749 (FONTENUMPROC) add_one_font_entity_to_list,
750 (LPARAM) &match_data, 0);
751 release_frame_dc (f, dc);
753 return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
757 w32font_open_internal (f, font_entity, pixel_size, font_object)
758 FRAME_PTR f;
759 Lisp_Object font_entity;
760 int pixel_size;
761 Lisp_Object font_object;
763 int len, size, i;
764 LOGFONT logfont;
765 HDC dc;
766 HFONT hfont, old_font;
767 Lisp_Object val, extra;
768 struct w32font_info *w32_font;
769 struct font * font;
770 OUTLINETEXTMETRICW* metrics = NULL;
772 w32_font = (struct w32font_info *) XFONT_OBJECT (font_object);
773 font = (struct font *) w32_font;
775 if (!font)
776 return 0;
778 bzero (&logfont, sizeof (logfont));
779 fill_in_logfont (f, &logfont, font_entity);
781 /* Prefer truetype fonts, to avoid known problems with type1 fonts, and
782 limitations in bitmap fonts. */
783 val = AREF (font_entity, FONT_FOUNDRY_INDEX);
784 if (!EQ (val, Qraster))
785 logfont.lfOutPrecision = OUT_TT_PRECIS;
787 size = XINT (AREF (font_entity, FONT_SIZE_INDEX));
788 if (!size)
789 size = pixel_size;
791 logfont.lfHeight = -size;
792 hfont = CreateFontIndirect (&logfont);
794 if (hfont == NULL)
795 return 0;
797 /* Get the metrics for this font. */
798 dc = get_frame_dc (f);
799 old_font = SelectObject (dc, hfont);
801 /* Try getting the outline metrics (only works for truetype fonts). */
802 len = GetOutlineTextMetricsW (dc, 0, NULL);
803 if (len)
805 metrics = (OUTLINETEXTMETRICW *) alloca (len);
806 if (GetOutlineTextMetricsW (dc, len, metrics))
807 bcopy (&metrics->otmTextMetrics, &w32_font->metrics,
808 sizeof (TEXTMETRICW));
809 else
810 metrics = NULL;
813 if (!metrics)
815 GetTextMetricsW (dc, &w32_font->metrics);
818 w32_font->cached_metrics = NULL;
819 w32_font->n_cache_blocks = 0;
821 SelectObject (dc, old_font);
822 release_frame_dc (f, dc);
824 w32_font->hfont = hfont;
827 char *name;
829 /* We don't know how much space we need for the full name, so start with
830 96 bytes and go up in steps of 32. */
831 len = 96;
832 name = alloca (len);
833 while (name && w32font_full_name (&logfont, font_entity, pixel_size,
834 name, len) < 0)
836 len += 32;
837 name = alloca (len);
839 if (name)
840 font->props[FONT_FULLNAME_INDEX]
841 = make_unibyte_string (name, strlen (name));
842 else
843 font->props[FONT_FULLNAME_INDEX] =
844 make_unibyte_string (logfont.lfFaceName, len);
847 font->max_width = w32_font->metrics.tmMaxCharWidth;
848 font->height = w32_font->metrics.tmHeight
849 + w32_font->metrics.tmExternalLeading;
850 font->space_width = font->average_width = w32_font->metrics.tmAveCharWidth;
852 font->vertical_centering = 0;
853 font->encoding_type = 0;
854 font->baseline_offset = 0;
855 font->relative_compose = 0;
856 font->default_ascent = w32_font->metrics.tmAscent;
857 font->font_encoder = NULL;
858 font->pixel_size = size;
859 font->driver = &w32font_driver;
860 /* Use format cached during list, as the information we have access to
861 here is incomplete. */
862 extra = AREF (font_entity, FONT_EXTRA_INDEX);
863 if (CONSP (extra))
865 val = assq_no_quit (QCformat, extra);
866 if (CONSP (val))
867 font->props[FONT_FORMAT_INDEX] = XCDR (val);
868 else
869 font->props[FONT_FORMAT_INDEX] = Qunknown;
871 else
872 font->props[FONT_FORMAT_INDEX] = Qunknown;
874 font->props[FONT_FILE_INDEX] = Qnil;
875 font->encoding_charset = -1;
876 font->repertory_charset = -1;
877 /* TODO: do we really want the minimum width here, which could be negative? */
878 font->min_width = font->space_width;
879 font->ascent = w32_font->metrics.tmAscent;
880 font->descent = w32_font->metrics.tmDescent;
882 if (metrics)
884 font->underline_thickness = metrics->otmsUnderscoreSize;
885 font->underline_position = -metrics->otmsUnderscorePosition;
887 else
889 font->underline_thickness = 0;
890 font->underline_position = -1;
893 /* For temporary compatibility with legacy code that expects the
894 name to be usable in x-list-fonts. Eventually we expect to change
895 x-list-fonts and other places that use fonts so that this can be
896 an fcname or similar. */
897 font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
899 return 1;
902 /* Callback function for EnumFontFamiliesEx.
903 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
904 static int CALLBACK
905 add_font_name_to_list (logical_font, physical_font, font_type, list_object)
906 ENUMLOGFONTEX *logical_font;
907 NEWTEXTMETRICEX *physical_font;
908 DWORD font_type;
909 LPARAM list_object;
911 Lisp_Object* list = (Lisp_Object *) list_object;
912 Lisp_Object family;
914 /* Skip vertical fonts (intended only for printing) */
915 if (logical_font->elfLogFont.lfFaceName[0] == '@')
916 return 1;
918 family = font_intern_prop (logical_font->elfLogFont.lfFaceName,
919 strlen (logical_font->elfLogFont.lfFaceName), 1);
920 if (! memq_no_quit (family, *list))
921 *list = Fcons (family, *list);
923 return 1;
926 static int w32_decode_weight P_ ((int));
927 static int w32_encode_weight P_ ((int));
929 /* Convert an enumerated Windows font to an Emacs font entity. */
930 static Lisp_Object
931 w32_enumfont_pattern_entity (frame, logical_font, physical_font,
932 font_type, requested_font, backend)
933 Lisp_Object frame;
934 ENUMLOGFONTEX *logical_font;
935 NEWTEXTMETRICEX *physical_font;
936 DWORD font_type;
937 LOGFONT *requested_font;
938 Lisp_Object backend;
940 Lisp_Object entity, tem;
941 LOGFONT *lf = (LOGFONT*) logical_font;
942 BYTE generic_type;
943 DWORD full_type = physical_font->ntmTm.ntmFlags;
945 entity = font_make_entity ();
947 ASET (entity, FONT_TYPE_INDEX, backend);
948 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet, font_type));
949 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
951 /* Foundry is difficult to get in readable form on Windows.
952 But Emacs crashes if it is not set, so set it to something more
953 generic. These values make xlfds compatible with Emacs 22. */
954 if (lf->lfOutPrecision == OUT_STRING_PRECIS)
955 tem = Qraster;
956 else if (lf->lfOutPrecision == OUT_STROKE_PRECIS)
957 tem = Qoutline;
958 else
959 tem = Qunknown;
961 ASET (entity, FONT_FOUNDRY_INDEX, tem);
963 /* Save the generic family in the extra info, as it is likely to be
964 useful to users looking for a close match. */
965 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0;
966 if (generic_type == FF_DECORATIVE)
967 tem = Qdecorative;
968 else if (generic_type == FF_MODERN)
969 tem = Qmono;
970 else if (generic_type == FF_ROMAN)
971 tem = Qserif;
972 else if (generic_type == FF_SCRIPT)
973 tem = Qscript;
974 else if (generic_type == FF_SWISS)
975 tem = Qsans;
976 else
977 tem = Qnil;
979 ASET (entity, FONT_ADSTYLE_INDEX, tem);
981 if (physical_font->ntmTm.tmPitchAndFamily & 0x01)
982 ASET (entity, FONT_SPACING_INDEX, make_number (FONT_SPACING_PROPORTIONAL));
983 else
984 ASET (entity, FONT_SPACING_INDEX, make_number (FONT_SPACING_CHARCELL));
986 if (requested_font->lfQuality != DEFAULT_QUALITY)
988 font_put_extra (entity, QCantialias,
989 lispy_antialias_type (requested_font->lfQuality));
991 ASET (entity, FONT_FAMILY_INDEX,
992 font_intern_prop (lf->lfFaceName, strlen (lf->lfFaceName), 1));
994 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
995 make_number (w32_decode_weight (lf->lfWeight)));
996 FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
997 make_number (lf->lfItalic ? 200 : 100));
998 /* TODO: PANOSE struct has this info, but need to call GetOutlineTextMetrics
999 to get it. */
1000 FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (100));
1002 if (font_type & RASTER_FONTTYPE)
1003 ASET (entity, FONT_SIZE_INDEX,
1004 make_number (physical_font->ntmTm.tmHeight
1005 + physical_font->ntmTm.tmExternalLeading));
1006 else
1007 ASET (entity, FONT_SIZE_INDEX, make_number (0));
1009 /* Cache unicode codepoints covered by this font, as there is no other way
1010 of getting this information easily. */
1011 if (font_type & TRUETYPE_FONTTYPE)
1013 tem = font_supported_scripts (&physical_font->ntmFontSig);
1014 if (!NILP (tem))
1015 font_put_extra (entity, QCscript, tem);
1018 /* This information is not fully available when opening fonts, so
1019 save it here. Only Windows 2000 and later return information
1020 about opentype and type1 fonts, so need a fallback for detecting
1021 truetype so that this information is not any worse than we could
1022 have obtained later. */
1023 if (EQ (backend, Quniscribe) && (full_type & NTMFLAGS_OPENTYPE))
1024 tem = intern ("opentype");
1025 else if (font_type & TRUETYPE_FONTTYPE)
1026 tem = intern ("truetype");
1027 else if (full_type & NTM_PS_OPENTYPE)
1028 tem = intern ("postscript");
1029 else if (full_type & NTM_TYPE1)
1030 tem = intern ("type1");
1031 else if (font_type & RASTER_FONTTYPE)
1032 tem = intern ("w32bitmap");
1033 else
1034 tem = intern ("w32vector");
1036 font_put_extra (entity, QCformat, tem);
1038 return entity;
1042 /* Convert generic families to the family portion of lfPitchAndFamily. */
1043 BYTE
1044 w32_generic_family (Lisp_Object name)
1046 /* Generic families. */
1047 if (EQ (name, Qmonospace) || EQ (name, Qmono))
1048 return FF_MODERN;
1049 else if (EQ (name, Qsans) || EQ (name, Qsans_serif) || EQ (name, Qsansserif))
1050 return FF_SWISS;
1051 else if (EQ (name, Qserif))
1052 return FF_ROMAN;
1053 else if (EQ (name, Qdecorative))
1054 return FF_DECORATIVE;
1055 else if (EQ (name, Qscript))
1056 return FF_SCRIPT;
1057 else
1058 return FF_DONTCARE;
1061 static int
1062 logfonts_match (font, pattern)
1063 LOGFONT *font, *pattern;
1065 /* Only check height for raster fonts. */
1066 if (pattern->lfHeight && font->lfOutPrecision == OUT_STRING_PRECIS
1067 && font->lfHeight != pattern->lfHeight)
1068 return 0;
1070 /* Have some flexibility with weights. */
1071 if (pattern->lfWeight
1072 && ((font->lfWeight < (pattern->lfWeight - 150))
1073 || font->lfWeight > (pattern->lfWeight + 150)))
1074 return 0;
1076 /* Charset and face should be OK. Italic has to be checked
1077 against the original spec, in case we don't have any preference. */
1078 return 1;
1081 /* Codepage Bitfields in FONTSIGNATURE struct. */
1082 #define CSB_JAPANESE (1 << 17)
1083 #define CSB_KOREAN ((1 << 19) | (1 << 21))
1084 #define CSB_CHINESE ((1 << 18) | (1 << 20))
1086 static int
1087 font_matches_spec (type, font, spec, backend, logfont)
1088 DWORD type;
1089 NEWTEXTMETRICEX *font;
1090 Lisp_Object spec;
1091 Lisp_Object backend;
1092 LOGFONT *logfont;
1094 Lisp_Object extra, val;
1096 /* Check italic. Can't check logfonts, since it is a boolean field,
1097 so there is no difference between "non-italic" and "don't care". */
1099 int slant = FONT_SLANT_NUMERIC (spec);
1101 if (slant >= 0
1102 && ((slant > 150 && !font->ntmTm.tmItalic)
1103 || (slant <= 150 && font->ntmTm.tmItalic)))
1104 return 0;
1107 /* Check adstyle against generic family. */
1108 val = AREF (spec, FONT_ADSTYLE_INDEX);
1109 if (!NILP (val))
1111 BYTE family = w32_generic_family (val);
1112 if (family != FF_DONTCARE
1113 && family != (font->ntmTm.tmPitchAndFamily & 0xF0))
1114 return 0;
1117 /* Check spacing */
1118 val = AREF (spec, FONT_SPACING_INDEX);
1119 if (INTEGERP (val))
1121 int spacing = XINT (val);
1122 int proportional = (spacing < FONT_SPACING_MONO);
1124 if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
1125 || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
1126 return 0;
1129 /* Check extra parameters. */
1130 for (extra = AREF (spec, FONT_EXTRA_INDEX);
1131 CONSP (extra); extra = XCDR (extra))
1133 Lisp_Object extra_entry;
1134 extra_entry = XCAR (extra);
1135 if (CONSP (extra_entry))
1137 Lisp_Object key = XCAR (extra_entry);
1139 val = XCDR (extra_entry);
1140 if (EQ (key, QCscript) && SYMBOLP (val))
1142 /* Only truetype fonts will have information about what
1143 scripts they support. This probably means the user
1144 will have to force Emacs to use raster, postscript
1145 or atm fonts for non-ASCII text. */
1146 if (type & TRUETYPE_FONTTYPE)
1148 Lisp_Object support
1149 = font_supported_scripts (&font->ntmFontSig);
1150 if (! memq_no_quit (val, support))
1151 return 0;
1153 else
1155 /* Return specific matches, but play it safe. Fonts
1156 that cover more than their charset would suggest
1157 are likely to be truetype or opentype fonts,
1158 covered above. */
1159 if (EQ (val, Qlatin))
1161 /* Although every charset but symbol, thai and
1162 arabic contains the basic ASCII set of latin
1163 characters, Emacs expects much more. */
1164 if (font->ntmTm.tmCharSet != ANSI_CHARSET)
1165 return 0;
1167 else if (EQ (val, Qsymbol))
1169 if (font->ntmTm.tmCharSet != SYMBOL_CHARSET)
1170 return 0;
1172 else if (EQ (val, Qcyrillic))
1174 if (font->ntmTm.tmCharSet != RUSSIAN_CHARSET)
1175 return 0;
1177 else if (EQ (val, Qgreek))
1179 if (font->ntmTm.tmCharSet != GREEK_CHARSET)
1180 return 0;
1182 else if (EQ (val, Qarabic))
1184 if (font->ntmTm.tmCharSet != ARABIC_CHARSET)
1185 return 0;
1187 else if (EQ (val, Qhebrew))
1189 if (font->ntmTm.tmCharSet != HEBREW_CHARSET)
1190 return 0;
1192 else if (EQ (val, Qthai))
1194 if (font->ntmTm.tmCharSet != THAI_CHARSET)
1195 return 0;
1197 else if (EQ (val, Qkana))
1199 if (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
1200 return 0;
1202 else if (EQ (val, Qbopomofo))
1204 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET)
1205 return 0;
1207 else if (EQ (val, Qhangul))
1209 if (font->ntmTm.tmCharSet != HANGUL_CHARSET
1210 && font->ntmTm.tmCharSet != JOHAB_CHARSET)
1211 return 0;
1213 else if (EQ (val, Qhan))
1215 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET
1216 && font->ntmTm.tmCharSet != GB2312_CHARSET
1217 && font->ntmTm.tmCharSet != HANGUL_CHARSET
1218 && font->ntmTm.tmCharSet != JOHAB_CHARSET
1219 && font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
1220 return 0;
1222 else
1223 /* Other scripts unlikely to be handled by non-truetype
1224 fonts. */
1225 return 0;
1228 else if (EQ (key, QClang) && SYMBOLP (val))
1230 /* Just handle the CJK languages here, as the lang
1231 parameter is used to select a font with appropriate
1232 glyphs in the cjk unified ideographs block. Other fonts
1233 support for a language can be solely determined by
1234 its character coverage. */
1235 if (EQ (val, Qja))
1237 if (!(font->ntmFontSig.fsCsb[0] & CSB_JAPANESE))
1238 return 0;
1240 else if (EQ (val, Qko))
1242 if (!(font->ntmFontSig.fsCsb[0] & CSB_KOREAN))
1243 return 0;
1245 else if (EQ (val, Qzh))
1247 if (!(font->ntmFontSig.fsCsb[0] & CSB_CHINESE))
1248 return 0;
1250 else
1251 /* Any other language, we don't recognize it. Only the above
1252 currently appear in fontset.el, so it isn't worth
1253 creating a mapping table of codepages/scripts to languages
1254 or opening the font to see if there are any language tags
1255 in it that the W32 API does not expose. Fontset
1256 spec should have a fallback, as some backends do
1257 not recognize language at all. */
1258 return 0;
1260 else if (EQ (key, QCotf) && CONSP (val))
1262 /* OTF features only supported by the uniscribe backend. */
1263 if (EQ (backend, Quniscribe))
1265 if (!uniscribe_check_otf (logfont, val))
1266 return 0;
1268 else
1269 return 0;
1273 return 1;
1276 static int
1277 w32font_coverage_ok (coverage, charset)
1278 FONTSIGNATURE * coverage;
1279 BYTE charset;
1281 DWORD subrange1 = coverage->fsUsb[1];
1283 #define SUBRANGE1_HAN_MASK 0x08000000
1284 #define SUBRANGE1_HANGEUL_MASK 0x01000000
1285 #define SUBRANGE1_JAPANESE_MASK (0x00060000 | SUBRANGE1_HAN_MASK)
1287 if (charset == GB2312_CHARSET || charset == CHINESEBIG5_CHARSET)
1289 return (subrange1 & SUBRANGE1_HAN_MASK) == SUBRANGE1_HAN_MASK;
1291 else if (charset == SHIFTJIS_CHARSET)
1293 return (subrange1 & SUBRANGE1_JAPANESE_MASK) == SUBRANGE1_JAPANESE_MASK;
1295 else if (charset == HANGEUL_CHARSET)
1297 return (subrange1 & SUBRANGE1_HANGEUL_MASK) == SUBRANGE1_HANGEUL_MASK;
1300 return 1;
1303 /* Callback function for EnumFontFamiliesEx.
1304 * Checks if a font matches everything we are trying to check agaist,
1305 * and if so, adds it to a list. Both the data we are checking against
1306 * and the list to which the fonts are added are passed in via the
1307 * lparam argument, in the form of a font_callback_data struct. */
1308 static int CALLBACK
1309 add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
1310 ENUMLOGFONTEX *logical_font;
1311 NEWTEXTMETRICEX *physical_font;
1312 DWORD font_type;
1313 LPARAM lParam;
1315 struct font_callback_data *match_data
1316 = (struct font_callback_data *) lParam;
1317 Lisp_Object backend = match_data->opentype_only ? Quniscribe : Qgdi;
1319 if ((!match_data->opentype_only
1320 || (((physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE)
1321 || (font_type & TRUETYPE_FONTTYPE))
1322 /* For the uniscribe backend, only consider fonts that claim
1323 to cover at least some part of Unicode. */
1324 && (physical_font->ntmFontSig.fsUsb[3]
1325 || physical_font->ntmFontSig.fsUsb[2]
1326 || physical_font->ntmFontSig.fsUsb[1]
1327 || (physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff))))
1328 && logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
1329 && font_matches_spec (font_type, physical_font,
1330 match_data->orig_font_spec, backend,
1331 &logical_font->elfLogFont)
1332 && w32font_coverage_ok (&physical_font->ntmFontSig,
1333 match_data->pattern.lfCharSet)
1334 /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif)
1335 We limit this to raster fonts, because the test can catch some
1336 genuine fonts (eg the full name of DejaVu Sans Mono Light is actually
1337 DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will
1338 therefore get through this test. Since full names can be prefixed
1339 by a foundry, we accept raster fonts if the font name is found
1340 anywhere within the full name. */
1341 && (logical_font->elfLogFont.lfOutPrecision != OUT_STRING_PRECIS
1342 || strstr (logical_font->elfFullName,
1343 logical_font->elfLogFont.lfFaceName)))
1345 Lisp_Object entity
1346 = w32_enumfont_pattern_entity (match_data->frame, logical_font,
1347 physical_font, font_type,
1348 &match_data->pattern,
1349 backend);
1350 if (!NILP (entity))
1352 Lisp_Object spec_charset = AREF (match_data->orig_font_spec,
1353 FONT_REGISTRY_INDEX);
1355 /* If registry was specified as iso10646-1, only report
1356 ANSI and DEFAULT charsets, as most unicode fonts will
1357 contain one of those plus others. */
1358 if ((EQ (spec_charset, Qiso10646_1)
1359 || EQ (spec_charset, Qunicode_bmp)
1360 || EQ (spec_charset, Qunicode_sip))
1361 && logical_font->elfLogFont.lfCharSet != DEFAULT_CHARSET
1362 && logical_font->elfLogFont.lfCharSet != ANSI_CHARSET)
1363 return 1;
1364 /* If registry was specified, but did not map to a windows
1365 charset, only report fonts that have unknown charsets.
1366 This will still report fonts that don't match, but at
1367 least it eliminates known definite mismatches. */
1368 else if (!NILP (spec_charset)
1369 && !EQ (spec_charset, Qiso10646_1)
1370 && !EQ (spec_charset, Qunicode_bmp)
1371 && !EQ (spec_charset, Qunicode_sip)
1372 && match_data->pattern.lfCharSet == DEFAULT_CHARSET
1373 && logical_font->elfLogFont.lfCharSet != DEFAULT_CHARSET)
1374 return 1;
1376 /* If registry was specified, ensure it is reported as the same. */
1377 if (!NILP (spec_charset))
1378 ASET (entity, FONT_REGISTRY_INDEX, spec_charset);
1380 match_data->list = Fcons (entity, match_data->list);
1382 /* If no registry specified, duplicate iso8859-1 truetype fonts
1383 as iso10646-1. */
1384 if (NILP (spec_charset)
1385 && font_type == TRUETYPE_FONTTYPE
1386 && logical_font->elfLogFont.lfCharSet == ANSI_CHARSET)
1388 Lisp_Object tem = Fcopy_font_spec (entity);
1389 ASET (tem, FONT_REGISTRY_INDEX, Qiso10646_1);
1390 match_data->list = Fcons (tem, match_data->list);
1394 return 1;
1397 /* Callback function for EnumFontFamiliesEx.
1398 * Terminates the search once we have a match. */
1399 static int CALLBACK
1400 add_one_font_entity_to_list (logical_font, physical_font, font_type, lParam)
1401 ENUMLOGFONTEX *logical_font;
1402 NEWTEXTMETRICEX *physical_font;
1403 DWORD font_type;
1404 LPARAM lParam;
1406 struct font_callback_data *match_data
1407 = (struct font_callback_data *) lParam;
1408 add_font_entity_to_list (logical_font, physical_font, font_type, lParam);
1410 /* If we have a font in the list, terminate the search. */
1411 return !NILP (match_data->list);
1414 /* Old function to convert from x to w32 charset, from w32fns.c. */
1415 static LONG
1416 x_to_w32_charset (lpcs)
1417 char * lpcs;
1419 Lisp_Object this_entry, w32_charset;
1420 char *charset;
1421 int len = strlen (lpcs);
1423 /* Support "*-#nnn" format for unknown charsets. */
1424 if (strncmp (lpcs, "*-#", 3) == 0)
1425 return atoi (lpcs + 3);
1427 /* All Windows fonts qualify as unicode. */
1428 if (!strncmp (lpcs, "iso10646", 8))
1429 return DEFAULT_CHARSET;
1431 /* Handle wildcards by ignoring them; eg. treat "big5*-*" as "big5". */
1432 charset = alloca (len + 1);
1433 strcpy (charset, lpcs);
1434 lpcs = strchr (charset, '*');
1435 if (lpcs)
1436 *lpcs = '\0';
1438 /* Look through w32-charset-info-alist for the character set.
1439 Format of each entry is
1440 (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
1442 this_entry = Fassoc (build_string (charset), Vw32_charset_info_alist);
1444 if (NILP (this_entry))
1446 /* At startup, we want iso8859-1 fonts to come up properly. */
1447 if (xstrcasecmp (charset, "iso8859-1") == 0)
1448 return ANSI_CHARSET;
1449 else
1450 return DEFAULT_CHARSET;
1453 w32_charset = Fcar (Fcdr (this_entry));
1455 /* Translate Lisp symbol to number. */
1456 if (EQ (w32_charset, Qw32_charset_ansi))
1457 return ANSI_CHARSET;
1458 if (EQ (w32_charset, Qw32_charset_symbol))
1459 return SYMBOL_CHARSET;
1460 if (EQ (w32_charset, Qw32_charset_shiftjis))
1461 return SHIFTJIS_CHARSET;
1462 if (EQ (w32_charset, Qw32_charset_hangeul))
1463 return HANGEUL_CHARSET;
1464 if (EQ (w32_charset, Qw32_charset_chinesebig5))
1465 return CHINESEBIG5_CHARSET;
1466 if (EQ (w32_charset, Qw32_charset_gb2312))
1467 return GB2312_CHARSET;
1468 if (EQ (w32_charset, Qw32_charset_oem))
1469 return OEM_CHARSET;
1470 if (EQ (w32_charset, Qw32_charset_johab))
1471 return JOHAB_CHARSET;
1472 if (EQ (w32_charset, Qw32_charset_easteurope))
1473 return EASTEUROPE_CHARSET;
1474 if (EQ (w32_charset, Qw32_charset_turkish))
1475 return TURKISH_CHARSET;
1476 if (EQ (w32_charset, Qw32_charset_baltic))
1477 return BALTIC_CHARSET;
1478 if (EQ (w32_charset, Qw32_charset_russian))
1479 return RUSSIAN_CHARSET;
1480 if (EQ (w32_charset, Qw32_charset_arabic))
1481 return ARABIC_CHARSET;
1482 if (EQ (w32_charset, Qw32_charset_greek))
1483 return GREEK_CHARSET;
1484 if (EQ (w32_charset, Qw32_charset_hebrew))
1485 return HEBREW_CHARSET;
1486 if (EQ (w32_charset, Qw32_charset_vietnamese))
1487 return VIETNAMESE_CHARSET;
1488 if (EQ (w32_charset, Qw32_charset_thai))
1489 return THAI_CHARSET;
1490 if (EQ (w32_charset, Qw32_charset_mac))
1491 return MAC_CHARSET;
1493 return DEFAULT_CHARSET;
1497 /* Convert a Lisp font registry (symbol) to a windows charset. */
1498 static LONG
1499 registry_to_w32_charset (charset)
1500 Lisp_Object charset;
1502 if (EQ (charset, Qiso10646_1) || EQ (charset, Qunicode_bmp)
1503 || EQ (charset, Qunicode_sip))
1504 return DEFAULT_CHARSET; /* UNICODE_CHARSET not defined in MingW32 */
1505 else if (EQ (charset, Qiso8859_1))
1506 return ANSI_CHARSET;
1507 else if (SYMBOLP (charset))
1508 return x_to_w32_charset (SDATA (SYMBOL_NAME (charset)));
1509 else
1510 return DEFAULT_CHARSET;
1513 /* Old function to convert from w32 to x charset, from w32fns.c. */
1514 static char *
1515 w32_to_x_charset (fncharset, matching)
1516 int fncharset;
1517 char *matching;
1519 static char buf[32];
1520 Lisp_Object charset_type;
1521 int match_len = 0;
1523 if (matching)
1525 /* If fully specified, accept it as it is. Otherwise use a
1526 substring match. */
1527 char *wildcard = strchr (matching, '*');
1528 if (wildcard)
1529 *wildcard = '\0';
1530 else if (strchr (matching, '-'))
1531 return matching;
1533 match_len = strlen (matching);
1536 switch (fncharset)
1538 case ANSI_CHARSET:
1539 /* Handle startup case of w32-charset-info-alist not
1540 being set up yet. */
1541 if (NILP (Vw32_charset_info_alist))
1542 return "iso8859-1";
1543 charset_type = Qw32_charset_ansi;
1544 break;
1545 case DEFAULT_CHARSET:
1546 charset_type = Qw32_charset_default;
1547 break;
1548 case SYMBOL_CHARSET:
1549 charset_type = Qw32_charset_symbol;
1550 break;
1551 case SHIFTJIS_CHARSET:
1552 charset_type = Qw32_charset_shiftjis;
1553 break;
1554 case HANGEUL_CHARSET:
1555 charset_type = Qw32_charset_hangeul;
1556 break;
1557 case GB2312_CHARSET:
1558 charset_type = Qw32_charset_gb2312;
1559 break;
1560 case CHINESEBIG5_CHARSET:
1561 charset_type = Qw32_charset_chinesebig5;
1562 break;
1563 case OEM_CHARSET:
1564 charset_type = Qw32_charset_oem;
1565 break;
1566 case EASTEUROPE_CHARSET:
1567 charset_type = Qw32_charset_easteurope;
1568 break;
1569 case TURKISH_CHARSET:
1570 charset_type = Qw32_charset_turkish;
1571 break;
1572 case BALTIC_CHARSET:
1573 charset_type = Qw32_charset_baltic;
1574 break;
1575 case RUSSIAN_CHARSET:
1576 charset_type = Qw32_charset_russian;
1577 break;
1578 case ARABIC_CHARSET:
1579 charset_type = Qw32_charset_arabic;
1580 break;
1581 case GREEK_CHARSET:
1582 charset_type = Qw32_charset_greek;
1583 break;
1584 case HEBREW_CHARSET:
1585 charset_type = Qw32_charset_hebrew;
1586 break;
1587 case VIETNAMESE_CHARSET:
1588 charset_type = Qw32_charset_vietnamese;
1589 break;
1590 case THAI_CHARSET:
1591 charset_type = Qw32_charset_thai;
1592 break;
1593 case MAC_CHARSET:
1594 charset_type = Qw32_charset_mac;
1595 break;
1596 case JOHAB_CHARSET:
1597 charset_type = Qw32_charset_johab;
1598 break;
1600 default:
1601 /* Encode numerical value of unknown charset. */
1602 sprintf (buf, "*-#%u", fncharset);
1603 return buf;
1607 Lisp_Object rest;
1608 char * best_match = NULL;
1609 int matching_found = 0;
1611 /* Look through w32-charset-info-alist for the character set.
1612 Prefer ISO codepages, and prefer lower numbers in the ISO
1613 range. Only return charsets for codepages which are installed.
1615 Format of each entry is
1616 (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
1618 for (rest = Vw32_charset_info_alist; CONSP (rest); rest = XCDR (rest))
1620 char * x_charset;
1621 Lisp_Object w32_charset;
1622 Lisp_Object codepage;
1624 Lisp_Object this_entry = XCAR (rest);
1626 /* Skip invalid entries in alist. */
1627 if (!CONSP (this_entry) || !STRINGP (XCAR (this_entry))
1628 || !CONSP (XCDR (this_entry))
1629 || !SYMBOLP (XCAR (XCDR (this_entry))))
1630 continue;
1632 x_charset = SDATA (XCAR (this_entry));
1633 w32_charset = XCAR (XCDR (this_entry));
1634 codepage = XCDR (XCDR (this_entry));
1636 /* Look for Same charset and a valid codepage (or non-int
1637 which means ignore). */
1638 if (EQ (w32_charset, charset_type)
1639 && (!INTEGERP (codepage) || XINT (codepage) == CP_DEFAULT
1640 || IsValidCodePage (XINT (codepage))))
1642 /* If we don't have a match already, then this is the
1643 best. */
1644 if (!best_match)
1646 best_match = x_charset;
1647 if (matching && !strnicmp (x_charset, matching, match_len))
1648 matching_found = 1;
1650 /* If we already found a match for MATCHING, then
1651 only consider other matches. */
1652 else if (matching_found
1653 && strnicmp (x_charset, matching, match_len))
1654 continue;
1655 /* If this matches what we want, and the best so far doesn't,
1656 then this is better. */
1657 else if (!matching_found && matching
1658 && !strnicmp (x_charset, matching, match_len))
1660 best_match = x_charset;
1661 matching_found = 1;
1663 /* If this is fully specified, and the best so far isn't,
1664 then this is better. */
1665 else if ((!strchr (best_match, '-') && strchr (x_charset, '-'))
1666 /* If this is an ISO codepage, and the best so far isn't,
1667 then this is better, but only if it fully specifies the
1668 encoding. */
1669 || (strnicmp (best_match, "iso", 3) != 0
1670 && strnicmp (x_charset, "iso", 3) == 0
1671 && strchr (x_charset, '-')))
1672 best_match = x_charset;
1673 /* If both are ISO8859 codepages, choose the one with the
1674 lowest number in the encoding field. */
1675 else if (strnicmp (best_match, "iso8859-", 8) == 0
1676 && strnicmp (x_charset, "iso8859-", 8) == 0)
1678 int best_enc = atoi (best_match + 8);
1679 int this_enc = atoi (x_charset + 8);
1680 if (this_enc > 0 && this_enc < best_enc)
1681 best_match = x_charset;
1686 /* If no match, encode the numeric value. */
1687 if (!best_match)
1689 sprintf (buf, "*-#%u", fncharset);
1690 return buf;
1693 strncpy (buf, best_match, 31);
1694 /* If the charset is not fully specified, put -0 on the end. */
1695 if (!strchr (best_match, '-'))
1697 int pos = strlen (best_match);
1698 /* Charset specifiers shouldn't be very long. If it is a made
1699 up one, truncating it should not do any harm since it isn't
1700 recognized anyway. */
1701 if (pos > 29)
1702 pos = 29;
1703 strcpy (buf + pos, "-0");
1705 buf[31] = '\0';
1706 return buf;
1710 static Lisp_Object
1711 w32_registry (w32_charset, font_type)
1712 LONG w32_charset;
1713 DWORD font_type;
1715 char *charset;
1717 /* If charset is defaulted, charset is unicode or unknown, depending on
1718 font type. */
1719 if (w32_charset == DEFAULT_CHARSET)
1720 return font_type == TRUETYPE_FONTTYPE ? Qiso10646_1 : Qunknown;
1722 charset = w32_to_x_charset (w32_charset, NULL);
1723 return font_intern_prop (charset, strlen(charset), 1);
1726 static int
1727 w32_decode_weight (fnweight)
1728 int fnweight;
1730 if (fnweight >= FW_HEAVY) return 210;
1731 if (fnweight >= FW_EXTRABOLD) return 205;
1732 if (fnweight >= FW_BOLD) return 200;
1733 if (fnweight >= FW_SEMIBOLD) return 180;
1734 if (fnweight >= FW_NORMAL) return 100;
1735 if (fnweight >= FW_LIGHT) return 50;
1736 if (fnweight >= FW_EXTRALIGHT) return 40;
1737 if (fnweight > FW_THIN) return 20;
1738 return 0;
1741 static int
1742 w32_encode_weight (n)
1743 int n;
1745 if (n >= 210) return FW_HEAVY;
1746 if (n >= 205) return FW_EXTRABOLD;
1747 if (n >= 200) return FW_BOLD;
1748 if (n >= 180) return FW_SEMIBOLD;
1749 if (n >= 100) return FW_NORMAL;
1750 if (n >= 50) return FW_LIGHT;
1751 if (n >= 40) return FW_EXTRALIGHT;
1752 if (n >= 20) return FW_THIN;
1753 return 0;
1756 /* Convert a Windows font weight into one of the weights supported
1757 by fontconfig (see font.c:font_parse_fcname). */
1758 static Lisp_Object
1759 w32_to_fc_weight (n)
1760 int n;
1762 if (n >= FW_EXTRABOLD) return intern ("black");
1763 if (n >= FW_BOLD) return intern ("bold");
1764 if (n >= FW_SEMIBOLD) return intern ("demibold");
1765 if (n >= FW_NORMAL) return intern ("medium");
1766 return intern ("light");
1769 /* Fill in all the available details of LOGFONT from FONT_SPEC. */
1770 static void
1771 fill_in_logfont (f, logfont, font_spec)
1772 FRAME_PTR f;
1773 LOGFONT *logfont;
1774 Lisp_Object font_spec;
1776 Lisp_Object tmp, extra;
1777 int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
1779 tmp = AREF (font_spec, FONT_DPI_INDEX);
1780 if (INTEGERP (tmp))
1782 dpi = XINT (tmp);
1784 else if (FLOATP (tmp))
1786 dpi = (int) (XFLOAT_DATA (tmp) + 0.5);
1789 /* Height */
1790 tmp = AREF (font_spec, FONT_SIZE_INDEX);
1791 if (INTEGERP (tmp))
1792 logfont->lfHeight = -1 * XINT (tmp);
1793 else if (FLOATP (tmp))
1794 logfont->lfHeight = (int) (-1.0 * dpi * XFLOAT_DATA (tmp) / 72.27 + 0.5);
1796 /* Escapement */
1798 /* Orientation */
1800 /* Weight */
1801 tmp = AREF (font_spec, FONT_WEIGHT_INDEX);
1802 if (INTEGERP (tmp))
1803 logfont->lfWeight = w32_encode_weight (FONT_WEIGHT_NUMERIC (font_spec));
1805 /* Italic */
1806 tmp = AREF (font_spec, FONT_SLANT_INDEX);
1807 if (INTEGERP (tmp))
1809 int slant = FONT_SLANT_NUMERIC (font_spec);
1810 logfont->lfItalic = slant > 150 ? 1 : 0;
1813 /* Underline */
1815 /* Strikeout */
1817 /* Charset */
1818 tmp = AREF (font_spec, FONT_REGISTRY_INDEX);
1819 if (! NILP (tmp))
1820 logfont->lfCharSet = registry_to_w32_charset (tmp);
1821 else
1822 logfont->lfCharSet = DEFAULT_CHARSET;
1824 /* Out Precision */
1826 /* Clip Precision */
1828 /* Quality */
1829 logfont->lfQuality = DEFAULT_QUALITY;
1831 /* Generic Family and Face Name */
1832 logfont->lfPitchAndFamily = FF_DONTCARE | DEFAULT_PITCH;
1834 tmp = AREF (font_spec, FONT_FAMILY_INDEX);
1835 if (! NILP (tmp))
1837 logfont->lfPitchAndFamily = w32_generic_family (tmp) | DEFAULT_PITCH;
1838 if ((logfont->lfPitchAndFamily & 0xF0) != FF_DONTCARE)
1839 ; /* Font name was generic, don't fill in font name. */
1840 /* Font families are interned, but allow for strings also in case of
1841 user input. */
1842 else if (SYMBOLP (tmp))
1843 strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE);
1846 tmp = AREF (font_spec, FONT_ADSTYLE_INDEX);
1847 if (!NILP (tmp))
1849 /* Override generic family. */
1850 BYTE family = w32_generic_family (tmp);
1851 if (family != FF_DONTCARE)
1852 logfont->lfPitchAndFamily = family | DEFAULT_PITCH;
1856 /* Set pitch based on the spacing property. */
1857 tmp = AREF (font_spec, FONT_SPACING_INDEX);
1858 if (INTEGERP (tmp))
1860 int spacing = XINT (tmp);
1861 if (spacing < FONT_SPACING_MONO)
1862 logfont->lfPitchAndFamily
1863 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
1864 else
1865 logfont->lfPitchAndFamily
1866 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
1869 /* Process EXTRA info. */
1870 for (extra = AREF (font_spec, FONT_EXTRA_INDEX);
1871 CONSP (extra); extra = XCDR (extra))
1873 tmp = XCAR (extra);
1874 if (CONSP (tmp))
1876 Lisp_Object key, val;
1877 key = XCAR (tmp), val = XCDR (tmp);
1878 /* Only use QCscript if charset is not provided, or is unicode
1879 and a single script is specified. This is rather crude,
1880 and is only used to narrow down the fonts returned where
1881 there is a definite match. Some scripts, such as latin, han,
1882 cjk-misc match multiple lfCharSet values, so we can't pre-filter
1883 them. */
1884 if (EQ (key, QCscript)
1885 && logfont->lfCharSet == DEFAULT_CHARSET
1886 && SYMBOLP (val))
1888 if (EQ (val, Qgreek))
1889 logfont->lfCharSet = GREEK_CHARSET;
1890 else if (EQ (val, Qhangul))
1891 logfont->lfCharSet = HANGUL_CHARSET;
1892 else if (EQ (val, Qkana) || EQ (val, Qkanbun))
1893 logfont->lfCharSet = SHIFTJIS_CHARSET;
1894 else if (EQ (val, Qbopomofo))
1895 logfont->lfCharSet = CHINESEBIG5_CHARSET;
1896 /* GB 18030 supports tibetan, yi, mongolian,
1897 fonts that support it should show up if we ask for
1898 GB2312 fonts. */
1899 else if (EQ (val, Qtibetan) || EQ (val, Qyi)
1900 || EQ (val, Qmongolian))
1901 logfont->lfCharSet = GB2312_CHARSET;
1902 else if (EQ (val, Qhebrew))
1903 logfont->lfCharSet = HEBREW_CHARSET;
1904 else if (EQ (val, Qarabic))
1905 logfont->lfCharSet = ARABIC_CHARSET;
1906 else if (EQ (val, Qthai))
1907 logfont->lfCharSet = THAI_CHARSET;
1908 else if (EQ (val, Qsymbol))
1909 logfont->lfCharSet = SYMBOL_CHARSET;
1911 else if (EQ (key, QCantialias) && SYMBOLP (val))
1913 logfont->lfQuality = w32_antialias_type (val);
1919 static void
1920 list_all_matching_fonts (match_data)
1921 struct font_callback_data *match_data;
1923 HDC dc;
1924 Lisp_Object families = w32font_list_family (match_data->frame);
1925 struct frame *f = XFRAME (match_data->frame);
1927 dc = get_frame_dc (f);
1929 while (!NILP (families))
1931 /* TODO: Use the Unicode versions of the W32 APIs, so we can
1932 handle non-ASCII font names. */
1933 char *name;
1934 Lisp_Object family = CAR (families);
1935 families = CDR (families);
1936 if (NILP (family))
1937 continue;
1938 else if (SYMBOLP (family))
1939 name = SDATA (SYMBOL_NAME (family));
1940 else
1941 continue;
1943 strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE);
1944 match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0';
1946 EnumFontFamiliesEx (dc, &match_data->pattern,
1947 (FONTENUMPROC) add_font_entity_to_list,
1948 (LPARAM) match_data, 0);
1951 release_frame_dc (f, dc);
1954 static Lisp_Object
1955 lispy_antialias_type (type)
1956 BYTE type;
1958 Lisp_Object lispy;
1960 switch (type)
1962 case NONANTIALIASED_QUALITY:
1963 lispy = Qnone;
1964 break;
1965 case ANTIALIASED_QUALITY:
1966 lispy = Qstandard;
1967 break;
1968 case CLEARTYPE_QUALITY:
1969 lispy = Qsubpixel;
1970 break;
1971 case CLEARTYPE_NATURAL_QUALITY:
1972 lispy = Qnatural;
1973 break;
1974 default:
1975 lispy = Qnil;
1976 break;
1978 return lispy;
1981 /* Convert antialiasing symbols to lfQuality */
1982 static BYTE
1983 w32_antialias_type (type)
1984 Lisp_Object type;
1986 if (EQ (type, Qnone))
1987 return NONANTIALIASED_QUALITY;
1988 else if (EQ (type, Qstandard))
1989 return ANTIALIASED_QUALITY;
1990 else if (EQ (type, Qsubpixel))
1991 return CLEARTYPE_QUALITY;
1992 else if (EQ (type, Qnatural))
1993 return CLEARTYPE_NATURAL_QUALITY;
1994 else
1995 return DEFAULT_QUALITY;
1998 /* Return a list of all the scripts that the font supports. */
1999 static Lisp_Object
2000 font_supported_scripts (FONTSIGNATURE * sig)
2002 DWORD * subranges = sig->fsUsb;
2003 Lisp_Object supported = Qnil;
2005 /* Match a single subrange. SYM is set if bit N is set in subranges. */
2006 #define SUBRANGE(n,sym) \
2007 if (subranges[(n) / 32] & (1 << ((n) % 32))) \
2008 supported = Fcons ((sym), supported)
2010 /* Match multiple subranges. SYM is set if any MASK bit is set in
2011 subranges[0 - 3]. */
2012 #define MASK_ANY(mask0,mask1,mask2,mask3,sym) \
2013 if ((subranges[0] & (mask0)) || (subranges[1] & (mask1)) \
2014 || (subranges[2] & (mask2)) || (subranges[3] & (mask3))) \
2015 supported = Fcons ((sym), supported)
2017 SUBRANGE (0, Qlatin);
2018 /* The following count as latin too, ASCII should be present in these fonts,
2019 so don't need to mark them separately. */
2020 /* 1: Latin-1 supplement, 2: Latin Extended A, 3: Latin Extended B. */
2021 SUBRANGE (4, Qphonetic);
2022 /* 5: Spacing and tone modifiers, 6: Combining Diacriticals. */
2023 SUBRANGE (7, Qgreek);
2024 SUBRANGE (8, Qcoptic);
2025 SUBRANGE (9, Qcyrillic);
2026 SUBRANGE (10, Qarmenian);
2027 SUBRANGE (11, Qhebrew);
2028 SUBRANGE (13, Qarabic);
2029 SUBRANGE (14, Qnko);
2030 SUBRANGE (15, Qdevanagari);
2031 SUBRANGE (16, Qbengali);
2032 SUBRANGE (17, Qgurmukhi);
2033 SUBRANGE (18, Qgujarati);
2034 SUBRANGE (19, Qoriya);
2035 SUBRANGE (20, Qtamil);
2036 SUBRANGE (21, Qtelugu);
2037 SUBRANGE (22, Qkannada);
2038 SUBRANGE (23, Qmalayalam);
2039 SUBRANGE (24, Qthai);
2040 SUBRANGE (25, Qlao);
2041 SUBRANGE (26, Qgeorgian);
2042 SUBRANGE (27, Qbalinese);
2043 /* 28: Hangul Jamo. */
2044 /* 29: Latin Extended, 30: Greek Extended, 31: Punctuation. */
2045 /* 32-47: Symbols (defined below). */
2046 SUBRANGE (48, Qcjk_misc);
2047 /* Match either 49: katakana or 50: hiragana for kana. */
2048 MASK_ANY (0, 0x00060000, 0, 0, Qkana);
2049 SUBRANGE (51, Qbopomofo);
2050 /* 52: Compatibility Jamo */
2051 SUBRANGE (53, Qphags_pa);
2052 /* 54: Enclosed CJK letters and months, 55: CJK Compatibility. */
2053 SUBRANGE (56, Qhangul);
2054 /* 57: Surrogates. */
2055 SUBRANGE (58, Qphoenician);
2056 SUBRANGE (59, Qhan); /* There are others, but this is the main one. */
2057 SUBRANGE (59, Qideographic_description); /* Windows lumps this in. */
2058 SUBRANGE (59, Qkanbun); /* And this. */
2059 /* 60: Private use, 61: CJK strokes and compatibility. */
2060 /* 62: Alphabetic Presentation, 63: Arabic Presentation A. */
2061 /* 64: Combining half marks, 65: Vertical and CJK compatibility. */
2062 /* 66: Small forms, 67: Arabic Presentation B, 68: Half and Full width. */
2063 /* 69: Specials. */
2064 SUBRANGE (70, Qtibetan);
2065 SUBRANGE (71, Qsyriac);
2066 SUBRANGE (72, Qthaana);
2067 SUBRANGE (73, Qsinhala);
2068 SUBRANGE (74, Qmyanmar);
2069 SUBRANGE (75, Qethiopic);
2070 SUBRANGE (76, Qcherokee);
2071 SUBRANGE (77, Qcanadian_aboriginal);
2072 SUBRANGE (78, Qogham);
2073 SUBRANGE (79, Qrunic);
2074 SUBRANGE (80, Qkhmer);
2075 SUBRANGE (81, Qmongolian);
2076 SUBRANGE (82, Qbraille);
2077 SUBRANGE (83, Qyi);
2078 SUBRANGE (84, Qbuhid);
2079 SUBRANGE (84, Qhanunoo);
2080 SUBRANGE (84, Qtagalog);
2081 SUBRANGE (84, Qtagbanwa);
2082 SUBRANGE (85, Qold_italic);
2083 SUBRANGE (86, Qgothic);
2084 SUBRANGE (87, Qdeseret);
2085 SUBRANGE (88, Qbyzantine_musical_symbol);
2086 SUBRANGE (88, Qmusical_symbol); /* Windows doesn't distinguish these. */
2087 SUBRANGE (89, Qmathematical);
2088 /* 90: Private use, 91: Variation selectors, 92: Tags. */
2089 SUBRANGE (93, Qlimbu);
2090 SUBRANGE (94, Qtai_le);
2091 /* 95: New Tai Le */
2092 SUBRANGE (90, Qbuginese);
2093 SUBRANGE (97, Qglagolitic);
2094 SUBRANGE (98, Qtifinagh);
2095 /* 99: Yijing Hexagrams. */
2096 SUBRANGE (100, Qsyloti_nagri);
2097 SUBRANGE (101, Qlinear_b);
2098 /* 102: Ancient Greek Numbers. */
2099 SUBRANGE (103, Qugaritic);
2100 SUBRANGE (104, Qold_persian);
2101 SUBRANGE (105, Qshavian);
2102 SUBRANGE (106, Qosmanya);
2103 SUBRANGE (107, Qcypriot);
2104 SUBRANGE (108, Qkharoshthi);
2105 /* 109: Tai Xuan Jing. */
2106 SUBRANGE (110, Qcuneiform);
2107 /* 111: Counting Rods. */
2109 /* There isn't really a main symbol range, so include symbol if any
2110 relevant range is set. */
2111 MASK_ANY (0x8000000, 0x0000FFFF, 0, 0, Qsymbol);
2113 /* Missing: Tai Viet (U+AA80) and Cham (U+AA00) . */
2114 #undef SUBRANGE
2115 #undef MASK_ANY
2117 return supported;
2120 /* Generate a full name for a Windows font.
2121 The full name is in fcname format, with weight, slant and antialiasing
2122 specified if they are not "normal". */
2123 static int
2124 w32font_full_name (font, font_obj, pixel_size, name, nbytes)
2125 LOGFONT * font;
2126 Lisp_Object font_obj;
2127 int pixel_size;
2128 char *name;
2129 int nbytes;
2131 int len, height, outline;
2132 char *p;
2133 Lisp_Object antialiasing, weight = Qnil;
2135 len = strlen (font->lfFaceName);
2137 outline = EQ (AREF (font_obj, FONT_FOUNDRY_INDEX), Qoutline);
2139 /* Represent size of scalable fonts by point size. But use pixelsize for
2140 raster fonts to indicate that they are exactly that size. */
2141 if (outline)
2142 len += 11; /* -SIZE */
2143 else
2144 len += 21;
2146 if (font->lfItalic)
2147 len += 7; /* :italic */
2149 if (font->lfWeight && font->lfWeight != FW_NORMAL)
2151 weight = w32_to_fc_weight (font->lfWeight);
2152 len += 1 + SBYTES (SYMBOL_NAME (weight)); /* :WEIGHT */
2155 antialiasing = lispy_antialias_type (font->lfQuality);
2156 if (! NILP (antialiasing))
2157 len += 11 + SBYTES (SYMBOL_NAME (antialiasing)); /* :antialias=NAME */
2159 /* Check that the buffer is big enough */
2160 if (len > nbytes)
2161 return -1;
2163 p = name;
2164 p += sprintf (p, "%s", font->lfFaceName);
2166 height = font->lfHeight ? eabs (font->lfHeight) : pixel_size;
2168 if (height > 0)
2170 if (outline)
2172 float pointsize = height * 72.0 / one_w32_display_info.resy;
2173 /* Round to nearest half point. floor is used, since round is not
2174 supported in MS library. */
2175 pointsize = floor (pointsize * 2 + 0.5) / 2;
2176 p += sprintf (p, "-%1.1f", pointsize);
2178 else
2179 p += sprintf (p, ":pixelsize=%d", height);
2182 if (SYMBOLP (weight) && ! NILP (weight))
2183 p += sprintf (p, ":%s", SDATA (SYMBOL_NAME (weight)));
2185 if (font->lfItalic)
2186 p += sprintf (p, ":italic");
2188 if (SYMBOLP (antialiasing) && ! NILP (antialiasing))
2189 p += sprintf (p, ":antialias=%s", SDATA (SYMBOL_NAME (antialiasing)));
2191 return (p - name);
2194 /* Convert a logfont and point size into a fontconfig style font name.
2195 POINTSIZE is in tenths of points.
2196 If SIZE indicates the size of buffer FCNAME, into which the font name
2197 is written. If the buffer is not large enough to contain the name,
2198 the function returns -1, otherwise it returns the number of bytes
2199 written to FCNAME. */
2200 static int logfont_to_fcname(font, pointsize, fcname, size)
2201 LOGFONT* font;
2202 int pointsize;
2203 char *fcname;
2204 int size;
2206 int len, height;
2207 char *p = fcname;
2208 Lisp_Object weight = Qnil;
2210 len = strlen (font->lfFaceName) + 2;
2211 height = pointsize / 10;
2212 while (height /= 10)
2213 len++;
2215 if (pointsize % 10)
2216 len += 2;
2218 if (font->lfItalic)
2219 len += 7; /* :italic */
2220 if (font->lfWeight && font->lfWeight != FW_NORMAL)
2222 weight = w32_to_fc_weight (font->lfWeight);
2223 len += SBYTES (SYMBOL_NAME (weight)) + 1;
2226 if (len > size)
2227 return -1;
2229 p += sprintf (p, "%s-%d", font->lfFaceName, pointsize / 10);
2230 if (pointsize % 10)
2231 p += sprintf (p, ".%d", pointsize % 10);
2233 if (SYMBOLP (weight) && !NILP (weight))
2234 p += sprintf (p, ":%s", SDATA (SYMBOL_NAME (weight)));
2236 if (font->lfItalic)
2237 p += sprintf (p, ":italic");
2239 return (p - fcname);
2242 static void
2243 compute_metrics (dc, w32_font, code, metrics)
2244 HDC dc;
2245 struct w32font_info *w32_font;
2246 unsigned int code;
2247 struct w32_metric_cache *metrics;
2249 GLYPHMETRICS gm;
2250 MAT2 transform;
2251 unsigned int options = GGO_METRICS;
2253 if (w32_font->glyph_idx)
2254 options |= GGO_GLYPH_INDEX;
2256 bzero (&transform, sizeof (transform));
2257 transform.eM11.value = 1;
2258 transform.eM22.value = 1;
2260 if (GetGlyphOutlineW (dc, code, options, &gm, 0, NULL, &transform)
2261 != GDI_ERROR)
2263 metrics->lbearing = gm.gmptGlyphOrigin.x;
2264 metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
2265 metrics->width = gm.gmCellIncX;
2266 metrics->status = W32METRIC_SUCCESS;
2268 else
2269 metrics->status = W32METRIC_FAIL;
2272 static void
2273 clear_cached_metrics (w32_font)
2274 struct w32font_info *w32_font;
2276 int i;
2277 for (i = 0; i < w32_font->n_cache_blocks; i++)
2279 if (w32_font->cached_metrics[i])
2280 bzero (w32_font->cached_metrics[i],
2281 CACHE_BLOCKSIZE * sizeof (struct font_metrics));
2285 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
2286 doc: /* Read a font name using a W32 font selection dialog.
2287 Return fontconfig style font string corresponding to the selection.
2289 If FRAME is omitted or nil, it defaults to the selected frame.
2290 If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts
2291 in the font selection dialog. */)
2292 (frame, exclude_proportional)
2293 Lisp_Object frame, exclude_proportional;
2295 FRAME_PTR f = check_x_frame (frame);
2296 CHOOSEFONT cf;
2297 LOGFONT lf;
2298 TEXTMETRIC tm;
2299 HDC hdc;
2300 HANDLE oldobj;
2301 char buf[100];
2303 bzero (&cf, sizeof (cf));
2304 bzero (&lf, sizeof (lf));
2306 cf.lStructSize = sizeof (cf);
2307 cf.hwndOwner = FRAME_W32_WINDOW (f);
2308 cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS | CF_NOVERTFONTS;
2310 /* If exclude_proportional is non-nil, limit the selection to
2311 monospaced fonts. */
2312 if (!NILP (exclude_proportional))
2313 cf.Flags |= CF_FIXEDPITCHONLY;
2315 cf.lpLogFont = &lf;
2317 /* Initialize as much of the font details as we can from the current
2318 default font. */
2319 hdc = GetDC (FRAME_W32_WINDOW (f));
2320 oldobj = SelectObject (hdc, FONT_HANDLE (FRAME_FONT (f)));
2321 GetTextFace (hdc, LF_FACESIZE, lf.lfFaceName);
2322 if (GetTextMetrics (hdc, &tm))
2324 lf.lfHeight = tm.tmInternalLeading - tm.tmHeight;
2325 lf.lfWeight = tm.tmWeight;
2326 lf.lfItalic = tm.tmItalic;
2327 lf.lfUnderline = tm.tmUnderlined;
2328 lf.lfStrikeOut = tm.tmStruckOut;
2329 lf.lfCharSet = tm.tmCharSet;
2330 cf.Flags |= CF_INITTOLOGFONTSTRUCT;
2332 SelectObject (hdc, oldobj);
2333 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
2335 if (!ChooseFont (&cf)
2336 || logfont_to_fcname (&lf, cf.iPointSize, buf, 100) < 0)
2337 return Qnil;
2339 return build_string (buf);
2342 struct font_driver w32font_driver =
2344 0, /* Qgdi */
2345 0, /* case insensitive */
2346 w32font_get_cache,
2347 w32font_list,
2348 w32font_match,
2349 w32font_list_family,
2350 NULL, /* free_entity */
2351 w32font_open,
2352 w32font_close,
2353 NULL, /* prepare_face */
2354 NULL, /* done_face */
2355 w32font_has_char,
2356 w32font_encode_char,
2357 w32font_text_extents,
2358 w32font_draw,
2359 NULL, /* get_bitmap */
2360 NULL, /* free_bitmap */
2361 NULL, /* get_outline */
2362 NULL, /* free_outline */
2363 NULL, /* anchor_point */
2364 NULL, /* otf_capability */
2365 NULL, /* otf_drive */
2366 NULL, /* start_for_frame */
2367 NULL, /* end_for_frame */
2368 NULL /* shape */
2372 /* Initialize state that does not change between invocations. This is only
2373 called when Emacs is dumped. */
2374 void
2375 syms_of_w32font ()
2377 DEFSYM (Qgdi, "gdi");
2378 DEFSYM (Quniscribe, "uniscribe");
2379 DEFSYM (QCformat, ":format");
2381 /* Generic font families. */
2382 DEFSYM (Qmonospace, "monospace");
2383 DEFSYM (Qserif, "serif");
2384 DEFSYM (Qsansserif, "sansserif");
2385 DEFSYM (Qscript, "script");
2386 DEFSYM (Qdecorative, "decorative");
2387 /* Aliases. */
2388 DEFSYM (Qsans_serif, "sans_serif");
2389 DEFSYM (Qsans, "sans");
2390 DEFSYM (Qmono, "mono");
2392 /* Fake foundries. */
2393 DEFSYM (Qraster, "raster");
2394 DEFSYM (Qoutline, "outline");
2395 DEFSYM (Qunknown, "unknown");
2397 /* Antialiasing. */
2398 DEFSYM (Qstandard, "standard");
2399 DEFSYM (Qsubpixel, "subpixel");
2400 DEFSYM (Qnatural, "natural");
2402 /* Languages */
2403 DEFSYM (Qja, "ja");
2404 DEFSYM (Qko, "ko");
2405 DEFSYM (Qzh, "zh");
2407 /* Scripts */
2408 DEFSYM (Qlatin, "latin");
2409 DEFSYM (Qgreek, "greek");
2410 DEFSYM (Qcoptic, "coptic");
2411 DEFSYM (Qcyrillic, "cyrillic");
2412 DEFSYM (Qarmenian, "armenian");
2413 DEFSYM (Qhebrew, "hebrew");
2414 DEFSYM (Qarabic, "arabic");
2415 DEFSYM (Qsyriac, "syriac");
2416 DEFSYM (Qnko, "nko");
2417 DEFSYM (Qthaana, "thaana");
2418 DEFSYM (Qdevanagari, "devanagari");
2419 DEFSYM (Qbengali, "bengali");
2420 DEFSYM (Qgurmukhi, "gurmukhi");
2421 DEFSYM (Qgujarati, "gujarati");
2422 DEFSYM (Qoriya, "oriya");
2423 DEFSYM (Qtamil, "tamil");
2424 DEFSYM (Qtelugu, "telugu");
2425 DEFSYM (Qkannada, "kannada");
2426 DEFSYM (Qmalayalam, "malayalam");
2427 DEFSYM (Qsinhala, "sinhala");
2428 DEFSYM (Qthai, "thai");
2429 DEFSYM (Qlao, "lao");
2430 DEFSYM (Qtibetan, "tibetan");
2431 DEFSYM (Qmyanmar, "myanmar");
2432 DEFSYM (Qgeorgian, "georgian");
2433 DEFSYM (Qhangul, "hangul");
2434 DEFSYM (Qethiopic, "ethiopic");
2435 DEFSYM (Qcherokee, "cherokee");
2436 DEFSYM (Qcanadian_aboriginal, "canadian-aboriginal");
2437 DEFSYM (Qogham, "ogham");
2438 DEFSYM (Qrunic, "runic");
2439 DEFSYM (Qkhmer, "khmer");
2440 DEFSYM (Qmongolian, "mongolian");
2441 DEFSYM (Qsymbol, "symbol");
2442 DEFSYM (Qbraille, "braille");
2443 DEFSYM (Qhan, "han");
2444 DEFSYM (Qideographic_description, "ideographic-description");
2445 DEFSYM (Qcjk_misc, "cjk-misc");
2446 DEFSYM (Qkana, "kana");
2447 DEFSYM (Qbopomofo, "bopomofo");
2448 DEFSYM (Qkanbun, "kanbun");
2449 DEFSYM (Qyi, "yi");
2450 DEFSYM (Qbyzantine_musical_symbol, "byzantine-musical-symbol");
2451 DEFSYM (Qmusical_symbol, "musical-symbol");
2452 DEFSYM (Qmathematical, "mathematical");
2453 DEFSYM (Qphonetic, "phonetic");
2454 DEFSYM (Qbalinese, "balinese");
2455 DEFSYM (Qbuginese, "buginese");
2456 DEFSYM (Qbuhid, "buhid");
2457 DEFSYM (Qcuneiform, "cuneiform");
2458 DEFSYM (Qcypriot, "cypriot");
2459 DEFSYM (Qdeseret, "deseret");
2460 DEFSYM (Qglagolitic, "glagolitic");
2461 DEFSYM (Qgothic, "gothic");
2462 DEFSYM (Qhanunoo, "hanunoo");
2463 DEFSYM (Qkharoshthi, "kharoshthi");
2464 DEFSYM (Qlimbu, "limbu");
2465 DEFSYM (Qlinear_b, "linear_b");
2466 DEFSYM (Qold_italic, "old_italic");
2467 DEFSYM (Qold_persian, "old_persian");
2468 DEFSYM (Qosmanya, "osmanya");
2469 DEFSYM (Qphags_pa, "phags-pa");
2470 DEFSYM (Qphoenician, "phoenician");
2471 DEFSYM (Qshavian, "shavian");
2472 DEFSYM (Qsyloti_nagri, "syloti_nagri");
2473 DEFSYM (Qtagalog, "tagalog");
2474 DEFSYM (Qtagbanwa, "tagbanwa");
2475 DEFSYM (Qtai_le, "tai_le");
2476 DEFSYM (Qtifinagh, "tifinagh");
2477 DEFSYM (Qugaritic, "ugaritic");
2479 /* W32 font encodings. */
2480 DEFVAR_LISP ("w32-charset-info-alist",
2481 &Vw32_charset_info_alist,
2482 doc: /* Alist linking Emacs character sets to Windows fonts and codepages.
2483 Each entry should be of the form:
2485 (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE))
2487 where CHARSET_NAME is a string used in font names to identify the charset,
2488 WINDOWS_CHARSET is a symbol that can be one of:
2490 w32-charset-ansi, w32-charset-default, w32-charset-symbol,
2491 w32-charset-shiftjis, w32-charset-hangeul, w32-charset-gb2312,
2492 w32-charset-chinesebig5, w32-charset-johab, w32-charset-hebrew,
2493 w32-charset-arabic, w32-charset-greek, w32-charset-turkish,
2494 w32-charset-vietnamese, w32-charset-thai, w32-charset-easteurope,
2495 w32-charset-russian, w32-charset-mac, w32-charset-baltic,
2496 or w32-charset-oem.
2498 CODEPAGE should be an integer specifying the codepage that should be used
2499 to display the character set, t to do no translation and output as Unicode,
2500 or nil to do no translation and output as 8 bit (or multibyte on far-east
2501 versions of Windows) characters. */);
2502 Vw32_charset_info_alist = Qnil;
2504 DEFSYM (Qw32_charset_ansi, "w32-charset-ansi");
2505 DEFSYM (Qw32_charset_symbol, "w32-charset-symbol");
2506 DEFSYM (Qw32_charset_default, "w32-charset-default");
2507 DEFSYM (Qw32_charset_shiftjis, "w32-charset-shiftjis");
2508 DEFSYM (Qw32_charset_hangeul, "w32-charset-hangeul");
2509 DEFSYM (Qw32_charset_chinesebig5, "w32-charset-chinesebig5");
2510 DEFSYM (Qw32_charset_gb2312, "w32-charset-gb2312");
2511 DEFSYM (Qw32_charset_oem, "w32-charset-oem");
2512 DEFSYM (Qw32_charset_johab, "w32-charset-johab");
2513 DEFSYM (Qw32_charset_easteurope, "w32-charset-easteurope");
2514 DEFSYM (Qw32_charset_turkish, "w32-charset-turkish");
2515 DEFSYM (Qw32_charset_baltic, "w32-charset-baltic");
2516 DEFSYM (Qw32_charset_russian, "w32-charset-russian");
2517 DEFSYM (Qw32_charset_arabic, "w32-charset-arabic");
2518 DEFSYM (Qw32_charset_greek, "w32-charset-greek");
2519 DEFSYM (Qw32_charset_hebrew, "w32-charset-hebrew");
2520 DEFSYM (Qw32_charset_vietnamese, "w32-charset-vietnamese");
2521 DEFSYM (Qw32_charset_thai, "w32-charset-thai");
2522 DEFSYM (Qw32_charset_mac, "w32-charset-mac");
2524 defsubr (&Sx_select_font);
2526 w32font_driver.type = Qgdi;
2527 register_font_driver (&w32font_driver, NULL);
2530 /* arch-tag: 65b8a3cd-46aa-4c0d-a1f3-99e75b9c07ee
2531 (do not change this comment) */