]> code.delx.au - gnu-emacs/blobdiff - src/macfont.m
Use eldoc-documentation-functions
[gnu-emacs] / src / macfont.m
index 23d272c91298ced6a76c12c9a6dfe072e6c89c81..c799100c8550823ac84311d5eae0f2f0c9474bec 100644 (file)
@@ -1,12 +1,12 @@
 /* Font driver on Mac OSX Core text.
-   Copyright (C) 2009-2015 Free Software Foundation, Inc.
+   Copyright (C) 2009-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -190,6 +190,14 @@ cfstring_create_with_string_noencode (Lisp_Object s)
   return string;
 }
 
+static CFIndex
+mac_font_get_weight (CTFontRef font)
+{
+  NSFont *nsFont = (NSFont *) font;
+
+  return [[NSFontManager sharedFontManager] weightOfFont:nsFont];
+}
+
 static CGFloat
 mac_screen_font_get_advance_width_for_glyph (ScreenFontRef font, CGGlyph glyph)
 {
@@ -198,57 +206,53 @@ mac_screen_font_get_advance_width_for_glyph (ScreenFontRef font, CGGlyph glyph)
   return advancement.width;
 }
 
+#if !USE_CT_GLYPH_INFO
 static CGGlyph
 mac_font_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
                             CGFontIndex cid)
 {
-#if USE_CT_GLYPH_INFO
-  return mac_ctfont_get_glyph_for_cid ((CTFontRef) font, collection, cid);
-#else
-  {
-    CGGlyph result = kCGFontIndexInvalid;
-    NSFont *nsFont = (NSFont *) font;
-    unichar characters[] = {0xfffd};
-    NSString *string =
-      [NSString stringWithCharacters:characters
-                              length:ARRAYELTS (characters)];
-    NSGlyphInfo *glyphInfo =
-      [NSGlyphInfo glyphInfoWithCharacterIdentifier:cid
-                                         collection:collection
-                                         baseString:string];
-    NSDictionary *attributes =
-      [NSDictionary dictionaryWithObjectsAndKeys:nsFont,NSFontAttributeName,
-                    glyphInfo,NSGlyphInfoAttributeName,nil];
-    NSTextStorage *textStorage =
-      [[NSTextStorage alloc] initWithString:string
-                                 attributes:attributes];
-    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
-    NSTextContainer *textContainer = [[NSTextContainer alloc] init];
-    NSFont *fontInTextStorage;
-
-    [layoutManager addTextContainer:textContainer];
-    [textContainer release];
-    [textStorage addLayoutManager:layoutManager];
-    [layoutManager release];
-
-    /* Force layout.  */
-    (void) [layoutManager glyphRangeForTextContainer:textContainer];
-
-    fontInTextStorage = [textStorage attribute:NSFontAttributeName atIndex:0
-                                effectiveRange:NULL];
-    if (fontInTextStorage == nsFont
-        || [[fontInTextStorage fontName] isEqualToString:[nsFont fontName]])
-      {
-        NSGlyph glyph = [layoutManager glyphAtIndex:0];
+  CGGlyph result = kCGFontIndexInvalid;
+  NSFont *nsFont = (NSFont *) font;
+  unichar characters[] = {0xfffd};
+  NSString *string =
+    [NSString stringWithCharacters:characters
+                           length:ARRAYELTS (characters)];
+  NSGlyphInfo *glyphInfo =
+    [NSGlyphInfo glyphInfoWithCharacterIdentifier:cid
+                                      collection:collection
+                                      baseString:string];
+  NSDictionary *attributes =
+    [NSDictionary dictionaryWithObjectsAndKeys:nsFont,NSFontAttributeName,
+                 glyphInfo,NSGlyphInfoAttributeName,nil];
+  NSTextStorage *textStorage =
+    [[NSTextStorage alloc] initWithString:string
+                              attributes:attributes];
+  NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
+  NSTextContainer *textContainer = [[NSTextContainer alloc] init];
+  NSFont *fontInTextStorage;
 
-        if (glyph < [nsFont numberOfGlyphs])
-          result = glyph;
-      }
+  [layoutManager addTextContainer:textContainer];
+  [textContainer release];
+  [textStorage addLayoutManager:layoutManager];
+  [layoutManager release];
 
