diff options
| author | Jason Rumney | 2007-12-08 01:49:30 +0000 |
|---|---|---|
| committer | Jason Rumney | 2007-12-08 01:49:30 +0000 |
| commit | 46fd1ded9154d06ae60ba389687672093223788f (patch) | |
| tree | 156ff53078ff001f99fd618a58a088e4c8aa4aed /src | |
| parent | c1ca4c2406d2c9d6b49f70b299321bc7715ce583 (diff) | |
| download | emacs-46fd1ded9154d06ae60ba389687672093223788f.tar.gz emacs-46fd1ded9154d06ae60ba389687672093223788f.zip | |
Include w32font.h.
(struct w32font_info): Add owning_frame field. Move to w32font.h.
(w32font_open): Set owning_frame.
(w32font_text_extents): Use owning_frame.
(struct font_callback_data): Add opentype_only field.
(add_font_entity_to_list): Use it to filter fonts.
Don't check against full name.
(w32font_list_internal): New function.
(w32font_list): Use it.
(w32font_match_internal): New function.
(w32font_match): Use it.
(w32font_get_cache, w32font_open, w32font_close, w32font_has_char)
(w32font_encode_char, w32font_text_extents, w32font_draw): Make non-static.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32font.c | 172 |
1 files changed, 99 insertions, 73 deletions
diff --git a/src/w32font.c b/src/w32font.c index adfdc34b21a..62c8f95d8bc 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -29,6 +29,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 29 | #include "charset.h" | 29 | #include "charset.h" |
| 30 | #include "fontset.h" | 30 | #include "fontset.h" |
| 31 | #include "font.h" | 31 | #include "font.h" |
| 32 | #include "w32font.h" | ||
| 32 | 33 | ||
| 33 | /* Cleartype available on Windows XP, cleartype_natural from XP SP1. | 34 | /* Cleartype available on Windows XP, cleartype_natural from XP SP1. |
| 34 | The latter does not try to fit cleartype smoothed fonts into the | 35 | The latter does not try to fit cleartype smoothed fonts into the |
| @@ -41,13 +42,6 @@ Boston, MA 02110-1301, USA. */ | |||
| 41 | #define CLEARTYPE_NATURAL_QUALITY 6 | 42 | #define CLEARTYPE_NATURAL_QUALITY 6 |
| 42 | #endif | 43 | #endif |
| 43 | 44 | ||
| 44 | /* The actual structure for a w32 font, that can be cast to struct font. */ | ||
| 45 | struct w32font_info | ||
| 46 | { | ||
| 47 | struct font font; | ||
| 48 | TEXTMETRIC metrics; | ||
| 49 | }; | ||
| 50 | |||
| 51 | extern struct font_driver w32font_driver; | 45 | extern struct font_driver w32font_driver; |
| 52 | 46 | ||
| 53 | Lisp_Object Qgdi; | 47 | Lisp_Object Qgdi; |
| @@ -113,6 +107,8 @@ struct font_callback_data | |||
| 113 | Lisp_Object frame; | 107 | Lisp_Object frame; |
| 114 | /* The list to add matches to. */ | 108 | /* The list to add matches to. */ |
| 115 | Lisp_Object list; | 109 | Lisp_Object list; |
| 110 | /* Whether to match only opentype fonts. */ | ||
| 111 | int opentype_only; | ||
| 116 | }; | 112 | }; |
| 117 | 113 | ||
| 118 | /* Handles the problem that EnumFontFamiliesEx will not return all | 114 | /* Handles the problem that EnumFontFamiliesEx will not return all |
| @@ -138,7 +134,7 @@ memq_no_quit (elt, list) | |||
| 138 | /* w32 implementation of get_cache for font backend. | 134 | /* w32 implementation of get_cache for font backend. |
| 139 | Return a cache of font-entities on FRAME. The cache must be a | 135 | Return a cache of font-entities on FRAME. The cache must be a |
| 140 | cons whose cdr part is the actual cache area. */ | 136 | cons whose cdr part is the actual cache area. */ |
| 141 | static Lisp_Object | 137 | Lisp_Object |
| 142 | w32font_get_cache (frame) | 138 | w32font_get_cache (frame) |
| 143 | Lisp_Object frame; | 139 | Lisp_Object frame; |
| 144 | { | 140 | { |
| @@ -155,33 +151,7 @@ static Lisp_Object | |||
| 155 | w32font_list (frame, font_spec) | 151 | w32font_list (frame, font_spec) |
| 156 | Lisp_Object frame, font_spec; | 152 | Lisp_Object frame, font_spec; |
| 157 | { | 153 | { |
| 158 | struct font_callback_data match_data; | 154 | return w32font_list_internal (frame, font_spec, 0); |
| 159 | HDC dc; | ||
| 160 | FRAME_PTR f = XFRAME (frame); | ||
| 161 | |||
| 162 | match_data.orig_font_spec = font_spec; | ||
| 163 | match_data.list = Qnil; | ||
| 164 | match_data.frame = frame; | ||
| 165 | bzero (&match_data.pattern, sizeof (LOGFONT)); | ||
| 166 | fill_in_logfont (f, &match_data.pattern, font_spec); | ||
| 167 | |||
| 168 | if (match_data.pattern.lfFaceName[0] == '\0') | ||
| 169 | { | ||
| 170 | /* EnumFontFamiliesEx does not take other fields into account if | ||
| 171 | font name is blank, so need to use two passes. */ | ||
| 172 | list_all_matching_fonts (&match_data); | ||
| 173 | } | ||
| 174 | else | ||
| 175 | { | ||
| 176 | dc = get_frame_dc (f); | ||
| 177 | |||
| 178 | EnumFontFamiliesEx (dc, &match_data.pattern, | ||
| 179 | (FONTENUMPROC) add_font_entity_to_list, | ||
| 180 | (LPARAM) &match_data, 0); | ||
| 181 | release_frame_dc (f, dc); | ||
| 182 | } | ||
| 183 | |||
| 184 | return NILP (match_data.list) ? null_vector : Fvconcat (1, &match_data.list); | ||
| 185 | } | 155 | } |
| 186 | 156 | ||
| 187 | /* w32 implementation of match for font backend. | 157 | /* w32 implementation of match for font backend. |
| @@ -192,27 +162,9 @@ static Lisp_Object | |||
| 192 | w32font_match (frame, font_spec) | 162 | w32font_match (frame, font_spec) |
| 193 | Lisp_Object frame, font_spec; | 163 | Lisp_Object frame, font_spec; |
| 194 | { | 164 | { |
| 195 | struct font_callback_data match_data; | 165 | return w32font_match_internal (frame, font_spec, 0); |
| 196 | HDC dc; | ||
| 197 | FRAME_PTR f = XFRAME (frame); | ||
| 198 | |||
| 199 | match_data.orig_font_spec = font_spec; | ||
| 200 | match_data.frame = frame; | ||
| 201 | match_data.list = Qnil; | ||
| 202 | bzero (&match_data.pattern, sizeof (LOGFONT)); | ||
| 203 | fill_in_logfont (f, &match_data.pattern, font_spec); | ||
| 204 | |||
| 205 | dc = get_frame_dc (f); | ||
| 206 | |||
| 207 | EnumFontFamiliesEx (dc, &match_data.pattern, | ||
| 208 | (FONTENUMPROC) add_one_font_entity_to_list, | ||
| 209 | (LPARAM) &match_data, 0); | ||
| 210 | release_frame_dc (f, dc); | ||
| 211 | |||
| 212 | return NILP (match_data.list) ? Qnil : XCAR (match_data.list); | ||
| 213 | } | 166 | } |
| 214 | 167 | ||
| 215 | |||
| 216 | /* w32 implementation of list_family for font backend. | 168 | /* w32 implementation of list_family for font backend. |
| 217 | List available families. The value is a list of family names | 169 | List available families. The value is a list of family names |
| 218 | (symbols). */ | 170 | (symbols). */ |
| @@ -240,7 +192,7 @@ w32font_list_family (frame) | |||
| 240 | /* w32 implementation of open for font backend. | 192 | /* w32 implementation of open for font backend. |
| 241 | Open a font specified by FONT_ENTITY on frame F. | 193 | Open a font specified by FONT_ENTITY on frame F. |
| 242 | If the font is scalable, open it with PIXEL_SIZE. */ | 194 | If the font is scalable, open it with PIXEL_SIZE. */ |
| 243 | static struct font * | 195 | struct font * |
| 244 | w32font_open (f, font_entity, pixel_size) | 196 | w32font_open (f, font_entity, pixel_size) |
| 245 | FRAME_PTR f; | 197 | FRAME_PTR f; |
| 246 | Lisp_Object font_entity; | 198 | Lisp_Object font_entity; |
| @@ -276,6 +228,8 @@ w32font_open (f, font_entity, pixel_size) | |||
| 276 | return NULL; | 228 | return NULL; |
| 277 | } | 229 | } |
| 278 | 230 | ||
| 231 | w32_font->owning_frame = f; | ||
| 232 | |||
| 279 | /* Get the metrics for this font. */ | 233 | /* Get the metrics for this font. */ |
| 280 | dc = get_frame_dc (f); | 234 | dc = get_frame_dc (f); |
| 281 | old_font = SelectObject (dc, hfont); | 235 | old_font = SelectObject (dc, hfont); |
| @@ -330,7 +284,7 @@ w32font_open (f, font_entity, pixel_size) | |||
| 330 | 284 | ||
| 331 | /* w32 implementation of close for font_backend. | 285 | /* w32 implementation of close for font_backend. |
| 332 | Close FONT on frame F. */ | 286 | Close FONT on frame F. */ |
| 333 | static void | 287 | void |
| 334 | w32font_close (f, font) | 288 | w32font_close (f, font) |
| 335 | FRAME_PTR f; | 289 | FRAME_PTR f; |
| 336 | struct font *font; | 290 | struct font *font; |
| @@ -353,7 +307,7 @@ w32font_close (f, font) | |||
| 353 | If FONT_ENTITY has a glyph for character C (Unicode code point), | 307 | If FONT_ENTITY has a glyph for character C (Unicode code point), |
| 354 | return 1. If not, return 0. If a font must be opened to check | 308 | return 1. If not, return 0. If a font must be opened to check |
| 355 | it, return -1. */ | 309 | it, return -1. */ |
| 356 | static int | 310 | int |
| 357 | w32font_has_char (entity, c) | 311 | w32font_has_char (entity, c) |
| 358 | Lisp_Object entity; | 312 | Lisp_Object entity; |
| 359 | int c; | 313 | int c; |
| @@ -379,7 +333,7 @@ w32font_has_char (entity, c) | |||
| 379 | /* w32 implementation of encode_char for font backend. | 333 | /* w32 implementation of encode_char for font backend. |
| 380 | Return a glyph code of FONT for characer C (Unicode code point). | 334 | Return a glyph code of FONT for characer C (Unicode code point). |
| 381 | If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */ | 335 | If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */ |
| 382 | static unsigned | 336 | unsigned |
| 383 | w32font_encode_char (font, c) | 337 | w32font_encode_char (font, c) |
| 384 | struct font *font; | 338 | struct font *font; |
| 385 | int c; | 339 | int c; |
| @@ -394,7 +348,7 @@ w32font_encode_char (font, c) | |||
| 394 | of METRICS. The glyphs are specified by their glyph codes in | 348 | of METRICS. The glyphs are specified by their glyph codes in |
| 395 | CODE (length NGLYPHS). Apparently metrics can be NULL, in this | 349 | CODE (length NGLYPHS). Apparently metrics can be NULL, in this |
| 396 | case just return the overall width. */ | 350 | case just return the overall width. */ |
| 397 | static int | 351 | int |
| 398 | w32font_text_extents (font, code, nglyphs, metrics) | 352 | w32font_text_extents (font, code, nglyphs, metrics) |
| 399 | struct font *font; | 353 | struct font *font; |
| 400 | unsigned *code; | 354 | unsigned *code; |
| @@ -403,13 +357,14 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 403 | { | 357 | { |
| 404 | int i; | 358 | int i; |
| 405 | HFONT old_font; | 359 | HFONT old_font; |
| 406 | /* FIXME: Be nice if we had a frame here, rather than getting the desktop's | 360 | HDC dc; |
| 407 | device context to measure against... */ | 361 | struct frame * f; |
| 408 | HDC dc = GetDC (NULL); | ||
| 409 | int total_width = 0; | 362 | int total_width = 0; |
| 410 | WORD *wcode = alloca(nglyphs * sizeof (WORD)); | 363 | WORD *wcode = alloca(nglyphs * sizeof (WORD)); |
| 411 | SIZE size; | 364 | SIZE size; |
| 412 | 365 | ||
| 366 | f = ((struct w32font_info *)font)->owning_frame; | ||
| 367 | dc = get_frame_dc (f); | ||
| 413 | old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont); | 368 | old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont); |
| 414 | 369 | ||
| 415 | if (metrics) | 370 | if (metrics) |
| @@ -452,7 +407,7 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 452 | { | 407 | { |
| 453 | /* Restore state and release DC. */ | 408 | /* Restore state and release DC. */ |
| 454 | SelectObject (dc, old_font); | 409 | SelectObject (dc, old_font); |
| 455 | ReleaseDC (NULL, dc); | 410 | release_frame_dc (f, dc); |
| 456 | 411 | ||
| 457 | return metrics->width; | 412 | return metrics->width; |
| 458 | } | 413 | } |
| @@ -495,7 +450,7 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 495 | 450 | ||
| 496 | /* Restore state and release DC. */ | 451 | /* Restore state and release DC. */ |
| 497 | SelectObject (dc, old_font); | 452 | SelectObject (dc, old_font); |
| 498 | ReleaseDC (NULL, dc); | 453 | release_frame_dc (f, dc); |
| 499 | 454 | ||
| 500 | return total_width; | 455 | return total_width; |
| 501 | } | 456 | } |
| @@ -513,7 +468,7 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 513 | and fonts in here and set them explicitly | 468 | and fonts in here and set them explicitly |
| 514 | */ | 469 | */ |
| 515 | 470 | ||
| 516 | static int | 471 | int |
| 517 | w32font_draw (s, from, to, x, y, with_background) | 472 | w32font_draw (s, from, to, x, y, with_background) |
| 518 | struct glyph_string *s; | 473 | struct glyph_string *s; |
| 519 | int from, to, x, y, with_background; | 474 | int from, to, x, y, with_background; |
| @@ -655,6 +610,81 @@ w32font_otf_drive (struct font *font, Lisp_Object features, | |||
| 655 | int alternate_subst); | 610 | int alternate_subst); |
| 656 | */ | 611 | */ |
| 657 | 612 | ||
| 613 | /* Internal implementation of w32font_list. | ||
| 614 | Additional parameter opentype_only restricts the returned fonts to | ||
| 615 | opentype fonts, which can be used with the Uniscribe backend. */ | ||
| 616 | Lisp_Object | ||
| 617 | w32font_list_internal (frame, font_spec, opentype_only) | ||
| 618 | Lisp_Object frame, font_spec; | ||
| 619 | int opentype_only; | ||
| 620 | { | ||
| 621 | struct font_callback_data match_data; | ||
| 622 | HDC dc; | ||
| 623 | FRAME_PTR f = XFRAME (frame); | ||
| 624 | |||
| 625 | match_data.orig_font_spec = font_spec; | ||
| 626 | match_data.list = Qnil; | ||
| 627 | match_data.frame = frame; | ||
| 628 | |||
| 629 | bzero (&match_data.pattern, sizeof (LOGFONT)); | ||
| 630 | fill_in_logfont (f, &match_data.pattern, font_spec); | ||
| 631 | |||
| 632 | match_data.opentype_only = opentype_only; | ||
| 633 | if (opentype_only) | ||
| 634 | match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS; | ||
| 635 | |||
| 636 | if (match_data.pattern.lfFaceName[0] == '\0') | ||
| 637 | { | ||
| 638 | /* EnumFontFamiliesEx does not take other fields into account if | ||
| 639 | font name is blank, so need to use two passes. */ | ||
| 640 | list_all_matching_fonts (&match_data); | ||
| 641 | } | ||
| 642 | else | ||
| 643 | { | ||
| 644 | dc = get_frame_dc (f); | ||
| 645 | |||
| 646 | EnumFontFamiliesEx (dc, &match_data.pattern, | ||
| 647 | (FONTENUMPROC) add_font_entity_to_list, | ||
| 648 | (LPARAM) &match_data, 0); | ||
| 649 | release_frame_dc (f, dc); | ||
| 650 | } | ||
| 651 | |||
| 652 | return NILP (match_data.list) ? null_vector : Fvconcat (1, &match_data.list); | ||
| 653 | } | ||
| 654 | |||
| 655 | /* Internal implementation of w32font_match. | ||
| 656 | Additional parameter opentype_only restricts the returned fonts to | ||
| 657 | opentype fonts, which can be used with the Uniscribe backend. */ | ||
| 658 | Lisp_Object | ||
| 659 | w32font_match_internal (frame, font_spec, opentype_only) | ||
| 660 | Lisp_Object frame, font_spec; | ||
| 661 | int opentype_only; | ||
| 662 | { | ||
| 663 | struct font_callback_data match_data; | ||
| 664 | HDC dc; | ||
| 665 | FRAME_PTR f = XFRAME (frame); | ||
| 666 | |||
| 667 | match_data.orig_font_spec = font_spec; | ||
| 668 | match_data.frame = frame; | ||
| 669 | match_data.list = Qnil; | ||
| 670 | |||
| 671 | bzero (&match_data.pattern, sizeof (LOGFONT)); | ||
| 672 | fill_in_logfont (f, &match_data.pattern, font_spec); | ||
| 673 | |||
| 674 | match_data.opentype_only = opentype_only; | ||
| 675 | if (opentype_only) | ||
| 676 | match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS; | ||
| 677 | |||
| 678 | dc = get_frame_dc (f); | ||
| 679 | |||
| 680 | EnumFontFamiliesEx (dc, &match_data.pattern, | ||
| 681 | (FONTENUMPROC) add_one_font_entity_to_list, | ||
| 682 | (LPARAM) &match_data, 0); | ||
| 683 | release_frame_dc (f, dc); | ||
| 684 | |||
| 685 | return NILP (match_data.list) ? Qnil : XCAR (match_data.list); | ||
| 686 | } | ||
| 687 | |||
| 658 | /* Callback function for EnumFontFamiliesEx. | 688 | /* Callback function for EnumFontFamiliesEx. |
| 659 | * Adds the name of a font to a Lisp list (passed in as the lParam arg). */ | 689 | * Adds the name of a font to a Lisp list (passed in as the lParam arg). */ |
| 660 | static int CALLBACK | 690 | static int CALLBACK |
| @@ -977,15 +1007,11 @@ add_font_entity_to_list (logical_font, physical_font, font_type, lParam) | |||
| 977 | struct font_callback_data *match_data | 1007 | struct font_callback_data *match_data |
| 978 | = (struct font_callback_data *) lParam; | 1008 | = (struct font_callback_data *) lParam; |
| 979 | 1009 | ||
| 980 | if (logfonts_match (&logical_font->elfLogFont, &match_data->pattern) | 1010 | if ((!match_data->opentype_only |
| 1011 | || (physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE)) | ||
| 1012 | && logfonts_match (&logical_font->elfLogFont, &match_data->pattern) | ||
| 981 | && font_matches_spec (font_type, physical_font, | 1013 | && font_matches_spec (font_type, physical_font, |
| 982 | match_data->orig_font_spec) | 1014 | match_data->orig_font_spec)) |
| 983 | /* Avoid Windows substitution so we can control substitution with | ||
| 984 | alternate-fontname-alist. Full name may have Bold and/or Italic | ||
| 985 | appended, so only compare the beginning of the name. */ | ||
| 986 | && !strnicmp ((char *)&logical_font->elfFullName, | ||
| 987 | (char *)&match_data->pattern.lfFaceName, | ||
| 988 | min (strlen(&match_data->pattern.lfFaceName), LF_FACESIZE))) | ||
| 989 | { | 1015 | { |
| 990 | Lisp_Object entity | 1016 | Lisp_Object entity |
| 991 | = w32_enumfont_pattern_entity (match_data->frame, logical_font, | 1017 | = w32_enumfont_pattern_entity (match_data->frame, logical_font, |