aboutsummaryrefslogtreecommitdiffstats
path: root/src/nsfont.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/nsfont.m')
-rw-r--r--src/nsfont.m105
1 files changed, 39 insertions, 66 deletions
diff --git a/src/nsfont.m b/src/nsfont.m
index 76c70aadf9f..9aa7b0865ab 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -1,6 +1,6 @@
1/* Font back-end driver for the NeXT/Open/GNUstep and MacOSX window system. 1/* Font back-end driver for the NeXT/Open/GNUstep and MacOSX window system.
2 See font.h 2 See font.h
3 Copyright (C) 2006-2011 Free Software Foundation, Inc. 3 Copyright (C) 2006-2012 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -126,8 +126,8 @@ ns_attribute_fvalue (NSFontDescriptor *fdesc, NSString *trait)
126/* Converts FONT_WEIGHT, FONT_SLANT, FONT_WIDTH, plus family and script/lang 126/* Converts FONT_WEIGHT, FONT_SLANT, FONT_WIDTH, plus family and script/lang
127 to NSFont descriptor. Information under extra only needed for matching. */ 127 to NSFont descriptor. Information under extra only needed for matching. */
128#define STYLE_REF 100 128#define STYLE_REF 100
129static NSFontDescriptor 129static NSFontDescriptor *
130*ns_spec_to_descriptor(Lisp_Object font_spec) 130ns_spec_to_descriptor (Lisp_Object font_spec)
131{ 131{
132 NSFontDescriptor *fdesc; 132 NSFontDescriptor *fdesc;
133 NSMutableDictionary *fdAttrs = [NSMutableDictionary new]; 133 NSMutableDictionary *fdAttrs = [NSMutableDictionary new];
@@ -152,8 +152,13 @@ static NSFontDescriptor
152 [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute]; 152 [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
153 153
154 fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]; 154 fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs];
155 if (family != nil) 155 if (family != nil)
156 {
156 fdesc = [fdesc fontDescriptorWithFamily: family]; 157 fdesc = [fdesc fontDescriptorWithFamily: family];
158 }
159
160 [fdAttrs release];
161 [tdict release];
157 return fdesc; 162 return fdesc;
158} 163}
159 164
@@ -256,7 +261,7 @@ ns_char_width (NSFont *sfont, int c)
256 261
257 262
258/* Return whether set1 covers set2 to a reasonable extent given by pct. 263/* Return whether set1 covers set2 to a reasonable extent given by pct.
259 We check, out of each 16 unicode char range containing chars in set2, 264 We check, out of each 16 Unicode char range containing chars in set2,
260 whether at least one character is present in set1. 265 whether at least one character is present in set1.
261 This must be true for pct of the pairs to consider it covering. */ 266 This must be true for pct of the pairs to consider it covering. */
262static BOOL 267static BOOL
@@ -297,13 +302,13 @@ static NSString
297 302
298 303
299/* Convert OTF 4-letter script code to emacs script name. (Why can't 304/* Convert OTF 4-letter script code to emacs script name. (Why can't
300 everyone just use some standard unicode names for these?) */ 305 everyone just use some standard Unicode names for these?) */
301static NSString 306static NSString
302*ns_otf_to_script (Lisp_Object otf) 307*ns_otf_to_script (Lisp_Object otf)
303{ 308{
304 Lisp_Object script = assq_no_quit (XCAR (otf), Votf_script_alist); 309 Lisp_Object script = assq_no_quit (XCAR (otf), Votf_script_alist);
305 return CONSP (script) 310 return CONSP (script)
306 ? [NSString stringWithUTF8String: SDATA (SYMBOL_NAME XCDR ((script)))] 311 ? [NSString stringWithUTF8String: SDATA (SYMBOL_NAME (XCDR ((script))))]
307 : @""; 312 : @"";
308} 313}
309 314
@@ -329,7 +334,7 @@ static NSString
329 334
330/* Searches the :script, :lang, and :otf extra-bundle properties of the spec, 335/* Searches the :script, :lang, and :otf extra-bundle properties of the spec,
331 plus registry regular property, for something that can be mapped to a 336 plus registry regular property, for something that can be mapped to a
332 unicode script. Empty string returned if no script spec found. */ 337 Unicode script. Empty string returned if no script spec found. */
333static NSString 338static NSString
334*ns_get_req_script (Lisp_Object font_spec) 339*ns_get_req_script (Lisp_Object font_spec)
335{ 340{
@@ -385,7 +390,7 @@ accumulate_script_ranges (Lisp_Object arg, Lisp_Object range, Lisp_Object val)
385} 390}
386 391
387 392
388/* Use the unicode range information in Vchar_script_table to convert a script 393/* Use the Unicode range information in Vchar_script_table to convert a script
389 name into an NSCharacterSet. */ 394 name into an NSCharacterSet. */
390static NSCharacterSet 395static NSCharacterSet
391*ns_script_to_charset (NSString *scriptName) 396*ns_script_to_charset (NSString *scriptName)
@@ -426,7 +431,7 @@ static NSCharacterSet
426 If none are found, we reduce the percentage and try again, until 5%. 431 If none are found, we reduce the percentage and try again, until 5%.
427 This provides a font with at least some characters if such can be found. 432 This provides a font with at least some characters if such can be found.
428 We don't use isSupersetOfSet: because (a) it doesn't work on Tiger, and 433 We don't use isSupersetOfSet: because (a) it doesn't work on Tiger, and
429 (b) need approximate match as fonts covering full unicode ranges are rare. */ 434 (b) need approximate match as fonts covering full Unicode ranges are rare. */
430static NSSet 435static NSSet
431*ns_get_covering_families (NSString *script, float pct) 436*ns_get_covering_families (NSString *script, float pct)
432{ 437{
@@ -469,6 +474,7 @@ static NSSet
469 if ([families count] > 0 || pct < 0.05) 474 if ([families count] > 0 || pct < 0.05)
470 break; 475 break;
471 } 476 }
477 [charset release];
472 } 478 }
473#ifdef NS_IMPL_COCOA 479#ifdef NS_IMPL_COCOA
474 if ([families count] == 0) 480 if ([families count] == 0)
@@ -536,12 +542,14 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
536 family = [fdesc objectForKey: NSFontFamilyAttribute]; 542 family = [fdesc objectForKey: NSFontFamilyAttribute];
537 if (family != nil && !foundItal && XINT (Flength (list)) > 0) 543 if (family != nil && !foundItal && XINT (Flength (list)) > 0)
538 { 544 {
539 NSFontDescriptor *sDesc = [[[NSFontDescriptor new] 545 NSFontDescriptor *s1 = [NSFontDescriptor new];
540 fontDescriptorWithSymbolicTraits: NSFontItalicTrait] 546 NSFontDescriptor *sDesc
541 fontDescriptorWithFamily: family]; 547 = [[s1 fontDescriptorWithSymbolicTraits: NSFontItalicTrait]
548 fontDescriptorWithFamily: family];
542 list = Fcons (ns_descriptor_to_entity (sDesc, 549 list = Fcons (ns_descriptor_to_entity (sDesc,
543 AREF (font_spec, FONT_EXTRA_INDEX), 550 AREF (font_spec, FONT_EXTRA_INDEX),
544 "synthItal"), list); 551 "synthItal"), list);
552 [s1 release];
545 } 553 }
546 554
547 /* Return something if was a match and nothing found. */ 555 /* Return something if was a match and nothing found. */
@@ -630,7 +638,7 @@ nsfont_list (Lisp_Object frame, Lisp_Object font_spec)
630} 638}
631 639
632 640
633/* Return a font entity most closely maching with FONT_SPEC on 641/* Return a font entity most closely matching with FONT_SPEC on
634 FRAME. The closeness is determined by the font backend, thus 642 FRAME. The closeness is determined by the font backend, thus
635 `face-font-selection-order' is ignored here. 643 `face-font-selection-order' is ignored here.
636 Properties to be considered are same as for list(). */ 644 Properties to be considered are same as for list(). */
@@ -804,8 +812,6 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
804 font->props[FONT_FILE_INDEX] = Qnil; 812 font->props[FONT_FILE_INDEX] = Qnil;
805 813
806 { 814 {
807 double expand, hshrink;
808 float full_height, min_height, hd;
809 const char *fontName = [[nsfont fontName] UTF8String]; 815 const char *fontName = [[nsfont fontName] UTF8String];
810 int len = strlen (fontName); 816 int len = strlen (fontName);
811 817
@@ -837,26 +843,16 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
837 [sfont maximumAdvancement].width : ns_char_width (sfont, '0'); 843 [sfont maximumAdvancement].width : ns_char_width (sfont, '0');
838 844
839 brect = [sfont boundingRectForFont]; 845 brect = [sfont boundingRectForFont];
840 full_height = brect.size.height;
841 min_height = [sfont ascender] - adjusted_descender;
842 hd = full_height - min_height;
843
844 /* standard height, similar to Carbon. Emacs.app: was 0.5 by default. */
845 expand = 0.0;
846 hshrink = 1.0;
847 846
848 font_info->underpos = 2; /*[sfont underlinePosition] is often clipped out */ 847 font_info->underpos = [sfont underlinePosition];
849 font_info->underwidth = [sfont underlineThickness]; 848 font_info->underwidth = [sfont underlineThickness];
850 font_info->size = font->pixel_size; 849 font_info->size = font->pixel_size;
851 font_info->voffset = lrint (hshrink * [sfont ascender] + expand * hd / 2);
852 850
853 /* max bounds */ 851 /* max bounds */
854 font_info->max_bounds.ascent = 852 font_info->max_bounds.ascent = lrint ([sfont ascender]);
855 lrint (hshrink * [sfont ascender] + expand * hd/2);
856 /* Descender is usually negative. Use floor to avoid 853 /* Descender is usually negative. Use floor to avoid
857 clipping descenders. */ 854 clipping descenders. */
858 font_info->max_bounds.descent = 855 font_info->max_bounds.descent = -lrint (floor(adjusted_descender));
859 -lrint (floor(hshrink* adjusted_descender - expand*hd/2));
860 font_info->height = 856 font_info->height =
861 font_info->max_bounds.ascent + font_info->max_bounds.descent; 857 font_info->max_bounds.ascent + font_info->max_bounds.descent;
862 font_info->max_bounds.width = lrint (font_info->width); 858 font_info->max_bounds.width = lrint (font_info->width);
@@ -1165,7 +1161,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1165 1161
1166 1162
1167 /* set up for character rendering */ 1163 /* set up for character rendering */
1168 r.origin.y += font->voffset + (s->height - font->height)/2; 1164 r.origin.y = s->ybase;
1169 1165
1170 col = (NS_FACE_FOREGROUND (face) != 0 1166 col = (NS_FACE_FOREGROUND (face) != 0
1171 ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f) 1167 ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f)
@@ -1196,20 +1192,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1196/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */ 1192/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */
1197 } 1193 }
1198 1194
1199 /* do underline */ 1195 [col set];
1200 if (face->underline_p)
1201 {
1202 if (face->underline_color != 0)
1203 [ns_lookup_indexed_color (face->underline_color, s->f) set];
1204 else
1205 [col set];
1206 DPSmoveto (context, r.origin.x, r.origin.y + font->underpos);
1207 DPSlineto (context, r.origin.x+r.size.width, r.origin.y+font->underpos);
1208 if (face->underline_color != 0)
1209 [col set];
1210 }
1211 else
1212 [col set];
1213 1196
1214 /* draw with DPSxshow () */ 1197 /* draw with DPSxshow () */
1215 DPSmoveto (context, r.origin.x, r.origin.y); 1198 DPSmoveto (context, r.origin.x, r.origin.y);
@@ -1255,23 +1238,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1255 CGContextSetTextDrawingMode (gcontext, kCGTextFill); 1238 CGContextSetTextDrawingMode (gcontext, kCGTextFill);
1256 } 1239 }
1257 1240
1258 if (face->underline_p) 1241 [col set];
1259 {
1260 if (face->underline_color != 0)
1261 [ns_lookup_indexed_color (face->underline_color, s->f) set];
1262 else
1263 [col set];
1264 CGContextBeginPath (gcontext);
1265 CGContextMoveToPoint (gcontext,
1266 r.origin.x, r.origin.y + font->underpos);
1267 CGContextAddLineToPoint (gcontext, r.origin.x + r.size.width,
1268 r.origin.y + font->underpos);
1269 CGContextStrokePath (gcontext);
1270 if (face->underline_color != 0)
1271 [col set];
1272 }
1273 else
1274 [col set];
1275 1242
1276 CGContextSetTextPosition (gcontext, r.origin.x, r.origin.y); 1243 CGContextSetTextPosition (gcontext, r.origin.x, r.origin.y);
1277 CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->cmp_from, 1244 CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->cmp_from,
@@ -1287,6 +1254,10 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1287 CGContextRestoreGState (gcontext); 1254 CGContextRestoreGState (gcontext);
1288 } 1255 }
1289#endif /* NS_IMPL_COCOA */ 1256#endif /* NS_IMPL_COCOA */
1257
1258 /* Draw underline, overline, strike-through. */
1259 ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x);
1260
1290 return to-from; 1261 return to-from;
1291} 1262}
1292 1263
@@ -1329,8 +1300,8 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
1329 if (!unichars || !(font_info->glyphs[block])) 1300 if (!unichars || !(font_info->glyphs[block]))
1330 abort (); 1301 abort ();
1331 1302
1332 /* create a string containing all unicode characters in this block */ 1303 /* create a string containing all Unicode characters in this block */
1333 for (idx = block<<8, i =0; i<0x100; idx++, i++) 1304 for (idx = block<<8, i = 0; i < 0x100; idx++, i++)
1334 if (idx < 0xD800 || idx > 0xDFFF) 1305 if (idx < 0xD800 || idx > 0xDFFF)
1335 unichars[i] = idx; 1306 unichars[i] = idx;
1336 else 1307 else
@@ -1346,7 +1317,7 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
1346 NSGlyphGenerator *glyphGenerator = [NSGlyphGenerator sharedGlyphGenerator]; 1317 NSGlyphGenerator *glyphGenerator = [NSGlyphGenerator sharedGlyphGenerator];
1347 /*NSCharacterSet *coveredChars = [nsfont coveredCharacterSet]; */ 1318 /*NSCharacterSet *coveredChars = [nsfont coveredCharacterSet]; */
1348 unsigned int numGlyphs = [font_info->nsfont numberOfGlyphs]; 1319 unsigned int numGlyphs = [font_info->nsfont numberOfGlyphs];
1349 NSUInteger gInd =0, cInd =0; 1320 NSUInteger gInd = 0, cInd = 0;
1350 1321
1351 [glyphStorage setString: allChars font: font_info->nsfont]; 1322 [glyphStorage setString: allChars font: font_info->nsfont];
1352 [glyphGenerator generateGlyphsForGlyphStorage: glyphStorage 1323 [glyphGenerator generateGlyphsForGlyphStorage: glyphStorage
@@ -1354,7 +1325,7 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
1354 glyphIndex: &gInd characterIndex: &cInd]; 1325 glyphIndex: &gInd characterIndex: &cInd];
1355#endif 1326#endif
1356 glyphs = font_info->glyphs[block]; 1327 glyphs = font_info->glyphs[block];
1357 for (i =0; i<0x100; i++, glyphs++) 1328 for (i = 0; i < 0x100; i++, glyphs++)
1358 { 1329 {
1359#ifdef NS_IMPL_GNUSTEP 1330#ifdef NS_IMPL_GNUSTEP
1360 g = unichars[i]; 1331 g = unichars[i];
@@ -1462,6 +1433,8 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
1462- (void) setString: (NSString *)str font: (NSFont *)font 1433- (void) setString: (NSString *)str font: (NSFont *)font
1463{ 1434{
1464 [dict setObject: font forKey: NSFontAttributeName]; 1435 [dict setObject: font forKey: NSFontAttributeName];
1436 if (attrStr != nil)
1437 [attrStr release];
1465 attrStr = [[NSAttributedString alloc] initWithString: str attributes: dict]; 1438 attrStr = [[NSAttributedString alloc] initWithString: str attributes: dict];
1466 maxChar = [str length]; 1439 maxChar = [str length];
1467 maxGlyph = 0; 1440 maxGlyph = 0;
@@ -1524,5 +1497,5 @@ syms_of_nsfont (void)
1524 DEFSYM (Qroman, "roman"); 1497 DEFSYM (Qroman, "roman");
1525 DEFSYM (Qmedium, "medium"); 1498 DEFSYM (Qmedium, "medium");
1526 DEFVAR_LISP ("ns-reg-to-script", Vns_reg_to_script, 1499 DEFVAR_LISP ("ns-reg-to-script", Vns_reg_to_script,
1527 doc: /* Internal use: maps font registry to unicode script. */); 1500 doc: /* Internal use: maps font registry to Unicode script. */);
1528} 1501}