diff options
Diffstat (limited to 'src/nsfont.m')
| -rw-r--r-- | src/nsfont.m | 105 |
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 | ||
| 5 | This file is part of GNU Emacs. | 5 | This 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 |
| 129 | static NSFontDescriptor | 129 | static NSFontDescriptor * |
| 130 | *ns_spec_to_descriptor(Lisp_Object font_spec) | 130 | ns_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. */ |
| 262 | static BOOL | 267 | static 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?) */ |
| 301 | static NSString | 306 | static 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. */ |
| 333 | static NSString | 338 | static 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. */ |
| 390 | static NSCharacterSet | 395 | static 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. */ |
| 430 | static NSSet | 435 | static 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 | } |