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:
parent
ba278e4a9b
commit
07715630ad
6 changed files with 1091 additions and 586 deletions
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
1203
src/nsfont.m
1203
src/nsfont.m
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
428
src/nsterm.m
428
src/nsterm.m
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Add table
Reference in a new issue