90869
|
1 /* Font backend for the Microsoft W32 API.
|
91447
|
2 Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
90869
|
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
|
91447
|
8 the Free Software Foundation; either version 3, or (at your option)
|
90869
|
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
|
92472
|
21 #ifdef USE_FONT_BACKEND
|
|
22
|
90869
|
23 #include <config.h>
|
|
24 #include <windows.h>
|
92413
|
25 #include <math.h>
|
90869
|
26
|
|
27 #include "lisp.h"
|
|
28 #include "w32term.h"
|
|
29 #include "frame.h"
|
|
30 #include "dispextern.h"
|
|
31 #include "character.h"
|
|
32 #include "charset.h"
|
|
33 #include "fontset.h"
|
|
34 #include "font.h"
|
91208
|
35 #include "w32font.h"
|
90869
|
36
|
91124
|
37 /* Cleartype available on Windows XP, cleartype_natural from XP SP1.
|
|
38 The latter does not try to fit cleartype smoothed fonts into the
|
|
39 same bounding box as the non-antialiased version of the font.
|
|
40 */
|
|
41 #ifndef CLEARTYPE_QUALITY
|
|
42 #define CLEARTYPE_QUALITY 5
|
|
43 #endif
|
|
44 #ifndef CLEARTYPE_NATURAL_QUALITY
|
|
45 #define CLEARTYPE_NATURAL_QUALITY 6
|
|
46 #endif
|
|
47
|
90869
|
48 extern struct font_driver w32font_driver;
|
|
49
|
91124
|
50 Lisp_Object Qgdi;
|
92409
|
51 Lisp_Object Quniscribe;
|
|
52 static Lisp_Object QCformat;
|
91260
|
53 static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif;
|
|
54 static Lisp_Object Qserif, Qscript, Qdecorative;
|
|
55 static Lisp_Object Qraster, Qoutline, Qunknown;
|
90906
|
56
|
91124
|
57 /* antialiasing */
|
|
58 extern Lisp_Object QCantialias; /* defined in font.c */
|
|
59 extern Lisp_Object Qnone; /* reuse from w32fns.c */
|
|
60 static Lisp_Object Qstandard, Qsubpixel, Qnatural;
|
|
61
|
90906
|
62 /* scripts */
|
|
63 static Lisp_Object Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
|
|
64 static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali;
|
|
65 static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu;
|
|
66 static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao;
|
|
67 static Lisp_Object Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic;
|
|
68 static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic;
|
|
69 static Lisp_Object Qkhmer, Qmongolian, Qsymbol, Qbraille, Qhan;
|
|
70 static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo;
|
|
71 static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol;
|
|
72 static Lisp_Object Qmusical_symbol, Qmathematical;
|
|
73
|
|
74 /* Font spacing symbols - defined in font.c. */
|
|
75 extern Lisp_Object Qc, Qp, Qm;
|
90869
|
76
|
|
77 static void fill_in_logfont P_ ((FRAME_PTR f, LOGFONT *logfont,
|
|
78 Lisp_Object font_spec));
|
|
79
|
91124
|
80 static BYTE w32_antialias_type P_ ((Lisp_Object type));
|
|
81 static Lisp_Object lispy_antialias_type P_ ((BYTE type));
|
|
82
|
90906
|
83 static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE * sig));
|
92390
|
84 static int w32font_full_name P_ ((LOGFONT * font, Lisp_Object font_obj,
|
|
85 int pixel_size, char *name, int nbytes));
|
92411
|
86 static void recompute_cached_metrics P_ ((HDC dc, struct w32font_info * font));
|
90869
|
87
|
92539
|
88 static Lisp_Object w32_registry P_ ((LONG w32_charset, DWORD font_type));
|
90869
|
89
|
|
90 /* EnumFontFamiliesEx callbacks. */
|
|
91 static int CALLBACK add_font_entity_to_list P_ ((ENUMLOGFONTEX *,
|
|
92 NEWTEXTMETRICEX *,
|
|
93 DWORD, LPARAM));
|
|
94 static int CALLBACK add_one_font_entity_to_list P_ ((ENUMLOGFONTEX *,
|
|
95 NEWTEXTMETRICEX *,
|
|
96 DWORD, LPARAM));
|
|
97 static int CALLBACK add_font_name_to_list P_ ((ENUMLOGFONTEX *,
|
|
98 NEWTEXTMETRICEX *,
|
|
99 DWORD, LPARAM));
|
|
100
|
90906
|
101 /* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
|
|
102 of what we really want. */
|
|
103 struct font_callback_data
|
|
104 {
|
|
105 /* The logfont we are matching against. EnumFontFamiliesEx only matches
|
|
106 face name and charset, so we need to manually match everything else
|
|
107 in the callback function. */
|
|
108 LOGFONT pattern;
|
|
109 /* The original font spec or entity. */
|
|
110 Lisp_Object orig_font_spec;
|
|
111 /* The frame the font is being loaded on. */
|
|
112 Lisp_Object frame;
|
|
113 /* The list to add matches to. */
|
|
114 Lisp_Object list;
|
91208
|
115 /* Whether to match only opentype fonts. */
|
|
116 int opentype_only;
|
90906
|
117 };
|
|
118
|
|
119 /* Handles the problem that EnumFontFamiliesEx will not return all
|
|
120 style variations if the font name is not specified. */
|
91182
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
121 static void list_all_matching_fonts P_ ((struct font_callback_data *match));
|
90906
|
122
|
92409
|
123 /* From old font code in w32fns.c */
|
|
124 char * w32_to_x_charset P_ ((int charset, char * matching));
|
90906
|
125
|
90869
|
126
|
|
127 static int
|
|
128 memq_no_quit (elt, list)
|
|
129 Lisp_Object elt, list;
|
|
130 {
|
|
131 while (CONSP (list) && ! EQ (XCAR (list), elt))
|
|
132 list = XCDR (list);
|
|
133 return (CONSP (list));
|
|
134 }
|
|
135
|
|
136 /* w32 implementation of get_cache for font backend.
|
|
137 Return a cache of font-entities on FRAME. The cache must be a
|
|
138 cons whose cdr part is the actual cache area. */
|
91208
|
139 Lisp_Object
|
91246
|
140 w32font_get_cache (f)
|
|
141 FRAME_PTR f;
|
90869
|
142 {
|
91246
|
143 struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
|
90869
|
144
|
|
145 return (dpyinfo->name_list_element);
|
|
146 }
|
|
147
|
|
148 /* w32 implementation of list for font backend.
|
|
149 List fonts exactly matching with FONT_SPEC on FRAME. The value
|
|
150 is a vector of font-entities. This is the sole API that
|
|
151 allocates font-entities. */
|
90889
|
152 static Lisp_Object
|
|
153 w32font_list (frame, font_spec)
|
|
154 Lisp_Object frame, font_spec;
|
90869
|
155 {
|
91208
|
156 return w32font_list_internal (frame, font_spec, 0);
|
90869
|
157 }
|
|
158
|
|
159 /* w32 implementation of match for font backend.
|
|
160 Return a font entity most closely matching with FONT_SPEC on
|
|
161 FRAME. The closeness is detemined by the font backend, thus
|
|
162 `face-font-selection-order' is ignored here. */
|
90889
|
163 static Lisp_Object
|
|
164 w32font_match (frame, font_spec)
|
|
165 Lisp_Object frame, font_spec;
|
90869
|
166 {
|
91208
|
167 return w32font_match_internal (frame, font_spec, 0);
|
90869
|
168 }
|
|
169
|
|
170 /* w32 implementation of list_family for font backend.
|
|
171 List available families. The value is a list of family names
|
|
172 (symbols). */
|
90889
|
173 static Lisp_Object
|
|
174 w32font_list_family (frame)
|
|
175 Lisp_Object frame;
|
90869
|
176 {
|
|
177 Lisp_Object list = Qnil;
|
|
178 LOGFONT font_match_pattern;
|
|
179 HDC dc;
|
|
180 FRAME_PTR f = XFRAME (frame);
|
|
181
|
|
182 bzero (&font_match_pattern, sizeof (font_match_pattern));
|
|
183
|
|
184 dc = get_frame_dc (f);
|
|
185
|
|
186 EnumFontFamiliesEx (dc, &font_match_pattern,
|
|
187 (FONTENUMPROC) add_font_name_to_list,
|
|
188 (LPARAM) &list, 0);
|
|
189 release_frame_dc (f, dc);
|
|
190
|
|
191 return list;
|
|
192 }
|
|
193
|
|
194 /* w32 implementation of open for font backend.
|
|
195 Open a font specified by FONT_ENTITY on frame F.
|
|
196 If the font is scalable, open it with PIXEL_SIZE. */
|
91211
|
197 static struct font *
|
90889
|
198 w32font_open (f, font_entity, pixel_size)
|
|
199 FRAME_PTR f;
|
|
200 Lisp_Object font_entity;
|
|
201 int pixel_size;
|
90869
|
202 {
|
|
203 struct w32font_info *w32_font = xmalloc (sizeof (struct w32font_info));
|
|
204
|
91211
|
205 if (w32_font == NULL)
|
90869
|
206 return NULL;
|
|
207
|
91211
|
208 if (!w32font_open_internal (f, font_entity, pixel_size, w32_font))
|
90869
|
209 {
|
|
210 xfree (w32_font);
|
|
211 return NULL;
|
|
212 }
|
|
213
|
91211
|
214 return (struct font *) w32_font;
|
90869
|
215 }
|
|
216
|
|
217 /* w32 implementation of close for font_backend.
|
|
218 Close FONT on frame F. */
|
91208
|
219 void
|
90889
|
220 w32font_close (f, font)
|
|
221 FRAME_PTR f;
|
|
222 struct font *font;
|
90869
|
223 {
|
|
224 if (font->font.font)
|
|
225 {
|
|
226 W32FontStruct *old_w32_font = (W32FontStruct *)font->font.font;
|
90933
|
227 DeleteObject (old_w32_font->hfont);
|
90869
|
228 xfree (old_w32_font);
|
|
229 font->font.font = 0;
|
|
230 }
|
|
231
|
91496
|
232 if (font->font.full_name && font->font.full_name != font->font.name)
|
|
233 xfree (font->font.full_name);
|
|
234
|
90869
|
235 if (font->font.name)
|
|
236 xfree (font->font.name);
|
91496
|
237
|
90869
|
238 xfree (font);
|
|
239 }
|
|
240
|
|
241 /* w32 implementation of has_char for font backend.
|
|
242 Optional.
|
|
243 If FONT_ENTITY has a glyph for character C (Unicode code point),
|
|
244 return 1. If not, return 0. If a font must be opened to check
|
|
245 it, return -1. */
|
91208
|
246 int
|
90889
|
247 w32font_has_char (entity, c)
|
|
248 Lisp_Object entity;
|
|
249 int c;
|
90869
|
250 {
|
90906
|
251 Lisp_Object supported_scripts, extra, script;
|
90869
|
252 DWORD mask;
|
|
253
|
90887
|
254 extra = AREF (entity, FONT_EXTRA_INDEX);
|
|
255 if (!CONSP (extra))
|
|
256 return -1;
|
|
257
|
90906
|
258 supported_scripts = assq_no_quit (QCscript, extra);
|
|
259 if (!CONSP (supported_scripts))
|
90869
|
260 return -1;
|
|
261
|
90906
|
262 supported_scripts = XCDR (supported_scripts);
|
90869
|
263
|
90906
|
264 script = CHAR_TABLE_REF (Vchar_script_table, c);
|
90869
|
265
|
92409
|
266 return (memq_no_quit (script, supported_scripts)) ? -1 : 0;
|
90869
|
267 }
|
|
268
|
|
269 /* w32 implementation of encode_char for font backend.
|
|
270 Return a glyph code of FONT for characer C (Unicode code point).
|
|
271 If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */
|
92409
|
272 static unsigned
|
90889
|
273 w32font_encode_char (font, c)
|
|
274 struct font *font;
|
|
275 int c;
|
90869
|
276 {
|
92409
|
277 struct frame *f;
|
|
278 HDC dc;
|
|
279 HFONT old_font;
|
|
280 DWORD retval;
|
|
281 GCP_RESULTSW result;
|
|
282 wchar_t in[2];
|
|
283 wchar_t out[2];
|
|
284 int len;
|
|
285 struct w32font_info *w32_font = (struct w32font_info *) font;
|
|
286
|
|
287 /* If glyph indexing is not working for this font, just return the
|
|
288 unicode code-point. */
|
|
289 if (!w32_font->glyph_idx)
|
|
290 return c;
|
|
291
|
|
292 if (c > 0xFFFF)
|
|
293 {
|
|
294 /* TODO: Encode as surrogate pair and lookup the glyph. */
|
|
295 return FONT_INVALID_CODE;
|
|
296 }
|
|
297 else
|
|
298 {
|
|
299 in[0] = (wchar_t) c;
|
|
300 len = 1;
|
|
301 }
|
|
302
|
|
303 bzero (&result, sizeof (result));
|
|
304 result.lStructSize = sizeof (result);
|
|
305 result.lpGlyphs = out;
|
|
306 result.nGlyphs = 2;
|
|
307
|
|
308 f = XFRAME (selected_frame);
|
|
309
|
|
310 dc = get_frame_dc (f);
|
|
311 old_font = SelectObject (dc, ((W32FontStruct *) (font->font.font))->hfont);
|
|
312
|
|
313 retval = GetCharacterPlacementW (dc, in, len, 0, &result, 0);
|
|
314
|
|
315 SelectObject (dc, old_font);
|
|
316 release_frame_dc (f, dc);
|
|
317
|
|
318 if (retval)
|
|
319 {
|
|
320 if (result.nGlyphs != 1 || !result.lpGlyphs[0])
|
|
321 return FONT_INVALID_CODE;
|
|
322 return result.lpGlyphs[0];
|
|
323 }
|
|
324 else
|
|
325 {
|
|
326 int i;
|
|
327 /* Mark this font as not supporting glyph indices. This can happen
|
|
328 on Windows9x, and maybe with non-Truetype fonts on NT etc. */
|
|
329 w32_font->glyph_idx = 0;
|
92411
|
330 recompute_cached_metrics (dc, w32_font);
|
92409
|
331
|
|
332 return c;
|
|
333 }
|
90869
|
334 }
|
|
335
|
|
336 /* w32 implementation of text_extents for font backend.
|
|
337 Perform the size computation of glyphs of FONT and fillin members
|
|
338 of METRICS. The glyphs are specified by their glyph codes in
|
91034
|
339 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
|
90869
|
340 case just return the overall width. */
|
91208
|
341 int
|
90889
|
342 w32font_text_extents (font, code, nglyphs, metrics)
|
|
343 struct font *font;
|
|
344 unsigned *code;
|
|
345 int nglyphs;
|
|
346 struct font_metrics *metrics;
|
90869
|
347 {
|
|
348 int i;
|
92151
|
349 HFONT old_font = NULL;
|
|
350 HDC dc = NULL;
|
91208
|
351 struct frame * f;
|
90869
|
352 int total_width = 0;
|
|
353 WORD *wcode = alloca(nglyphs * sizeof (WORD));
|
90906
|
354 SIZE size;
|
90869
|
355
|
91593
|
356 /* TODO: Frames can come and go, and their fonts outlive them. So we
|
|
357 can't cache the frame in the font structure. Use selected_frame
|
|
358 until the API is updated to pass in a frame. */
|
91260
|
359 f = XFRAME (selected_frame);
|
91258
|
360
|
90869
|
361 if (metrics)
|
|
362 {
|
|
363 GLYPHMETRICS gm;
|
90906
|
364 MAT2 transform;
|
92409
|
365 struct w32font_info *w32_font = (struct w32font_info *) font;
|
90906
|
366
|
|
367 /* Set transform to the identity matrix. */
|
|
368 bzero (&transform, sizeof (transform));
|
|
369 transform.eM11.value = 1;
|
|
370 transform.eM22.value = 1;
|
91034
|
371 metrics->width = 0;
|
|
372 metrics->ascent = 0;
|
|
373 metrics->descent = 0;
|
91593
|
374 metrics->lbearing = 0;
|
90869
|
375
|
|
376 for (i = 0; i < nglyphs; i++)
|
|
377 {
|
92409
|
378 if (*(code + i) < 128)
|
91593
|
379 {
|
|
380 /* Use cached metrics for ASCII. */
|
|
381 struct font_metrics *char_metric
|
92409
|
382 = &w32_font->ascii_metrics[*(code+i)];
|
91593
|
383
|
|
384 /* If we couldn't get metrics when caching, use fallback. */
|
|
385 if (char_metric->width == 0)
|
|
386 break;
|
|
387
|
|
388 metrics->lbearing = max (metrics->lbearing,
|
|
389 char_metric->lbearing - metrics->width);
|
|
390 metrics->rbearing = max (metrics->rbearing,
|
|
391 metrics->width + char_metric->rbearing);
|
|
392 metrics->width += char_metric->width;
|
|
393 metrics->ascent = max (metrics->ascent, char_metric->ascent);
|
|
394 metrics->descent = max (metrics->descent, char_metric->descent);
|
|
395 }
|
90869
|
396 else
|
|
397 {
|
92151
|
398 if (dc == NULL)
|
|
399 {
|
|
400 dc = get_frame_dc (f);
|
|
401 old_font = SelectObject (dc, ((W32FontStruct *)
|
|
402 (font->font.font))->hfont);
|
|
403 }
|
92409
|
404 if (GetGlyphOutlineW (dc, *(code + i),
|
|
405 GGO_METRICS
|
|
406 | w32_font->glyph_idx
|
|
407 ? GGO_GLYPH_INDEX : 0,
|
|
408 &gm, 0, NULL, &transform) != GDI_ERROR)
|
92151
|
409 {
|
|
410 int new_val = metrics->width + gm.gmBlackBoxX
|
|
411 + gm.gmptGlyphOrigin.x;
|
|
412 metrics->rbearing = max (metrics->rbearing, new_val);
|
|
413 new_val = -gm.gmptGlyphOrigin.x - metrics->width;
|
|
414 metrics->lbearing = max (metrics->lbearing, new_val);
|
|
415 metrics->width += gm.gmCellIncX;
|
|
416 new_val = -gm.gmptGlyphOrigin.y;
|
|
417 metrics->ascent = max (metrics->ascent, new_val);
|
|
418 new_val = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
|
|
419 metrics->descent = max (metrics->descent, new_val);
|
|
420 }
|
|
421 else
|
|
422 {
|
92409
|
423 if (w32_font->glyph_idx)
|
|
424 {
|
|
425 /* Disable glyph indexing for this font, as we can't
|
|
426 handle the metrics. Abort this run, our recovery
|
|
427 strategies rely on having unicode code points here.
|
|
428 This will cause a glitch in display, but in practice,
|
|
429 any problems should be caught when initialising the
|
|
430 metrics cache. */
|
|
431 w32_font->glyph_idx = 0;
|
92411
|
432 recompute_cached_metrics (dc, w32_font);
|
92409
|
433 SelectObject (dc, old_font);
|
|
434 release_frame_dc (f, dc);
|
|
435 return 0;
|
|
436 }
|
92151
|
437 /* Rely on an estimate based on the overall font metrics. */
|
|
438 break;
|
|
439 }
|
90869
|
440 }
|
|
441 }
|
91034
|
442
|
|
443 /* If we got through everything, return. */
|
|
444 if (i == nglyphs)
|
|
445 {
|
92151
|
446 if (dc != NULL)
|
|
447 {
|
|
448 /* Restore state and release DC. */
|
|
449 SelectObject (dc, old_font);
|
|
450 release_frame_dc (f, dc);
|
|
451 }
|
91034
|
452
|
|
453 return metrics->width;
|
|
454 }
|
90869
|
455 }
|
91034
|
456
|
|
457 for (i = 0; i < nglyphs; i++)
|
90869
|
458 {
|
91034
|
459 if (code[i] < 0x10000)
|
|
460 wcode[i] = code[i];
|
|
461 else
|
|
462 {
|
|
463 /* TODO: Convert to surrogate, reallocating array if needed */
|
|
464 wcode[i] = 0xffff;
|
|
465 }
|
90869
|
466 }
|
|
467
|
92151
|
468 if (dc == NULL)
|
|
469 {
|
|
470 dc = get_frame_dc (f);
|
|
471 old_font = SelectObject (dc, ((W32FontStruct *)
|
|
472 (font->font.font))->hfont);
|
|
473 }
|
|
474
|
90906
|
475 if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
|
90869
|
476 {
|
90906
|
477 total_width = size.cx;
|
90869
|
478 }
|
|
479
|
90906
|
480 if (!total_width)
|
90869
|
481 {
|
|
482 RECT rect;
|
|
483 rect.top = 0; rect.bottom = font->font.height; rect.left = 0; rect.right = 1;
|
|
484 DrawTextW (dc, wcode, nglyphs, &rect,
|
|
485 DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
|
|
486 total_width = rect.right;
|
|
487 }
|
90906
|
488
|
91034
|
489 if (metrics)
|
|
490 {
|
|
491 metrics->width = total_width;
|
|
492 metrics->ascent = font->ascent;
|
|
493 metrics->descent = font->descent;
|
|
494 metrics->lbearing = 0;
|
|
495 metrics->rbearing = total_width
|
|
496 + ((struct w32font_info *) font)->metrics.tmOverhang;
|
|
497 }
|
|
498
|
90869
|
499 /* Restore state and release DC. */
|
|
500 SelectObject (dc, old_font);
|
91208
|
501 release_frame_dc (f, dc);
|
90869
|
502
|
|
503 return total_width;
|
|
504 }
|
|
505
|
|
506 /* w32 implementation of draw for font backend.
|
|
507 Optional.
|
|
508 Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
|
|
509 position of frame F with S->FACE and S->GC. If WITH_BACKGROUND
|
|
510 is nonzero, fill the background in advance. It is assured that
|
91182
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
511 WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars).
|
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
512
|
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
513 TODO: Currently this assumes that the colors and fonts are already
|
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
514 set in the DC. This seems to be true now, but maybe only due to
|
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
515 the old font code setting it up. It may be safer to resolve faces
|
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
516 and fonts in here and set them explicitly
|
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
517 */
|
bbdb7226d848
(add_font_entity_to_list): Compare only the beginning of full name.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
518
|
91208
|
519 int
|
90889
|
520 w32font_draw (s, from, to, x, y, with_background)
|
|
521 struct glyph_string *s;
|
|
522 int from, to, x, y, with_background;
|
90869
|
523 {
|
92409
|
524 UINT options;
|
91030
|
525 HRGN orig_clip;
|
92409
|
526 struct w32font_info *w32font = (struct w32font_info *) s->face->font_info;
|
|
527
|
|
528 options = w32font->glyph_idx;
|
91030
|
529
|
|
530 /* Save clip region for later restoration. */
|
|
531 GetClipRgn(s->hdc, orig_clip);
|
|
532
|
|
533 if (s->num_clips > 0)
|
|
534 {
|
|
535 HRGN new_clip = CreateRectRgnIndirect (s->clip);
|
|
536
|
|
537 if (s->num_clips > 1)
|
|
538 {
|
|
539 HRGN clip2 = CreateRectRgnIndirect (s->clip + 1);
|
|
540
|
|
541 CombineRgn (new_clip, new_clip, clip2, RGN_OR);
|
|
542 DeleteObject (clip2);
|
|
543 }
|
|
544
|
|
545 SelectClipRgn (s->hdc, new_clip);
|
|
546 DeleteObject (new_clip);
|
|
547 }
|
90869
|
548
|
91128
|
549 /* Using OPAQUE background mode can clear more background than expected
|
|
550 when Cleartype is used. Draw the background manually to avoid this. */
|
|
551 SetBkMode (s->hdc, TRANSPARENT);
|
90869
|
552 if (with_background)
|
|
553 {
|
90908
|
554 HBRUSH brush;
|
|
555 RECT rect;
|
91128
|
556 struct font *font = (struct font *) s->face->font_info;
|
90908
|
557
|
|
558 brush = CreateSolidBrush (s->gc->background);
|
|
559 rect.left = x;
|
91128
|
560 rect.top = y - font->ascent;
|
90908
|
561 rect.right = x + s->width;
|
91128
|
562 rect.bottom = y + font->descent;
|
90908
|
563 FillRect (s->hdc, &rect, brush);
|
90915
|
564 DeleteObject (brush);
|
90869
|
565 }
|
90879
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
566
|
92187
|
567 if (s->padding_p)
|
|
568 {
|
|
569 int len = to - from, i;
|
|
570
|
|
571 for (i = 0; i < len; i++)
|
|
572 ExtTextOutW (s->hdc, x + i, y, options, NULL,
|
92199
|
573 s->char2b + from + i, 1, NULL);
|
92187
|
574 }
|
|
575 else
|
|
576 ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, to - from, NULL);
|
91030
|
577
|
|
578 /* Restore clip region. */
|
|
579 if (s->num_clips > 0)
|
|
580 {
|
|
581 SelectClipRgn (s->hdc, orig_clip);
|
|
582 }
|
90869
|
583 }
|
|
584
|
|
585 /* w32 implementation of free_entity for font backend.
|
|
586 Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value).
|
|
587 Free FONT_EXTRA_INDEX field of FONT_ENTITY.
|
90889
|
588 static void
|
|
589 w32font_free_entity (Lisp_Object entity);
|
90869
|
590 */
|
|
591
|
|
592 /* w32 implementation of prepare_face for font backend.
|
|
593 Optional (if FACE->extra is not used).
|
|
594 Prepare FACE for displaying characters by FONT on frame F by
|
|
595 storing some data in FACE->extra. If successful, return 0.
|
|
596 Otherwise, return -1.
|
90889
|
597 static int
|
|
598 w32font_prepare_face (FRAME_PTR f, struct face *face);
|
90869
|
599 */
|
|
600 /* w32 implementation of done_face for font backend.
|
|
601 Optional.
|
|
602 Done FACE for displaying characters by FACE->font on frame F.
|
90889
|
603 static void
|
|
604 w32font_done_face (FRAME_PTR f, struct face *face); */
|
90869
|
605
|
|
606 /* w32 implementation of get_bitmap for font backend.
|
|
607 Optional.
|
|
608 Store bitmap data for glyph-code CODE of FONT in BITMAP. It is
|
90915
|
609 intended that this method is called from the other font-driver
|
90869
|
610 for actual drawing.
|
90889
|
611 static int
|
|
612 w32font_get_bitmap (struct font *font, unsigned code,
|
|
613 struct font_bitmap *bitmap, int bits_per_pixel);
|
90869
|
614 */
|
|
615 /* w32 implementation of free_bitmap for font backend.
|
|
616 Optional.
|
|
617 Free bitmap data in BITMAP.
|
90889
|
618 static void
|
|
619 w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap);
|
90869
|
620 */
|
|
621 /* w32 implementation of get_outline for font backend.
|
|
622 Optional.
|
|
623 Return an outline data for glyph-code CODE of FONT. The format
|
|
624 of the outline data depends on the font-driver.
|
90889
|
625 static void *
|
|
626 w32font_get_outline (struct font *font, unsigned code);
|
90869
|
627 */
|
|
628 /* w32 implementation of free_outline for font backend.
|
|
629 Optional.
|
|
630 Free OUTLINE (that is obtained by the above method).
|
90889
|
631 static void
|
|
632 w32font_free_outline (struct font *font, void *outline);
|
90869
|
633 */
|
|
634 /* w32 implementation of anchor_point for font backend.
|
|
635 Optional.
|
|
636 Get coordinates of the INDEXth anchor point of the glyph whose
|
|
637 code is CODE. Store the coordinates in *X and *Y. Return 0 if
|
|
638 the operations was successfull. Otherwise return -1.
|
90889
|
639 static int
|
|
640 w32font_anchor_point (struct font *font, unsigned code,
|
90869
|
641 int index, int *x, int *y);
|
|
642 */
|
|
643 /* w32 implementation of otf_capability for font backend.
|
|
644 Optional.
|
|
645 Return a list describing which scripts/languages FONT
|
|
646 supports by which GSUB/GPOS features of OpenType tables.
|
90889
|
647 static Lisp_Object
|
|
648 w32font_otf_capability (struct font *font);
|
90869
|
649 */
|
|
650 /* w32 implementation of otf_drive for font backend.
|
|
651 Optional.
|
|
652 Apply FONT's OTF-FEATURES to the glyph string.
|
|
653
|
|
654 FEATURES specifies which OTF features to apply in this format:
|
|
655 (SCRIPT LANGSYS GSUB-FEATURE GPOS-FEATURE)
|
|
656 See the documentation of `font-drive-otf' for the detail.
|
|
657
|
|
658 This method applies the specified features to the codes in the
|
|
659 elements of GSTRING-IN (between FROMth and TOth). The output
|
|
660 codes are stored in GSTRING-OUT at the IDXth element and the
|
|
661 following elements.
|
|
662
|
|
663 Return the number of output codes. If none of the features are
|
|
664 applicable to the input data, return 0. If GSTRING-OUT is too
|
|
665 short, return -1.
|
90889
|
666 static int
|
|
667 w32font_otf_drive (struct font *font, Lisp_Object features,
|
|
668 Lisp_Object gstring_in, int from, int to,
|
|
669 Lisp_Object gstring_out, int idx,
|
|
670 int alternate_subst);
|
90869
|
671 */
|
|
672
|
91208
|
673 /* Internal implementation of w32font_list.
|
|
674 Additional parameter opentype_only restricts the returned fonts to
|
|
675 opentype fonts, which can be used with the Uniscribe backend. */
|
|
676 Lisp_Object
|
|
677 w32font_list_internal (frame, font_spec, opentype_only)
|
|
678 Lisp_Object frame, font_spec;
|
|
679 int opentype_only;
|
|
680 {
|
|
681 struct font_callback_data match_data;
|
|
682 HDC dc;
|
|
683 FRAME_PTR f = XFRAME (frame);
|
|
684
|
|
685 match_data.orig_font_spec = font_spec;
|
|
686 match_data.list = Qnil;
|
|
687 match_data.frame = frame;
|
|
688
|
|
689 bzero (&match_data.pattern, sizeof (LOGFONT));
|
|
690 fill_in_logfont (f, &match_data.pattern, font_spec);
|
|
691
|
|
692 match_data.opentype_only = opentype_only;
|
|
693 if (opentype_only)
|
|
694 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
|
|
695
|
|
696 if (match_data.pattern.lfFaceName[0] == '\0')
|
|
697 {
|
|
698 /* EnumFontFamiliesEx does not take other fields into account if
|
|
699 font name is blank, so need to use two passes. */
|
|
700 list_all_matching_fonts (&match_data);
|
|
701 }
|
|
702 else
|
|
703 {
|
|
704 dc = get_frame_dc (f);
|
|
705
|
|
706 EnumFontFamiliesEx (dc, &match_data.pattern,
|
|
707 (FONTENUMPROC) add_font_entity_to_list,
|
|
708 (LPARAM) &match_data, 0);
|
|
709 release_frame_dc (f, dc);
|
|
710 }
|
|
711
|
|
712 return NILP (match_data.list) ? null_vector : Fvconcat (1, &match_data.list);
|
|
713 }
|
|
714
|
|
715 /* Internal implementation of w32font_match.
|
|
716 Additional parameter opentype_only restricts the returned fonts to
|
|
717 opentype fonts, which can be used with the Uniscribe backend. */
|
|
718 Lisp_Object
|
|
719 w32font_match_internal (frame, font_spec, opentype_only)
|
|
720 Lisp_Object frame, font_spec;
|
|
721 int opentype_only;
|
|
722 {
|
|
723 struct font_callback_data match_data;
|
|
724 HDC dc;
|
|
725 FRAME_PTR f = XFRAME (frame);
|
|
726
|
|
727 match_data.orig_font_spec = font_spec;
|
|
728 match_data.frame = frame;
|
|
729 match_data.list = Qnil;
|
|
730
|
|
731 bzero (&match_data.pattern, sizeof (LOGFONT));
|
|
732 fill_in_logfont (f, &match_data.pattern, font_spec);
|
|
733
|
|
734 match_data.opentype_only = opentype_only;
|
|
735 if (opentype_only)
|
|
736 match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
|
|
737
|
|
738 dc = get_frame_dc (f);
|
|
739
|
|
740 EnumFontFamiliesEx (dc, &match_data.pattern,
|
|
741 (FONTENUMPROC) add_one_font_entity_to_list,
|
|
742 (LPARAM) &match_data, 0);
|
|
743 release_frame_dc (f, dc);
|
|
744
|
|
745 return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
|
|
746 }
|
|
747
|
91211
|
748 int
|
|
749 w32font_open_internal (f, font_entity, pixel_size, w32_font)
|
|
750 FRAME_PTR f;
|
|
751 Lisp_Object font_entity;
|
|
752 int pixel_size;
|
|
753 struct w32font_info *w32_font;
|
|
754 {
|
|
755 int len, size;
|
|
756 LOGFONT logfont;
|
|
757 HDC dc;
|
|
758 HFONT hfont, old_font;
|
|
759 Lisp_Object val, extra;
|
|
760 /* For backwards compatibility. */
|
|
761 W32FontStruct *compat_w32_font;
|
|
762
|
|
763 struct font * font = (struct font *) w32_font;
|
|
764 if (!font)
|
|
765 return 0;
|
|
766
|
|
767 bzero (&logfont, sizeof (logfont));
|
|
768 fill_in_logfont (f, &logfont, font_entity);
|
|
769
|
|
770 size = XINT (AREF (font_entity, FONT_SIZE_INDEX));
|
|
771 if (!size)
|
|
772 size = pixel_size;
|
|
773
|
|
774 logfont.lfHeight = -size;
|
|
775 hfont = CreateFontIndirect (&logfont);
|
|
776
|
|
777 if (hfont == NULL)
|
|
778 return 0;
|
|
779
|
|
780 /* Get the metrics for this font. */
|
|
781 dc = get_frame_dc (f);
|
|
782 old_font = SelectObject (dc, hfont);
|
|
783
|
|
784 GetTextMetrics (dc, &w32_font->metrics);
|
|
785
|
92712
|
786 w32_font->glyph_idx = ETO_GLYPH_INDEX;
|
|
787
|
91593
|
788 /* Cache ASCII metrics. */
|
92411
|
789 recompute_cached_metrics (dc, w32_font);
|
|
790
|
91211
|
791 SelectObject (dc, old_font);
|
|
792 release_frame_dc (f, dc);
|
92409
|
793
|
91211
|
794 /* W32FontStruct - we should get rid of this, and use the w32font_info
|
|
795 struct for any W32 specific fields. font->font.font can then be hfont. */
|
|
796 font->font.font = xmalloc (sizeof (W32FontStruct));
|
|
797 compat_w32_font = (W32FontStruct *) font->font.font;
|
|
798 bzero (compat_w32_font, sizeof (W32FontStruct));
|
|
799 compat_w32_font->font_type = UNICODE_FONT;
|
|
800 /* Duplicate the text metrics. */
|
|
801 bcopy (&w32_font->metrics, &compat_w32_font->tm, sizeof (TEXTMETRIC));
|
|
802 compat_w32_font->hfont = hfont;
|
|
803
|
|
804 len = strlen (logfont.lfFaceName);
|
|
805 font->font.name = (char *) xmalloc (len + 1);
|
|
806 bcopy (logfont.lfFaceName, font->font.name, len);
|
|
807 font->font.name[len] = '\0';
|
91496
|
808
|
|
809 {
|
|
810 char *name;
|
|
811
|
|
812 /* We don't know how much space we need for the full name, so start with
|
|
813 96 bytes and go up in steps of 32. */
|
|
814 len = 96;
|
91521
|
815 name = xmalloc (len);
|
92390
|
816 while (name && w32font_full_name (&logfont, font_entity, pixel_size,
|
|
817 name, len) < 0)
|
91496
|
818 {
|
91521
|
819 char *new = xrealloc (name, len += 32);
|
91496
|
820
|
|
821 if (! new)
|
91521
|
822 xfree (name);
|
91496
|
823 name = new;
|
|
824 }
|
|
825 if (name)
|
|
826 font->font.full_name = name;
|
|
827 else
|
|
828 font->font.full_name = font->font.name;
|
|
829 }
|
91211
|
830 font->font.charset = 0;
|
|
831 font->font.codepage = 0;
|
|
832 font->font.size = w32_font->metrics.tmMaxCharWidth;
|
|
833 font->font.height = w32_font->metrics.tmHeight
|
|
834 + w32_font->metrics.tmExternalLeading;
|
|
835 font->font.space_width = font->font.average_width
|
|
836 = w32_font->metrics.tmAveCharWidth;
|
|
837
|
|
838 font->font.vertical_centering = 0;
|
|
839 font->font.encoding_type = 0;
|
|
840 font->font.baseline_offset = 0;
|
|
841 font->font.relative_compose = 0;
|
|
842 font->font.default_ascent = w32_font->metrics.tmAscent;
|
|
843 font->font.font_encoder = NULL;
|
|
844 font->entity = font_entity;
|
|
845 font->pixel_size = size;
|
|
846 font->driver = &w32font_driver;
|
92409
|
847 /* Use format cached during list, as the information we have access to
|
|
848 here is incomplete. */
|
|
849 extra = AREF (font_entity, FONT_EXTRA_INDEX);
|
|
850 if (CONSP (extra))
|
|
851 {
|
|
852 val = assq_no_quit (QCformat, extra);
|
|
853 if (CONSP (val))
|
|
854 font->format = XCDR (val);
|
|
855 else
|
|
856 font->format = Qunknown;
|
|
857 }
|
|
858 else
|
|
859 font->format = Qunknown;
|
|
860
|
91211
|
861 font->file_name = NULL;
|
|
862 font->encoding_charset = -1;
|
|
863 font->repertory_charset = -1;
|
91545
|
864 /* TODO: do we really want the minimum width here, which could be negative? */
|
|
865 font->min_width = font->font.space_width;
|
91211
|
866 font->ascent = w32_font->metrics.tmAscent;
|
|
867 font->descent = w32_font->metrics.tmDescent;
|
|
868 font->scalable = w32_font->metrics.tmPitchAndFamily & TMPF_VECTOR;
|
|
869
|
91545
|
870 /* Set global flag fonts_changed_p to non-zero if the font loaded
|
|
871 has a character with a smaller width than any other character
|
|
872 before, or if the font loaded has a smaller height than any other
|
|
873 font loaded before. If this happens, it will make a glyph matrix
|
|
874 reallocation necessary. */
|
|
875 {
|
|
876 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
|
|
877 dpyinfo->n_fonts++;
|
|
878
|
|
879 if (dpyinfo->n_fonts == 1)
|
|
880 {
|
|
881 dpyinfo->smallest_font_height = font->font.height;
|
|
882 dpyinfo->smallest_char_width = font->min_width;
|
|
883 }
|
|
884 else
|
|
885 {
|
|
886 if (dpyinfo->smallest_font_height > font->font.height)
|
|
887 {
|
|
888 dpyinfo->smallest_font_height = font->font.height;
|
|
889 fonts_changed_p |= 1;
|
|
890 }
|
|
891 if (dpyinfo->smallest_char_width > font->min_width)
|
|
892 {
|
|
893 dpyinfo->smallest_char_width = font->min_width;
|
|
894 fonts_changed_p |= 1;
|
|
895 }
|
|
896 }
|
|
897 }
|
|
898
|
91211
|
899 return 1;
|
|
900 }
|
|
901
|
90869
|
902 /* Callback function for EnumFontFamiliesEx.
|
|
903 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
|
90889
|
904 static int CALLBACK
|
|
905 add_font_name_to_list (logical_font, physical_font, font_type, list_object)
|
|
906 ENUMLOGFONTEX *logical_font;
|
|
907 NEWTEXTMETRICEX *physical_font;
|
|
908 DWORD font_type;
|
|
909 LPARAM list_object;
|
90869
|
910 {
|
|
911 Lisp_Object* list = (Lisp_Object *) list_object;
|
91070
|
912 Lisp_Object family;
|
|
913
|
|
914 /* Skip vertical fonts (intended only for printing) */
|
|
915 if (logical_font->elfLogFont.lfFaceName[0] == '@')
|
|
916 return 1;
|
|
917
|
|
918 family = intern_downcase (logical_font->elfLogFont.lfFaceName,
|
|
919 strlen (logical_font->elfLogFont.lfFaceName));
|
90869
|
920 if (! memq_no_quit (family, *list))
|
|
921 *list = Fcons (family, *list);
|
|
922
|
|
923 return 1;
|
|
924 }
|
|
925
|
|
926 /* Convert an enumerated Windows font to an Emacs font entity. */
|
90889
|
927 static Lisp_Object
|
91124
|
928 w32_enumfont_pattern_entity (frame, logical_font, physical_font,
|
92409
|
929 font_type, requested_font, backend)
|
90906
|
930 Lisp_Object frame;
|
90889
|
931 ENUMLOGFONTEX *logical_font;
|
|
932 NEWTEXTMETRICEX *physical_font;
|
|
933 DWORD font_type;
|
91124
|
934 LOGFONT *requested_font;
|
92409
|
935 Lisp_Object backend;
|
90869
|
936 {
|
|
937 Lisp_Object entity, tem;
|
|
938 LOGFONT *lf = (LOGFONT*) logical_font;
|
|
939 BYTE generic_type;
|
92409
|
940 BYTE full_type = physical_font->ntmTm.ntmFlags;
|
90869
|
941
|
90906
|
942 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
|
90869
|
943
|
92409
|
944 ASET (entity, FONT_TYPE_INDEX, backend);
|
90906
|
945 ASET (entity, FONT_FRAME_INDEX, frame);
|
92539
|
946 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet, font_type));
|
90869
|
947 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
|
|
948
|
|
949 /* Foundry is difficult to get in readable form on Windows.
|
90906
|
950 But Emacs crashes if it is not set, so set it to something more
|
|
951 generic. Thes values make xflds compatible with Emacs 22. */
|
|
952 if (lf->lfOutPrecision == OUT_STRING_PRECIS)
|
|
953 tem = Qraster;
|
|
954 else if (lf->lfOutPrecision == OUT_STROKE_PRECIS)
|
|
955 tem = Qoutline;
|
|
956 else
|
|
957 tem = Qunknown;
|
|
958
|
|
959 ASET (entity, FONT_FOUNDRY_INDEX, tem);
|
|
960
|
|
961 /* Save the generic family in the extra info, as it is likely to be
|
|
962 useful to users looking for a close match. */
|
90869
|
963 generic_type = physical_font->ntmTm.tmPitchAndFamily & 0xF0;
|
|
964 if (generic_type == FF_DECORATIVE)
|
|
965 tem = Qdecorative;
|
|
966 else if (generic_type == FF_MODERN)
|
91260
|
967 tem = Qmono;
|
90869
|
968 else if (generic_type == FF_ROMAN)
|
90906
|
969 tem = Qserif;
|
90869
|
970 else if (generic_type == FF_SCRIPT)
|
|
971 tem = Qscript;
|
|
972 else if (generic_type == FF_SWISS)
|
91260
|
973 tem = Qsans;
|
90869
|
974 else
|
91260
|
975 tem = null_string;
|
|
976
|
|
977 ASET (entity, FONT_ADSTYLE_INDEX, tem);
|
90869
|
978
|
90906
|
979 if (physical_font->ntmTm.tmPitchAndFamily & 0x01)
|
|
980 font_put_extra (entity, QCspacing, make_number (FONT_SPACING_PROPORTIONAL));
|
|
981 else
|
|
982 font_put_extra (entity, QCspacing, make_number (FONT_SPACING_MONO));
|
90869
|
983
|
91124
|
984 if (requested_font->lfQuality != DEFAULT_QUALITY)
|
|
985 {
|
|
986 font_put_extra (entity, QCantialias,
|
|
987 lispy_antialias_type (requested_font->lfQuality));
|
|
988 }
|
90869
|
989 ASET (entity, FONT_FAMILY_INDEX,
|
|
990 intern_downcase (lf->lfFaceName, strlen (lf->lfFaceName)));
|
|
991
|
|
992 ASET (entity, FONT_WEIGHT_INDEX, make_number (lf->lfWeight));
|
|
993 ASET (entity, FONT_SLANT_INDEX, make_number (lf->lfItalic ? 200 : 100));
|
90906
|
994 /* TODO: PANOSE struct has this info, but need to call GetOutlineTextMetrics
|
|
995 to get it. */
|
|
996 ASET (entity, FONT_WIDTH_INDEX, make_number (100));
|
90869
|
997
|
90879
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
998 if (font_type & RASTER_FONTTYPE)
|
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
999 ASET (entity, FONT_SIZE_INDEX, make_number (physical_font->ntmTm.tmHeight));
|
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1000 else
|
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1001 ASET (entity, FONT_SIZE_INDEX, make_number (0));
|
90869
|
1002
|
|
1003 /* Cache unicode codepoints covered by this font, as there is no other way
|
|
1004 of getting this information easily. */
|
90879
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1005 if (font_type & TRUETYPE_FONTTYPE)
|
90869
|
1006 {
|
90906
|
1007 font_put_extra (entity, QCscript,
|
|
1008 font_supported_scripts (&physical_font->ntmFontSig));
|
90869
|
1009 }
|
90906
|
1010
|
92409
|
1011 /* This information is not fully available when opening fonts, so
|
|
1012 save it here. Only Windows 2000 and later return information
|
|
1013 about opentype and type1 fonts, so need a fallback for detecting
|
|
1014 truetype so that this information is not any worse than we could
|
|
1015 have obtained later. */
|
|
1016 if (full_type & NTM_TT_OPENTYPE || font_type & TRUETYPE_FONTTYPE)
|
|
1017 tem = intern ("truetype");
|
|
1018 else if (full_type & NTM_TYPE1)
|
|
1019 tem = intern ("type1");
|
|
1020 else if (full_type & NTM_PS_OPENTYPE)
|
|
1021 tem = intern ("postscript");
|
|
1022 else if (font_type & RASTER_FONTTYPE)
|
|
1023 tem = intern ("w32bitmap");
|
|
1024 else
|
|
1025 tem = intern ("w32vector");
|
|
1026
|
|
1027 font_put_extra (entity, QCformat, tem);
|
|
1028
|
90869
|
1029 return entity;
|
|
1030 }
|
|
1031
|
90906
|
1032
|
|
1033 /* Convert generic families to the family portion of lfPitchAndFamily. */
|
|
1034 BYTE
|
|
1035 w32_generic_family (Lisp_Object name)
|
|
1036 {
|
|
1037 /* Generic families. */
|
|
1038 if (EQ (name, Qmonospace) || EQ (name, Qmono))
|
|
1039 return FF_MODERN;
|
91260
|
1040 else if (EQ (name, Qsans) || EQ (name, Qsans_serif) || EQ (name, Qsansserif))
|
90906
|
1041 return FF_SWISS;
|
|
1042 else if (EQ (name, Qserif))
|
|
1043 return FF_ROMAN;
|
|
1044 else if (EQ (name, Qdecorative))
|
|
1045 return FF_DECORATIVE;
|
|
1046 else if (EQ (name, Qscript))
|
|
1047 return FF_SCRIPT;
|
|
1048 else
|
|
1049 return FF_DONTCARE;
|
|
1050 }
|
|
1051
|
|
1052 static int
|
|
1053 logfonts_match (font, pattern)
|
|
1054 LOGFONT *font, *pattern;
|
|
1055 {
|
|
1056 /* Only check height for raster fonts. */
|
|
1057 if (pattern->lfHeight && font->lfOutPrecision == OUT_STRING_PRECIS
|
|
1058 && font->lfHeight != pattern->lfHeight)
|
|
1059 return 0;
|
|
1060
|
|
1061 /* Have some flexibility with weights. */
|
|
1062 if (pattern->lfWeight
|
|
1063 && ((font->lfWeight < (pattern->lfWeight - 150))
|
|
1064 || font->lfWeight > (pattern->lfWeight + 150)))
|
|
1065 return 0;
|
|
1066
|
|
1067 /* Charset and face should be OK. Italic has to be checked
|
|
1068 against the original spec, in case we don't have any preference. */
|
|
1069 return 1;
|
|
1070 }
|
|
1071
|
|
1072 static int
|
|
1073 font_matches_spec (type, font, spec)
|
|
1074 DWORD type;
|
|
1075 NEWTEXTMETRICEX *font;
|
|
1076 Lisp_Object spec;
|
90869
|
1077 {
|
90906
|
1078 Lisp_Object extra, val;
|
|
1079
|
|
1080 /* Check italic. Can't check logfonts, since it is a boolean field,
|
|
1081 so there is no difference between "non-italic" and "don't care". */
|
|
1082 val = AREF (spec, FONT_SLANT_INDEX);
|
|
1083 if (INTEGERP (val))
|
|
1084 {
|
|
1085 int slant = XINT (val);
|
|
1086 if ((slant > 150 && !font->ntmTm.tmItalic)
|
|
1087 || (slant <= 150 && font->ntmTm.tmItalic))
|
|
1088 return 0;
|
|
1089 }
|
|
1090
|
91264
|
1091 /* Check adstyle against generic family. */
|
|
1092 val = AREF (spec, FONT_ADSTYLE_INDEX);
|
|
1093 if (!NILP (val))
|
|
1094 {
|
|
1095 BYTE family = w32_generic_family (val);
|
|
1096 if (family != FF_DONTCARE
|
|
1097 && family != (font->ntmTm.tmPitchAndFamily & 0xF0))
|
|
1098 return 0;
|
|
1099 }
|
|
1100
|
90906
|
1101 /* Check extra parameters. */
|
|
1102 for (extra = AREF (spec, FONT_EXTRA_INDEX);
|
|
1103 CONSP (extra); extra = XCDR (extra))
|
|
1104 {
|
|
1105 Lisp_Object extra_entry;
|
|
1106 extra_entry = XCAR (extra);
|
|
1107 if (CONSP (extra_entry))
|
|
1108 {
|
|
1109 Lisp_Object key = XCAR (extra_entry);
|
|
1110 val = XCDR (extra_entry);
|
91260
|
1111 if (EQ (key, QCspacing))
|
90906
|
1112 {
|
|
1113 int proportional;
|
|
1114 if (INTEGERP (val))
|
|
1115 {
|
|
1116 int spacing = XINT (val);
|
|
1117 proportional = (spacing < FONT_SPACING_MONO);
|
|
1118 }
|
|
1119 else if (EQ (val, Qp))
|
|
1120 proportional = 1;
|
|
1121 else if (EQ (val, Qc) || EQ (val, Qm))
|
|
1122 proportional = 0;
|
|
1123 else
|
|
1124 return 0; /* Bad font spec. */
|
90869
|
1125
|
90906
|
1126 if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
|
|
1127 || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
|
|
1128 return 0;
|
|
1129 }
|
|
1130 else if (EQ (key, QCscript) && SYMBOLP (val))
|
|
1131 {
|
|
1132 /* Only truetype fonts will have information about what
|
|
1133 scripts they support. This probably means the user
|
|
1134 will have to force Emacs to use raster, postscript
|
|
1135 or atm fonts for non-ASCII text. */
|
|
1136 if (type & TRUETYPE_FONTTYPE)
|
|
1137 {
|
|
1138 Lisp_Object support
|
|
1139 = font_supported_scripts (&font->ntmFontSig);
|
|
1140 if (! memq_no_quit (val, support))
|
|
1141 return 0;
|
|
1142 }
|
|
1143 else
|
|
1144 {
|
|
1145 /* Return specific matches, but play it safe. Fonts
|
|
1146 that cover more than their charset would suggest
|
|
1147 are likely to be truetype or opentype fonts,
|
|
1148 covered above. */
|
|
1149 if (EQ (val, Qlatin))
|
|
1150 {
|
|
1151 /* Although every charset but symbol, thai and
|
|
1152 arabic contains the basic ASCII set of latin
|
|
1153 characters, Emacs expects much more. */
|
|
1154 if (font->ntmTm.tmCharSet != ANSI_CHARSET)
|
|
1155 return 0;
|
|
1156 }
|
|
1157 else if (EQ (val, Qsymbol))
|
|
1158 {
|
|
1159 if (font->ntmTm.tmCharSet != SYMBOL_CHARSET)
|
|
1160 return 0;
|
|
1161 }
|
|
1162 else if (EQ (val, Qcyrillic))
|
|
1163 {
|
|
1164 if (font->ntmTm.tmCharSet != RUSSIAN_CHARSET)
|
|
1165 return 0;
|
|
1166 }
|
|
1167 else if (EQ (val, Qgreek))
|
|
1168 {
|
|
1169 if (font->ntmTm.tmCharSet != GREEK_CHARSET)
|
|
1170 return 0;
|
|
1171 }
|
|
1172 else if (EQ (val, Qarabic))
|
|
1173 {
|
|
1174 if (font->ntmTm.tmCharSet != ARABIC_CHARSET)
|
|
1175 return 0;
|
|
1176 }
|
|
1177 else if (EQ (val, Qhebrew))
|
|
1178 {
|
|
1179 if (font->ntmTm.tmCharSet != HEBREW_CHARSET)
|
|
1180 return 0;
|
|
1181 }
|
|
1182 else if (EQ (val, Qthai))
|
|
1183 {
|
|
1184 if (font->ntmTm.tmCharSet != THAI_CHARSET)
|
|
1185 return 0;
|
|
1186 }
|
|
1187 else if (EQ (val, Qkana))
|
|
1188 {
|
|
1189 if (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
|
|
1190 return 0;
|
|
1191 }
|
|
1192 else if (EQ (val, Qbopomofo))
|
|
1193 {
|
|
1194 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET)
|
|
1195 return 0;
|
|
1196 }
|
|
1197 else if (EQ (val, Qhangul))
|
|
1198 {
|
|
1199 if (font->ntmTm.tmCharSet != HANGUL_CHARSET
|
|
1200 && font->ntmTm.tmCharSet != JOHAB_CHARSET)
|
|
1201 return 0;
|
|
1202 }
|
|
1203 else if (EQ (val, Qhan))
|
|
1204 {
|
|
1205 if (font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET
|
|
1206 && font->ntmTm.tmCharSet != GB2312_CHARSET
|
|
1207 && font->ntmTm.tmCharSet != HANGUL_CHARSET
|
|
1208 && font->ntmTm.tmCharSet != JOHAB_CHARSET
|
|
1209 && font->ntmTm.tmCharSet != SHIFTJIS_CHARSET)
|
|
1210 return 0;
|
|
1211 }
|
|
1212 else
|
|
1213 /* Other scripts unlikely to be handled. */
|
|
1214 return 0;
|
|
1215 }
|
|
1216 }
|
|
1217 }
|
|
1218 }
|
90869
|
1219 return 1;
|
|
1220 }
|
|
1221
|
92539
|
1222 static int
|
|
1223 w32font_coverage_ok (coverage, charset)
|
|
1224 FONTSIGNATURE * coverage;
|
|
1225 BYTE charset;
|
|
1226 {
|
|
1227 DWORD subrange1 = coverage->fsUsb[1];
|
|
1228
|
|
1229 #define SUBRANGE1_HAN_MASK 0x08000000
|
|
1230 #define SUBRANGE1_HANGEUL_MASK 0x01000000
|
|
1231 #define SUBRANGE1_JAPANESE_MASK (0x00060000 | SUBRANGE1_HAN_MASK)
|
|
1232
|
|
1233 if (charset == GB2312_CHARSET || charset == CHINESEBIG5_CHARSET)
|
|
1234 {
|
|
1235 return (subrange1 & SUBRANGE1_HAN_MASK) == SUBRANGE1_HAN_MASK;
|
|
1236 }
|
|
1237 else if (charset == SHIFTJIS_CHARSET)
|
|
1238 {
|
|
1239 return (subrange1 & SUBRANGE1_JAPANESE_MASK) == SUBRANGE1_JAPANESE_MASK;
|
|
1240 }
|
|
1241 else if (charset == HANGEUL_CHARSET)
|
|
1242 {
|
|
1243 return (subrange1 & SUBRANGE1_HANGEUL_MASK) == SUBRANGE1_HANGEUL_MASK;
|
|
1244 }
|
|
1245
|
|
1246 return 1;
|
|
1247 }
|
|
1248
|
90869
|
1249 /* Callback function for EnumFontFamiliesEx.
|
90906
|
1250 * Checks if a font matches everything we are trying to check agaist,
|
|
1251 * and if so, adds it to a list. Both the data we are checking against
|
|
1252 * and the list to which the fonts are added are passed in via the
|
|
1253 * lparam argument, in the form of a font_callback_data struct. */
|
90889
|
1254 static int CALLBACK
|
90906
|
1255 add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
|
90889
|
1256 ENUMLOGFONTEX *logical_font;
|
|
1257 NEWTEXTMETRICEX *physical_font;
|
|
1258 DWORD font_type;
|
90906
|
1259 LPARAM lParam;
|
90869
|
1260 {
|
90906
|
1261 struct font_callback_data *match_data
|
|
1262 = (struct font_callback_data *) lParam;
|
|
1263
|
91208
|
1264 if ((!match_data->opentype_only
|
|
1265 || (physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE))
|
|
1266 && logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
|
90906
|
1267 && font_matches_spec (font_type, physical_font,
|
91264
|
1268 match_data->orig_font_spec)
|
92539
|
1269 && w32font_coverage_ok (&physical_font->ntmFontSig,
|
|
1270 match_data->pattern.lfCharSet)
|
91264
|
1271 /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif)
|
|
1272 We limit this to raster fonts, because the test can catch some
|
|
1273 genuine fonts (eg the full name of DejaVu Sans Mono Light is actually
|
|
1274 DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will
|
|
1275 therefore get through this test. Since full names can be prefixed
|
|
1276 by a foundry, we accept raster fonts if the font name is found
|
|
1277 anywhere within the full name. */
|
|
1278 && (logical_font->elfLogFont.lfOutPrecision != OUT_STRING_PRECIS
|
|
1279 || strstr (logical_font->elfFullName,
|
|
1280 logical_font->elfLogFont.lfFaceName)))
|
90906
|
1281 {
|
|
1282 Lisp_Object entity
|
|
1283 = w32_enumfont_pattern_entity (match_data->frame, logical_font,
|
91124
|
1284 physical_font, font_type,
|
92409
|
1285 &match_data->pattern,
|
|
1286 match_data->opentype_only
|
|
1287 ? Quniscribe : Qgdi);
|
90906
|
1288 if (!NILP (entity))
|
|
1289 match_data->list = Fcons (entity, match_data->list);
|
|
1290 }
|
|
1291 return 1;
|
|
1292 }
|
|
1293
|
|
1294 /* Callback function for EnumFontFamiliesEx.
|
|
1295 * Terminates the search once we have a match. */
|
|
1296 static int CALLBACK
|
|
1297 add_one_font_entity_to_list (logical_font, physical_font, font_type, lParam)
|
|
1298 ENUMLOGFONTEX *logical_font;
|
|
1299 NEWTEXTMETRICEX *physical_font;
|
|
1300 DWORD font_type;
|
|
1301 LPARAM lParam;
|
|
1302 {
|
|
1303 struct font_callback_data *match_data
|
|
1304 = (struct font_callback_data *) lParam;
|
|
1305 add_font_entity_to_list (logical_font, physical_font, font_type, lParam);
|
|
1306
|
|
1307 /* If we have a font in the list, terminate the search. */
|
|
1308 return !NILP (match_data->list);
|
90869
|
1309 }
|
|
1310
|
|
1311 /* Convert a Lisp font registry (symbol) to a windows charset. */
|
90889
|
1312 static LONG
|
|
1313 registry_to_w32_charset (charset)
|
|
1314 Lisp_Object charset;
|
90869
|
1315 {
|
|
1316 if (EQ (charset, Qiso10646_1) || EQ (charset, Qunicode_bmp)
|
|
1317 || EQ (charset, Qunicode_sip))
|
|
1318 return DEFAULT_CHARSET; /* UNICODE_CHARSET not defined in MingW32 */
|
|
1319 else if (EQ (charset, Qiso8859_1))
|
|
1320 return ANSI_CHARSET;
|
90879
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1321 else if (SYMBOLP (charset))
|
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1322 return x_to_w32_charset (SDATA (SYMBOL_NAME (charset)));
|
90869
|
1323 else if (STRINGP (charset))
|
|
1324 return x_to_w32_charset (SDATA (charset));
|
|
1325 else
|
|
1326 return DEFAULT_CHARSET;
|
|
1327 }
|
|
1328
|
90889
|
1329 static Lisp_Object
|
92539
|
1330 w32_registry (w32_charset, font_type)
|
90889
|
1331 LONG w32_charset;
|
92539
|
1332 DWORD font_type;
|
90869
|
1333 {
|
92539
|
1334 /* If charset is defaulted, use ANSI (unicode for truetype fonts). */
|
|
1335 if (w32_charset == DEFAULT_CHARSET)
|
|
1336 w32_charset = ANSI_CHARSET;
|
|
1337
|
|
1338 if (font_type == TRUETYPE_FONTTYPE && w32_charset == ANSI_CHARSET)
|
90906
|
1339 return Qiso10646_1;
|
90869
|
1340 else
|
90879
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1341 {
|
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1342 char * charset = w32_to_x_charset (w32_charset, NULL);
|
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1343 return intern_downcase (charset, strlen(charset));
|
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1344 }
|
90869
|
1345 }
|
|
1346
|
|
1347 /* Fill in all the available details of LOGFONT from FONT_SPEC. */
|
90889
|
1348 static void
|
|
1349 fill_in_logfont (f, logfont, font_spec)
|
|
1350 FRAME_PTR f;
|
|
1351 LOGFONT *logfont;
|
|
1352 Lisp_Object font_spec;
|
90869
|
1353 {
|
90906
|
1354 Lisp_Object tmp, extra;
|
90869
|
1355 int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
|
|
1356
|
90906
|
1357 extra = AREF (font_spec, FONT_EXTRA_INDEX);
|
|
1358 /* Allow user to override dpi settings. */
|
|
1359 if (CONSP (extra))
|
|
1360 {
|
|
1361 tmp = assq_no_quit (QCdpi, extra);
|
|
1362 if (CONSP (tmp) && INTEGERP (XCDR (tmp)))
|
|
1363 {
|
|
1364 dpi = XINT (XCDR (tmp));
|
|
1365 }
|
|
1366 else if (CONSP (tmp) && FLOATP (XCDR (tmp)))
|
|
1367 {
|
|
1368 dpi = (int) (XFLOAT_DATA (XCDR (tmp)) + 0.5);
|
|
1369 }
|
|
1370 }
|
90869
|
1371
|
|
1372 /* Height */
|
|
1373 tmp = AREF (font_spec, FONT_SIZE_INDEX);
|
|
1374 if (INTEGERP (tmp))
|
90879
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1375 logfont->lfHeight = -1 * XINT (tmp);
|
90869
|
1376 else if (FLOATP (tmp))
|
90906
|
1377 logfont->lfHeight = (int) (-1.0 * dpi * XFLOAT_DATA (tmp) / 72.27 + 0.5);
|
90869
|
1378
|
|
1379 /* Escapement */
|
|
1380
|
|
1381 /* Orientation */
|
|
1382
|
|
1383 /* Weight */
|
|
1384 tmp = AREF (font_spec, FONT_WEIGHT_INDEX);
|
|
1385 if (INTEGERP (tmp))
|
|
1386 logfont->lfWeight = XINT (tmp);
|
|
1387
|
|
1388 /* Italic */
|
|
1389 tmp = AREF (font_spec, FONT_SLANT_INDEX);
|
|
1390 if (INTEGERP (tmp))
|
|
1391 {
|
|
1392 int slant = XINT (tmp);
|
|
1393 logfont->lfItalic = slant > 150 ? 1 : 0;
|
|
1394 }
|
|
1395
|
|
1396 /* Underline */
|
|
1397
|
|
1398 /* Strikeout */
|
|
1399
|
|
1400 /* Charset */
|
|
1401 tmp = AREF (font_spec, FONT_REGISTRY_INDEX);
|
|
1402 if (! NILP (tmp))
|
90906
|
1403 logfont->lfCharSet = registry_to_w32_charset (tmp);
|
90869
|
1404
|
|
1405 /* Out Precision */
|
91124
|
1406
|
90869
|
1407 /* Clip Precision */
|
91124
|
1408
|
|
1409 /* Quality */
|
90879
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1410 logfont->lfQuality = DEFAULT_QUALITY;
|
82b86c925f88
* w32font.c (w32font_open): Handle size, height and pixel_size better.
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1411
|
90906
|
1412 /* Generic Family and Face Name */
|
|
1413 logfont->lfPitchAndFamily = FF_DONTCARE | DEFAULT_PITCH;
|
|
1414
|
90869
|
1415 tmp = AREF (font_spec, FONT_FAMILY_INDEX);
|
90906
|
1416 if (! NILP (tmp))
|
|
1417 {
|
|
1418 logfont->lfPitchAndFamily = w32_generic_family (tmp) | DEFAULT_PITCH;
|
|
1419 if ((logfont->lfPitchAndFamily & 0xF0) != FF_DONTCARE)
|
|
1420 ; /* Font name was generic, don't fill in font name. */
|
|
1421 /* Font families are interned, but allow for strings also in case of
|
|
1422 user input. */
|
|
1423 else if (SYMBOLP (tmp))
|
|
1424 strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE);
|
|
1425 else if (STRINGP (tmp))
|
|
1426 strncpy (logfont->lfFaceName, SDATA (tmp), LF_FACESIZE);
|
|
1427 }
|
90869
|
1428
|
91260
|
1429 tmp = AREF (font_spec, FONT_ADSTYLE_INDEX);
|
|
1430 if (!NILP (tmp))
|
|
1431 {
|
|
1432 /* Override generic family. */
|
|
1433 BYTE family = w32_generic_family (tmp);
|
|
1434 if (family != FF_DONTCARE)
|
|
1435 logfont->lfPitchAndFamily = family | DEFAULT_PITCH;
|
|
1436 }
|
|
1437
|
90906
|
1438 /* Process EXTRA info. */
|
|
1439 for ( ; CONSP (extra); extra = XCDR (extra))
|
|
1440 {
|
|
1441 tmp = XCAR (extra);
|
|
1442 if (CONSP (tmp))
|
|
1443 {
|
|
1444 Lisp_Object key, val;
|
|
1445 key = XCAR (tmp), val = XCDR (tmp);
|
91260
|
1446 if (EQ (key, QCspacing))
|
90906
|
1447 {
|
|
1448 /* Set pitch based on the spacing property. */
|
|
1449 if (INTEGERP (val))
|
|
1450 {
|
|
1451 int spacing = XINT (val);
|
|
1452 if (spacing < FONT_SPACING_MONO)
|
|
1453 logfont->lfPitchAndFamily
|
|
1454 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
|
|
1455 else
|
|
1456 logfont->lfPitchAndFamily
|
|
1457 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
|
|
1458 }
|
|
1459 else if (EQ (val, Qp))
|
|
1460 logfont->lfPitchAndFamily
|
|
1461 = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
|
|
1462 else if (EQ (val, Qc) || EQ (val, Qm))
|
|
1463 logfont->lfPitchAndFamily
|
|
1464 = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
|
|
1465 }
|
|
1466 /* Only use QCscript if charset is not provided, or is unicode
|
|
1467 and a single script is specified. This is rather crude,
|
|
1468 and is only used to narrow down the fonts returned where
|
|
1469 there is a definite match. Some scripts, such as latin, han,
|
|
1470 cjk-misc match multiple lfCharSet values, so we can't pre-filter
|
|
1471 them. */
|
|
1472 else if (EQ (key, QCscript)
|
|
1473 && logfont->lfCharSet == DEFAULT_CHARSET
|
|
1474 && SYMBOLP (val))
|
|
1475 {
|
|
1476 if (EQ (val, Qgreek))
|
|
1477 logfont->lfCharSet = GREEK_CHARSET;
|
|
1478 else if (EQ (val, Qhangul))
|
|
1479 logfont->lfCharSet = HANGUL_CHARSET;
|
|
1480 else if (EQ (val, Qkana) || EQ (val, Qkanbun))
|
|
1481 logfont->lfCharSet = SHIFTJIS_CHARSET;
|
|
1482 else if (EQ (val, Qbopomofo))
|
|
1483 logfont->lfCharSet = CHINESEBIG5_CHARSET;
|
|
1484 /* GB 18030 supports tibetan, yi, mongolian,
|
|
1485 fonts that support it should show up if we ask for
|
|
1486 GB2312 fonts. */
|
|
1487 else if (EQ (val, Qtibetan) || EQ (val, Qyi)
|
|
1488 || EQ (val, Qmongolian))
|
|
1489 logfont->lfCharSet = GB2312_CHARSET;
|
|
1490 else if (EQ (val, Qhebrew))
|
|
1491 logfont->lfCharSet = HEBREW_CHARSET;
|
|
1492 else if (EQ (val, Qarabic))
|
|
1493 logfont->lfCharSet = ARABIC_CHARSET;
|
|
1494 else if (EQ (val, Qthai))
|
|
1495 logfont->lfCharSet = THAI_CHARSET;
|
|
1496 else if (EQ (val, Qsymbol))
|
|
1497 logfont->lfCharSet = SYMBOL_CHARSET;
|
|
1498 }
|
91124
|
1499 else if (EQ (key, QCantialias) && SYMBOLP (val))
|
|
1500 {
|
|
1501 logfont->lfQuality = w32_antialias_type (val);
|
|
1502 }
|
90906
|
1503 }
|
|
1504 }
|
90869
|
1505 }
|
|
1506
|
90889
|
1507 static void
|
90906
|
1508 list_all_matching_fonts (match_data)
|
|
1509 struct font_callback_data *match_data;
|
90869
|
1510 {
|
|
1511 HDC dc;
|
90906
|
1512 Lisp_Object families = w32font_list_family (match_data->frame);
|
|
1513 struct frame *f = XFRAME (match_data->frame);
|
90869
|
1514
|
|
1515 dc = get_frame_dc (f);
|
|
1516
|
|
1517 while (!NILP (families))
|
|
1518 {
|
90906
|
1519 /* TODO: Use the Unicode versions of the W32 APIs, so we can
|
|
1520 handle non-ASCII font names. */
|
|
1521 char *name;
|
90869
|
1522 Lisp_Object family = CAR (families);
|
|
1523 families = CDR (families);
|
90906
|
1524 if (NILP (family))
|
|
1525 continue;
|
|
1526 else if (STRINGP (family))
|
|
1527 name = SDATA (family);
|
|
1528 else
|
|
1529 name = SDATA (SYMBOL_NAME (family));
|
90869
|
1530
|
90906
|
1531 strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE);
|
|
1532 match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0';
|
|
1533
|
|
1534 EnumFontFamiliesEx (dc, &match_data->pattern,
|
|
1535 (FONTENUMPROC) add_font_entity_to_list,
|
|
1536 (LPARAM) match_data, 0);
|
90869
|
1537 }
|
|
1538
|
|
1539 release_frame_dc (f, dc);
|
|
1540 }
|
|
1541
|
91124
|
1542 static Lisp_Object
|
|
1543 lispy_antialias_type (type)
|
|
1544 BYTE type;
|
|
1545 {
|
|
1546 Lisp_Object lispy;
|
|
1547
|
|
1548 switch (type)
|
|
1549 {
|
|
1550 case NONANTIALIASED_QUALITY:
|
|
1551 lispy = Qnone;
|
|
1552 break;
|
|
1553 case ANTIALIASED_QUALITY:
|
|
1554 lispy = Qstandard;
|
|
1555 break;
|
|
1556 case CLEARTYPE_QUALITY:
|
|
1557 lispy = Qsubpixel;
|
|
1558 break;
|
|
1559 case CLEARTYPE_NATURAL_QUALITY:
|
|
1560 lispy = Qnatural;
|
|
1561 break;
|
|
1562 default:
|
|
1563 lispy = Qnil;
|
|
1564 break;
|
|
1565 }
|
|
1566 return lispy;
|
|
1567 }
|
|
1568
|
|
1569 /* Convert antialiasing symbols to lfQuality */
|
|
1570 static BYTE
|
|
1571 w32_antialias_type (type)
|
|
1572 Lisp_Object type;
|
|
1573 {
|
|
1574 if (EQ (type, Qnone))
|
|
1575 return NONANTIALIASED_QUALITY;
|
|
1576 else if (EQ (type, Qstandard))
|
|
1577 return ANTIALIASED_QUALITY;
|
|
1578 else if (EQ (type, Qsubpixel))
|
|
1579 return CLEARTYPE_QUALITY;
|
|
1580 else if (EQ (type, Qnatural))
|
|
1581 return CLEARTYPE_NATURAL_QUALITY;
|
|
1582 else
|
|
1583 return DEFAULT_QUALITY;
|
|
1584 }
|
|
1585
|
90906
|
1586 /* Return a list of all the scripts that the font supports. */
|
|
1587 static Lisp_Object
|
|
1588 font_supported_scripts (FONTSIGNATURE * sig)
|
90869
|
1589 {
|
90906
|
1590 DWORD * subranges = sig->fsUsb;
|
|
1591 Lisp_Object supported = Qnil;
|
|
1592
|
|
1593 /* Match a single subrange. SYM is set if bit N is set in subranges. */
|
|
1594 #define SUBRANGE(n,sym) \
|
|
1595 if (subranges[(n) / 32] & (1 << ((n) % 32))) \
|
|
1596 supported = Fcons ((sym), supported)
|
|
1597
|
|
1598 /* Match multiple subranges. SYM is set if any MASK bit is set in
|
|
1599 subranges[0 - 3]. */
|
|
1600 #define MASK_ANY(mask0,mask1,mask2,mask3,sym) \
|
|
1601 if ((subranges[0] & (mask0)) || (subranges[1] & (mask1)) \
|
|
1602 || (subranges[2] & (mask2)) || (subranges[3] & (mask3))) \
|
|
1603 supported = Fcons ((sym), supported)
|
|
1604
|
|
1605 SUBRANGE (0, Qlatin); /* There are many others... */
|
|
1606
|
|
1607 SUBRANGE (7, Qgreek);
|
|
1608 SUBRANGE (8, Qcoptic);
|
|
1609 SUBRANGE (9, Qcyrillic);
|
|
1610 SUBRANGE (10, Qarmenian);
|
|
1611 SUBRANGE (11, Qhebrew);
|
|
1612 SUBRANGE (13, Qarabic);
|
|
1613 SUBRANGE (14, Qnko);
|
|
1614 SUBRANGE (15, Qdevanagari);
|
|
1615 SUBRANGE (16, Qbengali);
|
|
1616 SUBRANGE (17, Qgurmukhi);
|
|
1617 SUBRANGE (18, Qgujarati);
|
|
1618 SUBRANGE (19, Qoriya);
|
|
1619 SUBRANGE (20, Qtamil);
|
|
1620 SUBRANGE (21, Qtelugu);
|
|
1621 SUBRANGE (22, Qkannada);
|
|
1622 SUBRANGE (23, Qmalayalam);
|
|
1623 SUBRANGE (24, Qthai);
|
|
1624 SUBRANGE (25, Qlao);
|
|
1625 SUBRANGE (26, Qgeorgian);
|
90869
|
1626
|
90906
|
1627 SUBRANGE (48, Qcjk_misc);
|
|
1628 SUBRANGE (51, Qbopomofo);
|
|
1629 SUBRANGE (54, Qkanbun); /* Is this right? */
|
|
1630 SUBRANGE (56, Qhangul);
|
|
1631
|
|
1632 SUBRANGE (59, Qhan); /* There are others, but this is the main one. */
|
|
1633 SUBRANGE (59, Qideographic_description); /* Windows lumps this in */
|
|
1634
|
|
1635 SUBRANGE (70, Qtibetan);
|
|
1636 SUBRANGE (71, Qsyriac);
|
|
1637 SUBRANGE (72, Qthaana);
|
|
1638 SUBRANGE (73, Qsinhala);
|
|
1639 SUBRANGE (74, Qmyanmar);
|
|
1640 SUBRANGE (75, Qethiopic);
|
|
1641 SUBRANGE (76, Qcherokee);
|
|
1642 SUBRANGE (77, Qcanadian_aboriginal);
|
|
1643 SUBRANGE (78, Qogham);
|
|
1644 SUBRANGE (79, Qrunic);
|
|
1645 SUBRANGE (80, Qkhmer);
|
|
1646 SUBRANGE (81, Qmongolian);
|
|
1647 SUBRANGE (82, Qbraille);
|
|
1648 SUBRANGE (83, Qyi);
|
|
1649
|
|
1650 SUBRANGE (88, Qbyzantine_musical_symbol);
|
|
1651 SUBRANGE (88, Qmusical_symbol); /* Windows doesn't distinguish these. */
|
|
1652
|
|
1653 SUBRANGE (89, Qmathematical);
|
|
1654
|
|
1655 /* Match either katakana or hiragana for kana. */
|
|
1656 MASK_ANY (0, 0x00060000, 0, 0, Qkana);
|
|
1657
|
|
1658 /* There isn't really a main symbol range, so include symbol if any
|
|
1659 relevant range is set. */
|
|
1660 MASK_ANY (0x8000000, 0x0000FFFF, 0, 0, Qsymbol);
|
|
1661
|
|
1662 #undef SUBRANGE
|
|
1663 #undef MASK_ANY
|
|
1664
|
|
1665 return supported;
|
90869
|
1666 }
|
|
1667
|
92390
|
1668 /* Generate a full name for a Windows font.
|
|
1669 The full name is in fcname format, with weight, slant and antialiasing
|
|
1670 specified if they are not "normal". */
|
|
1671 static int
|
|
1672 w32font_full_name (font, font_obj, pixel_size, name, nbytes)
|
|
1673 LOGFONT * font;
|
|
1674 Lisp_Object font_obj;
|
|
1675 int pixel_size;
|
|
1676 char *name;
|
|
1677 int nbytes;
|
|
1678 {
|
92394
|
1679 int len, height, outline;
|
92390
|
1680 char *p;
|
|
1681 Lisp_Object antialiasing, weight = Qnil;
|
|
1682
|
92394
|
1683 len = strlen (font->lfFaceName);
|
|
1684
|
|
1685 outline = EQ (AREF (font_obj, FONT_FOUNDRY_INDEX), Qoutline);
|
|
1686
|
|
1687 /* Represent size of scalable fonts by point size. But use pixelsize for
|
|
1688 raster fonts to indicate that they are exactly that size. */
|
|
1689 if (outline)
|
|
1690 len += 11; /* -SIZE */
|
|
1691 else
|
|
1692 len = strlen (font->lfFaceName) + 21;
|
92390
|
1693
|
|
1694 if (font->lfItalic)
|
|
1695 len += 7; /* :italic */
|
|
1696
|
|
1697 if (font->lfWeight && font->lfWeight != FW_NORMAL)
|
|
1698 {
|
|
1699 weight = font_symbolic_weight (font_obj);
|
|
1700 len += 8 + SBYTES (SYMBOL_NAME (weight)); /* :weight=NAME */
|
|
1701 }
|
|
1702
|
|
1703 antialiasing = lispy_antialias_type (font->lfQuality);
|
|
1704 if (! NILP (antialiasing))
|
|
1705 len += 11 + SBYTES (SYMBOL_NAME (antialiasing)); /* :antialias=NAME */
|
|
1706
|
|
1707 /* Check that the buffer is big enough */
|
|
1708 if (len > nbytes)
|
|
1709 return -1;
|
|
1710
|
|
1711 p = name;
|
|
1712 p += sprintf (p, "%s", font->lfFaceName);
|
|
1713
|
92394
|
1714 height = font->lfHeight ? eabs (font->lfHeight) : pixel_size;
|
|
1715
|
|
1716 if (height > 0)
|
|
1717 {
|
|
1718 if (outline)
|
|
1719 {
|
|
1720 float pointsize = height * 72.0 / one_w32_display_info.resy;
|
92712
|
1721 /* Round to nearest half point. floor is used, since round is not
|
|
1722 supported in MS library. */
|
|
1723 pointsize = floor (pointsize * 2 + 0.5) / 2;
|
92394
|
1724 p += sprintf (p, "-%1.1f", pointsize);
|
|
1725 }
|
|
1726 else
|
|
1727 p += sprintf (p, ":pixelsize=%d", height);
|
|
1728 }
|
92390
|
1729
|
|
1730 if (font->lfItalic)
|
|
1731 p += sprintf (p, ":italic");
|
|
1732
|
|
1733 if (SYMBOLP (weight) && ! NILP (weight))
|
|
1734 p += sprintf (p, ":weight=%s", SDATA (SYMBOL_NAME (weight)));
|
|
1735
|
|
1736 if (SYMBOLP (antialiasing) && ! NILP (antialiasing))
|
|
1737 p += sprintf (p, ":antialias=%s", SDATA (SYMBOL_NAME (antialiasing)));
|
|
1738
|
|
1739 return (p - name);
|
|
1740 }
|
90869
|
1741
|
92409
|
1742
|
|
1743 static void
|
92411
|
1744 recompute_cached_metrics (dc, w32_font)
|
92409
|
1745 HDC dc;
|
92411
|
1746 struct w32font_info *w32_font;
|
92409
|
1747 {
|
|
1748 GLYPHMETRICS gm;
|
|
1749 MAT2 transform;
|
92411
|
1750 unsigned int i;
|
92409
|
1751
|
|
1752 bzero (&transform, sizeof (transform));
|
|
1753 transform.eM11.value = 1;
|
|
1754 transform.eM22.value = 1;
|
|
1755
|
|
1756 for (i = 0; i < 128; i++)
|
|
1757 {
|
|
1758 struct font_metrics* char_metric = &w32_font->ascii_metrics[i];
|
92411
|
1759 unsigned int options = GGO_METRICS;
|
|
1760 if (w32_font->glyph_idx)
|
|
1761 options |= GGO_GLYPH_INDEX;
|
92409
|
1762
|
92411
|
1763 if (GetGlyphOutlineW (dc, i, options, &gm, 0, NULL, &transform)
|
|
1764 != GDI_ERROR)
|
92409
|
1765 {
|
|
1766 char_metric->lbearing = -gm.gmptGlyphOrigin.x;
|
|
1767 char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x;
|
|
1768 char_metric->width = gm.gmCellIncX;
|
|
1769 char_metric->ascent = -gm.gmptGlyphOrigin.y;
|
|
1770 char_metric->descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
|
|
1771 }
|
|
1772 else
|
|
1773 char_metric->width = 0;
|
|
1774 }
|
|
1775 }
|
|
1776
|
90869
|
1777 struct font_driver w32font_driver =
|
|
1778 {
|
90964
|
1779 0, /* Qgdi */
|
90869
|
1780 w32font_get_cache,
|
|
1781 w32font_list,
|
|
1782 w32font_match,
|
|
1783 w32font_list_family,
|
|
1784 NULL, /* free_entity */
|
|
1785 w32font_open,
|
|
1786 w32font_close,
|
|
1787 NULL, /* prepare_face */
|
|
1788 NULL, /* done_face */
|
|
1789 w32font_has_char,
|
|
1790 w32font_encode_char,
|
|
1791 w32font_text_extents,
|
|
1792 w32font_draw,
|
|
1793 NULL, /* get_bitmap */
|
|
1794 NULL, /* free_bitmap */
|
|
1795 NULL, /* get_outline */
|
|
1796 NULL, /* free_outline */
|
|
1797 NULL, /* anchor_point */
|
|
1798 NULL, /* otf_capability */
|
91158
|
1799 NULL, /* otf_drive */
|
|
1800 NULL, /* start_for_frame */
|
|
1801 NULL, /* end_for_frame */
|
|
1802 NULL /* shape */
|
90869
|
1803 };
|
|
1804
|
|
1805
|
|
1806 /* Initialize state that does not change between invocations. This is only
|
|
1807 called when Emacs is dumped. */
|
90889
|
1808 void
|
|
1809 syms_of_w32font ()
|
90869
|
1810 {
|
90964
|
1811 DEFSYM (Qgdi, "gdi");
|
92409
|
1812 DEFSYM (Quniscribe, "uniscribe");
|
|
1813 DEFSYM (QCformat, ":format");
|
90906
|
1814
|
|
1815 /* Generic font families. */
|
|
1816 DEFSYM (Qmonospace, "monospace");
|
|
1817 DEFSYM (Qserif, "serif");
|
91260
|
1818 DEFSYM (Qsansserif, "sansserif");
|
90869
|
1819 DEFSYM (Qscript, "script");
|
90906
|
1820 DEFSYM (Qdecorative, "decorative");
|
|
1821 /* Aliases. */
|
91260
|
1822 DEFSYM (Qsans_serif, "sans_serif");
|
90906
|
1823 DEFSYM (Qsans, "sans");
|
|
1824 DEFSYM (Qmono, "mono");
|
|
1825
|
|
1826 /* Fake foundries. */
|
|
1827 DEFSYM (Qraster, "raster");
|
|
1828 DEFSYM (Qoutline, "outline");
|
90869
|
1829 DEFSYM (Qunknown, "unknown");
|
90906
|
1830
|
91124
|
1831 /* Antialiasing. */
|
|
1832 DEFSYM (Qstandard, "standard");
|
|
1833 DEFSYM (Qsubpixel, "subpixel");
|
|
1834 DEFSYM (Qnatural, "natural");
|
90906
|
1835
|
|
1836 /* Scripts */
|
|
1837 DEFSYM (Qlatin, "latin");
|
|
1838 DEFSYM (Qgreek, "greek");
|
|
1839 DEFSYM (Qcoptic, "coptic");
|
|
1840 DEFSYM (Qcyrillic, "cyrillic");
|
|
1841 DEFSYM (Qarmenian, "armenian");
|
|
1842 DEFSYM (Qhebrew, "hebrew");
|
|
1843 DEFSYM (Qarabic, "arabic");
|
|
1844 DEFSYM (Qsyriac, "syriac");
|
|
1845 DEFSYM (Qnko, "nko");
|
|
1846 DEFSYM (Qthaana, "thaana");
|
|
1847 DEFSYM (Qdevanagari, "devanagari");
|
|
1848 DEFSYM (Qbengali, "bengali");
|
|
1849 DEFSYM (Qgurmukhi, "gurmukhi");
|
|
1850 DEFSYM (Qgujarati, "gujarati");
|
|
1851 DEFSYM (Qoriya, "oriya");
|
|
1852 DEFSYM (Qtamil, "tamil");
|
|
1853 DEFSYM (Qtelugu, "telugu");
|
|
1854 DEFSYM (Qkannada, "kannada");
|
|
1855 DEFSYM (Qmalayalam, "malayalam");
|
|
1856 DEFSYM (Qsinhala, "sinhala");
|
|
1857 DEFSYM (Qthai, "thai");
|
|
1858 DEFSYM (Qlao, "lao");
|
|
1859 DEFSYM (Qtibetan, "tibetan");
|
|
1860 DEFSYM (Qmyanmar, "myanmar");
|
|
1861 DEFSYM (Qgeorgian, "georgian");
|
|
1862 DEFSYM (Qhangul, "hangul");
|
|
1863 DEFSYM (Qethiopic, "ethiopic");
|
|
1864 DEFSYM (Qcherokee, "cherokee");
|
|
1865 DEFSYM (Qcanadian_aboriginal, "canadian-aboriginal");
|
|
1866 DEFSYM (Qogham, "ogham");
|
|
1867 DEFSYM (Qrunic, "runic");
|
|
1868 DEFSYM (Qkhmer, "khmer");
|
|
1869 DEFSYM (Qmongolian, "mongolian");
|
|
1870 DEFSYM (Qsymbol, "symbol");
|
|
1871 DEFSYM (Qbraille, "braille");
|
|
1872 DEFSYM (Qhan, "han");
|
|
1873 DEFSYM (Qideographic_description, "ideographic-description");
|
|
1874 DEFSYM (Qcjk_misc, "cjk-misc");
|
|
1875 DEFSYM (Qkana, "kana");
|
|
1876 DEFSYM (Qbopomofo, "bopomofo");
|
|
1877 DEFSYM (Qkanbun, "kanbun");
|
|
1878 DEFSYM (Qyi, "yi");
|
|
1879 DEFSYM (Qbyzantine_musical_symbol, "byzantine-musical-symbol");
|
|
1880 DEFSYM (Qmusical_symbol, "musical-symbol");
|
|
1881 DEFSYM (Qmathematical, "mathematical");
|
|
1882
|
90964
|
1883 w32font_driver.type = Qgdi;
|
90869
|
1884 register_font_driver (&w32font_driver, NULL);
|
|
1885 }
|
92472
|
1886 #endif /* USE_FONT_BACKEND */
|
90898
|
1887
|
|
1888 /* arch-tag: 65b8a3cd-46aa-4c0d-a1f3-99e75b9c07ee
|
|
1889 (do not change this comment) */
|