mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-01 11:14:55 +00:00
Speed up opening fonts on Haiku
* src/font.h (font_property_index): Note that some font drivers use the extra data in a font entity to store driver-specific information. * src/haiku_font_support.cc (BFont_find): Set font indices. (be_open_font_at_index): New function. (BFont_open_pattern): Clean up coding style. * src/haiku_support.h (enum haiku_font_specification) (struct haiku_font_pattern): New fields and specifications for indices. * src/haikufont.c (haikufont_pattern_to_entity, haikufont_open): Use indices to open fonts if available in the extra data.
This commit is contained in:
parent
30caeb7896
commit
1468eef301
@ -155,8 +155,9 @@ enum font_property_index
|
||||
/* In a font-spec, the value is an alist of extra information of a
|
||||
font such as name, OpenType features, and language coverage.
|
||||
In addition, in a font-entity, the value may contain a pair
|
||||
(font-entity . INFO) where INFO is extra information to identify
|
||||
a font (font-driver dependent). */
|
||||
(font-entity . INFO) where INFO is extra information to
|
||||
identify a font (font-driver dependent). In a font-entity,
|
||||
this holds font driver-specific information. */
|
||||
FONT_EXTRA_INDEX, /* alist alist */
|
||||
|
||||
/* This value is the length of font-spec vector. */
|
||||
|
@ -574,18 +574,21 @@ BFont_find (struct haiku_font_pattern *pt)
|
||||
font_family name;
|
||||
font_style sname;
|
||||
uint32 flags;
|
||||
int sty_count;
|
||||
int fam_count = count_font_families ();
|
||||
int sty_count, fam_count, si, fi;
|
||||
struct haiku_font_pattern *p, *head, *n;
|
||||
bool oblique_seen_p;
|
||||
|
||||
for (int fi = 0; fi < fam_count; ++fi)
|
||||
fam_count = count_font_families ();
|
||||
|
||||
for (fi = 0; fi < fam_count; ++fi)
|
||||
{
|
||||
if (get_font_family (fi, &name, &flags) == B_OK)
|
||||
{
|
||||
sty_count = count_font_styles (name);
|
||||
if (!sty_count &&
|
||||
font_family_style_matches_p (name, NULL, flags, pt))
|
||||
if (!sty_count
|
||||
&& font_family_style_matches_p (name, NULL, flags, pt))
|
||||
{
|
||||
struct haiku_font_pattern *p = new struct haiku_font_pattern;
|
||||
p = new struct haiku_font_pattern;
|
||||
p->specified = 0;
|
||||
p->oblique_seen_p = 1;
|
||||
haiku_font_fill_pattern (p, name, NULL, flags);
|
||||
@ -598,11 +601,11 @@ BFont_find (struct haiku_font_pattern *pt)
|
||||
}
|
||||
else if (sty_count)
|
||||
{
|
||||
for (int si = 0; si < sty_count; ++si)
|
||||
for (si = 0; si < sty_count; ++si)
|
||||
{
|
||||
int oblique_seen_p = 0;
|
||||
struct haiku_font_pattern *head = r;
|
||||
struct haiku_font_pattern *p = NULL;
|
||||
oblique_seen_p = 0;
|
||||
head = r;
|
||||
p = NULL;
|
||||
|
||||
if (get_font_style (name, si, &sname, &flags) == B_OK)
|
||||
{
|
||||
@ -611,8 +614,18 @@ BFont_find (struct haiku_font_pattern *pt)
|
||||
p = new struct haiku_font_pattern;
|
||||
p->specified = 0;
|
||||
haiku_font_fill_pattern (p, name, (char *) &sname, flags);
|
||||
if (p->specified & FSPEC_SLANT &&
|
||||
((p->slant == SLANT_OBLIQUE) || (p->slant == SLANT_ITALIC)))
|
||||
|
||||
/* Add the indices to this font now so we
|
||||
won't have to loop over each font in
|
||||
order to open it later. */
|
||||
|
||||
p->specified |= FSPEC_INDICES;
|
||||
p->family_index = fi;
|
||||
p->style_index = si;
|
||||
|
||||
if (p->specified & FSPEC_SLANT
|
||||
&& (p->slant == SLANT_OBLIQUE
|
||||
|| p->slant == SLANT_ITALIC))
|
||||
oblique_seen_p = 1;
|
||||
|
||||
p->next = r;
|
||||
@ -627,9 +640,7 @@ BFont_find (struct haiku_font_pattern *pt)
|
||||
p->last = NULL;
|
||||
|
||||
for (; head; head = head->last)
|
||||
{
|
||||
head->oblique_seen_p = oblique_seen_p;
|
||||
}
|
||||
head->oblique_seen_p = oblique_seen_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -642,13 +653,18 @@ BFont_find (struct haiku_font_pattern *pt)
|
||||
if (!(pt->specified & FSPEC_SLANT))
|
||||
{
|
||||
/* r->last is invalid from here onwards. */
|
||||
for (struct haiku_font_pattern *p = r; p;)
|
||||
for (p = r; p;)
|
||||
{
|
||||
if (!p->oblique_seen_p)
|
||||
{
|
||||
struct haiku_font_pattern *n = new haiku_font_pattern;
|
||||
n = new haiku_font_pattern;
|
||||
*n = *p;
|
||||
|
||||
n->slant = SLANT_OBLIQUE;
|
||||
|
||||
/* Opening a font by its indices doesn't provide enough
|
||||
information to synthesize the oblique font later. */
|
||||
n->specified &= ~FSPEC_INDICES;
|
||||
p->next = n;
|
||||
p = p->next_family;
|
||||
}
|
||||
@ -660,26 +676,68 @@ BFont_find (struct haiku_font_pattern *pt)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Find and open a font with the family at FAMILY and the style at
|
||||
STYLE, and set its size to SIZE. Value is NULL if opening the font
|
||||
failed. */
|
||||
void *
|
||||
be_open_font_at_index (int family, int style, float size)
|
||||
{
|
||||
font_family family_name;
|
||||
font_style style_name;
|
||||
uint32 flags;
|
||||
status_t rc;
|
||||
BFont *font;
|
||||
|
||||
rc = get_font_family (family, &family_name, &flags);
|
||||
|
||||
if (rc != B_OK)
|
||||
return NULL;
|
||||
|
||||
rc = get_font_style (family_name, style, &style_name, &flags);
|
||||
|
||||
if (rc != B_OK)
|
||||
return NULL;
|
||||
|
||||
font = new BFont;
|
||||
|
||||
rc = font->SetFamilyAndStyle (family_name, style_name);
|
||||
|
||||
if (rc != B_OK)
|
||||
{
|
||||
delete font;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
font->SetSize (size);
|
||||
font->SetEncoding (B_UNICODE_UTF8);
|
||||
font->SetSpacing (B_BITMAP_SPACING);
|
||||
return font;
|
||||
}
|
||||
|
||||
/* Find and open a font matching the pattern PAT, which must have its
|
||||
family set. */
|
||||
int
|
||||
BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
|
||||
{
|
||||
int sty_count;
|
||||
int sty_count, si, code;
|
||||
font_family name;
|
||||
font_style sname;
|
||||
BFont *ft;
|
||||
uint32 flags = 0;
|
||||
struct haiku_font_pattern copy;
|
||||
|
||||
if (!(pat->specified & FSPEC_FAMILY))
|
||||
return 1;
|
||||
|
||||
strncpy (name, pat->family, sizeof name - 1);
|
||||
name[sizeof name - 1] = '\0';
|
||||
|
||||
sty_count = count_font_styles (name);
|
||||
|
||||
if (!sty_count &&
|
||||
font_family_style_matches_p (name, NULL, flags, pat, 1))
|
||||
if (!sty_count
|
||||
&& font_family_style_matches_p (name, NULL, flags, pat, 1))
|
||||
{
|
||||
BFont *ft = new BFont;
|
||||
ft = new BFont;
|
||||
ft->SetSize (size);
|
||||
ft->SetEncoding (B_UNICODE_UTF8);
|
||||
ft->SetSpacing (B_BITMAP_SPACING);
|
||||
@ -694,12 +752,13 @@ BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
|
||||
}
|
||||
else if (sty_count)
|
||||
{
|
||||
for (int si = 0; si < sty_count; ++si)
|
||||
for (si = 0; si < sty_count; ++si)
|
||||
{
|
||||
if (get_font_style (name, si, &sname, &flags) == B_OK &&
|
||||
font_family_style_matches_p (name, (char *) &sname, flags, pat))
|
||||
if (get_font_style (name, si, &sname, &flags) == B_OK
|
||||
&& font_family_style_matches_p (name, (char *) &sname,
|
||||
flags, pat))
|
||||
{
|
||||
BFont *ft = new BFont;
|
||||
ft = new BFont;
|
||||
ft->SetSize (size);
|
||||
ft->SetEncoding (B_UNICODE_UTF8);
|
||||
ft->SetSpacing (B_BITMAP_SPACING);
|
||||
@ -709,6 +768,7 @@ BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
|
||||
delete ft;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*font = (void *) ft;
|
||||
return 0;
|
||||
}
|
||||
@ -717,12 +777,14 @@ BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
|
||||
|
||||
if (pat->specified & FSPEC_SLANT && pat->slant == SLANT_OBLIQUE)
|
||||
{
|
||||
struct haiku_font_pattern copy = *pat;
|
||||
copy = *pat;
|
||||
copy.slant = SLANT_REGULAR;
|
||||
int code = BFont_open_pattern (©, font, size);
|
||||
code = BFont_open_pattern (©, font, size);
|
||||
|
||||
if (code)
|
||||
return code;
|
||||
BFont *ft = (BFont *) *font;
|
||||
|
||||
ft = (BFont *) *font;
|
||||
/* XXX Font measurements don't respect shear. Haiku bug?
|
||||
This apparently worked in BeOS.
|
||||
ft->SetShear (100.0); */
|
||||
|
@ -246,6 +246,7 @@ enum haiku_font_specification
|
||||
FSPEC_NEED_ONE_OF = 1 << 6,
|
||||
FSPEC_WIDTH = 1 << 7,
|
||||
FSPEC_LANGUAGE = 1 << 8,
|
||||
FSPEC_INDICES = 1 << 9,
|
||||
};
|
||||
|
||||
typedef char haiku_font_family_or_style[64];
|
||||
@ -300,25 +301,61 @@ enum haiku_font_weight
|
||||
|
||||
struct haiku_font_pattern
|
||||
{
|
||||
/* Bitmask indicating which fields are set. */
|
||||
int specified;
|
||||
|
||||
/* The next font in this list. */
|
||||
struct haiku_font_pattern *next;
|
||||
/* The next two fields are only temporarily used during the font
|
||||
discovery process! Do not rely on them being correct outside
|
||||
BFont_find. */
|
||||
|
||||
/* The last font in the list during font lookup. */
|
||||
struct haiku_font_pattern *last;
|
||||
|
||||
/* The next font in the list whose family differs from this one.
|
||||
Only valid during font lookup. */
|
||||
struct haiku_font_pattern *next_family;
|
||||
|
||||
/* The family of the font. */
|
||||
haiku_font_family_or_style family;
|
||||
|
||||
/* The style of the font. */
|
||||
haiku_font_family_or_style style;
|
||||
|
||||
/* Whether or the font is monospace. */
|
||||
int mono_spacing_p;
|
||||
int want_chars_len;
|
||||
int need_one_of_len;
|
||||
|
||||
/* The slant of the font. */
|
||||
enum haiku_font_slant slant;
|
||||
|
||||
/* The width of the font. */
|
||||
enum haiku_font_width width;
|
||||
|
||||
/* The language of the font. Used during font lookup. */
|
||||
enum haiku_font_language language;
|
||||
|
||||
/* The weight of the font. */
|
||||
enum haiku_font_weight weight;
|
||||
|
||||
/* List of characters that must be present in the font for the match
|
||||
to succeed. */
|
||||
int *wanted_chars;
|
||||
|
||||
/* The number of characters in `wanted_chars'. */
|
||||
int want_chars_len;
|
||||
|
||||
/* List of characters. The font must fullfill at least one of
|
||||
them for the match to succeed. */
|
||||
int *need_one_of;
|
||||
|
||||
/* The number of characters in `need_one_of'. */
|
||||
int need_one_of_len;
|
||||
|
||||
/* The index of the family of the font this pattern represents. */
|
||||
int family_index;
|
||||
|
||||
/* The index of the style of the font this pattern represents. */
|
||||
int style_index;
|
||||
|
||||
/* Temporary field used during font enumeration. */
|
||||
int oblique_seen_p;
|
||||
};
|
||||
|
||||
@ -635,6 +672,7 @@ extern bool be_use_subpixel_antialiasing (void);
|
||||
extern const char *be_find_setting (const char *);
|
||||
extern haiku_font_family_or_style *be_list_font_families (size_t *);
|
||||
extern void be_font_style_to_flags (char *, struct haiku_font_pattern *);
|
||||
extern void *be_open_font_at_index (int, int, float);
|
||||
extern int be_get_ui_color (const char *, uint32_t *);
|
||||
|
||||
extern void BMessage_delete (void *);
|
||||
|
@ -381,7 +381,9 @@ haikufont_maybe_handle_special_family (Lisp_Object family,
|
||||
static Lisp_Object
|
||||
haikufont_pattern_to_entity (struct haiku_font_pattern *ptn)
|
||||
{
|
||||
Lisp_Object ent = font_make_entity ();
|
||||
Lisp_Object ent;
|
||||
|
||||
ent = font_make_entity ();
|
||||
ASET (ent, FONT_TYPE_INDEX, Qhaiku);
|
||||
ASET (ent, FONT_FOUNDRY_INDEX, Qhaiku);
|
||||
ASET (ent, FONT_FAMILY_INDEX, Qdefault);
|
||||
@ -390,6 +392,14 @@ haikufont_pattern_to_entity (struct haiku_font_pattern *ptn)
|
||||
ASET (ent, FONT_SIZE_INDEX, make_fixnum (0));
|
||||
ASET (ent, FONT_AVGWIDTH_INDEX, make_fixnum (0));
|
||||
ASET (ent, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO));
|
||||
|
||||
/* FONT_EXTRA_INDEX in a font entity can be a cons of two numbers
|
||||
(STYLE . IDX) that tell Emacs how to open a font. */
|
||||
if (ptn->specified & FSPEC_INDICES)
|
||||
ASET (ent, FONT_EXTRA_INDEX,
|
||||
Fcons (make_fixnum (ptn->family_index),
|
||||
make_fixnum (ptn->style_index)));
|
||||
|
||||
FONT_SET_STYLE (ent, FONT_WIDTH_INDEX, Qnormal);
|
||||
FONT_SET_STYLE (ent, FONT_WEIGHT_INDEX, Qnormal);
|
||||
FONT_SET_STYLE (ent, FONT_SLANT_INDEX, Qnormal);
|
||||
@ -722,10 +732,11 @@ haikufont_open (struct frame *f, Lisp_Object font_entity, int x)
|
||||
struct haiku_font_pattern ptn;
|
||||
struct font *font;
|
||||
void *be_font;
|
||||
Lisp_Object font_object;
|
||||
Lisp_Object tem;
|
||||
Lisp_Object font_object, tem, extra;
|
||||
int px_size, min_width, max_width,
|
||||
avg_width, height, space_width, ascent,
|
||||
descent, underline_pos, underline_thickness;
|
||||
|
||||
block_input ();
|
||||
if (x <= 0)
|
||||
{
|
||||
/* Get pixel size from frame instead. */
|
||||
@ -733,19 +744,47 @@ haikufont_open (struct frame *f, Lisp_Object font_entity, int x)
|
||||
x = NILP (tem) ? 0 : XFIXNAT (tem);
|
||||
}
|
||||
|
||||
haikufont_spec_or_entity_to_pattern (font_entity, 1, &ptn);
|
||||
extra = AREF (font_entity, FONT_EXTRA_INDEX);
|
||||
|
||||
if (BFont_open_pattern (&ptn, &be_font, x))
|
||||
/* If the font's indices is already available, open the font using
|
||||
those instead. */
|
||||
|
||||
if (CONSP (extra) && FIXNUMP (XCAR (extra))
|
||||
&& FIXNUMP (XCDR (extra)))
|
||||
{
|
||||
block_input ();
|
||||
be_font = be_open_font_at_index (XFIXNUM (XCAR (extra)),
|
||||
XFIXNUM (XCDR (extra)), x);
|
||||
unblock_input ();
|
||||
|
||||
if (!be_font)
|
||||
return Qnil;
|
||||
}
|
||||
else
|
||||
{
|
||||
block_input ();
|
||||
haikufont_spec_or_entity_to_pattern (font_entity, 1, &ptn);
|
||||
|
||||
if (BFont_open_pattern (&ptn, &be_font, x))
|
||||
{
|
||||
haikufont_done_with_query_pattern (&ptn);
|
||||
unblock_input ();
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
haikufont_done_with_query_pattern (&ptn);
|
||||
unblock_input ();
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
haikufont_done_with_query_pattern (&ptn);
|
||||
block_input ();
|
||||
|
||||
/* `font_make_object' tries to treat the extra data as an alist.
|
||||
There is never any real data here, so clear that field. */
|
||||
|
||||
ASET (font_entity, FONT_EXTRA_INDEX, Qnil);
|
||||
font_object = font_make_object (VECSIZE (struct haikufont_info),
|
||||
font_entity, x);
|
||||
ASET (font_entity, FONT_EXTRA_INDEX, extra);
|
||||
|
||||
ASET (font_object, FONT_TYPE_INDEX, Qhaiku);
|
||||
font_info = (struct haikufont_info *) XFONT_OBJECT (font_object);
|
||||
@ -772,10 +811,6 @@ haikufont_open (struct frame *f, Lisp_Object font_entity, int x)
|
||||
font_info->metrics = NULL;
|
||||
font_info->metrics_nrows = 0;
|
||||
|
||||
int px_size, min_width, max_width,
|
||||
avg_width, height, space_width, ascent,
|
||||
descent, underline_pos, underline_thickness;
|
||||
|
||||
BFont_metrics (be_font, &px_size, &min_width,
|
||||
&max_width, &avg_width, &height,
|
||||
&space_width, &ascent, &descent,
|
||||
|
Loading…
Reference in New Issue
Block a user