This source file includes following definitions.
- w32_load_unicows_or_gdi32
- get_outline_metrics_w
- get_text_metrics_w
- get_glyph_outline_w
- get_char_width_32_w
- memq_no_quit
- intern_font_name
- w32font_get_cache
- w32font_list
- w32font_match
- w32font_list_family
- w32font_open
- w32font_close
- w32font_has_char
- w32font_encode_char
- w32font_text_extents
- w32font_draw
- w32font_list_internal
- w32font_match_internal
- w32font_open_internal
- add_font_name_to_list
- w32_enumfont_pattern_entity
- w32_generic_family
- logfonts_match
- font_matches_spec
- w32font_coverage_ok
- check_face_name
- add_font_entity_to_list
- add_one_font_entity_to_list
- x_to_w32_charset
- registry_to_w32_charset
- w32_to_x_charset
- w32_registry
- w32_decode_weight
- w32_encode_weight
- w32_to_fc_weight
- fill_in_logfont
- list_all_matching_fonts
- lispy_antialias_type
- w32_antialias_type
- font_supported_scripts
- w32font_full_name
- logfont_to_fcname
- compute_metrics
- w32font_filter_properties
- syms_of_w32font
- syms_of_w32font_for_pdumper
- globals_of_w32font
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20 #include <windows.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <ctype.h>
24 #include <commdlg.h>
25
26 #include "lisp.h"
27 #include "w32term.h"
28 #include "frame.h"
29 #include "coding.h"
30 #include "w32font.h"
31 #ifdef WINDOWSNT
32 #include "w32common.h"
33 #include "w32.h"
34 #endif
35
36 #include "pdumper.h"
37
38
39
40
41
42 #ifndef CLEARTYPE_QUALITY
43 #define CLEARTYPE_QUALITY 5
44 #endif
45 #ifndef CLEARTYPE_NATURAL_QUALITY
46 #define CLEARTYPE_NATURAL_QUALITY 6
47 #endif
48
49
50
51 #ifndef VIETNAMESE_CHARSET
52 #define VIETNAMESE_CHARSET 163
53 #endif
54 #ifndef JOHAB_CHARSET
55 #define JOHAB_CHARSET 130
56 #endif
57
58 static void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object);
59
60 static BYTE w32_antialias_type (Lisp_Object);
61 static Lisp_Object lispy_antialias_type (BYTE);
62
63 static Lisp_Object font_supported_scripts (FONTSIGNATURE *);
64 static int w32font_full_name (LOGFONT *, Lisp_Object, int, char *, int);
65 static void compute_metrics (HDC, struct w32font_info *, unsigned int,
66 struct w32_metric_cache *);
67
68 static Lisp_Object w32_registry (LONG, DWORD);
69
70
71 static int CALLBACK ALIGN_STACK add_font_entity_to_list (ENUMLOGFONTEX *,
72 NEWTEXTMETRICEX *,
73 DWORD, LPARAM);
74 static int CALLBACK ALIGN_STACK add_one_font_entity_to_list (ENUMLOGFONTEX *,
75 NEWTEXTMETRICEX *,
76 DWORD, LPARAM);
77 static int CALLBACK ALIGN_STACK add_font_name_to_list (ENUMLOGFONTEX *,
78 NEWTEXTMETRICEX *,
79 DWORD, LPARAM);
80
81
82
83 struct font_callback_data
84 {
85
86
87
88 LOGFONT pattern;
89
90 Lisp_Object orig_font_spec;
91
92 Lisp_Object frame;
93
94 Lisp_Object known_fonts;
95
96 Lisp_Object list;
97
98 bool opentype_only;
99 };
100
101
102
103 static void list_all_matching_fonts (struct font_callback_data *);
104
105 #ifdef WINDOWSNT
106
107 static BOOL g_b_init_get_outline_metrics_w;
108 static BOOL g_b_init_get_text_metrics_w;
109 static BOOL g_b_init_get_glyph_outline_w;
110 static BOOL g_b_init_get_char_width_32_w;
111
112 typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
113 HDC hdc,
114 UINT cbData,
115 LPOUTLINETEXTMETRICW lpotmw);
116 typedef BOOL (WINAPI * GetTextMetricsW_Proc) (
117 HDC hdc,
118 LPTEXTMETRICW lptmw);
119 typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) (
120 HDC hdc,
121 UINT uChar,
122 UINT uFormat,
123 LPGLYPHMETRICS lpgm,
124 DWORD cbBuffer,
125 LPVOID lpvBuffer,
126 const MAT2 *lpmat2);
127 typedef BOOL (WINAPI * GetCharWidth32W_Proc) (
128 HDC hdc,
129 UINT uFirstChar,
130 UINT uLastChar,
131 LPINT lpBuffer);
132
133
134
135
136
137
138
139
140
141 static HMODULE
142 w32_load_unicows_or_gdi32 (void)
143 {
144 return maybe_load_unicows_dll ();
145 }
146
147
148
149
150 static UINT WINAPI
151 get_outline_metrics_w(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpotmw)
152 {
153 static GetOutlineTextMetricsW_Proc s_pfn_Get_Outline_Text_MetricsW = NULL;
154 HMODULE hm_unicows = NULL;
155 if (g_b_init_get_outline_metrics_w == 0)
156 {
157 g_b_init_get_outline_metrics_w = 1;
158 hm_unicows = w32_load_unicows_or_gdi32 ();
159 if (hm_unicows)
160 s_pfn_Get_Outline_Text_MetricsW = (GetOutlineTextMetricsW_Proc)
161 get_proc_addr (hm_unicows, "GetOutlineTextMetricsW");
162 }
163 eassert (s_pfn_Get_Outline_Text_MetricsW != NULL);
164 return s_pfn_Get_Outline_Text_MetricsW (hdc, cbData, lpotmw);
165 }
166
167 static BOOL WINAPI
168 get_text_metrics_w(HDC hdc, LPTEXTMETRICW lptmw)
169 {
170 static GetTextMetricsW_Proc s_pfn_Get_Text_MetricsW = NULL;
171 HMODULE hm_unicows = NULL;
172 if (g_b_init_get_text_metrics_w == 0)
173 {
174 g_b_init_get_text_metrics_w = 1;
175 hm_unicows = w32_load_unicows_or_gdi32 ();
176 if (hm_unicows)
177 s_pfn_Get_Text_MetricsW = (GetTextMetricsW_Proc)
178 get_proc_addr (hm_unicows, "GetTextMetricsW");
179 }
180 eassert (s_pfn_Get_Text_MetricsW != NULL);
181 return s_pfn_Get_Text_MetricsW (hdc, lptmw);
182 }
183
184 static DWORD WINAPI
185 get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
186 DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2)
187 {
188 static GetGlyphOutlineW_Proc s_pfn_Get_Glyph_OutlineW = NULL;
189 HMODULE hm_unicows = NULL;
190 if (g_b_init_get_glyph_outline_w == 0)
191 {
192 g_b_init_get_glyph_outline_w = 1;
193 hm_unicows = w32_load_unicows_or_gdi32 ();
194 if (hm_unicows)
195 s_pfn_Get_Glyph_OutlineW = (GetGlyphOutlineW_Proc)
196 get_proc_addr (hm_unicows, "GetGlyphOutlineW");
197 }
198 eassert (s_pfn_Get_Glyph_OutlineW != NULL);
199 return s_pfn_Get_Glyph_OutlineW (hdc, uChar, uFormat, lpgm, cbBuffer,
200 lpvBuffer, lpmat2);
201 }
202
203 static DWORD WINAPI
204 get_char_width_32_w (HDC hdc, UINT uFirstChar, UINT uLastChar, LPINT lpBuffer)
205 {
206 static GetCharWidth32W_Proc s_pfn_Get_Char_Width_32W = NULL;
207 HMODULE hm_unicows = NULL;
208 if (g_b_init_get_char_width_32_w == 0)
209 {
210 g_b_init_get_char_width_32_w = 1;
211 hm_unicows = w32_load_unicows_or_gdi32 ();
212 if (hm_unicows)
213 s_pfn_Get_Char_Width_32W = (GetCharWidth32W_Proc)
214 get_proc_addr (hm_unicows, "GetCharWidth32W");
215 }
216 eassert (s_pfn_Get_Char_Width_32W != NULL);
217 return s_pfn_Get_Char_Width_32W (hdc, uFirstChar, uLastChar, lpBuffer);
218 }
219
220 #else
221
222
223
224 #define get_outline_metrics_w(h,d,o) GetOutlineTextMetricsW(h,d,o)
225 #define get_text_metrics_w(h,t) GetTextMetricsW(h,t)
226 #define get_glyph_outline_w(h,uc,f,gm,b,v,m) \
227 GetGlyphOutlineW(h,uc,f,gm,b,v,m)
228 #define get_char_width_32_w(h,fc,lc,b) GetCharWidth32W(h,fc,lc,b)
229
230 #endif
231
232 static int
233 memq_no_quit (Lisp_Object elt, Lisp_Object list)
234 {
235 while (CONSP (list) && ! EQ (XCAR (list), elt))
236 list = XCDR (list);
237 return (CONSP (list));
238 }
239
240 Lisp_Object
241 intern_font_name (char * string)
242 {
243 Lisp_Object str = DECODE_SYSTEM (build_string (string));
244 ptrdiff_t len = SCHARS (str);
245 Lisp_Object obarray = check_obarray (Vobarray);
246 Lisp_Object tem = oblookup (obarray, SSDATA (str), len, len);
247
248 return SYMBOLP (tem) ? tem : intern_driver (str, obarray, tem);
249 }
250
251
252
253
254 Lisp_Object
255 w32font_get_cache (struct frame *f)
256 {
257 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
258
259 return (dpyinfo->name_list_element);
260 }
261
262
263
264
265
266 static Lisp_Object
267 w32font_list (struct frame *f, Lisp_Object font_spec)
268 {
269 Lisp_Object fonts = w32font_list_internal (f, font_spec, 0);
270 FONT_ADD_LOG ("w32font-list", font_spec, fonts);
271 return fonts;
272 }
273
274
275
276
277
278 static Lisp_Object
279 w32font_match (struct frame *f, Lisp_Object font_spec)
280 {
281 Lisp_Object entity = w32font_match_internal (f, font_spec, 0);
282 FONT_ADD_LOG ("w32font-match", font_spec, entity);
283 return entity;
284 }
285
286
287
288
289 static Lisp_Object
290 w32font_list_family (struct frame *f)
291 {
292 Lisp_Object list = Qnil;
293 Lisp_Object prev_quit = Vinhibit_quit;
294 LOGFONT font_match_pattern;
295 HDC dc;
296
297 memset (&font_match_pattern, 0, sizeof (font_match_pattern));
298 font_match_pattern.lfCharSet = DEFAULT_CHARSET;
299
300
301
302
303
304 Vinhibit_quit = Qt;
305 dc = get_frame_dc (f);
306
307 EnumFontFamiliesEx (dc, &font_match_pattern,
308 (FONTENUMPROC) add_font_name_to_list,
309 (LPARAM) &list, 0);
310 release_frame_dc (f, dc);
311 Vinhibit_quit = prev_quit;
312
313 return list;
314 }
315
316
317
318
319 static Lisp_Object
320 w32font_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
321 {
322 Lisp_Object font_object
323 = font_make_object (VECSIZE (struct w32font_info),
324 font_entity, pixel_size);
325 struct w32font_info *w32_font
326 = (struct w32font_info *) XFONT_OBJECT (font_object);
327
328 ASET (font_object, FONT_TYPE_INDEX, Qgdi);
329
330 if (!w32font_open_internal (f, font_entity, pixel_size, font_object))
331 {
332 return Qnil;
333 }
334
335
336 w32_font->glyph_idx = 0;
337
338 return font_object;
339 }
340
341
342 void
343 w32font_close (struct font *font)
344 {
345 struct w32font_info *w32_font = (struct w32font_info *) font;
346
347 if (w32_font->hfont)
348 {
349
350 DeleteObject (w32_font->hfont);
351 w32_font->hfont = NULL;
352
353
354 if (w32_font->cached_metrics)
355 {
356 int i;
357
358 for (i = 0; i < w32_font->n_cache_blocks; i++)
359 xfree (w32_font->cached_metrics[i]);
360 xfree (w32_font->cached_metrics);
361 w32_font->cached_metrics = NULL;
362 }
363 }
364 }
365
366
367
368
369
370
371 int
372 w32font_has_char (Lisp_Object entity, int c)
373 {
374
375
376
377 return -1;
378
379 #if 0
380 Lisp_Object supported_scripts, extra, script;
381 DWORD mask;
382
383 extra = AREF (entity, FONT_EXTRA_INDEX);
384 if (!CONSP (extra))
385 return -1;
386
387 supported_scripts = assq_no_quit (QCscript, extra);
388
389
390 if (!CONSP (supported_scripts))
391 return -1;
392
393 supported_scripts = XCDR (supported_scripts);
394
395 script = CHAR_TABLE_REF (Vchar_script_table, c);
396
397
398
399
400
401 if (NILP (script) || memq_no_quit (script, supported_scripts))
402 return -1;
403
404
405
406
407
408 return -1;
409 #endif
410 }
411
412
413
414
415
416
417
418
419
420 static unsigned
421 w32font_encode_char (struct font *font, int c)
422 {
423 struct w32font_info * w32_font = (struct w32font_info *)font;
424
425 if (c < w32_font->metrics.tmFirstChar
426 || c > w32_font->metrics.tmLastChar)
427 return FONT_INVALID_CODE;
428 else
429 return c;
430 }
431
432
433
434
435
436
437 void
438 w32font_text_extents (struct font *font, const unsigned *code,
439 int nglyphs, struct font_metrics *metrics)
440 {
441 int i;
442 HFONT old_font = NULL;
443 HDC dc = NULL;
444 struct frame * f UNINIT;
445 int total_width = 0;
446 WORD *wcode;
447 SIZE size;
448 bool first;
449 Lisp_Object prev_quit = Vinhibit_quit;
450
451 struct w32font_info *w32_font = (struct w32font_info *) font;
452
453 memset (metrics, 0, sizeof (struct font_metrics));
454
455 for (i = 0, first = true; i < nglyphs; i++)
456 {
457 struct w32_metric_cache *char_metric;
458 int block = *(code + i) / CACHE_BLOCKSIZE;
459 int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
460
461 if (block >= w32_font->n_cache_blocks)
462 {
463 if (!w32_font->cached_metrics)
464 w32_font->cached_metrics
465 = xmalloc ((block + 1)
466 * sizeof (struct w32_metric_cache *));
467 else
468 w32_font->cached_metrics
469 = xrealloc (w32_font->cached_metrics,
470 (block + 1)
471 * sizeof (struct w32_metric_cache *));
472 memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
473 ((block + 1 - w32_font->n_cache_blocks)
474 * sizeof (struct w32_metric_cache *)));
475 w32_font->n_cache_blocks = block + 1;
476 }
477
478 if (!w32_font->cached_metrics[block])
479 {
480 w32_font->cached_metrics[block]
481 = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
482 }
483
484 char_metric = w32_font->cached_metrics[block] + pos_in_block;
485
486 if (char_metric->status == W32METRIC_NO_ATTEMPT)
487 {
488 if (dc == NULL)
489 {
490
491
492
493
494 f = XFRAME (selected_frame);
495
496
497
498
499
500 prev_quit = Vinhibit_quit;
501 Vinhibit_quit = Qt;
502 dc = get_frame_dc (f);
503 old_font = SelectObject (dc, w32_font->hfont);
504 }
505 compute_metrics (dc, w32_font, *(code + i), char_metric);
506 }
507
508 if (char_metric->status == W32METRIC_SUCCESS)
509 {
510 if (first)
511 {
512 metrics->lbearing = char_metric->lbearing;
513 metrics->rbearing = char_metric->rbearing;
514 metrics->width = 0;
515 metrics->ascent = char_metric->ascent;
516 metrics->descent = char_metric->descent;
517 first = false;
518 }
519 if (metrics->lbearing > char_metric->lbearing)
520 metrics->lbearing = char_metric->lbearing;
521 if (metrics->rbearing < char_metric->rbearing)
522 metrics->rbearing = char_metric->rbearing;
523 metrics->width += char_metric->width;
524 if (metrics->ascent < char_metric->ascent)
525 metrics->ascent = char_metric->ascent;
526 if (metrics->descent < char_metric->descent)
527 metrics->descent = char_metric->descent;
528 }
529 else
530
531
532 break;
533 }
534
535 if (i == nglyphs)
536 {
537 if (dc != NULL)
538 {
539
540 SelectObject (dc, old_font);
541 release_frame_dc (f, dc);
542 Vinhibit_quit = prev_quit;
543 }
544 return;
545 }
546
547
548
549
550
551
552 eassume (0 <= nglyphs);
553 wcode = alloca (nglyphs * sizeof (WORD) * 2);
554 for (i = 0; i < nglyphs; i++)
555 {
556 if (code[i] < 0x10000)
557 wcode[i] = code[i];
558 else
559 {
560 DWORD surrogate = code[i] - 0x10000;
561
562
563 wcode[i++] = 0xD800 + ((surrogate >> 10) & 0x03FF);
564
565 wcode[i] = 0xDC00 + (surrogate & 0x03FF);
566
567
568 nglyphs++;
569 }
570 }
571
572 if (dc == NULL)
573 {
574
575
576
577
578 f = XFRAME (selected_frame);
579
580
581
582
583
584 prev_quit = Vinhibit_quit;
585 Vinhibit_quit = Qt;
586 dc = get_frame_dc (f);
587 old_font = SelectObject (dc, w32_font->hfont);
588 }
589
590 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
591 {
592 total_width = size.cx;
593 }
594
595
596
597 if (!total_width)
598 {
599 RECT rect;
600 rect.top = 0; rect.bottom = font->height; rect.left = 0; rect.right = 1;
601 DrawTextW (dc, wcode, nglyphs, &rect,
602 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
603 total_width = rect.right;
604 }
605
606
607 metrics->width = total_width - w32_font->metrics.tmOverhang;
608 metrics->lbearing = 0;
609 metrics->rbearing = total_width;
610 metrics->ascent = font->ascent;
611 metrics->descent = font->descent;
612
613
614 SelectObject (dc, old_font);
615 release_frame_dc (f, dc);
616 Vinhibit_quit = prev_quit;
617 }
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632 int
633 w32font_draw (struct glyph_string *s, int from, int to,
634 int x, int y, bool with_background)
635 {
636 UINT options;
637 HRGN orig_clip = NULL;
638 int len = to - from;
639 struct w32font_info *w32font = (struct w32font_info *) s->font;
640
641 options = w32font->glyph_idx;
642
643 if (s->num_clips > 0)
644 {
645 HRGN new_clip = CreateRectRgnIndirect (s->clip);
646
647
648 orig_clip = CreateRectRgn (0, 0, 0, 0);
649 if (!GetClipRgn (s->hdc, orig_clip))
650 {
651 DeleteObject (orig_clip);
652 orig_clip = NULL;
653 }
654
655 if (s->num_clips > 1)
656 {
657 HRGN clip2 = CreateRectRgnIndirect (s->clip + 1);
658
659 CombineRgn (new_clip, new_clip, clip2, RGN_OR);
660 DeleteObject (clip2);
661 }
662
663 SelectClipRgn (s->hdc, new_clip);
664 DeleteObject (new_clip);
665 }
666
667
668
669 SetBkMode (s->hdc, TRANSPARENT);
670 if (with_background)
671 {
672 HBRUSH brush;
673 RECT rect;
674 struct font *font = s->font;
675 int ascent = font->ascent, descent = font->descent;
676
677
678
679
680
681
682
683
684
685
686 if (s->first_glyph->type == GLYPHLESS_GLYPH
687 && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
688 || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
689 {
690 ascent =
691 s->first_glyph->slice.glyphless.lower_yoff
692 - s->first_glyph->slice.glyphless.upper_yoff;
693 descent = 0;
694 }
695 brush = CreateSolidBrush (s->gc->background);
696 rect.left = x;
697 rect.top = y - ascent;
698 rect.right = x + s->width;
699 rect.bottom = y + descent;
700 FillRect (s->hdc, &rect, brush);
701 DeleteObject (brush);
702 }
703
704 if (s->padding_p)
705 {
706 int i;
707
708 for (i = 0; i < len; i++)
709 {
710 WCHAR c = s->char2b[from + i] & 0xFFFF;
711 ExtTextOutW (s->hdc, x + i, y, options, NULL, &c, 1, NULL);
712 }
713 }
714 else
715 {
716
717
718
719 eassert (len <= SHRT_MAX);
720 WCHAR *chars = alloca (len * sizeof (WCHAR));
721 int j;
722 for (j = 0; j < len; j++)
723 chars[j] = s->char2b[from + j] & 0xFFFF;
724 ExtTextOutW (s->hdc, x, y, options, NULL, chars, len, NULL);
725 }
726
727
728 if (s->num_clips > 0)
729 SelectClipRgn (s->hdc, orig_clip);
730
731 if (orig_clip)
732 DeleteObject (orig_clip);
733
734 return len;
735 }
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815 Lisp_Object
816 w32font_list_internal (struct frame *f, Lisp_Object font_spec,
817 bool opentype_only)
818 {
819 struct font_callback_data match_data;
820 HDC dc;
821
822 match_data.orig_font_spec = font_spec;
823 match_data.list = Qnil;
824 XSETFRAME (match_data.frame, f);
825
826 memset (&match_data.pattern, 0, sizeof (LOGFONT));
827 fill_in_logfont (f, &match_data.pattern, font_spec);
828
829
830
831 if (match_data.pattern.lfCharSet == DEFAULT_CHARSET)
832 {
833 Lisp_Object spec_charset = AREF (font_spec, FONT_REGISTRY_INDEX);
834 if (!NILP (spec_charset)
835 && !EQ (spec_charset, Qiso10646_1)
836 && !EQ (spec_charset, Qunicode_bmp)
837 && !EQ (spec_charset, Qunicode_sip)
838 && !EQ (spec_charset, Qunknown)
839 && !EQ (spec_charset, Qascii_0))
840 return Qnil;
841 }
842
843 match_data.opentype_only = opentype_only;
844 if (opentype_only)
845 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
846 match_data.known_fonts = Qnil;
847 Lisp_Object vw32_non_USB_fonts = Fsymbol_value (Qw32_non_USB_fonts), val;
848 if (CONSP (vw32_non_USB_fonts))
849 {
850 Lisp_Object extra;
851 for (extra = AREF (font_spec, FONT_EXTRA_INDEX);
852 CONSP (extra); extra = XCDR (extra))
853 {
854 Lisp_Object tem = XCAR (extra);
855 if (CONSP (tem)
856 && EQ (XCAR (tem), QCscript)
857 && SYMBOLP (XCDR (tem))
858 && !NILP (val = assq_no_quit (XCDR (tem), vw32_non_USB_fonts)))
859 {
860 match_data.known_fonts = XCDR (val);
861 break;
862 }
863 }
864 }
865
866 if (match_data.pattern.lfFaceName[0] == '\0')
867 {
868
869
870 list_all_matching_fonts (&match_data);
871 }
872 else
873 {
874 Lisp_Object prev_quit = Vinhibit_quit;
875
876
877
878
879
880 Vinhibit_quit = Qt;
881 dc = get_frame_dc (f);
882
883 EnumFontFamiliesEx (dc, &match_data.pattern,
884 (FONTENUMPROC) add_font_entity_to_list,
885 (LPARAM) &match_data, 0);
886 release_frame_dc (f, dc);
887 Vinhibit_quit = prev_quit;
888 }
889
890 return match_data.list;
891 }
892
893
894
895
896 Lisp_Object
897 w32font_match_internal (struct frame *f, Lisp_Object font_spec,
898 bool opentype_only)
899 {
900 struct font_callback_data match_data;
901 HDC dc;
902
903 match_data.orig_font_spec = font_spec;
904 XSETFRAME (match_data.frame, f);
905 match_data.list = Qnil;
906
907 memset (&match_data.pattern, 0, sizeof (LOGFONT));
908 fill_in_logfont (f, &match_data.pattern, font_spec);
909
910 match_data.opentype_only = opentype_only;
911 if (opentype_only)
912 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
913
914 match_data.known_fonts = Qnil;
915 Lisp_Object vw32_non_USB_fonts = Fsymbol_value (Qw32_non_USB_fonts), val;
916 if (CONSP (vw32_non_USB_fonts))
917 {
918 Lisp_Object extra;
919 for (extra = AREF (font_spec, FONT_EXTRA_INDEX);
920 CONSP (extra); extra = XCDR (extra))
921 {
922 Lisp_Object tem = XCAR (extra);
923 if (CONSP (tem)
924 && EQ (XCAR (tem), QCscript)
925 && SYMBOLP (XCDR (tem))
926 && !NILP (val = assq_no_quit (XCDR (tem), vw32_non_USB_fonts)))
927 {
928 match_data.known_fonts = XCDR (val);
929 break;
930 }
931 }
932 }
933
934
935
936
937
938 Lisp_Object prev_quit = Vinhibit_quit;
939 Vinhibit_quit = Qt;
940 dc = get_frame_dc (f);
941
942 EnumFontFamiliesEx (dc, &match_data.pattern,
943 (FONTENUMPROC) add_one_font_entity_to_list,
944 (LPARAM) &match_data, 0);
945 release_frame_dc (f, dc);
946 Vinhibit_quit = prev_quit;
947
948 return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
949 }
950
951 int
952 w32font_open_internal (struct frame *f, Lisp_Object font_entity,
953 int pixel_size, Lisp_Object font_object)
954 {
955 int len, size;
956 LOGFONT logfont;
957 HDC dc;
958 HFONT hfont, old_font;
959 Lisp_Object val;
960 struct w32font_info *w32_font;
961 struct font * font;
962 OUTLINETEXTMETRICW* metrics = NULL;
963
964 w32_font = (struct w32font_info *) XFONT_OBJECT (font_object);
965 font = (struct font *) w32_font;
966
967 if (!font)
968 return 0;
969
970 memset (&logfont, 0, sizeof (logfont));
971 fill_in_logfont (f, &logfont, font_entity);
972
973
974
975 val = AREF (font_entity, FONT_FOUNDRY_INDEX);
976 if (!EQ (val, Qraster))
977 logfont.lfOutPrecision = OUT_TT_PRECIS;
978
979 size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX));
980 if (!size)
981 size = pixel_size;
982
983 logfont.lfHeight = -size;
984 hfont = CreateFontIndirect (&logfont);
985
986 if (hfont == NULL)
987 return 0;
988
989
990 dc = get_frame_dc (f);
991 old_font = SelectObject (dc, hfont);
992
993
994 len = get_outline_metrics_w (dc, 0, NULL);
995 if (len)
996 {
997 metrics = (OUTLINETEXTMETRICW *) alloca (len);
998 if (get_outline_metrics_w (dc, len, metrics))
999 memcpy (&w32_font->metrics, &metrics->otmTextMetrics,
1000 sizeof (TEXTMETRICW));
1001 else
1002 metrics = NULL;
1003 }
1004
1005 if (!metrics)
1006 get_text_metrics_w (dc, &w32_font->metrics);
1007
1008 w32_font->cached_metrics = NULL;
1009 w32_font->n_cache_blocks = 0;
1010
1011 SelectObject (dc, old_font);
1012 release_frame_dc (f, dc);
1013
1014 w32_font->hfont = hfont;
1015
1016 {
1017 char *name;
1018
1019
1020
1021 len = 96;
1022 name = alloca (len);
1023 while (name && w32font_full_name (&logfont, font_entity, pixel_size,
1024 name, len) < 0)
1025 {
1026 len += 32;
1027 name = alloca (len);
1028 }
1029 if (name)
1030 font->props[FONT_FULLNAME_INDEX]
1031 = DECODE_SYSTEM (build_string (name));
1032 else
1033 font->props[FONT_FULLNAME_INDEX]
1034 = DECODE_SYSTEM (build_string (logfont.lfFaceName));
1035 }
1036
1037 font->max_width = w32_font->metrics.tmMaxCharWidth;
1038
1039
1040
1041
1042
1043
1044 font->space_width = font->average_width = w32_font->metrics.tmAveCharWidth;
1045
1046 font->vertical_centering = 0;
1047 font->baseline_offset = 0;
1048 font->relative_compose = 0;
1049 font->default_ascent = w32_font->metrics.tmAscent;
1050 font->pixel_size = size;
1051 font->driver = &w32font_driver;
1052 font->encoding_charset = -1;
1053 font->repertory_charset = -1;
1054
1055 font->min_width = font->space_width;
1056 font->ascent = w32_font->metrics.tmAscent;
1057 font->descent = w32_font->metrics.tmDescent;
1058 font->height = font->ascent + font->descent;
1059
1060 if (metrics)
1061 {
1062 font->underline_thickness = metrics->otmsUnderscoreSize;
1063 font->underline_position = -metrics->otmsUnderscorePosition;
1064 }
1065 else
1066 {
1067 font->underline_thickness = 0;
1068 font->underline_position = -1;
1069 }
1070
1071
1072
1073
1074
1075 font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
1076
1077 return 1;
1078 }
1079
1080
1081
1082 static int CALLBACK ALIGN_STACK
1083 add_font_name_to_list (ENUMLOGFONTEX *logical_font,
1084 NEWTEXTMETRICEX *physical_font,
1085 DWORD font_type, LPARAM list_object)
1086 {
1087 Lisp_Object* list = (Lisp_Object *) list_object;
1088 Lisp_Object family;
1089
1090
1091 if (logical_font->elfLogFont.lfFaceName[0] == '@')
1092 return 1;
1093
1094 family = intern_font_name (logical_font->elfLogFont.lfFaceName);
1095 if (! memq_no_quit (family, *list))
1096 *list = Fcons (family, *list);
1097
1098 return 1;
1099 }
1100
1101 static int w32_decode_weight (int);
1102 static int w32_encode_weight (int);
1103
1104
1105 static Lisp_Object
1106 w32_enumfont_pattern_entity (Lisp_Object frame,
1107 ENUMLOGFONTEX *logical_font,
1108 NEWTEXTMETRICEX *physical_font,
1109 DWORD font_type,
1110 LOGFONT *requested_font,
1111 Lisp_Object backend)
1112 {
1113 Lisp_Object entity, tem;
1114 LOGFONT *lf = (LOGFONT*) logical_font;
1115 BYTE generic_type;
1116 DWORD full_type = physical_font->ntmTm.ntmFlags;
1117
1118 entity = font_make_entity ();
1119
1120 ASET (entity, FONT_TYPE_INDEX, backend);
1121 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet, font_type));
1122 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
1123
1124
1125
1126
1127 if (lf->lfOutPrecision == OUT_STRING_PRECIS)
1128 tem = Qraster;
1129 else if (lf->lfOutPrecision == OUT_STROKE_PRECIS)
1130 tem = Qoutline;
1131 else
1132 tem = Qunknown;
1133
1134 ASET (entity, FONT_FOUNDRY_INDEX, tem);
1135
1136
1137
1138 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0;
1139 if (generic_type == FF_DECORATIVE)
1140 tem = Qdecorative;
1141 else if (generic_type == FF_MODERN)
1142 tem = Qmono;
1143 else if (generic_type == FF_ROMAN)
1144 tem = Qserif;
1145 else if (generic_type == FF_SCRIPT)
1146 tem = Qscript;
1147 else if (generic_type == FF_SWISS)
1148 tem = Qsans;
1149 else
1150 tem = Qnil;
1151
1152 ASET (entity, FONT_ADSTYLE_INDEX, tem);
1153
1154 if (physical_font->ntmTm.tmPitchAndFamily & 0x01)
1155 ASET (entity, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_PROPORTIONAL));
1156 else
1157 ASET (entity, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_CHARCELL));
1158
1159 if (requested_font->lfQuality != DEFAULT_QUALITY)
1160 {
1161 font_put_extra (entity, QCantialias,
1162 lispy_antialias_type (requested_font->lfQuality));
1163 }
1164 ASET (entity, FONT_FAMILY_INDEX,
1165 intern_font_name (lf->lfFaceName));
1166
1167 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
1168 make_fixnum (w32_decode_weight (lf->lfWeight)));
1169 FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
1170 make_fixnum (lf->lfItalic ? 200 : 100));
1171
1172
1173 FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_fixnum (100));
1174
1175 if (font_type & RASTER_FONTTYPE)
1176 ASET (entity, FONT_SIZE_INDEX,
1177 make_fixnum (physical_font->ntmTm.tmHeight
1178 + physical_font->ntmTm.tmExternalLeading));
1179 else
1180 ASET (entity, FONT_SIZE_INDEX, make_fixnum (0));
1181
1182
1183
1184 if (font_type & TRUETYPE_FONTTYPE)
1185 {
1186 tem = font_supported_scripts (&physical_font->ntmFontSig);
1187 if (!NILP (tem))
1188 font_put_extra (entity, QCscript, tem);
1189 }
1190
1191
1192
1193
1194
1195
1196 if (EQ (backend, Quniscribe) && (full_type & NTMFLAGS_OPENTYPE))
1197 tem = Qopentype;
1198 else if (font_type & TRUETYPE_FONTTYPE)
1199 tem = intern ("truetype");
1200 else if (full_type & NTM_PS_OPENTYPE)
1201 tem = Qpostscript;
1202 else if (full_type & NTM_TYPE1)
1203 tem = intern ("type1");
1204 else if (font_type & RASTER_FONTTYPE)
1205 tem = intern ("w32bitmap");
1206 else
1207 tem = intern ("w32vector");
1208
1209 font_put_extra (entity, QCformat, tem);
1210
1211 return entity;
1212 }
1213
1214
1215
1216 static BYTE
1217 w32_generic_family (Lisp_Object name)
1218 {
1219
1220 if (EQ (name, Qmonospace) || EQ (name, Qmono))
1221 return FF_MODERN;
1222 else if (EQ (name, Qsans) || EQ (name, Qsans_serif) || EQ (name, Qsansserif))
1223 return FF_SWISS;
1224 else if (EQ (name, Qserif))
1225 return FF_ROMAN;
1226 else if (EQ (name, Qdecorative))
1227 return FF_DECORATIVE;
1228 else if (EQ (name, Qscript))
1229 return FF_SCRIPT;
1230 else
1231 return FF_DONTCARE;
1232 }
1233
1234 static int
1235 logfonts_match (LOGFONT *font, LOGFONT *pattern)
1236 {
1237
1238 if (pattern->lfHeight && font->lfOutPrecision == OUT_STRING_PRECIS
1239 && font->lfHeight != pattern->lfHeight)
1240 return 0;
1241
1242
1243 if (pattern->lfWeight
1244 && ((font->lfWeight < (pattern->lfWeight - 150))
1245 || font->lfWeight > (pattern->lfWeight + 150)))
1246 return 0;
1247
1248
1249
1250 return 1;
1251 }
1252
1253
1254 #define CSB_JAPANESE (1 << 17)
1255 #define CSB_KOREAN ((1 << 19) | (1 << 21))
1256 #define CSB_CHINESE ((1 << 18) | (1 << 20))
1257
1258 static int
1259 font_matches_spec (DWORD type, NEWTEXTMETRICEX *font,
1260 Lisp_Object spec, Lisp_Object backend,
1261 LOGFONT *logfont)
1262 {
1263 Lisp_Object extra, val;
1264
1265
1266
1267 {
1268 int slant = FONT_SLANT_NUMERIC (spec);
1269
1270 if (slant >= 0
1271 && ((slant > 150 && !font->ntmTm.tmItalic)
1272 || (slant <= 150 && font->ntmTm.tmItalic)))
1273 return 0;
1274 }
1275
1276
1277 val = AREF (spec, FONT_ADSTYLE_INDEX);
1278 if (!NILP (val))
1279 {
1280 BYTE family = w32_generic_family (val);
1281 if (family != FF_DONTCARE
1282 && family != (font->ntmTm.tmPitchAndFamily & 0xF0))
1283 return 0;
1284 }
1285
1286
1287 val = AREF (spec, FONT_SPACING_INDEX);
1288 if (FIXNUMP (val))
1289 {
1290 int spacing = XFIXNUM (val);
1291 int proportional = (spacing < FONT_SPACING_MONO);
1292
1293 if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
1294 || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
1295 return 0;
1296 }
1297
1298
1299 for (extra = AREF (spec, FONT_EXTRA_INDEX);
1300 CONSP (extra); extra = XCDR (extra))
1301 {
1302 Lisp_Object extra_entry;
1303 extra_entry = XCAR (extra);
1304 if (CONSP (extra_entry))
1305 {
1306 Lisp_Object key = XCAR (extra_entry);
1307
1308 val = XCDR (extra_entry);
1309 if (EQ (key, QCscript) && SYMBOLP (val))
1310 {
1311
1312
1313
1314
1315 if (type & TRUETYPE_FONTTYPE)
1316 {
1317 Lisp_Object support
1318 = font_supported_scripts (&font->ntmFontSig);
1319 if (! memq_no_quit (val, support))
1320 return 0;
1321
1322
1323
1324
1325
1326 if (EQ (val, Qkana)
1327 && (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET
1328 || !(font->ntmFontSig.fsCsb[0] & CSB_JAPANESE)))
1329 return 0;
1330 }
1331 else
1332 {
1333
1334
1335
1336
1337 if (EQ (val, Qlatin))
1338 {
1339
1340
1341
1342 if (font->ntmTm.tmCharSet != ANSI_CHARSET)
1343 return 0;
1344 }
1345 else if (EQ (val, Qsymbol))
1346 {
1347 if (font->ntmTm.tmCharSet != SYMBOL_CHARSET)
1348 return 0;
1349 }
1350 else if (EQ (val, Qcyrillic))
1351 {
1352 if (font->ntmTm.tmCharSet != RUSSIAN_CHARSET)
1353 return 0;
1354 }
1355 else if (EQ (val, Qgreek))
1356 {
1357 if (font->ntmTm.tmCharSet != GREEK_CHARSET)
1358 return 0;
1359 }
1360 else if (EQ (val, Qarabic))
1361 {
1362 if (font->ntmTm.tmCharSet != ARABIC_CHARSET)
1363 return 0;
1364 }
1365 else if (EQ (val, Qhebrew))
1366 {
1367 if (font->ntmTm.tmCharSet != HEBREW_CHARSET)
1368 return 0;
1369 }
1370 else if (EQ (val, Qthai))
1371 {
1372 if (font->ntmTm.tmCharSet != THAI_CHARSET)
1373 return 0;
1374 }
1375 else if (EQ (val, Qkana))
1376 {
1377 if (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
1378 return 0;
1379 }
1380 else if (EQ (val, Qbopomofo))
1381 {
1382 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET)
1383 return 0;
1384 }
1385 else if (EQ (val, Qhangul))
1386 {
1387 if (font->ntmTm.tmCharSet != HANGUL_CHARSET
1388 && font->ntmTm.tmCharSet != JOHAB_CHARSET)
1389 return 0;
1390 }
1391 else if (EQ (val, Qhan))
1392 {
1393 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET
1394 && font->ntmTm.tmCharSet != GB2312_CHARSET
1395 && font->ntmTm.tmCharSet != HANGUL_CHARSET
1396 && font->ntmTm.tmCharSet != JOHAB_CHARSET
1397 && font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
1398 return 0;
1399 }
1400 else
1401
1402
1403 return 0;
1404 }
1405 }
1406 else if (EQ (key, QClang) && SYMBOLP (val))
1407 {
1408
1409
1410
1411
1412
1413 if (EQ (val, Qja))
1414 {
1415 if (!(font->ntmFontSig.fsCsb[0] & CSB_JAPANESE))
1416 return 0;
1417 }
1418 else if (EQ (val, Qko))
1419 {
1420 if (!(font->ntmFontSig.fsCsb[0] & CSB_KOREAN))
1421 return 0;
1422 }
1423 else if (EQ (val, Qzh))
1424 {
1425 if (!(font->ntmFontSig.fsCsb[0] & CSB_CHINESE))
1426 return 0;
1427 }
1428 else
1429
1430
1431
1432
1433
1434
1435
1436 return 0;
1437 }
1438 else if (EQ (key, QCotf) && CONSP (val))
1439 {
1440
1441 if (EQ (backend, Quniscribe))
1442 {
1443 if (!uniscribe_check_otf (logfont, val))
1444 return 0;
1445 }
1446 else
1447 return 0;
1448 }
1449 }
1450 }
1451 return 1;
1452 }
1453
1454 static int
1455 w32font_coverage_ok (FONTSIGNATURE * coverage, BYTE charset)
1456 {
1457 DWORD subrange1 = coverage->fsUsb[1];
1458
1459 #define SUBRANGE1_HAN_MASK 0x08000000
1460 #define SUBRANGE1_HANGEUL_MASK 0x01000000
1461 #define SUBRANGE1_JAPANESE_MASK (0x00060000 | SUBRANGE1_HAN_MASK)
1462
1463 if (charset == GB2312_CHARSET || charset == CHINESEBIG5_CHARSET)
1464 {
1465 return (subrange1 & SUBRANGE1_HAN_MASK) == SUBRANGE1_HAN_MASK;
1466 }
1467 else if (charset == SHIFTJIS_CHARSET)
1468 {
1469 return (subrange1 & SUBRANGE1_JAPANESE_MASK) == SUBRANGE1_JAPANESE_MASK;
1470 }
1471 else if (charset == HANGEUL_CHARSET)
1472 {
1473 return (subrange1 & SUBRANGE1_HANGEUL_MASK) == SUBRANGE1_HANGEUL_MASK;
1474 }
1475
1476 return 1;
1477 }
1478
1479 #ifndef WINDOWSNT
1480 #define _strlwr strlwr
1481 #endif
1482
1483 static int
1484 check_face_name (LOGFONT *font, char *full_name)
1485 {
1486 char full_iname[LF_FULLFACESIZE+1];
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498 if (!xstrcasecmp (font->lfFaceName, "helvetica"))
1499 {
1500 strncpy (full_iname, full_name, LF_FULLFACESIZE);
1501 full_iname[LF_FULLFACESIZE] = 0;
1502 _strlwr (full_iname);
1503 return strstr ("helvetica", full_iname) != NULL;
1504 }
1505
1506 if (!xstrcasecmp (font->lfFaceName, "helv"))
1507 {
1508 strncpy (full_iname, full_name, LF_FULLFACESIZE);
1509 full_iname[LF_FULLFACESIZE] = 0;
1510 _strlwr (full_iname);
1511 return strstr ("helv", full_iname) != NULL;
1512 }
1513
1514
1515
1516 else if (!xstrcasecmp (font->lfFaceName, "times"))
1517 return xstrcasecmp (full_name, "times") == 0;
1518
1519 return 1;
1520 }
1521
1522
1523
1524
1525
1526
1527
1528 static int CALLBACK ALIGN_STACK
1529 add_font_entity_to_list (ENUMLOGFONTEX *logical_font,
1530 NEWTEXTMETRICEX *physical_font,
1531 DWORD font_type, LPARAM lParam)
1532 {
1533 struct font_callback_data *match_data
1534 = (struct font_callback_data *) lParam;
1535 Lisp_Object backend = match_data->opentype_only ? Quniscribe : Qgdi;
1536 Lisp_Object entity;
1537
1538 int is_unicode = physical_font->ntmFontSig.fsUsb[3]
1539 || physical_font->ntmFontSig.fsUsb[2]
1540 || physical_font->ntmFontSig.fsUsb[1]
1541 || physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff;
1542
1543
1544
1545 if (strncmp (logical_font->elfLogFont.lfFaceName,
1546 "Arial Unicode MS", 16) == 0)
1547 {
1548
1549 physical_font->ntmFontSig.fsUsb[0] &= 0xf7ffafef;
1550
1551 physical_font->ntmFontSig.fsUsb[1] &= 0xfbdfffff;
1552
1553 physical_font->ntmFontSig.fsUsb[2] |= 0x00000040;
1554 }
1555
1556
1557
1558
1559
1560 if (match_data->opentype_only
1561 && ((!(physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE)
1562 && !(font_type & TRUETYPE_FONTTYPE))
1563 || !is_unicode))
1564 return 1;
1565
1566
1567 if (!logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
1568 || !(font_matches_spec (font_type, physical_font,
1569 match_data->orig_font_spec, backend,
1570 &logical_font->elfLogFont)
1571 || (!NILP (match_data->known_fonts)
1572 && memq_no_quit
1573 (intern_font_name (logical_font->elfLogFont.lfFaceName),
1574 match_data->known_fonts)))
1575 || !w32font_coverage_ok (&physical_font->ntmFontSig,
1576 match_data->pattern.lfCharSet))
1577 return 1;
1578
1579
1580
1581
1582
1583
1584
1585
1586 if ((logical_font->elfLogFont.lfOutPrecision == OUT_STRING_PRECIS
1587 && !strstr ((char *)logical_font->elfFullName,
1588 logical_font->elfLogFont.lfFaceName))
1589
1590
1591 || (!check_face_name (&logical_font->elfLogFont,
1592 (char *)logical_font->elfFullName)))
1593 return 1;
1594
1595
1596 entity = w32_enumfont_pattern_entity (match_data->frame, logical_font,
1597 physical_font, font_type,
1598 &match_data->pattern,
1599 backend);
1600
1601 if (!NILP (entity))
1602 {
1603 Lisp_Object spec_charset = AREF (match_data->orig_font_spec,
1604 FONT_REGISTRY_INDEX);
1605
1606
1607 if (EQ (spec_charset, Qiso10646_1))
1608 {
1609 if (!is_unicode)
1610 return 1;
1611 }
1612
1613 else if (EQ (spec_charset, Qunicode_bmp))
1614 {
1615 if (!physical_font->ntmFontSig.fsUsb[3]
1616 && !(physical_font->ntmFontSig.fsUsb[2] & 0xFFFFFF9E)
1617 && !(physical_font->ntmFontSig.fsUsb[1] & 0xE81FFFFF)
1618 && !(physical_font->ntmFontSig.fsUsb[0] & 0x007F001F))
1619 return 1;
1620 }
1621
1622
1623
1624 else if (EQ (spec_charset, Qunicode_sip))
1625 {
1626 if (!(physical_font->ntmFontSig.fsUsb[1] & 0x02000000)
1627 || !(physical_font->ntmFontSig.fsUsb[1] & 0x28000000))
1628 return 1;
1629 }
1630
1631
1632
1633
1634 if (!NILP (spec_charset))
1635 {
1636
1637
1638
1639 if (logical_font->elfLogFont.lfCharSet == SHIFTJIS_CHARSET
1640 && !(physical_font->ntmFontSig.fsCsb[0] & CSB_JAPANESE))
1641 return 1;
1642 else
1643 ASET (entity, FONT_REGISTRY_INDEX, spec_charset);
1644 }
1645
1646
1647 else if (match_data->opentype_only)
1648 {
1649 if (logical_font->elfLogFont.lfCharSet == ANSI_CHARSET
1650 || logical_font->elfLogFont.lfCharSet == DEFAULT_CHARSET)
1651 ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1);
1652 else
1653 return 1;
1654 }
1655
1656
1657 match_data->list = Fcons (entity, match_data->list);
1658 }
1659 return 1;
1660 }
1661
1662
1663
1664 static int CALLBACK ALIGN_STACK
1665 add_one_font_entity_to_list (ENUMLOGFONTEX *logical_font,
1666 NEWTEXTMETRICEX *physical_font,
1667 DWORD font_type, LPARAM lParam)
1668 {
1669 struct font_callback_data *match_data
1670 = (struct font_callback_data *) lParam;
1671 add_font_entity_to_list (logical_font, physical_font, font_type, lParam);
1672
1673
1674 return NILP (match_data->list);
1675 }
1676
1677
1678 static LONG
1679 x_to_w32_charset (char * lpcs)
1680 {
1681 Lisp_Object this_entry, w32_charset;
1682 char *charset;
1683 int len = strlen (lpcs);
1684
1685
1686 if (strncmp (lpcs, "*-#", 3) == 0)
1687 return atoi (lpcs + 3);
1688
1689
1690 if (!strncmp (lpcs, "iso10646", 8))
1691 return DEFAULT_CHARSET;
1692
1693
1694 charset = alloca (len + 1);
1695 strcpy (charset, lpcs);
1696 lpcs = strchr (charset, '*');
1697 if (lpcs)
1698 *lpcs = '\0';
1699
1700
1701
1702
1703
1704 this_entry = Fassoc (build_string (charset), Vw32_charset_info_alist, Qnil);
1705
1706 if (NILP (this_entry))
1707 {
1708
1709 if (xstrcasecmp (charset, "iso8859-1") == 0)
1710 return ANSI_CHARSET;
1711 else
1712 return DEFAULT_CHARSET;
1713 }
1714
1715 w32_charset = Fcar (Fcdr (this_entry));
1716
1717
1718 if (EQ (w32_charset, Qw32_charset_ansi))
1719 return ANSI_CHARSET;
1720 if (EQ (w32_charset, Qw32_charset_symbol))
1721 return SYMBOL_CHARSET;
1722 if (EQ (w32_charset, Qw32_charset_shiftjis))
1723 return SHIFTJIS_CHARSET;
1724 if (EQ (w32_charset, Qw32_charset_hangeul))
1725 return HANGEUL_CHARSET;
1726 if (EQ (w32_charset, Qw32_charset_chinesebig5))
1727 return CHINESEBIG5_CHARSET;
1728 if (EQ (w32_charset, Qw32_charset_gb2312))
1729 return GB2312_CHARSET;
1730 if (EQ (w32_charset, Qw32_charset_oem))
1731 return OEM_CHARSET;
1732 if (EQ (w32_charset, Qw32_charset_johab))
1733 return JOHAB_CHARSET;
1734 if (EQ (w32_charset, Qw32_charset_easteurope))
1735 return EASTEUROPE_CHARSET;
1736 if (EQ (w32_charset, Qw32_charset_turkish))
1737 return TURKISH_CHARSET;
1738 if (EQ (w32_charset, Qw32_charset_baltic))
1739 return BALTIC_CHARSET;
1740 if (EQ (w32_charset, Qw32_charset_russian))
1741 return RUSSIAN_CHARSET;
1742 if (EQ (w32_charset, Qw32_charset_arabic))
1743 return ARABIC_CHARSET;
1744 if (EQ (w32_charset, Qw32_charset_greek))
1745 return GREEK_CHARSET;
1746 if (EQ (w32_charset, Qw32_charset_hebrew))
1747 return HEBREW_CHARSET;
1748 if (EQ (w32_charset, Qw32_charset_vietnamese))
1749 return VIETNAMESE_CHARSET;
1750 if (EQ (w32_charset, Qw32_charset_thai))
1751 return THAI_CHARSET;
1752 if (EQ (w32_charset, Qw32_charset_mac))
1753 return MAC_CHARSET;
1754
1755 return DEFAULT_CHARSET;
1756 }
1757
1758
1759
1760 static LONG
1761 registry_to_w32_charset (Lisp_Object charset)
1762 {
1763 if (EQ (charset, Qiso10646_1) || EQ (charset, Qunicode_bmp)
1764 || EQ (charset, Qunicode_sip))
1765 return DEFAULT_CHARSET;
1766 else if (EQ (charset, Qiso8859_1))
1767 return ANSI_CHARSET;
1768 else if (SYMBOLP (charset))
1769 return x_to_w32_charset (SSDATA (SYMBOL_NAME (charset)));
1770 else
1771 return DEFAULT_CHARSET;
1772 }
1773
1774
1775 static char *
1776 w32_to_x_charset (int fncharset, char *matching)
1777 {
1778 static char buf[32];
1779 Lisp_Object charset_type;
1780 int match_len = 0;
1781
1782 if (matching)
1783 {
1784
1785
1786 char *wildcard = strchr (matching, '*');
1787 if (wildcard)
1788 *wildcard = '\0';
1789 else if (strchr (matching, '-'))
1790 return matching;
1791
1792 match_len = strlen (matching);
1793 }
1794
1795 switch (fncharset)
1796 {
1797 case ANSI_CHARSET:
1798
1799
1800 if (NILP (Vw32_charset_info_alist))
1801 return (char *)"iso8859-1";
1802 charset_type = Qw32_charset_ansi;
1803 break;
1804 case DEFAULT_CHARSET:
1805 charset_type = Qw32_charset_default;
1806 break;
1807 case SYMBOL_CHARSET:
1808 charset_type = Qw32_charset_symbol;
1809 break;
1810 case SHIFTJIS_CHARSET:
1811 charset_type = Qw32_charset_shiftjis;
1812 break;
1813 case HANGEUL_CHARSET:
1814 charset_type = Qw32_charset_hangeul;
1815 break;
1816 case GB2312_CHARSET:
1817 charset_type = Qw32_charset_gb2312;
1818 break;
1819 case CHINESEBIG5_CHARSET:
1820 charset_type = Qw32_charset_chinesebig5;
1821 break;
1822 case OEM_CHARSET:
1823 charset_type = Qw32_charset_oem;
1824 break;
1825 case EASTEUROPE_CHARSET:
1826 charset_type = Qw32_charset_easteurope;
1827 break;
1828 case TURKISH_CHARSET:
1829 charset_type = Qw32_charset_turkish;
1830 break;
1831 case BALTIC_CHARSET:
1832 charset_type = Qw32_charset_baltic;
1833 break;
1834 case RUSSIAN_CHARSET:
1835 charset_type = Qw32_charset_russian;
1836 break;
1837 case ARABIC_CHARSET:
1838 charset_type = Qw32_charset_arabic;
1839 break;
1840 case GREEK_CHARSET:
1841 charset_type = Qw32_charset_greek;
1842 break;
1843 case HEBREW_CHARSET:
1844 charset_type = Qw32_charset_hebrew;
1845 break;
1846 case VIETNAMESE_CHARSET:
1847 charset_type = Qw32_charset_vietnamese;
1848 break;
1849 case THAI_CHARSET:
1850 charset_type = Qw32_charset_thai;
1851 break;
1852 case MAC_CHARSET:
1853 charset_type = Qw32_charset_mac;
1854 break;
1855 case JOHAB_CHARSET:
1856 charset_type = Qw32_charset_johab;
1857 break;
1858
1859 default:
1860
1861 sprintf (buf, "*-#%d", fncharset);
1862 return buf;
1863 }
1864
1865 {
1866 Lisp_Object rest;
1867 char * best_match = NULL;
1868 int matching_found = 0;
1869
1870
1871
1872
1873
1874
1875
1876
1877 for (rest = Vw32_charset_info_alist; CONSP (rest); rest = XCDR (rest))
1878 {
1879 char * x_charset;
1880 Lisp_Object w32_charset;
1881 Lisp_Object codepage;
1882
1883 Lisp_Object this_entry = XCAR (rest);
1884
1885
1886 if (!CONSP (this_entry) || !STRINGP (XCAR (this_entry))
1887 || !CONSP (XCDR (this_entry))
1888 || !SYMBOLP (XCAR (XCDR (this_entry))))
1889 continue;
1890
1891 x_charset = SSDATA (XCAR (this_entry));
1892 w32_charset = XCAR (XCDR (this_entry));
1893 codepage = XCDR (XCDR (this_entry));
1894
1895
1896
1897 if (EQ (w32_charset, charset_type)
1898 && (!FIXNUMP (codepage) || XFIXNUM (codepage) == CP_DEFAULT
1899 || IsValidCodePage (XFIXNUM (codepage))))
1900 {
1901
1902
1903 if (!best_match)
1904 {
1905 best_match = x_charset;
1906 if (matching && !strnicmp (x_charset, matching, match_len))
1907 matching_found = 1;
1908 }
1909
1910
1911 else if (matching_found
1912 && strnicmp (x_charset, matching, match_len))
1913 continue;
1914
1915
1916 else if (!matching_found && matching
1917 && !strnicmp (x_charset, matching, match_len))
1918 {
1919 best_match = x_charset;
1920 matching_found = 1;
1921 }
1922
1923
1924 else if ((!strchr (best_match, '-') && strchr (x_charset, '-'))
1925
1926
1927
1928 || (strnicmp (best_match, "iso", 3) != 0
1929 && strnicmp (x_charset, "iso", 3) == 0
1930 && strchr (x_charset, '-')))
1931 best_match = x_charset;
1932
1933
1934 else if (strnicmp (best_match, "iso8859-", 8) == 0
1935 && strnicmp (x_charset, "iso8859-", 8) == 0)
1936 {
1937 int best_enc = atoi (best_match + 8);
1938 int this_enc = atoi (x_charset + 8);
1939 if (this_enc > 0 && this_enc < best_enc)
1940 best_match = x_charset;
1941 }
1942 }
1943 }
1944
1945
1946 if (!best_match)
1947 {
1948 sprintf (buf, "*-#%d", fncharset);
1949 return buf;
1950 }
1951
1952 strncpy (buf, best_match, 31);
1953
1954 if (!strchr (best_match, '-'))
1955 {
1956 int pos = strlen (best_match);
1957
1958
1959
1960 if (pos > 29)
1961 pos = 29;
1962 strcpy (buf + pos, "-0");
1963 }
1964 buf[31] = '\0';
1965 return buf;
1966 }
1967 }
1968
1969 static Lisp_Object
1970 w32_registry (LONG w32_charset, DWORD font_type)
1971 {
1972 char *charset;
1973
1974
1975
1976 if (w32_charset == DEFAULT_CHARSET)
1977 return font_type == TRUETYPE_FONTTYPE ? Qiso10646_1 : Qunknown;
1978
1979 charset = w32_to_x_charset (w32_charset, NULL);
1980 return font_intern_prop (charset, strlen (charset), 1);
1981 }
1982
1983 static int
1984 w32_decode_weight (int fnweight)
1985 {
1986 if (fnweight >= FW_HEAVY) return 210;
1987 if (fnweight >= FW_EXTRABOLD) return 205;
1988 if (fnweight >= FW_BOLD) return 200;
1989 if (fnweight >= FW_SEMIBOLD) return 180;
1990 if (fnweight >= FW_MEDIUM) return 100;
1991 if (fnweight >= FW_NORMAL) return 80;
1992 if (fnweight >= FW_LIGHT) return 50;
1993 if (fnweight >= FW_EXTRALIGHT) return 40;
1994 if (fnweight >= FW_THIN) return 20;
1995 return 0;
1996 }
1997
1998 static int
1999 w32_encode_weight (int n)
2000 {
2001 if (n >= 210) return FW_HEAVY;
2002 if (n >= 205) return FW_EXTRABOLD;
2003 if (n >= 200) return FW_BOLD;
2004 if (n >= 180) return FW_SEMIBOLD;
2005 if (n >= 100) return FW_MEDIUM;
2006 if (n >= 80) return FW_NORMAL;
2007 if (n >= 50) return FW_LIGHT;
2008 if (n >= 40) return FW_EXTRALIGHT;
2009 if (n >= 20) return FW_THIN;
2010 return 0;
2011 }
2012
2013
2014
2015 static Lisp_Object
2016 w32_to_fc_weight (int n)
2017 {
2018 if (n >= FW_HEAVY) return Qblack;
2019 if (n >= FW_EXTRABOLD) return Qextra_bold;
2020 if (n >= FW_BOLD) return Qbold;
2021 if (n >= FW_SEMIBOLD) return Qsemi_bold;
2022 if (n >= FW_MEDIUM) return Qmedium;
2023 if (n >= FW_NORMAL) return Qnormal;
2024 if (n >= FW_LIGHT) return Qlight;
2025 if (n >= FW_EXTRALIGHT) return Qextra_light;
2026 return Qthin;
2027 }
2028
2029
2030 static void
2031 fill_in_logfont (struct frame *f, LOGFONT *logfont, Lisp_Object font_spec)
2032 {
2033 Lisp_Object tmp, extra;
2034 int dpi = FRAME_RES (f);
2035
2036 tmp = AREF (font_spec, FONT_DPI_INDEX);
2037 if (FIXNUMP (tmp))
2038 dpi = XFIXNUM (tmp);
2039 else if (FLOATP (tmp))
2040 dpi = (int) (XFLOAT_DATA (tmp) + 0.5);
2041
2042
2043 tmp = AREF (font_spec, FONT_SIZE_INDEX);
2044 if (FIXNUMP (tmp))
2045 logfont->lfHeight = -1 * XFIXNUM (tmp);
2046 else if (FLOATP (tmp))
2047 logfont->lfHeight = (int) (-1.0 * dpi * XFLOAT_DATA (tmp) / 72.27 + 0.5);
2048
2049
2050
2051
2052
2053
2054 tmp = AREF (font_spec, FONT_WEIGHT_INDEX);
2055 if (FIXNUMP (tmp))
2056 logfont->lfWeight = w32_encode_weight (FONT_WEIGHT_NUMERIC (font_spec));
2057
2058
2059 tmp = AREF (font_spec, FONT_SLANT_INDEX);
2060 if (FIXNUMP (tmp))
2061 {
2062 int slant = FONT_SLANT_NUMERIC (font_spec);
2063 logfont->lfItalic = slant > 150 ? 1 : 0;
2064 }
2065
2066
2067
2068
2069
2070
2071 tmp = AREF (font_spec, FONT_REGISTRY_INDEX);
2072 if (! NILP (tmp))
2073 logfont->lfCharSet = registry_to_w32_charset (tmp);
2074 else
2075 logfont->lfCharSet = DEFAULT_CHARSET;
2076
2077
2078
2079
2080
2081
2082 logfont->lfQuality = DEFAULT_QUALITY;
2083
2084
2085 logfont->lfPitchAndFamily = FF_DONTCARE | DEFAULT_PITCH;
2086
2087 tmp = AREF (font_spec, FONT_FAMILY_INDEX);
2088 if (! NILP (tmp))
2089 {
2090 logfont->lfPitchAndFamily = w32_generic_family (tmp) | DEFAULT_PITCH;
2091 if ((logfont->lfPitchAndFamily & 0xF0) != FF_DONTCARE)
2092 ;
2093
2094
2095 else if (SYMBOLP (tmp))
2096 {
2097 strncpy (logfont->lfFaceName,
2098 SSDATA (ENCODE_SYSTEM (SYMBOL_NAME (tmp))), LF_FACESIZE);
2099 logfont->lfFaceName[LF_FACESIZE-1] = '\0';
2100 }
2101 }
2102
2103 tmp = AREF (font_spec, FONT_ADSTYLE_INDEX);
2104 if (!NILP (tmp))
2105 {
2106
2107 BYTE family = w32_generic_family (tmp);
2108 if (family != FF_DONTCARE)
2109 logfont->lfPitchAndFamily = family | DEFAULT_PITCH;
2110 }
2111
2112
2113 tmp = AREF (font_spec, FONT_SPACING_INDEX);
2114 if (FIXNUMP (tmp))
2115 {
2116 int spacing = XFIXNUM (tmp);
2117 if (spacing < FONT_SPACING_MONO)
2118 logfont->lfPitchAndFamily
2119 = (logfont->lfPitchAndFamily & 0xF0) | VARIABLE_PITCH;
2120 else
2121 logfont->lfPitchAndFamily
2122 = (logfont->lfPitchAndFamily & 0xF0) | FIXED_PITCH;
2123 }
2124
2125
2126 for (extra = AREF (font_spec, FONT_EXTRA_INDEX);
2127 CONSP (extra); extra = XCDR (extra))
2128 {
2129 tmp = XCAR (extra);
2130 if (CONSP (tmp))
2131 {
2132 Lisp_Object key, val;
2133 key = XCAR (tmp), val = XCDR (tmp);
2134
2135
2136
2137
2138
2139
2140 if (EQ (key, QCscript)
2141 && logfont->lfCharSet == DEFAULT_CHARSET
2142 && SYMBOLP (val))
2143 {
2144 if (EQ (val, Qgreek))
2145 logfont->lfCharSet = GREEK_CHARSET;
2146 else if (EQ (val, Qhangul))
2147 logfont->lfCharSet = HANGUL_CHARSET;
2148 else if (EQ (val, Qkana) || EQ (val, Qkanbun))
2149 logfont->lfCharSet = SHIFTJIS_CHARSET;
2150 else if (EQ (val, Qbopomofo))
2151 logfont->lfCharSet = CHINESEBIG5_CHARSET;
2152
2153
2154
2155 else if (EQ (val, Qtibetan) || EQ (val, Qyi)
2156 || EQ (val, Qmongolian))
2157 logfont->lfCharSet = GB2312_CHARSET;
2158 else if (EQ (val, Qhebrew))
2159 logfont->lfCharSet = HEBREW_CHARSET;
2160 else if (EQ (val, Qarabic))
2161 logfont->lfCharSet = ARABIC_CHARSET;
2162 else if (EQ (val, Qthai))
2163 logfont->lfCharSet = THAI_CHARSET;
2164 }
2165 else if (EQ (key, QCantialias) && SYMBOLP (val))
2166 {
2167 logfont->lfQuality = w32_antialias_type (val);
2168 }
2169 }
2170 }
2171 }
2172
2173 static void
2174 list_all_matching_fonts (struct font_callback_data *match_data)
2175 {
2176 HDC dc;
2177 Lisp_Object families = w32font_list_family (XFRAME (match_data->frame));
2178 struct frame *f = XFRAME (match_data->frame);
2179
2180
2181
2182
2183
2184 Lisp_Object prev_quit = Vinhibit_quit;
2185 Vinhibit_quit = Qt;
2186 dc = get_frame_dc (f);
2187
2188 while (!NILP (families))
2189 {
2190
2191
2192
2193
2194 char *name;
2195 Lisp_Object family = CAR (families);
2196 families = CDR (families);
2197 if (NILP (family))
2198 continue;
2199 else if (SYMBOLP (family))
2200 name = SSDATA (ENCODE_SYSTEM (SYMBOL_NAME (family)));
2201 else
2202 continue;
2203
2204 strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE);
2205 match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0';
2206
2207 EnumFontFamiliesEx (dc, &match_data->pattern,
2208 (FONTENUMPROC) add_font_entity_to_list,
2209 (LPARAM) match_data, 0);
2210 }
2211
2212 release_frame_dc (f, dc);
2213 Vinhibit_quit = prev_quit;
2214 }
2215
2216 static Lisp_Object
2217 lispy_antialias_type (BYTE type)
2218 {
2219 Lisp_Object lispy;
2220
2221 switch (type)
2222 {
2223 case NONANTIALIASED_QUALITY:
2224 lispy = Qnone;
2225 break;
2226 case ANTIALIASED_QUALITY:
2227 lispy = Qstandard;
2228 break;
2229 case CLEARTYPE_QUALITY:
2230 lispy = Qsubpixel;
2231 break;
2232 case CLEARTYPE_NATURAL_QUALITY:
2233 lispy = Qnatural;
2234 break;
2235 default:
2236 lispy = Qnil;
2237 break;
2238 }
2239 return lispy;
2240 }
2241
2242
2243 static BYTE
2244 w32_antialias_type (Lisp_Object type)
2245 {
2246 if (EQ (type, Qnone))
2247 return NONANTIALIASED_QUALITY;
2248 else if (EQ (type, Qstandard))
2249 return ANTIALIASED_QUALITY;
2250 else if (EQ (type, Qsubpixel))
2251 return CLEARTYPE_QUALITY;
2252 else if (EQ (type, Qnatural))
2253 return CLEARTYPE_NATURAL_QUALITY;
2254 else
2255 return DEFAULT_QUALITY;
2256 }
2257
2258
2259 static Lisp_Object
2260 font_supported_scripts (FONTSIGNATURE * sig)
2261 {
2262 DWORD * subranges = sig->fsUsb;
2263 Lisp_Object supported = Qnil;
2264
2265
2266 #define SUBRANGE(n,sym) \
2267 if (subranges[(n) / 32] & (1U << ((n) % 32))) \
2268 supported = Fcons ((sym), supported)
2269
2270
2271
2272 #define MASK_ANY(mask0,mask1,mask2,mask3,sym) \
2273 if ((subranges[0] & (mask0)) || (subranges[1] & (mask1)) \
2274 || (subranges[2] & (mask2)) || (subranges[3] & (mask3))) \
2275 supported = Fcons ((sym), supported)
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288 MASK_ANY (0x2000000F, 0, 0, 0, Qlatin);
2289 SUBRANGE (4, Qphonetic);
2290
2291
2292 MASK_ANY (0x40000080, 0, 0, 0, Qgreek);
2293 SUBRANGE (8, Qcoptic);
2294 SUBRANGE (9, Qcyrillic);
2295 SUBRANGE (10, Qarmenian);
2296 SUBRANGE (11, Qhebrew);
2297
2298
2299
2300
2301
2302 SUBRANGE (12, Qvai);
2303 SUBRANGE (13, Qarabic);
2304 SUBRANGE (14, Qnko);
2305 SUBRANGE (15, Qdevanagari);
2306 SUBRANGE (16, Qbengali);
2307 SUBRANGE (17, Qgurmukhi);
2308 SUBRANGE (18, Qgujarati);
2309 SUBRANGE (19, Qoriya);
2310 SUBRANGE (20, Qtamil);
2311 SUBRANGE (21, Qtelugu);
2312 SUBRANGE (22, Qkannada);
2313 SUBRANGE (23, Qmalayalam);
2314 SUBRANGE (24, Qthai);
2315 SUBRANGE (25, Qlao);
2316 SUBRANGE (26, Qgeorgian);
2317 SUBRANGE (27, Qbalinese);
2318
2319
2320
2321
2322
2323 SUBRANGE (48, Qcjk_misc);
2324
2325 MASK_ANY (0, 0x00060000, 0, 0, Qkana);
2326 SUBRANGE (51, Qbopomofo);
2327
2328 SUBRANGE (53, Qphags_pa);
2329
2330 SUBRANGE (56, Qhangul);
2331
2332 SUBRANGE (58, Qphoenician);
2333 SUBRANGE (59, Qhan);
2334 SUBRANGE (59, Qideographic_description);
2335 SUBRANGE (59, Qkanbun);
2336
2337
2338
2339
2340
2341
2342
2343
2344 SUBRANGE (70, Qtibetan);
2345 SUBRANGE (71, Qsyriac);
2346 SUBRANGE (72, Qthaana);
2347 SUBRANGE (73, Qsinhala);
2348 SUBRANGE (74, Qburmese);
2349 SUBRANGE (75, Qethiopic);
2350 SUBRANGE (76, Qcherokee);
2351 SUBRANGE (77, Qcanadian_aboriginal);
2352 SUBRANGE (78, Qogham);
2353 SUBRANGE (79, Qrunic);
2354 SUBRANGE (80, Qkhmer);
2355 SUBRANGE (81, Qmongolian);
2356 SUBRANGE (82, Qbraille);
2357 SUBRANGE (83, Qyi);
2358 SUBRANGE (84, Qbuhid);
2359 SUBRANGE (84, Qhanunoo);
2360 SUBRANGE (84, Qtagalog);
2361 SUBRANGE (84, Qtagbanwa);
2362 SUBRANGE (85, Qold_italic);
2363 SUBRANGE (86, Qgothic);
2364 SUBRANGE (87, Qdeseret);
2365 SUBRANGE (88, Qbyzantine_musical_symbol);
2366 SUBRANGE (88, Qmusical_symbol);
2367 SUBRANGE (89, Qmathematical_bold);
2368 SUBRANGE (89, Qmathematical_italic);
2369 SUBRANGE (89, Qmathematical_bold_italic);
2370 SUBRANGE (89, Qmathematical_script);
2371 SUBRANGE (89, Qmathematical_bold_script);
2372 SUBRANGE (89, Qmathematical_fraktur);
2373 SUBRANGE (89, Qmathematical_double_struck);
2374 SUBRANGE (89, Qmathematical_bold_fraktur);
2375 SUBRANGE (89, Qmathematical_sans_serif);
2376 SUBRANGE (89, Qmathematical_sans_serif_bold);
2377 SUBRANGE (89, Qmathematical_sans_serif_italic);
2378 SUBRANGE (89, Qmathematical_sans_serif_bold_italic);
2379 SUBRANGE (89, Qmathematical_monospace);
2380
2381 SUBRANGE (93, Qlimbu);
2382 SUBRANGE (94, Qtai_le);
2383 SUBRANGE (95, Qtai_le);
2384 SUBRANGE (96, Qbuginese);
2385 SUBRANGE (97, Qglagolitic);
2386 SUBRANGE (98, Qtifinagh);
2387
2388 SUBRANGE (99, Qhan);
2389 SUBRANGE (100, Qsyloti_nagri);
2390 SUBRANGE (101, Qlinear_b);
2391 SUBRANGE (101, Qaegean_number);
2392 SUBRANGE (102, Qancient_greek_number);
2393 SUBRANGE (103, Qugaritic);
2394 SUBRANGE (104, Qold_persian);
2395 SUBRANGE (105, Qshavian);
2396 SUBRANGE (106, Qosmanya);
2397 SUBRANGE (107, Qcypriot);
2398 SUBRANGE (108, Qkharoshthi);
2399 SUBRANGE (109, Qtai_xuan_jing_symbol);
2400 SUBRANGE (110, Qcuneiform);
2401 SUBRANGE (111, Qcounting_rod_numeral);
2402 SUBRANGE (112, Qsundanese);
2403 SUBRANGE (113, Qlepcha);
2404 SUBRANGE (114, Qol_chiki);
2405 SUBRANGE (115, Qsaurashtra);
2406 SUBRANGE (116, Qkayah_li);
2407 SUBRANGE (117, Qrejang);
2408 SUBRANGE (118, Qcham);
2409 SUBRANGE (119, Qancient_symbol);
2410 SUBRANGE (120, Qphaistos_disc);
2411 SUBRANGE (121, Qlycian);
2412 SUBRANGE (121, Qcarian);
2413 SUBRANGE (121, Qlydian);
2414 SUBRANGE (122, Qdomino_tile);
2415 SUBRANGE (122, Qmahjong_tile);
2416
2417
2418
2419
2420 MASK_ANY (0x80000000, 0x0000FFFF, 0, 0, Qsymbol);
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466 #undef SUBRANGE
2467 #undef MASK_ANY
2468
2469 return supported;
2470 }
2471
2472
2473
2474
2475 static int
2476 w32font_full_name (LOGFONT * font, Lisp_Object font_obj,
2477 int pixel_size, char *name, int nbytes)
2478 {
2479 int len, height, outline;
2480 char *p;
2481 Lisp_Object antialiasing, weight = Qnil;
2482
2483 len = strlen (font->lfFaceName);
2484
2485 outline = EQ (AREF (font_obj, FONT_FOUNDRY_INDEX), Qoutline);
2486
2487
2488
2489 if (outline)
2490 len += 11;
2491 else
2492 len += 21;
2493
2494 if (font->lfItalic)
2495 len += 7;
2496
2497 if (font->lfWeight && font->lfWeight != FW_NORMAL)
2498 {
2499 weight = w32_to_fc_weight (font->lfWeight);
2500 len += 1 + SBYTES (SYMBOL_NAME (weight));
2501 }
2502
2503 antialiasing = lispy_antialias_type (font->lfQuality);
2504 if (! NILP (antialiasing))
2505 len += 11 + SBYTES (SYMBOL_NAME (antialiasing));
2506
2507
2508 if (len > nbytes)
2509 return -1;
2510
2511 p = name;
2512 p += sprintf (p, "%s", font->lfFaceName);
2513
2514 height = font->lfHeight ? eabs (font->lfHeight) : pixel_size;
2515
2516 if (height > 0)
2517 {
2518 if (outline)
2519 {
2520 double pointsize = height * 72.0 / one_w32_display_info.resy;
2521
2522
2523 pointsize = floor (pointsize * 2 + 0.5) / 2;
2524 p += sprintf (p, "-%1.1f", pointsize);
2525 }
2526 else
2527 p += sprintf (p, ":pixelsize=%d", height);
2528 }
2529
2530 if (SYMBOLP (weight) && ! NILP (weight))
2531 p += sprintf (p, ":%s", SDATA (SYMBOL_NAME (weight)));
2532
2533 if (font->lfItalic)
2534 p += sprintf (p, ":italic");
2535
2536 if (SYMBOLP (antialiasing) && ! NILP (antialiasing))
2537 p += sprintf (p, ":antialias=%s", SDATA (SYMBOL_NAME (antialiasing)));
2538
2539 return (p - name);
2540 }
2541
2542
2543
2544
2545
2546
2547
2548 static int
2549 logfont_to_fcname (LOGFONT* font, int pointsize, char *fcname, int size)
2550 {
2551 int len, height;
2552 char *p = fcname;
2553 Lisp_Object weight = Qnil;
2554
2555 len = strlen (font->lfFaceName) + 2;
2556 height = pointsize / 10;
2557 while (height /= 10)
2558 len++;
2559
2560 if (pointsize % 10)
2561 len += 2;
2562
2563 if (font->lfItalic)
2564 len += 7;
2565 if (font->lfWeight && font->lfWeight != FW_NORMAL)
2566 {
2567 weight = w32_to_fc_weight (font->lfWeight);
2568 len += SBYTES (SYMBOL_NAME (weight)) + 1;
2569 }
2570
2571 if (len > size)
2572 return -1;
2573
2574 p += sprintf (p, "%s-%d", font->lfFaceName, pointsize / 10);
2575 if (pointsize % 10)
2576 p += sprintf (p, ".%d", pointsize % 10);
2577
2578 if (SYMBOLP (weight) && !NILP (weight))
2579 p += sprintf (p, ":%s", SDATA (SYMBOL_NAME (weight)));
2580
2581 if (font->lfItalic)
2582 p += sprintf (p, ":italic");
2583
2584 return (p - fcname);
2585 }
2586
2587 static void
2588 compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
2589 struct w32_metric_cache *metrics)
2590 {
2591 GLYPHMETRICS gm;
2592 MAT2 transform;
2593 unsigned int options = GGO_METRICS;
2594 INT width;
2595
2596 if (w32_font->glyph_idx)
2597 options |= GGO_GLYPH_INDEX;
2598
2599 memset (&transform, 0, sizeof (transform));
2600 transform.eM11.value = 1;
2601 transform.eM22.value = 1;
2602
2603 if (get_glyph_outline_w (dc, code, options, &gm, 0, NULL, &transform)
2604 != GDI_ERROR)
2605 {
2606 metrics->lbearing = gm.gmptGlyphOrigin.x;
2607 metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
2608 metrics->width = gm.gmCellIncX;
2609 metrics->ascent = gm.gmptGlyphOrigin.y;
2610 metrics->descent = gm.gmBlackBoxY - gm.gmptGlyphOrigin.y;
2611 metrics->status = W32METRIC_SUCCESS;
2612 }
2613 else if (get_char_width_32_w (dc, code, code, &width) != 0)
2614 {
2615 metrics->lbearing = 0;
2616 metrics->rbearing = width;
2617 metrics->width = width;
2618 metrics->ascent = w32_font->font.ascent;
2619 metrics->descent = w32_font->font.descent;
2620 metrics->status = W32METRIC_SUCCESS;
2621 }
2622 else
2623 metrics->status = W32METRIC_FAIL;
2624 }
2625
2626 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
2627 doc:
2628
2629
2630
2631
2632 )
2633 (Lisp_Object frame, Lisp_Object exclude_proportional)
2634 {
2635 struct frame *f = decode_window_system_frame (frame);
2636 CHOOSEFONT cf;
2637 LOGFONT lf;
2638 TEXTMETRIC tm;
2639 HDC hdc;
2640 HANDLE oldobj;
2641 char buf[100];
2642
2643 memset (&cf, 0, sizeof (cf));
2644 memset (&lf, 0, sizeof (lf));
2645
2646 cf.lStructSize = sizeof (cf);
2647 cf.hwndOwner = FRAME_W32_WINDOW (f);
2648 cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS | CF_NOVERTFONTS;
2649
2650
2651
2652 if (!NILP (exclude_proportional))
2653 cf.Flags |= CF_FIXEDPITCHONLY;
2654
2655 cf.lpLogFont = &lf;
2656
2657
2658
2659 hdc = GetDC (FRAME_W32_WINDOW (f));
2660 oldobj = SelectObject (hdc, FONT_HANDLE (FRAME_FONT (f)));
2661 GetTextFace (hdc, LF_FACESIZE, lf.lfFaceName);
2662 if (GetTextMetrics (hdc, &tm))
2663 {
2664 lf.lfHeight = tm.tmInternalLeading - tm.tmHeight;
2665 lf.lfWeight = tm.tmWeight;
2666 lf.lfItalic = tm.tmItalic;
2667 lf.lfUnderline = tm.tmUnderlined;
2668 lf.lfStrikeOut = tm.tmStruckOut;
2669 lf.lfCharSet = tm.tmCharSet;
2670 cf.Flags |= CF_INITTOLOGFONTSTRUCT;
2671 }
2672 SelectObject (hdc, oldobj);
2673 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
2674
2675 {
2676 specpdl_ref count = SPECPDL_INDEX ();
2677 Lisp_Object value = Qnil;
2678
2679 w32_dialog_in_progress (Qt);
2680 specbind (Qinhibit_redisplay, Qt);
2681 record_unwind_protect (w32_dialog_in_progress, Qnil);
2682
2683 if (ChooseFont (&cf)
2684 && logfont_to_fcname (&lf, cf.iPointSize, buf, 100) >= 0)
2685 value = DECODE_SYSTEM (build_string (buf));
2686
2687 unbind_to (count, Qnil);
2688
2689 return value;
2690 }
2691 }
2692
2693 static const char *const w32font_booleans [] = {
2694 NULL,
2695 };
2696
2697 static const char *const w32font_non_booleans [] = {
2698 ":script",
2699 ":antialias",
2700 ":style",
2701 NULL,
2702 };
2703
2704 static void
2705 w32font_filter_properties (Lisp_Object font, Lisp_Object alist)
2706 {
2707 font_filter_properties (font, alist, w32font_booleans, w32font_non_booleans);
2708 }
2709
2710 struct font_driver w32font_driver =
2711 {
2712 LISPSYM_INITIALLY (Qgdi),
2713 false,
2714 w32font_get_cache,
2715 w32font_list,
2716 w32font_match,
2717 w32font_list_family,
2718 NULL,
2719 w32font_open,
2720 w32font_close,
2721 NULL,
2722 NULL,
2723 w32font_has_char,
2724 w32font_encode_char,
2725 w32font_text_extents,
2726 w32font_draw,
2727 NULL,
2728 NULL,
2729 NULL,
2730 NULL,
2731 NULL,
2732 NULL,
2733 NULL,
2734 NULL,
2735 NULL,
2736 NULL,
2737 w32font_filter_properties,
2738 NULL,
2739 };
2740
2741
2742
2743
2744
2745 static void syms_of_w32font_for_pdumper (void);
2746
2747 void
2748 syms_of_w32font (void)
2749 {
2750 DEFSYM (Qgdi, "gdi");
2751 DEFSYM (Quniscribe, "uniscribe");
2752 DEFSYM (Qharfbuzz, "harfbuzz");
2753 DEFSYM (QCformat, ":format");
2754
2755
2756 DEFSYM (Qmonospace, "monospace");
2757 DEFSYM (Qserif, "serif");
2758 DEFSYM (Qsansserif, "sansserif");
2759 DEFSYM (Qscript, "script");
2760 DEFSYM (Qdecorative, "decorative");
2761
2762 DEFSYM (Qsans_serif, "sans_serif");
2763 DEFSYM (Qsans, "sans");
2764 DEFSYM (Qmono, "mono");
2765
2766
2767 DEFSYM (Qraster, "raster");
2768 DEFSYM (Qoutline, "outline");
2769 DEFSYM (Qunknown, "unknown");
2770
2771
2772 DEFSYM (Qstandard, "standard");
2773 DEFSYM (Qsubpixel, "subpixel");
2774 DEFSYM (Qnatural, "natural");
2775
2776
2777 DEFSYM (Qzh, "zh");
2778
2779
2780 DEFSYM (Qlatin, "latin");
2781 DEFSYM (Qgreek, "greek");
2782 DEFSYM (Qcoptic, "coptic");
2783 DEFSYM (Qcyrillic, "cyrillic");
2784 DEFSYM (Qarmenian, "armenian");
2785 DEFSYM (Qhebrew, "hebrew");
2786 DEFSYM (Qvai, "vai");
2787 DEFSYM (Qarabic, "arabic");
2788 DEFSYM (Qsyriac, "syriac");
2789 DEFSYM (Qnko, "nko");
2790 DEFSYM (Qthaana, "thaana");
2791 DEFSYM (Qdevanagari, "devanagari");
2792 DEFSYM (Qbengali, "bengali");
2793 DEFSYM (Qgurmukhi, "gurmukhi");
2794 DEFSYM (Qgujarati, "gujarati");
2795 DEFSYM (Qoriya, "oriya");
2796 DEFSYM (Qtamil, "tamil");
2797 DEFSYM (Qtelugu, "telugu");
2798 DEFSYM (Qkannada, "kannada");
2799 DEFSYM (Qmalayalam, "malayalam");
2800 DEFSYM (Qsinhala, "sinhala");
2801 DEFSYM (Qthai, "thai");
2802 DEFSYM (Qlao, "lao");
2803 DEFSYM (Qtibetan, "tibetan");
2804 DEFSYM (Qburmese, "burmese");
2805 DEFSYM (Qgeorgian, "georgian");
2806 DEFSYM (Qhangul, "hangul");
2807 DEFSYM (Qethiopic, "ethiopic");
2808 DEFSYM (Qcherokee, "cherokee");
2809 DEFSYM (Qcanadian_aboriginal, "canadian-aboriginal");
2810 DEFSYM (Qogham, "ogham");
2811 DEFSYM (Qrunic, "runic");
2812 DEFSYM (Qkhmer, "khmer");
2813 DEFSYM (Qmongolian, "mongolian");
2814 DEFSYM (Qbraille, "braille");
2815 DEFSYM (Qhan, "han");
2816 DEFSYM (Qideographic_description, "ideographic-description");
2817 DEFSYM (Qcjk_misc, "cjk-misc");
2818 DEFSYM (Qkana, "kana");
2819 DEFSYM (Qbopomofo, "bopomofo");
2820 DEFSYM (Qkanbun, "kanbun");
2821 DEFSYM (Qyi, "yi");
2822 DEFSYM (Qbyzantine_musical_symbol, "byzantine-musical-symbol");
2823 DEFSYM (Qmusical_symbol, "musical-symbol");
2824 DEFSYM (Qmathematical_bold, "mathematical-bold");
2825 DEFSYM (Qmathematical_italic, "mathematical-italic");
2826 DEFSYM (Qmathematical_bold_italic, "mathematical-bold-italic");
2827 DEFSYM (Qmathematical_script, "mathematical-script");
2828 DEFSYM (Qmathematical_bold_script, "mathematical-bold-script");
2829 DEFSYM (Qmathematical_fraktur, "mathematical-fraktur");
2830 DEFSYM (Qmathematical_double_struck, "mathematical-double-struck");
2831 DEFSYM (Qmathematical_bold_fraktur, "mathematical-bold-fraktur");
2832 DEFSYM (Qmathematical_sans_serif, "mathematical-sans-serif");
2833 DEFSYM (Qmathematical_sans_serif_bold, "mathematical-sans-serif-bold");
2834 DEFSYM (Qmathematical_sans_serif_italic, "mathematical-sans-serif-italic");
2835 DEFSYM (Qmathematical_sans_serif_bold_italic, "mathematical-sans-serif-bold-italic");
2836 DEFSYM (Qmathematical_monospace, "mathematical-monospace");
2837 DEFSYM (Qcham, "cham");
2838 DEFSYM (Qphonetic, "phonetic");
2839 DEFSYM (Qbalinese, "balinese");
2840 DEFSYM (Qbuginese, "buginese");
2841 DEFSYM (Qbuhid, "buhid");
2842 DEFSYM (Qcuneiform, "cuneiform");
2843 DEFSYM (Qcypriot, "cypriot");
2844 DEFSYM (Qdeseret, "deseret");
2845 DEFSYM (Qglagolitic, "glagolitic");
2846 DEFSYM (Qgothic, "gothic");
2847 DEFSYM (Qhanunoo, "hanunoo");
2848 DEFSYM (Qkharoshthi, "kharoshthi");
2849 DEFSYM (Qlimbu, "limbu");
2850 DEFSYM (Qlinear_b, "linear-b");
2851 DEFSYM (Qaegean_number, "aegean-number");
2852 DEFSYM (Qold_italic, "old-italic");
2853 DEFSYM (Qold_persian, "old-persian");
2854 DEFSYM (Qosmanya, "osmanya");
2855 DEFSYM (Qphags_pa, "phags-pa");
2856 DEFSYM (Qphoenician, "phoenician");
2857 DEFSYM (Qshavian, "shavian");
2858 DEFSYM (Qsyloti_nagri, "syloti-nagri");
2859 DEFSYM (Qtagalog, "tagalog");
2860 DEFSYM (Qtagbanwa, "tagbanwa");
2861 DEFSYM (Qtai_le, "tai-le");
2862 DEFSYM (Qtifinagh, "tifinagh");
2863 DEFSYM (Qugaritic, "ugaritic");
2864 DEFSYM (Qlycian, "lycian");
2865 DEFSYM (Qcarian, "carian");
2866 DEFSYM (Qlydian, "lydian");
2867 DEFSYM (Qdomino_tile, "domino-tile");
2868 DEFSYM (Qmahjong_tile, "mahjong-tile");
2869 DEFSYM (Qtai_xuan_jing_symbol, "tai-xuan-jing-symbol");
2870 DEFSYM (Qcounting_rod_numeral, "counting-rod-numeral");
2871 DEFSYM (Qancient_symbol, "ancient-symbol");
2872 DEFSYM (Qphaistos_disc, "phaistos-disc");
2873 DEFSYM (Qancient_greek_number, "ancient-greek-number");
2874 DEFSYM (Qsundanese, "sundanese");
2875 DEFSYM (Qlepcha, "lepcha");
2876 DEFSYM (Qol_chiki, "ol-chiki");
2877 DEFSYM (Qsaurashtra, "saurashtra");
2878 DEFSYM (Qkayah_li, "kayah-li");
2879 DEFSYM (Qrejang, "rejang");
2880
2881
2882 DEFVAR_LISP ("w32-charset-info-alist",
2883 Vw32_charset_info_alist,
2884 doc:
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903 );
2904 Vw32_charset_info_alist = Qnil;
2905
2906 DEFSYM (Qw32_charset_ansi, "w32-charset-ansi");
2907 DEFSYM (Qw32_charset_symbol, "w32-charset-symbol");
2908 DEFSYM (Qw32_charset_default, "w32-charset-default");
2909 DEFSYM (Qw32_charset_shiftjis, "w32-charset-shiftjis");
2910 DEFSYM (Qw32_charset_hangeul, "w32-charset-hangeul");
2911 DEFSYM (Qw32_charset_chinesebig5, "w32-charset-chinesebig5");
2912 DEFSYM (Qw32_charset_gb2312, "w32-charset-gb2312");
2913 DEFSYM (Qw32_charset_oem, "w32-charset-oem");
2914 DEFSYM (Qw32_charset_johab, "w32-charset-johab");
2915 DEFSYM (Qw32_charset_easteurope, "w32-charset-easteurope");
2916 DEFSYM (Qw32_charset_turkish, "w32-charset-turkish");
2917 DEFSYM (Qw32_charset_baltic, "w32-charset-baltic");
2918 DEFSYM (Qw32_charset_russian, "w32-charset-russian");
2919 DEFSYM (Qw32_charset_arabic, "w32-charset-arabic");
2920 DEFSYM (Qw32_charset_greek, "w32-charset-greek");
2921 DEFSYM (Qw32_charset_hebrew, "w32-charset-hebrew");
2922 DEFSYM (Qw32_charset_vietnamese, "w32-charset-vietnamese");
2923 DEFSYM (Qw32_charset_thai, "w32-charset-thai");
2924 DEFSYM (Qw32_charset_mac, "w32-charset-mac");
2925 DEFSYM (Qw32_non_USB_fonts, "w32-non-USB-fonts");
2926
2927 defsubr (&Sx_select_font);
2928
2929 pdumper_do_now_and_after_load (syms_of_w32font_for_pdumper);
2930 }
2931
2932 static void
2933 syms_of_w32font_for_pdumper (void)
2934 {
2935 register_font_driver (&w32font_driver, NULL);
2936 }
2937
2938 void
2939 globals_of_w32font (void)
2940 {
2941 #ifdef WINDOWSNT
2942 g_b_init_get_outline_metrics_w = 0;
2943 g_b_init_get_text_metrics_w = 0;
2944 g_b_init_get_glyph_outline_w = 0;
2945 g_b_init_get_char_width_32_w = 0;
2946 #endif
2947 }