/* font.c -- "Font" primitives.
-Copyright (C) 2006-2011 Free Software Foundation, Inc.
+Copyright (C) 2006-2012 Free Software Foundation, Inc.
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H13PRO009
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
+#include <float.h>
#include <stdio.h>
#include <ctype.h>
#include <setjmp.h>
\f
-/* Creaters of font-related Lisp object. */
+/* Creators of font-related Lisp object. */
static Lisp_Object
font_make_spec (void)
STR. */
Lisp_Object
-font_intern_prop (const char *str, int len, int force_symbol)
+font_intern_prop (const char *str, ptrdiff_t len, int force_symbol)
{
- int i;
+ ptrdiff_t i;
Lisp_Object tem;
Lisp_Object obarray;
EMACS_INT nbytes, nchars;
if (len == 1 && *str == '*')
return Qnil;
- if (!force_symbol && len >=1 && isdigit (*str))
+ if (!force_symbol && 0 < len && '0' <= *str && *str <= '9')
{
for (i = 1; i < len; i++)
- if (! isdigit (str[i]))
+ if (! ('0' <= str[i] && str[i] <= '9'))
break;
if (i == len)
- return make_number (atoi (str));
+ {
+ EMACS_INT n;
+
+ i = 0;
+ for (n = 0; (n += str[i++] - '0') <= MOST_POSITIVE_FIXNUM; n *= 10)
+ {
+ if (i == len)
+ return make_number (n);
+ if (MOST_POSITIVE_FIXNUM / 10 < n)
+ break;
+ }
+
+ xsignal1 (Qoverflow_error, make_string (str, len));
+ }
}
/* The following code is copied from the function intern (in
/* Function to validate PROP's value VAL, or NULL if any value is
ok. The value is VAL or its regularized value if VAL is valid,
and Qerror if not. */
- Lisp_Object (*validater) (Lisp_Object prop, Lisp_Object val);
+ Lisp_Object (*validator) (Lisp_Object prop, Lisp_Object val);
} font_property_table[] =
{ { &QCtype, font_prop_validate_symbol },
{ &QCfoundry, font_prop_validate_symbol },
if (idx < 0)
return val;
}
- validated = (font_property_table[idx].validater) (prop, val);
+ validated = (font_property_table[idx].validator) (prop, val);
if (EQ (validated, Qerror))
signal_error ("invalid font property", Fcons (prop, val));
return validated;
struct {
/* Minimum possible field. */
int from;
- /* Maxinum possible field. */
+ /* Maximum possible field. */
int to;
/* Bit mask of possible field. Nth bit corresponds to Nth field. */
int mask;
range_mask = (range_mask << 1) | 1;
/* The triplet RANGE_FROM, RANGE_TO, and RANGE_MASK is a
- position-based retriction for FIELD[I]. */
+ position-based restriction for FIELD[I]. */
for (i = 0, range_from = 0, range_to = 14 - n; i < n;
i++, range_from++, range_to++, range_mask <<= 1)
{
else
{
/* The triplet FROM, TO, and MASK is a value-based
- retriction for FIELD[I]. */
+ restriction for FIELD[I]. */
int from, to;
unsigned mask;
}
}
- /* Decide all fileds from restrictions in RANGE. */
+ /* Decide all fields from restrictions in RANGE. */
for (i = j = 0; i < n ; i++)
{
if (j < range[i].from)
int
font_parse_xlfd (char *name, Lisp_Object font)
{
- int len = strlen (name);
+ ptrdiff_t len = strlen (name);
int i, j, n;
char *f[XLFD_LAST_INDEX + 1];
Lisp_Object val;
char *p;
const char *f[XLFD_REGISTRY_INDEX + 1];
Lisp_Object val;
- int i, j, len = 0;
+ int i, j, len;
font_assert (FONTP (font));
if (NILP (val))
{
if (j == XLFD_REGISTRY_INDEX)
- f[j] = "*-*", len += 4;
+ f[j] = "*-*";
else
- f[j] = "*", len += 2;
+ f[j] = "*";
}
else
{
&& ! strchr (SSDATA (val), '-'))
{
/* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */
- if (SDATA (val)[SBYTES (val) - 1] == '*')
- {
- f[j] = p = alloca (SBYTES (val) + 3);
- sprintf (p, "%s-*", SDATA (val));
- len += SBYTES (val) + 3;
- }
- else
- {
- f[j] = p = alloca (SBYTES (val) + 4);
- sprintf (p, "%s*-*", SDATA (val));
- len += SBYTES (val) + 4;
- }
+ ptrdiff_t alloc = SBYTES (val) + 4;
+ if (nbytes <= alloc)
+ return -1;
+ f[j] = p = alloca (alloc);
+ sprintf (p, "%s%s-*", SDATA (val),
+ "*" + (SDATA (val)[SBYTES (val) - 1] == '*'));
}
else
- f[j] = SSDATA (val), len += SBYTES (val) + 1;
+ f[j] = SSDATA (val);
}
}
{
val = font_style_symbolic (font, i, 0);
if (NILP (val))
- f[j] = "*", len += 2;
+ f[j] = "*";
else
{
val = SYMBOL_NAME (val);
- f[j] = SSDATA (val), len += SBYTES (val) + 1;
+ f[j] = SSDATA (val);
}
}
font_assert (NUMBERP (val) || NILP (val));
if (INTEGERP (val))
{
- i = XINT (val);
- if (i <= 0)
- i = pixel_size;
- if (i > 0)
+ EMACS_INT v = XINT (val);
+ if (v <= 0)
+ v = pixel_size;
+ if (v > 0)
{
- f[XLFD_PIXEL_INDEX] = p = alloca (22);
- len += sprintf (p, "%d-*", i) + 1;
+ f[XLFD_PIXEL_INDEX] = p =
+ alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
+ sprintf (p, "%"pI"d-*", v);
}
else
- f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
+ f[XLFD_PIXEL_INDEX] = "*-*";
}
else if (FLOATP (val))
{
- i = XFLOAT_DATA (val) * 10;
- f[XLFD_PIXEL_INDEX] = p = alloca (12);
- len += sprintf (p, "*-%d", i) + 1;
+ double v = XFLOAT_DATA (val) * 10;
+ f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1);
+ sprintf (p, "*-%.0f", v);
}
else
- f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
+ f[XLFD_PIXEL_INDEX] = "*-*";
if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
{
- i = XINT (AREF (font, FONT_DPI_INDEX));
- f[XLFD_RESX_INDEX] = p = alloca (22);
- len += sprintf (p, "%d-%d", i, i) + 1;
+ EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
+ f[XLFD_RESX_INDEX] = p =
+ alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
+ sprintf (p, "%"pI"d-%"pI"d", v, v);
}
else
- f[XLFD_RESX_INDEX] = "*-*", len += 4;
+ f[XLFD_RESX_INDEX] = "*-*";
if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
{
- int spacing = XINT (AREF (font, FONT_SPACING_INDEX));
+ EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p"
: spacing <= FONT_SPACING_DUAL ? "d"
: spacing <= FONT_SPACING_MONO ? "m"
: "c");
- len += 2;
}
else
- f[XLFD_SPACING_INDEX] = "*", len += 2;
+ f[XLFD_SPACING_INDEX] = "*";
if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
{
- f[XLFD_AVGWIDTH_INDEX] = p = alloca (22);
- len += sprintf (p, "%"pI"d",
- XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1;
+ f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT));
+ sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
}
else
- f[XLFD_AVGWIDTH_INDEX] = "*", len += 2;
- len++; /* for terminating '\0'. */
- if (len >= nbytes)
- return -1;
- return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
+ f[XLFD_AVGWIDTH_INDEX] = "*";
+ len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX],
f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX],
f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
f[XLFD_REGISTRY_INDEX]);
+ return len < nbytes ? len : -1;
}
/* Parse NAME (null terminated) and store information in FONT
char *p, *q;
char *size_beg = NULL, *size_end = NULL;
char *props_beg = NULL, *family_end = NULL;
- int len = strlen (name);
+ ptrdiff_t len = strlen (name);
if (len == 0)
return -1;
{
int decimal = 0, size_found = 1;
for (q = p + 1; *q && *q != ':'; q++)
- if (! isdigit(*q))
+ if (! isdigit (*q))
{
if (*q != '.' || decimal)
{
if (*q != '=')
{
/* Must be an enumerated value. */
- int word_len;
+ ptrdiff_t word_len;
p = p + 1;
word_len = q - p;
val = font_intern_prop (p, q - p, 1);
Lisp_Object weight = Qnil, slant = Qnil;
Lisp_Object width = Qnil, size = Qnil;
char *word_start;
- int word_len;
+ ptrdiff_t word_len;
/* Scan backwards from the end, looking for a size. */
for (p = name + len - 1; p >= name; p--)
font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
{
Lisp_Object family, foundry;
- Lisp_Object tail, val;
+ Lisp_Object val;
int point_size;
- int i, len = 1;
+ int i;
char *p;
+ char *lim;
Lisp_Object styles[3];
const char *style_names[3] = { "weight", "slant", "width" };
- char work[256];
family = AREF (font, FONT_FAMILY_INDEX);
if (! NILP (family))
{
if (SYMBOLP (family))
- {
- family = SYMBOL_NAME (family);
- len += SBYTES (family);
- }
+ family = SYMBOL_NAME (family);
else
family = Qnil;
}
if (XINT (val) != 0)
pixel_size = XINT (val);
point_size = -1;
- len += 21; /* for ":pixelsize=NUM" */
}
else
{
abort ();
pixel_size = -1;
point_size = (int) XFLOAT_DATA (val);
- len += 11; /* for "-NUM" */
}
foundry = AREF (font, FONT_FOUNDRY_INDEX);
if (! NILP (foundry))
{
if (SYMBOLP (foundry))
- {
- foundry = SYMBOL_NAME (foundry);
- len += 9 + SBYTES (foundry); /* ":foundry=NAME" */
- }
+ foundry = SYMBOL_NAME (foundry);
else
foundry = Qnil;
}
for (i = 0; i < 3; i++)
- {
- styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
- if (! NILP (styles[i]))
- len += sprintf (work, ":%s=%s", style_names[i],
- SDATA (SYMBOL_NAME (styles[i])));
- }
-
- if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
- len += sprintf (work, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX)));
- if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
- len += strlen (":spacing=100");
- if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
- len += strlen (":scalable=false"); /* or ":scalable=true" */
- for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
- {
- Lisp_Object key = XCAR (XCAR (tail)), value = XCDR (XCAR (tail));
-
- len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */
- if (STRINGP (value))
- len += SBYTES (value);
- else if (INTEGERP (value))
- len += sprintf (work, "%"pI"d", XINT (value));
- else if (SYMBOLP (value))
- len += (NILP (value) ? 5 : 4); /* for "false" or "true" */
- }
+ styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
- if (len > nbytes)
- return -1;
p = name;
+ lim = name + nbytes;
if (! NILP (family))
- p += sprintf (p, "%s", SDATA (family));
+ {
+ int len = snprintf (p, lim - p, "%s", SSDATA (family));
+ if (! (0 <= len && len < lim - p))
+ return -1;
+ p += len;
+ }
if (point_size > 0)
{
- if (p == name)
- p += sprintf (p, "%d", point_size);
- else
- p += sprintf (p, "-%d", point_size);
+ int len = snprintf (p, lim - p, "-%d" + (p == name), point_size);
+ if (! (0 <= len && len < lim - p))
+ return -1;
+ p += len;
}
else if (pixel_size > 0)
- p += sprintf (p, ":pixelsize=%d", pixel_size);
+ {
+ int len = snprintf (p, lim - p, ":pixelsize=%d", pixel_size);
+ if (! (0 <= len && len < lim - p))
+ return -1;
+ p += len;
+ }
if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
- p += sprintf (p, ":foundry=%s",
- SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX))));
+ {
+ int len = snprintf (p, lim - p, ":foundry=%s",
+ SSDATA (SYMBOL_NAME (AREF (font,
+ FONT_FOUNDRY_INDEX))));
+ if (! (0 <= len && len < lim - p))
+ return -1;
+ p += len;
+ }
for (i = 0; i < 3; i++)
if (! NILP (styles[i]))
- p += sprintf (p, ":%s=%s", style_names[i],
- SDATA (SYMBOL_NAME (styles[i])));
+ {
+ int len = snprintf (p, lim - p, ":%s=%s", style_names[i],
+ SSDATA (SYMBOL_NAME (styles[i])));
+ if (! (0 <= len && len < lim - p))
+ return -1;
+ p += len;
+ }
+
if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
- p += sprintf (p, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX)));
+ {
+ int len = snprintf (p, lim - p, ":dpi=%"pI"d",
+ XINT (AREF (font, FONT_DPI_INDEX)));
+ if (! (0 <= len && len < lim - p))
+ return -1;
+ p += len;
+ }
+
if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
- p += sprintf (p, ":spacing=%"pI"d", XINT (AREF (font, FONT_SPACING_INDEX)));
+ {
+ int len = snprintf (p, lim - p, ":spacing=%"pI"d",
+ XINT (AREF (font, FONT_SPACING_INDEX)));
+ if (! (0 <= len && len < lim - p))
+ return -1;
+ p += len;
+ }
+
if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
{
- if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0)
- p += sprintf (p, ":scalable=true");
- else
- p += sprintf (p, ":scalable=false");
+ int len = snprintf (p, lim - p,
+ (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
+ ? ":scalable=true"
+ : ":scalable=false"));
+ if (! (0 <= len && len < lim - p))
+ return -1;
+ p += len;
}
+
return (p - name);
}
#define LGSTRING_GLYPH_SIZE 8
static int
-check_gstring (gstring)
- Lisp_Object gstring;
+check_gstring (Lisp_Object gstring)
{
Lisp_Object val;
int i, j;
}
static void
-check_otf_features (otf_features)
- Lisp_Object otf_features;
+check_otf_features (Lisp_Object otf_features)
{
Lisp_Object val;
Lisp_Object otf_list;
static Lisp_Object
-otf_tag_symbol (tag)
- OTF_Tag tag;
+otf_tag_symbol (OTF_Tag tag)
{
char name[5];
}
static OTF *
-otf_open (file)
- Lisp_Object file;
+otf_open (Lisp_Object file)
{
Lisp_Object val = Fassoc (file, otf_list);
OTF *otf;
(struct font_driver).otf_capability. */
Lisp_Object
-font_otf_capability (font)
- struct font *font;
+font_otf_capability (struct font *font)
{
OTF *otf;
Lisp_Object capability = Fcons (Qnil, Qnil);
FEATURES. */
static void
-generate_otf_features (spec, features)
- Lisp_Object spec;
- char *features;
+generate_otf_features (Lisp_Object spec, char *features)
{
Lisp_Object val;
char *p;
else if (! asterisk)
{
val = SYMBOL_NAME (val);
- p += sprintf (p, "%s", SDATA (val));
+ p += esprintf (p, "%s", SDATA (val));
}
else
{
val = SYMBOL_NAME (val);
- p += sprintf (p, "~%s", SDATA (val));
+ p += esprintf (p, "~%s", SDATA (val));
}
}
if (CONSP (spec))
}
Lisp_Object
-font_otf_DeviceTable (device_table)
- OTF_DeviceTable *device_table;
+font_otf_DeviceTable (OTF_DeviceTable *device_table)
{
int len = device_table->StartSize - device_table->EndSize + 1;
}
Lisp_Object
-font_otf_ValueRecord (value_format, value_record)
- int value_format;
- OTF_ValueRecord *value_record;
+font_otf_ValueRecord (int value_format, OTF_ValueRecord *value_record)
{
Lisp_Object val = Fmake_vector (make_number (8), Qnil);
}
Lisp_Object
-font_otf_Anchor (anchor)
- OTF_Anchor *anchor;
+font_otf_Anchor (OTF_Anchor *anchor)
{
Lisp_Object val;
{
/* We use the higher 6-bit for the actual size difference. The
lowest bit is set if the DPI is different. */
- int diff;
- int pixel_size = XINT (spec_prop[FONT_SIZE_INDEX]);
+ EMACS_INT diff;
+ EMACS_INT pixel_size = XINT (spec_prop[FONT_SIZE_INDEX]);
if (CONSP (Vface_font_rescale_alist))
pixel_size *= font_rescale_ratio (entity);
else
{
Lisp_Object alters
- = Fassoc_string (val, Vface_alternative_font_family_alist,
- /* Font family names are case-sensitive under NS. */
-#ifndef HAVE_NS
- Qt
-#else
- Qnil
-#endif
- );
+ = Fassoc_string (val, Vface_alternative_font_family_alist, Qt);
if (! NILP (alters))
{
if (INTEGERP (height))
pt = XINT (height);
else
- abort(); /* We should never end up here. */
+ abort (); /* We should never end up here. */
}
pt /= 10;
#ifdef HAVE_NS
if (size == 0)
{
- Lisp_Object ffsize = get_frame_param(f, Qfontsize);
+ Lisp_Object ffsize = get_frame_param (f, Qfontsize);
size = NUMBERP (ffsize) ? POINT_TO_PIXEL (XINT (ffsize), f->resy) : 0;
}
#endif
else
FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte);
category = CHAR_TABLE_REF (Vunicode_category_table, c);
- if (EQ (category, QCf)
- || CHAR_VARIATION_SELECTOR_P (c))
+ if (INTEGERP (category)
+ && (XINT (category) == UNICODE_CATEGORY_Cf
+ || CHAR_VARIATION_SELECTOR_P (c)))
continue;
if (NILP (font_object))
{
language system must contain `mark' feature.
usage: (font-spec ARGS...) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object spec = font_make_spec ();
- size_t i;
+ ptrdiff_t i;
for (i = 0; i < nargs; i += 2)
{
{
struct font *font;
Lisp_Object font_object, n, glyph;
- int i, j, from, to;
+ EMACS_INT i, j, from, to;
if (! composition_gstring_p (gstring))
signal_error ("Invalid glyph-string: ", gstring);
for (i = 0; i < 255; i++)
if (variations[i])
{
- Lisp_Object code;
int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
- /* Stops GCC whining about limited range of data type. */
- EMACS_INT var = variations[i];
-
- if (var > MOST_POSITIVE_FIXNUM)
- code = Fcons (make_number ((variations[i]) >> 16),
- make_number ((variations[i]) & 0xFFFF));
- else
- code = make_number (variations[i]);
+ Lisp_Object code = INTEGER_TO_CONS (variations[i]);
val = Fcons (Fcons (make_number (vs), code), val);
}
return val;
the table by a character gives the corresponding glyph code.
REPERTORY specifies a repertory of characters supported by the font.
-If REPERTORY is a charset, all characters beloging to the charset are
+If REPERTORY is a charset, all characters belonging to the charset are
supported. If REPERTORY is a char-table, all characters who have a
non-nil value in the table are supported. If REPERTORY is nil, Emacs
gets the repertory information by an opened font and ENCODING. */);