* src/nsfns.m (ns_display_info_for_name, Fx_open_connection): Doc fixes.
[bpt/emacs.git] / src / nsfont.m
index 412a677..14e24c2 100644 (file)
@@ -1,6 +1,6 @@
 /* Font back-end driver for the NeXT/Open/GNUstep and MacOSX window system.
    See font.h
-   Copyright (C) 2006-2012 Free Software Foundation, Inc.
+   Copyright (C) 2006-2014 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -23,7 +23,6 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu)
 /* This should be the first include, as it may set up #defines affecting
    interpretation of even the system includes. */
 #include <config.h>
-#include <setjmp.h>
 
 #include "lisp.h"
 #include "dispextern.h"
@@ -34,7 +33,6 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu)
 #include "window.h"
 #include "fontset.h"
 #include "nsterm.h"
-#include "frame.h"
 #include "character.h"
 #include "font.h"
 #include "termchar.h"
@@ -45,14 +43,15 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu)
 #endif
 
 #define NSFONT_TRACE 0
+#define LCD_SMOOTHING_MARGIN 2
 
 extern Lisp_Object Qns;
-extern Lisp_Object Qnormal, Qbold, Qitalic, Qcondensed, Qexpanded;
+extern Lisp_Object Qnormal, Qbold, Qitalic;
 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 */
 static void ns_uni_to_glyphs (struct nsfont_info *font_info,
@@ -60,6 +59,7 @@ static void ns_uni_to_glyphs (struct nsfont_info *font_info,
 static void ns_glyph_metrics (struct nsfont_info *font_info,
                               unsigned char block);
 
+#define INVALID_GLYPH 0xFFFF
 
 /* ==========================================================================
 
@@ -73,10 +73,9 @@ static void ns_glyph_metrics (struct nsfont_info *font_info,
 static void
 ns_escape_name (char *name)
 {
-  int i =0, len =strlen (name);
-  for ( ; i<len; i++)
-    if (name[i] == ' ')
-      name[i] = '_';
+  for (; *name; name++)
+    if (*name == ' ')
+      *name = '_';
 }
 
 
@@ -84,10 +83,9 @@ ns_escape_name (char *name)
 static void
 ns_unescape_name (char *name)
 {
-  int i =0, len =strlen (name);
-  for ( ; i<len; i++)
-    if (name[i] == '_')
-      name[i] = ' ';
+  for (; *name; name++)
+    if (*name == '_')
+      *name = ' ';
 }
 
 
@@ -119,7 +117,7 @@ ns_attribute_fvalue (NSFontDescriptor *fdesc, NSString *trait)
 {
     NSDictionary *tdict = [fdesc objectForKey: NSFontTraitsAttribute];
     NSNumber *val = [tdict objectForKey: trait];
-    return val == nil ? 0.0 : [val floatValue];
+    return val == nil ? 0.0F : [val floatValue];
 }
 
 
@@ -138,23 +136,26 @@ ns_spec_to_descriptor (Lisp_Object font_spec)
     /* add each attr in font_spec to fdAttrs.. */
     n = min (FONT_WEIGHT_NUMERIC (font_spec), 200);
     if (n != -1 && n != STYLE_REF)
-       [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+       [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
                  forKey: NSFontWeightTrait];
     n = min (FONT_SLANT_NUMERIC (font_spec), 200);
     if (n != -1 && n != STYLE_REF)
-       [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+       [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
                  forKey: NSFontSlantTrait];
     n = min (FONT_WIDTH_NUMERIC (font_spec), 200);
     if (n > -1 && (n > STYLE_REF + 10 || n < STYLE_REF - 10))
-       [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+       [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
                  forKey: NSFontWidthTrait];
     if ([tdict count] > 0)
        [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
 
-    fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs];
+    fdesc = [[[NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]
+               retain] autorelease];
+
     if (family != nil)
       {
-       fdesc = [fdesc fontDescriptorWithFamily: family];
+        NSFontDescriptor *fdesc2 = [fdesc fontDescriptorWithFamily: family];
+        fdesc = [[fdesc2 retain] autorelease];
       }
 
     [fdAttrs release];
@@ -201,8 +202,8 @@ ns_descriptor_to_entity (NSFontDescriptor *desc,
                    make_number (100 + 100
                         * ns_attribute_fvalue (desc, NSFontSlantTrait)));*/
     FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
-                   traits & NSFontCondensedTrait ? Qcondensed :
-                   traits & NSFontExpandedTrait ? Qexpanded : Qnormal);
+                    traits & NSFontCondensedTrait ? Qcondensed :
+                    traits & NSFontExpandedTrait ? Qexpanded : Qnormal);
 /*    FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
                    make_number (100 + 100
                         * ns_attribute_fvalue (desc, NSFontWidthTrait)));*/
@@ -237,10 +238,10 @@ ns_fallback_entity (void)
 
 
 /* Utility: get width of a char c in screen font SFONT */
-static float
+static CGFloat
 ns_char_width (NSFont *sfont, int c)
 {
-  float w = -1.0;
+  CGFloat w = -1.0;
   NSString *cstr = [NSString stringWithFormat: @"%c", c];
 
 #ifdef NS_IMPL_COCOA
@@ -266,7 +267,7 @@ static NSString *ascii_printable;
 static int
 ns_ascii_average_width (NSFont *sfont)
 {
-  float w = -1.0;
+  CGFloat w = -1.0;
 
   if (!ascii_printable)
     {
@@ -285,14 +286,14 @@ ns_ascii_average_width (NSFont *sfont)
     w = [sfont advancementForGlyph: glyph].width;
 #endif
 
-  if (w < 0.0)
+  if (w < (CGFloat) 0.0)
     {
       NSDictionary *attrsDictionary =
        [NSDictionary dictionaryWithObject: sfont forKey: NSFontAttributeName];
       w = [ascii_printable sizeWithAttributes: attrsDictionary].width;
     }
 
-  return lrint (w / 95.0);
+  return lrint (w / (CGFloat) 95.0);
 }
 
 
@@ -320,7 +321,7 @@ ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct)
                off++;
          }
 //fprintf(stderr, "off = %d\ttot = %d\n", off,tot);
-    return (float)off / tot < 1.0 - pct;
+    return (float)off / tot < 1.0F - pct;
 }
 
 
@@ -359,10 +360,10 @@ static NSString
 *ns_registry_to_script (char *reg)
 {
     Lisp_Object script, r, rts = Vns_reg_to_script;
-    while CONSP (rts)
+    while (CONSP (rts))
       {
         r = XCAR (XCAR (rts));
-        if (!strncmp(SSDATA(r), reg, strlen(SSDATA(r))))
+        if (!strncmp (SSDATA (r), reg, SBYTES (r)))
           {
             script = XCDR (XCAR (rts));
             return [NSString stringWithUTF8String: SSDATA (SYMBOL_NAME (script))];
@@ -444,7 +445,7 @@ static NSCharacterSet
       {
        Lisp_Object ranges, range_list;
 
-       ranges = Fcons (script, Qnil);
+       ranges = list1 (script);
        map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
                        ranges);
        range_list = Fnreverse (XCDR (ranges));
@@ -511,8 +512,8 @@ static NSSet
                    if (ns_charset_covers(fset, charset, pct))
                        [families addObject: family];
                  }
-                pct -= 0.2;
-               if ([families count] > 0 || pct < 0.05)
+                pct -= 0.2F;
+               if ([families count] > 0 || pct < 0.05F)
                    break;
              }
             [charset release];
@@ -525,7 +526,7 @@ static NSSet
       }
 
     if (NSFONT_TRACE)
-       NSLog(@"    returning %d families", [families count]);
+      NSLog(@"    returning %lu families", (unsigned long)[families count]);
     return families;
 }
 
@@ -545,6 +546,7 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
     NSSet *cFamilies;
     BOOL foundItal = NO;
 
+    block_input ();
     if (NSFONT_TRACE)
       {
        fprintf (stderr, "nsfont: %s for fontspec:\n    ",
@@ -560,9 +562,10 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
        [fkeys removeObject: NSFontFamilyAttribute];
 
     matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
+
     if (NSFONT_TRACE)
-       NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc,
-             [matchingDescs count]);
+       NSLog(@"Got desc %@ and found %lu matching fonts from it: ", fdesc,
+             (unsigned long)[matchingDescs count]);
 
     for (dEnum = [matchingDescs objectEnumerator]; (desc = [dEnum nextObject]);)
       {
@@ -593,6 +596,8 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
         [s1 release];
       }
 
+    unblock_input ();
+
     /* Return something if was a match and nothing found. */
     if (isMatch)
       return ns_fallback_entity ();
@@ -613,19 +618,19 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
    ========================================================================== */
 
 
-static Lisp_Object nsfont_get_cache (FRAME_PTR frame);
-static Lisp_Object nsfont_list (Lisp_Object frame, Lisp_Object font_spec);
-static Lisp_Object nsfont_match (Lisp_Object frame, Lisp_Object font_spec);
-static Lisp_Object nsfont_list_family (Lisp_Object frame);
-static Lisp_Object nsfont_open (FRAME_PTR f, Lisp_Object font_entity,
+static Lisp_Object nsfont_get_cache (struct frame *frame);
+static Lisp_Object nsfont_list (struct frame *, Lisp_Object);
+static Lisp_Object nsfont_match (struct frame *, Lisp_Object);
+static Lisp_Object nsfont_list_family (struct frame *);
+static Lisp_Object nsfont_open (struct frame *f, Lisp_Object font_entity,
                                  int pixel_size);
-static void nsfont_close (FRAME_PTR f, struct font *font);
+static void nsfont_close (struct font *font);
 static int nsfont_has_char (Lisp_Object entity, int c);
 static unsigned int nsfont_encode_char (struct font *font, int c);
 static int nsfont_text_extents (struct font *font, unsigned int *code,
                                 int nglyphs, struct font_metrics *metrics);
 static int nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
-                        int with_background);
+                        bool with_background);
 
 struct font_driver nsfont_driver =
   {
@@ -653,9 +658,9 @@ struct font_driver nsfont_driver =
 /* Return a cache of font-entities on FRAME.  The cache must be a
    cons whose cdr part is the actual cache area.  */
 static Lisp_Object
-nsfont_get_cache (FRAME_PTR frame)
+nsfont_get_cache (struct frame *frame)
 {
-  Display_Info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
+  Display_Info *dpyinfo = FRAME_DISPLAY_INFO (frame);
   return (dpyinfo->name_list_element);
 }
 
@@ -673,9 +678,9 @@ nsfont_get_cache (FRAME_PTR frame)
    weight, slant, width, size (0 if scalable),
    dpi, spacing, avgwidth (0 if scalable)  */
 static Lisp_Object
-nsfont_list (Lisp_Object frame, Lisp_Object font_spec)
+nsfont_list (struct frame *f, Lisp_Object font_spec)
 {
-    return ns_findfonts (font_spec, NO);
+  return ns_findfonts (font_spec, NO);
 }
 
 
@@ -684,22 +689,24 @@ nsfont_list (Lisp_Object frame, Lisp_Object font_spec)
    `face-font-selection-order' is ignored here.
    Properties to be considered are same as for list(). */
 static Lisp_Object
-nsfont_match (Lisp_Object frame, Lisp_Object font_spec)
+nsfont_match (struct frame *f, Lisp_Object font_spec)
 {
-    return ns_findfonts(font_spec, YES);
+  return ns_findfonts (font_spec, YES);
 }
 
 
 /* List available families.  The value is a list of family names
    (symbols). */
 static Lisp_Object
-nsfont_list_family (Lisp_Object frame)
+nsfont_list_family (struct frame *f)
 {
   Lisp_Object list = Qnil;
-  NSEnumerator *families =
-    [[[NSFontManager sharedFontManager] availableFontFamilies]
-      objectEnumerator];
+  NSEnumerator *families;
   NSString *family;
+
+  block_input ();
+  families = [[[NSFontManager sharedFontManager] availableFontFamilies]
+               objectEnumerator];
   while ((family = [families nextObject]))
       list = Fcons (intern ([family UTF8String]), list);
   /* FIXME: escape the name? */
@@ -708,6 +715,7 @@ nsfont_list_family (Lisp_Object frame)
     fprintf (stderr, "nsfont: list families returning %"pI"d entries\n",
             XINT (Flength (list)));
 
+  unblock_input ();
   return list;
 }
 
@@ -715,7 +723,7 @@ nsfont_list_family (Lisp_Object frame)
 /* Open a font specified by FONT_ENTITY on frame F.  If the font is
    scalable, open it with PIXEL_SIZE.  */
 static Lisp_Object
-nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
+nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
 {
   BOOL synthItal;
   unsigned int traits = 0;
@@ -729,16 +737,8 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
   NSRect brect;
   Lisp_Object font_object;
   int fixLeopardBug;
-  static NSMutableDictionary *fontCache = nil;
-  NSNumber *cached;
 
-  /* 2008/03/08: The same font may end up being requested for different
-     entities, due to small differences in numeric values or other issues,
-     or for different copies of the same entity.  Therefore we cache to
-     avoid creating multiple struct font objects (with metrics cache, etc.)
-     for the same NSFont object. */
-  if (fontCache == nil)
-    fontCache = [[NSMutableDictionary alloc] init];
+  block_input ();
 
   if (NSFONT_TRACE)
     {
@@ -761,9 +761,9 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
     family = [[NSFont userFixedPitchFontOfSize: 0] familyName];
   /* Should be > 0.23 as some font descriptors (e.g. Terminus) set to that
      when setting family in ns_spec_to_descriptor(). */
-  if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50)
+  if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50F)
       traits |= NSBoldFontMask;
-  if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05))
+  if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F))
       traits |= NSItalicFontMask;
 
   /* see http://cocoadev.com/forums/comments.php?DiscussionID=74 */
@@ -794,38 +794,28 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
   if (NSFONT_TRACE)
     NSLog (@"%@\n", nsfont);
 
-  /* Check the cache */
-  cached = [fontCache objectForKey: nsfont];
-  if (cached != nil && !synthItal)
-    {
-      if (NSFONT_TRACE)
-        fprintf(stderr, "*** nsfont_open CACHE HIT!\n");
-      /* FIXME: Cast from (unsigned long) to Lisp_Object. */
-      XHASH (font_object) = [cached unsignedLongValue];
-      return font_object;
-    }
-  else
-    {
-      font_object = font_make_object (VECSIZE (struct nsfont_info),
-                                      font_entity, pixel_size);
-      if (!synthItal)
-        [fontCache setObject: [NSNumber numberWithUnsignedLong:
-                                         (unsigned long) XHASH (font_object)]
-                     forKey: nsfont];
-    }
-
+  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)
-    return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */
+    {
+      unblock_input ();
+      return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */
+    }
 
   font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
   font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics);
 
-  BLOCK_INPUT;
-
   /* for metrics */
+#ifdef NS_IMPL_COCOA
+  sfont = [nsfont screenFontWithRenderingMode:
+                    NSFontAntialiasedIntegerAdvancementsRenderingMode];
+#else
   sfont = [nsfont screenFont];
+#endif
+
   if (sfont == nil)
     sfont = nsfont;
 
@@ -833,14 +823,12 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
   font = (struct font *) font_info;
   font->pixel_size = [sfont pointSize];
   font->driver = &nsfont_driver;
-  font->encoding_type = FONT_ENCODING_NOT_DECIDED;
   font->encoding_charset = -1;
   font->repertory_charset = -1;
   font->default_ascent = 0;
   font->vertical_centering = 0;
   font->baseline_offset = 0;
   font->relative_compose = 0;
-  font->font_encoder = NULL;
 
   font->props[FONT_FORMAT_INDEX] = Qns;
   font->props[FONT_FILE_INDEX] = Qnil;
@@ -881,16 +869,17 @@ nsfont_open (FRAME_PTR 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);
     font_info->max_bounds.lbearing = lrint (brect.origin.x);
     font_info->max_bounds.rbearing =
-      lrint (brect.size.width - font_info->width);
+      lrint (brect.size.width - (CGFloat) font_info->width);
 
 #ifdef NS_IMPL_COCOA
     /* set up synthItal and the CG font */
@@ -931,38 +920,38 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
     font->underline_thickness = lrint (font_info->underwidth);
 
     font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
-    font->props[FONT_FULLNAME_INDEX] =
-      make_unibyte_string (font_info->name, strlen (font_info->name));
+    font->props[FONT_FULLNAME_INDEX] = build_unibyte_string (font_info->name);
   }
-  UNBLOCK_INPUT;
+  unblock_input ();
 
   return font_object;
 }
 
 
-/* Close FONT on frame F. */
+/* Close FONT. */
 static void
-nsfont_close (FRAME_PTR f, struct font *font)
+nsfont_close (struct font *font)
 {
-  struct nsfont_info *font_info = (struct nsfont_info *)font;
-  int i;
-
-  /* FIXME: this occurs apparently due to same failure to detect same font
-            that causes need for cache in nsfont_open () */
-  if (!font_info)
-      return;
+  struct nsfont_info *font_info = (struct nsfont_info *) font;
 
-  for (i =0; i<0x100; i++)
+  /* FIXME: font_info may be NULL due to same failure to detect
+     same font that causes need for cache in nsfont_open.  */
+  if (font_info && font_info->name)
     {
-      xfree (font_info->glyphs[i]);
-      xfree (font_info->metrics[i]);
-    }
-  [font_info->nsfont release];
+      int i;
+
+      for (i = 0; i < 0x100; i++)
+       {
+         xfree (font_info->glyphs[i]);
+         xfree (font_info->metrics[i]);
+       }
+      [font_info->nsfont release];
 #ifdef NS_IMPL_COCOA
-  CGFontRelease (font_info->cgfont);
+      CGFontRelease (font_info->cgfont);
 #endif
-  xfree (font_info->name);
-  xfree (font_info);
+      xfree (font_info->name);
+      font_info->name = NULL;
+    }
 }
 
 
@@ -993,7 +982,7 @@ nsfont_encode_char (struct font *font, int c)
     ns_uni_to_glyphs (font_info, high);
 
   g = font_info->glyphs[high][low];
-  return g == 0xFFFF ? FONT_INVALID_CODE : g;
+  return g == INVALID_GLYPH ? FONT_INVALID_CODE : g;
 }
 
 
@@ -1042,17 +1031,17 @@ nsfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
 
 
 /* Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
-   position of frame F with S->FACE and S->GC.  If WITH_BACKGROUND
-   is nonzero, fill the background in advance.  It is assured that
-   WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars). */
+   position of frame F with S->FACE and S->GC.  If WITH_BACKGROUND,
+   fill the background in advance.  It is assured that WITH_BACKGROUND
+   is false when (FROM > 0 || TO < S->nchars). */
 static int
 nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
-             int with_background)
+             bool with_background)
 /* NOTE: focus and clip must be set
      also, currently assumed (true in nsterm.m call) from ==0, to ==nchars */
 {
-  static char cbuf[1024];
-  char *c = cbuf;
+  static unsigned char cbuf[1024];
+  unsigned char *c = cbuf;
 #ifdef NS_IMPL_GNUSTEP
   static float advances[1024];
   float *adv = advances;
@@ -1062,15 +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;
@@ -1185,7 +1185,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
           : FRAME_BACKGROUND_COLOR (s->f)) set];
       else
         {
-          struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (s->f);
+          struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
           [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
         }
       NSRectFill (br);
@@ -1198,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)));
@@ -1218,7 +1218,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
         [bgCol set];
         DPSmoveto (context, r.origin.x, r.origin.y);
 /*[context GSSetTextDrawingMode: GSTextFillStroke]; /// not implemented yet */
-        DPSxshow (context, cbuf, advances, len);
+        DPSxshow (context, (const char *) cbuf, advances, len);
         DPSstroke (context);
         [col set];
 /*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */
@@ -1228,7 +1228,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
 
     /* draw with DPSxshow () */
     DPSmoveto (context, r.origin.x, r.origin.y);
-    DPSxshow (context, cbuf, advances, len);
+    DPSxshow (context, (const char *) cbuf, advances, len);
     DPSstroke (context);
 
     DPSgrestore (context);
@@ -1249,7 +1249,9 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
 
     CGContextSaveGState (gcontext);
 
-    fliptf.c =  font->synthItal ? Fix2X (kATSItalicQDSkew) : 0.0;
+    // Used to be Fix2X (kATSItalicQDSkew), but Fix2X is deprecated
+    // and kATSItalicQDSkew is 0.25.
+    fliptf.c =  font->synthItal ? 0.25 : 0.0;
 
     CGContextSetFont (gcontext, font->cgfont);
     CGContextSetFontSize (gcontext, font->size);
@@ -1274,22 +1276,20 @@ 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;
 }
 
@@ -1318,7 +1318,7 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
     fprintf (stderr, "%p\tFinding glyphs for glyphs in block %d\n",
             font_info, block);
 
BLOCK_INPUT;
 block_input ();
 
 #ifdef NS_IMPL_COCOA
   if (firstTime)
@@ -1330,7 +1330,7 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
 
   font_info->glyphs[block] = xmalloc (0x100 * sizeof (unsigned short));
   if (!unichars || !(font_info->glyphs[block]))
-    abort ();
+    emacs_abort ();
 
   /* create a string containing all Unicode characters in this block */
   for (idx = block<<8, i = 0; i < 0x100; idx++, i++)
@@ -1364,8 +1364,8 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
 #else
         g = glyphStorage->cglyphs[i];
         /* TODO: is this a good check?  maybe need to use coveredChars.. */
-        if (g > numGlyphs)
-          g = 0xFFFF; /* hopefully unused... */
+        if (g > numGlyphs || g == NSNullGlyph)
+          g = INVALID_GLYPH; /* hopefully unused... */
 #endif
         *glyphs = g;
       }
@@ -1375,7 +1375,7 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
 #endif
   }
 
-  UNBLOCK_INPUT;
+  unblock_input ();
   xfree (unichars);
 }
 
@@ -1400,17 +1400,22 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
     numGlyphs = 0x10000;
 #endif
 
- BLOCK_INPUT;
- sfont = [font_info->nsfont screenFont];
+  block_input ();
+#ifdef NS_IMPL_COCOA
+  sfont = [font_info->nsfont screenFontWithRenderingMode:
+                      NSFontAntialiasedIntegerAdvancementsRenderingMode];
+#else
+  sfont = [font_info->nsfont screenFont];
+#endif
 
   font_info->metrics[block] = xzalloc (0x100 * sizeof (struct font_metrics));
   if (!(font_info->metrics[block]))
-    abort ();
+    emacs_abort ();
 
   metrics = font_info->metrics[block];
   for (g = block<<8, i =0; i<0x100 && g < numGlyphs; g++, i++, metrics++)
     {
-      float w, lb, rb;
+      CGFloat w, lb, rb;
       NSRect r = [sfont boundingRectForGlyph: g];
 
       w = max ([sfont advancementForGlyph: g].width, 2.0);
@@ -1418,18 +1423,19 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
 
       lb = r.origin.x;
       rb = r.size.width - w;
+      // Add to bearing for LCD smoothing.  We don't know if it is there.
       if (lb < 0)
-        metrics->lbearing = round (lb);
+        metrics->lbearing = round (lb - LCD_SMOOTHING_MARGIN);
       if (font_info->ital)
-        rb += 0.22 * font_info->height;
-      metrics->rbearing = lrint (w + rb);
+        rb += (CGFloat) (0.22F * font_info->height);
+      metrics->rbearing = lrint (w + rb + LCD_SMOOTHING_MARGIN);
 
       metrics->descent = r.origin.y < 0 ? -r.origin.y : 0;
  /*lrint (hshrink * [sfont ascender] + expand * hd/2); */
       metrics->ascent = r.size.height - metrics->descent;
 /*-lrint (hshrink* [sfont descender] - expand * hd/2); */
     }
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 
@@ -1487,7 +1493,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
         characterIndex: (NSUInteger)charIndex
 {
   len = glyphIndex+length;
-  for (i =glyphIndex; i<len; i++)
+  for (i =glyphIndex; i<len; i++) 
     cglyphs[i] = glyphs[i-glyphIndex];
   if (len > maxGlyph)
     maxGlyph = len;
@@ -1524,6 +1530,8 @@ syms_of_nsfont (void)
 {
   nsfont_driver.type = Qns;
   register_font_driver (&nsfont_driver, NULL);
+  DEFSYM (Qcondensed, "condensed");
+  DEFSYM (Qexpanded, "expanded");
   DEFSYM (Qapple, "apple");
   DEFSYM (Qroman, "roman");
   DEFSYM (Qmedium, "medium");