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