(x_set_alpha): Set alpha to -1 if nil given.
[bpt/emacs.git] / src / nsfont.m
index bbf991e..7adced7 100644 (file)
@@ -96,8 +96,8 @@ nsfont_get_family (Lisp_Object font_spec)
       char *tmp = strdup (SDATA (SYMBOL_NAME (tem)));
       NSString *family;
       nsfont_unescape_name (tmp);
-      /* PENDING: this seems to be needed only for font names that are
-         hard-coded into emacs, like 'helvetica' for splash screen */
+      /* TODO: this seems to be needed only for font names that are
+               hard-coded into emacs, like 'helvetica' for splash screen */
       if (tmp)
         tmp[0] = toupper (tmp[0]);
       family = [NSString stringWithUTF8String: tmp];
@@ -108,7 +108,7 @@ nsfont_get_family (Lisp_Object font_spec)
 
 
 /* Converts FONT_WEIGHT, FONT_SLANT, FONT_WIDTH to NSFont traits. */
-/* PENDING (20080601): The font backend's strategy for handling font
+/* TODO (20080601): The font backend's strategy for handling font
            styles continues to evolve.  When/if this stabilizes, we
            can change the code here to be more sophisticated and accurate.
            For now, we rely on "normal/plain" style being numeric 100. */
@@ -121,20 +121,18 @@ nsfont_spec_to_traits (Lisp_Object font_spec)
 
   n = FONT_WEIGHT_NUMERIC (font_spec);
   if (n != -1)
-      traits |= (n > STYLE_REF) ? NSBoldFontMask : NSUnboldFontMask;
+      traits |= (n > STYLE_REF) ? NSBoldFontMask
+                               : (n < STYLE_REF) ? NSUnboldFontMask : 0;
 
   n = FONT_SLANT_NUMERIC (font_spec);
   if (n != -1)
-      traits |= (n > STYLE_REF) ? NSItalicFontMask : NSUnitalicFontMask;
+      traits |= (n > STYLE_REF) ? NSItalicFontMask
+                               : (n < STYLE_REF) ? NSUnitalicFontMask : 0;
 
   n = FONT_WIDTH_NUMERIC (font_spec);
   if (n > -1)
-    {
-      if (n < STYLE_REF - 10)
-        traits |= NSCondensedFontMask;
-      else if (n > STYLE_REF + 10)
-        traits |= NSExpandedFontMask;
-    }
+      traits |= (n > STYLE_REF + 10) ? NSExpandedFontMask
+                                       : (n < STYLE_REF - 10) ? NSExpandedFontMask : 0;
 
 /*fprintf (stderr, "  returning traits = %u\n", traits); */
   return traits;
@@ -150,7 +148,7 @@ nsfont_fmember_to_entity (NSString *family, NSArray *famMember)
   unsigned int traits = [[famMember objectAtIndex: 3] unsignedIntValue];
 /*   NSString *psName = [famMember objectAtIndex: 0]; */
   NSMutableString *suffix = [[famMember objectAtIndex: 1] mutableCopy];
-  char *escapedFamily = [family UTF8String];
+  char *escapedFamily = strdup ([family UTF8String]);
 
   nsfont_escape_name (escapedFamily);
   [suffix replaceOccurrencesOfString: @" " withString: @"" options: 0
@@ -178,9 +176,10 @@ nsfont_fmember_to_entity (NSString *family, NSArray *famMember)
     {
       fprintf (stderr, "created font_entity:\n    ");
       debug_print (font_entity);
-     }
+    }
 
   [suffix release];
+  free (escapedFamily);
   return font_entity;
 }
 
@@ -189,12 +188,12 @@ nsfont_fmember_to_entity (NSString *family, NSArray *famMember)
 static int
 nsfont_trait_distance (unsigned int traits1, unsigned int traits2)
 {
-  int i, d =0;
-  for (i =0; i<sizeof (unsigned int)*8; i++)
+  int i, d = 0;
+  for (i = 0; i < sizeof (unsigned int) * 8; i++)
     {
       d += (traits1 & 0x1) ^ (traits2 & 0x1);
-      traits1 >> 1;
-      traits2 >> 1;
+      traits1 >>= 1;
+      traits2 >>= 1;
     }
   return d;
 }
