Commit e02fe26c authored by Jimmy Aguilar Mena's avatar Jimmy Aguilar Mena

New parameter to control the face extension..

* src/xdisp.c (handle_face_prop_general): New function to specialize
handle_face_prop with ATTR_FILTER.
* src/dispextern.h (face_at_buffer_position): Added
LFACE_ATTRIBUTE_INDEX.
* src/xfaces.c (merge_face_ref): Added LFACE_ATTRIBUTE_INDEX to merge
conditionally.
parent bc8db397
......@@ -3554,8 +3554,8 @@ int lookup_derived_face (struct window *, struct frame *,
void init_frame_faces (struct frame *);
void free_frame_faces (struct frame *);
void recompute_basic_faces (struct frame *);
int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t,
bool, int);
int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *,
ptrdiff_t, bool, int, enum lface_attribute_index);
int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t,
bool, Lisp_Object);
int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t,
......
......@@ -3785,10 +3785,10 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
if (STRINGP (string))
face_id = face_at_string_position (w, string, pos, 0, &endptr,
DEFAULT_FACE_ID, false);
DEFAULT_FACE_ID, 0);
else
face_id = face_at_buffer_position (w, pos, &endptr,
pos + 100, false, -1);
pos + 100, false, -1, 0);
face = FACE_FROM_ID (f, face_id);
}
if (multibyte)
......@@ -3832,7 +3832,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
if (NILP (string))
face_id = face_at_buffer_position (w, pos, &ignore, *limit,
false, -1);
false, -1, 0);
else
{
face_id =
......@@ -4618,7 +4618,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
w = XWINDOW (window);
f = XFRAME (w->frame);
face_id = face_at_buffer_position (w, pos, &dummy,
pos + 100, false, -1);
pos + 100, false, -1, 0);
}
if (! CHAR_VALID_P (c))
return Qnil;
......
......@@ -4148,15 +4148,18 @@ handle_fontified_prop (struct it *it)
Faces
***********************************************************************/
/* Set up iterator IT from face properties at its current position.
Called from handle_stop. */
static enum prop_handled
handle_face_prop (struct it *it)
handle_face_prop_general (struct it *it,
enum lface_attribute_index attr_filter)
{
int new_face_id;
int new_face_id, *face_id_ptr;
ptrdiff_t next_stop;
if (attr_filter == LFACE_EXTEND_INDEX)
face_id_ptr = &(it->extend_face_id);
else
face_id_ptr = &(it->face_id);
if (!STRINGP (it->string))
{
new_face_id
......@@ -4165,7 +4168,7 @@ handle_face_prop (struct it *it)
&next_stop,
(IT_CHARPOS (*it)
+ TEXT_PROP_DISTANCE_LIMIT),
false, it->base_face_id);
false, it->base_face_id, attr_filter);
/* Is this a start of a run of characters with box face?
Caveat: this can be called for a freshly initialized
......@@ -4173,13 +4176,13 @@ handle_face_prop (struct it *it)
face will not change until limit, i.e. if the new face has a
box, all characters up to limit will have one. But, as
usual, we don't know whether limit is really the end. */
if (new_face_id != it->face_id)
if (new_face_id != *face_id_ptr)
{
struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
/* If it->face_id is -1, old_face below will be NULL, see
the definition of FACE_FROM_ID_OR_NULL. This will happen
if this is the initial call that gets the face. */
struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr);
/* If the value of face_id of the iterator is -1, we have to
look in front of IT's position and see whether there is a
......@@ -4285,10 +4288,10 @@ handle_face_prop (struct it *it)
box, all characters up to that position will have a
box. But, as usual, we don't know whether that position
is really the end. */
if (new_face_id != it->face_id)
if (new_face_id != *face_id_ptr)
{
struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr);
/* If new face has a box but old face hasn't, this is the
start of a run of characters with box, i.e. it has a
......@@ -4299,11 +4302,21 @@ handle_face_prop (struct it *it)
}
}
it->face_id = new_face_id;
*face_id_ptr = new_face_id;
return HANDLED_NORMALLY;
}
/* Set up iterator IT from face properties at its current position.
Called from handle_stop. */
static enum prop_handled
handle_face_prop (struct it *it)
{
return handle_face_prop_general (it, 0);
}
/* Return the ID of the face ``underlying'' IT's current position,
which is in a string. If the iterator is associated with a
buffer, return the face at IT's current buffer position.
......@@ -4527,7 +4540,7 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
face_id = face_at_buffer_position (it->w,
CHARPOS (pos),
&next_check_charpos,
limit, false, -1);
limit, false, -1, 0);
/* Correct the face for charsets different from ASCII. Do it
for the multibyte case only. The face returned above is
......@@ -7649,10 +7662,11 @@ get_next_display_element (struct it *it)
else
{
next_face_id =
face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
face_at_buffer_position (it->w, CHARPOS (pos),
&ignore,
CHARPOS (pos)
+ TEXT_PROP_DISTANCE_LIMIT,
false, -1);
false, -1, 0);
it->end_of_box_run_p
= (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX);
......@@ -32068,7 +32082,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
hlinfo->mouse_face_face_id
= face_at_buffer_position (w, mouse_charpos, &ignore,
mouse_charpos + 1,
!hlinfo->mouse_face_hidden, -1);
!hlinfo->mouse_face_hidden, -1, 0);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
}
......@@ -347,7 +347,8 @@ static struct face_cache *make_face_cache (struct frame *);
static void free_face_cache (struct face_cache *);
static bool merge_face_ref (struct window *w,
struct frame *, Lisp_Object, Lisp_Object *,
bool, struct named_merge_point *);
bool, struct named_merge_point *,
enum lface_attribute_index);
static int color_distance (Emacs_Color *x, Emacs_Color *y);
#ifdef HAVE_WINDOW_SYSTEM
......@@ -1910,7 +1911,8 @@ get_lface_attributes (struct window *w,
attrs[i] = Qunspecified;
return merge_face_ref (w, f, XCDR (face_remapping), attrs,
signal_p, named_merge_points);
signal_p, named_merge_points,
0);
}
}
......@@ -2065,7 +2067,8 @@ merge_face_vectors (struct window *w,
if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
&& !NILP (from[LFACE_INHERIT_INDEX]))
merge_face_ref (w, f, from[LFACE_INHERIT_INDEX],
to, false, named_merge_points);
to, false, named_merge_points,
0);
if (FONT_SPEC_P (from[LFACE_FONT_INDEX]))
{
......@@ -2131,7 +2134,8 @@ merge_face_vectors (struct window *w,
static bool
merge_named_face (struct window *w,
struct frame *f, Lisp_Object face_name, Lisp_Object *to,
struct named_merge_point *named_merge_points)
struct named_merge_point *named_merge_points,
enum lface_attribute_index attr_filter)
{
struct named_merge_point named_merge_point;
......@@ -2141,9 +2145,13 @@ merge_named_face (struct window *w,
{
Lisp_Object from[LFACE_VECTOR_SIZE];
bool ok = get_lface_attributes (w, f, face_name, from, false,
named_merge_points);
named_merge_points);
if (ok)
eassert (attr_filter < LFACE_VECTOR_SIZE);
if (ok && (attr_filter == 0
|| (!NILP (from[attr_filter])
&& !UNSPECIFIEDP (from[attr_filter]))))
merge_face_vectors (w, f, from, to, named_merge_points);
return ok;
......@@ -2274,6 +2282,11 @@ filter_face_ref (Lisp_Object face_ref,
of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face
inheritance or list structure; it may be 0 for most callers.
attr_filter is the index of a parameter that conditions the merging
for named faces (case 1) to only the face_ref where
lface[merge_face_ref] is non-nil. To merge unconditionally set this
value to 0.
FACE_REF may be a single face specification or a list of such
specifications. Each face specification can be:
......@@ -2302,7 +2315,8 @@ filter_face_ref (Lisp_Object face_ref,
static bool
merge_face_ref (struct window *w,
struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
bool err_msgs, struct named_merge_point *named_merge_points)
bool err_msgs, struct named_merge_point *named_merge_points,
enum lface_attribute_index attr_filter)
{
bool ok = true; /* Succeed without an error? */
Lisp_Object filtered_face_ref;
......@@ -2514,7 +2528,8 @@ merge_face_ref (struct window *w,
/* This is not really very useful; it's just like a
normal face reference. */
if (! merge_face_ref (w, f, value, to,
err_msgs, named_merge_points))
err_msgs, named_merge_points,
0))
err = true;
}
else if (EQ (keyword, QCextend))
......@@ -2544,16 +2559,19 @@ merge_face_ref (struct window *w,
Lisp_Object next = XCDR (face_ref);
if (! NILP (next))
ok = merge_face_ref (w, f, next, to, err_msgs, named_merge_points);
ok = merge_face_ref (w, f, next, to, err_msgs,
named_merge_points, 0);
if (! merge_face_ref (w, f, first, to, err_msgs, named_merge_points))
if (! merge_face_ref (w, f, first, to, err_msgs,
named_merge_points, 0))
ok = false;
}
}
else
{
/* FACE_REF ought to be a face name. */
ok = merge_named_face (w, f, face_ref, to, named_merge_points);
ok = merge_named_face (w, f, face_ref, to, named_merge_points,
attr_filter);
if (!ok && err_msgs)
add_to_log ("Invalid face reference: %s", face_ref);
}
......@@ -4534,7 +4552,8 @@ lookup_face (struct frame *f, Lisp_Object *attr)
suitable face is found, realize a new one. */
int
face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face)
face_for_font (struct frame *f, Lisp_Object font_object,
struct face *base_face)
{
struct face_cache *cache = FRAME_FACE_CACHE (f);
unsigned hash;
......@@ -4769,7 +4788,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
Lisp_Object lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified);
merge_face_ref (NULL, XFRAME (selected_frame),
plist, XVECTOR (lface)->contents,
true, 0);
true, NULL, 0);
return lface;
}
......@@ -5126,7 +5145,7 @@ face for italic. */)
for (i = 0; i < LFACE_VECTOR_SIZE; i++)
attrs[i] = Qunspecified;
merge_face_ref (NULL, f, attributes, attrs, true, 0);
merge_face_ref (NULL, f, attributes, attrs, true, NULL, 0);
def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID);
if (def_face == NULL)
......@@ -6012,7 +6031,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
Lisp_Object attrs[LFACE_VECTOR_SIZE];
struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
memcpy (attrs, default_face->lface, sizeof attrs);
merge_face_ref (NULL, f, prop, attrs, true, 0);
merge_face_ref (NULL, f, prop, attrs, true, NULL, 0);
face_id = lookup_face (f, attrs);
}
......@@ -6024,6 +6043,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
which a different face is needed, as far as text properties and
overlays are concerned. W is a window displaying current_buffer.
attr_filter is passed merge_face_ref.
REGION_BEG, REGION_END delimit the region, so it can be
highlighted.
......@@ -6043,7 +6064,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop)
int
face_at_buffer_position (struct window *w, ptrdiff_t pos,
ptrdiff_t *endptr, ptrdiff_t limit,
bool mouse, int base_face_id)
bool mouse, int base_face_id,
enum lface_attribute_index attr_filter)
{
struct frame *f = XFRAME (w->frame);
Lisp_Object attrs[LFACE_VECTOR_SIZE];
......@@ -6104,8 +6126,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
}
/* Optimize common cases where we can use the default face. */
if (noverlays == 0
&& NILP (prop))
if (noverlays == 0 && NILP (prop))
{
SAFE_FREE ();
return default_face->id;
......@@ -6116,7 +6137,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
/* Merge in attributes specified via text properties. */
if (!NILP (prop))
merge_face_ref (w, f, prop, attrs, true, 0);
merge_face_ref (w, f, prop, attrs, true, NULL, 0);
/* Now merge the overlay data. */
noverlays = sort_overlays (overlay_vec, noverlays, w);
......@@ -6136,7 +6157,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
so discard the mouse-face text property, if any, and
use the overlay property instead. */
memcpy (attrs, default_face->lface, sizeof attrs);
merge_face_ref (w, f, prop, attrs, true, 0);
merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
}
oend = OVERLAY_END (overlay_vec[i]);
......@@ -6153,8 +6174,9 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
ptrdiff_t oendpos;
prop = Foverlay_get (overlay_vec[i], propname);
if (!NILP (prop))
merge_face_ref (w, f, prop, attrs, true, 0);
merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter);
oend = OVERLAY_END (overlay_vec[i]);
oendpos = OVERLAY_POSITION (oend);
......@@ -6220,7 +6242,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
/* Merge in attributes specified via text properties. */
if (!NILP (prop))
merge_face_ref (w, f, prop, attrs, true, 0);
merge_face_ref (w, f, prop, attrs, true, NULL, 0);
*endptr = endpos;
......@@ -6255,7 +6277,7 @@ int
face_at_string_position (struct window *w, Lisp_Object string,
ptrdiff_t pos, ptrdiff_t bufpos,
ptrdiff_t *endptr, enum face_id base_face_id,
bool mouse_p)
bool mouse_p)
{
Lisp_Object prop, position, end, limit;
struct frame *f = XFRAME (WINDOW_FRAME (w));
......@@ -6299,7 +6321,7 @@ face_at_string_position (struct window *w, Lisp_Object string,
/* Merge in attributes specified via text properties. */
if (!NILP (prop))
merge_face_ref (w, f, prop, attrs, true, 0);
merge_face_ref (w, f, prop, attrs, true, NULL, 0);
/* Look up a realized face with the given face attributes,
or realize a new one for ASCII characters. */
......@@ -6349,7 +6371,7 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id,
if (!NILP (face_name))
{
if (!merge_named_face (w, f, face_name, attrs, 0))
if (!merge_named_face (w, f, face_name, attrs, NULL, 0))
return base_face_id;
}
else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment