From: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
To: Jason Rumney <jasonr@gnu.org>
Cc: finalpatch <fengli@gmail.com>, emacs-devel@gnu.org
Subject: Re: font-backend
Date: Sat, 23 Feb 2008 11:44:32 +0900 [thread overview]
Message-ID: <wl4pc0mlwv.wl%mituharu@math.s.chiba-u.ac.jp> (raw)
In-Reply-To: <47BF839E.1010402@gnu.org>
>>>>> On Sat, 23 Feb 2008 02:23:26 +0000, Jason Rumney <jasonr@gnu.org> 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
mituharu@math.s.chiba-u.ac.jp
/* 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;
}
next prev parent reply other threads:[~2008-02-23 2:44 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-15 0:43 23.0.60;show-paren-mode causes abnormal vertical lines on Win32 =?gb18030?B?0+G94A==?=
2008-02-15 9:12 ` 23.0.60; show-paren-mode " Jason Rumney
2008-02-15 14:24 ` Stefan Monnier
2008-02-15 21:44 ` Jason Rumney
2008-02-15 23:02 ` Juanma Barranquero
2008-02-15 23:16 ` Jason Rumney
2008-02-15 23:27 ` Juanma Barranquero
2008-02-15 23:31 ` font-backend [was Re: 23.0.60; show-paren-mode causes abnormal vertical lines on Win32.] Glenn Morris
2008-02-15 23:47 ` font-backend Miles Bader
2008-02-16 13:18 ` font-backend Eli Zaretskii
2008-02-16 13:27 ` font-backend Miles Bader
2008-02-16 17:12 ` font-backend Jason Rumney
2008-02-17 9:29 ` font-backend Kenichi Handa
2008-02-22 14:00 ` font-backend finalpatch
2008-02-22 16:43 ` font-backend Stefan Monnier
2008-02-23 0:15 ` font-backend Feng Li
2008-02-23 0:25 ` font-backend YAMAMOTO Mitsuharu
2008-02-23 2:23 ` font-backend Jason Rumney
2008-02-23 2:44 ` YAMAMOTO Mitsuharu [this message]
2008-02-24 15:24 ` font-backend Jason Rumney
2008-02-25 10:03 ` font-backend finalpatch
2008-02-23 2:28 ` font-backend Jason Rumney
2008-02-23 2:38 ` font-backend Feng Li
2008-02-16 3:08 ` 23.0.60; show-paren-mode causes abnormal vertical lines on Win32 Stefan Monnier
2008-02-16 6:01 ` Dan Nicolaescu
2008-02-19 15:51 ` Stefan Monnier
2008-02-19 20:44 ` Dan Nicolaescu
2008-02-17 13:22 ` Richard Stallman
[not found] ` <42b562540802150241wb2d1b66n2f0b50b6c9bbca36@mail.gmail.com>
2008-02-15 23:10 ` Jason Rumney
2008-02-15 23:15 ` Drew Adams
2008-02-17 4:57 ` yu jie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=wl4pc0mlwv.wl%mituharu@math.s.chiba-u.ac.jp \
--to=mituharu@math.s.chiba-u.ac.jp \
--cc=emacs-devel@gnu.org \
--cc=fengli@gmail.com \
--cc=jasonr@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).