@@ -266,7 +265,7 @@ nsfont_get_cache (FRAME_PTR frame)
 
 
 /* List fonts exactly matching with FONT_SPEC on FRAME.  The value
-   is a vector of font-entities.  This is the sole API that
+   is a **list** of font-entities.  This is the sole API that
    allocates font-entities.  */
 static Lisp_Object
 nsfont_list (Lisp_Object frame, Lisp_Object font_spec)
@@ -348,7 +347,7 @@ nsfont_list (Lisp_Object frame, Lisp_Object font_spec)
   if (NSFONT_TRACE)
       fprintf (stderr, "    Returning %d entities.\n", XINT (Flength (list)));
 
-  return (NILP (list) ? Qnil : Fvconcat (1, &list));/* Qnil was null_vector */
+  return list;
 }
 
 
@@ -376,7 +375,7 @@ nsfont_match (Lisp_Object frame, Lisp_Object font_spec)
     fprintf (stderr, "adstyle: '%s'\n", SDATA (tem));
 #endif
   tem = AREF (font_spec, FONT_REGISTRY_INDEX);
-  if (!EQ (tem, Qiso10646_1) && !EQ (tem, Qunicode_bmp))
+  if (!NILP (tem) && !EQ (tem, Qiso10646_1) && !EQ (tem, Qunicode_bmp))
     return nsfont_fallback_entity ();
 
   family = nsfont_get_family (font_spec);