-    [textStorage release];
+  /* Force layout.  */
+  (void) [layoutManager glyphRangeForTextContainer:textContainer];
 
-    return result;
-  }
+  fontInTextStorage = [textStorage attribute:NSFontAttributeName atIndex:0
+                             effectiveRange:NULL];
+  if (fontInTextStorage == nsFont
+      || [[fontInTextStorage fontName] isEqualToString:[nsFont fontName]])
+    {
+      NSGlyph glyph = [layoutManager glyphAtIndex:0];
+
+      if (glyph < [nsFont numberOfGlyphs])
+       result = glyph;
+    }
+
+  [textStorage release];
+
+  return result;
 }
 #endif
 
@@ -762,6 +766,37 @@ cfnumber_get_font_symbolic_traits_value (CFNumberRef number,
   return false;
 }
 
+static CGFloat
+mac_font_descriptor_get_adjusted_weight (CTFontDescriptorRef desc, CGFloat val)
+{
+  long percent_val = lround (val * 100);
+
+  if (percent_val == -40)
+    {
+      CTFontRef font = NULL;
+      CFStringRef name =
+       CTFontDescriptorCopyAttribute (desc, kCTFontNameAttribute);
+
+      if (name)
+       {
+         font = CTFontCreateWithName (name, 0, NULL);
+         CFRelease (name);
+       }
+      if (font)
+       {
+         CFIndex weight = mac_font_get_weight (font);
+
+         /* Workaround for crash when displaying Oriya characters
+            with Arial Unicode MS on OS X 10.11.  */
+         if (weight == 5)
+           val = 0;
+         CFRelease (font);
+       }
+    }
+
+  return val;
+}
+
 static void
 macfont_store_descriptor_attributes (CTFontDescriptorRef desc,
                                      Lisp_Object spec_or_entity)
@@ -785,6 +820,7 @@ macfont_store_descriptor_attributes (CTFontDescriptorRef desc,
         enum font_property_index index;
         CFStringRef trait;
         CGPoint points[6];
+       CGFloat (*adjust_func) (CTFontDescriptorRef, CGFloat);
       } numeric_traits[] =
           {{FONT_WEIGHT_INDEX, kCTFontWeightTrait,
             {{-0.4, 50},       /* light */
@@ -792,11 +828,12 @@ macfont_store_descriptor_attributes (CTFontDescriptorRef desc,
              {0, 100},         /* normal */
              {0.24, 140},      /* (semi-bold + normal) / 2 */
              {0.4, 200},       /* bold */
-             {CGFLOAT_MAX, CGFLOAT_MAX}}},
+             {CGFLOAT_MAX, CGFLOAT_MAX}},
+           mac_font_descriptor_get_adjusted_weight},
            {FONT_SLANT_INDEX, kCTFontSlantTrait,
-            {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}},
+            {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}, NULL},
            {FONT_WIDTH_INDEX, kCTFontWidthTrait,
-            {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}};
+            {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}, NULL}};
       int i;
 
       for (i = 0; i < ARRAYELTS (numeric_traits); i++)
@@ -806,6 +843,8 @@ macfont_store_descriptor_attributes (CTFontDescriptorRef desc,
             {
               CGPoint *point = numeric_traits[i].points;
 
+             if (numeric_traits[i].adjust_func)
+               floatval = (*numeric_traits[i].adjust_func) (desc, floatval);
               while (point->x < floatval)
                 point++;
               if (point == numeric_traits[i].points)
@@ -945,13 +984,7 @@ macfont_set_family_cache (Lisp_Object symbol, CFStringRef string)
   Lisp_Object value;
 
   if (!HASH_TABLE_P (macfont_family_cache))
-    {
-      Lisp_Object args[2];
-
-      args[0] = QCtest;
-      args[1] = Qeq;
-      macfont_family_cache = Fmake_hash_table (2, args);
-    }
+    macfont_family_cache = CALLN (Fmake_hash_table, QCtest, Qeq);
 
   h = XHASH_TABLE (macfont_family_cache);
   i = hash_lookup (h, symbol, &hash);
@@ -2340,9 +2373,9 @@ macfont_list (struct frame *f, Lisp_Object spec)
                   != (spacing >= FONT_SPACING_MONO)))
             continue;
 
