1 /* Font backend for the Microsoft W32 API.
2 Copyright (C) 2007 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 2, or (at your option)
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; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
27 #include "dispextern.h"
28 #include "character.h"
34 /* Cleartype available on Windows XP, cleartype_natural from XP SP1.
35 The latter does not try to fit cleartype smoothed fonts into the
36 same bounding box as the non-antialiased version of the font.
38 #ifndef CLEARTYPE_QUALITY
39 #define CLEARTYPE_QUALITY 5
41 #ifndef CLEARTYPE_NATURAL_QUALITY
42 #define CLEARTYPE_NATURAL_QUALITY 6
45 extern struct font_driver w32font_driver
;
48 static Lisp_Object Qmonospace
, Qsansserif
, Qmono
, Qsans
, Qsans_serif
;
49 static Lisp_Object Qserif
, Qscript
, Qdecorative
;
50 static Lisp_Object Qraster
, Qoutline
, Qunknown
;
53 extern Lisp_Object QCantialias
; /* defined in font.c */
54 extern Lisp_Object Qnone
; /* reuse from w32fns.c */
55 static Lisp_Object Qstandard
, Qsubpixel
, Qnatural
;
58 static Lisp_Object Qlatin
, Qgreek
, Qcoptic
, Qcyrillic
, Qarmenian
, Qhebrew
;
59 static Lisp_Object Qarabic
, Qsyriac
, Qnko
, Qthaana
, Qdevanagari
, Qbengali
;
60 static Lisp_Object Qgurmukhi
, Qgujarati
, Qoriya
, Qtamil
, Qtelugu
;
61 static Lisp_Object Qkannada
, Qmalayalam
, Qsinhala
, Qthai
, Qlao
;
62 static Lisp_Object Qtibetan
, Qmyanmar
, Qgeorgian
, Qhangul
, Qethiopic
;
63 static Lisp_Object Qcherokee
, Qcanadian_aboriginal
, Qogham
, Qrunic
;
64 static Lisp_Object Qkhmer
, Qmongolian
, Qsymbol
, Qbraille
, Qhan
;
65 static Lisp_Object Qideographic_description
, Qcjk_misc
, Qkana
, Qbopomofo
;
66 static Lisp_Object Qkanbun
, Qyi
, Qbyzantine_musical_symbol
;
67 static Lisp_Object Qmusical_symbol
, Qmathematical
;
69 /* Font spacing symbols - defined in font.c. */
70 extern Lisp_Object Qc
, Qp
, Qm
;
72 static void fill_in_logfont
P_ ((FRAME_PTR f
, LOGFONT
*logfont
,
73 Lisp_Object font_spec
));
75 static BYTE w32_antialias_type
P_ ((Lisp_Object type
));
76 static Lisp_Object lispy_antialias_type
P_ ((BYTE type
));
78 static Lisp_Object font_supported_scripts
P_ ((FONTSIGNATURE
* sig
));
80 /* From old font code in w32fns.c */
81 char * w32_to_x_charset
P_ ((int charset
, char * matching
));
83 static Lisp_Object w32_registry
P_ ((LONG w32_charset
));
85 /* EnumFontFamiliesEx callbacks. */
86 static int CALLBACK add_font_entity_to_list
P_ ((ENUMLOGFONTEX
*,
89 static int CALLBACK add_one_font_entity_to_list
P_ ((ENUMLOGFONTEX
*,
92 static int CALLBACK add_font_name_to_list
P_ ((ENUMLOGFONTEX
*,
96 /* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
97 of what we really want. */
98 struct font_callback_data
100 /* The logfont we are matching against. EnumFontFamiliesEx only matches
101 face name and charset, so we need to manually match everything else
102 in the callback function. */
104 /* The original font spec or entity. */
105 Lisp_Object orig_font_spec
;
106 /* The frame the font is being loaded on. */
108 /* The list to add matches to. */
110 /* Whether to match only opentype fonts. */
114 /* Handles the problem that EnumFontFamiliesEx will not return all
115 style variations if the font name is not specified. */
116 static void list_all_matching_fonts
P_ ((struct font_callback_data
*match
));
119 /* MingW headers only define this when _WIN32_WINNT >= 0x0500, but we
120 target older versions. */
121 #ifndef GGI_MARK_NONEXISTING_GLYPHS
122 #define GGI_MARK_NONEXISTING_GLYPHS 1
126 memq_no_quit (elt
, list
)
127 Lisp_Object elt
, list
;
129 while (CONSP (list
) && ! EQ (XCAR (list
), elt
))
131 return (CONSP (list
));
134 /* w32 implementation of get_cache for font backend.
135 Return a cache of font-entities on FRAME. The cache must be a
136 cons whose cdr part is the actual cache area. */
138 w32font_get_cache (f
)
141 struct w32_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
143 return (dpyinfo
->name_list_element
);
146 /* w32 implementation of list for font backend.
147 List fonts exactly matching with FONT_SPEC on FRAME. The value
148 is a vector of font-entities. This is the sole API that
149 allocates font-entities. */
151 w32font_list (frame
, font_spec
)
152 Lisp_Object frame
, font_spec
;
154 return w32font_list_internal (frame
, font_spec
, 0);
157 /* w32 implementation of match for font backend.
158 Return a font entity most closely matching with FONT_SPEC on
159 FRAME. The closeness is detemined by the font backend, thus
160 `face-font-selection-order' is ignored here. */
162 w32font_match (frame
, font_spec
)
163 Lisp_Object frame
, font_spec
;
165 return w32font_match_internal (frame
, font_spec
, 0);
168 /* w32 implementation of list_family for font backend.
169 List available families. The value is a list of family names
172 w32font_list_family (frame
)
175 Lisp_Object list
= Qnil
;
176 LOGFONT font_match_pattern
;
178 FRAME_PTR f
= XFRAME (frame
);
180 bzero (&font_match_pattern
, sizeof (font_match_pattern
));
182 dc
= get_frame_dc (f
);
184 EnumFontFamiliesEx (dc
, &font_match_pattern
,
185 (FONTENUMPROC
) add_font_name_to_list
,
187 release_frame_dc (f
, dc
);
192 /* w32 implementation of open for font backend.
193 Open a font specified by FONT_ENTITY on frame F.
194 If the font is scalable, open it with PIXEL_SIZE. */
196 w32font_open (f
, font_entity
, pixel_size
)
198 Lisp_Object font_entity
;
201 struct w32font_info
*w32_font
= xmalloc (sizeof (struct w32font_info
));
203 if (w32_font
== NULL
)
206 if (!w32font_open_internal (f
, font_entity
, pixel_size
, w32_font
))
212 return (struct font
*) w32_font
;
215 /* w32 implementation of close for font_backend.
216 Close FONT on frame F. */
218 w32font_close (f
, font
)
224 W32FontStruct
*old_w32_font
= (W32FontStruct
*)font
->font
.font
;
225 DeleteObject (old_w32_font
->hfont
);
226 xfree (old_w32_font
);
231 xfree (font
->font
.name
);
235 /* w32 implementation of has_char for font backend.
237 If FONT_ENTITY has a glyph for character C (Unicode code point),
238 return 1. If not, return 0. If a font must be opened to check
241 w32font_has_char (entity
, c
)
245 Lisp_Object supported_scripts
, extra
, script
;
248 extra
= AREF (entity
, FONT_EXTRA_INDEX
);
252 supported_scripts
= assq_no_quit (QCscript
, extra
);
253 if (!CONSP (supported_scripts
))
256 supported_scripts
= XCDR (supported_scripts
);
258 script
= CHAR_TABLE_REF (Vchar_script_table
, c
);
260 return (memq_no_quit (script
, supported_scripts
)) ? 1 : 0;
263 /* w32 implementation of encode_char for font backend.
264 Return a glyph code of FONT for characer C (Unicode code point).
265 If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */
267 w32font_encode_char (font
, c
)
271 /* Avoid unneccesary conversion - all the Win32 APIs will take a unicode
276 /* w32 implementation of text_extents for font backend.
277 Perform the size computation of glyphs of FONT and fillin members
278 of METRICS. The glyphs are specified by their glyph codes in
279 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
280 case just return the overall width. */
282 w32font_text_extents (font
, code
, nglyphs
, metrics
)
286 struct font_metrics
*metrics
;
293 WORD
*wcode
= alloca(nglyphs
* sizeof (WORD
));
297 /* Frames can come and go, and their fonts outlive them. This is
298 particularly troublesome with tooltip frames, and causes crashes. */
299 f
= ((struct w32font_info
*)font
)->owning_frame
;
301 f
= XFRAME (selected_frame
);
304 dc
= get_frame_dc (f
);
305 old_font
= SelectObject (dc
, ((W32FontStruct
*)(font
->font
.font
))->hfont
);
312 /* Set transform to the identity matrix. */
313 bzero (&transform
, sizeof (transform
));
314 transform
.eM11
.value
= 1;
315 transform
.eM22
.value
= 1;
318 metrics
->descent
= 0;
320 for (i
= 0; i
< nglyphs
; i
++)
322 if (GetGlyphOutlineW (dc
, *(code
+ i
), GGO_METRICS
, &gm
, 0,
323 NULL
, &transform
) != GDI_ERROR
)
325 int new_val
= metrics
->width
+ gm
.gmBlackBoxX
326 + gm
.gmptGlyphOrigin
.x
;
328 metrics
->rbearing
= max (metrics
->rbearing
, new_val
);
329 metrics
->width
+= gm
.gmCellIncX
;
330 new_val
= -gm
.gmptGlyphOrigin
.y
;
331 metrics
->ascent
= max (metrics
->ascent
, new_val
);
332 new_val
= gm
.gmBlackBoxY
+ gm
.gmptGlyphOrigin
.y
;
333 metrics
->descent
= max (metrics
->descent
, new_val
);
337 /* Rely on an estimate based on the overall font metrics. */
342 /* If we got through everything, return. */
345 /* Restore state and release DC. */
346 SelectObject (dc
, old_font
);
347 release_frame_dc (f
, dc
);
349 return metrics
->width
;
353 for (i
= 0; i
< nglyphs
; i
++)
355 if (code
[i
] < 0x10000)
359 /* TODO: Convert to surrogate, reallocating array if needed */
364 if (GetTextExtentPoint32W (dc
, wcode
, nglyphs
, &size
))
366 total_width
= size
.cx
;
372 rect
.top
= 0; rect
.bottom
= font
->font
.height
; rect
.left
= 0; rect
.right
= 1;
373 DrawTextW (dc
, wcode
, nglyphs
, &rect
,
374 DT_CALCRECT
| DT_NOPREFIX
| DT_SINGLELINE
);
375 total_width
= rect
.right
;
380 metrics
->width
= total_width
;
381 metrics
->ascent
= font
->ascent
;
382 metrics
->descent
= font
->descent
;
383 metrics
->lbearing
= 0;
384 metrics
->rbearing
= total_width
385 + ((struct w32font_info
*) font
)->metrics
.tmOverhang
;
388 /* Restore state and release DC. */
389 SelectObject (dc
, old_font
);
390 release_frame_dc (f
, dc
);
395 /* w32 implementation of draw for font backend.
397 Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
398 position of frame F with S->FACE and S->GC. If WITH_BACKGROUND
399 is nonzero, fill the background in advance. It is assured that
400 WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars).
402 TODO: Currently this assumes that the colors and fonts are already
403 set in the DC. This seems to be true now, but maybe only due to
404 the old font code setting it up. It may be safer to resolve faces
405 and fonts in here and set them explicitly
409 w32font_draw (s
, from
, to
, x
, y
, with_background
)
410 struct glyph_string
*s
;
411 int from
, to
, x
, y
, with_background
;
416 /* Save clip region for later restoration. */
417 GetClipRgn(s
->hdc
, orig_clip
);
419 if (s
->num_clips
> 0)
421 HRGN new_clip
= CreateRectRgnIndirect (s
->clip
);
423 if (s
->num_clips
> 1)
425 HRGN clip2
= CreateRectRgnIndirect (s
->clip
+ 1);
427 CombineRgn (new_clip
, new_clip
, clip2
, RGN_OR
);
428 DeleteObject (clip2
);
431 SelectClipRgn (s
->hdc
, new_clip
);
432 DeleteObject (new_clip
);
435 /* Using OPAQUE background mode can clear more background than expected
436 when Cleartype is used. Draw the background manually to avoid this. */
437 SetBkMode (s
->hdc
, TRANSPARENT
);
442 struct font
*font
= (struct font
*) s
->face
->font_info
;
444 brush
= CreateSolidBrush (s
->gc
->background
);
446 rect
.top
= y
- font
->ascent
;
447 rect
.right
= x
+ s
->width
;
448 rect
.bottom
= y
+ font
->descent
;
449 FillRect (s
->hdc
, &rect
, brush
);
450 DeleteObject (brush
);
453 ExtTextOutW (s
->hdc
, x
, y
, options
, NULL
, s
->char2b
+ from
, to
- from
, NULL
);
455 /* Restore clip region. */
456 if (s
->num_clips
> 0)
458 SelectClipRgn (s
->hdc
, orig_clip
);
462 /* w32 implementation of free_entity for font backend.
463 Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value).
464 Free FONT_EXTRA_INDEX field of FONT_ENTITY.
466 w32font_free_entity (Lisp_Object entity);
469 /* w32 implementation of prepare_face for font backend.
470 Optional (if FACE->extra is not used).
471 Prepare FACE for displaying characters by FONT on frame F by
472 storing some data in FACE->extra. If successful, return 0.
473 Otherwise, return -1.
475 w32font_prepare_face (FRAME_PTR f, struct face *face);
477 /* w32 implementation of done_face for font backend.
479 Done FACE for displaying characters by FACE->font on frame F.
481 w32font_done_face (FRAME_PTR f, struct face *face); */
483 /* w32 implementation of get_bitmap for font backend.
485 Store bitmap data for glyph-code CODE of FONT in BITMAP. It is
486 intended that this method is called from the other font-driver
489 w32font_get_bitmap (struct font *font, unsigned code,
490 struct font_bitmap *bitmap, int bits_per_pixel);
492 /* w32 implementation of free_bitmap for font backend.
494 Free bitmap data in BITMAP.
496 w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap);
498 /* w32 implementation of get_outline for font backend.
500 Return an outline data for glyph-code CODE of FONT. The format
501 of the outline data depends on the font-driver.
503 w32font_get_outline (struct font *font, unsigned code);
505 /* w32 implementation of free_outline for font backend.
507 Free OUTLINE (that is obtained by the above method).
509 w32font_free_outline (struct font *font, void *outline);
511 /* w32 implementation of anchor_point for font backend.
513 Get coordinates of the INDEXth anchor point of the glyph whose
514 code is CODE. Store the coordinates in *X and *Y. Return 0 if
515 the operations was successfull. Otherwise return -1.
517 w32font_anchor_point (struct font *font, unsigned code,
518 int index, int *x, int *y);
520 /* w32 implementation of otf_capability for font backend.
522 Return a list describing which scripts/languages FONT
523 supports by which GSUB/GPOS features of OpenType tables.
525 w32font_otf_capability (struct font *font);
527 /* w32 implementation of otf_drive for font backend.
529 Apply FONT's OTF-FEATURES to the glyph string.
531 FEATURES specifies which OTF features to apply in this format:
532 (SCRIPT LANGSYS GSUB-FEATURE GPOS-FEATURE)
533 See the documentation of `font-drive-otf' for the detail.
535 This method applies the specified features to the codes in the
536 elements of GSTRING-IN (between FROMth and TOth). The output
537 codes are stored in GSTRING-OUT at the IDXth element and the
540 Return the number of output codes. If none of the features are
541 applicable to the input data, return 0. If GSTRING-OUT is too
544 w32font_otf_drive (struct font *font, Lisp_Object features,
545 Lisp_Object gstring_in, int from, int to,
546 Lisp_Object gstring_out, int idx,
547 int alternate_subst);
550 /* Internal implementation of w32font_list.
551 Additional parameter opentype_only restricts the returned fonts to
552 opentype fonts, which can be used with the Uniscribe backend. */
554 w32font_list_internal (frame
, font_spec
, opentype_only
)
555 Lisp_Object frame
, font_spec
;
558 struct font_callback_data match_data
;
560 FRAME_PTR f
= XFRAME (frame
);
562 match_data
.orig_font_spec
= font_spec
;
563 match_data
.list
= Qnil
;
564 match_data
.frame
= frame
;
566 bzero (&match_data
.pattern
, sizeof (LOGFONT
));
567 fill_in_logfont (f
, &match_data
.pattern
, font_spec
);
569 match_data
.opentype_only
= opentype_only
;
571 match_data
.pattern
.lfOutPrecision
= OUT_OUTLINE_PRECIS
;
573 if (match_data
.pattern
.lfFaceName
[0] == '\0')
575 /* EnumFontFamiliesEx does not take other fields into account if
576 font name is blank, so need to use two passes. */
577 list_all_matching_fonts (&match_data
);
581 dc
= get_frame_dc (f
);
583 EnumFontFamiliesEx (dc
, &match_data
.pattern
,
584 (FONTENUMPROC
) add_font_entity_to_list
,
585 (LPARAM
) &match_data
, 0);
586 release_frame_dc (f
, dc
);
589 return NILP (match_data
.list
) ? null_vector
: Fvconcat (1, &match_data
.list
);
592 /* Internal implementation of w32font_match.
593 Additional parameter opentype_only restricts the returned fonts to
594 opentype fonts, which can be used with the Uniscribe backend. */
596 w32font_match_internal (frame
, font_spec
, opentype_only
)
597 Lisp_Object frame
, font_spec
;
600 struct font_callback_data match_data
;
602 FRAME_PTR f
= XFRAME (frame
);
604 match_data
.orig_font_spec
= font_spec
;
605 match_data
.frame
= frame
;
606 match_data
.list
= Qnil
;
608 bzero (&match_data
.pattern
, sizeof (LOGFONT
));
609 fill_in_logfont (f
, &match_data
.pattern
, font_spec
);
611 match_data
.opentype_only
= opentype_only
;
613 match_data
.pattern
.lfOutPrecision
= OUT_OUTLINE_PRECIS
;
615 dc
= get_frame_dc (f
);
617 EnumFontFamiliesEx (dc
, &match_data
.pattern
,
618 (FONTENUMPROC
) add_one_font_entity_to_list
,
619 (LPARAM
) &match_data
, 0);
620 release_frame_dc (f
, dc
);
622 return NILP (match_data
.list
) ? Qnil
: XCAR (match_data
.list
);
626 w32font_open_internal (f
, font_entity
, pixel_size
, w32_font
)
628 Lisp_Object font_entity
;
630 struct w32font_info
*w32_font
;
635 HFONT hfont
, old_font
;
636 Lisp_Object val
, extra
;
637 /* For backwards compatibility. */
638 W32FontStruct
*compat_w32_font
;
640 struct font
* font
= (struct font
*) w32_font
;
644 bzero (&logfont
, sizeof (logfont
));
645 fill_in_logfont (f
, &logfont
, font_entity
);
647 size
= XINT (AREF (font_entity
, FONT_SIZE_INDEX
));
651 logfont
.lfHeight
= -size
;
652 hfont
= CreateFontIndirect (&logfont
);
657 w32_font
->owning_frame
= f
;
659 /* Get the metrics for this font. */
660 dc
= get_frame_dc (f
);
661 old_font
= SelectObject (dc
, hfont
);
663 GetTextMetrics (dc
, &w32_font
->metrics
);
665 SelectObject (dc
, old_font
);
666 release_frame_dc (f
, dc
);
667 /* W32FontStruct - we should get rid of this, and use the w32font_info
668 struct for any W32 specific fields. font->font.font can then be hfont. */
669 font
->font
.font
= xmalloc (sizeof (W32FontStruct
));
670 compat_w32_font
= (W32FontStruct
*) font
->font
.font
;
671 bzero (compat_w32_font
, sizeof (W32FontStruct
));
672 compat_w32_font
->font_type
= UNICODE_FONT
;
673 /* Duplicate the text metrics. */
674 bcopy (&w32_font
->metrics
, &compat_w32_font
->tm
, sizeof (TEXTMETRIC
));
675 compat_w32_font
->hfont
= hfont
;
677 len
= strlen (logfont
.lfFaceName
);
678 font
->font
.name
= (char *) xmalloc (len
+ 1);
679 bcopy (logfont
.lfFaceName
, font
->font
.name
, len
);
680 font
->font
.name
[len
] = '\0';
681 font
->font
.full_name
= font
->font
.name
;
682 font
->font
.charset
= 0;
683 font
->font
.codepage
= 0;
684 font
->font
.size
= w32_font
->metrics
.tmMaxCharWidth
;
685 font
->font
.height
= w32_font
->metrics
.tmHeight
686 + w32_font
->metrics
.tmExternalLeading
;
687 font
->font
.space_width
= font
->font
.average_width
688 = w32_font
->metrics
.tmAveCharWidth
;
690 font
->font
.vertical_centering
= 0;
691 font
->font
.encoding_type
= 0;
692 font
->font
.baseline_offset
= 0;
693 font
->font
.relative_compose
= 0;
694 font
->font
.default_ascent
= w32_font
->metrics
.tmAscent
;
695 font
->font
.font_encoder
= NULL
;
696 font
->entity
= font_entity
;
697 font
->pixel_size
= size
;
698 font
->driver
= &w32font_driver
;
700 font
->file_name
= NULL
;
701 font
->encoding_charset
= -1;
702 font
->repertory_charset
= -1;
704 font
->ascent
= w32_font
->metrics
.tmAscent
;
705 font
->descent
= w32_font
->metrics
.tmDescent
;
706 font
->scalable
= w32_font
->metrics
.tmPitchAndFamily
& TMPF_VECTOR
;
711 /* Callback function for EnumFontFamiliesEx.
712 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
714 add_font_name_to_list (logical_font
, physical_font
, font_type
, list_object
)
715 ENUMLOGFONTEX
*logical_font
;
716 NEWTEXTMETRICEX
*physical_font
;
720 Lisp_Object
* list
= (Lisp_Object
*) list_object
;
723 /* Skip vertical fonts (intended only for printing) */
724 if (logical_font
->elfLogFont
.lfFaceName
[0] == '@')
727 family
= intern_downcase (logical_font
->elfLogFont
.lfFaceName
,
728 strlen (logical_font
->elfLogFont
.lfFaceName
));
729 if (! memq_no_quit (family
, *list
))
730 *list
= Fcons (family
, *list
);
735 /* Convert an enumerated Windows font to an Emacs font entity. */
737 w32_enumfont_pattern_entity (frame
, logical_font
, physical_font
,
738 font_type
, requested_font
)
740 ENUMLOGFONTEX
*logical_font
;
741 NEWTEXTMETRICEX
*physical_font
;
743 LOGFONT
*requested_font
;
745 Lisp_Object entity
, tem
;
746 LOGFONT
*lf
= (LOGFONT
*) logical_font
;
749 entity
= Fmake_vector (make_number (FONT_ENTITY_MAX
), Qnil
);
751 ASET (entity
, FONT_TYPE_INDEX
, Qgdi
);
752 ASET (entity
, FONT_FRAME_INDEX
, frame
);
753 ASET (entity
, FONT_REGISTRY_INDEX
, w32_registry (lf
->lfCharSet
));
754 ASET (entity
, FONT_OBJLIST_INDEX
, Qnil
);
756 /* Foundry is difficult to get in readable form on Windows.
757 But Emacs crashes if it is not set, so set it to something more
758 generic. Thes values make xflds compatible with Emacs 22. */
759 if (lf
->lfOutPrecision
== OUT_STRING_PRECIS
)
761 else if (lf
->lfOutPrecision
== OUT_STROKE_PRECIS
)
766 ASET (entity
, FONT_FOUNDRY_INDEX
, tem
);
768 /* Save the generic family in the extra info, as it is likely to be
769 useful to users looking for a close match. */
770 generic_type
= physical_font
->ntmTm
.tmPitchAndFamily
& 0xF0;
771 if (generic_type
== FF_DECORATIVE
)
773 else if (generic_type
== FF_MODERN
)
775 else if (generic_type
== FF_ROMAN
)
777 else if (generic_type
== FF_SCRIPT
)
779 else if (generic_type
== FF_SWISS
)
784 ASET (entity
, FONT_ADSTYLE_INDEX
, tem
);
786 if (physical_font
->ntmTm
.tmPitchAndFamily
& 0x01)
787 font_put_extra (entity
, QCspacing
, make_number (FONT_SPACING_PROPORTIONAL
));
789 font_put_extra (entity
, QCspacing
, make_number (FONT_SPACING_MONO
));
791 if (requested_font
->lfQuality
!= DEFAULT_QUALITY
)
793 font_put_extra (entity
, QCantialias
,
794 lispy_antialias_type (requested_font
->lfQuality
));
796 ASET (entity
, FONT_FAMILY_INDEX
,
797 intern_downcase (lf
->lfFaceName
, strlen (lf
->lfFaceName
)));
799 ASET (entity
, FONT_WEIGHT_INDEX
, make_number (lf
->lfWeight
));
800 ASET (entity
, FONT_SLANT_INDEX
, make_number (lf
->lfItalic
? 200 : 100));
801 /* TODO: PANOSE struct has this info, but need to call GetOutlineTextMetrics
803 ASET (entity
, FONT_WIDTH_INDEX
, make_number (100));
805 if (font_type
& RASTER_FONTTYPE
)
806 ASET (entity
, FONT_SIZE_INDEX
, make_number (physical_font
->ntmTm
.tmHeight
));
808 ASET (entity
, FONT_SIZE_INDEX
, make_number (0));
810 /* Cache unicode codepoints covered by this font, as there is no other way
811 of getting this information easily. */
812 if (font_type
& TRUETYPE_FONTTYPE
)
814 font_put_extra (entity
, QCscript
,
815 font_supported_scripts (&physical_font
->ntmFontSig
));
822 /* Convert generic families to the family portion of lfPitchAndFamily. */
824 w32_generic_family (Lisp_Object name
)
826 /* Generic families. */
827 if (EQ (name
, Qmonospace
) || EQ (name
, Qmono
))
829 else if (EQ (name
, Qsans
) || EQ (name
, Qsans_serif
) || EQ (name
, Qsansserif
))
831 else if (EQ (name
, Qserif
))
833 else if (EQ (name
, Qdecorative
))
834 return FF_DECORATIVE
;
835 else if (EQ (name
, Qscript
))
842 logfonts_match (font
, pattern
)
843 LOGFONT
*font
, *pattern
;
845 /* Only check height for raster fonts. */
846 if (pattern
->lfHeight
&& font
->lfOutPrecision
== OUT_STRING_PRECIS
847 && font
->lfHeight
!= pattern
->lfHeight
)
850 /* Have some flexibility with weights. */
851 if (pattern
->lfWeight
852 && ((font
->lfWeight
< (pattern
->lfWeight
- 150))
853 || font
->lfWeight
> (pattern
->lfWeight
+ 150)))
856 /* Charset and face should be OK. Italic has to be checked
857 against the original spec, in case we don't have any preference. */
862 font_matches_spec (type
, font
, spec
)
864 NEWTEXTMETRICEX
*font
;
867 Lisp_Object extra
, val
;
869 /* Check italic. Can't check logfonts, since it is a boolean field,
870 so there is no difference between "non-italic" and "don't care". */
871 val
= AREF (spec
, FONT_SLANT_INDEX
);
874 int slant
= XINT (val
);
875 if ((slant
> 150 && !font
->ntmTm
.tmItalic
)
876 || (slant
<= 150 && font
->ntmTm
.tmItalic
))
880 /* Check adstyle against generic family. */
881 val
= AREF (spec
, FONT_ADSTYLE_INDEX
);
884 BYTE family
= w32_generic_family (val
);
885 if (family
!= FF_DONTCARE
886 && family
!= (font
->ntmTm
.tmPitchAndFamily
& 0xF0))
890 /* Check extra parameters. */
891 for (extra
= AREF (spec
, FONT_EXTRA_INDEX
);
892 CONSP (extra
); extra
= XCDR (extra
))
894 Lisp_Object extra_entry
;
895 extra_entry
= XCAR (extra
);
896 if (CONSP (extra_entry
))
898 Lisp_Object key
= XCAR (extra_entry
);
899 val
= XCDR (extra_entry
);
900 if (EQ (key
, QCspacing
))
905 int spacing
= XINT (val
);
906 proportional
= (spacing
< FONT_SPACING_MONO
);
908 else if (EQ (val
, Qp
))
910 else if (EQ (val
, Qc
) || EQ (val
, Qm
))
913 return 0; /* Bad font spec. */
915 if ((proportional
&& !(font
->ntmTm
.tmPitchAndFamily
& 0x01))
916 || (!proportional
&& (font
->ntmTm
.tmPitchAndFamily
& 0x01)))
919 else if (EQ (key
, QCscript
) && SYMBOLP (val
))
921 /* Only truetype fonts will have information about what
922 scripts they support. This probably means the user
923 will have to force Emacs to use raster, postscript
924 or atm fonts for non-ASCII text. */
925 if (type
& TRUETYPE_FONTTYPE
)
928 = font_supported_scripts (&font
->ntmFontSig
);
929 if (! memq_no_quit (val
, support
))
934 /* Return specific matches, but play it safe. Fonts
935 that cover more than their charset would suggest
936 are likely to be truetype or opentype fonts,
938 if (EQ (val
, Qlatin
))
940 /* Although every charset but symbol, thai and
941 arabic contains the basic ASCII set of latin
942 characters, Emacs expects much more. */
943 if (font
->ntmTm
.tmCharSet
!= ANSI_CHARSET
)
946 else if (EQ (val
, Qsymbol
))
948 if (font
->ntmTm
.tmCharSet
!= SYMBOL_CHARSET
)
951 else if (EQ (val
, Qcyrillic
))
953 if (font
->ntmTm
.tmCharSet
!= RUSSIAN_CHARSET
)
956 else if (EQ (val
, Qgreek
))
958 if (font
->ntmTm
.tmCharSet
!= GREEK_CHARSET
)
961 else if (EQ (val
, Qarabic
))
963 if (font
->ntmTm
.tmCharSet
!= ARABIC_CHARSET
)
966 else if (EQ (val
, Qhebrew
))
968 if (font
->ntmTm
.tmCharSet
!= HEBREW_CHARSET
)
971 else if (EQ (val
, Qthai
))
973 if (font
->ntmTm
.tmCharSet
!= THAI_CHARSET
)
976 else if (EQ (val
, Qkana
))
978 if (font
->ntmTm
.tmCharSet
!= SHIFTJIS_CHARSET
)
981 else if (EQ (val
, Qbopomofo
))
983 if (font
->ntmTm
.tmCharSet
!= CHINESEBIG5_CHARSET
)
986 else if (EQ (val
, Qhangul
))
988 if (font
->ntmTm
.tmCharSet
!= HANGUL_CHARSET
989 && font
->ntmTm
.tmCharSet
!= JOHAB_CHARSET
)
992 else if (EQ (val
, Qhan
))
994 if (font
->ntmTm
.tmCharSet
!= CHINESEBIG5_CHARSET
995 && font
->ntmTm
.tmCharSet
!= GB2312_CHARSET
996 && font
->ntmTm
.tmCharSet
!= HANGUL_CHARSET
997 && font
->ntmTm
.tmCharSet
!= JOHAB_CHARSET
998 && font
->ntmTm
.tmCharSet
!= SHIFTJIS_CHARSET
)
1002 /* Other scripts unlikely to be handled. */
1011 /* Callback function for EnumFontFamiliesEx.
1012 * Checks if a font matches everything we are trying to check agaist,
1013 * and if so, adds it to a list. Both the data we are checking against
1014 * and the list to which the fonts are added are passed in via the
1015 * lparam argument, in the form of a font_callback_data struct. */
1017 add_font_entity_to_list (logical_font
, physical_font
, font_type
, lParam
)
1018 ENUMLOGFONTEX
*logical_font
;
1019 NEWTEXTMETRICEX
*physical_font
;
1023 struct font_callback_data
*match_data
1024 = (struct font_callback_data
*) lParam
;
1026 if ((!match_data
->opentype_only
1027 || (physical_font
->ntmTm
.ntmFlags
& NTMFLAGS_OPENTYPE
))
1028 && logfonts_match (&logical_font
->elfLogFont
, &match_data
->pattern
)
1029 && font_matches_spec (font_type
, physical_font
,
1030 match_data
->orig_font_spec
)
1031 /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif)
1032 We limit this to raster fonts, because the test can catch some
1033 genuine fonts (eg the full name of DejaVu Sans Mono Light is actually
1034 DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will
1035 therefore get through this test. Since full names can be prefixed
1036 by a foundry, we accept raster fonts if the font name is found
1037 anywhere within the full name. */
1038 && (logical_font
->elfLogFont
.lfOutPrecision
!= OUT_STRING_PRECIS
1039 || strstr (logical_font
->elfFullName
,
1040 logical_font
->elfLogFont
.lfFaceName
)))
1043 = w32_enumfont_pattern_entity (match_data
->frame
, logical_font
,
1044 physical_font
, font_type
,
1045 &match_data
->pattern
);
1047 match_data
->list
= Fcons (entity
, match_data
->list
);
1052 /* Callback function for EnumFontFamiliesEx.
1053 * Terminates the search once we have a match. */
1055 add_one_font_entity_to_list (logical_font
, physical_font
, font_type
, lParam
)
1056 ENUMLOGFONTEX
*logical_font
;
1057 NEWTEXTMETRICEX
*physical_font
;
1061 struct font_callback_data
*match_data
1062 = (struct font_callback_data
*) lParam
;
1063 add_font_entity_to_list (logical_font
, physical_font
, font_type
, lParam
);
1065 /* If we have a font in the list, terminate the search. */
1066 return !NILP (match_data
->list
);
1069 /* Convert a Lisp font registry (symbol) to a windows charset. */
1071 registry_to_w32_charset (charset
)
1072 Lisp_Object charset
;
1074 if (EQ (charset
, Qiso10646_1
) || EQ (charset
, Qunicode_bmp
)
1075 || EQ (charset
, Qunicode_sip
))
1076 return DEFAULT_CHARSET
; /* UNICODE_CHARSET not defined in MingW32 */
1077 else if (EQ (charset
, Qiso8859_1
))
1078 return ANSI_CHARSET
;
1079 else if (SYMBOLP (charset
))
1080 return x_to_w32_charset (SDATA (SYMBOL_NAME (charset
)));
1081 else if (STRINGP (charset
))
1082 return x_to_w32_charset (SDATA (charset
));
1084 return DEFAULT_CHARSET
;
1088 w32_registry (w32_charset
)
1091 if (w32_charset
== ANSI_CHARSET
)
1095 char * charset
= w32_to_x_charset (w32_charset
, NULL
);
1096 return intern_downcase (charset
, strlen(charset
));
1100 /* Fill in all the available details of LOGFONT from FONT_SPEC. */
1102 fill_in_logfont (f
, logfont
, font_spec
)
1105 Lisp_Object font_spec
;
1107 Lisp_Object tmp
, extra
;
1108 int dpi
= FRAME_W32_DISPLAY_INFO (f
)->resy
;
1110 extra
= AREF (font_spec
, FONT_EXTRA_INDEX
);
1111 /* Allow user to override dpi settings. */
1114 tmp
= assq_no_quit (QCdpi
, extra
);
1115 if (CONSP (tmp
) && INTEGERP (XCDR (tmp
)))
1117 dpi
= XINT (XCDR (tmp
));
1119 else if (CONSP (tmp
) && FLOATP (XCDR (tmp
)))
1121 dpi
= (int) (XFLOAT_DATA (XCDR (tmp
)) + 0.5);
1126 tmp
= AREF (font_spec
, FONT_SIZE_INDEX
);
1128 logfont
->lfHeight
= -1 * XINT (tmp
);
1129 else if (FLOATP (tmp
))
1130 logfont
->lfHeight
= (int) (-1.0 * dpi
* XFLOAT_DATA (tmp
) / 72.27 + 0.5);
1137 tmp
= AREF (font_spec
, FONT_WEIGHT_INDEX
);
1139 logfont
->lfWeight
= XINT (tmp
);
1142 tmp
= AREF (font_spec
, FONT_SLANT_INDEX
);
1145 int slant
= XINT (tmp
);
1146 logfont
->lfItalic
= slant
> 150 ? 1 : 0;
1154 tmp
= AREF (font_spec
, FONT_REGISTRY_INDEX
);
1156 logfont
->lfCharSet
= registry_to_w32_charset (tmp
);
1160 /* Clip Precision */
1163 logfont
->lfQuality
= DEFAULT_QUALITY
;
1165 /* Generic Family and Face Name */
1166 logfont
->lfPitchAndFamily
= FF_DONTCARE
| DEFAULT_PITCH
;
1168 tmp
= AREF (font_spec
, FONT_FAMILY_INDEX
);
1171 logfont
->lfPitchAndFamily
= w32_generic_family (tmp
) | DEFAULT_PITCH
;
1172 if ((logfont
->lfPitchAndFamily
& 0xF0) != FF_DONTCARE
)
1173 ; /* Font name was generic, don't fill in font name. */
1174 /* Font families are interned, but allow for strings also in case of
1176 else if (SYMBOLP (tmp
))
1177 strncpy (logfont
->lfFaceName
, SDATA (SYMBOL_NAME (tmp
)), LF_FACESIZE
);
1178 else if (STRINGP (tmp
))
1179 strncpy (logfont
->lfFaceName
, SDATA (tmp
), LF_FACESIZE
);
1182 tmp
= AREF (font_spec
, FONT_ADSTYLE_INDEX
);
1185 /* Override generic family. */
1186 BYTE family
= w32_generic_family (tmp
);
1187 if (family
!= FF_DONTCARE
)
1188 logfont
->lfPitchAndFamily
= family
| DEFAULT_PITCH
;
1191 /* Process EXTRA info. */
1192 for ( ; CONSP (extra
); extra
= XCDR (extra
))
1197 Lisp_Object key
, val
;
1198 key
= XCAR (tmp
), val
= XCDR (tmp
);
1199 if (EQ (key
, QCspacing
))
1201 /* Set pitch based on the spacing property. */
1204 int spacing
= XINT (val
);
1205 if (spacing
< FONT_SPACING_MONO
)
1206 logfont
->lfPitchAndFamily
1207 = logfont
->lfPitchAndFamily
& 0xF0 | VARIABLE_PITCH
;
1209 logfont
->lfPitchAndFamily
1210 = logfont
->lfPitchAndFamily
& 0xF0 | FIXED_PITCH
;
1212 else if (EQ (val
, Qp
))
1213 logfont
->lfPitchAndFamily
1214 = logfont
->lfPitchAndFamily
& 0xF0 | VARIABLE_PITCH
;
1215 else if (EQ (val
, Qc
) || EQ (val
, Qm
))
1216 logfont
->lfPitchAndFamily
1217 = logfont
->lfPitchAndFamily
& 0xF0 | FIXED_PITCH
;
1219 /* Only use QCscript if charset is not provided, or is unicode
1220 and a single script is specified. This is rather crude,
1221 and is only used to narrow down the fonts returned where
1222 there is a definite match. Some scripts, such as latin, han,
1223 cjk-misc match multiple lfCharSet values, so we can't pre-filter
1225 else if (EQ (key
, QCscript
)
1226 && logfont
->lfCharSet
== DEFAULT_CHARSET
1229 if (EQ (val
, Qgreek
))
1230 logfont
->lfCharSet
= GREEK_CHARSET
;
1231 else if (EQ (val
, Qhangul
))
1232 logfont
->lfCharSet
= HANGUL_CHARSET
;
1233 else if (EQ (val
, Qkana
) || EQ (val
, Qkanbun
))
1234 logfont
->lfCharSet
= SHIFTJIS_CHARSET
;
1235 else if (EQ (val
, Qbopomofo
))
1236 logfont
->lfCharSet
= CHINESEBIG5_CHARSET
;
1237 /* GB 18030 supports tibetan, yi, mongolian,
1238 fonts that support it should show up if we ask for
1240 else if (EQ (val
, Qtibetan
) || EQ (val
, Qyi
)
1241 || EQ (val
, Qmongolian
))
1242 logfont
->lfCharSet
= GB2312_CHARSET
;
1243 else if (EQ (val
, Qhebrew
))
1244 logfont
->lfCharSet
= HEBREW_CHARSET
;
1245 else if (EQ (val
, Qarabic
))
1246 logfont
->lfCharSet
= ARABIC_CHARSET
;
1247 else if (EQ (val
, Qthai
))
1248 logfont
->lfCharSet
= THAI_CHARSET
;
1249 else if (EQ (val
, Qsymbol
))
1250 logfont
->lfCharSet
= SYMBOL_CHARSET
;
1252 else if (EQ (key
, QCantialias
) && SYMBOLP (val
))
1254 logfont
->lfQuality
= w32_antialias_type (val
);
1261 list_all_matching_fonts (match_data
)
1262 struct font_callback_data
*match_data
;
1265 Lisp_Object families
= w32font_list_family (match_data
->frame
);
1266 struct frame
*f
= XFRAME (match_data
->frame
);
1268 dc
= get_frame_dc (f
);
1270 while (!NILP (families
))
1272 /* TODO: Use the Unicode versions of the W32 APIs, so we can
1273 handle non-ASCII font names. */
1275 Lisp_Object family
= CAR (families
);
1276 families
= CDR (families
);
1279 else if (STRINGP (family
))
1280 name
= SDATA (family
);
1282 name
= SDATA (SYMBOL_NAME (family
));
1284 strncpy (match_data
->pattern
.lfFaceName
, name
, LF_FACESIZE
);
1285 match_data
->pattern
.lfFaceName
[LF_FACESIZE
- 1] = '\0';
1287 EnumFontFamiliesEx (dc
, &match_data
->pattern
,
1288 (FONTENUMPROC
) add_font_entity_to_list
,
1289 (LPARAM
) match_data
, 0);
1292 release_frame_dc (f
, dc
);
1296 lispy_antialias_type (type
)
1303 case NONANTIALIASED_QUALITY
:
1306 case ANTIALIASED_QUALITY
:
1309 case CLEARTYPE_QUALITY
:
1312 case CLEARTYPE_NATURAL_QUALITY
:
1322 /* Convert antialiasing symbols to lfQuality */
1324 w32_antialias_type (type
)
1327 if (EQ (type
, Qnone
))
1328 return NONANTIALIASED_QUALITY
;
1329 else if (EQ (type
, Qstandard
))
1330 return ANTIALIASED_QUALITY
;
1331 else if (EQ (type
, Qsubpixel
))
1332 return CLEARTYPE_QUALITY
;
1333 else if (EQ (type
, Qnatural
))
1334 return CLEARTYPE_NATURAL_QUALITY
;
1336 return DEFAULT_QUALITY
;
1339 /* Return a list of all the scripts that the font supports. */
1341 font_supported_scripts (FONTSIGNATURE
* sig
)
1343 DWORD
* subranges
= sig
->fsUsb
;
1344 Lisp_Object supported
= Qnil
;
1346 /* Match a single subrange. SYM is set if bit N is set in subranges. */
1347 #define SUBRANGE(n,sym) \
1348 if (subranges[(n) / 32] & (1 << ((n) % 32))) \
1349 supported = Fcons ((sym), supported)
1351 /* Match multiple subranges. SYM is set if any MASK bit is set in
1352 subranges[0 - 3]. */
1353 #define MASK_ANY(mask0,mask1,mask2,mask3,sym) \
1354 if ((subranges[0] & (mask0)) || (subranges[1] & (mask1)) \
1355 || (subranges[2] & (mask2)) || (subranges[3] & (mask3))) \
1356 supported = Fcons ((sym), supported)
1358 SUBRANGE (0, Qlatin
); /* There are many others... */
1360 SUBRANGE (7, Qgreek
);
1361 SUBRANGE (8, Qcoptic
);
1362 SUBRANGE (9, Qcyrillic
);
1363 SUBRANGE (10, Qarmenian
);
1364 SUBRANGE (11, Qhebrew
);
1365 SUBRANGE (13, Qarabic
);
1366 SUBRANGE (14, Qnko
);
1367 SUBRANGE (15, Qdevanagari
);
1368 SUBRANGE (16, Qbengali
);
1369 SUBRANGE (17, Qgurmukhi
);
1370 SUBRANGE (18, Qgujarati
);
1371 SUBRANGE (19, Qoriya
);
1372 SUBRANGE (20, Qtamil
);
1373 SUBRANGE (21, Qtelugu
);
1374 SUBRANGE (22, Qkannada
);
1375 SUBRANGE (23, Qmalayalam
);
1376 SUBRANGE (24, Qthai
);
1377 SUBRANGE (25, Qlao
);
1378 SUBRANGE (26, Qgeorgian
);
1380 SUBRANGE (48, Qcjk_misc
);
1381 SUBRANGE (51, Qbopomofo
);
1382 SUBRANGE (54, Qkanbun
); /* Is this right? */
1383 SUBRANGE (56, Qhangul
);
1385 SUBRANGE (59, Qhan
); /* There are others, but this is the main one. */
1386 SUBRANGE (59, Qideographic_description
); /* Windows lumps this in */
1388 SUBRANGE (70, Qtibetan
);
1389 SUBRANGE (71, Qsyriac
);
1390 SUBRANGE (72, Qthaana
);
1391 SUBRANGE (73, Qsinhala
);
1392 SUBRANGE (74, Qmyanmar
);
1393 SUBRANGE (75, Qethiopic
);
1394 SUBRANGE (76, Qcherokee
);
1395 SUBRANGE (77, Qcanadian_aboriginal
);
1396 SUBRANGE (78, Qogham
);
1397 SUBRANGE (79, Qrunic
);
1398 SUBRANGE (80, Qkhmer
);
1399 SUBRANGE (81, Qmongolian
);
1400 SUBRANGE (82, Qbraille
);
1403 SUBRANGE (88, Qbyzantine_musical_symbol
);
1404 SUBRANGE (88, Qmusical_symbol
); /* Windows doesn't distinguish these. */
1406 SUBRANGE (89, Qmathematical
);
1408 /* Match either katakana or hiragana for kana. */
1409 MASK_ANY (0, 0x00060000, 0, 0, Qkana
);
1411 /* There isn't really a main symbol range, so include symbol if any
1412 relevant range is set. */
1413 MASK_ANY (0x8000000, 0x0000FFFF, 0, 0, Qsymbol
);
1422 struct font_driver w32font_driver
=
1428 w32font_list_family
,
1429 NULL
, /* free_entity */
1432 NULL
, /* prepare_face */
1433 NULL
, /* done_face */
1435 w32font_encode_char
,
1436 w32font_text_extents
,
1438 NULL
, /* get_bitmap */
1439 NULL
, /* free_bitmap */
1440 NULL
, /* get_outline */
1441 NULL
, /* free_outline */
1442 NULL
, /* anchor_point */
1443 NULL
, /* otf_capability */
1444 NULL
, /* otf_drive */
1445 NULL
, /* start_for_frame */
1446 NULL
, /* end_for_frame */
1451 /* Initialize state that does not change between invocations. This is only
1452 called when Emacs is dumped. */
1456 DEFSYM (Qgdi
, "gdi");
1458 /* Generic font families. */
1459 DEFSYM (Qmonospace
, "monospace");
1460 DEFSYM (Qserif
, "serif");
1461 DEFSYM (Qsansserif
, "sansserif");
1462 DEFSYM (Qscript
, "script");
1463 DEFSYM (Qdecorative
, "decorative");
1465 DEFSYM (Qsans_serif
, "sans_serif");
1466 DEFSYM (Qsans
, "sans");
1467 DEFSYM (Qmono
, "mono");
1469 /* Fake foundries. */
1470 DEFSYM (Qraster
, "raster");
1471 DEFSYM (Qoutline
, "outline");
1472 DEFSYM (Qunknown
, "unknown");
1475 DEFSYM (Qstandard
, "standard");
1476 DEFSYM (Qsubpixel
, "subpixel");
1477 DEFSYM (Qnatural
, "natural");
1480 DEFSYM (Qlatin
, "latin");
1481 DEFSYM (Qgreek
, "greek");
1482 DEFSYM (Qcoptic
, "coptic");
1483 DEFSYM (Qcyrillic
, "cyrillic");
1484 DEFSYM (Qarmenian
, "armenian");
1485 DEFSYM (Qhebrew
, "hebrew");
1486 DEFSYM (Qarabic
, "arabic");
1487 DEFSYM (Qsyriac
, "syriac");
1488 DEFSYM (Qnko
, "nko");
1489 DEFSYM (Qthaana
, "thaana");
1490 DEFSYM (Qdevanagari
, "devanagari");
1491 DEFSYM (Qbengali
, "bengali");
1492 DEFSYM (Qgurmukhi
, "gurmukhi");
1493 DEFSYM (Qgujarati
, "gujarati");
1494 DEFSYM (Qoriya
, "oriya");
1495 DEFSYM (Qtamil
, "tamil");
1496 DEFSYM (Qtelugu
, "telugu");
1497 DEFSYM (Qkannada
, "kannada");
1498 DEFSYM (Qmalayalam
, "malayalam");
1499 DEFSYM (Qsinhala
, "sinhala");
1500 DEFSYM (Qthai
, "thai");
1501 DEFSYM (Qlao
, "lao");
1502 DEFSYM (Qtibetan
, "tibetan");
1503 DEFSYM (Qmyanmar
, "myanmar");
1504 DEFSYM (Qgeorgian
, "georgian");
1505 DEFSYM (Qhangul
, "hangul");
1506 DEFSYM (Qethiopic
, "ethiopic");
1507 DEFSYM (Qcherokee
, "cherokee");
1508 DEFSYM (Qcanadian_aboriginal
, "canadian-aboriginal");
1509 DEFSYM (Qogham
, "ogham");
1510 DEFSYM (Qrunic
, "runic");
1511 DEFSYM (Qkhmer
, "khmer");
1512 DEFSYM (Qmongolian
, "mongolian");
1513 DEFSYM (Qsymbol
, "symbol");
1514 DEFSYM (Qbraille
, "braille");
1515 DEFSYM (Qhan
, "han");
1516 DEFSYM (Qideographic_description
, "ideographic-description");
1517 DEFSYM (Qcjk_misc
, "cjk-misc");
1518 DEFSYM (Qkana
, "kana");
1519 DEFSYM (Qbopomofo
, "bopomofo");
1520 DEFSYM (Qkanbun
, "kanbun");
1522 DEFSYM (Qbyzantine_musical_symbol
, "byzantine-musical-symbol");
1523 DEFSYM (Qmusical_symbol
, "musical-symbol");
1524 DEFSYM (Qmathematical
, "mathematical");
1526 w32font_driver
.type
= Qgdi
;
1527 register_font_driver (&w32font_driver
, NULL
);
1530 /* arch-tag: 65b8a3cd-46aa-4c0d-a1f3-99e75b9c07ee
1531 (do not change this comment) */