From 3fa2054efdfa3c22456072254e6c67682a595233 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Sun, 15 Sep 2013 19:58:46 +0200 Subject: [PATCH] Port the font backend from the Mac port. * configure.ac: Add check for OSX 10.5, required for macfont.o. * etc/NEWS: Mention the macfont backend. * src/Makefile.in (NS_OBJ, SOME_MACHINE_OBJECTS): Add macfont.o. * src/font.c (syms_of_font): Call syms_of_macfont. * src/font.h: Declare syms_of_macfont. * src/nsfns.m: Include macfont.h. (Fx_create_frame): Register macfont driver, make a better default font. (Fns_popup_font_panel): Get font from macfont driver, if used. * src/nsfont.m (ns_tmp_flags, ns_tmp_font): Remove. (nsfont_open): Set font driver type. Set font->ascent and font->descent. Figure out font instead of ns_tmp_font, and flags instead of ns_tmp_flags. Fix indentation. Remove call to ns_draw_text_decoration, moved to nsterm. * src/nsterm.m: Include macfont.h. (ns_tmp_flags, ns_tmp_font): Remove. (ns_compute_glyph_string_overhangs): Check for driver Qns. (ns_draw_glyph_string): Use local variables instead of ns_tmp_flags, ns_tmp_font. Call ns_draw_text_decoration here instead of nsfont.m. (changeFont:): Fix code style. Check for font driver type when getiing font. * src/nsterm.h (FONT_DESCENT, FONT_ASCENT): Define to (f)->ascent and (f)->descent. --- ChangeLog | 4 +++ configure.ac | 34 +++++++++++++++++++++---- etc/ChangeLog | 4 +++ etc/NEWS | 5 ++++ src/ChangeLog | 32 ++++++++++++++++++++++++ src/Makefile.in | 4 +-- src/font.c | 1 + src/font.h | 1 + src/nsfns.m | 32 +++++++++++++++++++++--- src/nsfont.m | 35 +++++++++++++++----------- src/nsterm.h | 6 ++--- src/nsterm.m | 66 ++++++++++++++++++++++++++++++++++--------------- 12 files changed, 175 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4fc4e065e9..c034a29300 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-09-15 Jan Djärv + + * configure.ac: Add check for OSX 10.5, required for macfont.o. + 2013-09-09 Glenn Morris * configure.ac (LDFLAGS_NOCOMBRELOC): New variable. diff --git a/configure.ac b/configure.ac index ab2e48b6f0..86a5f30098 100644 --- a/configure.ac +++ b/configure.ac @@ -1623,7 +1623,10 @@ fail; [AC_MSG_ERROR([`--with-ns' was specified, but the include files are missing or cannot be compiled.])]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], + macfont_file="" + if test "${NS_IMPL_COCOA}" = "yes"; then + AC_MSG_CHECKING([for OSX 10.4 or newer]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [ #ifdef MAC_OS_X_VERSION_MAX_ALLOWED #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 @@ -1635,13 +1638,33 @@ fail; ])], ns_osx_have_104=yes, ns_osx_have_104=no) + AC_MSG_RESULT([$ns_osx_have_104]) + + if test $ns_osx_have_104 = no; then + AC_MSG_ERROR([`OSX 10.4 or newer is required']); + fi + AC_MSG_CHECKING([for OSX 10.5 or newer]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], + [ +#ifdef MAC_OS_X_VERSION_MAX_ALLOWED +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 + ; /* OK */ +#else +#error "OSX 10.5 not found" +#endif +#endif + ])], + ns_osx_have_105=yes, + ns_osx_have_105=no) + AC_MSG_RESULT([$ns_osx_have_105]) + if test $ns_osx_have_105 = yes; then + macfont_file="macfont.o" + fi + fi AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [NSInteger i;])], ns_have_nsinteger=yes, ns_have_nsinteger=no) - if test $ns_osx_have_104 = no; then - AC_MSG_ERROR([`OSX 10.4 or newer is required']); - fi if test $ns_have_nsinteger = yes; then AC_DEFINE(NS_HAVE_NSINTEGER, 1, [Define to 1 if `NSInteger' is defined.]) fi @@ -1677,7 +1700,8 @@ if test "${HAVE_NS}" = yes; then leimdir="\${ns_appresdir}/leim" INSTALL_ARCH_INDEP_EXTRA= fi - NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o" + + NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o $macfont_file" fi CFLAGS="$tmp_CFLAGS" CPPFLAGS="$tmp_CPPFLAGS" diff --git a/etc/ChangeLog b/etc/ChangeLog index bd5534d944..5483d824da 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,7 @@ +2013-09-15 Jan Djärv + + * NEWS: Mention the macfont backend. + 2013-09-09 Glenn Morris * refcards/Makefile (PS_ENGLISH, PS_CZECH, PS_FRENCH, PS_GERMAN) diff --git a/etc/NEWS b/etc/NEWS index a5da8eaa89..7558fc5305 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -54,6 +54,11 @@ and zlib-format compressed data. ** Emacs for NS (OSX, GNUStep) can be built with ImageMagick support. pkg-config is required to find ImageMagick libraries. +** For OSX >= 10.5, the Core text based font backend from the Mac port is used. +For GNUStep and OSX 10.4 the old backend is used. +To use the old backend by default, do on the command line: +% defaults write org.gnu.Emacs FontBackend ns + * Startup Changes in Emacs 24.4 diff --git a/src/ChangeLog b/src/ChangeLog index 5f28dc3d7d..e3b29c9b21 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,35 @@ +2013-09-15 Jan Djärv + + * nsterm.m: Include macfont.h. + (ns_tmp_flags, ns_tmp_font): Remove. + (ns_compute_glyph_string_overhangs): Check for driver Qns. + (ns_draw_glyph_string): Use local variables instead of ns_tmp_flags, + ns_tmp_font. Call ns_draw_text_decoration here instead of nsfont.m. + (changeFont:): Fix code style. Check for font driver type when + getiing font. + + * nsterm.h (FONT_DESCENT, FONT_ASCENT): Define to (f)->ascent and + (f)->descent. + + * nsfont.m (ns_tmp_flags, ns_tmp_font): Remove. + (nsfont_open): Set font driver type. + Set font->ascent and font->descent. Figure out font instead of + ns_tmp_font, and flags instead of ns_tmp_flags. + Fix indentation. Remove call to ns_draw_text_decoration, + moved to nsterm. + + * nsfns.m: Include macfont.h. + (Fx_create_frame): Register macfont driver, make a better default font. + (Fns_popup_font_panel): Get font from macfont driver, if used. + + * macfont.m, macfont.h, maccuvs.h: New files. + + * font.h: Declare syms_of_macfont. + + * font.c (syms_of_font): Call syms_of_macfont. + + * Makefile.in (NS_OBJ, SOME_MACHINE_OBJECTS): Add macfont.o. + 2013-09-15 Dmitry Antipov Drop VERTICAL_SCROLL_BAR_WIDTH_TRIM. For X, it is zero since 1999, diff --git a/src/Makefile.in b/src/Makefile.in index fe8d2d13ce..254aa175d4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -266,7 +266,7 @@ MSDOS_OBJ = MSDOS_X_OBJ = NS_OBJ=@NS_OBJ@ -## nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o if HAVE_NS. +## nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macfont.o if HAVE_NS. NS_OBJC_OBJ=@NS_OBJC_OBJ@ ## Only set if NS_IMPL_GNUSTEP. GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@ @@ -388,7 +388,7 @@ obj = $(base_obj) $(NS_OBJC_OBJ) SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \ fontset.o dbusbind.o cygw32.o \ - nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o \ + nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macfont.o \ w32.o w32console.o w32fns.o w32heap.o w32inevt.o w32notify.o \ w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \ w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \ diff --git a/src/font.c b/src/font.c index fb64f2d907..27f4f5dca9 100644 --- a/src/font.c +++ b/src/font.c @@ -5199,6 +5199,7 @@ EMACS_FONT_LOG is set. Otherwise, it is set to t. */); #endif /* HAVE_NTGUI */ #ifdef HAVE_NS syms_of_nsfont (); + syms_of_macfont (); #endif /* HAVE_NS */ #endif /* HAVE_WINDOW_SYSTEM */ } diff --git a/src/font.h b/src/font.h index 3e0d97baaa..0ec5659091 100644 --- a/src/font.h +++ b/src/font.h @@ -825,6 +825,7 @@ extern void syms_of_w32font (void); extern Lisp_Object Qfontsize; extern struct font_driver nsfont_driver; extern void syms_of_nsfont (void); +extern void syms_of_macfont (void); #endif /* HAVE_NS */ #ifndef FONT_DEBUG diff --git a/src/nsfns.m b/src/nsfns.m index 8eaf529ed0..1b4e6b7f57 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -46,6 +46,9 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #ifdef NS_IMPL_COCOA #include +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#include "macfont.h" +#endif #endif #if 0 @@ -1171,7 +1174,17 @@ This function is an internal primitive--use `make-frame' instead. */) } block_input (); + +#ifdef NS_IMPL_GNUSTEP || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 register_font_driver (&nsfont_driver, f); +#else + if (CTGetCoreTextVersion != NULL + && CTGetCoreTextVersion () >= kCTVersionNumber10_5) + mac_register_font_driver (f); + register_font_driver (&nsfont_driver, f); +#endif + x_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); @@ -1181,8 +1194,13 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qfontsize, make_number (0 /*(int)[font pointSize]*/), "fontSize", "FontSize", RES_TYPE_NUMBER); + // Remove ' Regular', not handled by backends. + char *fontname = xstrdup ([[font displayName] UTF8String]); + int len = strlen (fontname); + if (len > 8 && strcmp (fontname + len - 8, " Regular") == 0) + fontname[len-8] = '\0'; x_default_parameter (f, parms, Qfont, - build_string ([[font fontName] UTF8String]), + build_string (fontname), "font", "Font", RES_TYPE_STRING); } unblock_input (); @@ -1362,9 +1380,15 @@ DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel, { struct frame *f = decode_window_system_frame (frame); id fm = [NSFontManager sharedFontManager]; - - [fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont - isMultiple: NO]; + struct font *font = f->output_data.ns->font; + NSFont *nsfont; + if (EQ (font->driver->type, Qns)) + nsfont = ((struct nsfont_info *)font)->nsfont; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + else + nsfont = (NSFont *) macfont_get_nsctfont (font); +#endif + [fm setSelectedFont: nsfont isMultiple: NO]; [fm orderFrontFontPanel: NSApp]; return Qnil; } diff --git a/src/nsfont.m b/src/nsfont.m index b61147d66c..d9c8660f1c 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -51,8 +51,6 @@ static Lisp_Object Qapple, Qroman, Qmedium; static Lisp_Object Qcondensed, Qexpanded; extern Lisp_Object Qappend; extern float ns_antialias_threshold; -extern int ns_tmp_flags; -extern struct nsfont_info *ns_tmp_font; /* font glyph and metrics caching functions, implemented at end */ @@ -798,6 +796,7 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size) font_object = font_make_object (VECSIZE (struct nsfont_info), font_entity, pixel_size); + ASET (font_object, FONT_TYPE_INDEX, nsfont_driver.type); font_info = (struct nsfont_info *) XFONT_OBJECT (font_object); font = (struct font *) font_info; if (!font) @@ -871,10 +870,11 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size) font_info->size = font->pixel_size; /* max bounds */ - font_info->max_bounds.ascent = lrint ([sfont ascender]); + font->ascent = font_info->max_bounds.ascent = lrint ([sfont ascender]); /* Descender is usually negative. Use floor to avoid clipping descenders. */ - font_info->max_bounds.descent = -lrint (floor(adjusted_descender)); + font->descent = + font_info->max_bounds.descent = -lrint (floor(adjusted_descender)); font_info->height = font_info->max_bounds.ascent + font_info->max_bounds.descent; font_info->max_bounds.width = lrint (font_info->width); @@ -1051,16 +1051,26 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, #endif struct face *face; NSRect r; - struct nsfont_info *font = ns_tmp_font; + struct nsfont_info *font; NSColor *col, *bgCol; unsigned short *t = s->char2b; - int i, len; + int i, len, flags; char isComposite = s->first_glyph->type == COMPOSITE_GLYPH; int end = isComposite ? s->cmp_to : s->nchars; block_input (); + + font = (struct nsfont_info *)s->face->font; + if (font == NULL) + font = (struct nsfont_info *)FRAME_FONT (s->f); + /* Select face based on input flags */ - switch (ns_tmp_flags) + 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)); + + switch (flags) { case NS_DUMPGLYPH_CURSOR: face = s->face; @@ -1188,8 +1198,8 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, col = (NS_FACE_FOREGROUND (face) != 0 ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f) : FRAME_FOREGROUND_COLOR (s->f)); - /* FIXME: find another way to pass this */ - bgCol = (ns_tmp_flags != NS_DUMPGLYPH_FOREGROUND ? nil + + bgCol = (flags != NS_DUMPGLYPH_FOREGROUND ? nil : (NS_FACE_BACKGROUND (face) != 0 ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) : FRAME_BACKGROUND_COLOR (s->f))); @@ -1264,22 +1274,19 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, CGContextSetTextPosition (gcontext, r.origin.x, r.origin.y); CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->cmp_from, - advances, len); + advances, len); if (face->overstrike) { CGContextSetTextPosition (gcontext, r.origin.x+0.5, r.origin.y); CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->cmp_from, - advances, len); + advances, len); } CGContextRestoreGState (gcontext); } #endif /* NS_IMPL_COCOA */ - /* Draw underline, overline, strike-through. */ - ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x); - unblock_input (); return to-from; } diff --git a/src/nsterm.h b/src/nsterm.h index d8482cebbb..1b5804b98b 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -701,10 +701,8 @@ struct x_output #define FONT_WIDTH(f) ((f)->max_width) #define FONT_HEIGHT(f) ((f)->height) -/*#define FONT_BASE(f) ((f)->ascent) */ -#define FONT_BASE(f) (((struct nsfont_info *)f)->max_bounds.ascent) -/*#define FONT_DESCENT(f) ((f)->descent) */ -#define FONT_DESCENT(f) (((struct nsfont_info *)f)->max_bounds.descent) +#define FONT_BASE(f) ((f)->ascent) +#define FONT_DESCENT(f) ((f)->descent) #define FRAME_DEFAULT_FACE(f) FACE_FROM_ID (f, DEFAULT_FACE_ID) diff --git a/src/nsterm.m b/src/nsterm.m index 1dac6ba9fe..2fc8a09c80 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -64,6 +64,12 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #include "process.h" #endif +#ifdef NS_IMPL_COCOA +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#include "macfont.h" +#endif +#endif + /* call tracing */ #if 0 int term_trace_num = 0; @@ -198,8 +204,6 @@ static NSRect uRect; #endif static BOOL gsaved = NO; static BOOL ns_fake_keydown = NO; -int ns_tmp_flags; /* FIXME */ -struct nsfont_info *ns_tmp_font; /* FIXME */ #ifdef NS_IMPL_COCOA static BOOL ns_menu_bar_is_hidden = NO; #endif @@ -2158,8 +2162,11 @@ ns_compute_glyph_string_overhangs (struct glyph_string *s) else { s->left_overhang = 0; - s->right_overhang = ((struct nsfont_info *)font)->ital ? - FONT_HEIGHT (font) * 0.2 : 0; + if (EQ (font->driver->type, Qns)) + s->right_overhang = ((struct nsfont_info *)font)->ital ? + FONT_HEIGHT (font) * 0.2 : 0; + else + s->right_overhang = 0; } } @@ -3133,8 +3140,10 @@ ns_draw_glyph_string (struct glyph_string *s) { /* TODO (optimize): focus for box and contents draw */ NSRect r[2]; - int n; + int n, flags; char box_drawn_p = 0; + struct font *font = s->face->font; + if (! font) font = FRAME_FONT (s->f); NSTRACE (ns_draw_glyph_string); @@ -3201,13 +3210,10 @@ ns_draw_glyph_string (struct glyph_string *s) ns_maybe_dumpglyphs_background (s, s->first_glyph->type == COMPOSITE_GLYPH); - ns_tmp_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)); - ns_tmp_font = (struct nsfont_info *)s->face->font; - if (ns_tmp_font == NULL) - ns_tmp_font = (struct nsfont_info *)FRAME_FONT (s->f); + 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)); if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) { @@ -3216,10 +3222,21 @@ ns_draw_glyph_string (struct glyph_string *s) NS_FACE_FOREGROUND (s->face) = tmp; } - ns_tmp_font->font.driver->draw + font->driver->draw (s, 0, s->nchars, s->x, s->y, - (ns_tmp_flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p) - || ns_tmp_flags == NS_DUMPGLYPH_MOUSEFACE); + (flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p) + || flags == NS_DUMPGLYPH_MOUSEFACE); + + { + 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) { @@ -3959,7 +3976,7 @@ static struct redisplay_interface ns_redisplay_interface = 0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */ 0, /* destroy_fringe_bitmap */ ns_compute_glyph_string_overhangs, - ns_draw_glyph_string, /* interface to nsfont.m */ + ns_draw_glyph_string, ns_define_frame_cursor, ns_clear_frame_area, ns_draw_window_cursor, @@ -4809,17 +4826,26 @@ not_in_argv (NSString *arg) /* called on font panel selection */ - (void)changeFont: (id)sender { - NSEvent *e =[[self window] currentEvent]; - struct face *face =FRAME_DEFAULT_FACE (emacsframe); + NSEvent *e = [[self window] currentEvent]; + struct face *face = FRAME_DEFAULT_FACE (emacsframe); + struct font *font = face->font; id newFont; CGFloat size; + NSFont *nsfont; NSTRACE (changeFont); + if (!emacs_event) return; - if ((newFont = [sender convertFont: - ((struct nsfont_info *)face->font)->nsfont])) + if (EQ (font->driver->type, Qns)) + nsfont = ((struct nsfont_info *)font)->nsfont; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + else + nsfont = (NSFont *) macfont_get_nsctfont (font); +#endif + + if ((newFont = [sender convertFont: nsfont])) { SET_FRAME_GARBAGED (emacsframe); /* now needed as of 2008/10 */ -- 2.20.1