New file for w32 font backend.
[bpt/emacs.git] / src / w32font.c
CommitLineData
f7a84cb4
JR
1/* Font backend for the Microsoft W32 API.
2 Copyright (C) 2007 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19Boston, MA 02110-1301, USA. */
20
21#include <config.h>
22#include <windows.h>
23
24#include "lisp.h"
25#include "w32term.h"
26#include "frame.h"
27#include "dispextern.h"
28#include "character.h"
29#include "charset.h"
30#include "fontset.h"
31#include "font.h"
32
33/* The actual structure for a w32 font, that can be cast to struct font. */
34struct w32font_info
35{
36 struct font font;
37 TEXTMETRIC metrics;
38 /* Unicode subset bitfield. See MSDN documentation for FONTSIGNATURE. */
39 DWORD *subranges;
40};
41
42extern struct font_driver w32font_driver;
43
44Lisp_Object Qw32;
45static Lisp_Object Qmodern, Qswiss, Qroman, Qdecorative, Qscript, Qunknown;
46
47static void fill_in_logfont P_ ((FRAME_PTR f, LOGFONT *logfont,
48 Lisp_Object font_spec));
49
50static void set_fonts_frame P_ ((Lisp_Object fontlist, Lisp_Object frame));
51
52static int unicode_range_for_char (unsigned c);
53
54static void list_all_matching_fonts P_ ((Lisp_Object frame,
55 LOGFONT *font_match_pattern,
56 Lisp_Object* list));
57
58/* From old font code in w32fns.c */
59char * w32_to_x_charset P_ ((int charset, char * matching));
60
61static Lisp_Object w32_registry P_ ((LONG w32_charset));
62
63/* EnumFontFamiliesEx callbacks. */
64static int CALLBACK add_font_entity_to_list P_ ((ENUMLOGFONTEX *,
65 NEWTEXTMETRICEX *,
66 DWORD, LPARAM));
67static int CALLBACK add_one_font_entity_to_list P_ ((ENUMLOGFONTEX *,
68 NEWTEXTMETRICEX *,
69 DWORD, LPARAM));
70static int CALLBACK add_font_name_to_list P_ ((ENUMLOGFONTEX *,
71 NEWTEXTMETRICEX *,
72 DWORD, LPARAM));
73
74/* W32 API functions only available on some versions of Windows */
75typedef DWORD (*GETGLYPHINDICES) (HDC, wchar_t *, int, LPWORD, DWORD);
76typedef BOOL (*GETTEXTEXTENTPTI) (HDC, LPWORD, int, LPSIZE);
77static GETGLYPHINDICES get_glyph_indices_fn = NULL;
78static GETTEXTEXTENTPTI get_text_extent_pointi_fn = NULL;
79/* MingW headers only define this when _WIN32_WINNT >= 0x0500, but we
80 target older versions. */
81#define GGI_MARK_NONEXISTING_GLYPHS 1
82
83static int
84memq_no_quit (elt, list)
85 Lisp_Object elt, list;
86{
87 while (CONSP (list) && ! EQ (XCAR (list), elt))
88 list = XCDR (list);
89 return (CONSP (list));
90}
91
92/* w32 implementation of get_cache for font backend.
93 Return a cache of font-entities on FRAME. The cache must be a
94 cons whose cdr part is the actual cache area. */
95static Lisp_Object w32font_get_cache (Lisp_Object frame)
96{
97 struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (frame));
98
99 return (dpyinfo->name_list_element);
100}
101
102/* w32 implementation of list for font backend.
103 List fonts exactly matching with FONT_SPEC on FRAME. The value
104 is a vector of font-entities. This is the sole API that
105 allocates font-entities. */
106static Lisp_Object w32font_list (Lisp_Object frame, Lisp_Object font_spec)
107{
108 Lisp_Object list = Qnil;
109 LOGFONT font_match_pattern;
110 HDC dc;
111 FRAME_PTR f = XFRAME (frame);
112
113 bzero (&font_match_pattern, sizeof (font_match_pattern));
114 fill_in_logfont (f, &font_match_pattern, font_spec);
115
116
117 if (font_match_pattern.lfFaceName[0] == '\0')
118 {
119 /* EnumFontFamiliesEx does not take other fields into account if
120 font name is blank, so need to use two passes. */
121 list_all_matching_fonts (frame, &font_match_pattern, &list);
122 }
123 else
124 {
125 dc = get_frame_dc (f);
126
127 EnumFontFamiliesEx (dc, &font_match_pattern,
128 (FONTENUMPROC) add_font_entity_to_list,
129 (LPARAM) &list, 0);
130 release_frame_dc (f, dc);
131 }
132
133 set_fonts_frame (list, frame);
134
135 return list;
136}
137
138/* w32 implementation of match for font backend.
139 Return a font entity most closely matching with FONT_SPEC on
140 FRAME. The closeness is detemined by the font backend, thus
141 `face-font-selection-order' is ignored here. */
142static Lisp_Object w32font_match (Lisp_Object frame, Lisp_Object font_spec)
143{
144 Lisp_Object list = Qnil;
145 LOGFONT font_match_pattern;
146 HDC dc;
147 FRAME_PTR f = XFRAME (frame);
148
149 bzero (&font_match_pattern, sizeof (font_match_pattern));
150 fill_in_logfont (f, &font_match_pattern, font_spec);
151
152 dc = get_frame_dc (f);
153
154 EnumFontFamiliesEx (dc, &font_match_pattern,
155 (FONTENUMPROC) add_one_font_entity_to_list,
156 (LPARAM) &list, 0);
157 release_frame_dc (f, dc);
158
159 set_fonts_frame (list, frame);
160
161 return NILP (list) ? Qnil : XCAR (list);
162}
163
164
165/* w32 implementation of list_family for font backend.
166 List available families. The value is a list of family names
167 (symbols). */
168static Lisp_Object w32font_list_family (Lisp_Object frame)
169{
170 Lisp_Object list = Qnil;
171 LOGFONT font_match_pattern;
172 HDC dc;
173 FRAME_PTR f = XFRAME (frame);
174
175 bzero (&font_match_pattern, sizeof (font_match_pattern));
176
177 dc = get_frame_dc (f);
178
179 EnumFontFamiliesEx (dc, &font_match_pattern,
180 (FONTENUMPROC) add_font_name_to_list,
181 (LPARAM) &list, 0);
182 release_frame_dc (f, dc);
183
184 return list;
185}
186
187/* w32 implementation of open for font backend.
188 Open a font specified by FONT_ENTITY on frame F.
189 If the font is scalable, open it with PIXEL_SIZE. */
190static struct font* w32font_open (FRAME_PTR f, Lisp_Object font_entity,
191 int pixel_size)
192{
193 int len;
194 LOGFONT logfont;
195 HDC dc;
196 HFONT hfont, old_font;
197 Lisp_Object val;
198 /* For backwards compatibility. */
199 W32FontStruct *compat_w32_font;
200
201 struct w32font_info *w32_font = xmalloc (sizeof (struct w32font_info));
202
203 struct font * font = (struct font *) w32_font;
204 if (!font)
205 return NULL;
206
207 bzero (&logfont, sizeof (logfont));
208 fill_in_logfont (f, &logfont, font_entity);
209
210 hfont = CreateFontIndirect (&logfont);
211
212 if (hfont == NULL)
213 {
214 xfree (w32_font);
215 return NULL;
216 }
217
218 /* Get the metrics for this font. */
219 dc = get_frame_dc (f);
220 old_font = SelectObject (dc, hfont);
221
222 GetTextMetrics (dc, &w32_font->metrics);
223
224 SelectObject (dc, old_font);
225 release_frame_dc (f, dc);
226 /* W32FontStruct - we should get rid of this, and use the w32font_info
227 struct for any W32 specific fields. font->font.font can then be hfont. */
228 font->font.font = xmalloc (sizeof (W32FontStruct));
229 compat_w32_font = (W32FontStruct *) font->font.font;
230 bzero (compat_w32_font, sizeof (W32FontStruct));
231 compat_w32_font->font_type = UNICODE_FONT;
232 /* Duplicate the text metrics. */
233 bcopy (&w32_font->metrics, &compat_w32_font->tm, sizeof (TEXTMETRIC));
234 compat_w32_font->hfont = hfont;
235
236 font->font.font_idx = 0;
237 len = strlen (logfont.lfFaceName);
238 font->font.name = (char *) xmalloc (len + 1);
239 bcopy (logfont.lfFaceName, font->font.name, len);
240 font->font.name[len] = '\0';
241 font->font.full_name = font->font.name;
242 font->font.charset = 0;
243 font->font.codepage = 0;
244 font->font.size = logfont.lfWidth;
245 font->font.height = w32_font->metrics.tmHeight;
246 font->font.space_width = font->font.average_width
247 = w32_font->metrics.tmAveCharWidth;
248
249 font->font.vertical_centering = 0;
250 font->font.encoding_type = 0;
251 font->font.baseline_offset = 0;
252 font->font.relative_compose = 0;
253 font->font.default_ascent = w32_font->metrics.tmAscent;
254 font->font.font_encoder = NULL;
255 font->entity = font_entity;
256 font->pixel_size = pixel_size;
257 font->driver = &w32font_driver;
258 font->format = Qw32;
259 font->file_name = NULL;
260 font->encoding_charset = -1;
261 font->repertory_charset = -1;
262 font->min_width = 0;
263 font->ascent = w32_font->metrics.tmAscent;
264 font->descent = w32_font->metrics.tmDescent;
265 font->scalable = w32_font->metrics.tmPitchAndFamily & TMPF_VECTOR;
266
267 /* Truetype fonts will have extra information about the characters
268 covered by the font. */
269 val = AREF (font_entity, FONT_EXTRA_INDEX);
270 if (XTYPE (val) == Lisp_Misc && XMISCTYPE (val) == Lisp_Misc_Save_Value)
271 ((struct w32font_info *)(font))->subranges = XSAVE_VALUE (val)->pointer;
272 else
273 ((struct w32font_info *)(font))->subranges = NULL;
274
275 return font;
276}
277
278/* w32 implementation of close for font_backend.
279 Close FONT on frame F. */
280static void w32font_close (FRAME_PTR f, struct font *font)
281{
282 if (font->font.font)
283 {
284 W32FontStruct *old_w32_font = (W32FontStruct *)font->font.font;
285 DeleteObject (font->font.font);
286 xfree (old_w32_font);
287 font->font.font = 0;
288 }
289
290 if (font->font.name)
291 xfree (font->font.name);
292 xfree (font);
293}
294
295/* w32 implementation of has_char for font backend.
296 Optional.
297 If FONT_ENTITY has a glyph for character C (Unicode code point),
298 return 1. If not, return 0. If a font must be opened to check
299 it, return -1. */
300static int w32font_has_char (Lisp_Object entity, int c)
301{
302 Lisp_Object val;
303 DWORD *ranges;
304 int index;
305 DWORD mask;
306
307 val = AREF (entity, FONT_EXTRA_INDEX);
308 if (XTYPE (val) != Lisp_Misc || XMISCTYPE (val) != Lisp_Misc_Save_Value)
309 return -1;
310
311 ranges = XSAVE_VALUE (val)->pointer;
312
313 index = unicode_range_for_char (c);
314 mask = 1 << (index % 32);
315 index = index / 32;
316
317 if (ranges[index] & mask)
318 return 1;
319 else
320 return 0;
321}
322
323/* w32 implementation of encode_char for font backend.
324 Return a glyph code of FONT for characer C (Unicode code point).
325 If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */
326static unsigned w32font_encode_char (struct font *font, int c)
327{
328 if (get_glyph_indices_fn)
329 {
330 HFONT old_font;
331 WORD glyph[2];
332 int converted;
333 /* FIXME: Be nice if we had a frame here, rather than getting
334 the desktop's device context to measure against... */
335 HDC dc = GetDC (NULL);
336 wchar_t string[2];
337 string[0] = c;
338 string[1] = 0x0000;
339
340 if (get_glyph_indices_fn)
341 converted = (*get_glyph_indices_fn) (dc, string, 1, glyph,
342 GGI_MARK_NONEXISTING_GLYPHS);
343
344 /* Restore state and release DC. */
345 SelectObject (dc, old_font);
346 ReleaseDC (NULL, dc);
347 if (converted > 0 && glyph[0] != 0xFFFF)
348 return glyph[0];
349 else if (converted != GDI_ERROR)
350 return FONT_INVALID_CODE;
351 }
352 /* On older platforms, or if the above fails, return the unicode
353 code point. */
354 return c;
355}
356
357/* w32 implementation of text_extents for font backend.
358 Perform the size computation of glyphs of FONT and fillin members
359 of METRICS. The glyphs are specified by their glyph codes in
360 CODE (length NGLYPHS). Apparently medtrics can be NULL, in this
361 case just return the overall width. */
362static int w32font_text_extents (struct font *font,
363 unsigned *code, int nglyphs,
364 struct font_metrics *metrics)
365{
366 int i;
367 HFONT old_font;
368 /* FIXME: Be nice if we had a frame here, rather than getting the desktop's
369 device context to measure against... */
370 HDC dc = GetDC (NULL);
371 int total_width = 0;
372
373 /* TODO: Allow some extra room for surrogates. */
374 WORD *wcode = alloca(nglyphs * sizeof (WORD));
375
376 old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont);
377
378 if (metrics)
379 {
380 GLYPHMETRICS gm;
381 int i;
382 UINT format = GGO_METRICS;
383 if (get_text_extent_pointi_fn)
384 format |= GGO_GLYPH_INDEX;
385
386 for (i = 0; i < nglyphs; i++)
387 {
388 if (GetGlyphOutline (dc, *(code + i), format, &gm, 0, NULL, NULL)
389 != GDI_ERROR)
390 {
391 metrics[i].lbearing = gm.gmptGlyphOrigin.x;
392 metrics[i].rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
393 metrics[i].width = gm.gmCellIncX;
394 metrics[i].ascent = -gm.gmptGlyphOrigin.y;
395 metrics[i].descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
396 }
397 else
398 {
399 metrics[i].lbearing = 0;
400 metrics[i].rbearing = font->font.size
401 + ((struct w32font_info *) font)->metrics.tmOverhang;
402 metrics[i].width = font->font.size;
403 metrics[i].ascent = font->ascent;
404 metrics[i].descent = font->descent;
405 }
406 }
407 }
408
409 for (i = 0; i < nglyphs; i++)
410 {
411 if (code[i] < 0x10000)
412 wcode[i] = code[i];
413 else
414 {
415 /* TODO: Convert to surrogate, reallocating array if needed */
416 wcode[i] = 0xffff;
417 }
418 }
419
420 if (get_text_extent_pointi_fn)
421 {
422 SIZE size;
423 if ((*get_text_extent_pointi_fn) (dc, wcode, nglyphs, &size))
424 {
425 total_width = size.cx;
426 }
427 }
428
429 if (total_width == 0)
430 {
431 RECT rect;
432 rect.top = 0; rect.bottom = font->font.height; rect.left = 0; rect.right = 1;
433 DrawTextW (dc, wcode, nglyphs, &rect,
434 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
435 total_width = rect.right;
436 }
437 /* Restore state and release DC. */
438 SelectObject (dc, old_font);
439 ReleaseDC (NULL, dc);
440
441 return total_width;
442}
443
444/* w32 implementation of draw for font backend.
445 Optional.
446 Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
447 position of frame F with S->FACE and S->GC. If WITH_BACKGROUND
448 is nonzero, fill the background in advance. It is assured that
449 WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars). */
450static int w32font_draw (struct glyph_string *s, int from, int to,
451 int x, int y, int with_background)
452{
453 UINT options = 0;
454
455 if (with_background)
456 {
457 options = ETO_OPAQUE;
458 SetBkColor (s->hdc, s->gc->background);
459 }
460 else
461 SetBkMode (s->hdc, TRANSPARENT);
462 ExtTextOutW (s->hdc, x, y, 0, NULL, s->char2b + from, to - from + 1, NULL);
463}
464
465/* w32 implementation of free_entity for font backend.
466 Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value).
467 Free FONT_EXTRA_INDEX field of FONT_ENTITY.
468static void w32font_free_entity (Lisp_Object entity);
469 */
470
471/* w32 implementation of prepare_face for font backend.
472 Optional (if FACE->extra is not used).
473 Prepare FACE for displaying characters by FONT on frame F by
474 storing some data in FACE->extra. If successful, return 0.
475 Otherwise, return -1.
476static int w32font_prepare_face (FRAME_PTR f, struct face *face);
477 */
478/* w32 implementation of done_face for font backend.
479 Optional.
480 Done FACE for displaying characters by FACE->font on frame F.
481static void w32font_done_face (FRAME_PTR f, struct face *face); */
482
483/* w32 implementation of get_bitmap for font backend.
484 Optional.
485 Store bitmap data for glyph-code CODE of FONT in BITMAP. It is
486 intended that this method is callled from the other font-driver
487 for actual drawing.
488static int w32font_get_bitmap (struct font *font, unsigned code,
489 struct font_bitmap *bitmap,
490 int bits_per_pixel);
491 */
492/* w32 implementation of free_bitmap for font backend.
493 Optional.
494 Free bitmap data in BITMAP.
495static void w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap);
496 */
497/* w32 implementation of get_outline for font backend.
498 Optional.
499 Return an outline data for glyph-code CODE of FONT. The format
500 of the outline data depends on the font-driver.
501static void* w32font_get_outline (struct font *font, unsigned code);
502 */
503/* w32 implementation of free_outline for font backend.
504 Optional.
505 Free OUTLINE (that is obtained by the above method).
506static void w32font_free_outline (struct font *font, void *outline);
507 */
508/* w32 implementation of anchor_point for font backend.
509 Optional.
510 Get coordinates of the INDEXth anchor point of the glyph whose
511 code is CODE. Store the coordinates in *X and *Y. Return 0 if
512 the operations was successfull. Otherwise return -1.
513static int w32font_anchor_point (struct font *font, unsigned code,
514 int index, int *x, int *y);
515 */
516/* w32 implementation of otf_capability for font backend.
517 Optional.
518 Return a list describing which scripts/languages FONT
519 supports by which GSUB/GPOS features of OpenType tables.
520static Lisp_Object w32font_otf_capability (struct font *font);
521 */
522/* w32 implementation of otf_drive for font backend.
523 Optional.
524 Apply FONT's OTF-FEATURES to the glyph string.
525
526 FEATURES specifies which OTF features to apply in this format:
527 (SCRIPT LANGSYS GSUB-FEATURE GPOS-FEATURE)
528 See the documentation of `font-drive-otf' for the detail.
529
530 This method applies the specified features to the codes in the
531 elements of GSTRING-IN (between FROMth and TOth). The output
532 codes are stored in GSTRING-OUT at the IDXth element and the
533 following elements.
534
535 Return the number of output codes. If none of the features are
536 applicable to the input data, return 0. If GSTRING-OUT is too
537 short, return -1.
538static int w32font_otf_drive (struct font *font, Lisp_Object features,
539 Lisp_Object gstring_in, int from, int to,
540 Lisp_Object gstring_out, int idx,
541 int alternate_subst);
542 */
543
544/* Callback function for EnumFontFamiliesEx.
545 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
546static int CALLBACK add_font_name_to_list (ENUMLOGFONTEX *logical_font,
547 NEWTEXTMETRICEX *physical_font,
548 DWORD font_type,
549 LPARAM list_object)
550{
551 Lisp_Object* list = (Lisp_Object *) list_object;
552 Lisp_Object family = intern_downcase (logical_font->elfLogFont.lfFaceName,
553 strlen (logical_font->elfLogFont.lfFaceName));
554 if (! memq_no_quit (family, *list))
555 *list = Fcons (family, *list);
556
557 return 1;
558}
559
560/* Convert an enumerated Windows font to an Emacs font entity. */
561Lisp_Object w32_enumfont_pattern_entity (ENUMLOGFONTEX *logical_font,
562 NEWTEXTMETRICEX *physical_font,
563 DWORD font_type)
564{
565 Lisp_Object entity, tem;
566 LOGFONT *lf = (LOGFONT*) logical_font;
567 BYTE generic_type;
568
569 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), null_string);
570
571 ASET (entity, FONT_TYPE_INDEX, Qw32);
572 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet));
573 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
574
575 /* Foundry is difficult to get in readable form on Windows.
576 But Emacs crashes if it is not set, so set it to the generic type. */
577 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0;
578 if (generic_type == FF_DECORATIVE)
579 tem = Qdecorative;
580 else if (generic_type == FF_MODERN)
581 tem = Qmodern;
582 else if (generic_type == FF_ROMAN)
583 tem = Qroman;
584 else if (generic_type == FF_SCRIPT)
585 tem = Qscript;
586 else if (generic_type == FF_SWISS)
587 tem = Qswiss;
588 else
589 tem = Qunknown;
590
591 ASET (entity, FONT_FOUNDRY_INDEX, tem);
592
593 ASET (entity, FONT_FAMILY_INDEX,
594 intern_downcase (lf->lfFaceName, strlen (lf->lfFaceName)));
595
596 ASET (entity, FONT_WEIGHT_INDEX, make_number (lf->lfWeight));
597 ASET (entity, FONT_SLANT_INDEX, make_number (lf->lfItalic ? 200 : 100));
598 ASET (entity, FONT_WIDTH_INDEX,
599 make_number (physical_font->ntmTm.tmAveCharWidth));
600
601 ASET (entity, FONT_SIZE_INDEX, make_number (abs (lf->lfHeight)));
602
603 /* Cache unicode codepoints covered by this font, as there is no other way
604 of getting this information easily. */
605 if (font_type == TRUETYPE_FONTTYPE)
606 {
607 DWORD *subranges = xmalloc(16);
608 memcpy (subranges, physical_font->ntmFontSig.fsUsb, 16);
609 ASET (entity, FONT_EXTRA_INDEX, make_save_value (subranges, 0));
610 }
611 return entity;
612}
613
614/* Callback function for EnumFontFamiliesEx.
615 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
616static int CALLBACK add_font_entity_to_list (ENUMLOGFONTEX *logical_font,
617 NEWTEXTMETRICEX *physical_font,
618 DWORD font_type,
619 LPARAM list_object)
620{
621 Lisp_Object *list = (Lisp_Object *) list_object;
622 Lisp_Object entity = w32_enumfont_pattern_entity (logical_font,
623 physical_font, font_type);
624 if (!NILP (entity))
625 *list = Fcons (entity, *list);
626
627 return 1;
628}
629
630/* Callback function for EnumFontFamiliesEx.
631 * Adds the name of a font to a Lisp list (passed in as the lParam arg),
632 * then terminate the search. */
633static int CALLBACK add_one_font_entity_to_list (ENUMLOGFONTEX *logical_font,
634 NEWTEXTMETRICEX *physical_font,
635 DWORD font_type,
636 LPARAM list_object)
637{
638 add_font_entity_to_list (logical_font, physical_font, font_type, list_object);
639 return 0;
640}
641
642/* Convert a Lisp font registry (symbol) to a windows charset. */
643static LONG registry_to_w32_charset (Lisp_Object charset)
644{
645 if (EQ (charset, Qiso10646_1) || EQ (charset, Qunicode_bmp)
646 || EQ (charset, Qunicode_sip))
647 return DEFAULT_CHARSET; /* UNICODE_CHARSET not defined in MingW32 */
648 else if (EQ (charset, Qiso8859_1))
649 return ANSI_CHARSET;
650 else if (STRINGP (charset))
651 return x_to_w32_charset (SDATA (charset));
652 else
653 return DEFAULT_CHARSET;
654}
655
656static Lisp_Object w32_registry (LONG w32_charset)
657{
658 if (w32_charset == ANSI_CHARSET)
659 return Qiso8859_1;
660 else
661 return build_string (w32_to_x_charset (w32_charset, NULL));
662}
663
664static void set_fonts_frame (Lisp_Object fontlist, Lisp_Object frame)
665{
666 if (VECTORP (fontlist))
667 ASET (fontlist, FONT_FRAME_INDEX, frame);
668 else
669 {
670 for ( ; CONSP (fontlist); fontlist = XCDR (fontlist))
671 {
672 Lisp_Object entity = XCAR (fontlist);
673 if (VECTORP (entity))
674 ASET (entity, FONT_FRAME_INDEX, frame);
675 }
676 }
677}
678
679/* Fill in all the available details of LOGFONT from FONT_SPEC. */
680static void fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec)
681{
682 Lisp_Object val, tmp, extra;
683 int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
684
685 /* TODO: Allow user to override dpi settings. */
686
687 /* Height */
688 tmp = AREF (font_spec, FONT_SIZE_INDEX);
689 if (INTEGERP (tmp))
690 logfont->lfHeight = -1 * dpi / 720 * XINT (tmp);
691 else if (FLOATP (tmp))
692 logfont->lfHeight = -1 * (int) XFLOAT(tmp);
693
694 /* Width */
695 tmp = AREF (font_spec, FONT_WIDTH_INDEX);
696 if (INTEGERP (tmp))
697 logfont->lfWidth = XINT (tmp);
698
699 /* Escapement */
700
701 /* Orientation */
702
703 /* Weight */
704 tmp = AREF (font_spec, FONT_WEIGHT_INDEX);
705 if (INTEGERP (tmp))
706 logfont->lfWeight = XINT (tmp);
707
708 /* Italic */
709 tmp = AREF (font_spec, FONT_SLANT_INDEX);
710 if (INTEGERP (tmp))
711 {
712 int slant = XINT (tmp);
713 logfont->lfItalic = slant > 150 ? 1 : 0;
714 }
715
716 /* Underline */
717
718 /* Strikeout */
719
720 /* Charset */
721 tmp = AREF (font_spec, FONT_REGISTRY_INDEX);
722 if (! NILP (tmp))
723 {
724 if (STRINGP (tmp))
725 logfont->lfCharSet = x_to_w32_charset (SDATA (tmp));
726 else
727 logfont->lfCharSet = registry_to_w32_charset (tmp);
728 }
729
730 /* Out Precision */
731 /* Clip Precision */
732 /* Quality */
733 /* Pitch and Family */
734 /* Facename TODO: handle generic names */
735 tmp = AREF (font_spec, FONT_FAMILY_INDEX);
736 /* Font families are interned */
737 if (SYMBOLP (tmp))
738 strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE);
739 else if (STRINGP (tmp))
740 strncpy (logfont->lfFaceName, SDATA (tmp), LF_FACESIZE);
741
742}
743
744static void list_all_matching_fonts (Lisp_Object frame,
745 LOGFONT *font_match_pattern,
746 Lisp_Object* list)
747{
748 HDC dc;
749 Lisp_Object families = w32font_list_family (frame);
750 struct frame *f = XFRAME (frame);
751
752 dc = get_frame_dc (f);
753
754 while (!NILP (families))
755 {
756 Lisp_Object family = CAR (families);
757 families = CDR (families);
758 if (STRINGP (family))
759 {
760 /* TODO: Use the Unicode versions of the W32 APIs, so we can
761 handle non-ASCII font names. */
762 char * name = SDATA (family);
763 strncpy (font_match_pattern->lfFaceName, name, LF_FACESIZE);
764 font_match_pattern->lfFaceName[LF_FACESIZE - 1] = '\0';
765
766 EnumFontFamiliesEx (dc, font_match_pattern,
767 (FONTENUMPROC) add_font_entity_to_list,
768 (LPARAM)&list, 0);
769 }
770 }
771
772 release_frame_dc (f, dc);
773}
774
775static int unicode_range_for_char (unsigned c)
776{
777 /* Is there really no Windows API function for this?!!! */
778 if (c < 0x80)
779 return 0; // Basic Latin
780 else if (c < 0x100)
781 return 1; // Latin-1 supplement
782 else if (c < 0x180)
783 return 2; // Latin Extended-A
784 else if (c < 0x250)
785 return 3; // Latin Extended-B
786 else if (c < 0x2B0)
787 return 4; // IPA Extensions
788 else if (c < 0x300)
789 return 5; // Spacing modifiers
790 else if (c < 0x370)
791 return 6; // Combining diacritical marks
792 else if (c < 0x400)
793 return 7; // Greek and Coptic
794 else if (c < 0x530)
795 return 9; // Cyrillic, Cyrillic supplementary
796 else if (c < 0x590)
797 return 10; // Armenian
798 else if (c < 0x600)
799 return 11; // Hebrew
800 else if (c < 0x700)
801 return 13; // Arabic
802 else if (c < 0x750)
803 return 71; // Syriac
804 else if (c < 0x780)
805 return 13; // Arabic supplement
806 else if (c < 0x7c0)
807 return 72; // Thaana
808 else if (c < 0x800)
809 return 14; // N'Ko
810 else if (c < 0x900)
811 return -1; // Unsupported range
812 else if (c < 0x980)
813 return 15; // Devanagari
814 else if (c < 0xA00)
815 return 16; // Bengali
816 else if (c < 0xA80)
817 return 17; // Gurmukhi
818 else if (c < 0xB00)
819 return 18; // Gujarati
820 else if (c < 0xB80)
821 return 19; // Oriya
822 else if (c < 0xC00)
823 return 20; // Tamil
824 else if (c < 0xC80)
825 return 21; // Telugu
826 else if (c < 0xD00)
827 return 22; // Kannada
828 else if (c < 0xD80)
829 return 23; // Malayalam
830 else if (c < 0xE00)
831 return 73; // Sinhala
832 else if (c < 0xE80)
833 return 24; // Thai
834 else if (c < 0xF00)
835 return 25; // Lao
836 else if (c < 0x1000)
837 return 70; // Tibetan
838 else if (c < 0x10A0)
839 return 74; // Myanmar
840 else if (c < 0x1100)
841 return 26; // Georgian
842 else if (c < 0x1200)
843 return 28; // Hangul Jamo
844 else if (c < 0x13A0)
845 return 75; // Ethiopic, Ethiopic Supplement
846 else if (c < 0x1400)
847 return 76; // Cherokee
848 else if (c < 0x1680)
849 return 77; // Unified Canadian Aboriginal Syllabics
850 else if (c < 0x16A0)
851 return 78; // Ogham
852 else if (c < 0x1700)
853 return 79; // Runic
854 else if (c < 0x1780)
855 return 84; // Tagalog, Hanunoo, Buhid, Tagbanwa
856 else if (c < 0x1800)
857 return 80; // Khmer
858 else if (c < 0x18B0)
859 return 81; // Mongolian
860 else if (c < 0x1900)
861 return -1; // Unsupported range
862 else if (c < 0x1950)
863 return 93; // Limbu
864 else if (c < 0x1980)
865 return 94; // Tai Le
866 else if (c < 0x19E0)
867 return 95; // New Tai Le
868 else if (c < 0x1A00)
869 return 80; // Khmer Symbols
870 else if (c < 0x1A20)
871 return 96; // Buginese
872 else if (c < 0x1B00)
873 return -1; // Unsupported range
874 else if (c < 0x1B80)
875 return 27; // Balinese
876 else if (c < 0x1D00)
877 return -1; // Unsupported range
878 else if (c < 0x1DC0)
879 return 4; // Phonetic extensions + supplement
880 else if (c < 0x1E00)
881 return 6; // Combining diacritical marks supplement
882 else if (c < 0x1F00)
883 return 29; // Latin Extended additional
884 else if (c < 0x2000)
885 return 30; // Greek Extended
886 else if (c < 0x2070)
887 return 31; // General Punctuation
888 else if (c < 0x20A0)
889 return 32; // Subscripts and Superscripts
890 else if (c < 0x20D0)
891 return 33; // Currency symbols
892 else if (c < 0x2100)
893 return 34; // Combining marks for diacriticals
894 else if (c < 0x2150)
895 return 35; // Letterlike symbols
896 else if (c < 0x2190)
897 return 36; // Number forms
898 else if (c < 0x2200)
899 return 37; // Arrows
900 else if (c < 0x2300)
901 return 38; // Mathematical operators
902 else if (c < 0x2400)
903 return 39; // Miscellaneous technical
904 else if (c < 0x2440)
905 return 40; // Control pictures
906 else if (c < 0x2460)
907 return 41; // Optical character recognition
908 else if (c < 0x2500)
909 return 42; // Enclosed alphanumerics
910 else if (c < 0x2580)
911 return 43; // Box drawing
912 else if (c < 0x25A0)
913 return 44; // Block elements
914 else if (c < 0x2600)
915 return 45; // Geometric shapes
916 else if (c < 0x2700)
917 return 46; // Miscellaneous symbols
918 else if (c < 0x27C0)
919 return 47; // Dingbats
920 else if (c < 0x27F0)
921 return 38; // Misc Math symbols-A
922 else if (c < 0x2800)
923 return 37; // Supplemental arrows-A
924 else if (c < 0x2900)
925 return 82; // Braille patterns
926 else if (c < 0x2980)
927 return 37; // Supplemental arrows-B
928 else if (c < 0x2B00)
929 return 38; // Misc Math symbols-B, Supplemental Math operators
930 else if (c < 0x2C00)
931 return 37; // Misc Symbols and Arrows
932 else if (c < 0x2C60)
933 return 97; // Galgolitic
934 else if (c < 0x2C80)
935 return 29; // Latin Extended-C
936 else if (c < 0x2D00)
937 return 8; // Coptic
938 else if (c < 0x2D30)
939 return 26; // Georgian supplement
940 else if (c < 0x2D80)
941 return 98; // Tifinagh
942 else if (c < 0x2DE0)
943 return 75; // Ethiopic extended
944 else if (c < 0x2E00)
945 return -1; // Unsupported range
946 else if (c < 0x2E80)
947 return 31; // Supplemental punctuation
948 else if (c < 0x2FE0)
949 return 59; // CJK radicals supplement, Kangxi radicals
950 else if (c < 0x2FF0)
951 return -1; // Unsupported range
952 else if (c < 0x3000)
953 return 59; // Ideographic description characters
954 else if (c < 0x3040)
955 return 48; // CJK symbols and punctuation
956 else if (c < 0x30A0)
957 return 49; // Hiragana
958 else if (c < 0x3100)
959 return 50; // Katakana
960 else if (c < 0x3130)
961 return 51; // Bopomofo
962 else if (c < 0x3190)
963 return 52; // Hangul compatibility Jamo
964 else if (c < 0x31A0)
965 return 59; // Kanbun
966 else if (c < 0x31C0)
967 return 51; // Bopomofo extended
968 else if (c < 0x31F0)
969 return 61; // CJK strokes
970 else if (c < 0x3200)
971 return 50; // Katakana phonetic extensions
972 else if (c < 0x3300)
973 return 54; // CJK enclosed letters and months
974 else if (c < 0x3400)
975 return 55; // CJK compatibility
976 else if (c < 0x4DC0)
977 return 59; // CJK unified ideographs extension-A
978 else if (c < 0x4E00)
979 return 99; // Yijing Hexagram Symbols
980 else if (c < 0xA000)
981 return 59; // CJK unified ideographs
982 else if (c < 0xA4D0)
983 return 83; // Yi syllables, Yi radicals
984 else if (c < 0xA700)
985 return -1; // Unsupported range
986 else if (c < 0xA720)
987 return 5; // Modifier tone letters
988 else if (c < 0xA800)
989 return 29; // Latin Extended-D
990 else if (c < 0xA830)
991 return 100; // Syloti Nagri
992 else if (c < 0xA840)
993 return -1; // Unsupported range
994 else if (c < 0xA880)
995 return 53; // Phags-pa
996 else if (c < 0xAC00)
997 return -1; // Unsupported range
998 else if (c < 0xD7A4)
999 return 56; // Hangul syllables
1000 else if (c < 0xD800)
1001 return -1; // Unsupported range
1002 else if (c < 0xE000)
1003 return 57; // Surrogates
1004 else if (c < 0xF900)
1005 return 60; // Private use (plane 0)
1006 else if (c < 0xFB00)
1007 return 61; // CJK Compatibility ideographs
1008 else if (c < 0xFB50)
1009 return 62; // Alphabetic Presentation Forms
1010 else if (c < 0xFE00)
1011 return 63; // Arabic Presentation Forms-A
1012 else if (c < 0xFE10)
1013 return 91; // Variation selectors
1014 else if (c < 0xFE20)
1015 return 65; // Vertical forms
1016 else if (c < 0xFE30)
1017 return 64; // Combining half marks
1018 else if (c < 0xFE50)
1019 return 65; // CJK compatibility forms
1020 else if (c < 0xFE70)
1021 return 66; // Small form variants
1022 else if (c < 0xFEFF)
1023 return 67; // Arabic Presentation Forms-B
1024 else if (c == 0xFEFF)
1025 return -1; // Unsupported range
1026 else if (c < 0xFFF0)
1027 return 68; // Halfwidth and fullwidth forms
1028 else if (c <= 0xFFFF)
1029 return 69; // Specials
1030
1031 // If int is 64 bit, it could represent characters from 10000 up, but
1032 // any font that handles them should have the surrogate bit set (57).
1033 return 57;
1034}
1035
1036
1037struct font_driver w32font_driver =
1038 {
1039 0, /* Qw32 */
1040 w32font_get_cache,
1041 w32font_list,
1042 w32font_match,
1043 w32font_list_family,
1044 NULL, /* free_entity */
1045 w32font_open,
1046 w32font_close,
1047 NULL, /* prepare_face */
1048 NULL, /* done_face */
1049 w32font_has_char,
1050 w32font_encode_char,
1051 w32font_text_extents,
1052 w32font_draw,
1053 NULL, /* get_bitmap */
1054 NULL, /* free_bitmap */
1055 NULL, /* get_outline */
1056 NULL, /* free_outline */
1057 NULL, /* anchor_point */
1058 NULL, /* otf_capability */
1059 NULL /* otf_drive */
1060 };
1061
1062/* Initialize the font subsystem for the environment on which
1063 Emacs is running. */
1064void w32font_initialize ()
1065{
1066 /* Load functions that might not exist on older versions of Windows. */
1067 HANDLE gdi = LoadLibrary ("gdi32.dll");
1068
1069 get_glyph_indices_fn
1070 = (GETGLYPHINDICES) GetProcAddress (gdi, "GetGlyphIndicesW");
1071 get_text_extent_pointi_fn
1072 = (GETTEXTEXTENTPTI) GetProcAddress (gdi, "GetTextExtentPoint32W");
1073}
1074
1075/* Initialize state that does not change between invocations. This is only
1076 called when Emacs is dumped. */
1077void syms_of_w32font ()
1078{
1079 DEFSYM (Qw32, "w32");
1080 DEFSYM (Qdecorative, "decorative");
1081 DEFSYM (Qmodern, "modern");
1082 DEFSYM (Qroman, "roman");
1083 DEFSYM (Qscript, "script");
1084 DEFSYM (Qswiss, "swiss");
1085 DEFSYM (Qunknown, "unknown");
1086
1087 w32font_driver.type = Qw32;
1088 register_font_driver (&w32font_driver, NULL);
1089}