#include "w32term.h"
#endif /* HAVE_NTGUI */
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif /* HAVE_NS */
+
#ifdef MAC_OS
#include "macterm.h"
#endif /* MAC_OS */
Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
+
+#ifdef HAVE_NS
+extern Lisp_Object Qfontsize;
+#endif
Lisp_Object Qopentype;
/* Important character set strings. */
Lisp_Object Qascii_0, Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip;
+#ifdef HAVE_NS
+#define DEFAULT_ENCODING Qiso10646_1
+#else
+#define DEFAULT_ENCODING Qiso8859_1
+#endif
+
/* Special vector of zero length. This is repeatedly used by (struct
font_driver *)->list when a specified font is not found. */
static Lisp_Object null_vector;
return font_entity;
}
+/* Create a font-object whose structure size is SIZE. If ENTITY is
+ not nil, copy properties from ENTITY to the font-object. If
+ PIXELSIZE is positive, set the `size' property to PIXELSIZE. */
Lisp_Object
-font_make_object (size)
+font_make_object (size, entity, pixelsize)
int size;
+ Lisp_Object entity;
+ int pixelsize;
{
Lisp_Object font_object;
struct font *font
= (struct font *) allocate_pseudovector (size, FONT_OBJECT_MAX, PVEC_FONT);
+ int i;
+
XSETFONT (font_object, font);
+ if (! NILP (entity))
+ {
+ for (i = 1; i < FONT_SPEC_MAX; i++)
+ font->props[i] = AREF (entity, i);
+ if (! NILP (AREF (entity, FONT_EXTRA_INDEX)))
+ font->props[FONT_EXTRA_INDEX]
+ = Fcopy_sequence (AREF (entity, FONT_EXTRA_INDEX));
+ }
+ if (size > 0)
+ font->props[FONT_SIZE_INDEX] = make_number (pixelsize);
return font_object;
}
}
Lisp_Object
-font_style_symbolic_from_value (prop, val, for_face)
+font_style_symbolic (font, prop, for_face)
+ Lisp_Object font;
enum font_property_index prop;
- Lisp_Object val;
int for_face;
{
+ Lisp_Object val = AREF (font, prop);
Lisp_Object table, elt;
int i;
return (for_face ? AREF (elt, 1) : AREF (elt, (i & 0xF) + 1));
}
-Lisp_Object
-font_style_symbolic (font, prop, for_face)
- Lisp_Object font;
- enum font_property_index prop;
- int for_face;
-{
- Lisp_Object val = AREF (font, prop);
- return font_style_symbolic_from_value (prop, val, for_face);
-}
-
extern Lisp_Object Vface_alternative_font_family_alist;
extern Lisp_Object find_font_encoding P_ ((Lisp_Object));
if (*p == '~')
p++;
ASET (font, FONT_AVGWIDTH_INDEX,
- font_intern_prop (p, f[XLFD_REGISTRY_INDEX] - 1 - p, 1));
+ font_intern_prop (p, f[XLFD_REGISTRY_INDEX] - 1 - p, 0));
}
else
{
p++;
else if (*p == ':')
{
- family_end = p;
- props_beg = p + 1;
+ props_beg = family_end = p;
break;
}
else if (*p == '-')
double point_size = strtod (size_beg, &size_end);
ASET (font, FONT_SIZE_INDEX, make_float (point_size));
if (*size_end == ':' && size_end[1])
- props_beg = size_end + 1;
+ props_beg = size_end;
}
if (props_beg)
{
- /* Now parse ":KEY=VAL" patterns. Store known keys and values in
- extra, copy unknown ones to COPY. It is stored in extra slot by
- the key QCfc_unknown_spec. */
- char *copy;
-
- name = copy = alloca (name + len - props_beg);
- if (! copy)
- return -1;
+ /* Now parse ":KEY=VAL" patterns. */
+ Lisp_Object val;
- p = props_beg;
- while (*p)
+ for (p = props_beg; *p; p = q)
{
- Lisp_Object val;
- int word_len, prop;
-
-#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0)
-
for (q = p + 1; *q && *q != '=' && *q != ':'; q++);
- word_len = q - p;
if (*q != '=')
{
/* Must be an enumerated value. */
+ int word_len;
+ p = p + 1;
+ word_len = q - p;
val = font_intern_prop (p, q - p, 1);
+
+#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0)
+
if (PROP_MATCH ("light", 5)
|| PROP_MATCH ("medium", 6)
|| PROP_MATCH ("demibold", 8)
else if (PROP_MATCH ("proportional", 12))
ASET (font, FONT_SPACING_INDEX,
make_number (FONT_SPACING_PROPORTIONAL));
- else
- {
- /* Unknown key */
- bcopy (p, copy, word_len);
- copy += word_len;
- }
+#undef PROP_MATCH
}
- else /* KEY=VAL pairs */
+ else
{
+ /* KEY=VAL pairs */
Lisp_Object key;
- char *keyhead = p;
+ int prop;
- if (word_len == 9 && memcmp (p, "pixelsize=", 10) == 0)
+ if (q - p == 10 && memcmp (p + 1, "pixelsize", 9) == 0)
prop = FONT_SIZE_INDEX;
else
{
key = font_intern_prop (p, q - p, 1);
prop = get_font_prop_index (key);
}
+
p = q + 1;
for (q = p; *q && *q != ':'; q++);
-
val = font_intern_prop (p, q - p, 0);
- if (! NILP (val))
- {
- if (prop >= FONT_FOUNDRY_INDEX
- && prop < FONT_EXTRA_INDEX)
- ASET (font, prop,
- font_prop_validate (prop, Qnil, val));
- else if (prop >= 0)
- Ffont_put (font, key, val);
- else
- bcopy (keyhead, copy, q - keyhead);
- copy += q - keyhead;
- }
+
+ if (prop >= FONT_FOUNDRY_INDEX
+ && prop < FONT_EXTRA_INDEX)
+ ASET (font, prop, font_prop_validate (prop, Qnil, val));
+ else
+ Ffont_put (font, key, val);
}
- p = *q ? q + 1 : q;
-#undef PROP_MATCH
+ p = q;
}
- if (name != copy)
- font_put_extra (font, QCfc_unknown_spec,
- make_unibyte_string (name, copy - name));
}
}
else
{
if (isdigit (*p))
{
- char *r;
int size_found = 1;
+
for (q = p + 1; *q && *q != ' '; q++)
if (! isdigit (*q))
{
}
weight = font_style_symbolic (font, FONT_WEIGHT_INDEX, 0);
- if (weight == Qnormal)
+ if (EQ (weight, Qnormal))
weight = Qnil;
else if (! NILP (weight))
{
}
slant = font_style_symbolic (font, FONT_SLANT_INDEX, 0);
- if (slant == Qnormal)
+ if (EQ (slant, Qnormal))
slant = Qnil;
else if (! NILP (slant))
{
static unsigned font_score P_ ((Lisp_Object, Lisp_Object *));
static int font_compare P_ ((const void *, const void *));
static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object,
- int));
+ Lisp_Object, int));
/* We sort fonts by scoring each of them against a specified
font-spec. The score value is 32 bit (`unsigned'), and the smaller
/* Score font-entity ENTITY against properties of font-spec SPEC_PROP.
The return value indicates how different ENTITY is compared with
- SPEC_PROP.
-
- ALTERNATE_FAMILIES, if non-nil, is a pre-calculated list of
- alternate family names for AREF (SPEC_PROP, FONT_FAMILY_INDEX). */
+ SPEC_PROP. */
static unsigned
font_score (entity, spec_prop)
/* Score the size. Maximum difference is 127. */
i = FONT_SIZE_INDEX;
- if (! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i])
- && XINT (AREF (entity, i)) > 0)
+ if (! NILP (spec_prop[i]) && XINT (AREF (entity, i)) > 0)
{
/* We use the higher 6-bit for the actual size difference. The
lowest bit is set if the DPI is different. */
/* Sort font-entities in vector VEC by closeness to font-spec PREFER.
If PREFER specifies a point-size, calculate the corresponding
pixel-size from QCdpi property of PREFER or from the Y-resolution
- of FRAME before sorting. If SPEC is not nil, it is a font-spec to
- get the font-entities in VEC.
+ of FRAME before sorting.
If BEST-ONLY is nonzero, return the best matching entity. Otherwise,
return the sorted VEC. */
static Lisp_Object
-font_sort_entites (vec, prefer, frame, spec, best_only)
- Lisp_Object vec, prefer, frame, spec;
+font_sort_entites (vec, prefer, frame, best_only)
+ Lisp_Object vec, prefer, frame;
int best_only;
{
Lisp_Object prefer_prop[FONT_SPEC_MAX];
if (len <= 1)
return best_only ? AREF (vec, 0) : vec;
- for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
+ for (i = FONT_WEIGHT_INDEX; i <= FONT_DPI_INDEX; i++)
prefer_prop[i] = AREF (prefer, i);
-
- if (! NILP (spec))
- {
- /* A font driver may return a font that has a property value
- different from the value specified in SPEC if the driver
- thinks they are the same. That happens, for instance, such a
- generic family name as "serif" is specified. So, to ignore
- such a difference, for all properties specified in SPEC, set
- the corresponding properties in PREFER_PROP to nil. */
- for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
- if (! NILP (AREF (spec, i)))
- prefer_prop[i] = Qnil;
- }
-
if (FLOATP (prefer_prop[FONT_SIZE_INDEX]))
prefer_prop[FONT_SIZE_INDEX]
= make_number (font_pixel_size (XFRAME (frame), prefer));
break;
}
}
- if (NILP (best_entity))
+ if (! best_only)
{
qsort (data, len, sizeof *data, font_compare);
for (i = 0; i < len; i++)
}
}
+static int
+font_check_otf_features (script, langsys, features, table)
+ Lisp_Object script, langsys, features, table;
+{
+ Lisp_Object val;
+ int negative;
+
+ table = assq_no_quit (script, table);
+ if (NILP (table))
+ return 0;
+ table = XCDR (table);
+ if (! NILP (langsys))
+ {
+ table = assq_no_quit (langsys, table);
+ if (NILP (table))
+ return 0;
+ }
+ else
+ {
+ val = assq_no_quit (Qnil, table);
+ if (NILP (val))
+ table = XCAR (table);
+ else
+ table = val;
+ }
+ table = XCDR (table);
+ for (negative = 0; CONSP (features); features = XCDR (features))
+ {
+ if (NILP (XCAR (features)))
+ negative = 1;
+ if (NILP (Fmemq (XCAR (features), table)) != negative)
+ return 0;
+ }
+ return 1;
+}
-/* Check if ENTITY matches with the font specification SPEC. */
+/* Check if OTF_CAPABILITY satisfies SPEC (otf-spec). */
-int
-font_match_p (spec, entity)
- Lisp_Object spec, entity;
+static int
+font_check_otf (Lisp_Object spec, Lisp_Object otf_capability)
{
- Lisp_Object prefer_prop[FONT_SPEC_MAX];
- Lisp_Object alternate_families = Qnil;
- int i;
+ Lisp_Object script, langsys = Qnil, gsub = Qnil, gpos = Qnil;
- for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++)
- prefer_prop[i] = AREF (spec, i);
- if (FLOATP (prefer_prop[FONT_SIZE_INDEX]))
- prefer_prop[FONT_SIZE_INDEX]
- = make_number (font_pixel_size (XFRAME (selected_frame), spec));
- if (! NILP (prefer_prop[FONT_FAMILY_INDEX]))
+ script = XCAR (spec);
+ spec = XCDR (spec);
+ if (! NILP (spec))
{
- alternate_families
- = Fassoc_string (prefer_prop[FONT_FAMILY_INDEX],
- Vface_alternative_font_family_alist, Qt);
- if (CONSP (alternate_families))
- alternate_families = XCDR (alternate_families);
+ langsys = XCAR (spec);
+ spec = XCDR (spec);
+ if (! NILP (spec))
+ {
+ gsub = XCAR (spec);
+ spec = XCDR (spec);
+ if (! NILP (spec))
+ gpos = XCAR (spec);
+ }
}
- return (font_score (entity, prefer_prop) == 0);
+ if (! NILP (gsub) && ! font_check_otf_features (script, langsys, gsub,
+ XCAR (otf_capability)))
+ return 0;
+ if (! NILP (gpos) && ! font_check_otf_features (script, langsys, gpos,
+ XCDR (otf_capability)))
+ return 0;
+ return 1;
}
-/* CHeck a lispy font object corresponding to FONT. */
+
+/* Check if FONT (font-entity or font-object) matches with the font
+ specification SPEC. */
int
-font_check_object (font)
- struct font *font;
+font_match_p (spec, font)
+ Lisp_Object spec, font;
{
- Lisp_Object tail, elt;
+ Lisp_Object prop[FONT_SPEC_MAX], *props;
+ Lisp_Object extra, font_extra;
+ int i;
- for (tail = font->props[FONT_OBJLIST_INDEX]; CONSP (tail);
- tail = XCDR (tail))
+ for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++)
+ if (! NILP (AREF (spec, i))
+ && ! NILP (AREF (font, i))
+ && ! EQ (AREF (spec, i), AREF (font, i)))
+ return 0;
+ props = XFONT_SPEC (spec)->props;
+ if (FLOATP (props[FONT_SIZE_INDEX]))
{
- elt = XCAR (tail);
- if (font == XFONT_OBJECT (elt))
- return 1;
+ for (i = FONT_FOUNDRY_INDEX; i < FONT_SIZE_INDEX; i++)
+ prop[i] = AREF (spec, i);
+ prop[FONT_SIZE_INDEX]
+ = make_number (font_pixel_size (XFRAME (selected_frame), spec));
+ props = prop;
+ }
+
+ if (font_score (font, props) > 0)
+ return 0;
+ extra = AREF (spec, FONT_EXTRA_INDEX);
+ font_extra = AREF (font, FONT_EXTRA_INDEX);
+ for (; CONSP (extra); extra = XCDR (extra))
+ {
+ Lisp_Object key = XCAR (XCAR (extra));
+ Lisp_Object val = XCDR (XCAR (extra)), val2;
+
+ if (EQ (key, QClang))
+ {
+ val2 = assq_no_quit (key, font_extra);
+ if (NILP (val2))
+ return 0;
+ val2 = XCDR (val2);
+ if (CONSP (val))
+ {
+ if (! CONSP (val2))
+ return 0;
+ while (CONSP (val))
+ if (NILP (Fmemq (val, val2)))
+ return 0;
+ }
+ else
+ if (CONSP (val2)
+ ? NILP (Fmemq (val, XCDR (val2)))
+ : ! EQ (val, val2))
+ return 0;
+ }
+ else if (EQ (key, QCscript))
+ {
+ val2 = assq_no_quit (val, Vscript_representative_chars);
+ if (! NILP (val2))
+ for (val2 = XCDR (val2); CONSP (val2); val2 = XCDR (val2))
+ if (font_encode_char (font, XINT (XCAR (val2)))
+ == FONT_INVALID_CODE)
+ return 0;
+ }
+ else if (EQ (key, QCotf))
+ {
+ struct font *fontp;
+
+ if (! FONT_OBJECT_P (font))
+ return 0;
+ fontp = XFONT_OBJECT (font);
+ if (! fontp->driver->otf_capability)
+ return 0;
+ val2 = fontp->driver->otf_capability (fontp);
+ if (NILP (val2) || ! font_check_otf (val, val2))
+ return 0;
+ }
}
- return 0;
-}
+ return 1;
+}
\f
/* Font cache
Lisp_Object val = XCAR (objlist);
struct font *font = XFONT_OBJECT (val);
- font_assert (font && driver == font->driver);
- driver->close (f, font);
- num_fonts--;
+ if (! NILP (AREF (val, FONT_TYPE_INDEX)))
+ {
+ font_assert (font && driver == font->driver);
+ driver->close (f, font);
+ num_fonts--;
+ }
}
if (driver->free_entity)
driver->free_entity (entity);
&& ((XINT (AREF (spec, prop)) >> 8)
!= (XINT (AREF (entity, prop)) >> 8)))
prop = FONT_SPEC_MAX;
- if (prop++ <= FONT_SIZE_INDEX
+ if (prop < FONT_SPEC_MAX
&& size
&& XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
{
: diff > FONT_PIXEL_SIZE_QUANTUM))
prop = FONT_SPEC_MAX;
}
+ if (prop < FONT_SPEC_MAX
+ && INTEGERP (AREF (spec, FONT_DPI_INDEX))
+ && INTEGERP (AREF (entity, FONT_DPI_INDEX))
+ && ! EQ (AREF (spec, FONT_DPI_INDEX), AREF (entity, FONT_DPI_INDEX)))
+ prop = FONT_SPEC_MAX;
+ if (prop < FONT_SPEC_MAX
+ && INTEGERP (AREF (spec, FONT_AVGWIDTH_INDEX))
+ && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
+ && ! EQ (AREF (spec, FONT_AVGWIDTH_INDEX),
+ AREF (entity, FONT_AVGWIDTH_INDEX)))
+ prop = FONT_SPEC_MAX;
if (prop < FONT_SPEC_MAX)
val = Fcons (entity, val);
}
struct font_driver_list *driver_list;
Lisp_Object objlist, size, val, font_object;
struct font *font;
- int min_width;
+ int min_width, height;
font_assert (FONT_ENTITY_P (entity));
size = AREF (entity, FONT_SIZE_INDEX);
for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist);
objlist = XCDR (objlist))
- if (XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size)
+ if (! NILP (AREF (XCAR (objlist), FONT_TYPE_INDEX))
+ && XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size)
return XCAR (objlist);
val = AREF (entity, FONT_TYPE_INDEX);
return Qnil;
ASET (entity, FONT_OBJLIST_INDEX,
Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX)));
- ASET (font_object, FONT_OBJLIST_INDEX, AREF (entity, FONT_OBJLIST_INDEX));
+ ASET (font_object, FONT_OBJLIST_INDEX, Qnil);
num_fonts++;
font = XFONT_OBJECT (font_object);
: font->average_width ? font->average_width
: font->space_width ? font->space_width
: 1);
+ height = (font->height ? font->height : 1);
#ifdef HAVE_WINDOW_SYSTEM
FRAME_X_DISPLAY_INFO (f)->n_fonts++;
if (FRAME_X_DISPLAY_INFO (f)->n_fonts == 1)
{
FRAME_SMALLEST_CHAR_WIDTH (f) = min_width;
- FRAME_SMALLEST_FONT_HEIGHT (f) = font->height;
+ FRAME_SMALLEST_FONT_HEIGHT (f) = height;
fonts_changed_p = 1;
}
else
{
if (FRAME_SMALLEST_CHAR_WIDTH (f) > min_width)
FRAME_SMALLEST_CHAR_WIDTH (f) = min_width, fonts_changed_p = 1;
- if (FRAME_SMALLEST_FONT_HEIGHT (f) > font->height)
- FRAME_SMALLEST_FONT_HEIGHT (f) = font->height, fonts_changed_p = 1;
+ if (FRAME_SMALLEST_FONT_HEIGHT (f) > height)
+ FRAME_SMALLEST_FONT_HEIGHT (f) = height, fonts_changed_p = 1;
}
#endif
Lisp_Object font_object;
{
struct font *font = XFONT_OBJECT (font_object);
- Lisp_Object objlist;
- Lisp_Object tail, prev = Qnil;
- objlist = AREF (font_object, FONT_OBJLIST_INDEX);
- for (prev = Qnil, tail = objlist; CONSP (tail);
- prev = tail, tail = XCDR (tail))
- if (EQ (font_object, XCAR (tail)))
- {
- font_add_log ("close", font_object, Qnil);
- font->driver->close (f, font);
+ if (NILP (AREF (font_object, FONT_TYPE_INDEX)))
+ /* Already closed. */
+ return;
+ font_add_log ("close", font_object, Qnil);
+ font->driver->close (f, font);
#ifdef HAVE_WINDOW_SYSTEM
- font_assert (FRAME_X_DISPLAY_INFO (f)->n_fonts);
- FRAME_X_DISPLAY_INFO (f)->n_fonts--;
+ font_assert (FRAME_X_DISPLAY_INFO (f)->n_fonts);
+ FRAME_X_DISPLAY_INFO (f)->n_fonts--;
#endif
- if (NILP (prev))
- ASET (font_object, FONT_OBJLIST_INDEX, XCDR (objlist));
- else
- XSETCDR (prev, XCDR (objlist));
- num_fonts--;
- return;
- }
- abort ();
+ num_fonts--;
}
{
Lisp_Object work;
Lisp_Object frame, entities, val, props[FONT_REGISTRY_INDEX + 1] ;
- Lisp_Object size, foundry[3], *family, registry[3];
+ Lisp_Object size, foundry[3], *family, registry[3], adstyle[3];
int pixel_size;
- int i, j, k, result;
+ int i, j, k, l, result;
registry[0] = AREF (spec, FONT_REGISTRY_INDEX);
if (NILP (registry[0]))
{
- registry[0] = Qiso8859_1;
+ registry[0] = DEFAULT_ENCODING;
registry[1] = Qascii_0;
registry[2] = null_vector;
}
else
foundry[0] = Qnil, foundry[1] = null_vector;
+ adstyle[0] = AREF (work, FONT_ADSTYLE_INDEX);
+ if (! NILP (adstyle[0]))
+ adstyle[1] = null_vector;
+ else if (FONTP (attrs[LFACE_FONT_INDEX]))
+ {
+ Lisp_Object face_font = attrs[LFACE_FONT_INDEX];
+
+ if (! NILP (AREF (face_font, FONT_ADSTYLE_INDEX)))
+ {
+ adstyle[0] = AREF (face_font, FONT_ADSTYLE_INDEX);
+ adstyle[1] = Qnil;
+ adstyle[2] = null_vector;
+ }
+ else
+ adstyle[0] = Qnil, adstyle[1] = null_vector;
+ }
+ else
+ adstyle[0] = Qnil, adstyle[1] = null_vector;
+
+
val = AREF (work, FONT_FAMILY_INDEX);
if (NILP (val) && STRINGP (attrs[LFACE_FAMILY_INDEX]))
val = font_intern_prop (SDATA (attrs[LFACE_FAMILY_INDEX]),
for (k = 0; SYMBOLP (registry[k]); k++)
{
ASET (work, FONT_REGISTRY_INDEX, registry[k]);
- entities = font_list_entities (frame, work);
- if (ASIZE (entities) > 0)
- goto found;
+ for (l = 0; SYMBOLP (adstyle[l]); l++)
+ {
+ ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]);
+ entities = font_list_entities (frame, work);
+ if (ASIZE (entities) > 0)
+ goto found;
+ }
}
}
}
if (NILP (AREF (prefer, FONT_WIDTH_INDEX)))
FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]);
ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size));
- entities = font_sort_entites (entities, prefer, frame, work, c < 0);
+ entities = font_sort_entites (entities, prefer, frame, c < 0);
}
if (c < 0)
return entities;
pt /= 10;
size = POINT_TO_PIXEL (pt, f->resy);
+#ifdef HAVE_NS
+ if (size == 0)
+ {
+ Lisp_Object ffsize = get_frame_param(f, Qfontsize);
+ size = NUMBERP (ffsize) ? POINT_TO_PIXEL (XINT (ffsize), f->resy) : 0;
+ }
+#endif
}
return font_open_entity (f, entity, size);
}
attrs[LFACE_FAMILY_INDEX] = attrs[LFACE_FOUNDRY_INDEX] = Qnil;
attrs[LFACE_SWIDTH_INDEX] = attrs[LFACE_WEIGHT_INDEX]
= attrs[LFACE_SLANT_INDEX] = Qnormal;
+#ifndef HAVE_NS
attrs[LFACE_HEIGHT_INDEX] = make_number (120);
+#else
+ attrs[LFACE_HEIGHT_INDEX] = make_number (0);
+#endif
attrs[LFACE_FONT_INDEX] = Qnil;
return font_load_for_lface (f, attrs, spec);
if (! face->font)
return Qnil;
- font_assert (font_check_object ((struct font *) face->font));
XSETFONT (font_object, face->font);
return font_object;
}
VALUE must be a non-negative integer or a floating point number
specifying the font size. It specifies the font size in pixels
(if VALUE is an integer), or in points (if VALUE is a float).
+
+`:name'
+
+VALUE must be a string of XLFD-style or fontconfig-style font name.
usage: (font-spec ARGS ...) */)
(nargs, args)
int nargs;
(font)
Lisp_Object font;
{
- Lisp_Object new_spec, tail, extra;
+ Lisp_Object new_spec, tail, prev, extra;
int i;
CHECK_FONT (font);
new_spec = font_make_spec ();
for (i = 1; i < FONT_EXTRA_INDEX; i++)
ASET (new_spec, i, AREF (font, i));
- extra = Qnil;
- for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
- {
- if (! EQ (XCAR (XCAR (tail)), QCfont_entity))
- extra = Fcons (Fcons (XCAR (XCAR (tail)), XCDR (XCAR (tail))), extra);
- }
+ extra = Fcopy_sequence (AREF (font, FONT_EXTRA_INDEX));
+ /* We must remove :font-entity property. */
+ for (prev = Qnil, tail = extra; CONSP (tail); prev = tail, tail = XCDR (tail))
+ if (EQ (XCAR (XCAR (tail)), QCfont_entity))
+ {
+ if (NILP (prev))
+ extra = XCDR (extra);
+ else
+ XSETCDR (prev, XCDR (tail));
+ break;
+ }
ASET (new_spec, FONT_EXTRA_INDEX, extra);
return new_spec;
}
CHECK_SYMBOL (key);
idx = get_font_prop_index (key);
+ if (idx >= FONT_WEIGHT_INDEX && idx <= FONT_WIDTH_INDEX)
+ return font_style_symbolic (font, idx, 0);
if (idx >= 0 && idx < FONT_EXTRA_INDEX)
return AREF (font, idx);
return Fcdr (Fassq (key, AREF (font, FONT_EXTRA_INDEX)));
}
+#ifdef HAVE_WINDOW_SYSTEM
+
DEFUN ("font-face-attributes", Ffont_face_attributes, Sfont_face_attributes, 1, 2, 0,
doc: /* Return a plist of face attributes generated by FONT.
FONT is a font name, a font-spec, a font-entity, or a font-object.
The return value is a list of the form
-(:family FAMILY :height HEIGHT :weight WEIGHT :slant SLANT :width WIDTH)
+\(:family FAMILY :height HEIGHT :weight WEIGHT :slant SLANT :width WIDTH)
-where FAMILY, FOUNDRY, HEIGHT, WEIGHT, SLANT, and WIDTH are face
-attribute values compatible with `set-face-attribute'.
+where FAMILY, HEIGHT, WEIGHT, SLANT, and WIDTH are face attribute values
+compatible with `set-face-attribute'. Some of these key-attribute pairs
+may be omitted from the list if they are not specified by FONT.
-The optional argument FRAME specifies the frame that the face
-attributes are to be displayed on. If omitted, the selected frame is
-used. */)
+The optional argument FRAME specifies the frame that the face attributes
+are to be displayed on. If omitted, the selected frame is used. */)
(font, frame)
- Lisp_Object font;
+ Lisp_Object font, frame;
{
struct frame *f;
Lisp_Object plist[10];
Lisp_Object val;
+ int n = 0;
if (NILP (frame))
frame = selected_frame;
else if (! FONTP (font))
signal_error ("Invalid font object", font);
- plist[0] = QCfamily;
val = AREF (font, FONT_FAMILY_INDEX);
- plist[1] = NILP (val) ? Qnil : SYMBOL_NAME (val);
+ if (! NILP (val))
+ {
+ plist[n++] = QCfamily;
+ plist[n++] = SYMBOL_NAME (val);
+ }
- plist[2] = QCheight;
val = AREF (font, FONT_SIZE_INDEX);
if (INTEGERP (val))
{
Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX);
int dpi = INTEGERP (font_dpi) ? XINT (font_dpi) : f->resy;
- plist[3] = make_number (10 * PIXEL_TO_POINT (XINT (val), dpi));
+ plist[n++] = QCheight;
+ plist[n++] = make_number (PIXEL_TO_POINT (XINT (val) * 10, dpi));
}
else if (FLOATP (val))
- plist[3] = make_number (10 * (int) XFLOAT_DATA (val));
- else
- plist[3] = Qnil;
+ {
+ plist[n++] = QCheight;
+ plist[n++] = make_number (10 * (int) XFLOAT_DATA (val));
+ }
- plist[4] = QCweight;
val = FONT_WEIGHT_FOR_FACE (font);
- plist[5] = NILP (val) ? Qnormal : val;
+ if (! NILP (val))
+ {
+ plist[n++] = QCweight;
+ plist[n++] = val;
+ }
- plist[6] = QCslant;
val = FONT_SLANT_FOR_FACE (font);
- plist[7] = NILP (val) ? Qnormal : val;
+ if (! NILP (val))
+ {
+ plist[n++] = QCslant;
+ plist[n++] = val;
+ }
- plist[8] = QCwidth;
val = FONT_WIDTH_FOR_FACE (font);
- plist[9] = NILP (val) ? Qnormal : val;
+ if (! NILP (val))
+ {
+ plist[n++] = QCwidth;
+ plist[n++] = val;
+ }
- return Flist (10, plist);
+ return Flist (n, plist);
}
+#endif
+
DEFUN ("font-put", Ffont_put, Sfont_put, 3, 3, 0,
doc: /* Set one property of FONT-SPEC: give property PROP value VAL. */)
(font_spec, prop, val)
return Fcons (AREF (vec, 0), Qnil);
if (! NILP (prefer))
- vec = font_sort_entites (vec, prefer, frame, font_spec, 0);
+ vec = font_sort_entites (vec, prefer, frame, 0);
list = tail = Fcons (AREF (vec, 0), Qnil);
if (n == 0 || n > len)
if (FONTP (arg))
arg = Ffont_xlfd_name (arg, Qt);
if (FONTP (result))
- result = Ffont_xlfd_name (result, Qt);
+ {
+ val = Ffont_xlfd_name (result, Qt);
+ if (! FONT_SPEC_P (result))
+ val = concat3 (SYMBOL_NAME (AREF (result, FONT_TYPE_INDEX)),
+ build_string (":"), val);
+ result = val;
+ }
else if (CONSP (result))
{
result = Fcopy_sequence (result);
extern void syms_of_bdffont P_ (());
extern void syms_of_w32font P_ (());
extern void syms_of_atmfont P_ (());
+extern void syms_of_nsfont P_ (());
void
syms_of_font ()
defsubr (&Sfontp);
defsubr (&Sfont_spec);
defsubr (&Sfont_get);
+#ifdef HAVE_WINDOW_SYSTEM
defsubr (&Sfont_face_attributes);
+#endif
defsubr (&Sfont_put);
defsubr (&Slist_fonts);
defsubr (&Sfont_family_list);
#ifdef WINDOWSNT
syms_of_w32font ();
#endif /* WINDOWSNT */
+#ifdef HAVE_NS
+ syms_of_nsfont ();
+#endif /* HAVE_NS */
#ifdef MAC_OS
syms_of_atmfont ();
#endif /* MAC_OS */