aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Rumney2007-06-02 23:42:23 +0000
committerJason Rumney2007-06-02 23:42:23 +0000
commitd205d43b31ac971fba532ec49fe53800684f4dae (patch)
tree2ab4b9b9f15b7c947121f032f4ee33480a8bb4b5
parent96db405702377452ae325695d792e1f4f4929c5e (diff)
downloademacs-d205d43b31ac971fba532ec49fe53800684f4dae.tar.gz
emacs-d205d43b31ac971fba532ec49fe53800684f4dae.zip
(w32font_info): Remove subranges.
(QCsubranges, Qmodern, Qswiss, Qroman): Remove. (QCfamily, Qmonospace, Qsans_serif, Qmono, Qsans, Qsans__serif) (Qraster, Qoutline, Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian) (Qhebrew, Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali) (Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu, Qkannada) (Qmalayalam, Qsinhala, Qthai, Qlao, Qtibetan, Qmyanmar, Qgeorgian) (Qhangul, Qethiopic, Qcherokee, Qcanadian_aboriginal, Qogham) (Qrunic, Qkhmer, Qmongolian, Qsymbol, Qbraille, Qhan) (Qideographic_description, Qcjk_misc, Qkana, Qbopomofo, Qkanbun) (Qyi, Qbyzantine_musical_symbol, Qmusical_symbol, Qmathematical): New symbols. (font_callback_data): New struct. (w32font_list, w32font_match): Use it. (w32font_open): Don't populate subranges. (w32font_has_char): Use script Lisp symbols, not subrange bitmask. (w32font_encode_char): Always return unicode code-point as-is. (w32font_text_extents): Supply a tranformation matrix to GetGlyphOutline. Never look up by glyph index. Avoid looping twice. Use unicode version of GetTexExtentPoint32 instead of glyph index version. (set_fonts_frame): Remove (w32_enumfont_pattern_entity): Add frame parameter, use it to set frame parameter. Use backward compatible fake foundries. Save generic family in extra slot under QCfamily. Make width slot constant. Save QCspacing value. Save list of scripts instead of binary subranges. (w32_generic_family, logfonts_match, font_matches_spec): New functions. (add_font_entity_to_list): Use font_callback_data struct. Filter unwanted fonts. (add_one_font_entity_to_list): Use font_callback_data struct. (w32_registry): Default to iso10646_1; (fill_in_logfont): Use dpi from extra slot. Don't bother with string font registries. Don't fill in font name if it is a generic family name, fill family instead. Use spacing, family and script extra info to fill pitch, family and charset fields. (list_all_matching_fonts): Use font_callback_data struct. (unicode_range_for_char): Remove. (font_supported_scripts): New function. (w32font_initialize): Remove. (syms_of_w32font): Update which symbols are defined.
-rw-r--r--src/w32font.c1115
1 files changed, 632 insertions, 483 deletions
diff --git a/src/w32font.c b/src/w32font.c
index e0e3f69cac6..b8b8e6a71d9 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -35,25 +35,33 @@ struct w32font_info
35{ 35{
36 struct font font; 36 struct font font;
37 TEXTMETRIC metrics; 37 TEXTMETRIC metrics;
38 /* Unicode subset bitfield. See MSDN documentation for FONTSIGNATURE. */
39 DWORD *subranges;
40}; 38};
41 39
42extern struct font_driver w32font_driver; 40extern struct font_driver w32font_driver;
43 41
44Lisp_Object Qw32, QCsubranges; 42Lisp_Object Qw32, QCfamily;
45static Lisp_Object Qmodern, Qswiss, Qroman, Qdecorative, Qscript, Qunknown; 43static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;
44static Lisp_Object Qscript, Qdecorative, Qraster, Qoutline, Qunknown;
45
46/* scripts */
47static Lisp_Object Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
48static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali;
49static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu;
50static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao;
51static Lisp_Object Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic;
52static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic;
53static Lisp_Object Qkhmer, Qmongolian, Qsymbol, Qbraille, Qhan;
54static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo;
55static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol;
56static Lisp_Object Qmusical_symbol, Qmathematical;
57
58/* Font spacing symbols - defined in font.c. */
59extern Lisp_Object Qc, Qp, Qm;
46 60
47static void fill_in_logfont P_ ((FRAME_PTR f, LOGFONT *logfont, 61static void fill_in_logfont P_ ((FRAME_PTR f, LOGFONT *logfont,
48 Lisp_Object font_spec)); 62 Lisp_Object font_spec));
49 63
50static void set_fonts_frame P_ ((Lisp_Object fontlist, Lisp_Object frame)); 64static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE * sig));
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 65
58/* From old font code in w32fns.c */ 66/* From old font code in w32fns.c */
59char * w32_to_x_charset P_ ((int charset, char * matching)); 67char * w32_to_x_charset P_ ((int charset, char * matching));
@@ -71,11 +79,27 @@ static int CALLBACK add_font_name_to_list P_ ((ENUMLOGFONTEX *,
71 NEWTEXTMETRICEX *, 79 NEWTEXTMETRICEX *,
72 DWORD, LPARAM)); 80 DWORD, LPARAM));
73 81
74/* W32 API functions only available on some versions of Windows */ 82/* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
75typedef DWORD (*GETGLYPHINDICES) (HDC, wchar_t *, int, LPWORD, DWORD); 83 of what we really want. */
76typedef BOOL (*GETTEXTEXTENTPTI) (HDC, LPWORD, int, LPSIZE); 84struct font_callback_data
77static GETGLYPHINDICES get_glyph_indices_fn = NULL; 85{
78static GETTEXTEXTENTPTI get_text_extent_pointi_fn = NULL; 86 /* The logfont we are matching against. EnumFontFamiliesEx only matches
87 face name and charset, so we need to manually match everything else
88 in the callback function. */
89 LOGFONT pattern;
90 /* The original font spec or entity. */
91 Lisp_Object orig_font_spec;
92 /* The frame the font is being loaded on. */
93 Lisp_Object frame;
94 /* The list to add matches to. */
95 Lisp_Object list;
96};
97
98/* Handles the problem that EnumFontFamiliesEx will not return all
99 style variations if the font name is not specified. */
100static void list_all_matching_fonts P_ ((struct font_callback_data *match_data));
101
102
79/* MingW headers only define this when _WIN32_WINNT >= 0x0500, but we 103/* MingW headers only define this when _WIN32_WINNT >= 0x0500, but we
80 target older versions. */ 104 target older versions. */
81#define GGI_MARK_NONEXISTING_GLYPHS 1 105#define GGI_MARK_NONEXISTING_GLYPHS 1
@@ -109,34 +133,34 @@ static Lisp_Object
109w32font_list (frame, font_spec) 133w32font_list (frame, font_spec)
110 Lisp_Object frame, font_spec; 134 Lisp_Object frame, font_spec;
111{ 135{
112 Lisp_Object list = Qnil; 136 Lisp_Object tem;
113 LOGFONT font_match_pattern; 137 struct font_callback_data match_data;
114 HDC dc; 138 HDC dc;
115 FRAME_PTR f = XFRAME (frame); 139 FRAME_PTR f = XFRAME (frame);
116 140
117 bzero (&font_match_pattern, sizeof (font_match_pattern)); 141 match_data.orig_font_spec = font_spec;
118 fill_in_logfont (f, &font_match_pattern, font_spec); 142 match_data.list = Qnil;
143 match_data.frame = frame;
144 bzero (&match_data.pattern, sizeof (LOGFONT));
145 fill_in_logfont (f, &match_data.pattern, font_spec);
119 146
120 147 if (match_data.pattern.lfFaceName[0] == '\0')
121 if (font_match_pattern.lfFaceName[0] == '\0')
122 { 148 {
123 /* EnumFontFamiliesEx does not take other fields into account if 149 /* EnumFontFamiliesEx does not take other fields into account if
124 font name is blank, so need to use two passes. */ 150 font name is blank, so need to use two passes. */
125 list_all_matching_fonts (frame, &font_match_pattern, &list); 151 list_all_matching_fonts (&match_data);
126 } 152 }
127 else 153 else
128 { 154 {
129 dc = get_frame_dc (f); 155 dc = get_frame_dc (f);
130 156
131 EnumFontFamiliesEx (dc, &font_match_pattern, 157 EnumFontFamiliesEx (dc, &match_data.pattern,
132 (FONTENUMPROC) add_font_entity_to_list, 158 (FONTENUMPROC) add_font_entity_to_list,
133 (LPARAM) &list, 0); 159 (LPARAM) &match_data, 0);
134 release_frame_dc (f, dc); 160 release_frame_dc (f, dc);
135 } 161 }
136 162
137 set_fonts_frame (list, frame); 163 return NILP (match_data.list) ? null_vector : Fvconcat (1, &match_data.list);
138
139 return list;
140} 164}
141 165
142/* w32 implementation of match for font backend. 166/* w32 implementation of match for font backend.
@@ -147,24 +171,24 @@ static Lisp_Object
147w32font_match (frame, font_spec) 171w32font_match (frame, font_spec)
148 Lisp_Object frame, font_spec; 172 Lisp_Object frame, font_spec;
149{ 173{
150 Lisp_Object list = Qnil; 174 struct font_callback_data match_data;
151 LOGFONT font_match_pattern;
152 HDC dc; 175 HDC dc;
153 FRAME_PTR f = XFRAME (frame); 176 FRAME_PTR f = XFRAME (frame);
154 177
155 bzero (&font_match_pattern, sizeof (font_match_pattern)); 178 match_data.orig_font_spec = font_spec;
156 fill_in_logfont (f, &font_match_pattern, font_spec); 179 match_data.frame = frame;
180 match_data.list = Qnil;
181 bzero (&match_data.pattern, sizeof (LOGFONT));
182 fill_in_logfont (f, &match_data.pattern, font_spec);
157 183
158 dc = get_frame_dc (f); 184 dc = get_frame_dc (f);
159 185
160 EnumFontFamiliesEx (dc, &font_match_pattern, 186 EnumFontFamiliesEx (dc, &match_data.pattern,
161 (FONTENUMPROC) add_one_font_entity_to_list, 187 (FONTENUMPROC) add_one_font_entity_to_list,
162 (LPARAM) &list, 0); 188 (LPARAM) &match_data, 0);
163 release_frame_dc (f, dc); 189 release_frame_dc (f, dc);
164 190
165 set_fonts_frame (list, frame); 191 return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
166
167 return NILP (list) ? Qnil : XCAR (list);
168} 192}
169 193
170 194
@@ -219,7 +243,7 @@ w32font_open (f, font_entity, pixel_size)
219 fill_in_logfont (f, &logfont, font_entity); 243 fill_in_logfont (f, &logfont, font_entity);
220 244
221 size = XINT (AREF (font_entity, FONT_SIZE_INDEX)); 245 size = XINT (AREF (font_entity, FONT_SIZE_INDEX));
222 if (size == 0) 246 if (!size)
223 size = pixel_size; 247 size = pixel_size;
224 248
225 logfont.lfHeight = -size; 249 logfont.lfHeight = -size;
@@ -281,22 +305,6 @@ w32font_open (f, font_entity, pixel_size)
281 font->descent = w32_font->metrics.tmDescent; 305 font->descent = w32_font->metrics.tmDescent;
282 font->scalable = w32_font->metrics.tmPitchAndFamily & TMPF_VECTOR; 306 font->scalable = w32_font->metrics.tmPitchAndFamily & TMPF_VECTOR;
283 307
284 /* Truetype fonts will have extra information about the characters
285 covered by the font. */
286 ((struct w32font_info *)(font))->subranges = NULL;
287 extra = AREF (font_entity, FONT_EXTRA_INDEX);
288 if (CONSP (extra))
289 {
290 val = assq_no_quit (extra, QCsubranges);
291 if (CONSP (val))
292 {
293 val = XCDR (val);
294
295 if (XTYPE (val) == Lisp_Misc && XMISCTYPE (val) == Lisp_Misc_Save_Value)
296 ((struct w32font_info *)(font))->subranges = XSAVE_VALUE (val)->pointer;
297 }
298 }
299
300 return font; 308 return font;
301} 309}
302 310
@@ -330,33 +338,22 @@ w32font_has_char (entity, c)
330 Lisp_Object entity; 338 Lisp_Object entity;
331 int c; 339 int c;
332{ 340{
333 Lisp_Object val, extra; 341 Lisp_Object supported_scripts, extra, script;
334 DWORD *ranges;
335 int index;
336 DWORD mask; 342 DWORD mask;
337 343
338 extra = AREF (entity, FONT_EXTRA_INDEX); 344 extra = AREF (entity, FONT_EXTRA_INDEX);
339 if (!CONSP (extra)) 345 if (!CONSP (extra))
340 return -1; 346 return -1;
341 347
342 val = assq_no_quit (extra, QCsubranges); 348 supported_scripts = assq_no_quit (QCscript, extra);
343 if (!CONSP (val)) 349 if (!CONSP (supported_scripts))
344 return -1;
345
346 val = XCDR (val);
347 if (XTYPE (val) != Lisp_Misc || XMISCTYPE (val) != Lisp_Misc_Save_Value)
348 return -1; 350 return -1;
349 351
350 ranges = XSAVE_VALUE (val)->pointer; 352 supported_scripts = XCDR (supported_scripts);
351 353
352 index = unicode_range_for_char (c); 354 script = CHAR_TABLE_REF (Vchar_script_table, c);
353 mask = 1 << (index % 32);
354 index = index / 32;
355 355
356 if (ranges[index] & mask) 356 return (memq_no_quit (script, supported_scripts)) ? 1 : 0;
357 return 1;
358 else
359 return 0;
360} 357}
361 358
362/* w32 implementation of encode_char for font backend. 359/* w32 implementation of encode_char for font backend.
@@ -367,32 +364,8 @@ w32font_encode_char (font, c)
367 struct font *font; 364 struct font *font;
368 int c; 365 int c;
369{ 366{
370 if (get_glyph_indices_fn) 367 /* Avoid unneccesary conversion - all the Win32 APIs will take a unicode
371 { 368 character. */
372 HFONT old_font;
373 WORD glyph[2];
374 int converted;
375 /* FIXME: Be nice if we had a frame here, rather than getting
376 the desktop's device context to measure against... */
377 HDC dc = GetDC (NULL);
378 wchar_t string[2];
379 string[0] = c;
380 string[1] = 0x0000;
381
382 if (get_glyph_indices_fn)
383 converted = (*get_glyph_indices_fn) (dc, string, 1, glyph,
384 GGI_MARK_NONEXISTING_GLYPHS);
385
386 /* Restore state and release DC. */
387 SelectObject (dc, old_font);
388 ReleaseDC (NULL, dc);
389 if (converted > 0 && glyph[0] != 0xFFFF)
390 return glyph[0];
391 else if (converted != GDI_ERROR)
392 return FONT_INVALID_CODE;
393 }
394 /* On older platforms, or if the above fails, return the unicode
395 code point. */
396 return c; 369 return c;
397} 370}
398 371
@@ -417,21 +390,34 @@ w32font_text_extents (font, code, nglyphs, metrics)
417 390
418 /* TODO: Allow some extra room for surrogates. */ 391 /* TODO: Allow some extra room for surrogates. */
419 WORD *wcode = alloca(nglyphs * sizeof (WORD)); 392 WORD *wcode = alloca(nglyphs * sizeof (WORD));
393 SIZE size;
420 394
421 old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont); 395 old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont);
422 396
423 if (metrics) 397 if (metrics)
424 { 398 {
425 GLYPHMETRICS gm; 399 GLYPHMETRICS gm;
426 int i; 400 MAT2 transform;
401 int i, width;
427 UINT format = GGO_METRICS; 402 UINT format = GGO_METRICS;
428 if (get_text_extent_pointi_fn) 403
429 format |= GGO_GLYPH_INDEX; 404 /* Set transform to the identity matrix. */
405 bzero (&transform, sizeof (transform));
406 transform.eM11.value = 1;
407 transform.eM22.value = 1;
430 408
431 for (i = 0; i < nglyphs; i++) 409 for (i = 0; i < nglyphs; i++)
432 { 410 {
433 if (GetGlyphOutline (dc, *(code + i), format, &gm, 0, NULL, NULL) 411 if (code[i] < 0x10000)
434 != GDI_ERROR) 412 wcode[i] = code[i];
413 else
414 {
415 /* TODO: Convert to surrogate, reallocating array if needed */
416 wcode[i] = 0xffff;
417 }
418
419 if (GetGlyphOutlineW (dc, *(code + i), format, &gm, 0,
420 NULL, &transform) != GDI_ERROR)
435 { 421 {
436 metrics[i].lbearing = gm.gmptGlyphOrigin.x; 422 metrics[i].lbearing = gm.gmptGlyphOrigin.x;
437 metrics[i].rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX; 423 metrics[i].rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
@@ -450,28 +436,26 @@ w32font_text_extents (font, code, nglyphs, metrics)
450 } 436 }
451 } 437 }
452 } 438 }
453 439 else
454 for (i = 0; i < nglyphs; i++)
455 { 440 {
456 if (code[i] < 0x10000) 441 for (i = 0; i < nglyphs; i++)
457 wcode[i] = code[i]; 442 {
458 else 443 if (code[i] < 0x10000)
459 { 444 wcode[i] = code[i];
460 /* TODO: Convert to surrogate, reallocating array if needed */ 445 else
461 wcode[i] = 0xffff; 446 {
462 } 447 /* TODO: Convert to surrogate, reallocating array if needed */
448 wcode[i] = 0xffff;
449 }
450 }
463 } 451 }
464 452
465 if (get_text_extent_pointi_fn) 453 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
466 { 454 {
467 SIZE size; 455 total_width = size.cx;
468 if ((*get_text_extent_pointi_fn) (dc, wcode, nglyphs, &size))
469 {
470 total_width = size.cx;
471 }
472 } 456 }
473 457
474 if (total_width == 0) 458 if (!total_width)
475 { 459 {
476 RECT rect; 460 RECT rect;
477 rect.top = 0; rect.bottom = font->font.height; rect.left = 0; rect.right = 1; 461 rect.top = 0; rect.bottom = font->font.height; rect.left = 0; rect.right = 1;
@@ -479,6 +463,7 @@ w32font_text_extents (font, code, nglyphs, metrics)
479 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE); 463 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
480 total_width = rect.right; 464 total_width = rect.right;
481 } 465 }
466
482 /* Restore state and release DC. */ 467 /* Restore state and release DC. */
483 SelectObject (dc, old_font); 468 SelectObject (dc, old_font);
484 ReleaseDC (NULL, dc); 469 ReleaseDC (NULL, dc);
@@ -497,7 +482,6 @@ w32font_draw (s, from, to, x, y, with_background)
497 struct glyph_string *s; 482 struct glyph_string *s;
498 int from, to, x, y, with_background; 483 int from, to, x, y, with_background;
499{ 484{
500 /* TODO: Do we need to specify ETO_GLYPH_INDEX or is char2b always utf-16? */
501 UINT options = 0; 485 UINT options = 0;
502 486
503 if (with_background) 487 if (with_background)
@@ -619,7 +603,8 @@ add_font_name_to_list (logical_font, physical_font, font_type, list_object)
619 603
620/* Convert an enumerated Windows font to an Emacs font entity. */ 604/* Convert an enumerated Windows font to an Emacs font entity. */
621static Lisp_Object 605static Lisp_Object
622w32_enumfont_pattern_entity (logical_font, physical_font, font_type) 606w32_enumfont_pattern_entity (frame, logical_font, physical_font, font_type)
607 Lisp_Object frame;
623 ENUMLOGFONTEX *logical_font; 608 ENUMLOGFONTEX *logical_font;
624 NEWTEXTMETRICEX *physical_font; 609 NEWTEXTMETRICEX *physical_font;
625 DWORD font_type; 610 DWORD font_type;
@@ -628,37 +613,58 @@ w32_enumfont_pattern_entity (logical_font, physical_font, font_type)
628 LOGFONT *lf = (LOGFONT*) logical_font; 613 LOGFONT *lf = (LOGFONT*) logical_font;
629 BYTE generic_type; 614 BYTE generic_type;
630 615
631 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), null_string); 616 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
632 617
633 ASET (entity, FONT_TYPE_INDEX, Qw32); 618 ASET (entity, FONT_TYPE_INDEX, Qw32);
619 ASET (entity, FONT_FRAME_INDEX, frame);
634 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet)); 620 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet));
635 ASET (entity, FONT_OBJLIST_INDEX, Qnil); 621 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
636 622
637 /* Foundry is difficult to get in readable form on Windows. 623 /* Foundry is difficult to get in readable form on Windows.
638 But Emacs crashes if it is not set, so set it to the generic type. */ 624 But Emacs crashes if it is not set, so set it to something more
625 generic. Thes values make xflds compatible with Emacs 22. */
626 if (lf->lfOutPrecision == OUT_STRING_PRECIS)
627 tem = Qraster;
628 else if (lf->lfOutPrecision == OUT_STROKE_PRECIS)
629 tem = Qoutline;
630 else
631 tem = Qunknown;
632
633 ASET (entity, FONT_FOUNDRY_INDEX, tem);
634
635 /* Save the generic family in the extra info, as it is likely to be
636 useful to users looking for a close match. */
639 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0; 637 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0;
640 if (generic_type == FF_DECORATIVE) 638 if (generic_type == FF_DECORATIVE)
641 tem = Qdecorative; 639 tem = Qdecorative;
642 else if (generic_type == FF_MODERN) 640 else if (generic_type == FF_MODERN)
643 tem = Qmodern; 641 tem = Qmonospace;
644 else if (generic_type == FF_ROMAN) 642 else if (generic_type == FF_ROMAN)
645 tem = Qroman; 643 tem = Qserif;
646 else if (generic_type == FF_SCRIPT) 644 else if (generic_type == FF_SCRIPT)
647 tem = Qscript; 645 tem = Qscript;
648 else if (generic_type == FF_SWISS) 646 else if (generic_type == FF_SWISS)
649 tem = Qswiss; 647 tem = Qsans_serif;
650 else 648 else
651 tem = Qunknown; 649 tem = Qnil;
650
651 if (! NILP (tem))
652 font_put_extra (entity, QCfamily, tem);
652 653
653 ASET (entity, FONT_FOUNDRY_INDEX, tem); 654
655 if (physical_font->ntmTm.tmPitchAndFamily & 0x01)
656 font_put_extra (entity, QCspacing, make_number (FONT_SPACING_PROPORTIONAL));
657 else
658 font_put_extra (entity, QCspacing, make_number (FONT_SPACING_MONO));
654 659
655 ASET (entity, FONT_FAMILY_INDEX, 660 ASET (entity, FONT_FAMILY_INDEX,
656 intern_downcase (lf->lfFaceName, strlen (lf->lfFaceName))); 661 intern_downcase (lf->lfFaceName, strlen (lf->lfFaceName)));
657 662
658 ASET (entity, FONT_WEIGHT_INDEX, make_number (lf->lfWeight)); 663 ASET (entity, FONT_WEIGHT_INDEX, make_number (lf->lfWeight));
659 ASET (entity, FONT_SLANT_INDEX, make_number (lf->lfItalic ? 200 : 100)); 664 ASET (entity, FONT_SLANT_INDEX, make_number (lf->lfItalic ? 200 : 100));
660 ASET (entity, FONT_WIDTH_INDEX, 665 /* TODO: PANOSE struct has this info, but need to call GetOutlineTextMetrics
661 make_number (physical_font->ntmTm.tmAveCharWidth)); 666 to get it. */
667 ASET (entity, FONT_WIDTH_INDEX, make_number (100));
662 668
663 if (font_type & RASTER_FONTTYPE) 669 if (font_type & RASTER_FONTTYPE)
664 ASET (entity, FONT_SIZE_INDEX, make_number (physical_font->ntmTm.tmHeight)); 670 ASET (entity, FONT_SIZE_INDEX, make_number (physical_font->ntmTm.tmHeight));
@@ -669,43 +675,255 @@ w32_enumfont_pattern_entity (logical_font, physical_font, font_type)
669 of getting this information easily. */ 675 of getting this information easily. */
670 if (font_type & TRUETYPE_FONTTYPE) 676 if (font_type & TRUETYPE_FONTTYPE)
671 { 677 {
672 DWORD *subranges = xmalloc(16); 678 font_put_extra (entity, QCscript,
673 memcpy (subranges, physical_font->ntmFontSig.fsUsb, 16); 679 font_supported_scripts (&physical_font->ntmFontSig));
674 font_put_extra (entity, QCsubranges, make_save_value (subranges, 0));
675 } 680 }
681
676 return entity; 682 return entity;
677} 683}
678 684
685
686/* Convert generic families to the family portion of lfPitchAndFamily. */
687BYTE
688w32_generic_family (Lisp_Object name)
689{
690 /* Generic families. */
691 if (EQ (name, Qmonospace) || EQ (name, Qmono))
692 return FF_MODERN;
693 else if (EQ (name, Qsans_serif) || EQ (name, Qsans__serif)
694 || EQ (name, Qsans))
695 return FF_SWISS;
696 else if (EQ (name, Qserif))
697 return FF_ROMAN;
698 else if (EQ (name, Qdecorative))
699 return FF_DECORATIVE;
700 else if (EQ (name, Qscript))
701 return FF_SCRIPT;
702 else
703 return FF_DONTCARE;
704}
705
706static int
707logfonts_match (font, pattern)
708 LOGFONT *font, *pattern;
709{
710 /* Only check height for raster fonts. */
711 if (pattern->lfHeight && font->lfOutPrecision == OUT_STRING_PRECIS
712 && font->lfHeight != pattern->lfHeight)
713 return 0;
714
715 /* Have some flexibility with weights. */
716 if (pattern->lfWeight
717 && ((font->lfWeight < (pattern->lfWeight - 150))
718 || font->lfWeight > (pattern->lfWeight + 150)))
719 return 0;
720
721 /* Charset and face should be OK. Italic has to be checked
722 against the original spec, in case we don't have any preference. */
723 return 1;
724}
725
726static int
727font_matches_spec (type, font, spec)
728 DWORD type;
729 NEWTEXTMETRICEX *font;
730 Lisp_Object spec;
731{
732 Lisp_Object extra, val;
733
734 /* Check italic. Can't check logfonts, since it is a boolean field,
735 so there is no difference between "non-italic" and "don't care". */
736 val = AREF (spec, FONT_SLANT_INDEX);
737 if (INTEGERP (val))
738 {
739 int slant = XINT (val);
740 if ((slant > 150 && !font->ntmTm.tmItalic)
741 || (slant <= 150 && font->ntmTm.tmItalic))
742 {
743 OutputDebugString ("italic mismatch");
744 return 0;
745 }
746 }
747
748 /* Check extra parameters. */
749 for (extra = AREF (spec, FONT_EXTRA_INDEX);
750 CONSP (extra); extra = XCDR (extra))
751 {
752 Lisp_Object extra_entry;
753 extra_entry = XCAR (extra);
754 if (CONSP (extra_entry))
755 {
756 Lisp_Object key = XCAR (extra_entry);
757 val = XCDR (extra_entry);
758 if (EQ (key, QCfamily))
759 {
760 /* Generic family. Most useful when there is no font name
761 specified. eg, if a script does not exist in the default
762 font, we could look for a font with the same generic family
763 that does support the script. Full PANOSE support would
764 be better, but we need to open the font to get that. */
765 BYTE w32_family = w32_generic_family (val);
766
767 /* Reject if FF_DONTCARE is returned, as it means the
768 font spec is bad. */
769 if (w32_family == FF_DONTCARE
770 || w32_family != (font->ntmTm.tmPitchAndFamily & 0xF0))
771 return 0;
772 }
773 else if (EQ (key, QCspacing))
774 {
775 int proportional;
776 if (INTEGERP (val))
777 {
778 int spacing = XINT (val);
779 proportional = (spacing < FONT_SPACING_MONO);
780 }
781 else if (EQ (val, Qp))
782 proportional = 1;
783 else if (EQ (val, Qc) || EQ (val, Qm))
784 proportional = 0;
785 else
786 return 0; /* Bad font spec. */
787
788 if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
789 || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
790 return 0;
791 }
792 else if (EQ (key, QCscript) && SYMBOLP (val))
793 {
794 /* Only truetype fonts will have information about what
795 scripts they support. This probably means the user
796 will have to force Emacs to use raster, postscript
797 or atm fonts for non-ASCII text. */
798 if (type & TRUETYPE_FONTTYPE)
799 {
800 Lisp_Object support
801 = font_supported_scripts (&font->ntmFontSig);
802 if (! memq_no_quit (val, support))
803 return 0;
804 }
805 else
806 {
807 /* Return specific matches, but play it safe. Fonts
808 that cover more than their charset would suggest
809 are likely to be truetype or opentype fonts,
810 covered above. */
811 if (EQ (val, Qlatin))
812 {
813 /* Although every charset but symbol, thai and
814 arabic contains the basic ASCII set of latin
815 characters, Emacs expects much more. */
816 if (font->ntmTm.tmCharSet != ANSI_CHARSET)
817 return 0;
818 }
819 else if (EQ (val, Qsymbol))
820 {
821 if (font->ntmTm.tmCharSet != SYMBOL_CHARSET)
822 return 0;
823 }
824 else if (EQ (val, Qcyrillic))
825 {
826 if (font->ntmTm.tmCharSet != RUSSIAN_CHARSET)
827 return 0;
828 }
829 else if (EQ (val, Qgreek))
830 {
831 if (font->ntmTm.tmCharSet != GREEK_CHARSET)
832 return 0;
833 }
834 else if (EQ (val, Qarabic))
835 {
836 if (font->ntmTm.tmCharSet != ARABIC_CHARSET)
837 return 0;
838 }
839 else if (EQ (val, Qhebrew))
840 {
841 if (font->ntmTm.tmCharSet != HEBREW_CHARSET)
842 return 0;
843 }
844 else if (EQ (val, Qthai))
845 {
846 if (font->ntmTm.tmCharSet != THAI_CHARSET)
847 return 0;
848 }
849 else if (EQ (val, Qkana))
850 {
851 if (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
852 return 0;
853 }
854 else if (EQ (val, Qbopomofo))
855 {
856 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET)
857 return 0;
858 }
859 else if (EQ (val, Qhangul))
860 {
861 if (font->ntmTm.tmCharSet != HANGUL_CHARSET
862 && font->ntmTm.tmCharSet != JOHAB_CHARSET)
863 return 0;
864 }
865 else if (EQ (val, Qhan))
866 {
867 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET
868 && font->ntmTm.tmCharSet != GB2312_CHARSET
869 && font->ntmTm.tmCharSet != HANGUL_CHARSET
870 && font->ntmTm.tmCharSet != JOHAB_CHARSET
871 && font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
872 return 0;
873 }
874 else
875 /* Other scripts unlikely to be handled. */
876 return 0;
877 }
878 }
879 }
880 }
881 return 1;
882}
883
679/* Callback function for EnumFontFamiliesEx. 884/* Callback function for EnumFontFamiliesEx.
680 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */ 885 * Checks if a font matches everything we are trying to check agaist,
886 * and if so, adds it to a list. Both the data we are checking against
887 * and the list to which the fonts are added are passed in via the
888 * lparam argument, in the form of a font_callback_data struct. */
681static int CALLBACK 889static int CALLBACK
682add_font_entity_to_list (logical_font, physical_font, font_type, list_object) 890add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
683 ENUMLOGFONTEX *logical_font; 891 ENUMLOGFONTEX *logical_font;
684 NEWTEXTMETRICEX *physical_font; 892 NEWTEXTMETRICEX *physical_font;
685 DWORD font_type; 893 DWORD font_type;
686 LPARAM list_object; 894 LPARAM lParam;
687{ 895{
688 Lisp_Object *list = (Lisp_Object *) list_object; 896 struct font_callback_data *match_data
689 Lisp_Object entity = w32_enumfont_pattern_entity (logical_font, 897 = (struct font_callback_data *) lParam;
690 physical_font, font_type);
691 if (!NILP (entity))
692 *list = Fcons (entity, *list);
693 898
899 if (logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
900 && font_matches_spec (font_type, physical_font,
901 match_data->orig_font_spec))
902 {
903 Lisp_Object entity
904 = w32_enumfont_pattern_entity (match_data->frame, logical_font,
905 physical_font, font_type);
906 if (!NILP (entity))
907 match_data->list = Fcons (entity, match_data->list);
908 }
694 return 1; 909 return 1;
695} 910}
696 911
697/* Callback function for EnumFontFamiliesEx. 912/* Callback function for EnumFontFamiliesEx.
698 * Adds the name of a font to a Lisp list (passed in as the lParam arg), 913 * Terminates the search once we have a match. */
699 * then terminate the search. */
700static int CALLBACK 914static int CALLBACK
701add_one_font_entity_to_list (logical_font, physical_font, font_type, list) 915add_one_font_entity_to_list (logical_font, physical_font, font_type, lParam)
702 ENUMLOGFONTEX *logical_font; 916 ENUMLOGFONTEX *logical_font;
703 NEWTEXTMETRICEX *physical_font; 917 NEWTEXTMETRICEX *physical_font;
704 DWORD font_type; 918 DWORD font_type;
705 LPARAM list; 919 LPARAM lParam;
706{ 920{
707 add_font_entity_to_list (logical_font, physical_font, font_type, list); 921 struct font_callback_data *match_data
708 return 0; 922 = (struct font_callback_data *) lParam;
923 add_font_entity_to_list (logical_font, physical_font, font_type, lParam);
924
925 /* If we have a font in the list, terminate the search. */
926 return !NILP (match_data->list);
709} 927}
710 928
711/* Convert a Lisp font registry (symbol) to a windows charset. */ 929/* Convert a Lisp font registry (symbol) to a windows charset. */
@@ -731,7 +949,7 @@ w32_registry (w32_charset)
731 LONG w32_charset; 949 LONG w32_charset;
732{ 950{
733 if (w32_charset == ANSI_CHARSET) 951 if (w32_charset == ANSI_CHARSET)
734 return Qiso8859_1; 952 return Qiso10646_1;
735 else 953 else
736 { 954 {
737 char * charset = w32_to_x_charset (w32_charset, NULL); 955 char * charset = w32_to_x_charset (w32_charset, NULL);
@@ -739,24 +957,6 @@ w32_registry (w32_charset)
739 } 957 }
740} 958}
741 959
742static void
743set_fonts_frame (fontlist, frame)
744 Lisp_Object fontlist;
745 Lisp_Object frame;
746{
747 if (VECTORP (fontlist))
748 ASET (fontlist, FONT_FRAME_INDEX, frame);
749 else
750 {
751 for ( ; CONSP (fontlist); fontlist = XCDR (fontlist))
752 {
753 Lisp_Object entity = XCAR (fontlist);
754 if (VECTORP (entity))
755 ASET (entity, FONT_FRAME_INDEX, frame);
756 }
757 }
758}
759
760/* Fill in all the available details of LOGFONT from FONT_SPEC. */ 960/* Fill in all the available details of LOGFONT from FONT_SPEC. */
761static void 961static void
762fill_in_logfont (f, logfont, font_spec) 962fill_in_logfont (f, logfont, font_spec)
@@ -764,23 +964,30 @@ fill_in_logfont (f, logfont, font_spec)
764 LOGFONT *logfont; 964 LOGFONT *logfont;
765 Lisp_Object font_spec; 965 Lisp_Object font_spec;
766{ 966{
767 Lisp_Object val, tmp, extra; 967 Lisp_Object tmp, extra;
768 int dpi = FRAME_W32_DISPLAY_INFO (f)->resy; 968 int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
769 969
770 /* TODO: Allow user to override dpi settings. */ 970 extra = AREF (font_spec, FONT_EXTRA_INDEX);
971 /* Allow user to override dpi settings. */
972 if (CONSP (extra))
973 {
974 tmp = assq_no_quit (QCdpi, extra);
975 if (CONSP (tmp) && INTEGERP (XCDR (tmp)))
976 {
977 dpi = XINT (XCDR (tmp));
978 }
979 else if (CONSP (tmp) && FLOATP (XCDR (tmp)))
980 {
981 dpi = (int) (XFLOAT_DATA (XCDR (tmp)) + 0.5);
982 }
983 }
771 984
772 /* Height */ 985 /* Height */
773 tmp = AREF (font_spec, FONT_SIZE_INDEX); 986 tmp = AREF (font_spec, FONT_SIZE_INDEX);
774 if (INTEGERP (tmp)) 987 if (INTEGERP (tmp))
775 logfont->lfHeight = -1 * XINT (tmp); 988 logfont->lfHeight = -1 * XINT (tmp);
776 else if (FLOATP (tmp)) 989 else if (FLOATP (tmp))
777 logfont->lfHeight = (int) (-1.0 * dpi * XFLOAT_DATA (tmp) / 72.0); 990 logfont->lfHeight = (int) (-1.0 * dpi * XFLOAT_DATA (tmp) / 72.27 + 0.5);
778
779 /* Width TODO: makes fonts look distorted.
780 tmp = AREF (font_spec, FONT_WIDTH_INDEX);
781 if (INTEGERP (tmp))
782 logfont->lfWidth = XINT (tmp);
783 */
784 991
785 /* Escapement */ 992 /* Escapement */
786 993
@@ -806,12 +1013,7 @@ fill_in_logfont (f, logfont, font_spec)
806 /* Charset */ 1013 /* Charset */
807 tmp = AREF (font_spec, FONT_REGISTRY_INDEX); 1014 tmp = AREF (font_spec, FONT_REGISTRY_INDEX);
808 if (! NILP (tmp)) 1015 if (! NILP (tmp))
809 { 1016 logfont->lfCharSet = registry_to_w32_charset (tmp);
810 if (STRINGP (tmp))
811 logfont->lfCharSet = x_to_w32_charset (SDATA (tmp));
812 else
813 logfont->lfCharSet = registry_to_w32_charset (tmp);
814 }
815 1017
816 /* Out Precision */ 1018 /* Out Precision */
817 /* Clip Precision */ 1019 /* Clip Precision */
@@ -819,311 +1021,211 @@ fill_in_logfont (f, logfont, font_spec)
819 can enable/disable anti-aliasing for individual fonts. */ 1021 can enable/disable anti-aliasing for individual fonts. */
820 logfont->lfQuality = DEFAULT_QUALITY; 1022 logfont->lfQuality = DEFAULT_QUALITY;
821 1023
822 /* Pitch and Family */ 1024 /* Generic Family and Face Name */
823 /* Facename TODO: handle generic names */ 1025 logfont->lfPitchAndFamily = FF_DONTCARE | DEFAULT_PITCH;
1026
824 tmp = AREF (font_spec, FONT_FAMILY_INDEX); 1027 tmp = AREF (font_spec, FONT_FAMILY_INDEX);
825 /* Font families are interned */ 1028 if (! NILP (tmp))
826 if (SYMBOLP (tmp)) 1029 {
827 strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE); 1030 logfont->lfPitchAndFamily = w32_generic_family (tmp) | DEFAULT_PITCH;
828 else if (STRINGP (tmp)) 1031 if ((logfont->lfPitchAndFamily & 0xF0) != FF_DONTCARE)
829 strncpy (logfont->lfFaceName, SDATA (tmp), LF_FACESIZE); 1032 ; /* Font name was generic, don't fill in font name. */
1033 /* Font families are interned, but allow for strings also in case of
1034 user input. */
1035 else if (SYMBOLP (tmp))
1036 strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE);
1037 else if (STRINGP (tmp))
1038 strncpy (logfont->lfFaceName, SDATA (tmp), LF_FACESIZE);
1039 }
830 1040
1041 /* Process EXTRA info. */
1042 for ( ; CONSP (extra); extra = XCDR (extra))
1043 {
1044 tmp = XCAR (extra);
1045 if (CONSP (tmp))
1046 {
1047 Lisp_Object key, val;
1048 key = XCAR (tmp), val = XCDR (tmp);
1049 if (EQ (key, QCfamily))
1050 {
1051 /* Override generic family. */
1052 BYTE family = w32_generic_family (val);
1053 if (family != FF_DONTCARE)
1054 logfont->lfPitchAndFamily
1055 = logfont->lfPitchAndFamily & 0x0F | family;
1056 }
1057 else if (EQ (key, QCspacing))
1058 {
1059 /* Set pitch based on the spacing property. */
1060 if (INTEGERP (val))
1061 {
1062 int spacing = XINT (val);
1063 if (spacing < FONT_SPACING_MONO)
1064 logfont->lfPitchAndFamily
1065 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
1066 else
1067 logfont->lfPitchAndFamily
1068 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
1069 }
1070 else if (EQ (val, Qp))
1071 logfont->lfPitchAndFamily
1072 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
1073 else if (EQ (val, Qc) || EQ (val, Qm))
1074 logfont->lfPitchAndFamily
1075 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
1076 }
1077 /* Only use QCscript if charset is not provided, or is unicode
1078 and a single script is specified. This is rather crude,
1079 and is only used to narrow down the fonts returned where
1080 there is a definite match. Some scripts, such as latin, han,
1081 cjk-misc match multiple lfCharSet values, so we can't pre-filter
1082 them. */
1083 else if (EQ (key, QCscript)
1084 && logfont->lfCharSet == DEFAULT_CHARSET
1085 && SYMBOLP (val))
1086 {
1087 if (EQ (val, Qgreek))
1088 logfont->lfCharSet = GREEK_CHARSET;
1089 else if (EQ (val, Qhangul))
1090 logfont->lfCharSet = HANGUL_CHARSET;
1091 else if (EQ (val, Qkana) || EQ (val, Qkanbun))
1092 logfont->lfCharSet = SHIFTJIS_CHARSET;
1093 else if (EQ (val, Qbopomofo))
1094 logfont->lfCharSet = CHINESEBIG5_CHARSET;
1095 /* GB 18030 supports tibetan, yi, mongolian,
1096 fonts that support it should show up if we ask for
1097 GB2312 fonts. */
1098 else if (EQ (val, Qtibetan) || EQ (val, Qyi)
1099 || EQ (val, Qmongolian))
1100 logfont->lfCharSet = GB2312_CHARSET;
1101 else if (EQ (val, Qhebrew))
1102 logfont->lfCharSet = HEBREW_CHARSET;
1103 else if (EQ (val, Qarabic))
1104 logfont->lfCharSet = ARABIC_CHARSET;
1105 else if (EQ (val, Qthai))
1106 logfont->lfCharSet = THAI_CHARSET;
1107 else if (EQ (val, Qsymbol))
1108 logfont->lfCharSet = SYMBOL_CHARSET;
1109 }
1110 }
1111 }
831} 1112}
832 1113
833static void 1114static void
834list_all_matching_fonts (frame, font_match_pattern, list) 1115list_all_matching_fonts (match_data)
835 Lisp_Object frame; 1116 struct font_callback_data *match_data;
836 LOGFONT *font_match_pattern;
837 Lisp_Object* list;
838{ 1117{
839 HDC dc; 1118 HDC dc;
840 Lisp_Object families = w32font_list_family (frame); 1119 Lisp_Object families = w32font_list_family (match_data->frame);
841 struct frame *f = XFRAME (frame); 1120 struct frame *f = XFRAME (match_data->frame);
842 1121
843 dc = get_frame_dc (f); 1122 dc = get_frame_dc (f);
844 1123
845 while (!NILP (families)) 1124 while (!NILP (families))
846 { 1125 {
1126 /* TODO: Use the Unicode versions of the W32 APIs, so we can
1127 handle non-ASCII font names. */
1128 char *name;
847 Lisp_Object family = CAR (families); 1129 Lisp_Object family = CAR (families);
848 families = CDR (families); 1130 families = CDR (families);
849 if (STRINGP (family)) 1131 if (NILP (family))
850 { 1132 continue;
851 /* TODO: Use the Unicode versions of the W32 APIs, so we can 1133 else if (STRINGP (family))
852 handle non-ASCII font names. */ 1134 name = SDATA (family);
853 char * name = SDATA (family); 1135 else
854 strncpy (font_match_pattern->lfFaceName, name, LF_FACESIZE); 1136 name = SDATA (SYMBOL_NAME (family));
855 font_match_pattern->lfFaceName[LF_FACESIZE - 1] = '\0'; 1137
856 1138 strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE);
857 EnumFontFamiliesEx (dc, font_match_pattern, 1139 match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0';
858 (FONTENUMPROC) add_font_entity_to_list, 1140
859 (LPARAM)&list, 0); 1141 EnumFontFamiliesEx (dc, &match_data->pattern,
860 } 1142 (FONTENUMPROC) add_font_entity_to_list,
1143 (LPARAM) match_data, 0);
861 } 1144 }
862 1145
863 release_frame_dc (f, dc); 1146 release_frame_dc (f, dc);
864} 1147}
865 1148
866static int 1149/* Return a list of all the scripts that the font supports. */
867unicode_range_for_char (c) 1150static Lisp_Object
868 unsigned c; 1151font_supported_scripts (FONTSIGNATURE * sig)
869{ 1152{
870 /* Is there really no Windows API function for this?!!! */ 1153 DWORD * subranges = sig->fsUsb;
871 if (c < 0x80) 1154 Lisp_Object supported = Qnil;
872 return 0; // Basic Latin 1155
873 else if (c < 0x100) 1156 /* Match a single subrange. SYM is set if bit N is set in subranges. */
874 return 1; // Latin-1 supplement 1157#define SUBRANGE(n,sym) \
875 else if (c < 0x180) 1158 if (subranges[(n) / 32] & (1 << ((n) % 32))) \
876 return 2; // Latin Extended-A 1159 supported = Fcons ((sym), supported)
877 else if (c < 0x250) 1160
878 return 3; // Latin Extended-B 1161 /* Match multiple subranges. SYM is set if any MASK bit is set in
879 else if (c < 0x2B0) 1162 subranges[0 - 3]. */
880 return 4; // IPA Extensions 1163#define MASK_ANY(mask0,mask1,mask2,mask3,sym) \
881 else if (c < 0x300) 1164 if ((subranges[0] & (mask0)) || (subranges[1] & (mask1)) \
882 return 5; // Spacing modifiers 1165 || (subranges[2] & (mask2)) || (subranges[3] & (mask3))) \
883 else if (c < 0x370) 1166 supported = Fcons ((sym), supported)
884 return 6; // Combining diacritical marks 1167
885 else if (c < 0x400) 1168 SUBRANGE (0, Qlatin); /* There are many others... */
886 return 7; // Greek and Coptic 1169
887 else if (c < 0x530) 1170 SUBRANGE (7, Qgreek);
888 return 9; // Cyrillic, Cyrillic supplementary 1171 SUBRANGE (8, Qcoptic);
889 else if (c < 0x590) 1172 SUBRANGE (9, Qcyrillic);
890 return 10; // Armenian 1173 SUBRANGE (10, Qarmenian);
891 else if (c < 0x600) 1174 SUBRANGE (11, Qhebrew);
892 return 11; // Hebrew 1175 SUBRANGE (13, Qarabic);
893 else if (c < 0x700) 1176 SUBRANGE (14, Qnko);
894 return 13; // Arabic 1177 SUBRANGE (15, Qdevanagari);
895 else if (c < 0x750) 1178 SUBRANGE (16, Qbengali);
896 return 71; // Syriac 1179 SUBRANGE (17, Qgurmukhi);
897 else if (c < 0x780) 1180 SUBRANGE (18, Qgujarati);
898 return 13; // Arabic supplement 1181 SUBRANGE (19, Qoriya);
899 else if (c < 0x7c0) 1182 SUBRANGE (20, Qtamil);
900 return 72; // Thaana 1183 SUBRANGE (21, Qtelugu);
901 else if (c < 0x800) 1184 SUBRANGE (22, Qkannada);
902 return 14; // N'Ko 1185 SUBRANGE (23, Qmalayalam);
903 else if (c < 0x900) 1186 SUBRANGE (24, Qthai);
904 return -1; // Unsupported range 1187 SUBRANGE (25, Qlao);
905 else if (c < 0x980) 1188 SUBRANGE (26, Qgeorgian);
906 return 15; // Devanagari 1189
907 else if (c < 0xA00) 1190 SUBRANGE (48, Qcjk_misc);
908 return 16; // Bengali 1191 SUBRANGE (51, Qbopomofo);
909 else if (c < 0xA80) 1192 SUBRANGE (54, Qkanbun); /* Is this right? */
910 return 17; // Gurmukhi 1193 SUBRANGE (56, Qhangul);
911 else if (c < 0xB00) 1194
912 return 18; // Gujarati 1195 SUBRANGE (59, Qhan); /* There are others, but this is the main one. */
913 else if (c < 0xB80) 1196 SUBRANGE (59, Qideographic_description); /* Windows lumps this in */
914 return 19; // Oriya 1197
915 else if (c < 0xC00) 1198 SUBRANGE (70, Qtibetan);
916 return 20; // Tamil 1199 SUBRANGE (71, Qsyriac);
917 else if (c < 0xC80) 1200 SUBRANGE (72, Qthaana);
918 return 21; // Telugu 1201 SUBRANGE (73, Qsinhala);
919 else if (c < 0xD00) 1202 SUBRANGE (74, Qmyanmar);
920 return 22; // Kannada 1203 SUBRANGE (75, Qethiopic);
921 else if (c < 0xD80) 1204 SUBRANGE (76, Qcherokee);
922 return 23; // Malayalam 1205 SUBRANGE (77, Qcanadian_aboriginal);
923 else if (c < 0xE00) 1206 SUBRANGE (78, Qogham);
924 return 73; // Sinhala 1207 SUBRANGE (79, Qrunic);
925 else if (c < 0xE80) 1208 SUBRANGE (80, Qkhmer);
926 return 24; // Thai 1209 SUBRANGE (81, Qmongolian);
927 else if (c < 0xF00) 1210 SUBRANGE (82, Qbraille);
928 return 25; // Lao 1211 SUBRANGE (83, Qyi);
929 else if (c < 0x1000) 1212
930 return 70; // Tibetan 1213 SUBRANGE (88, Qbyzantine_musical_symbol);
931 else if (c < 0x10A0) 1214 SUBRANGE (88, Qmusical_symbol); /* Windows doesn't distinguish these. */
932 return 74; // Myanmar 1215
933 else if (c < 0x1100) 1216 SUBRANGE (89, Qmathematical);
934 return 26; // Georgian 1217
935 else if (c < 0x1200) 1218 /* Match either katakana or hiragana for kana. */
936 return 28; // Hangul Jamo 1219 MASK_ANY (0, 0x00060000, 0, 0, Qkana);
937 else if (c < 0x13A0) 1220
938 return 75; // Ethiopic, Ethiopic Supplement 1221 /* There isn't really a main symbol range, so include symbol if any
939 else if (c < 0x1400) 1222 relevant range is set. */
940 return 76; // Cherokee 1223 MASK_ANY (0x8000000, 0x0000FFFF, 0, 0, Qsymbol);
941 else if (c < 0x1680) 1224
942 return 77; // Unified Canadian Aboriginal Syllabics 1225#undef SUBRANGE
943 else if (c < 0x16A0) 1226#undef MASK_ANY
944 return 78; // Ogham 1227
945 else if (c < 0x1700) 1228 return supported;
946 return 79; // Runic
947 else if (c < 0x1780)
948 return 84; // Tagalog, Hanunoo, Buhid, Tagbanwa
949 else if (c < 0x1800)
950 return 80; // Khmer
951 else if (c < 0x18B0)
952 return 81; // Mongolian
953 else if (c < 0x1900)
954 return -1; // Unsupported range
955 else if (c < 0x1950)
956 return 93; // Limbu
957 else if (c < 0x1980)
958 return 94; // Tai Le
959 else if (c < 0x19E0)
960 return 95; // New Tai Le
961 else if (c < 0x1A00)
962 return 80; // Khmer Symbols
963 else if (c < 0x1A20)
964 return 96; // Buginese
965 else if (c < 0x1B00)
966 return -1; // Unsupported range
967 else if (c < 0x1B80)
968 return 27; // Balinese
969 else if (c < 0x1D00)
970 return -1; // Unsupported range
971 else if (c < 0x1DC0)
972 return 4; // Phonetic extensions + supplement
973 else if (c < 0x1E00)
974 return 6; // Combining diacritical marks supplement
975 else if (c < 0x1F00)
976 return 29; // Latin Extended additional
977 else if (c < 0x2000)
978 return 30; // Greek Extended
979 else if (c < 0x2070)
980 return 31; // General Punctuation
981 else if (c < 0x20A0)
982 return 32; // Subscripts and Superscripts
983 else if (c < 0x20D0)
984 return 33; // Currency symbols
985 else if (c < 0x2100)
986 return 34; // Combining marks for diacriticals
987 else if (c < 0x2150)
988 return 35; // Letterlike symbols
989 else if (c < 0x2190)
990 return 36; // Number forms
991 else if (c < 0x2200)
992 return 37; // Arrows
993 else if (c < 0x2300)
994 return 38; // Mathematical operators
995 else if (c < 0x2400)
996 return 39; // Miscellaneous technical
997 else if (c < 0x2440)
998 return 40; // Control pictures
999 else if (c < 0x2460)
1000 return 41; // Optical character recognition
1001 else if (c < 0x2500)
1002 return 42; // Enclosed alphanumerics
1003 else if (c < 0x2580)
1004 return 43; // Box drawing
1005 else if (c < 0x25A0)
1006 return 44; // Block elements
1007 else if (c < 0x2600)
1008 return 45; // Geometric shapes
1009 else if (c < 0x2700)
1010 return 46; // Miscellaneous symbols
1011 else if (c < 0x27C0)
1012 return 47; // Dingbats
1013 else if (c < 0x27F0)
1014 return 38; // Misc Math symbols-A
1015 else if (c < 0x2800)
1016 return 37; // Supplemental arrows-A
1017 else if (c < 0x2900)
1018 return 82; // Braille patterns
1019 else if (c < 0x2980)
1020 return 37; // Supplemental arrows-B
1021 else if (c < 0x2B00)
1022 return 38; // Misc Math symbols-B, Supplemental Math operators
1023 else if (c < 0x2C00)
1024 return 37; // Misc Symbols and Arrows
1025 else if (c < 0x2C60)
1026 return 97; // Galgolitic
1027 else if (c < 0x2C80)
1028 return 29; // Latin Extended-C
1029 else if (c < 0x2D00)
1030 return 8; // Coptic
1031 else if (c < 0x2D30)
1032 return 26; // Georgian supplement
1033 else if (c < 0x2D80)
1034 return 98; // Tifinagh
1035 else if (c < 0x2DE0)
1036 return 75; // Ethiopic extended
1037 else if (c < 0x2E00)
1038 return -1; // Unsupported range
1039 else if (c < 0x2E80)
1040 return 31; // Supplemental punctuation
1041 else if (c < 0x2FE0)
1042 return 59; // CJK radicals supplement, Kangxi radicals
1043 else if (c < 0x2FF0)
1044 return -1; // Unsupported range
1045 else if (c < 0x3000)
1046 return 59; // Ideographic description characters
1047 else if (c < 0x3040)
1048 return 48; // CJK symbols and punctuation
1049 else if (c < 0x30A0)
1050 return 49; // Hiragana
1051 else if (c < 0x3100)
1052 return 50; // Katakana
1053 else if (c < 0x3130)
1054 return 51; // Bopomofo
1055 else if (c < 0x3190)
1056 return 52; // Hangul compatibility Jamo
1057 else if (c < 0x31A0)
1058 return 59; // Kanbun
1059 else if (c < 0x31C0)
1060 return 51; // Bopomofo extended
1061 else if (c < 0x31F0)
1062 return 61; // CJK strokes
1063 else if (c < 0x3200)
1064 return 50; // Katakana phonetic extensions
1065 else if (c < 0x3300)
1066 return 54; // CJK enclosed letters and months
1067 else if (c < 0x3400)
1068 return 55; // CJK compatibility
1069 else if (c < 0x4DC0)
1070 return 59; // CJK unified ideographs extension-A
1071 else if (c < 0x4E00)
1072 return 99; // Yijing Hexagram Symbols
1073 else if (c < 0xA000)
1074 return 59; // CJK unified ideographs
1075 else if (c < 0xA4D0)
1076 return 83; // Yi syllables, Yi radicals
1077 else if (c < 0xA700)
1078 return -1; // Unsupported range
1079 else if (c < 0xA720)
1080 return 5; // Modifier tone letters
1081 else if (c < 0xA800)
1082 return 29; // Latin Extended-D
1083 else if (c < 0xA830)
1084 return 100; // Syloti Nagri
1085 else if (c < 0xA840)
1086 return -1; // Unsupported range
1087 else if (c < 0xA880)
1088 return 53; // Phags-pa
1089 else if (c < 0xAC00)
1090 return -1; // Unsupported range
1091 else if (c < 0xD7A4)
1092 return 56; // Hangul syllables
1093 else if (c < 0xD800)
1094 return -1; // Unsupported range
1095 else if (c < 0xE000)
1096 return 57; // Surrogates
1097 else if (c < 0xF900)
1098 return 60; // Private use (plane 0)
1099 else if (c < 0xFB00)
1100 return 61; // CJK Compatibility ideographs
1101 else if (c < 0xFB50)
1102 return 62; // Alphabetic Presentation Forms
1103 else if (c < 0xFE00)
1104 return 63; // Arabic Presentation Forms-A
1105 else if (c < 0xFE10)
1106 return 91; // Variation selectors
1107 else if (c < 0xFE20)
1108 return 65; // Vertical forms
1109 else if (c < 0xFE30)
1110 return 64; // Combining half marks
1111 else if (c < 0xFE50)
1112 return 65; // CJK compatibility forms
1113 else if (c < 0xFE70)
1114 return 66; // Small form variants
1115 else if (c < 0xFEFF)
1116 return 67; // Arabic Presentation Forms-B
1117 else if (c == 0xFEFF)
1118 return -1; // Unsupported range
1119 else if (c < 0xFFF0)
1120 return 68; // Halfwidth and fullwidth forms
1121 else if (c <= 0xFFFF)
1122 return 69; // Specials
1123
1124 // If int is 64 bit, it could represent characters from 10000 up, but
1125 // any font that handles them should have the surrogate bit set (57).
1126 return 57;
1127} 1229}
1128 1230
1129 1231
@@ -1152,19 +1254,6 @@ struct font_driver w32font_driver =
1152 NULL /* otf_drive */ 1254 NULL /* otf_drive */
1153 }; 1255 };
1154 1256
1155/* Initialize the font subsystem for the environment on which
1156 Emacs is running. */
1157void
1158w32font_initialize ()
1159{
1160 /* Load functions that might not exist on older versions of Windows. */
1161 HANDLE gdi = LoadLibrary ("gdi32.dll");
1162
1163 get_glyph_indices_fn
1164 = (GETGLYPHINDICES) GetProcAddress (gdi, "GetGlyphIndicesW");
1165 get_text_extent_pointi_fn
1166 = (GETTEXTEXTENTPTI) GetProcAddress (gdi, "GetTextExtentPoint32W");
1167}
1168 1257
1169/* Initialize state that does not change between invocations. This is only 1258/* Initialize state that does not change between invocations. This is only
1170 called when Emacs is dumped. */ 1259 called when Emacs is dumped. */
@@ -1172,13 +1261,73 @@ void
1172syms_of_w32font () 1261syms_of_w32font ()
1173{ 1262{
1174 DEFSYM (Qw32, "w32"); 1263 DEFSYM (Qw32, "w32");
1175 DEFSYM (Qdecorative, "decorative"); 1264
1176 DEFSYM (Qmodern, "modern"); 1265 /* Generic font families. */
1177 DEFSYM (Qroman, "roman"); 1266 DEFSYM (Qmonospace, "monospace");
1267 DEFSYM (Qserif, "serif");
1268 DEFSYM (Qsans_serif, "sans-serif");
1178 DEFSYM (Qscript, "script"); 1269 DEFSYM (Qscript, "script");
1179 DEFSYM (Qswiss, "swiss"); 1270 DEFSYM (Qdecorative, "decorative");
1271 /* Aliases. */
1272 DEFSYM (Qsans__serif, "sans_serif");
1273 DEFSYM (Qsans, "sans");
1274 DEFSYM (Qmono, "mono");
1275
1276 /* Fake foundries. */
1277 DEFSYM (Qraster, "raster");
1278 DEFSYM (Qoutline, "outline");
1180 DEFSYM (Qunknown, "unknown"); 1279 DEFSYM (Qunknown, "unknown");
1181 DEFSYM (QCsubranges, ":subranges"); 1280
1281 /* Indexes for extra info. */
1282 DEFSYM (QCfamily, ":family");
1283
1284 /* Scripts */
1285 DEFSYM (Qlatin, "latin");
1286 DEFSYM (Qgreek, "greek");
1287 DEFSYM (Qcoptic, "coptic");
1288 DEFSYM (Qcyrillic, "cyrillic");
1289 DEFSYM (Qarmenian, "armenian");
1290 DEFSYM (Qhebrew, "hebrew");
1291 DEFSYM (Qarabic, "arabic");
1292 DEFSYM (Qsyriac, "syriac");
1293 DEFSYM (Qnko, "nko");
1294 DEFSYM (Qthaana, "thaana");
1295 DEFSYM (Qdevanagari, "devanagari");
1296 DEFSYM (Qbengali, "bengali");
1297 DEFSYM (Qgurmukhi, "gurmukhi");
1298 DEFSYM (Qgujarati, "gujarati");
1299 DEFSYM (Qoriya, "oriya");
1300 DEFSYM (Qtamil, "tamil");
1301 DEFSYM (Qtelugu, "telugu");
1302 DEFSYM (Qkannada, "kannada");
1303 DEFSYM (Qmalayalam, "malayalam");
1304 DEFSYM (Qsinhala, "sinhala");
1305 DEFSYM (Qthai, "thai");
1306 DEFSYM (Qlao, "lao");
1307 DEFSYM (Qtibetan, "tibetan");
1308 DEFSYM (Qmyanmar, "myanmar");
1309 DEFSYM (Qgeorgian, "georgian");
1310 DEFSYM (Qhangul, "hangul");
1311 DEFSYM (Qethiopic, "ethiopic");
1312 DEFSYM (Qcherokee, "cherokee");
1313 DEFSYM (Qcanadian_aboriginal, "canadian-aboriginal");
1314 DEFSYM (Qogham, "ogham");
1315 DEFSYM (Qrunic, "runic");
1316 DEFSYM (Qkhmer, "khmer");
1317 DEFSYM (Qmongolian, "mongolian");
1318 DEFSYM (Qsymbol, "symbol");
1319 DEFSYM (Qbraille, "braille");
1320 DEFSYM (Qhan, "han");
1321 DEFSYM (Qideographic_description, "ideographic-description");
1322 DEFSYM (Qcjk_misc, "cjk-misc");
1323 DEFSYM (Qkana, "kana");
1324 DEFSYM (Qbopomofo, "bopomofo");
1325 DEFSYM (Qkanbun, "kanbun");
1326 DEFSYM (Qyi, "yi");
1327 DEFSYM (Qbyzantine_musical_symbol, "byzantine-musical-symbol");
1328 DEFSYM (Qmusical_symbol, "musical-symbol");
1329 DEFSYM (Qmathematical, "mathematical");
1330
1182 w32font_driver.type = Qw32; 1331 w32font_driver.type = Qw32;
1183 register_font_driver (&w32font_driver, NULL); 1332 register_font_driver (&w32font_driver, NULL);
1184} 1333}