aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Rumney2008-07-30 21:45:35 +0000
committerJason Rumney2008-07-30 21:45:35 +0000
commitbd187c49598c3a6db2ed0cbfe84a36171be7121d (patch)
tree9e01bcbe6374049c336c19cd1102d88e7d4e87b0
parent00fade45540b2f21c3bfc040621909da1601cfe5 (diff)
downloademacs-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/ChangeLog11
-rw-r--r--src/w32font.c107
-rw-r--r--src/w32font.h2
-rw-r--r--src/w32uniscribe.c3
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 @@
12008-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
12008-07-30 Chong Yidong <cyd@stupidchicken.com> 122008-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 */
319static unsigned 329static unsigned
320w32font_encode_char (font, c) 330w32font_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
49struct w32font_info 49struct 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;