Commit 45eb10fb authored by Kenichi Handa's avatar Kenichi Handa
Browse files

(font_prop_validate_symbol): The argument prop_index is

deleted.
(font_prop_validate_style, font_prop_validate_non_neg)
(font_prop_validate_spacing): Likewise.
(font_property_table): Arguments to validater changed.  Callers
changed.
(font_lispy_object): Deleted.
(font_at): Use font_find_object instead fo font_lispy_object.
parent c5bb82f6
...@@ -88,7 +88,7 @@ Lisp_Object null_string; ...@@ -88,7 +88,7 @@ Lisp_Object null_string;
Lisp_Object null_vector; Lisp_Object null_vector;
/* Vector of 3 elements. Each element is an alist for one of font /* Vector of 3 elements. Each element is an alist for one of font
style properties (weight, slant, width). The alist contains a style properties (weight, slant, width). Each alist contains a
mapping between symbolic property values (e.g. `medium' for weight) mapping between symbolic property values (e.g. `medium' for weight)
and numeric property values (e.g. 100). So, it looks like this: and numeric property values (e.g. 100). So, it looks like this:
[((thin . 0) ... (heavy . 210)) [((thin . 0) ... (heavy . 210))
...@@ -232,6 +232,11 @@ intern_downcase (str, len) ...@@ -232,6 +232,11 @@ intern_downcase (str, len)
extern Lisp_Object Vface_alternative_font_family_alist; extern Lisp_Object Vface_alternative_font_family_alist;
/* Setup font_family_alist of the form:
((FAMILY-SYMBOL ALIAS-SYMBOL ...) ...)
from Vface_alternative_font_family_alist of the form:
((FAMILY-STRING ALIAS-STRING ...) ...) */
static void static void
build_font_family_alist () build_font_family_alist ()
{ {
...@@ -248,22 +253,18 @@ build_font_family_alist () ...@@ -248,22 +253,18 @@ build_font_family_alist ()
} }
/* Font property validater. */ /* Font property value validaters. See the comment of
font_property_table for the meaning of the arguments. */
static Lisp_Object font_prop_validate_symbol P_ ((enum font_property_index,
Lisp_Object, Lisp_Object)); static Lisp_Object font_prop_validate_symbol P_ ((Lisp_Object, Lisp_Object));
static Lisp_Object font_prop_validate_style P_ ((enum font_property_index, static Lisp_Object font_prop_validate_style P_ ((Lisp_Object, Lisp_Object));
Lisp_Object, Lisp_Object)); static Lisp_Object font_prop_validate_non_neg P_ ((Lisp_Object, Lisp_Object));
static Lisp_Object font_prop_validate_non_neg P_ ((enum font_property_index, static Lisp_Object font_prop_validate_spacing P_ ((Lisp_Object, Lisp_Object));
Lisp_Object, Lisp_Object));
static Lisp_Object font_prop_validate_spacing P_ ((enum font_property_index,
Lisp_Object, Lisp_Object));
static int get_font_prop_index P_ ((Lisp_Object, int)); static int get_font_prop_index P_ ((Lisp_Object, int));
static Lisp_Object font_prop_validate P_ ((Lisp_Object)); static Lisp_Object font_prop_validate P_ ((Lisp_Object));
static Lisp_Object static Lisp_Object
font_prop_validate_symbol (prop_index, prop, val) font_prop_validate_symbol (prop, val)
enum font_property_index prop_index;
Lisp_Object prop, val; Lisp_Object prop, val;
{ {
if (EQ (prop, QCotf)) if (EQ (prop, QCotf))
...@@ -282,8 +283,7 @@ font_prop_validate_symbol (prop_index, prop, val) ...@@ -282,8 +283,7 @@ font_prop_validate_symbol (prop_index, prop, val)
} }
static Lisp_Object static Lisp_Object
font_prop_validate_style (prop_index, prop, val) font_prop_validate_style (prop, val)
enum font_property_index prop_index;
Lisp_Object prop, val; Lisp_Object prop, val;
{ {
if (! INTEGERP (val)) if (! INTEGERP (val))
...@@ -294,6 +294,11 @@ font_prop_validate_style (prop_index, prop, val) ...@@ -294,6 +294,11 @@ font_prop_validate_style (prop_index, prop, val)
val = Qerror; val = Qerror;
else else
{ {
enum font_property_index prop_index
= (EQ (prop, QCweight) ? FONT_WEIGHT_INDEX
: EQ (prop, QCslant) ? FONT_SLANT_INDEX
: FONT_WIDTH_INDEX);
val = prop_name_to_numeric (prop_index, val); val = prop_name_to_numeric (prop_index, val);
if (NILP (val)) if (NILP (val))
val = Qerror; val = Qerror;
...@@ -303,8 +308,7 @@ font_prop_validate_style (prop_index, prop, val) ...@@ -303,8 +308,7 @@ font_prop_validate_style (prop_index, prop, val)
} }
static Lisp_Object static Lisp_Object
font_prop_validate_non_neg (prop_index, prop, val) font_prop_validate_non_neg (prop, val)
enum font_property_index prop_index;
Lisp_Object prop, val; Lisp_Object prop, val;
{ {
return (NATNUMP (val) || (FLOATP (val) && XFLOAT_DATA (val) >= 0) return (NATNUMP (val) || (FLOATP (val) && XFLOAT_DATA (val) >= 0)
...@@ -312,8 +316,7 @@ font_prop_validate_non_neg (prop_index, prop, val) ...@@ -312,8 +316,7 @@ font_prop_validate_non_neg (prop_index, prop, val)
} }
static Lisp_Object static Lisp_Object
font_prop_validate_spacing (prop_index, prop, val) font_prop_validate_spacing (prop, val)
enum font_property_index prop_index;
Lisp_Object prop, val; Lisp_Object prop, val;
{ {
if (NILP (val) || (NATNUMP (val) && XINT (val) <= FONT_SPACING_CHARCELL)) if (NILP (val) || (NATNUMP (val) && XINT (val) <= FONT_SPACING_CHARCELL))
...@@ -333,9 +336,10 @@ struct ...@@ -333,9 +336,10 @@ struct
{ {
/* Pointer to the key symbol. */ /* Pointer to the key symbol. */
Lisp_Object *key; Lisp_Object *key;
/* Function to validate the value VAL, or NULL if any value is ok. */ /* Function to validate PROP's value VAL, or NULL if any value is
Lisp_Object (*validater) P_ ((enum font_property_index prop_index, ok. The value is VAL or its regularized value if VAL is valid,
Lisp_Object prop, Lisp_Object val)); and Qerror if not. */
Lisp_Object (*validater) P_ ((Lisp_Object prop, Lisp_Object val));
} font_property_table[] = } font_property_table[] =
{ { &QCtype, font_prop_validate_symbol }, { { &QCtype, font_prop_validate_symbol },
{ &QCfoundry, font_prop_validate_symbol }, { &QCfoundry, font_prop_validate_symbol },
...@@ -354,9 +358,14 @@ struct ...@@ -354,9 +358,14 @@ struct
{ &QCotf, font_prop_validate_symbol } { &QCotf, font_prop_validate_symbol }
}; };
/* Size (number of elements) of the above table. */
#define FONT_PROPERTY_TABLE_SIZE \ #define FONT_PROPERTY_TABLE_SIZE \
((sizeof font_property_table) / (sizeof *font_property_table)) ((sizeof font_property_table) / (sizeof *font_property_table))
/* Return an index number of font property KEY or -1 if KEY is not an
already known property. Start searching font_property_table from
index FROM (which is 0 or FONT_EXTRA_INDEX). */
static int static int
get_font_prop_index (key, from) get_font_prop_index (key, from)
Lisp_Object key; Lisp_Object key;
...@@ -368,6 +377,10 @@ get_font_prop_index (key, from) ...@@ -368,6 +377,10 @@ get_font_prop_index (key, from)
return -1; return -1;
} }
/* Validate font properties in SPEC (vector) while updating elements
to regularized values. Signal an error if an invalid property is
found. */
static Lisp_Object static Lisp_Object
font_prop_validate (spec) font_prop_validate (spec)
Lisp_Object spec; Lisp_Object spec;
...@@ -380,7 +393,7 @@ font_prop_validate (spec) ...@@ -380,7 +393,7 @@ font_prop_validate (spec)
if (! NILP (AREF (spec, i))) if (! NILP (AREF (spec, i)))
{ {
prop = *font_property_table[i].key; prop = *font_property_table[i].key;
val = (font_property_table[i].validater) (i, prop, AREF (spec, i)); val = (font_property_table[i].validater) (prop, AREF (spec, i));
if (EQ (val, Qerror)) if (EQ (val, Qerror))
Fsignal (Qfont, list2 (build_string ("invalid font property"), Fsignal (Qfont, list2 (build_string ("invalid font property"),
Fcons (prop, AREF (spec, i)))); Fcons (prop, AREF (spec, i))));
...@@ -397,7 +410,7 @@ font_prop_validate (spec) ...@@ -397,7 +410,7 @@ font_prop_validate (spec)
if (i >= 0 if (i >= 0
&& font_property_table[i].validater) && font_property_table[i].validater)
{ {
val = (font_property_table[i].validater) (i, prop, XCDR (elt)); val = (font_property_table[i].validater) (prop, XCDR (elt));
if (EQ (val, Qerror)) if (EQ (val, Qerror))
Fsignal (Qfont, list2 (build_string ("invalid font property"), Fsignal (Qfont, list2 (build_string ("invalid font property"),
elt)); elt));
...@@ -407,6 +420,8 @@ font_prop_validate (spec) ...@@ -407,6 +420,8 @@ font_prop_validate (spec)
return spec; return spec;
} }
/* Store VAL as a value of extra font property PROP in FONT. */
Lisp_Object Lisp_Object
font_put_extra (font, prop, val) font_put_extra (font, prop, val)
Lisp_Object font, prop, val; Lisp_Object font, prop, val;
...@@ -1357,6 +1372,10 @@ font_parse_name (name, font) ...@@ -1357,6 +1372,10 @@ font_parse_name (name, font)
return font_parse_fcname (name, font); return font_parse_fcname (name, font);
} }
/* Merge old style font specification (either a font name NAME or a
combination of a family name FAMILY and a registry name REGISTRY
into the font specification SPEC. */
void void
font_merge_old_spec (name, family, registry, spec) font_merge_old_spec (name, family, registry, spec)
Lisp_Object name, family, registry, spec; Lisp_Object name, family, registry, spec;
...@@ -1401,22 +1420,11 @@ font_merge_old_spec (name, family, registry, spec) ...@@ -1401,22 +1420,11 @@ font_merge_old_spec (name, family, registry, spec)
} }
} }
static Lisp_Object
font_lispy_object (font) /* This part (through the next ^L) is still experimental and never
struct font *font; tested. We may drastically change codes. */
{
Lisp_Object objlist = AREF (font->entity, FONT_OBJLIST_INDEX);
for (; ! NILP (objlist); objlist = XCDR (objlist))
{
struct Lisp_Save_Value *p = XSAVE_VALUE (XCAR (objlist));
if (font == (struct font *) p->pointer) /* OTF handler */
break;
}
xassert (! NILP (objlist));
return XCAR (objlist);
}
#define LGSTRING_HEADER_SIZE 6 #define LGSTRING_HEADER_SIZE 6
#define LGSTRING_GLYPH_SIZE 8 #define LGSTRING_GLYPH_SIZE 8
...@@ -1476,9 +1484,6 @@ check_gstring (gstring) ...@@ -1476,9 +1484,6 @@ check_gstring (gstring)
return -1; return -1;
} }
/* OTF handler */
static void static void
check_otf_features (otf_features) check_otf_features (otf_features)
Lisp_Object otf_features; Lisp_Object otf_features;
...@@ -1978,7 +1983,6 @@ font_drive_otf (font, otf_features, gstring_in, from, to, gstring_out, idx, ...@@ -1978,7 +1983,6 @@ font_drive_otf (font, otf_features, gstring_in, from, to, gstring_out, idx,
#endif /* HAVE_LIBOTF */ #endif /* HAVE_LIBOTF */
/* G-string (glyph string) handler */ /* G-string (glyph string) handler */
/* G-string is a vector of the form [HEADER GLYPH ...]. /* G-string is a vector of the form [HEADER GLYPH ...].
...@@ -2105,7 +2109,7 @@ static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object, ...@@ -2105,7 +2109,7 @@ static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object,
font-spec. The score value is 32 bit (`unsigned'), and the smaller font-spec. The score value is 32 bit (`unsigned'), and the smaller
the value is, the closer the font is to the font-spec. the value is, the closer the font is to the font-spec.
Each 1-bit in the highest 4 bits of the score is used for atomic Each 1-bit of the highest 4 bits of the score is used for atomic
properties FOUNDRY, FAMILY, ADSTYLE, and REGISTRY. properties FOUNDRY, FAMILY, ADSTYLE, and REGISTRY.
Each 7-bit in the lowest 28 bits are used for numeric properties Each 7-bit in the lowest 28 bits are used for numeric properties
...@@ -2235,6 +2239,10 @@ font_sort_entites (vec, prefer, frame, spec) ...@@ -2235,6 +2239,10 @@ font_sort_entites (vec, prefer, frame, spec)
/* API of Font Service Layer. */ /* API of Font Service Layer. */
/* Reflect ORDER (see the variable font_sort_order in xfaces.c) to
sort_shift_bits. Finternal_set_font_selection_order calls this
function with font_sort_order after setting up it. */
void void
font_update_sort_order (order) font_update_sort_order (order)
int *order; int *order;
...@@ -2256,6 +2264,9 @@ font_update_sort_order (order) ...@@ -2256,6 +2264,9 @@ font_update_sort_order (order)
} }
} }
/* Return weight property of FONT as symbol. */
Lisp_Object Lisp_Object
font_symbolic_weight (font) font_symbolic_weight (font)
Lisp_Object font; Lisp_Object font;
...@@ -2267,6 +2278,9 @@ font_symbolic_weight (font) ...@@ -2267,6 +2278,9 @@ font_symbolic_weight (font)
return weight; return weight;
} }
/* Return slant property of FONT as symbol. */
Lisp_Object Lisp_Object
font_symbolic_slant (font) font_symbolic_slant (font)
Lisp_Object font; Lisp_Object font;
...@@ -2278,6 +2292,9 @@ font_symbolic_slant (font) ...@@ -2278,6 +2292,9 @@ font_symbolic_slant (font)
return slant; return slant;
} }
/* Return width property of FONT as symbol. */
Lisp_Object Lisp_Object
font_symbolic_width (font) font_symbolic_width (font)
Lisp_Object font; Lisp_Object font;
...@@ -2289,6 +2306,9 @@ font_symbolic_width (font) ...@@ -2289,6 +2306,9 @@ font_symbolic_width (font)
return width; return width;
} }
/* Check if ENTITY matches with the font specification SPEC. */
int int
font_match_p (spec, entity) font_match_p (spec, entity)
Lisp_Object spec, entity; Lisp_Object spec, entity;
...@@ -2307,6 +2327,9 @@ font_match_p (spec, entity) ...@@ -2307,6 +2327,9 @@ font_match_p (spec, entity)
return 1; return 1;
} }
/* Return a lispy font object corresponding to FONT. */
Lisp_Object Lisp_Object
font_find_object (font) font_find_object (font)
struct font *font; struct font *font;
...@@ -2327,6 +2350,7 @@ font_find_object (font) ...@@ -2327,6 +2350,7 @@ font_find_object (font)
static Lisp_Object scratch_font_spec, scratch_font_prefer; static Lisp_Object scratch_font_spec, scratch_font_prefer;
/* Return a vector of font-entities matching with SPEC on frame F. */ /* Return a vector of font-entities matching with SPEC on frame F. */
static Lisp_Object static Lisp_Object
...@@ -2402,6 +2426,9 @@ font_list_entities (frame, spec) ...@@ -2402,6 +2426,9 @@ font_list_entities (frame, spec)
return (i > 0 ? Fvconcat (i, vec) : null_vector); return (i > 0 ? Fvconcat (i, vec) : null_vector);
} }
/* Return a font entity matching with SPEC on FRAME. */
static Lisp_Object static Lisp_Object
font_matching_entity (frame, spec) font_matching_entity (frame, spec)
Lisp_Object frame, spec; Lisp_Object frame, spec;
...@@ -2447,6 +2474,10 @@ font_matching_entity (frame, spec) ...@@ -2447,6 +2474,10 @@ font_matching_entity (frame, spec)
static int num_fonts; static int num_fonts;
/* Open a font of ENTITY and PIXEL_SIZE on frame F, and return the
opened font object. */
static Lisp_Object static Lisp_Object
font_open_entity (f, entity, pixel_size) font_open_entity (f, entity, pixel_size)
FRAME_PTR f; FRAME_PTR f;
...@@ -2493,6 +2524,9 @@ font_open_entity (f, entity, pixel_size) ...@@ -2493,6 +2524,9 @@ font_open_entity (f, entity, pixel_size)
return val; return val;
} }
/* Close FONT_OBJECT that is opened on frame F. */
void void
font_close_object (f, font_object) font_close_object (f, font_object)
FRAME_PTR f; FRAME_PTR f;
...@@ -2524,6 +2558,9 @@ font_close_object (f, font_object) ...@@ -2524,6 +2558,9 @@ font_close_object (f, font_object)
abort (); abort ();
} }
/* Return 1 iff FONT on F has a glyph for character C. */
int int
font_has_char (f, font, c) font_has_char (f, font, c)
FRAME_PTR f; FRAME_PTR f;
...@@ -2560,6 +2597,9 @@ font_has_char (f, font, c) ...@@ -2560,6 +2597,9 @@ font_has_char (f, font, c)
return (fontp->driver->encode_char (fontp, c) != FONT_INVALID_CODE); return (fontp->driver->encode_char (fontp, c) != FONT_INVALID_CODE);
} }
/* Return the glyph ID of FONT_OBJECT for character C. */
unsigned unsigned
font_encode_char (font_object, c) font_encode_char (font_object, c)
Lisp_Object font_object; Lisp_Object font_object;
...@@ -2570,6 +2610,9 @@ font_encode_char (font_object, c) ...@@ -2570,6 +2610,9 @@ font_encode_char (font_object, c)
return font->driver->encode_char (font, c); return font->driver->encode_char (font, c);
} }
/* Return the name of FONT_OBJECT. */
Lisp_Object Lisp_Object
font_get_name (font_object) font_get_name (font_object)
Lisp_Object font_object; Lisp_Object font_object;
...@@ -2582,6 +2625,9 @@ font_get_name (font_object) ...@@ -2582,6 +2625,9 @@ font_get_name (font_object)
return (name ? make_unibyte_string (name, strlen (name)) : null_string); return (name ? make_unibyte_string (name, strlen (name)) : null_string);
} }
/* Return the specification of FONT_OBJECT. */
Lisp_Object Lisp_Object
font_get_spec (font_object) font_get_spec (font_object)
Lisp_Object font_object; Lisp_Object font_object;
...@@ -2596,6 +2642,10 @@ font_get_spec (font_object) ...@@ -2596,6 +2642,10 @@ font_get_spec (font_object)
return spec; return spec;
} }
/* Return the frame on which FONT exists. FONT is a font object or a
font entity. */
Lisp_Object Lisp_Object
font_get_frame (font) font_get_frame (font)
Lisp_Object font; Lisp_Object font;
...@@ -2606,6 +2656,7 @@ font_get_frame (font) ...@@ -2606,6 +2656,7 @@ font_get_frame (font)
return AREF (font, FONT_FRAME_INDEX); return AREF (font, FONT_FRAME_INDEX);
} }
/* Find a font entity best matching with LFACE. If SPEC is non-nil, /* Find a font entity best matching with LFACE. If SPEC is non-nil,
the font must exactly match with it. */ the font must exactly match with it. */
...@@ -2667,14 +2718,11 @@ font_find_for_lface (f, lface, spec) ...@@ -2667,14 +2718,11 @@ font_find_for_lface (f, lface, spec)
if (! NILP (lface[LFACE_FAMILY_INDEX])) if (! NILP (lface[LFACE_FAMILY_INDEX]))
font_merge_old_spec (Qnil, lface[LFACE_FAMILY_INDEX], Qnil, prefer); font_merge_old_spec (Qnil, lface[LFACE_FAMILY_INDEX], Qnil, prefer);
ASET (prefer, FONT_WEIGHT_INDEX, ASET (prefer, FONT_WEIGHT_INDEX,
font_prop_validate_style (FONT_WEIGHT_INDEX, QCweight, font_prop_validate_style (QCweight, lface[LFACE_WEIGHT_INDEX]));
lface[LFACE_WEIGHT_INDEX]));
ASET (prefer, FONT_SLANT_INDEX, ASET (prefer, FONT_SLANT_INDEX,
font_prop_validate_style (FONT_SLANT_INDEX, QCslant, font_prop_validate_style (QCslant, lface[LFACE_SLANT_INDEX]));
lface[LFACE_SLANT_INDEX]));
ASET (prefer, FONT_WIDTH_INDEX, ASET (prefer, FONT_WIDTH_INDEX,
font_prop_validate_style (FONT_WIDTH_INDEX, QCwidth, font_prop_validate_style (QCwidth, lface[LFACE_SWIDTH_INDEX]));
lface[LFACE_SWIDTH_INDEX]));
pt = XINT (lface[LFACE_HEIGHT_INDEX]); pt = XINT (lface[LFACE_HEIGHT_INDEX]);
ASET (prefer, FONT_SIZE_INDEX, make_float (pt / 10)); ASET (prefer, FONT_SIZE_INDEX, make_float (pt / 10));
...@@ -2684,6 +2732,9 @@ font_find_for_lface (f, lface, spec) ...@@ -2684,6 +2732,9 @@ font_find_for_lface (f, lface, spec)
return AREF (entities, 0); return AREF (entities, 0);
} }
Lisp_Object Lisp_Object
font_open_for_lface (f, entity, lface, spec) font_open_for_lface (f, entity, lface, spec)
FRAME_PTR f; FRAME_PTR f;
...@@ -2705,6 +2756,11 @@ font_open_for_lface (f, entity, lface, spec) ...@@ -2705,6 +2756,11 @@ font_open_for_lface (f, entity, lface, spec)
return font_open_entity (f, entity, size); return font_open_entity (f, entity, size);
} }
/* Load a font best matching with FACE's font-related properties into
FACE on frame F. If no proper font is found, record that FACE has
no font. */
void void
font_load_for_face (f, face) font_load_for_face (f, face)
FRAME_PTR f; FRAME_PTR f;
...@@ -2739,6 +2795,9 @@ font_load_for_face (f, face) ...@@ -2739,6 +2795,9 @@ font_load_for_face (f, face)
} }
} }
/* Make FACE on frame F ready to use the font opened for FACE. */
void void
font_prepare_for_face (f, face) font_prepare_for_face (f, face)
FRAME_PTR f; FRAME_PTR f;
...@@ -2750,6 +2809,9 @@ font_prepare_for_face (f, face) ...@@ -2750,6 +2809,9 @@ font_prepare_for_face (f, face)
font->driver->prepare_face (f, face); font->driver->prepare_face (f, face);
} }
/* Make FACE on frame F stop using the font opened for FACE. */
void void
font_done_for_face (f, face) font_done_for_face (f, face)
FRAME_PTR f; FRAME_PTR f;
...@@ -2762,6 +2824,10 @@ font_done_for_face (f, face) ...@@ -2762,6 +2824,10 @@ font_done_for_face (f, face)
face->extra = NULL; face->extra = NULL;
} }
/* Open a font best matching with NAME on frame F. If no proper font
is found, return Qnil. */
Lisp_Object Lisp_Object
font_open_by_name (f, name) font_open_by_name (f, name)
FRAME_PTR f; FRAME_PTR f;
...@@ -2856,6 +2922,7 @@ register_font_driver (driver, f) ...@@ -2856,6 +2922,7 @@ register_font_driver (driver, f)
num_font_drivers++; num_font_drivers++;
} }
/* Free font-driver list on frame F. It doesn't free font-drivers /* Free font-driver list on frame F. It doesn't free font-drivers
themselves. */ themselves. */
...@@ -2872,6 +2939,7 @@ free_font_driver_list (f) ...@@ -2872,6 +2939,7 @@ free_font_driver_list (f)
} }
} }
/* Make the frame F use font backends listed in NEW_BACKENDS (list of /* Make the frame F use font backends listed in NEW_BACKENDS (list of
symbols). If NEW_BACKENDS is nil, make F use all available font symbols). If NEW_BACKENDS is nil, make F use all available font
drivers. If no backend is available, dont't alter drivers. If no backend is available, dont't alter
...@@ -2907,6 +2975,10 @@ font_update_drivers (f, new_drivers) ...@@ -2907,6 +2975,10 @@ font_update_drivers (f, new_drivers)
} }