Commit 4843aac3 authored by Alp Aker's avatar Alp Aker Committed by Chong Yidong
Browse files

Implement strike-through and overline on NextStep (Bug#8863).

* src/nsfont.m (nsfont_open): Use underline position provided by font,
instead of hard-coded value of 2.
(nsfont_draw): Call ns_draw_text_decoration instead.

* src/nsterm.h: Add declaration for ns_draw_text_decoration.

* src/nsterm.m (ns_draw_text_decoration): New function for drawing
underline, overline, and strike-through.
(ns_dumpglyphs_image, ns_dumpglyphs_stretch): Add call to
ns_draw_text_decoration.  Change treatment of cursor drawing to
accomodate underlining, etc.
parent bc7ece87
2011-07-26 Alp Aker <alp.tekin.aker@gmail.com>
Implement strike-through and overline on NextStep (Bug#8863).
* nsfont.m (nsfont_open): Use underline position provided by font,
instead of hard-coded value of 2.
(nsfont_draw): Call ns_draw_text_decoration instead.
* nsterm.h: Add declaration for ns_draw_text_decoration.
* nsterm.m (ns_draw_text_decoration): New function for drawing
underline, overline, and strike-through.
(ns_dumpglyphs_image, ns_dumpglyphs_stretch): Add call to
ns_draw_text_decoration. Change treatment of cursor drawing to
accomodate underlining, etc.
2011-07-28 Eli Zaretskii <eliz@gnu.org>
* buffer.c (init_buffer_once): Set bidi-display-reordering to t by
......
......@@ -845,7 +845,7 @@ when setting family in ns_spec_to_descriptor(). */
expand = 0.0;
hshrink = 1.0;
font_info->underpos = 2; /*[sfont underlinePosition] is often clipped out */
font_info->underpos = [sfont underlinePosition];
font_info->underwidth = [sfont underlineThickness];
font_info->size = font->pixel_size;
font_info->voffset = lrint (hshrink * [sfont ascender] + expand * hd / 2);
......@@ -1196,20 +1196,7 @@ WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars). */
/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */
}
/* do underline */
if (face->underline_p)
{
if (face->underline_color != 0)
[ns_lookup_indexed_color (face->underline_color, s->f) set];
else
[col set];
DPSmoveto (context, r.origin.x, r.origin.y + font->underpos);
DPSlineto (context, r.origin.x+r.size.width, r.origin.y+font->underpos);
if (face->underline_color != 0)
[col set];
}
else
[col set];
[col set];
/* draw with DPSxshow () */
DPSmoveto (context, r.origin.x, r.origin.y);
......@@ -1255,23 +1242,7 @@ WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars). */
CGContextSetTextDrawingMode (gcontext, kCGTextFill);
}
if (face->underline_p)
{
if (face->underline_color != 0)
[ns_lookup_indexed_color (face->underline_color, s->f) set];
else
[col set];
CGContextBeginPath (gcontext);
CGContextMoveToPoint (gcontext,
r.origin.x, r.origin.y + font->underpos);
CGContextAddLineToPoint (gcontext, r.origin.x + r.size.width,
r.origin.y + font->underpos);
CGContextStrokePath (gcontext);
if (face->underline_color != 0)
[col set];
}
else
[col set];
[col set];
CGContextSetTextPosition (gcontext, r.origin.x, r.origin.y);
CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->cmp_from,
......@@ -1287,6 +1258,10 @@ WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars). */
CGContextRestoreGState (gcontext);
}
#endif /* NS_IMPL_COCOA */
/* Draw underline, overline, strike-through. */
ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x);
return to-from;
}
......
......@@ -825,6 +825,13 @@ extern unsigned long ns_get_rgb_color (struct frame *f,
float r, float g, float b, float a);
extern NSPoint last_mouse_motion_position;
/* From nsterm.m, needed in nsfont.m. */
#ifdef __OBJC__
extern void
ns_draw_text_decoration (struct glyph_string *s, struct face *face,
NSColor *defaultCol, CGFloat width, CGFloat x);
#endif
#ifdef NS_IMPL_GNUSTEP
extern char gnustep_base_version[]; /* version tracking */
#endif
......
......@@ -263,8 +263,6 @@ Updated by Christian Limpach (chris@nice.ch)
static void ns_judge_scroll_bars (struct frame *f);
void x_set_frame_alpha (struct frame *f);
/* FIXME: figure out what to do with underline_minimum_offset. */
/* ==========================================================================
......@@ -2597,6 +2595,107 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
return n;
}
void
ns_draw_text_decoration (struct glyph_string *s, struct face *face,
NSColor *defaultCol, CGFloat width, CGFloat x)
/* --------------------------------------------------------------------------
Draw underline, overline, and strike-through on glyph string s.
-------------------------------------------------------------------------- */
{
if (s->for_overlaps)
return;
/* Do underline. */
if (face->underline_p)
{
NSRect r;
unsigned long thickness, position;
/* If the prev was underlined, match its appearance. */
if (s->prev && s->prev->face->underline_p
&& s->prev->underline_thickness > 0)
{
thickness = s->prev->underline_thickness;
position = s->prev->underline_position;
}
else
{
struct font *font;
unsigned long descent;
font=s->font;
descent = s->y + s->height - s->ybase;
/* Use underline thickness of font, defaulting to 1. */
thickness = (font && font->underline_thickness > 0)
? font->underline_thickness : 1;
/* Determine the offset of underlining from the baseline. */
if (x_underline_at_descent_line)
position = descent - thickness;
else if (x_use_underline_position_properties
&& font && font->underline_position >= 0)
position = font->underline_position;
else if (font)
position = lround (font->descent / 2);
else
position = underline_minimum_offset;
position = max (position, underline_minimum_offset);
/* Ensure underlining is not cropped. */
if (descent <= position)
{
position = descent - 1;
thickness = 1;
}
else if (descent < position + thickness)
thickness = 1;
}
s->underline_thickness = thickness;
s->underline_position = position;
r = NSMakeRect (x, s->ybase + position, width, thickness);
if (face->underline_defaulted_p)
[defaultCol set];
else
[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)
{
NSRect r;
r = NSMakeRect (x, s->y, width, 1);
if (face->overline_color_defaulted_p)
[defaultCol set];
else
[ns_lookup_indexed_color (face->overline_color, s->f) set];
NSRectFill (r);
}
/* Do strike-through. We follow other terms for thickness and
vertical position.*/
if (face->strike_through_p)
{
NSRect r;
unsigned long dy;
dy = lrint ((s->height - 1) / 2);
r = NSMakeRect (x, s->y + dy, width, 1);
if (face->strike_through_color_defaulted_p)
[defaultCol set];
else
[ns_lookup_indexed_color (face->strike_through_color, s->f) set];
NSRectFill (r);
}
}
static void
ns_draw_box (NSRect r, float thickness, NSColor *col, char left_p, char right_p)
......@@ -2854,6 +2953,7 @@ Function modeled after x_draw_glyph_string_box ().
char raised_p;
NSRect br;
struct face *face;
NSColor *tdCol;
NSTRACE (ns_dumpglyphs_image);
......@@ -2882,10 +2982,7 @@ Function modeled after x_draw_glyph_string_box ().
else
face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
if (s->hl == DRAW_CURSOR)
[FRAME_CURSOR_COLOR (s->f) set];
else
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
|| s->img->mask || s->img->pixmap == 0 || s->width != s->background_width)
......@@ -2923,6 +3020,27 @@ Function modeled after x_draw_glyph_string_box ().
[img compositeToPoint: NSMakePoint (x, y + s->slice.height)
operation: NSCompositeSourceOver];
if (s->hl == DRAW_CURSOR)
{
[FRAME_CURSOR_COLOR (s->f) set];
if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
tdCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
else
/* Currently on NS img->mask is always 0. Since
get_window_cursor_type specifies a hollow box cursor when on
a non-masked image we never reach this clause. But we put it
in in antipication of better support for image masks on
NS. */
tdCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
}
else
{
tdCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
}
/* Draw underline, overline, strike-through. */
ns_draw_text_decoration (s, face, tdCol, br.size.width, br.origin.x);
/* Draw relief, if requested */
if (s->img->relief || s->hl ==DRAW_IMAGE_RAISED || s->hl ==DRAW_IMAGE_SUNKEN)
{
......@@ -2967,12 +3085,27 @@ Function modeled after x_draw_glyph_string_box ().
NSRect r[2];
int n, i;
struct face *face;
NSColor *fgCol, *bgCol;
if (!s->background_filled_p)
{
n = ns_get_glyph_string_clip_rect (s, r);
*r = NSMakeRect (s->x, s->y, s->background_width, s->height);
ns_focus (s->f, r, n);
if (s->hl == DRAW_MOUSE_FACE)
{
face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
if (!face)
face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
}
else
face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
for (i=0; i<n; i++)
{
if (!s->row->full_width_p)
......@@ -2998,30 +3131,37 @@ Function modeled after x_draw_glyph_string_box ().
FRAME_PIXEL_WIDTH (s->f));
}
[bgCol set];
/* NOTE: under NS this is NOT used to draw cursors, but we must avoid
overwriting cursor (usually when cursor on a tab) */
if (s->hl == DRAW_CURSOR)
{
r[i].origin.x += s->width;
r[i].size.width -= s->width;
}
}
CGFloat x, width;
ns_focus (s->f, r, n);
x = r[i].origin.x;
width = s->w->phys_cursor_width;
r[i].size.width -= width;
r[i].origin.x += width;
if (s->hl == DRAW_MOUSE_FACE)
{
face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
if (!face)
face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
}
else
face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
NSRectFill (r[i]);
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
/* Draw overlining, etc. on the cursor. */
if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
ns_draw_text_decoration (s, face, bgCol, width, x);
else
ns_draw_text_decoration (s, face, fgCol, width, x);
}
else
{
NSRectFill (r[i]);
}
NSRectFill (r[0]);
NSRectFill (r[1]);
/* Draw overlining, etc. on the stretch glyph (or the part
of the stretch glyph after the cursor). */
ns_draw_text_decoration (s, face, fgCol, r[i].size.width,
r[i].origin.x);
}
ns_unfocus (s->f);
s->background_filled_p = 1;
}
......@@ -6556,23 +6696,17 @@ Convert an X font name (XLFD) to an NS font name.
Vx_toolkit_scroll_bars = Qnil;
#endif
/* these are unsupported but we need the declarations to avoid whining
messages from cus-start.el */
DEFVAR_BOOL ("x-use-underline-position-properties",
x_use_underline_position_properties,
doc: /* NOT SUPPORTED UNDER NS.
*Non-nil means make use of UNDERLINE_POSITION font properties.
doc: /*Non-nil means make use of UNDERLINE_POSITION font properties.
A value of nil means ignore them. If you encounter fonts with bogus
UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
to 4.1, set this to nil.
NOTE: Not supported on Mac yet. */);
to 4.1, set this to nil. */);
x_use_underline_position_properties = 0;
DEFVAR_BOOL ("x-underline-at-descent-line",
x_underline_at_descent_line,
doc: /* NOT SUPPORTED UNDER NS.
*Non-nil means to draw the underline at the same place as the descent line.
doc: /* Non-nil means to draw the underline at the same place as the descent line.
A value of nil means to draw the underline according to the value of the
variable `x-use-underline-position-properties', which is usually at the
baseline level. The default value is nil. */);
......
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