mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
Implement wave-style variant of underlining.
* doc/lispref/display.texi: Document new face attribute. * lisp/cus-face.el (custom-face-attributes): Add wave-style underline attribute. * lisp/faces.el (set-face-attribute): Update docstring. * src/dispextern.h (face_underline_type): New enum. (face): Add field for underline type. * src/nsterm.m (ns_draw_underwave): New function. (ns_draw_text_decoration): Use it. * src/w32term.c (w32_restore_glyph_string_clip, w32_draw_underwave): New functions. (x_draw_glyph_string): Use them. * src/xfaces.c (Qline, Qwave): New Lisp objects. (check_lface_attrs, merge_face_ref) (Finternal_set_lisp_face_attribute, realize_x_face): Handle wave-style underline face attributes. * src/xterm.c (x_draw_underwave): New function. (x_draw_glyph_string): Use it.
This commit is contained in:
parent
40d8bcb854
commit
9b0e3ebaef
11 changed files with 590 additions and 180 deletions
|
|
@ -1,3 +1,8 @@
|
|||
2012-06-16 Aurelien Aptel <aurelien.aptel@gmail.com>
|
||||
|
||||
* doc/lispref/display.texi: Document wave-style underline
|
||||
face attribute.
|
||||
|
||||
2012-06-13 Andreas Schwab <schwab@linux-m68k.org>
|
||||
|
||||
* configure.in: Rename --enable-use-lisp-union-type to
|
||||
|
|
|
|||
|
|
@ -2130,10 +2130,32 @@ Background color, a string. The value can be a system-defined color
|
|||
name, or a hexadecimal color specification. @xref{Color Names}.
|
||||
|
||||
@item :underline
|
||||
Whether or not characters should be underlined, and in what color. If
|
||||
the value is @code{t}, underlining uses the foreground color of the
|
||||
face. If the value is a string, underlining uses that color. The
|
||||
value @code{nil} means do not underline.
|
||||
Whether or not characters should be underlined, and in what
|
||||
color. Here are the possible values of the @code{:underline}
|
||||
attribute, and what they mean:
|
||||
|
||||
@table @asis
|
||||
@item @code{nil}
|
||||
Don't underline.
|
||||
|
||||
@item @code{t}
|
||||
Underline with the foreground color of the face.
|
||||
|
||||
@item @var{color}
|
||||
Underline in color @var{color}.
|
||||
|
||||
@item @code{(:color @var{color} :style @var{style})}
|
||||
If @var{color} is a string, underline in it.
|
||||
If @var{color} is @code{foreground-color}, underline with the
|
||||
foreground color of the face.
|
||||
|
||||
If @var{style} is @code{wave} underline with a wave.
|
||||
If @var{style} is @code{line} underline with a line.
|
||||
|
||||
If the attribute @code{:color} is omited, underline with the
|
||||
foreground color of the face.
|
||||
If the attribute @code{:style} is omited, underline with a line.
|
||||
@end table
|
||||
|
||||
@item :overline
|
||||
Whether or not characters should be overlined, and in what color.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
2012-06-16 Aurelien Aptel <aurelien.aptel@gmail.com>
|
||||
|
||||
* cus-face.el (custom-face-attributes): Add wave-style underline
|
||||
attribute.
|
||||
* faces.el (set-face-attribute): Update docstring to describe
|
||||
wave-style underline attribute.
|
||||
|
||||
2012-06-16 Chong Yidong <cyd@gnu.org>
|
||||
|
||||
* term/xterm.el (terminal-init-xterm): Discard input before
|
||||
|
|
|
|||
|
|
@ -135,8 +135,13 @@
|
|||
(choice :tag "Underline"
|
||||
:help-echo "Control text underlining."
|
||||
(const :tag "Off" nil)
|
||||
(const :tag "On" t)
|
||||
(color :tag "Colored")))
|
||||
(list :tag "On"
|
||||
(const :format "" :value :color)
|
||||
(choice :tag "Color" (const :tag "Foreground Color" foreground-color) color)
|
||||
(const :format "" :value :style)
|
||||
(choice :tag "Style"
|
||||
(const :tag "Line" line)
|
||||
(const :tag "Wave" wave)))))
|
||||
|
||||
(:overline
|
||||
(choice :tag "Overline"
|
||||
|
|
|
|||
|
|
@ -623,10 +623,21 @@ VALUE must be a color name, a string.
|
|||
|
||||
`:underline'
|
||||
|
||||
VALUE specifies whether characters in FACE should be underlined. If
|
||||
VALUE is t, underline with foreground color of the face. If VALUE is
|
||||
a string, underline with that color. If VALUE is nil, explicitly
|
||||
don't underline.
|
||||
VALUE specifies whether characters in FACE should be underlined.
|
||||
If VALUE is t, underline with foreground color of the face.
|
||||
If VALUE is a string, underline with that color.
|
||||
If VALUE is nil, explicitly don't underline.
|
||||
|
||||
Otherwise, VALUE must be a property list of the form:
|
||||
|
||||
`(:color COLOR :style STYLE)'.
|
||||
|
||||
COLOR can be a either a color name string or `foreground-color'.
|
||||
STYLE can be either `line' or `wave'.
|
||||
If a keyword/value pair is missing from the property list, a
|
||||
default value will be used for the value.
|
||||
The default value of COLOR is the foreground color of the face.
|
||||
The default value of STYLE is `line'.
|
||||
|
||||
`:overline'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
2012-06-16 Aurelien Aptel <aurelien.aptel@gmail.com>
|
||||
|
||||
Implement wave-style variant of underlining.
|
||||
* dispextern.h (face_underline_type): New enum.
|
||||
(face): Add field for underline type.
|
||||
* nsterm.m (ns_draw_underwave): New function.
|
||||
(ns_draw_text_decoration): Use it.
|
||||
* w32term.c (w32_restore_glyph_string_clip, w32_draw_underwave):
|
||||
New functions.
|
||||
(x_draw_glyph_string): Use them.
|
||||
* xfaces.c (Qline, Qwave): New Lisp objects.
|
||||
(check_lface_attrs, merge_face_ref)
|
||||
(Finternal_set_lisp_face_attribute, realize_x_face): Handle
|
||||
wave-style underline face attributes.
|
||||
* xterm.c (x_draw_underwave): New function.
|
||||
(x_draw_glyph_string): Use it.
|
||||
|
||||
2012-06-16 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* makefile.w32-in ($(BLD)/emacs.$(O), $(BLD)/fringe.$(O))
|
||||
|
|
|
|||
|
|
@ -1510,6 +1510,13 @@ enum face_box_type
|
|||
FACE_SUNKEN_BOX
|
||||
};
|
||||
|
||||
/* Underline type. */
|
||||
|
||||
enum face_underline_type
|
||||
{
|
||||
FACE_UNDER_LINE,
|
||||
FACE_UNDER_WAVE
|
||||
};
|
||||
|
||||
/* Structure describing a realized face.
|
||||
|
||||
|
|
@ -1585,6 +1592,9 @@ struct face
|
|||
drawing shadows. */
|
||||
unsigned use_box_color_for_shadows_p : 1;
|
||||
|
||||
/* Style of underlining. */
|
||||
enum face_underline_type underline_type;
|
||||
|
||||
/* Non-zero if text in this face should be underlined, overlined,
|
||||
strike-through or have a box drawn around it. */
|
||||
unsigned underline_p : 1;
|
||||
|
|
|
|||
68
src/nsterm.m
68
src/nsterm.m
|
|
@ -2595,6 +2595,60 @@ ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
|
|||
return n;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
Draw a wavy line under glyph string s. The wave fills wave_height
|
||||
pixels from y.
|
||||
|
||||
x wave_length = 3
|
||||
--
|
||||
y * * * * *
|
||||
|* * * * * * * * *
|
||||
wave_height = 3 | * * * *
|
||||
--------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x)
|
||||
{
|
||||
int wave_height = 3, wave_length = 3;
|
||||
int y, dx, dy, odd, xmax;
|
||||
NSPoint a, b;
|
||||
NSRect waveClip;
|
||||
|
||||
dx = wave_length;
|
||||
dy = wave_height - 1;
|
||||
y = s->ybase + 1;
|
||||
xmax = x + width;
|
||||
|
||||
/* Find and set clipping rectangle */
|
||||
waveClip = NSMakeRect (x, y, width, wave_height);
|
||||
[[NSGraphicsContext currentContext] saveGraphicsState];
|
||||
NSRectClip (waveClip);
|
||||
|
||||
/* Draw the waves */
|
||||
a.x = x - ((int)(x) % dx);
|
||||
b.x = a.x + dx;
|
||||
odd = (int)(a.x/dx) % 2;
|
||||
a.y = b.y = y;
|
||||
|
||||
if (odd)
|
||||
a.y += dy;
|
||||
else
|
||||
b.y += dy;
|
||||
|
||||
while (a.x <= xmax)
|
||||
{
|
||||
[NSBezierPath strokeLineFromPoint:a toPoint:b];
|
||||
a.x = b.x, a.y = b.y;
|
||||
b.x += dx, b.y = y + odd*dy;
|
||||
odd = !odd;
|
||||
}
|
||||
|
||||
/* Restore previous clipping rectangle(s) */
|
||||
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ns_draw_text_decoration (struct glyph_string *s, struct face *face,
|
||||
NSColor *defaultCol, CGFloat width, CGFloat x)
|
||||
|
|
@ -2608,6 +2662,18 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
|
|||
/* Do underline. */
|
||||
if (face->underline_p)
|
||||
{
|
||||
if (s->face->underline_type == FACE_UNDER_WAVE)
|
||||
{
|
||||
if (face->underline_defaulted_p)
|
||||
[defaultCol set];
|
||||
else
|
||||
[ns_lookup_indexed_color (face->underline_color, s->f) set];
|
||||
|
||||
ns_draw_underwave (s, width, x);
|
||||
}
|
||||
else if (s->face->underline_type == FACE_UNDER_LINE)
|
||||
{
|
||||
|
||||
NSRect r;
|
||||
unsigned long thickness, position;
|
||||
|
||||
|
|
@ -2664,7 +2730,7 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
|
|||
[ns_lookup_indexed_color (face->underline_color, s->f) set];
|
||||
NSRectFill (r);
|
||||
}
|
||||
|
||||
}
|
||||
/* Do overline. We follow other terms in using a thickness of 1
|
||||
and ignoring overline_margin. */
|
||||
if (face->overline_p)
|
||||
|
|
|
|||
102
src/w32term.c
102
src/w32term.c
|
|
@ -313,6 +313,94 @@ w32_set_clip_rectangle (HDC hdc, RECT *rect)
|
|||
SelectClipRgn (hdc, NULL);
|
||||
}
|
||||
|
||||
/* Restore clipping rectangle in S */
|
||||
static void
|
||||
w32_restore_glyph_string_clip (struct glyph_string *s)
|
||||
{
|
||||
RECT *r = s->clip;
|
||||
int n = s->num_clips;
|
||||
|
||||
if (n == 1)
|
||||
w32_set_clip_rectangle (s->hdc, r);
|
||||
else if (n > 1)
|
||||
{
|
||||
HRGN clip1 = CreateRectRgnIndirect (r);
|
||||
HRGN clip2 = CreateRectRgnIndirect (r + 1);
|
||||
if (CombineRgn (clip1, clip1, clip2, RGN_OR) != ERROR)
|
||||
SelectClipRgn (s->hdc, clip1);
|
||||
DeleteObject (clip1);
|
||||
DeleteObject (clip2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Draw a wavy line under S. The wave fills wave_height pixels from y0.
|
||||
|
||||
x0 wave_length = 2
|
||||
--
|
||||
y0 * * * * *
|
||||
|* * * * * * * * *
|
||||
wave_height = 3 | * * * *
|
||||
|
||||
*/
|
||||
|
||||
void
|
||||
w32_draw_underwave (struct glyph_string *s, COLORREF color)
|
||||
{
|
||||
int wave_height = 2, wave_length = 3;
|
||||
int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
|
||||
XRectangle wave_clip, string_clip, final_clip;
|
||||
RECT w32_final_clip, w32_string_clip;
|
||||
HPEN hp, oldhp;
|
||||
|
||||
dx = wave_length;
|
||||
dy = wave_height - 1;
|
||||
x0 = s->x;
|
||||
y0 = s->ybase + 1;
|
||||
width = s->width;
|
||||
xmax = x0 + width;
|
||||
|
||||
/* Find and set clipping rectangle */
|
||||
|
||||
wave_clip = (XRectangle){ x0, y0, width, wave_height };
|
||||
get_glyph_string_clip_rect (s, &w32_string_clip);
|
||||
CONVERT_TO_XRECT (string_clip, w32_string_clip);
|
||||
|
||||
if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
|
||||
return;
|
||||
|
||||
hp = CreatePen (PS_SOLID, 0, color);
|
||||
oldhp = SelectObject (s->hdc, hp);
|
||||
CONVERT_FROM_XRECT (final_clip, w32_final_clip);
|
||||
w32_set_clip_rectangle (s->hdc, &w32_final_clip);
|
||||
|
||||
/* Draw the waves */
|
||||
|
||||
x1 = x0 - (x0 % dx);
|
||||
x2 = x1 + dx;
|
||||
odd = (x1/dx) % 2;
|
||||
y1 = y2 = y0;
|
||||
|
||||
if (odd)
|
||||
y1 += dy;
|
||||
else
|
||||
y2 += dy;
|
||||
|
||||
MoveToEx (s->hdc, x1, y1, NULL);
|
||||
|
||||
while (x1 <= xmax)
|
||||
{
|
||||
LineTo (s->hdc, x2, y2);
|
||||
x1 = x2, y1 = y2;
|
||||
x2 += dx, y2 = y0 + odd*dy;
|
||||
odd = !odd;
|
||||
}
|
||||
|
||||
/* Restore previous pen and clipping rectangle(s) */
|
||||
w32_restore_glyph_string_clip (s);
|
||||
SelectObject (s->hdc, oldhp);
|
||||
DeleteObject (hp);
|
||||
}
|
||||
|
||||
/* Draw a hollow rectangle at the specified position. */
|
||||
void
|
||||
|
|
@ -2346,6 +2434,19 @@ x_draw_glyph_string (struct glyph_string *s)
|
|||
{
|
||||
/* Draw underline. */
|
||||
if (s->face->underline_p)
|
||||
{
|
||||
if (s->face->underline_type == FACE_UNDER_WAVE)
|
||||
{
|
||||
COLORREF color;
|
||||
|
||||
if (s->face->underline_defaulted_p)
|
||||
color = s->gc->foreground;
|
||||
else
|
||||
color = s->face->underline_color;
|
||||
|
||||
w32_draw_underwave (s, color);
|
||||
}
|
||||
else if (s->face->underline_type == FACE_UNDER_LINE)
|
||||
{
|
||||
unsigned long thickness, position;
|
||||
int y;
|
||||
|
|
@ -2403,6 +2504,7 @@ x_draw_glyph_string (struct glyph_string *s)
|
|||
y, s->width, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Draw overline. */
|
||||
if (s->face->overline_p)
|
||||
{
|
||||
|
|
|
|||
119
src/xfaces.c
119
src/xfaces.c
|
|
@ -320,6 +320,7 @@ static Lisp_Object QCfontset;
|
|||
|
||||
Lisp_Object Qnormal;
|
||||
Lisp_Object Qbold;
|
||||
static Lisp_Object Qline, Qwave;
|
||||
static Lisp_Object Qultra_light, Qextra_light, Qlight;
|
||||
static Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
|
||||
static Lisp_Object Qoblique, Qreverse_oblique, Qreverse_italic;
|
||||
|
|
@ -1894,7 +1895,8 @@ check_lface_attrs (Lisp_Object *attrs)
|
|||
xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
|
||||
|| IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
|
||||
|| SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
|
||||
|| STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
|
||||
|| STRINGP (attrs[LFACE_UNDERLINE_INDEX])
|
||||
|| CONSP (attrs[LFACE_UNDERLINE_INDEX]));
|
||||
xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
|
||||
|| IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
|
||||
|| SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
|
||||
|
|
@ -2525,7 +2527,8 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
|
|||
{
|
||||
if (EQ (value, Qt)
|
||||
|| NILP (value)
|
||||
|| STRINGP (value))
|
||||
|| STRINGP (value)
|
||||
|| CONSP (value))
|
||||
to[LFACE_UNDERLINE_INDEX] = value;
|
||||
else
|
||||
err = 1;
|
||||
|
|
@ -2948,13 +2951,52 @@ FRAME 0 means change the face on all frames, and change the default
|
|||
}
|
||||
else if (EQ (attr, QCunderline))
|
||||
{
|
||||
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
|
||||
if ((SYMBOLP (value)
|
||||
&& !EQ (value, Qt)
|
||||
&& !EQ (value, Qnil))
|
||||
/* Underline color. */
|
||||
|| (STRINGP (value)
|
||||
&& SCHARS (value) == 0))
|
||||
int valid_p = 0;
|
||||
|
||||
if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
|
||||
valid_p = 1;
|
||||
else if (NILP (value) || EQ (value, Qt))
|
||||
valid_p = 1;
|
||||
else if (STRINGP (value) && SCHARS (value) > 0)
|
||||
valid_p = 1;
|
||||
else if (CONSP (value))
|
||||
{
|
||||
Lisp_Object key, val, list;
|
||||
|
||||
list = value;
|
||||
valid_p = 1;
|
||||
|
||||
while (!NILP (CAR_SAFE(list)))
|
||||
{
|
||||
key = CAR_SAFE (list);
|
||||
list = CDR_SAFE (list);
|
||||
val = CAR_SAFE (list);
|
||||
list = CDR_SAFE (list);
|
||||
|
||||
if(NILP (key) || NILP (val))
|
||||
{
|
||||
valid_p = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
else if (EQ (key, QCcolor)
|
||||
&& !(EQ (val, Qforeground_color)
|
||||
|| (STRINGP (val) && SCHARS (val) > 0)))
|
||||
{
|
||||
valid_p = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
else if (EQ (key, QCstyle)
|
||||
&& !(EQ (val, Qline) || EQ (val, Qwave)))
|
||||
{
|
||||
valid_p = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid_p)
|
||||
signal_error ("Invalid face underline", value);
|
||||
|
||||
old_value = LFACE_UNDERLINE (lface);
|
||||
|
|
@ -5576,7 +5618,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
|
|||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
struct face *default_face;
|
||||
struct frame *f;
|
||||
Lisp_Object stipple, overline, strike_through, box;
|
||||
Lisp_Object stipple, underline, overline, strike_through, box;
|
||||
|
||||
xassert (FRAME_WINDOW_P (cache->f));
|
||||
|
||||
|
|
@ -5709,28 +5751,75 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
|
|||
|
||||
/* Text underline, overline, strike-through. */
|
||||
|
||||
if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt))
|
||||
underline = attrs[LFACE_UNDERLINE_INDEX];
|
||||
if (EQ (underline, Qt))
|
||||
{
|
||||
/* Use default color (same as foreground color). */
|
||||
face->underline_p = 1;
|
||||
face->underline_type = FACE_UNDER_LINE;
|
||||
face->underline_defaulted_p = 1;
|
||||
face->underline_color = 0;
|
||||
}
|
||||
else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX]))
|
||||
else if (STRINGP (underline))
|
||||
{
|
||||
/* Use specified color. */
|
||||
face->underline_p = 1;
|
||||
face->underline_type = FACE_UNDER_LINE;
|
||||
face->underline_defaulted_p = 0;
|
||||
face->underline_color
|
||||
= load_color (f, face, attrs[LFACE_UNDERLINE_INDEX],
|
||||
= load_color (f, face, underline,
|
||||
LFACE_UNDERLINE_INDEX);
|
||||
}
|
||||
else if (NILP (attrs[LFACE_UNDERLINE_INDEX]))
|
||||
else if (NILP (underline))
|
||||
{
|
||||
face->underline_p = 0;
|
||||
face->underline_defaulted_p = 0;
|
||||
face->underline_color = 0;
|
||||
}
|
||||
else if (CONSP (underline))
|
||||
{
|
||||
/* `(:color COLOR :style STYLE)'.
|
||||
STYLE being one of `line' or `wave'. */
|
||||
face->underline_p = 1;
|
||||
face->underline_color = 0;
|
||||
face->underline_defaulted_p = 1;
|
||||
face->underline_type = FACE_UNDER_LINE;
|
||||
|
||||
while (CONSP (underline))
|
||||
{
|
||||
Lisp_Object keyword, value;
|
||||
|
||||
keyword = XCAR (underline);
|
||||
underline = XCDR (underline);
|
||||
|
||||
if (!CONSP (underline))
|
||||
break;
|
||||
value = XCAR (underline);
|
||||
underline = XCDR (underline);
|
||||
|
||||
if (EQ (keyword, QCcolor))
|
||||
{
|
||||
if (EQ (value, Qforeground_color))
|
||||
{
|
||||
face->underline_defaulted_p = 1;
|
||||
face->underline_color = 0;
|
||||
}
|
||||
else if (STRINGP (value))
|
||||
{
|
||||
face->underline_defaulted_p = 0;
|
||||
face->underline_color = load_color (f, face, value,
|
||||
LFACE_UNDERLINE_INDEX);
|
||||
}
|
||||
}
|
||||
else if (EQ (keyword, QCstyle))
|
||||
{
|
||||
if (EQ (value, Qline))
|
||||
face->underline_type = FACE_UNDER_LINE;
|
||||
else if (EQ (value, Qwave))
|
||||
face->underline_type = FACE_UNDER_WAVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
overline = attrs[LFACE_OVERLINE_INDEX];
|
||||
if (STRINGP (overline))
|
||||
|
|
@ -6476,6 +6565,8 @@ syms_of_xfaces (void)
|
|||
DEFSYM (QCcolor, ":color");
|
||||
DEFSYM (QCline_width, ":line-width");
|
||||
DEFSYM (QCstyle, ":style");
|
||||
DEFSYM (Qline, "line");
|
||||
DEFSYM (Qwave, "wave");
|
||||
DEFSYM (Qreleased_button, "released-button");
|
||||
DEFSYM (Qpressed_button, "pressed-button");
|
||||
DEFSYM (Qnormal, "normal");
|
||||
|
|
|
|||
76
src/xterm.c
76
src/xterm.c
|
|
@ -2663,6 +2663,65 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
|
|||
s->background_filled_p = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Draw a wavy line under S. The wave fills wave_height pixels from y0.
|
||||
|
||||
x0 wave_length = 2
|
||||
--
|
||||
y0 * * * * *
|
||||
|* * * * * * * * *
|
||||
wave_height = 3 | * * * *
|
||||
|
||||
*/
|
||||
|
||||
static void
|
||||
x_draw_underwave (struct glyph_string *s)
|
||||
{
|
||||
int wave_height = 2, wave_length = 3;
|
||||
int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
|
||||
XRectangle wave_clip, string_clip, final_clip;
|
||||
|
||||
dx = wave_length;
|
||||
dy = wave_height - 1;
|
||||
x0 = s->x;
|
||||
y0 = s->ybase + 1;
|
||||
width = s->width;
|
||||
xmax = x0 + width;
|
||||
|
||||
/* Find and set clipping rectangle */
|
||||
|
||||
wave_clip = (XRectangle){ x0, y0, width, wave_height };
|
||||
get_glyph_string_clip_rect (s, &string_clip);
|
||||
|
||||
if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
|
||||
return;
|
||||
|
||||
XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
|
||||
|
||||
/* Draw the waves */
|
||||
|
||||
x1 = x0 - (x0 % dx);
|
||||
x2 = x1 + dx;
|
||||
odd = (x1/dx) % 2;
|
||||
y1 = y2 = y0;
|
||||
|
||||
if (odd)
|
||||
y1 += dy;
|
||||
else
|
||||
y2 += dy;
|
||||
|
||||
while (x1 <= xmax)
|
||||
{
|
||||
XDrawLine (s->display, s->window, s->gc, x1, y1, x2, y2);
|
||||
x1 = x2, y1 = y2;
|
||||
x2 += dx, y2 = y0 + odd*dy;
|
||||
odd = !odd;
|
||||
}
|
||||
|
||||
/* Restore previous clipping rectangle(s) */
|
||||
XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
|
||||
}
|
||||
|
||||
|
||||
/* Draw glyph string S. */
|
||||
|
||||
|
|
@ -2765,6 +2824,21 @@ x_draw_glyph_string (struct glyph_string *s)
|
|||
{
|
||||
/* Draw underline. */
|
||||
if (s->face->underline_p)
|
||||
{
|
||||
if (s->face->underline_type == FACE_UNDER_WAVE)
|
||||
{
|
||||
if (s->face->underline_defaulted_p)
|
||||
x_draw_underwave (s);
|
||||
else
|
||||
{
|
||||
XGCValues xgcv;
|
||||
XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
|
||||
XSetForeground (s->display, s->gc, s->face->underline_color);
|
||||
x_draw_underwave (s);
|
||||
XSetForeground (s->display, s->gc, xgcv.foreground);
|
||||
}
|
||||
}
|
||||
else if (s->face->underline_type == FACE_UNDER_LINE)
|
||||
{
|
||||
unsigned long thickness, position;
|
||||
int y;
|
||||
|
|
@ -2826,7 +2900,7 @@ x_draw_glyph_string (struct glyph_string *s)
|
|||
XSetForeground (s->display, s->gc, xgcv.foreground);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Draw overline. */
|
||||
if (s->face->overline_p)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue