Improve font display on NS port

* src/nsfns.m (Fx_create_frame): Use "fixed" for the default font on
GNUstep.

* src/nsfont.m (LCD_SMOOTHING_MARGIN, ns_escape_name)
(ns_unescape_name, ns_attribute_fvalue)
(STYLE_REF): Remove unused defines and functions.

(struct ns_glyph_layout, enum lgstring_direction).
(enum gs_font_slant, enum gs_font_weight, enum gs_font_width)
(enum gs_specified, struct gs_font_data): New enumerators and
structures.

(ns_font_descs_match_p)
(ns_done_font_data, ns_get_font_data): New functions.
(ns_glyph_metrics): Stop escaping names.

(ns_spec_to_descriptor): Fix font descriptor creation for symbolic
font spec entires.
(ns_descriptor_to_entity): Create entries with the correct symbolic
styles.

(ns_fallback_entity): Fix fallback entity selection.
(ns_findfonts): Use our own font matcher instead of the broken GNUstep
matcher.

(ns_list_family): Remove obsolete comment.
(nsfont_open): Remove obsolete code, comments, and synthItal logic
which doesn't work on GNUstep.

(nsfont_encode_char): Use a type that can fit NSGlyph
(nsfont_draw): Chose correct font, remove obsolete mouse face logic,
obsolete comments, and switch to using glyph-based drawing instead of
character-based drawing.

(ns_font_shape, nsfont_shape): New functions.

(ns_uni_to_glyphs_1): New function.
(ns_uni_to_glyphs): Return glyphs instead of unicode codepoints.

(ns_glyph_metrics): Use NSGlyphs instead of unicode codepoints and fix
left bearing, right bearing, ascent and descent computation.

(struct nsfont_driver): Add shaping capability.

* src/nsterm.h (struct nsfont_info): Use unsigned int for glyph cache.

* src/nsterm.c (ns_focus): Set DPS clipping on GNUstep.

(ns_compute_glyph_string_overhangs): Fix overhang computation by using
xterm code.
(ns_draw_window_cursor): Simplify cursor drawing.
(ns_maybe_dumpglyphs_background): Test for cursor HL and remove
obsolete mouse face logic.
(ns_dumpglyphs_image)
(ns_dumpglyphs_box_or_relief): Rectify for new cursor logic.
(ns_dumpglyphs_stretch): Rectify for new cursor logic and rely on
ns_draw_glyph_string to set focus.
(ns_draw_glyph_string_foreground): Remove mouse face logic.
(ns_draw_glyph_strings): Implement overhangs, remove obsolete
comment, and always focus before dumping glyphs.
(ns_draw_text_decoration): Add condition for DRAW_CURSOR and simplify
color selection.
(ns_define_frame_cursor): Remove nonsensical code (define_frame_cursor
has nothing to do with the text cursor, aka caret).

* src/xdisp.c (draw_glyphs): Enable code for NS port to fix mouse face
cursor display.

* src/macfont.m (get_cgcolor_from_nscolor): New function.
(macfont_draw): Remove obsolete mouse-face code and enable cursor
display.
This commit is contained in:
Po Lu 2021-10-23 19:44:03 +08:00 committed by Alan Third
parent ba278e4a9b
commit 07715630ad
6 changed files with 1091 additions and 586 deletions

View file

@ -613,6 +613,21 @@ static void mac_font_get_glyphs_for_variants (CFDataRef, UTF32Char,
return cgColor;
}
static CGColorRef
get_cgcolor_from_nscolor (NSColor *nsColor, struct frame *f)
{
[nsColor set];
CGColorSpaceRef colorSpace = [[nsColor colorSpace] CGColorSpace];
NSInteger noc = [nsColor numberOfComponents];
CGFloat *components = xmalloc (sizeof(CGFloat)*(1+noc));
CGColorRef cgColor;
[nsColor getComponents: components];
cgColor = CGColorCreate (colorSpace, components);
xfree (components);
return cgColor;
}
#define CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND(context, face, f) \
do { \
CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (face), f); \
@ -2911,14 +2926,14 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
if (!CGRectIsNull (background_rect))
{
if (s->hl == DRAW_MOUSE_FACE)
if (s->hl == DRAW_CURSOR)
{
face = FACE_FROM_ID_OR_NULL (s->f,
MOUSE_HL_INFO (s->f)->mouse_face_face_id);
if (!face)
face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
CGColorRef *colorref = get_cgcolor_from_nscolor (FRAME_CURSOR_COLOR (f), f);
CGContextSetFillColorWithColor (context, colorref);
CGColorRelease (colorref);
}
CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face, f);
else
CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face, f);
CGContextFillRects (context, &background_rect, 1);
}
@ -2927,7 +2942,14 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
CGAffineTransform atfm;
CGContextScaleCTM (context, 1, -1);
CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f);
if (s->hl == DRAW_CURSOR)
{
CGColorRef *colorref = get_cgcolor_from_nscolor (FRAME_BACKGROUND_COLOR (f), f);
CGContextSetFillColorWithColor (context, colorref);
CGColorRelease (colorref);
}
else
CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f);
if (macfont_info->synthetic_italic_p)
atfm = synthetic_italic_atfm;
else

View file

@ -1236,6 +1236,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
"fontBackend", "FontBackend", RES_TYPE_STRING);
{
#ifdef NS_IMPL_COCOA
/* use for default font name */
id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */
gui_default_parameter (f, parms, Qfontsize,
@ -1250,6 +1251,11 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
build_string (fontname),
"font", "Font", RES_TYPE_STRING);
xfree (fontname);
#else
gui_default_parameter (f, parms, Qfont,
build_string ("fixed"),
"font", "Font", RES_TYPE_STRING);
#endif
}
unblock_input ();

File diff suppressed because it is too large Load diff

View file

@ -820,7 +820,7 @@ struct nsfont_info
XCharStruct max_bounds;
/* We compute glyph codes and metrics on-demand in blocks of 256 indexed
by hibyte, lobyte. */
unsigned short **glyphs; /* map Unicode index to glyph */
unsigned int **glyphs; /* map Unicode index to glyph */
struct font_metrics **metrics;
};
#endif

View file

