/* Font back-end driver for the NeXT/Open/GNUstep and MacOSX window system.
See font.h
- Copyright (C) 2006-2012 Free Software Foundation, Inc.
+ Copyright (C) 2006-2013 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* This should be the first include, as it may set up #defines affecting
interpretation of even the system includes. */
#include <config.h>
-#include <setjmp.h>
#include "lisp.h"
#include "dispextern.h"
#endif
#define NSFONT_TRACE 0
+#define LCD_SMOOTHING_MARGIN 2
extern Lisp_Object Qns;
-extern Lisp_Object Qnormal, Qbold, Qitalic, Qcondensed, Qexpanded;
+extern Lisp_Object Qnormal, Qbold, Qitalic;
static Lisp_Object Qapple, Qroman, Qmedium;
+static Lisp_Object Qcondensed, Qexpanded;
extern Lisp_Object Qappend;
extern float ns_antialias_threshold;
extern int ns_tmp_flags;
extern struct nsfont_info *ns_tmp_font;
+
/* font glyph and metrics caching functions, implemented at end */
static void ns_uni_to_glyphs (struct nsfont_info *font_info,
unsigned char block);
static void
ns_escape_name (char *name)
{
- int i =0, len =strlen (name);
- for ( ; i<len; i++)
- if (name[i] == ' ')
- name[i] = '_';
+ for (; *name; name++)
+ if (*name == ' ')
+ *name = '_';
}
static void
ns_unescape_name (char *name)
{
- int i =0, len =strlen (name);
- for ( ; i<len; i++)
- if (name[i] == '_')
- name[i] = ' ';
+ for (; *name; name++)
+ if (*name == '_')
+ *name = ' ';
}
make_number (100 + 100
* ns_attribute_fvalue (desc, NSFontSlantTrait)));*/
FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
- traits & NSFontCondensedTrait ? Qcondensed :
- traits & NSFontExpandedTrait ? Qexpanded : Qnormal);
+ traits & NSFontCondensedTrait ? Qcondensed :
+ traits & NSFontExpandedTrait ? Qexpanded : Qnormal);
/* FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
make_number (100 + 100
* ns_attribute_fvalue (desc, NSFontWidthTrait)));*/
if (!ascii_printable)
{
- char chars[95];
+ char chars[96];
int ch;
for (ch = 0; ch < 95; ch++)
chars[ch] = ' ' + ch;
+ chars[95] = '\0';
- ascii_printable = [NSString initWithFormat: @"%s", chars];
+ ascii_printable = [[NSString alloc] initWithFormat: @"%s", chars];
}
#ifdef NS_IMPL_COCOA
while CONSP (rts)
{
r = XCAR (XCAR (rts));
- if (!strncmp(SSDATA(r), reg, strlen(SSDATA(r))))
+ if (!strncmp (SSDATA (r), reg, SBYTES (r)))
{
script = XCDR (XCAR (rts));
return [NSString stringWithUTF8String: SSDATA (SYMBOL_NAME (script))];
NSSet *cFamilies;
BOOL foundItal = NO;
+ block_input ();
if (NSFONT_TRACE)
{
fprintf (stderr, "nsfont: %s for fontspec:\n ",
[fkeys removeObject: NSFontFamilyAttribute];
matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
+
if (NSFONT_TRACE)
NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc,
[matchingDescs count]);
[s1 release];
}
+ unblock_input ();
+
/* Return something if was a match and nothing found. */
if (isMatch)
return ns_fallback_entity ();
static int nsfont_text_extents (struct font *font, unsigned int *code,
int nglyphs, struct font_metrics *metrics);
static int nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
- int with_background);
+ bool with_background);
struct font_driver nsfont_driver =
{
nsfont_list_family (Lisp_Object frame)
{
Lisp_Object list = Qnil;
- NSEnumerator *families =
- [[[NSFontManager sharedFontManager] availableFontFamilies]
- objectEnumerator];
+ NSEnumerator *families;
NSString *family;
+
+ block_input ();
+ families = [[[NSFontManager sharedFontManager] availableFontFamilies]
+ objectEnumerator];
while ((family = [families nextObject]))
list = Fcons (intern ([family UTF8String]), list);
/* FIXME: escape the name? */
fprintf (stderr, "nsfont: list families returning %"pI"d entries\n",
XINT (Flength (list)));
+ unblock_input ();
return list;
}
NSRect brect;
Lisp_Object font_object;
int fixLeopardBug;
- 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. */
- if (fontCache == nil)
- fontCache = [[NSMutableDictionary alloc] init];
+ block_input ();
if (NSFONT_TRACE)
{
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");
- /* FIXME: Cast from (unsigned long) to Lisp_Object. */
- XHASH (font_object) = [cached unsignedLongValue];
- return font_object;
- }
- else
- {
- font_object = font_make_object (VECSIZE (struct nsfont_info),
- font_entity, pixel_size);
- if (!synthItal)
- [fontCache setObject: [NSNumber numberWithUnsignedLong:
- (unsigned long) XHASH (font_object)]
- forKey: nsfont];
- }
-
+ 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; /* FIXME: other terms do, but return Qnil causes segfault */
+ {
+ unblock_input ();
+ return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */
+ }
font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics);
- BLOCK_INPUT;
-
/* for metrics */
+#ifdef NS_IMPL_COCOA
+ sfont = [nsfont screenFontWithRenderingMode:
+ NSFontAntialiasedIntegerAdvancementsRenderingMode];
+#else
sfont = [nsfont screenFont];
+#endif
+
if (sfont == nil)
sfont = nsfont;
font = (struct font *) font_info;
font->pixel_size = [sfont pointSize];
font->driver = &nsfont_driver;
- font->encoding_type = FONT_ENCODING_NOT_DECIDED;
font->encoding_charset = -1;
font->repertory_charset = -1;
font->default_ascent = 0;
font->props[FONT_FULLNAME_INDEX] =
make_unibyte_string (font_info->name, strlen (font_info->name));
}
- UNBLOCK_INPUT;
+ unblock_input ();
return font_object;
}
/* Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
- position of frame F with S->FACE and S->GC. If WITH_BACKGROUND
- is nonzero, fill the background in advance. It is assured that
- WITH_BACKGROUND is zero when (FROM > 0 || TO < S->nchars). */
+ position of frame F with S->FACE and S->GC. If WITH_BACKGROUND,
+ fill the background in advance. It is assured that WITH_BACKGROUND
+ is false when (FROM > 0 || TO < S->nchars). */
static int
nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
- int with_background)
+ bool with_background)
/* NOTE: focus and clip must be set
also, currently assumed (true in nsterm.m call) from ==0, to ==nchars */
{
char isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
int end = isComposite ? s->cmp_to : s->nchars;
+ block_input ();
/* Select face based on input flags */
switch (ns_tmp_flags)
{
/* Draw underline, overline, strike-through. */
ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x);
+ unblock_input ();
return to-from;
}
fprintf (stderr, "%p\tFinding glyphs for glyphs in block %d\n",
font_info, block);
- BLOCK_INPUT;
+ block_input ();
#ifdef NS_IMPL_COCOA
if (firstTime)
font_info->glyphs[block] = xmalloc (0x100 * sizeof (unsigned short));
if (!unichars || !(font_info->glyphs[block]))
- abort ();
+ emacs_abort ();
/* create a string containing all Unicode characters in this block */
for (idx = block<<8, i = 0; i < 0x100; idx++, i++)
#endif
}
- UNBLOCK_INPUT;
+ unblock_input ();
xfree (unichars);
}
numGlyphs = 0x10000;
#endif
- BLOCK_INPUT;
- sfont = [font_info->nsfont screenFont];
+ block_input ();
+#ifdef NS_IMPL_COCOA
+ sfont = [font_info->nsfont screenFontWithRenderingMode:
+ NSFontAntialiasedIntegerAdvancementsRenderingMode];
+#else
+ sfont = [font_info->nsfont screenFont];
+#endif
font_info->metrics[block] = xzalloc (0x100 * sizeof (struct font_metrics));
if (!(font_info->metrics[block]))
- abort ();
+ emacs_abort ();
metrics = font_info->metrics[block];
for (g = block<<8, i =0; i<0x100 && g < numGlyphs; g++, i++, metrics++)
lb = r.origin.x;
rb = r.size.width - w;
+ // Add to bearing for LCD smoothing. We don't know if it is there.
if (lb < 0)
- metrics->lbearing = round (lb);
+ metrics->lbearing = round (lb - LCD_SMOOTHING_MARGIN);
if (font_info->ital)
rb += 0.22 * font_info->height;
- metrics->rbearing = lrint (w + rb);
+ metrics->rbearing = lrint (w + rb + LCD_SMOOTHING_MARGIN);
metrics->descent = r.origin.y < 0 ? -r.origin.y : 0;
/*lrint (hshrink * [sfont ascender] + expand * hd/2); */
metrics->ascent = r.size.height - metrics->descent;
/*-lrint (hshrink* [sfont descender] - expand * hd/2); */
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
nsfont_driver.type = Qns;
register_font_driver (&nsfont_driver, NULL);
+ DEFSYM (Qcondensed, "condensed");
+ DEFSYM (Qexpanded, "expanded");
DEFSYM (Qapple, "apple");
DEFSYM (Qroman, "roman");
DEFSYM (Qmedium, "medium");