mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-24 19:03:29 +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:
parent
aa2ee344e3
commit
82f9d56522
214
src/w32term.c
214
src/w32term.c
@ -79,15 +79,6 @@ enum bitmap_type
|
|||||||
ZV_LINE_BITMAP
|
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
|
/* Bitmaps are all unsigned short, as Windows requires bitmap data to
|
||||||
be Word aligned. For some reason they are horizontally reflected
|
be Word aligned. For some reason they are horizontally reflected
|
||||||
compared to how they appear on X, so changes in xterm.c should be
|
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 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;
|
extern Lisp_Object Vwindow_system;
|
||||||
|
|
||||||
#define x_any_window_to_frame x_window_to_frame
|
#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 *));
|
int *));
|
||||||
static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
|
static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
|
||||||
int, wchar_t *, 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 *,
|
wchar_t *,
|
||||||
enum w32_char_font_type));
|
enum w32_char_font_type));
|
||||||
static 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
|
If CHAR2B is not contained in FONT, the font's default character
|
||||||
metric is returned. */
|
metric is returned. */
|
||||||
|
|
||||||
static XCharStruct *
|
static int
|
||||||
w32_bdf_per_char_metric (font, char2b, dim)
|
w32_bdf_per_char_metric (font, char2b, dim, pcm)
|
||||||
XFontStruct *font;
|
XFontStruct *font;
|
||||||
wchar_t *char2b;
|
wchar_t *char2b;
|
||||||
int dim;
|
int dim;
|
||||||
|
XCharStruct * pcm;
|
||||||
{
|
{
|
||||||
glyph_metric * bdf_metric;
|
glyph_metric * bdf_metric;
|
||||||
char buf[2];
|
char buf[2];
|
||||||
XCharStruct * pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct));
|
|
||||||
|
|
||||||
if (dim == 1)
|
if (dim == 1)
|
||||||
buf[0] = (char)char2b;
|
buf[0] = (char)char2b;
|
||||||
@ -1158,42 +1151,32 @@ w32_bdf_per_char_metric (font, char2b, dim)
|
|||||||
- (bdf_metric->bbox + bdf_metric->bbw);
|
- (bdf_metric->bbox + bdf_metric->bbw);
|
||||||
pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
|
pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
|
||||||
pcm->descent = bdf_metric->bboy;
|
pcm->descent = bdf_metric->bboy;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
return 0;
|
||||||
{
|
|
||||||
xfree (pcm);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return pcm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static XCharStruct *
|
static int
|
||||||
w32_per_char_metric (hdc, font, char2b, font_type)
|
w32_native_per_char_metric (font, char2b, font_type, pcm)
|
||||||
HDC hdc;
|
|
||||||
XFontStruct *font;
|
XFontStruct *font;
|
||||||
wchar_t *char2b;
|
wchar_t *char2b;
|
||||||
enum w32_char_font_type font_type;
|
enum w32_char_font_type font_type;
|
||||||
|
XCharStruct * pcm;
|
||||||
{
|
{
|
||||||
/* NTEMACS_TODO: Use GetGlyphOutline where possible (no Unicode
|
/* NTEMACS_TODO: Use GetGlyphOutline where possible (no Unicode
|
||||||
version on W9x) */
|
version on W9x) */
|
||||||
|
|
||||||
/* The result metric information. */
|
HDC hdc = GetDC (NULL);
|
||||||
XCharStruct *pcm;
|
HFONT old_font;
|
||||||
BOOL retval;
|
BOOL retval = FALSE;
|
||||||
|
|
||||||
xassert (font && char2b);
|
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)
|
old_font = SelectObject (hdc, font->hfont);
|
||||||
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);
|
|
||||||
|
|
||||||
if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
|
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)
|
if (font_type == UNICODE_FONT)
|
||||||
retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
|
retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
|
||||||
else if (font_type == ANSI_FONT)
|
else
|
||||||
retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
|
retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
|
||||||
|
|
||||||
if (retval)
|
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->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
|
||||||
pcm->lbearing = char_widths.abcA;
|
pcm->lbearing = char_widths.abcA;
|
||||||
pcm->rbearing = pcm->width - char_widths.abcC;
|
pcm->rbearing = pcm->width - char_widths.abcC;
|
||||||
}
|
pcm->ascent = FONT_BASE (font);
|
||||||
else
|
pcm->descent = FONT_DESCENT (font);
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
if (retval)
|
||||||
{
|
{
|
||||||
pcm->width = char_width;
|
pcm->width = sz.cx - font->tm.tmOverhang;
|
||||||
pcm->rbearing = char_width;
|
pcm->rbearing = sz.cx;
|
||||||
pcm->lbearing = 0;
|
pcm->lbearing = 0;
|
||||||
}
|
pcm->ascent = FONT_BASE (font);
|
||||||
else
|
pcm->descent = FONT_DESCENT (font);
|
||||||
{
|
|
||||||
xfree (pcm);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcm->ascent = FONT_BASE (font);
|
|
||||||
pcm->descent = FONT_DESCENT (font);
|
|
||||||
|
|
||||||
if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
|
if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
|
||||||
{
|
{
|
||||||
xfree (pcm);
|
retval = FALSE;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
int font_not_found_p;
|
||||||
struct font_info *font_info;
|
struct font_info *font_info;
|
||||||
int boff; /* baseline offset */
|
int boff; /* baseline offset */
|
||||||
HDC hdc;
|
|
||||||
/* We may change it->multibyte_p upon unibyte<->multibyte
|
/* We may change it->multibyte_p upon unibyte<->multibyte
|
||||||
conversion. So, save the current value now and restore it
|
conversion. So, save the current value now and restore it
|
||||||
later.
|
later.
|
||||||
@ -1906,8 +1946,6 @@ x_produce_glyphs (it)
|
|||||||
*/
|
*/
|
||||||
int saved_multibyte_p = it->multibyte_p;
|
int saved_multibyte_p = it->multibyte_p;
|
||||||
|
|
||||||
hdc = get_frame_dc (it->f);
|
|
||||||
|
|
||||||
/* Maybe translate single-byte characters to multibyte, or the
|
/* Maybe translate single-byte characters to multibyte, or the
|
||||||
other way. */
|
other way. */
|
||||||
it->char_to_display = it->c;
|
it->char_to_display = it->c;
|
||||||
@ -1955,9 +1993,6 @@ x_produce_glyphs (it)
|
|||||||
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
|
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font->hfont)
|
|
||||||
SelectObject (hdc, font->hfont);
|
|
||||||
|
|
||||||
if (it->char_to_display >= ' '
|
if (it->char_to_display >= ' '
|
||||||
&& (!it->multibyte_p || it->char_to_display < 128))
|
&& (!it->multibyte_p || it->char_to_display < 128))
|
||||||
{
|
{
|
||||||
@ -1966,7 +2001,7 @@ x_produce_glyphs (it)
|
|||||||
|
|
||||||
it->nglyphs = 1;
|
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);
|
font->bdf ? BDF_1D_FONT : ANSI_FONT);
|
||||||
it->ascent = FONT_BASE (font) + boff;
|
it->ascent = FONT_BASE (font) + boff;
|
||||||
it->descent = FONT_DESCENT (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. */
|
glyph row. This is used to optimize X output code. */
|
||||||
if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
|
if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
|
||||||
it->glyph_row->contains_overlapping_glyphs_p = 1;
|
it->glyph_row->contains_overlapping_glyphs_p = 1;
|
||||||
if (pcm)
|
|
||||||
xfree (pcm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (it->char_to_display == '\n')
|
else if (it->char_to_display == '\n')
|
||||||
@ -2094,7 +2127,7 @@ x_produce_glyphs (it)
|
|||||||
else
|
else
|
||||||
type = UNICODE_FONT;
|
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)
|
if (font_not_found_p || !pcm)
|
||||||
{
|
{
|
||||||
@ -2141,11 +2174,7 @@ x_produce_glyphs (it)
|
|||||||
|
|
||||||
if (it->glyph_row)
|
if (it->glyph_row)
|
||||||
x_append_glyph (it);
|
x_append_glyph (it);
|
||||||
|
|
||||||
if (pcm)
|
|
||||||
xfree (pcm);
|
|
||||||
}
|
}
|
||||||
release_frame_dc (it->f, hdc);
|
|
||||||
it->multibyte_p = saved_multibyte_p;
|
it->multibyte_p = saved_multibyte_p;
|
||||||
}
|
}
|
||||||
else if (it->what == IT_COMPOSITION)
|
else if (it->what == IT_COMPOSITION)
|
||||||
@ -2798,14 +2827,13 @@ w32_get_glyph_overhangs (hdc, glyph, f, left, right)
|
|||||||
font = face->font;
|
font = face->font;
|
||||||
|
|
||||||
if (font
|
if (font
|
||||||
&& (pcm = w32_per_char_metric (hdc, font, &char2b,
|
&& (pcm = w32_per_char_metric (font, &char2b,
|
||||||
glyph->w32_font_type)))
|
glyph->w32_font_type)))
|
||||||
{
|
{
|
||||||
if (pcm->rbearing > pcm->width)
|
if (pcm->rbearing > pcm->width)
|
||||||
*right = pcm->rbearing - pcm->width;
|
*right = pcm->rbearing - pcm->width;
|
||||||
if (pcm->lbearing < 0)
|
if (pcm->lbearing < 0)
|
||||||
*left = -pcm->lbearing;
|
*left = -pcm->lbearing;
|
||||||
xfree (pcm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user