@ -1079,11 +1079,16 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
/* clipping */
if (r)
{
[[NSGraphicsContext currentContext] saveGraphicsState];
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
[ctx saveGraphicsState];
#ifdef NS_IMPL_COCOA
if (n == 2)
NSRectClipList (r, 2);
else
NSRectClip (*r);
#else
GSRectClipList (ctx, r, n);
#endif
gsaved = YES;
}
}
@ -2435,9 +2440,6 @@ Hide the window (X11 semantics)
EmacsView *view = FRAME_NS_VIEW (f);
FRAME_POINTER_TYPE (f) = cursor;
[[view window] invalidateCursorRectsForView: view];
/* Redisplay assumes this function also draws the changed frame
cursor, but this function doesn't, so do it explicitly. */
gui_update_cursor (f, 1);
}
}
@ -2849,39 +2851,31 @@ Hide the window (X11 semantics)
External (RIF); compute left/right overhang of whole string and set in s
-------------------------------------------------------------------------- */
{
struct font *font = s->font;
if (s->char2b)
if (s->cmp == NULL
&& (s->first_glyph->type == CHAR_GLYPH
|| s->first_glyph->type == COMPOSITE_GLYPH))
{
struct font_metrics metrics;
if (s->first_glyph->type == CHAR_GLYPH && !s->font_not_found_p)
{
font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
s->left_overhang = -metrics.lbearing;
s->right_overhang
= metrics.rbearing > metrics.width
? metrics.rbearing - metrics.width : 0;
}
else if (s->first_glyph->type == COMPOSITE_GLYPH)
{
Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
s->right_overhang = (metrics.rbearing > metrics.width
? metrics.rbearing - metrics.width : 0);
s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
}
}
else
{
s->left_overhang = 0;
#ifdef NS_IMPL_GNUSTEP
if (EQ (font->driver->type, Qns))
s->right_overhang = ((struct nsfont_info *)font)->ital ?
FONT_HEIGHT (font) * 0.2 : 0;
if (s->first_glyph->type == CHAR_GLYPH)
{
struct font *font = s->font;
font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
}
else
#endif
s->right_overhang = 0;
{
Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
}
s->right_overhang = (metrics.rbearing > metrics.width
? metrics.rbearing - metrics.width : 0);
s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
}
else if (s->cmp)
{
s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
s->left_overhang = - s->cmp->lbearing;
}
}
@ -3021,14 +3015,13 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
struct frame *f = WINDOW_XFRAME (w);
struct glyph *phys_cursor_glyph;
struct glyph *cursor_glyph;
struct face *face;
NSColor *hollow_color = FRAME_BACKGROUND_COLOR (f);
/* If cursor is out of bounds, don't draw garbage. This can happen
in mini-buffer windows when switching between echo area glyphs
and mini-buffer. */
NSTRACE ("ns_draw_window_cursor");
NSTRACE ("ns_draw_window_cursor (on = %d, cursor_type = %d)",
on_p, cursor_type);
if (!on_p)
return;
@ -3044,6 +3037,8 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
if ((phys_cursor_glyph = get_phys_cursor_glyph (w)) == NULL)
{
NSTRACE_MSG ("No phys cursor glyph was found!");
if (glyph_row->exact_window_width_line_p
&& w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
{
@ -3053,10 +3048,6 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
return;
}
/* We draw the cursor (with NSRectFill), then draw the glyph on top
(other terminals do it the other way round). We must set
w->phys_cursor_width to the cursor width. For bar cursors, that
is CURSOR_WIDTH; for box cursors, it is the glyph width. */
get_phys_cursor_geometry (w, glyph_row, phys_cursor_glyph, &fx, &fy, &h);
/* The above get_phys_cursor_geometry call set w->phys_cursor_width
@ -3088,17 +3079,17 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
/* Prevent the cursor from being drawn outside the text area. */
r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
ns_focus (f, &r, 1);
ns_focus (f, NULL, 0);
face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
if (face && NS_FACE_BACKGROUND (face)
== ns_index_color (FRAME_CURSOR_COLOR (f), f))
{
[ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
hollow_color = FRAME_CURSOR_COLOR (f);
}
else
[FRAME_CURSOR_COLOR (f) set];
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
[ctx saveGraphicsState];
#ifdef NS_IMPL_GNUSTEP
GSRectClipList (ctx, &r, 1);
#else
NSRectClip (r);
#endif
[FRAME_CURSOR_COLOR (f) set];
switch (cursor_type)
{
@ -3106,13 +3097,11 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
case NO_CURSOR:
break;
case FILLED_BOX_CURSOR:
NSRectFill (r);
draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
break;
case HOLLOW_BOX_CURSOR:
NSRectFill (r);
[hollow_color set];
NSRectFill (NSInsetRect (r, 1, 1));
[FRAME_CURSOR_COLOR (f) set];
draw_phys_cursor_glyph (w, glyph_row, DRAW_NORMAL_TEXT);
[NSBezierPath strokeRect: r];
break;
case HBAR_CURSOR:
NSRectFill (r);
@ -3128,12 +3117,9 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
NSRectFill (s);
break;
}
ns_unfocus (f);
/* Draw the character under the cursor. Other terms only draw
the character on top of box cursors, so do the same here. */
if (cursor_type == FILLED_BOX_CURSOR || cursor_type == HOLLOW_BOX_CURSOR)
draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
[ctx restoreGraphicsState];
ns_unfocus (f);
}
@ -3313,16 +3299,18 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
if (s->for_overlaps)
return;
if (s->hl == DRAW_CURSOR)
[FRAME_BACKGROUND_COLOR (s->f) set];
else if (face->underline_defaulted_p)
[defaultCol set];
else
[ns_lookup_indexed_color (face->underline_color, s->f) set];
/* Do underline. */
if (face->underline)
{
if (s->face->underline == 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 == FACE_UNDER_LINE)
@ -3393,11 +3381,6 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
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);
}
}
@ -3407,11 +3390,6 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
{
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);
}
@ -3434,10 +3412,6 @@ larger if there are taller display elements (e.g., characters
dy = lrint ((glyph_height - h) / 2);
r = NSMakeRect (x, glyph_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);
}
}
@ -3585,17 +3559,7 @@ Function modeled after x_draw_glyph_string_box ().
struct glyph *last_glyph;
NSRect r;
int hthickness, vthickness;
struct face *face;
if (s->hl == DRAW_MOUSE_FACE)
{
face = FACE_FROM_ID_OR_NULL (s->f,
MOUSE_HL_INFO (s->f)->mouse_face_face_id);
if (!face)
face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
}
else
face = s->face;
struct face *face = s->face;
vthickness = face->box_vertical_line_width;
hthickness = face->box_horizontal_line_width;
@ -3669,34 +3633,26 @@ Function modeled after x_draw_glyph_string_box ().
|| FONT_TOO_HIGH (s->font)
|| s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
{
struct face *face;
if (s->hl == DRAW_MOUSE_FACE)
{
face
= FACE_FROM_ID_OR_NULL (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);
struct face *face = s->face;
if (!face->stipple)
[(NS_FACE_BACKGROUND (face) != 0
? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
: FRAME_BACKGROUND_COLOR (s->f)) set];
{
if (s->hl != DRAW_CURSOR)
[(NS_FACE_BACKGROUND (face) != 0
? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
: FRAME_BACKGROUND_COLOR (s->f)) set];
else
[FRAME_CURSOR_COLOR (s->f) set];
}
else
{
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
[[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
}
if (s->hl != DRAW_CURSOR)
{
NSRect r = NSMakeRect (s->x, s->y + box_line_width,
s->background_width,
s->height-2*box_line_width);
NSRectFill (r);
}
NSRect r = NSMakeRect (s->x, s->y + box_line_width,
s->background_width,
s->height-2*box_line_width);
NSRectFill (r);
s->background_filled_p = 1;
}
@ -3717,7 +3673,7 @@ Function modeled after x_draw_glyph_string_box ().
int th;
char raised_p;
NSRect br;
struct face *face;
struct face *face = s->face;
NSColor *tdCol;
NSTRACE ("ns_dumpglyphs_image");
@ -3738,15 +3694,6 @@ Function modeled after x_draw_glyph_string_box ().
/* Draw BG: if we need larger area than image itself cleared, do that,
otherwise, since we composite the image under NS (instead of mucking
with its background color), we must clear just the image area. */
if (s->hl == DRAW_MOUSE_FACE)
{
face = FACE_FROM_ID_OR_NULL (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);
[ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
@ -3817,16 +3764,8 @@ Function modeled after x_draw_glyph_string_box ().
if (s->hl == DRAW_CURSOR)
{
[FRAME_CURSOR_COLOR (s->f) set];
if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
[FRAME_CURSOR_COLOR (s->f) set];
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 anticipation of better support for image masks on
NS. */
tdCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
}
else
{
@ -3878,66 +3817,35 @@ Function modeled after x_draw_glyph_string_box ().
static void
ns_dumpglyphs_stretch (struct glyph_string *s)
{
NSRect r[2];
NSRect glyphRect;
int n;
struct face *face;
struct face *face = s->face;
NSColor *fgCol, *bgCol;
if (!s->background_filled_p)
{
n = ns_get_glyph_string_clip_rect (s, r);
ns_focus (s->f, r, n);
if (s->hl == DRAW_MOUSE_FACE)
{
face = FACE_FROM_ID_OR_NULL (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);
face = s->face;
bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
if (s->hl == DRAW_CURSOR)
{
fgCol = bgCol;
bgCol = FRAME_CURSOR_COLOR (s->f);
}
glyphRect = NSMakeRect (s->x, s->y, s->background_width, s->height);
[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)
{
CGFloat x, width;
/* FIXME: This looks like it will only work for left to
right languages. */
x = NSMinX (glyphRect);
width = s->w->phys_cursor_width;
glyphRect.size.width -= width;
glyphRect.origin.x += width;
NSRectFill (glyphRect);
/* 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 (glyphRect);
}
NSRectFill (glyphRect);
/* Draw overlining, etc. on the stretch glyph (or the part
of the stretch glyph after the cursor). */
ns_draw_text_decoration (s, face, fgCol, NSWidth (glyphRect),
NSMinX (glyphRect));
ns_unfocus (s->f);
s->background_filled_p = 1;
}
}
@ -3946,7 +3854,7 @@ overwriting cursor (usually when cursor on a tab) */
static void
ns_draw_glyph_string_foreground (struct glyph_string *s)
{
int x, flags;
int x;
struct font *font = s->font;
/* If first glyph of S has a left box line, start drawing the text
@ -3957,15 +3865,9 @@ overwriting cursor (usually when cursor on a tab) */
else
x = s->x;
flags = s->hl == DRAW_CURSOR ? NS_DUMPGLYPH_CURSOR :
(s->hl == DRAW_MOUSE_FACE ? NS_DUMPGLYPH_MOUSEFACE :
(s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND :
NS_DUMPGLYPH_NORMAL));
font->driver->draw
(s, s->cmp_from, s->nchars, x, s->ybase,
(flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p)
|| flags == NS_DUMPGLYPH_MOUSEFACE);
!s->for_overlaps && !s->background_filled_p);
}
@ -4072,9 +3974,9 @@ overwriting cursor (usually when cursor on a tab) */
struct font *font = s->face->font;
if (! font) font = FRAME_FONT (s->f);
NSTRACE_WHEN (NSTRACE_GROUP_GLYPHS, "ns_draw_glyph_string");
NSTRACE ("ns_draw_glyph_string (hl = %u)", s->hl);
if (s->next && s->right_overhang && !s->for_overlaps/*&&s->hl!=DRAW_CURSOR*/)
if (s->next && s->right_overhang && !s->for_overlaps)
{
int width;
struct glyph_string *next;
@ -4111,14 +4013,21 @@ overwriting cursor (usually when cursor on a tab) */
box_drawn_p = 1;
}
n = ns_get_glyph_string_clip_rect (s, r);
if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
&& !s->clip_tail
&& ((s->prev && s->prev->hl != s->hl && s->left_overhang)
|| (s->next && s->next->hl != s->hl && s->right_overhang)))
r[0] = NSIntersectionRect (r[0], NSMakeRect (s->x, s->y, s->width, s->height));
ns_focus (s->f, r, n);
switch (s->first_glyph->type)
{
case IMAGE_GLYPH:
n = ns_get_glyph_string_clip_rect (s, r);
ns_focus (s->f, r, n);
ns_dumpglyphs_image (s, r[0]);
ns_unfocus (s->f);
break;
case XWIDGET_GLYPH:
@ -4131,57 +4040,36 @@ overwriting cursor (usually when cursor on a tab) */
case CHAR_GLYPH:
case COMPOSITE_GLYPH:
n = ns_get_glyph_string_clip_rect (s, r);
ns_focus (s->f, r, n);
if (s->for_overlaps || (s->cmp_from > 0
&& ! s->first_glyph->u.cmp.automatic))
s->background_filled_p = 1;
else
ns_maybe_dumpglyphs_background
(s, s->first_glyph->type == COMPOSITE_GLYPH);
if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
{
unsigned long tmp = NS_FACE_BACKGROUND (s->face);
NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
NS_FACE_FOREGROUND (s->face) = tmp;
}
{
BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
if (s->for_overlaps || (isComposite
&& (s->cmp_from > 0
&& ! s->first_glyph->u.cmp.automatic)))
s->background_filled_p = 1;
else
ns_maybe_dumpglyphs_background
(s, s->first_glyph->type == COMPOSITE_GLYPH);
if (isComposite)
ns_draw_composite_glyph_string_foreground (s);
else
ns_draw_glyph_string_foreground (s);
if (isComposite)
ns_draw_composite_glyph_string_foreground (s);
else
ns_draw_glyph_string_foreground (s);
{
NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face),
s->f)
: FRAME_FOREGROUND_COLOR (s->f));
[col set];
/* Draw underline, overline, strike-through. */
ns_draw_text_decoration (s, s->face, col, s->width, s->x);
}
}
{
NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face),
s->f)
: FRAME_FOREGROUND_COLOR (s->f));
[col set];
/* Draw underline, overline, strike-through. */
ns_draw_text_decoration (s, s->face, col, s->width, s->x);
}
if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
{
unsigned long tmp = NS_FACE_BACKGROUND (s->face);
NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
NS_FACE_FOREGROUND (s->face) = tmp;
}
ns_unfocus (s->f);
break;
case GLYPHLESS_GLYPH:
n = ns_get_glyph_string_clip_rect (s, r);
ns_focus (s->f, r, n);
if (s->for_overlaps || (s->cmp_from > 0
&& ! s->first_glyph->u.cmp.automatic))
s->background_filled_p = 1;
@ -4191,7 +4079,6 @@ overwriting cursor (usually when cursor on a tab) */
/* ... */
/* Not yet implemented. */
/* ... */
ns_unfocus (s->f);
break;
default:
@ -4200,13 +4087,92 @@ overwriting cursor (usually when cursor on a tab) */
/* Draw box if not done already. */
if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX)
ns_dumpglyphs_box_or_relief (s);
ns_unfocus (s->f);
/* Draw surrounding overhangs. */
if (s->prev)
{
n = ns_get_glyph_string_clip_rect (s, r);
ns_focus (s->f, r, n);
ns_dumpglyphs_box_or_relief (s);
ns_focus (s->f, NULL, 0);
struct glyph_string *prev;
for (prev = s->prev; prev; prev = prev->prev)
if (prev->hl != s->hl
&& prev->x + prev->width + prev->right_overhang > s->x)
{
/* As prev was drawn while clipped to its own area, we
must draw the right_overhang part using s->hl now. */
enum draw_glyphs_face save = prev->hl;
struct face *save_face = prev->face;
prev->face = s->face;
NSRect r = NSMakeRect (s->x, s->y, s->width, s->height);
[[NSGraphicsContext currentContext] saveGraphicsState];
NSRectClip (r);
#ifdef NS_IMPL_GNUSTEP
DPSgsave ([NSGraphicsContext currentContext]);
DPSrectclip ([NSGraphicsContext currentContext], s->x, s->y,
s->width, s->height);
#endif
prev->num_clips = 1;
prev->hl = s->hl;
if (prev->first_glyph->type == CHAR_GLYPH)
ns_draw_glyph_string_foreground (prev);
else
ns_draw_composite_glyph_string_foreground (prev);
#ifdef NS_IMPL_GNUSTEP
DPSgrestore ([NSGraphicsContext currentContext]);
#endif
[[NSGraphicsContext currentContext] restoreGraphicsState];
prev->hl = save;
prev->face = save_face;
prev->num_clips = 0;
}
ns_unfocus (s->f);
}
if (s->next)
{
ns_focus (s->f, NULL, 0);
struct glyph_string *next;
for (next = s->next; next; next = next->next)
if (next->hl != s->hl
&& next->x - next->left_overhang < s->x + s->width)
{
/* As next will be drawn while clipped to its own area,
we must draw the left_overhang part using s->hl now. */
enum draw_glyphs_face save = next->hl;
struct face *save_face = next->face;
next->hl = s->hl;
next->face = s->face;
NSRect r = NSMakeRect (s->x, s->y, s->width, s->height);
[[NSGraphicsContext currentContext] saveGraphicsState];
NSRectClip (r);
#ifdef NS_IMPL_GNUSTEP
DPSgsave ([NSGraphicsContext currentContext]);
DPSrectclip ([NSGraphicsContext currentContext], s->x, s->y,
s->width, s->height);
#endif
next->num_clips = 1;
if (next->first_glyph->type == CHAR_GLYPH)
ns_draw_glyph_string_foreground (next);
else
ns_draw_composite_glyph_string_foreground (next);
#ifdef NS_IMPL_GNUSTEP
DPSgrestore ([NSGraphicsContext currentContext]);
#endif
[[NSGraphicsContext currentContext] restoreGraphicsState];
next->hl = save;
next->num_clips = 0;
next->face = save_face;
next->clip_head = next;
next->background_filled_p = 0;
}
ns_unfocus (s->f);
}
s->num_clips = 0;
}

View file

@ -29306,7 +29306,6 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
for (s = head; s; s = s->next)
FRAME_RIF (f)->draw_glyph_string (s);
#ifndef HAVE_NS
/* When focus a sole frame and move horizontally, this clears on_p
causing a failure to erase prev cursor position. */
if (area == TEXT_AREA
@ -29325,7 +29324,6 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
row->y, MATRIX_ROW_BOTTOM_Y (row));
}
#endif
/* Value is the x-position up to which drawn, relative to AREA of W.
This doesn't include parts drawn because of overhangs. */