[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: font-backend
From: |
YAMAMOTO Mitsuharu |
Subject: |
Re: font-backend |
Date: |
Sat, 23 Feb 2008 11:44:32 +0900 |
User-agent: |
Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.8 (Shijō) APEL/10.6 Emacs/23.0.50 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI) |
>>>>> On Sat, 23 Feb 2008 02:23:26 +0000, Jason Rumney <address@hidden> said:
>> I'm developing a font backend driver using Core Text, which is a
>> new framework available from Mac OS X 10.5. It was slower than
>> Emacs 22 first, but now it shows good performance with caching the
>> results of metrics calculations.
> Yes, it is definitely the metrics calculations that are slowing
> things down on Windows too. I added some code to cache the metrics
> for ASCII characters some time ago, but the problem remains for
> buffers containing many non-ASCII characters.
But it still does get_frame_dc and SelectObject even for the
ASCII-only case. I think this can be deferred until cache miss
happens.
FWIW, below shows what the Core Text font backend is doing on the
metrics caching. I assume the height of a valid metrics value is
always nonnegative.
YAMAMOTO Mitsuharu
address@hidden
/* The actual structure for Mac Core Text font that can be casted to
struct font. */
struct ctfont_info
{
struct font font;
CTFontRef ctfont;
unsigned synthetic_italic_p : 1;
unsigned synthetic_bold_p : 1;
short metrics_nrows;
struct font_metrics **metrics;
};
#define METRICS_NCOLS_PER_ROW (128)
enum metrics_status
{
METRICS_INVALID = -1, /* metrics entry is invalid */
METRICS_WIDTH_VALID = -2 /* width is valid but others are invalid */
};
#define METRICS_STATUS(metrics) ((metrics)->ascent + (metrics)->descent)
#define METRICS_SET_STATUS(metrics, status) \
((metrics)->ascent = 0, (metrics)->descent = (status))
static int
ctfont_glyph_extents (font, glyph, metrics)
struct font *font;
CGGlyph glyph;
struct font_metrics *metrics;
{
struct ctfont_info *ctfont_info = (struct ctfont_info *) font;
CTFontRef ctfont = ctfont_info->ctfont;
int row, col;
struct font_metrics *cache;
int width;
row = glyph / METRICS_NCOLS_PER_ROW;
col = glyph % METRICS_NCOLS_PER_ROW;
if (row >= ctfont_info->metrics_nrows)
{
ctfont_info->metrics =
xrealloc (ctfont_info->metrics,
sizeof (struct font_metrics *) * (row + 1));
bzero (ctfont_info->metrics + ctfont_info->metrics_nrows,
(sizeof (struct font_metrics *)
* (row + 1 - ctfont_info->metrics_nrows)));
ctfont_info->metrics_nrows = row + 1;
}
if (ctfont_info->metrics[row] == NULL)
{
struct font_metrics *new;
int i;
new = xmalloc (sizeof (struct font_metrics) * METRICS_NCOLS_PER_ROW);
for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
METRICS_SET_STATUS (new + i, METRICS_INVALID);
ctfont_info->metrics[row] = new;
}
cache = ctfont_info->metrics[row] + col;
if (METRICS_STATUS (cache) == METRICS_INVALID)
{
cache->width =
CTFontGetAdvancesForGlyphs (ctfont, kCTFontDefaultOrientation,
&glyph, NULL, 1) + 0.5;
METRICS_SET_STATUS (cache, METRICS_WIDTH_VALID);
}
width = cache->width;
if (metrics)
{
if (METRICS_STATUS (cache) == METRICS_WIDTH_VALID)
{
CGRect bounds;
bounds = CTFontGetBoundingRectsForGlyphs (ctfont,
kCTFontDefaultOrientation,
&glyph, NULL, 1);
if (ctfont_info->synthetic_italic_p)
bounds = CGRectApplyAffineTransform (bounds, synthetic_italic_atfm);
if (ctfont_info->synthetic_bold_p)
{
CGFloat d = - synthetic_bold_factor * CTFontGetSize (ctfont) / 2;
bounds = CGRectInset (bounds, d, d);
}
bounds = CGRectIntegral (bounds);
cache->lbearing = CGRectGetMinX (bounds);
cache->rbearing = CGRectGetMaxX (bounds);
cache->width = width;
cache->ascent = CGRectGetMaxY (bounds);
cache->descent = -CGRectGetMinY (bounds);
}
*metrics = *cache;
}
return width;
}
static int
ctfont_text_extents (font, code, nglyphs, metrics)
struct font *font;
unsigned *code;
int nglyphs;
struct font_metrics *metrics;
{
int width, i;
BLOCK_INPUT;
width = ctfont_glyph_extents (font, code[0], metrics);
for (i = 1; i < nglyphs; i++)
{
struct font_metrics m;
int w = ctfont_glyph_extents (font, code[i], metrics ? &m : NULL);
if (metrics)
{
if (width + m.lbearing < metrics->lbearing)
metrics->lbearing = width + m.lbearing;
if (width + m.rbearing > metrics->rbearing)
metrics->rbearing = width + m.rbearing;
if (m.ascent > metrics->ascent)
metrics->ascent = m.ascent;
if (m.descent > metrics->descent)
metrics->descent = m.descent;
}
width += w;
}
UNBLOCK_INPUT;
if (metrics)
metrics->width = width;
return width;
}
- Re: font-backend, (continued)
- Re: font-backend, Miles Bader, 2008/02/15
- Re: font-backend, Eli Zaretskii, 2008/02/16
- Re: font-backend, Miles Bader, 2008/02/16
- Re: font-backend, Jason Rumney, 2008/02/16
- Re: font-backend, Kenichi Handa, 2008/02/17
- Re: font-backend, finalpatch, 2008/02/22
- Re: font-backend, Stefan Monnier, 2008/02/22
- Re: font-backend, Feng Li, 2008/02/23
- Re: font-backend, YAMAMOTO Mitsuharu, 2008/02/22
- Re: font-backend, Jason Rumney, 2008/02/22
- Re: font-backend,
YAMAMOTO Mitsuharu <=
- Re: font-backend, Jason Rumney, 2008/02/24
- Re: font-backend, finalpatch, 2008/02/25
- Re: font-backend, Jason Rumney, 2008/02/22
- Re: font-backend, Feng Li, 2008/02/23
- Re: 23.0.60; show-paren-mode causes abnormal vertical lines on Win32., Stefan Monnier, 2008/02/15
- Re: 23.0.60; show-paren-mode causes abnormal vertical lines on Win32., Dan Nicolaescu, 2008/02/16
- Re: 23.0.60; show-paren-mode causes abnormal vertical lines on Win32., Stefan Monnier, 2008/02/19
- Re: 23.0.60; show-paren-mode causes abnormal vertical lines on Win32., Dan Nicolaescu, 2008/02/19
- Re: 23.0.60; show-paren-mode causes abnormal vertical lines on Win32., Richard Stallman, 2008/02/17
- Message not available
- Re: 23.0.60; show-paren-mode causes abnormal vertical lines on Win32., Jason Rumney, 2008/02/15