@@ -412,7 +411,7 @@ nsfont_match (Lisp_Object frame, Lisp_Object font_spec)
     if (fontNames && [fontNames count]  > 0)
       {
         NSString *fontName = [fontNames objectAtIndex: 0];
-        /*PENDING: is there a more efficient way to get family name? */
+        /* XXX: is there a more efficient way to get family name? */
         NSFont *font = [NSFont fontWithName: fontName size: 0];
         if (font != nil)
           {
@@ -452,7 +451,7 @@ nsfont_list_family (Lisp_Object frame)
   NSString *family;
   while (family = [families nextObject])
       list = Fcons (intern ([family UTF8String]), list);
-  /*PENDING: escape the name? */
+  /* FIXME: escape the name? */
 
   if (NSFONT_TRACE)
     fprintf (stderr, "nsfont: list families returning %d entries\n",
@@ -499,26 +498,17 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
   Lisp_Object font_object;
   int i;
   int fixLeopardBug;
-#if 0
   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.
-     2008/06/01: This is still an issue, but after font backend refactoring
-     caching will be more difficult, needs to be reworked before enabling. */
+     2008/06/01: This is still an issue after font backend refactoring. */
   if (fontCache == nil)
     fontCache = [[NSMutableDictionary alloc] init];
-#endif
-
-  font_object = font_make_object (VECSIZE (struct nsfont_info), font_entity,
-                                  pixel_size);
-  font_info = (struct nsfont_info *) XFONT_OBJECT (font_object);
-  font = (struct font *)font_info;
-  if (!font)
-    return Qnil; /*PENDING: this copies w32, but causes a segfault */
 
   if (NSFONT_TRACE)
     {
@@ -539,8 +529,9 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
   family = nsfont_get_family (font_entity);
   if (NSFONT_TRACE)
     {
-      fprintf (stderr, "family: '%s'\ttraits = %ld\tbold = %d\n",
-               [family UTF8String], traits, traits & NSBoldFontMask);
+      fprintf (stderr, "family: '%s'\ttraits = %ld\tbold = %d\titalic = %d\n",
+               [family UTF8String], traits, traits & NSBoldFontMask,
+               traits & NSItalicFontMask);
     }
 
   /* see http://cocoadev.com/forums/comments.php?DiscussionID =74 */
@@ -575,38 +566,43 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
         }
     }
 
-#if 0
-  {
-    NSNumber *cached = [fontCache objectForKey: nsfont];
-    if (cached != nil && !synthItal)
-      {
-fprintf (stderr, "*** CACHE HIT!\n");
-        struct font_info *existing =
-          (struct nsfont_info *)[cached unsignedLongValue];
-        /* ... */
-      }
-    else
-      {
-        if (!synthItal)
-          [fontCache
-            setObject: [NSNumber numberWithUnsignedLong:
-                                   (unsigned long)font_info]
-               forKey: nsfont];
-      }
-  }
-#endif
+  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");
+      return (Lisp_Object)[cached unsignedLongValue];
+    }
+  else
+    {
+      font_object = font_make_object (VECSIZE (struct nsfont_info),
+                                      font_entity, pixel_size);
+      if (!synthItal)
+        [fontCache
+          setObject: [NSNumber numberWithUnsignedLong:
+                                 (unsigned long)font_object]
+          forKey: nsfont];
+    }
+
+  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 */
 
-  font_info->glyphs = (unsigned short *)
+  font_info->glyphs = (unsigned short **)
     xmalloc (0x100 * sizeof (unsigned short *));
-  font_info->metrics = (struct font_metrics *)
+  font_info->metrics = (struct font_metrics **)
     xmalloc (0x100 * sizeof (struct font_metrics *));
   if (!font_info->glyphs || !font_info->metrics)
     return Qnil;
   bzero (font_info->glyphs, 0x100 * sizeof (unsigned short *));
   bzero (font_info->metrics, 0x100 * sizeof (struct font_metrics *));
 
-
-BLOCK_INPUT;
+  BLOCK_INPUT;
 
   /* for metrics */
   sfont = [nsfont screenFont];
@@ -626,7 +622,7 @@ BLOCK_INPUT;
   font->relative_compose = 0;
   font->font_encoder = NULL;
 
-  /*PENDING: does anything care about this? */
+  /* TODO: does anything care about this? */
   font->props[FONT_FORMAT_INDEX] = Qns;
   font->props[FONT_FILE_INDEX] = Qnil;
 
@@ -722,7 +718,7 @@ BLOCK_INPUT;
     /* set up metrics portion of font struct */
     font->ascent = [sfont ascender];
     font->descent = -[sfont descender];
-    font->min_width = [sfont widthOfString: @"|"]; /* PENDING */
+    font->min_width = [sfont widthOfString: @"|"]; /* FIXME */
     font->space_width = lrint (nsfont_char_width (sfont, ' '));
     font->average_width = lrint (font_info->width);
     font->max_width = lrint (font_info->max_bounds.width);
@@ -747,9 +743,9 @@ nsfont_close (FRAME_PTR f, struct font *font)
   struct nsfont_info *font_info = (struct nsfont_info *)font;
   int i;
 
-  /* PENDING: this occurs apparently due to same failure to detect same font
-     that causes need for cache in nsfont_open ()
-     (came after unicode-2 -> trunk) */
+  /* FIXME: this occurs apparently due to same failure to detect same font
+            that causes need for cache in nsfont_open ()
+            (came after unicode-2 -> trunk) */
   if (!font_info)
       return;
 
@@ -819,8 +815,8 @@ nsfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
   for (i =0; i<nglyphs; i++)
     {
       /* get metrics for this glyph, filling cache if need be */
-      /* PENDING: get metrics for whole string from an NSLayoutManager
-                 (if not too slow) */
+      /* TODO: get metrics for whole string from an NSLayoutManager
+               (if not too slow) */
       high = (code[i] & 0xFF00) >> 8;
       low = code[i] & 0x00FF;
       if (!font_info->metrics[high])
@@ -901,20 +897,20 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
     XCharStruct *cs;
     int cwidth, twidth = 0;
     int hi, lo;
-    char isComposite = 0; /* s->first_glyph->type == COMPOSITE_GLYPH; */
-    /* PENDING: composition: no vertical displacement is considered. */
-    t+= s->gidx; /* advance into composition */
-    for (i =0; i<s->nchars - s->gidx; i++, t++)
+    char isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
+    /* FIXME: composition: no vertical displacement is considered. */
+    t += s->cmp_from; /* advance into composition */
+    for (i = s->cmp_from; i < s->nchars; i++, t++)
       {
         hi = (*t & 0xFF00) >> 8;
         lo = *t & 0x00FF;
         if (isComposite)
           {
-            cwidth = s->cmp->offsets[s->gidx++ * 2] - twidth;
+            cwidth = s->cmp->offsets[i * 2] /* (H offset) */ - twidth;
           }
         else
           {
-            if (!font->metrics[hi]) /*PENDING: why/how can we need this now? */
+            if (!font->metrics[hi]) /* FIXME: why/how can we need this now? */
               ns_glyph_metrics (font, hi);
             cwidth = font->metrics[hi][lo].width;
           }
@@ -968,7 +964,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
         }
 
       if (!s->face->stipple)
-        [(NS_FACE_BACKGROUND (face) != nil
+        [(NS_FACE_BACKGROUND (face) != 0
           ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
           : FRAME_BACKGROUND_COLOR (s->f)) set];
       else
@@ -983,12 +979,12 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
   /* set up for character rendering */
   r.origin.y += font->voffset + (s->height - font->height)/2;
 
-  col = (NS_FACE_FOREGROUND (face) != nil
+  col = (NS_FACE_FOREGROUND (face) != 0
          ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f)
          : FRAME_FOREGROUND_COLOR (s->f));
-  /*PENDING: find another way to pass this */
+  /* FIXME: find another way to pass this */
   bgCol = (ns_tmp_flags != NS_DUMPGLYPH_FOREGROUND ? nil
-           : (NS_FACE_BACKGROUND (face) != nil
+           : (NS_FACE_BACKGROUND (face) != 0
               ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
               : FRAME_BACKGROUND_COLOR (s->f)));
 
@@ -1015,13 +1011,13 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
     /* do underline */
     if (face->underline_p)
       {
-        if (face->underline_color != nil)
+        if (face->underline_color != 0)
           [ns_lookup_indexed_color (face->underline_color, s->f) set];
         else
           [col set];
         DPSmoveto (context, r.origin.x, r.origin.y + font->underpos);
         DPSlineto (context, r.origin.x+r.size.width, r.origin.y+font->underpos);
-        if (face->underline_color != nil)
+        if (face->underline_color != 0)
           [col set];
       }
     else
@@ -1059,7 +1055,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
       CGContextSetShouldAntialias (gcontext, 0);
     else
       CGContextSetShouldAntialias (gcontext, 1);
-    if (ns_use_qd_smoothing)
+    if (EQ (ns_use_qd_smoothing, Qt))
       CGContextSetFontRenderingMode (gcontext, 2); /* 0 is Cocoa, 2 is QD */
 
     CGContextSetTextMatrix (gcontext, fliptf);
@@ -1076,7 +1072,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
 
     if (face->underline_p)
       {
-        if (face->underline_color != nil)
+        if (face->underline_color != 0)
           [ns_lookup_indexed_color (face->underline_color, s->f) set];
         else
           [col set];
@@ -1086,20 +1082,20 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
         CGContextAddLineToPoint (gcontext, r.origin.x + r.size.width,
                                 r.origin.y + font->underpos);
         CGContextStrokePath (gcontext);
-        if (face->underline_color != nil)
+        if (face->underline_color != 0)
           [col set];
       }
     else
       [col set];
 
     CGContextSetTextPosition (gcontext, r.origin.x, r.origin.y);
-    CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->gidx,
+    CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->cmp_from,
                                     advances, len);
 
     if (face->overstrike)
       {
         CGContextSetTextPosition (gcontext, r.origin.x+0.5, r.origin.y);
-        CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->gidx,
+        CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->cmp_from,
                                         advances, len);
       }
 
@@ -1226,7 +1222,7 @@ void nsfont_make_fontset_for_font (Lisp_Object name, Lisp_Object font_object)
 
         if (cfont != nil)
           {
-            char *family = [[cfont familyName] UTF8String];
+            char *family = strdup([[cfont familyName] UTF8String]);
             Lisp_Object famAndReg;
 
             nsfont_escape_name (family);
@@ -1238,6 +1234,7 @@ void nsfont_make_fontset_for_font (Lisp_Object name, Lisp_Object font_object)
                        SDATA (SYMBOL_NAME (scripts[i])));
 
             Fset_fontset_font (name, scripts[i], famAndReg, Qnil, Qnil);
+            free (family);
           }
         else
           {
@@ -1318,7 +1315,7 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
         g = unichars[i];
 #else
         g = glyphStorage->cglyphs[i];
-        /*PENDING: is this a good check?  maybe need to use coveredChars.. */
+        /* TODO: is this a good check?  maybe need to use coveredChars.. */
         if (g > numGlyphs)
           g = 0xFFFF; /* hopefully unused... */
 #endif