/* Font back-end driver for the NeXT/Open/GNUstep and MacOSX window system.
See font.h
- Copyright (C) 2006-2011 Free Software Foundation, Inc.
+ Copyright (C) 2006-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
return nil;
else
{
- char *tmp = xstrdup (SDATA (SYMBOL_NAME (tem)));
+ char *tmp = xstrdup (SSDATA (SYMBOL_NAME (tem)));
NSString *family;
ns_unescape_name (tmp);
family = [NSString stringWithUTF8String: tmp];
/* Converts FONT_WEIGHT, FONT_SLANT, FONT_WIDTH, plus family and script/lang
to NSFont descriptor. Information under extra only needed for matching. */
#define STYLE_REF 100
-static NSFontDescriptor
-*ns_spec_to_descriptor(Lisp_Object font_spec)
+static NSFontDescriptor *
+ns_spec_to_descriptor (Lisp_Object font_spec)
{
NSFontDescriptor *fdesc;
NSMutableDictionary *fdAttrs = [NSMutableDictionary new];
fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs];
if (family != nil)
+ {
fdesc = [fdesc fontDescriptorWithFamily: family];
+ }
+
+ [fdAttrs release];
+ [tdict release];
return fdesc;
}
/* Return whether set1 covers set2 to a reasonable extent given by pct.
- We check, out of each 16 unicode char range containing chars in set2,
+ We check, out of each 16 Unicode char range containing chars in set2,
whether at least one character is present in set1.
This must be true for pct of the pairs to consider it covering. */
static BOOL
const unsigned short *bytes2 = [[set2 bitmapRepresentation] bytes];
int i, off = 0, tot = 0;
+ /* Work around what appears to be a GNUstep bug.
+ See <http://bugs.gnu.org/11853>. */
+ if (! (bytes1 && bytes2))
+ return NO;
+
for (i=0; i<4096; i++, bytes1++, bytes2++)
if (*bytes2)
{
static NSString
*ns_lang_to_script (Lisp_Object lang)
{
- if (!strcmp (SDATA (SYMBOL_NAME (lang)), "ja"))
+ if (!strcmp (SSDATA (SYMBOL_NAME (lang)), "ja"))
return @"han";
/* NOTE: ja given for any hanzi that's also a kanji, but Chinese fonts
have more characters. */
- else if (!strcmp (SDATA (SYMBOL_NAME (lang)), "zh"))
+ else if (!strcmp (SSDATA (SYMBOL_NAME (lang)), "zh"))
return @"han";
- else if (!strcmp (SDATA (SYMBOL_NAME (lang)), "ko"))
+ else if (!strcmp (SSDATA (SYMBOL_NAME (lang)), "ko"))
return @"hangul";
else
return @"";
/* Convert OTF 4-letter script code to emacs script name. (Why can't
- everyone just use some standard unicode names for these?) */
+ everyone just use some standard Unicode names for these?) */
static NSString
*ns_otf_to_script (Lisp_Object otf)
{
Lisp_Object script = assq_no_quit (XCAR (otf), Votf_script_alist);
return CONSP (script)
- ? [NSString stringWithUTF8String: SDATA (SYMBOL_NAME XCDR ((script)))]
+ ? [NSString stringWithUTF8String: SSDATA (SYMBOL_NAME (XCDR ((script))))]
: @"";
}
while CONSP (rts)
{
r = XCAR (XCAR (rts));
- if (!strncmp(SDATA(r), reg, strlen(SDATA(r))))
+ if (!strncmp(SSDATA(r), reg, strlen(SSDATA(r))))
{
script = XCDR (XCAR (rts));
- return [NSString stringWithUTF8String: SDATA (SYMBOL_NAME (script))];
+ return [NSString stringWithUTF8String: SSDATA (SYMBOL_NAME (script))];
}
rts = XCDR (rts);
}
/* Searches the :script, :lang, and :otf extra-bundle properties of the spec,
plus registry regular property, for something that can be mapped to a
- unicode script. Empty string returned if no script spec found. */
+ Unicode script. Empty string returned if no script spec found. */
static NSString
*ns_get_req_script (Lisp_Object font_spec)
{
Lisp_Object key = XCAR (tmp), val = XCDR (tmp);
if (EQ (key, QCscript) && SYMBOLP (val))
return [NSString stringWithUTF8String:
- SDATA (SYMBOL_NAME (val))];
+ SSDATA (SYMBOL_NAME (val))];
if (EQ (key, QClang) && SYMBOLP (val))
return ns_lang_to_script (val);
if (EQ (key, QCotf) && CONSP (val) && SYMBOLP (XCAR (val)))
if (EQ (reg, Qiso10646_1))
reg = Qiso8859_1;
#endif
- return ns_registry_to_script (SDATA (SYMBOL_NAME (reg)));
+ return ns_registry_to_script (SSDATA (SYMBOL_NAME (reg)));
}
return @"";
}
-/* Use the unicode range information in Vchar_script_table to convert a script
+/* Use the Unicode range information in Vchar_script_table to convert a script
name into an NSCharacterSet. */
static NSCharacterSet
*ns_script_to_charset (NSString *scriptName)
If none are found, we reduce the percentage and try again, until 5%.
This provides a font with at least some characters if such can be found.
We don't use isSupersetOfSet: because (a) it doesn't work on Tiger, and
- (b) need approximate match as fonts covering full unicode ranges are rare. */
+ (b) need approximate match as fonts covering full Unicode ranges are rare. */
static NSSet
*ns_get_covering_families (NSString *script, float pct)
{
while (1)
{
NSEnumerator *allFamiliesEnum = [allFamilies objectEnumerator];
- while (family = [allFamiliesEnum nextObject])
+ while ((family = [allFamiliesEnum nextObject]))
{
NSCharacterSet *fset = [[fontMgr fontWithFamily: family
traits: 0 weight: 5 size: 12.0] coveredCharacterSet];
if ([families count] > 0 || pct < 0.05)
break;
}
+ [charset release];
}
#ifdef NS_IMPL_COCOA
if ([families count] == 0)
NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc,
[matchingDescs count]);
- for (dEnum = [matchingDescs objectEnumerator]; desc = [dEnum nextObject]; )
+ for (dEnum = [matchingDescs objectEnumerator]; (desc = [dEnum nextObject]);)
{
if (![cFamilies containsObject:
[desc objectForKey: NSFontFamilyAttribute]])
family = [fdesc objectForKey: NSFontFamilyAttribute];
if (family != nil && !foundItal && XINT (Flength (list)) > 0)
{
- NSFontDescriptor *sDesc = [[[NSFontDescriptor new]
- fontDescriptorWithSymbolicTraits: NSFontItalicTrait]
- fontDescriptorWithFamily: family];
+ NSFontDescriptor *s1 = [NSFontDescriptor new];
+ NSFontDescriptor *sDesc
+ = [[s1 fontDescriptorWithSymbolicTraits: NSFontItalicTrait]
+ fontDescriptorWithFamily: family];
list = Fcons (ns_descriptor_to_entity (sDesc,
AREF (font_spec, FONT_EXTRA_INDEX),
"synthItal"), list);
+ [s1 release];
}
/* Return something if was a match and nothing found. */
return ns_fallback_entity ();
if (NSFONT_TRACE)
- fprintf (stderr, " Returning %ld entities.\n",
- (long) XINT (Flength (list)));
+ fprintf (stderr, " Returning %"pI"d entities.\n",
+ XINT (Flength (list)));
return list;
}
}
-/* Return a font entity most closely maching with FONT_SPEC on
+/* Return a font entity most closely matching with FONT_SPEC on
FRAME. The closeness is determined by the font backend, thus
`face-font-selection-order' is ignored here.
Properties to be considered are same as for list(). */
[[[NSFontManager sharedFontManager] availableFontFamilies]
objectEnumerator];
NSString *family;
- while (family = [families nextObject])
+ while ((family = [families nextObject]))
list = Fcons (intern ([family UTF8String]), list);
/* FIXME: escape the name? */
if (NSFONT_TRACE)
- fprintf (stderr, "nsfont: list families returning %ld entries\n",
- (long) XINT (Flength (list)));
+ fprintf (stderr, "nsfont: list families returning %"pI"d entries\n",
+ XINT (Flength (list)));
return list;
}
Lisp_Object tem;
NSRect brect;
Lisp_Object font_object;
- int i;
int fixLeopardBug;
static NSMutableDictionary *fontCache = nil;
NSNumber *cached;
}
tem = AREF (font_entity, FONT_ADSTYLE_INDEX);
- synthItal = !NILP (tem) && !strncmp ("synthItal", SDATA (SYMBOL_NAME (tem)),
+ synthItal = !NILP (tem) && !strncmp ("synthItal", SSDATA (SYMBOL_NAME (tem)),
9);
family = ns_get_family (font_entity);
if (family == nil)
if (!font)
return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */
- font_info->glyphs = (unsigned short **)
- xmalloc (0x100 * sizeof (unsigned short *));
- font_info->metrics = (struct font_metrics **)
- xmalloc (0x100 * sizeof (struct font_metrics *));
- if (!font_info->glyphs || !font_info->metrics)
- return Qnil;
- memset (font_info->glyphs, 0, 0x100 * sizeof (unsigned short *));
- memset (font_info->metrics, 0, 0x100 * sizeof (struct font_metrics *));
+ font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
+ font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics);
BLOCK_INPUT;
font->props[FONT_FILE_INDEX] = Qnil;
{
- double expand, hshrink;
- float full_height, min_height, hd;
const char *fontName = [[nsfont fontName] UTF8String];
- int len = strlen (fontName);
/* The values specified by fonts are not always exact. For
* example, a 6x8 font could specify that the descender is
[font_info->nsfont retain];
/* set up ns_font (defined in nsgui.h) */
- font_info->name = (char *)xmalloc (strlen (fontName)+1);
- strcpy (font_info->name, fontName);
+ font_info->name = xstrdup (fontName);
font_info->bold = [fontMgr traitsOfFont: nsfont] & NSBoldFontMask;
font_info->ital =
synthItal || ([fontMgr traitsOfFont: nsfont] & NSItalicFontMask);
[sfont maximumAdvancement].width : ns_char_width (sfont, '0');
brect = [sfont boundingRectForFont];
- full_height = brect.size.height;
- min_height = [sfont ascender] - adjusted_descender;
- hd = full_height - min_height;
- /* standard height, similar to Carbon. Emacs.app: was 0.5 by default. */
- expand = 0.0;
- hshrink = 1.0;
-
- font_info->underpos = 2; /*[sfont underlinePosition] is often clipped out */
+ font_info->underpos = [sfont underlinePosition];
font_info->underwidth = [sfont underlineThickness];
font_info->size = font->pixel_size;
- font_info->voffset = lrint (hshrink * [sfont ascender] + expand * hd / 2);
/* max bounds */
- font_info->max_bounds.ascent =
- lrint (hshrink * [sfont ascender] + expand * hd/2);
+ 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(hshrink* adjusted_descender - expand*hd/2));
+ 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);
NS to render the string, it will come out differently from the individual
character widths added up because of layout processing. */
{
- XCharStruct *cs;
int cwidth, twidth = 0;
int hi, lo;
/* FIXME: composition: no vertical displacement is considered. */
/* set up for character rendering */
- r.origin.y += font->voffset + (s->height - font->height)/2;
+ r.origin.y = s->ybase;
col = (NS_FACE_FOREGROUND (face) != 0
? ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f)
/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */
}
- /* do underline */
- if (face->underline_p)
- {
- 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 != 0)
- [col set];
- }
- else
- [col set];
+ [col set];
/* draw with DPSxshow () */
DPSmoveto (context, r.origin.x, r.origin.y);
CGContextSetTextDrawingMode (gcontext, kCGTextFill);
}
- if (face->underline_p)
- {
- if (face->underline_color != 0)
- [ns_lookup_indexed_color (face->underline_color, s->f) set];
- else
- [col set];
- CGContextBeginPath (gcontext);
- CGContextMoveToPoint (gcontext,
- r.origin.x, r.origin.y + font->underpos);
- CGContextAddLineToPoint (gcontext, r.origin.x + r.size.width,
- r.origin.y + font->underpos);
- CGContextStrokePath (gcontext);
- if (face->underline_color != 0)
- [col set];
- }
- else
- [col set];
+ [col set];
CGContextSetTextPosition (gcontext, r.origin.x, r.origin.y);
CGContextShowGlyphsWithAdvances (gcontext, s->char2b + s->cmp_from,
CGContextRestoreGState (gcontext);
}
#endif /* NS_IMPL_COCOA */
+
+ /* Draw underline, overline, strike-through. */
+ ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x);
+
return to-from;
}
if (!unichars || !(font_info->glyphs[block]))
abort ();
- /* create a string containing all unicode characters in this block */
- for (idx = block<<8, i =0; i<0x100; idx++, i++)
+ /* create a string containing all Unicode characters in this block */
+ for (idx = block<<8, i = 0; i < 0x100; idx++, i++)
if (idx < 0xD800 || idx > 0xDFFF)
unichars[i] = idx;
else
NSGlyphGenerator *glyphGenerator = [NSGlyphGenerator sharedGlyphGenerator];
/*NSCharacterSet *coveredChars = [nsfont coveredCharacterSet]; */
unsigned int numGlyphs = [font_info->nsfont numberOfGlyphs];
- NSUInteger gInd =0, cInd =0;
+ NSUInteger gInd = 0, cInd = 0;
[glyphStorage setString: allChars font: font_info->nsfont];
[glyphGenerator generateGlyphsForGlyphStorage: glyphStorage
glyphIndex: &gInd characterIndex: &cInd];
#endif
glyphs = font_info->glyphs[block];
- for (i =0; i<0x100; i++, glyphs++)
+ for (i = 0; i < 0x100; i++, glyphs++)
{
#ifdef NS_IMPL_GNUSTEP
g = unichars[i];
BLOCK_INPUT;
sfont = [font_info->nsfont screenFont];
- font_info->metrics[block] = xmalloc (0x100 * sizeof (struct font_metrics));
- memset (font_info->metrics[block], 0, 0x100 * sizeof (struct font_metrics));
+ font_info->metrics[block] = xzalloc (0x100 * sizeof (struct font_metrics));
if (!(font_info->metrics[block]))
abort ();
maxChar = 0;
maxGlyph = 0;
dict = [NSMutableDictionary new];
- cglyphs = (CGGlyph *)xmalloc (c * sizeof (CGGlyph));
+ cglyphs = xmalloc (c * sizeof (CGGlyph));
return self;
}
- (void) setString: (NSString *)str font: (NSFont *)font
{
[dict setObject: font forKey: NSFontAttributeName];
+ if (attrStr != nil)
+ [attrStr release];
attrStr = [[NSAttributedString alloc] initWithString: str attributes: dict];
maxChar = [str length];
maxGlyph = 0;
DEFSYM (Qroman, "roman");
DEFSYM (Qmedium, "medium");
DEFVAR_LISP ("ns-reg-to-script", Vns_reg_to_script,
- doc: /* Internal use: maps font registry to unicode script. */);
+ doc: /* Internal use: maps font registry to Unicode script. */);
}