1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-09 15:50:21 +00:00

(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.
This commit is contained in:
Andrew Innes 2000-10-21 13:26:41 +00:00
parent aa2ee344e3
commit 82f9d56522

View File

@ -79,15 +79,6 @@ enum bitmap_type
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 void w32_menu_display_help (HMENU menu, UINT menu_item, UINT flags);
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 @@ static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
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 @@ static void x_produce_image_glyph P_ ((struct it *it));
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 @@ w32_bdf_per_char_metric (font, char2b, dim)
- (bdf_metric->bbox + bdf_metric->bbw);
pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
pcm->descent = bdf_metric->bboy;
return 1;
}
else
{
xfree (pcm);
return NULL;
}
return pcm;
return 0;
}
static XCharStruct *
w32_per_char_metric (hdc, font, char2b, font_type)
HDC hdc;
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);
xassert (font->hfont);
xassert (font_type == UNICODE_FONT || font_type == ANSI_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);
old_font = SelectObject (hdc, font->hfont);
if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
{
@ -1201,7 +1184,7 @@ w32_per_char_metric (hdc, font, char2b, font_type)
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 @@ w32_per_char_metric (hdc, font, char2b, font_type)
pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
pcm->lbearing = char_widths.abcA;
pcm->rbearing = pcm->width - char_widths.abcC;
}
else
{
/* 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->ascent = FONT_BASE (font);
pcm->descent = FONT_DESCENT (font);
}
}
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)
{
/* 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)
{
pcm->width = char_width;
pcm->rbearing = char_width;
pcm->width = sz.cx - font->tm.tmOverhang;
pcm->rbearing = sz.cx;
pcm->lbearing = 0;
}
else
{
xfree (pcm);
return NULL;
pcm->ascent = FONT_BASE (font);
pcm->descent = FONT_DESCENT (font);
}
}
pcm->ascent = FONT_BASE (font);
pcm->descent = FONT_DESCENT (font);
if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
{
xfree (pcm);
return NULL;
retval = FALSE;
}
return pcm;
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
{
if ((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 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
w32_native_per_char_metric (font, &char2b, ANSI_FONT,
&font->max_bounds);
}
}
@ -1893,7 +1934,6 @@ x_produce_glyphs (it)
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 @@ x_produce_glyphs (it)
*/
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 @@ x_produce_glyphs (it)
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 @@ x_produce_glyphs (it)
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 @@ x_produce_glyphs (it)
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 @@ x_produce_glyphs (it)
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 @@ x_produce_glyphs (it)
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 @@ w32_get_glyph_overhangs (hdc, glyph, f, left, right)
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);
}
}
}