-          /* Don't use a color bitmap font unless its family is
-             explicitly specified.  */
-          if ((sym_traits & kCTFontTraitColorGlyphs) && NILP (family))
+          /* Don't use a color bitmap font until it is supported on
+            free platforms.  */
+          if (sym_traits & kCTFontTraitColorGlyphs)
             continue;
 
           if (j > 0
@@ -2723,7 +2756,6 @@ macfont_has_char (Lisp_Object font, int c)
 static unsigned
 macfont_encode_char (struct font *font, int c)
 {
-  struct macfont_info *macfont_info = (struct macfont_info *) font;
   CGGlyph glyph;
 
   block_input ();
@@ -2824,7 +2856,8 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
     {
       if (s->hl == DRAW_MOUSE_FACE)
         {
-          face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
+          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);
         }
@@ -3385,18 +3418,24 @@ mac_font_descriptor_supports_languages (CTFontDescriptorRef descriptor,
     result = false;
   else
     {
-      CFIndex desc_languages_count, i, languages_count;
+      CFRange range = CFRangeMake (0, CFArrayGetCount (desc_languages));
+      CFIndex i, languages_count = CFArrayGetCount (languages);
 
-      desc_languages_count = CFArrayGetCount (desc_languages);
-      languages_count = CFArrayGetCount (languages);
       for (i = 0; i < languages_count; i++)
-        if (!CFArrayContainsValue (desc_languages,
-                                   CFRangeMake (0, desc_languages_count),
-                                   CFArrayGetValueAtIndex (languages, i)))
-          {
-            result = false;
-            break;
-          }
+       {
+         CFStringRef language = CFArrayGetValueAtIndex (languages, i);
+
+         if (!CFArrayContainsValue (desc_languages, range, language)
+             /* PingFang SC contains "zh" and "zh-Hant" as covered
+                languages, but does not contain "zh-Hans".  */
+             && !(CFEqual (language, CFSTR ("zh-Hans"))
+                  && CFArrayContainsValue (desc_languages, range,
+                                           CFSTR ("zh"))))
+           {
+             result = false;
+             break;
+           }
+       }
       CFRelease (desc_languages);
     }
 
@@ -3728,6 +3767,7 @@ mac_font_shape (CTFontRef font, CFStringRef string,
             {
               struct mac_glyph_layout *gl;
               CGPoint position;
+             CGFloat max_x;
 
               if (!RIGHT_TO_LEFT_P)
                 gl = glbuf + range.location;
@@ -3749,12 +3789,13 @@ mac_font_shape (CTFontRef font, CFStringRef string,
               CTRunGetGlyphs (ctrun, range, &gl->glyph_id);
 
               CTRunGetPositions (ctrun, range, &position);
+             max_x = position.x + CTRunGetTypographicBounds (ctrun, range,
+                                                             NULL, NULL, NULL);
+             max_x = max (max_x, total_advance);
               gl->advance_delta = position.x - total_advance;
               gl->baseline_delta = position.y;
-              gl->advance = (gl->advance_delta
-                             + CTRunGetTypographicBounds (ctrun, range,
-                                                          NULL, NULL, NULL));
-              total_advance += gl->advance;
+              gl->advance = max_x - total_advance;
+              total_advance = max_x;
             }
 
           if (RIGHT_TO_LEFT_P)
@@ -4004,8 +4045,6 @@ mac_register_font_driver (struct frame *f)
 void
 syms_of_macfont (void)
 {
-  static struct font_driver mac_font_driver;
-
   /* Core Text, for Mac OS X.  */
   DEFSYM (Qmac_ct, "mac-ct");
   macfont_driver.type = Qmac_ct;