comparison src/w32font.c @ 97135:09abb4487286

* 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.
author Jason Rumney <jasonr@gnu.org>
date Wed, 30 Jul 2008 21:45:35 +0000
parents 32466fc89674
children 3c62347bccdb
comparison
equal deleted inserted replaced
97134:b29e23ccc6f8 97135:09abb4487286
232 w32font_open (f, font_entity, pixel_size) 232 w32font_open (f, font_entity, pixel_size)
233 FRAME_PTR f; 233 FRAME_PTR f;
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 238 = font_make_object (VECSIZE (struct w32font_info),
239 font_object = font_make_object (VECSIZE (struct w32font_info), 239 font_entity, pixel_size);
240 font_entity, pixel_size); 240 struct w32font_info *w32_font
241 = (struct w32font_info *) XFONT_OBJECT (font_object);
242
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))
244 { 246 {
245 return Qnil; 247 return Qnil;
246 } 248 }
249
250 /* GDI backend does not use glyph indices. */
251 w32_font->glyph_idx = 0;
247 252
248 return font_object; 253 return font_object;
249 } 254 }
250 255
251 /* w32 implementation of close for font_backend. 256 /* w32 implementation of close for font_backend.
313 return 0; 318 return 0;
314 } 319 }
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; 335
326 HFONT old_font; 336 if (c < w32_font->metrics.tmFirstChar
327 DWORD retval; 337 || c > w32_font->metrics.tmLastChar)
328 GCP_RESULTSW result; 338 return FONT_INVALID_CODE;
329 wchar_t in[2]; 339 else
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; 340 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
362 dc = get_frame_dc (f);
363 old_font = SelectObject (dc, w32_font->hfont);
364
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
384 {
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.
397 Perform the size computation of glyphs of FONT and fillin members 344 Perform the size computation of glyphs of FONT and fillin members
398 of METRICS. The glyphs are specified by their glyph codes in 345 of METRICS. The glyphs are specified by their glyph codes in
818 HDC dc; 765 HDC dc;
819 HFONT hfont, old_font; 766 HFONT hfont, old_font;
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;
827 774
828 if (!font) 775 if (!font)
850 /* Get the metrics for this font. */ 797 /* Get the metrics for this font. */
851 dc = get_frame_dc (f); 798 dc = get_frame_dc (f);
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;
876 w32_font->n_cache_blocks = 0; 819 w32_font->n_cache_blocks = 0;
877 820