diff options
| author | Jason Rumney | 2008-07-30 21:45:35 +0000 |
|---|---|---|
| committer | Jason Rumney | 2008-07-30 21:45:35 +0000 |
| commit | bd187c49598c3a6db2ed0cbfe84a36171be7121d (patch) | |
| tree | 9e01bcbe6374049c336c19cd1102d88e7d4e87b0 | |
| parent | 00fade45540b2f21c3bfc040621909da1601cfe5 (diff) | |
| download | emacs-bd187c49598c3a6db2ed0cbfe84a36171be7121d.tar.gz emacs-bd187c49598c3a6db2ed0cbfe84a36171be7121d.zip | |
* w32font.h (struct w32font_info): Use unicode version of textmetrics.
* w32font.c (w32font_encode_char): Leave as unicode if in range.
(w32font_open_internal): Get unicode version of textmetrics.
Don't enable or disable glyph indices here.
(w32font_open): Disable use of glyph indices.
* w32uniscribe.c (uniscribe_open): Enable use of glyph indices.
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/w32font.c | 107 | ||||
| -rw-r--r-- | src/w32font.h | 2 | ||||
| -rw-r--r-- | src/w32uniscribe.c | 3 |
4 files changed, 40 insertions, 83 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index de9cd6a8f40..f4062fa765d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2008-07-30 Jason Rumney <jasonr@gnu.org> | ||
| 2 | |||
| 3 | * w32font.h (struct w32font_info): Use unicode version of textmetrics. | ||
| 4 | |||
| 5 | * w32font.c (w32font_encode_char): Leave as unicode if in range. | ||
| 6 | (w32font_open_internal): Get unicode version of textmetrics. | ||
| 7 | Don't enable or disable glyph indices here. | ||
| 8 | (w32font_open): Disable use of glyph indices. | ||
| 9 | |||
| 10 | * w32uniscribe.c (uniscribe_open): Enable use of glyph indices. | ||
| 11 | |||
| 1 | 2008-07-30 Chong Yidong <cyd@stupidchicken.com> | 12 | 2008-07-30 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 13 | ||
| 3 | * minibuf.c (Vread_buffer_function): Doc fix. | 14 | * minibuf.c (Vread_buffer_function): Doc fix. |
diff --git a/src/w32font.c b/src/w32font.c index ef8410915f2..4a2812560ee 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -234,10 +234,12 @@ w32font_open (f, font_entity, pixel_size) | |||
| 234 | Lisp_Object font_entity; | 234 | Lisp_Object font_entity; |
| 235 | int pixel_size; | 235 | int pixel_size; |
| 236 | { | 236 | { |
| 237 | Lisp_Object font_object; | 237 | Lisp_Object font_object |
| 238 | = font_make_object (VECSIZE (struct w32font_info), | ||
| 239 | font_entity, pixel_size); | ||
| 240 | struct w32font_info *w32_font | ||
| 241 | = (struct w32font_info *) XFONT_OBJECT (font_object); | ||
| 238 | 242 | ||
| 239 | font_object = font_make_object (VECSIZE (struct w32font_info), | ||
| 240 | font_entity, pixel_size); | ||
| 241 | ASET (font_object, FONT_TYPE_INDEX, Qgdi); | 243 | ASET (font_object, FONT_TYPE_INDEX, Qgdi); |
| 242 | 244 | ||
| 243 | if (!w32font_open_internal (f, font_entity, pixel_size, font_object)) | 245 | if (!w32font_open_internal (f, font_entity, pixel_size, font_object)) |
| @@ -245,6 +247,9 @@ w32font_open (f, font_entity, pixel_size) | |||
| 245 | return Qnil; | 247 | return Qnil; |
| 246 | } | 248 | } |
| 247 | 249 | ||
| 250 | /* GDI backend does not use glyph indices. */ | ||
| 251 | w32_font->glyph_idx = 0; | ||
| 252 | |||
| 248 | return font_object; | 253 | return font_object; |
| 249 | } | 254 | } |
| 250 | 255 | ||
| @@ -315,82 +320,24 @@ w32font_has_char (entity, c) | |||
| 315 | 320 | ||
| 316 | /* w32 implementation of encode_char for font backend. | 321 | /* w32 implementation of encode_char for font backend. |
| 317 | Return a glyph code of FONT for characer C (Unicode code point). | 322 | Return a glyph code of FONT for characer C (Unicode code point). |
| 318 | If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */ | 323 | If FONT doesn't have such a glyph, return FONT_INVALID_CODE. |
| 324 | |||
| 325 | For speed, the gdi backend uses unicode (Emacs calls encode_char | ||
| 326 | far too often for it to be efficient). But we still need to detect | ||
| 327 | which characters are not supported by the font. | ||
| 328 | */ | ||
| 319 | static unsigned | 329 | static unsigned |
| 320 | w32font_encode_char (font, c) | 330 | w32font_encode_char (font, c) |
| 321 | struct font *font; | 331 | struct font *font; |
| 322 | int c; | 332 | int c; |
| 323 | { | 333 | { |
| 324 | struct frame *f; | 334 | struct w32font_info * w32_font = (struct w32font_info *)font; |
| 325 | HDC dc; | ||
| 326 | HFONT old_font; | ||
| 327 | DWORD retval; | ||
| 328 | GCP_RESULTSW result; | ||
| 329 | wchar_t in[2]; | ||
| 330 | wchar_t out[2]; | ||
| 331 | int len; | ||
| 332 | struct w32font_info *w32_font = (struct w32font_info *) font; | ||
| 333 | |||
| 334 | /* If glyph indexing is not working for this font, just return the | ||
| 335 | unicode code-point. */ | ||
| 336 | if (!w32_font->glyph_idx) | ||
| 337 | return c; | ||
| 338 | |||
| 339 | if (c > 0xFFFF) | ||
| 340 | { | ||
| 341 | DWORD surrogate = c - 0x10000; | ||
| 342 | |||
| 343 | /* High surrogate: U+D800 - U+DBFF. */ | ||
| 344 | in[0] = 0xD800 + ((surrogate >> 10) & 0x03FF); | ||
| 345 | /* Low surrogate: U+DC00 - U+DFFF. */ | ||
| 346 | in[1] = 0xDC00 + (surrogate & 0x03FF); | ||
| 347 | len = 2; | ||
| 348 | } | ||
| 349 | else | ||
| 350 | { | ||
| 351 | in[0] = (wchar_t) c; | ||
| 352 | len = 1; | ||
| 353 | } | ||
| 354 | |||
| 355 | bzero (&result, sizeof (result)); | ||
| 356 | result.lStructSize = sizeof (result); | ||
| 357 | result.lpGlyphs = out; | ||
| 358 | result.nGlyphs = 2; | ||
| 359 | |||
| 360 | f = XFRAME (selected_frame); | ||
| 361 | 335 | ||
| 362 | dc = get_frame_dc (f); | 336 | if (c < w32_font->metrics.tmFirstChar |
| 363 | old_font = SelectObject (dc, w32_font->hfont); | 337 | || c > w32_font->metrics.tmLastChar) |
| 364 | 338 | return FONT_INVALID_CODE; | |
| 365 | /* GetCharacterPlacement is used here rather than GetGlyphIndices because | ||
| 366 | it is supported on Windows NT 4 and 9x/ME. But it cannot reliably report | ||
| 367 | missing glyphs, see below for workaround. */ | ||
| 368 | retval = GetCharacterPlacementW (dc, in, len, 0, &result, 0); | ||
| 369 | |||
| 370 | SelectObject (dc, old_font); | ||
| 371 | release_frame_dc (f, dc); | ||
| 372 | |||
| 373 | if (retval) | ||
| 374 | { | ||
| 375 | if (result.nGlyphs != 1 || !result.lpGlyphs[0] | ||
| 376 | /* GetCharacterPlacementW seems to return 3, which seems to be | ||
| 377 | the space glyph in most/all truetype fonts, instead of 0 | ||
| 378 | for unsupported glyphs. */ | ||
| 379 | || (result.lpGlyphs[0] == 3 && !iswspace (in[0]))) | ||
| 380 | return FONT_INVALID_CODE; | ||
| 381 | return result.lpGlyphs[0]; | ||
| 382 | } | ||
| 383 | else | 339 | else |
| 384 | { | 340 | return c; |
| 385 | int i; | ||
| 386 | /* Mark this font as not supporting glyph indices. This can happen | ||
| 387 | on Windows9x, and maybe with non-Truetype fonts on NT etc. */ | ||
| 388 | w32_font->glyph_idx = 0; | ||
| 389 | /* Clear metrics cache. */ | ||
| 390 | clear_cached_metrics (w32_font); | ||
| 391 | |||
| 392 | return c; | ||
| 393 | } | ||
| 394 | } | 341 | } |
| 395 | 342 | ||
| 396 | /* w32 implementation of text_extents for font backend. | 343 | /* w32 implementation of text_extents for font backend. |
| @@ -820,7 +767,7 @@ w32font_open_internal (f, font_entity, pixel_size, font_object) | |||
| 820 | Lisp_Object val, extra; | 767 | Lisp_Object val, extra; |
| 821 | struct w32font_info *w32_font; | 768 | struct w32font_info *w32_font; |
| 822 | struct font * font; | 769 | struct font * font; |
| 823 | OUTLINETEXTMETRIC* metrics = NULL; | 770 | OUTLINETEXTMETRICW* metrics = NULL; |
| 824 | 771 | ||
| 825 | w32_font = (struct w32font_info *) XFONT_OBJECT (font_object); | 772 | w32_font = (struct w32font_info *) XFONT_OBJECT (font_object); |
| 826 | font = (struct font *) w32_font; | 773 | font = (struct font *) w32_font; |
| @@ -852,24 +799,20 @@ w32font_open_internal (f, font_entity, pixel_size, font_object) | |||
| 852 | old_font = SelectObject (dc, hfont); | 799 | old_font = SelectObject (dc, hfont); |
| 853 | 800 | ||
| 854 | /* Try getting the outline metrics (only works for truetype fonts). */ | 801 | /* Try getting the outline metrics (only works for truetype fonts). */ |
| 855 | len = GetOutlineTextMetrics (dc, 0, NULL); | 802 | len = GetOutlineTextMetricsW (dc, 0, NULL); |
| 856 | if (len) | 803 | if (len) |
| 857 | { | 804 | { |
| 858 | metrics = (OUTLINETEXTMETRIC *) alloca (len); | 805 | metrics = (OUTLINETEXTMETRICW *) alloca (len); |
| 859 | if (GetOutlineTextMetrics (dc, len, metrics)) | 806 | if (GetOutlineTextMetricsW (dc, len, metrics)) |
| 860 | bcopy (&metrics->otmTextMetrics, &w32_font->metrics, | 807 | bcopy (&metrics->otmTextMetrics, &w32_font->metrics, |
| 861 | sizeof (TEXTMETRIC)); | 808 | sizeof (TEXTMETRICW)); |
| 862 | else | 809 | else |
| 863 | metrics = NULL; | 810 | metrics = NULL; |
| 864 | |||
| 865 | /* If it supports outline metrics, it should support Glyph Indices. */ | ||
| 866 | w32_font->glyph_idx = ETO_GLYPH_INDEX; | ||
| 867 | } | 811 | } |
| 868 | 812 | ||
| 869 | if (!metrics) | 813 | if (!metrics) |
| 870 | { | 814 | { |
| 871 | GetTextMetrics (dc, &w32_font->metrics); | 815 | GetTextMetricsW (dc, &w32_font->metrics); |
| 872 | w32_font->glyph_idx = 0; | ||
| 873 | } | 816 | } |
| 874 | 817 | ||
| 875 | w32_font->cached_metrics = NULL; | 818 | w32_font->cached_metrics = NULL; |
diff --git a/src/w32font.h b/src/w32font.h index 25cf4ece560..748b329f8da 100644 --- a/src/w32font.h +++ b/src/w32font.h | |||
| @@ -49,7 +49,7 @@ struct w32_metric_cache | |||
| 49 | struct w32font_info | 49 | struct w32font_info |
| 50 | { | 50 | { |
| 51 | struct font font; | 51 | struct font font; |
| 52 | TEXTMETRIC metrics; | 52 | TEXTMETRICW metrics; |
| 53 | unsigned int glyph_idx; | 53 | unsigned int glyph_idx; |
| 54 | struct w32_metric_cache **cached_metrics; | 54 | struct w32_metric_cache **cached_metrics; |
| 55 | int n_cache_blocks; | 55 | int n_cache_blocks; |
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c index da49036d010..e987b112a67 100644 --- a/src/w32uniscribe.c +++ b/src/w32uniscribe.c | |||
| @@ -135,6 +135,9 @@ uniscribe_open (f, font_entity, pixel_size) | |||
| 135 | /* Initialize the cache for this font. */ | 135 | /* Initialize the cache for this font. */ |
| 136 | uniscribe_font->cache = NULL; | 136 | uniscribe_font->cache = NULL; |
| 137 | 137 | ||
| 138 | /* Uniscribe backend uses glyph indices. */ | ||
| 139 | uniscribe_font->w32_font.glyph_idx = ETO_GLYPH_INDEX; | ||
| 140 | |||
| 138 | /* Mark the format as opentype */ | 141 | /* Mark the format as opentype */ |
| 139 | uniscribe_font->w32_font.font.props[FONT_FORMAT_INDEX] = Qopentype; | 142 | uniscribe_font->w32_font.font.props[FONT_FORMAT_INDEX] = Qopentype; |
| 140 | uniscribe_font->w32_font.font.driver = &uniscribe_font_driver; | 143 | uniscribe_font->w32_font.font.driver = &uniscribe_font_driver; |