Mercurial > emacs
changeset 32720:8530cd0a7455
(w32_per_char_metric): Remove HDC argument. Use
cached information in emulated XFontStruct to handle common cases
quickly. Do not allocate XCharStruct for return.
(w32_native_per_char_metric): New function.
(w32_bdf_per_char_metric): Fill in supplied XCharStruct instead of
allocating one.
(x_produce_glyphs): Don't get an HDC. Change calls to
w32_per_char_metric to match arg change above. Remove calls to
free results.
(w32_get_glyph_overhangs): Ditto.
(w32_cache_char_metrics): New function.
author | Andrew Innes <andrewi@gnu.org> |
---|---|
date | Sat, 21 Oct 2000 13:26:41 +0000 |
parents | e6e8694bf692 |
children | 0574ffc14f77 |
files | src/w32term.c |
diffstat | 1 files changed, 130 insertions(+), 102 deletions(-) [+] |
line wrap: on
line diff
--- a/src/w32term.c Sat Oct 21 13:24:14 2000 +0000 +++ b/src/w32term.c Sat Oct 21 13:26:41 2000 +0000 @@ -79,15 +79,6 @@ ZV_LINE_BITMAP }; -enum w32_char_font_type -{ - UNKNOWN_FONT, - ANSI_FONT, - UNICODE_FONT, - BDF_1D_FONT, - BDF_2D_FONT -}; - /* Bitmaps are all unsigned short, as Windows requires bitmap data to be Word aligned. For some reason they are horizontally reflected compared to how they appear on X, so changes in xterm.c should be @@ -189,6 +180,8 @@ extern int w32_codepage_for_font (char *fontname); +extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp, + unsigned char *text, int dim); extern Lisp_Object Vwindow_system; #define x_any_window_to_frame x_window_to_frame @@ -1101,7 +1094,7 @@ int *)); static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int, int, wchar_t *, int)); -static XCharStruct *w32_per_char_metric P_ ((HDC hdc, XFontStruct *, +static XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, enum w32_char_font_type)); static enum w32_char_font_type @@ -1130,15 +1123,15 @@ If CHAR2B is not contained in FONT, the font's default character metric is returned. */ -static XCharStruct * -w32_bdf_per_char_metric (font, char2b, dim) +static int +w32_bdf_per_char_metric (font, char2b, dim, pcm) XFontStruct *font; wchar_t *char2b; int dim; + XCharStruct * pcm; { glyph_metric * bdf_metric; char buf[2]; - XCharStruct * pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct)); if (dim == 1) buf[0] = (char)char2b; @@ -1158,42 +1151,32 @@ - (bdf_metric->bbox + bdf_metric->bbw); pcm->ascent = bdf_metric->bboy + bdf_metric->bbh; pcm->descent = bdf_metric->bboy; - } - else - { - xfree (pcm); - return NULL; - } - return pcm; -} - - -static XCharStruct * -w32_per_char_metric (hdc, font, char2b, font_type) - HDC hdc; + + return 1; + } + return 0; +} + + +static int +w32_native_per_char_metric (font, char2b, font_type, pcm) XFontStruct *font; wchar_t *char2b; enum w32_char_font_type font_type; + XCharStruct * pcm; { /* NTEMACS_TODO: Use GetGlyphOutline where possible (no Unicode version on W9x) */ - /* The result metric information. */ - XCharStruct *pcm; - BOOL retval; + HDC hdc = GetDC (NULL); + HFONT old_font; + BOOL retval = FALSE; xassert (font && char2b); - xassert (font_type != UNKNOWN_FONT); - - if (font_type == BDF_1D_FONT) - return w32_bdf_per_char_metric (font, char2b, 1); - else if (font_type == BDF_2D_FONT) - return w32_bdf_per_char_metric (font, char2b, 2); - - pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct)); - - if (font->hfont) - SelectObject (hdc, font->hfont); + xassert (font->hfont); + xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT); + + old_font = SelectObject (hdc, font->hfont); if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0) { @@ -1201,7 +1184,7 @@ if (font_type == UNICODE_FONT) retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths); - else if (font_type == ANSI_FONT) + else retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths); if (retval) @@ -1209,61 +1192,119 @@ pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC; pcm->lbearing = char_widths.abcA; pcm->rbearing = pcm->width - char_widths.abcC; + pcm->ascent = FONT_BASE (font); + pcm->descent = FONT_DESCENT (font); } + } + + if (!retval) + { + /* Either font is not a True-type font, or GetCharABCWidthsW + failed (it is not supported on Windows 9x for instance), so we + can't determine the full info we would like. All is not lost + though - we can call GetTextExtentPoint32 to get rbearing and + deduce width based on the font's per-string overhang. lbearing + is assumed to be zero. */ + SIZE sz; + + if (font_type == UNICODE_FONT) + retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz); else + retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz); + + if (retval) { - /* Windows 9x does not implement GetCharABCWidthsW, so if that - failed, try GetTextExtentPoint32W, which is implemented and - at least gives us some of the info we are after (total - character width). */ - SIZE sz; - - if (font_type == UNICODE_FONT) - retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz); - - if (retval) - { - pcm->width = sz.cx; - pcm->rbearing = sz.cx; - pcm->lbearing = 0; - } - else - { - xfree (pcm); - return NULL; - } + pcm->width = sz.cx - font->tm.tmOverhang; + pcm->rbearing = sz.cx; + pcm->lbearing = 0; + pcm->ascent = FONT_BASE (font); + pcm->descent = FONT_DESCENT (font); } } + + + if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0) + { + retval = FALSE; + } + + SelectObject (hdc, old_font); + ReleaseDC (NULL, hdc); + + return retval; +} + + +static XCharStruct * +w32_per_char_metric (font, char2b, font_type) + XFontStruct *font; + wchar_t *char2b; + enum w32_char_font_type font_type; +{ + /* The result metric information. */ + XCharStruct *pcm; + BOOL retval; + + xassert (font && char2b); + xassert (font_type != UNKNOWN_FONT); + + /* Handle the common cases quickly. */ + if (font->per_char == NULL) + /* TODO: determine whether char2b exists in font? */ + return &font->max_bounds; + else if (*char2b < 128) + return &font->per_char[*char2b]; + + pcm = &font->scratch; + + if (font_type == BDF_1D_FONT) + retval = w32_bdf_per_char_metric (font, char2b, 1, pcm); + else if (font_type == BDF_2D_FONT) + retval = w32_bdf_per_char_metric (font, char2b, 2, pcm); + else + retval = w32_native_per_char_metric (font, char2b, font_type, pcm); + + if (retval) + return pcm; + + return NULL; +} + +void +w32_cache_char_metrics (font) + XFontStruct *font; +{ + wchar_t char2b = L'x'; + + /* Cache char metrics for the common cases. */ + if (font->bdf) + { + /* TODO: determine whether font is fixed-pitch. */ + w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds); + } else { - /* Do our best to deduce the desired metrics data for non-Truetype - fonts (generally, raster fonts). */ - INT char_width; - - retval = GetCharWidth (hdc, *char2b, *char2b, &char_width); - if (retval) + if ((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0) { - pcm->width = char_width; - pcm->rbearing = char_width; - pcm->lbearing = 0; + /* Font is not fixed pitch, so cache per_char info for the + ASCII characters. It would be much more work, and probably + not worth it, to cache other chars, since we may change + between using Unicode and ANSI text drawing functions at + run-time. */ + int i; + + font->per_char = xmalloc (128 * sizeof(XCharStruct)); + for (i = 0; i < 128; i++) + { + char2b = i; + w32_native_per_char_metric (font, &char2b, ANSI_FONT, + &font->per_char[i]); + } } else - { - xfree (pcm); - return NULL; - } - } - - pcm->ascent = FONT_BASE (font); - pcm->descent = FONT_DESCENT (font); - - if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0) - { - xfree (pcm); - return NULL; - } - - return pcm; + w32_native_per_char_metric (font, &char2b, ANSI_FONT, + &font->max_bounds); + } } @@ -1893,7 +1934,6 @@ int font_not_found_p; struct font_info *font_info; int boff; /* baseline offset */ - HDC hdc; /* We may change it->multibyte_p upon unibyte<->multibyte conversion. So, save the current value now and restore it later. @@ -1906,8 +1946,6 @@ */ int saved_multibyte_p = it->multibyte_p; - hdc = get_frame_dc (it->f); - /* Maybe translate single-byte characters to multibyte, or the other way. */ it->char_to_display = it->c; @@ -1955,9 +1993,6 @@ boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; } - if (font->hfont) - SelectObject (hdc, font->hfont); - if (it->char_to_display >= ' ' && (!it->multibyte_p || it->char_to_display < 128)) { @@ -1966,7 +2001,7 @@ it->nglyphs = 1; - pcm = w32_per_char_metric (hdc, font, &char2b, + pcm = w32_per_char_metric (font, &char2b, font->bdf ? BDF_1D_FONT : ANSI_FONT); it->ascent = FONT_BASE (font) + boff; it->descent = FONT_DESCENT (font) - boff; @@ -2034,8 +2069,6 @@ glyph row. This is used to optimize X output code. */ if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width)) it->glyph_row->contains_overlapping_glyphs_p = 1; - if (pcm) - xfree (pcm); } } else if (it->char_to_display == '\n') @@ -2094,7 +2127,7 @@ else type = UNICODE_FONT; - pcm = w32_per_char_metric (hdc, font, &char2b, type); + pcm = w32_per_char_metric (font, &char2b, type); if (font_not_found_p || !pcm) { @@ -2141,11 +2174,7 @@ if (it->glyph_row) x_append_glyph (it); - - if (pcm) - xfree (pcm); } - release_frame_dc (it->f, hdc); it->multibyte_p = saved_multibyte_p; } else if (it->what == IT_COMPOSITION) @@ -2798,14 +2827,13 @@ font = face->font; if (font - && (pcm = w32_per_char_metric (hdc, font, &char2b, + && (pcm = w32_per_char_metric (font, &char2b, glyph->w32_font_type))) { if (pcm->rbearing > pcm->width) *right = pcm->rbearing - pcm->width; if (pcm->lbearing < 0) *left = -pcm->lbearing; - xfree (pcm); } } }