/* 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.
#include "window.h"
#include "fontset.h"
#include "nsterm.h"
-#include "frame.h"
#include "character.h"
#include "font.h"
#include "termchar.h"
#endif
#define NSFONT_TRACE 0
+#define LCD_SMOOTHING_MARGIN 2
extern Lisp_Object Qns;
extern Lisp_Object Qnormal, Qbold, Qitalic;
static void ns_glyph_metrics (struct nsfont_info *font_info,
unsigned char block);
+#define INVALID_GLYPH 0xFFFF
/* ==========================================================================
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 = ' ';
}
{
NSDictionary *tdict = [fdesc objectForKey: NSFontTraitsAttribute];
NSNumber *val = [tdict objectForKey: trait];
- return val == nil ? 0.0 : [val floatValue];
+ return val == nil ? 0.0F : [val floatValue];
}
/* add each attr in font_spec to fdAttrs.. */
n = min (FONT_WEIGHT_NUMERIC (font_spec), 200);
if (n != -1 && n != STYLE_REF)
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+ [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
forKey: NSFontWeightTrait];
n = min (FONT_SLANT_NUMERIC (font_spec), 200);
if (n != -1 && n != STYLE_REF)
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+ [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
forKey: NSFontSlantTrait];
n = min (FONT_WIDTH_NUMERIC (font_spec), 200);
if (n > -1 && (n > STYLE_REF + 10 || n < STYLE_REF - 10))
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+ [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
forKey: NSFontWidthTrait];
if ([tdict count] > 0)
[fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
- fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs];
+ fdesc = [[[NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]
+ retain] autorelease];
+
if (family != nil)
{
- fdesc = [fdesc fontDescriptorWithFamily: family];
+ NSFontDescriptor *fdesc2 = [fdesc fontDescriptorWithFamily: family];
+ fdesc = [[fdesc2 retain] autorelease];
}
[fdAttrs release];
/* Utility: get width of a char c in screen font SFONT */
-static float
+static CGFloat
ns_char_width (NSFont *sfont, int c)
{
- float w = -1.0;
+ CGFloat w = -1.0;
NSString *cstr = [NSString stringWithFormat: @"%c", c];
#ifdef NS_IMPL_COCOA
static int
ns_ascii_average_width (NSFont *sfont)
{
- float w = -1.0;
+ CGFloat w = -1.0;
if (!ascii_printable)
{
w = [sfont advancementForGlyph: glyph].width;
#endif
- if (w < 0.0)
+ if (w < (CGFloat) 0.0)
{
NSDictionary *attrsDictionary =
[NSDictionary dictionaryWithObject: sfont forKey: NSFontAttributeName];
w = [ascii_printable sizeWithAttributes: attrsDictionary].width;
}
- return lrint (w / 95.0);
+ return lrint (w / (CGFloat) 95.0);
}
off++;
}
//fprintf(stderr, "off = %d\ttot = %d\n", off,tot);
- return (float)off / tot < 1.0 - pct;
+ return (float)off / tot < 1.0F - pct;
}
*ns_registry_to_script (char *reg)
{
Lisp_Object script, r, rts = Vns_reg_to_script;
- while CONSP (rts)
+ 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))];
{
Lisp_Object ranges, range_list;
- ranges = Fcons (script, Qnil);
+ ranges = list1 (script);
map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
ranges);
range_list = Fnreverse (XCDR (ranges));
if (ns_charset_covers(fset, charset, pct))
[families addObject: family];
}
- pct -= 0.2;
- if ([families count] > 0 || pct < 0.05)
+ pct -= 0.2F;
+ if ([families count] > 0 || pct < 0.05F)
break;
}
[charset release];
NSSet *cFamilies;
BOOL foundItal = NO;
+ block_input ();
if (NSFONT_TRACE)
{
fprintf (stderr, "nsfont: %s for fontspec:\n ",
if (isMatch)
[fkeys removeObject: NSFontFamilyAttribute];
- if ([fkeys count] > 0)
- matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
- else
- matchingDescs = [NSMutableArray array];
+ matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
if (NSFONT_TRACE)
NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc,
[s1 release];
}
+ unblock_input ();
+
/* Return something if was a match and nothing found. */
if (isMatch)
return ns_fallback_entity ();
========================================================================== */
-static Lisp_Object nsfont_get_cache (FRAME_PTR frame);
-static Lisp_Object nsfont_list (Lisp_Object frame, Lisp_Object font_spec);
-static Lisp_Object nsfont_match (Lisp_Object frame, Lisp_Object font_spec);
-static Lisp_Object nsfont_list_family (Lisp_Object frame);
-static Lisp_Object nsfont_open (FRAME_PTR f, Lisp_Object font_entity,
+static Lisp_Object nsfont_get_cache (struct frame *frame);
+static Lisp_Object nsfont_list (struct frame *, Lisp_Object);
+static Lisp_Object nsfont_match (struct frame *, Lisp_Object);
+static Lisp_Object nsfont_list_family (struct frame *);
+static Lisp_Object nsfont_open (struct frame *f, Lisp_Object font_entity,
int pixel_size);
-static void nsfont_close (FRAME_PTR f, struct font *font);
+static void nsfont_close (struct frame *f, struct font *font);
static int nsfont_has_char (Lisp_Object entity, int c);
static unsigned int nsfont_encode_char (struct font *font, int c);
static int nsfont_text_extents (struct font *font, unsigned int *code,
/* Return a cache of font-entities on FRAME. The cache must be a
cons whose cdr part is the actual cache area. */
static Lisp_Object
-nsfont_get_cache (FRAME_PTR frame)
+nsfont_get_cache (struct frame *frame)
{
- Display_Info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
+ Display_Info *dpyinfo = FRAME_DISPLAY_INFO (frame);
return (dpyinfo->name_list_element);
}
weight, slant, width, size (0 if scalable),
dpi, spacing, avgwidth (0 if scalable) */
static Lisp_Object
-nsfont_list (Lisp_Object frame, Lisp_Object font_spec)
+nsfont_list (struct frame *f, Lisp_Object font_spec)
{
- return ns_findfonts (font_spec, NO);
+ return ns_findfonts (font_spec, NO);
}
`face-font-selection-order' is ignored here.
Properties to be considered are same as for list(). */
static Lisp_Object
-nsfont_match (Lisp_Object frame, Lisp_Object font_spec)
+nsfont_match (struct frame *f, Lisp_Object font_spec)
{
- return ns_findfonts(font_spec, YES);
+ return ns_findfonts (font_spec, YES);
}
/* List available families. The value is a list of family names
(symbols). */
static Lisp_Object
-nsfont_list_family (Lisp_Object frame)
+nsfont_list_family (struct frame *f)
{
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;
}
/* Open a font specified by FONT_ENTITY on frame F. If the font is
scalable, open it with PIXEL_SIZE. */
static Lisp_Object
-nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
+nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
{
BOOL synthItal;
unsigned int traits = 0;
Lisp_Object font_object;
int fixLeopardBug;
+ block_input ();
+
if (NSFONT_TRACE)
{
fprintf (stderr, "nsfont: open size %d of fontentity:\n ", pixel_size);
family = [[NSFont userFixedPitchFontOfSize: 0] familyName];
/* Should be > 0.23 as some font descriptors (e.g. Terminus) set to that
when setting family in ns_spec_to_descriptor(). */
- if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50)
+ if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50F)
traits |= NSBoldFontMask;
- if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05))
+ if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F))
traits |= NSItalicFontMask;
/* see http://cocoadev.com/forums/comments.php?DiscussionID=74 */
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:
font_info->max_bounds.width = lrint (font_info->width);
font_info->max_bounds.lbearing = lrint (brect.origin.x);
font_info->max_bounds.rbearing =
- lrint (brect.size.width - font_info->width);
+ lrint (brect.size.width - (CGFloat) font_info->width);
#ifdef NS_IMPL_COCOA
/* set up synthItal and the CG font */
font->underline_thickness = lrint (font_info->underwidth);
font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
- font->props[FONT_FULLNAME_INDEX] =
- make_unibyte_string (font_info->name, strlen (font_info->name));
+ font->props[FONT_FULLNAME_INDEX] = build_unibyte_string (font_info->name);
}
unblock_input ();
/* Close FONT on frame F. */
static void
-nsfont_close (FRAME_PTR f, struct font *font)
+nsfont_close (struct frame *f, struct font *font)
{
struct nsfont_info *font_info = (struct nsfont_info *)font;
int i;
ns_uni_to_glyphs (font_info, high);
g = font_info->glyphs[high][low];
- return g == 0xFFFF ? FONT_INVALID_CODE : g;
+ return g == INVALID_GLYPH ? FONT_INVALID_CODE : g;
}
/* NOTE: focus and clip must be set
also, currently assumed (true in nsterm.m call) from ==0, to ==nchars */
{
- static char cbuf[1024];
- char *c = cbuf;
+ static unsigned char cbuf[1024];
+ unsigned char *c = cbuf;
#ifdef NS_IMPL_GNUSTEP
static float advances[1024];
float *adv = advances;
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)
{
: FRAME_BACKGROUND_COLOR (s->f)) set];
else
{
- struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (s->f);
+ struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
[[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
}
NSRectFill (br);
[bgCol set];
DPSmoveto (context, r.origin.x, r.origin.y);
/*[context GSSetTextDrawingMode: GSTextFillStroke]; /// not implemented yet */
- DPSxshow (context, cbuf, advances, len);
+ DPSxshow (context, (const char *) cbuf, advances, len);
DPSstroke (context);
[col set];
/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */
/* draw with DPSxshow () */
DPSmoveto (context, r.origin.x, r.origin.y);
- DPSxshow (context, cbuf, advances, len);
+ DPSxshow (context, (const char *) cbuf, advances, len);
DPSstroke (context);
DPSgrestore (context);
else
CGContextSetShouldAntialias (gcontext, 1);
- CGContextSetShouldSmoothFonts (gcontext, NO);
CGContextSetTextMatrix (gcontext, fliptf);
if (bgCol != nil)
/* Draw underline, overline, strike-through. */
ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x);
+ unblock_input ();
return to-from;
}
#else
g = glyphStorage->cglyphs[i];
/* TODO: is this a good check? maybe need to use coveredChars.. */
- if (g > numGlyphs)
- g = 0xFFFF; /* hopefully unused... */
+ if (g > numGlyphs || g == NSNullGlyph)
+ g = INVALID_GLYPH; /* hopefully unused... */
#endif
*glyphs = g;
}
metrics = font_info->metrics[block];
for (g = block<<8, i =0; i<0x100 && g < numGlyphs; g++, i++, metrics++)
{
- float w, lb, rb;
+ CGFloat w, lb, rb;
NSRect r = [sfont boundingRectForGlyph: g];
w = max ([sfont advancementForGlyph: g].width, 2.0);
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);
+ rb += (CGFloat) (0.22F * font_info->height);
+ 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); */
characterIndex: (NSUInteger)charIndex
{
len = glyphIndex+length;
- for (i =glyphIndex; i<len; i++)
+ for (i =glyphIndex; i<len; i++)
cglyphs[i] = glyphs[i-glyphIndex];
if (len > maxGlyph)
maxGlyph = len;