This is nsfaces.m in view mode; [Download] [Up]
/* "Face" primitives. Copyright (C) 1993, 1994 Free Software Foundation. This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This is derived from work by Lucid (some parts very loosely so). */ /* NOTE: face->font==0 does not mean unused face in this file ! */ #import <appkit/appkit.h> #include <sys/types.h> #include <sys/stat.h> #include "config.h" #include "lisp.h" #ifdef HAVE_NS #include "nsterm.h" #include "buffer.h" #include "dispextern.h" #include "frame.h" #include "blockinput.h" #include "window.h" #include "multi-frame.h" /* The number of face-id's in use (same for all frames). */ int ns_next_face_id; static NXColor default_color; int ns_face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ ); void ns_recompute_basic_faces ( /* FRAME_PTR f */ ); static int new_computed_face (struct frame *f, struct ns_face *new_face); static void ensure_face_ready (struct frame *f, int fid); static int face_eql(const struct ns_face *f1,const struct ns_face *f2); int ns_load_font(struct ns_face *f) { double shrink; float bbox1,bbox3,under; id font,screenfont; NXFontMetrics *m; if (!NUMBERP(ns_shrink_space)) return 4; shrink=XFLOATINT(ns_shrink_space); if (f->name==0 || f->size==-1) return 1; font=[Font newFont:f->name size:f->size]; if (font==nil) return 2; if (screenfont=[font screenFont]) font=screenfont; m=[font metrics]; if (!m->isFixedPitch) return 3; f->font=font; f->width=[font getWidthOf:"M"]; bbox1=m->fontBBox[1]; bbox3=m->fontBBox[3]; under=m->underlinePosition; if (!m->isScreenFont) { bbox1=floor(f->size*bbox1); bbox3=ceil (f->size*bbox3); under=floor(f->size*under); } f->height=rint(shrink*bbox3) - bbox1; f->descender=-bbox1; f->underpos=under-bbox1; f->underwidth=rint(m->underlineThickness); return 0; } /* Clear out face_vector and start anew. This should be done from time to time just to avoid keeping too many graphics contexts in face_vector that are no longer needed. */ void ns_clear_face_cache (void) { /* Empty for NS */ return; } static int face_eql(const struct ns_face *f1,const struct ns_face *f2) { return(f1->size==f2->size && f1->underline==f2->underline && f1->stipple == f2->stipple && NXEqualColor(f1->foreground_color,f2->foreground_color) && NXEqualColor(f1->background_color,f2->background_color) && (f1->name==f2->name)); } /* Managing parameter face arrays for frames. */ void ns_init_frame_faces (struct frame *f) { ensure_face_ready (f, 0); ensure_face_ready (f, 1); f->output_data.ns->n_computed_faces=0; f->output_data.ns->computed_faces=0; new_computed_face (f, f->output_data.ns->param_faces[0]); new_computed_face (f, f->output_data.ns->param_faces[1]); ns_recompute_basic_faces(f); #if 0 { int i; Lisp_Object tail, frame; //FIXME/cl check FOR_EACH_FRAME (tail, frame) if (FRAME_NS_P (XFRAME (frame)) && XFRAME (frame) != f) for (i=2; i< XFRAME(frame)->output_data.ns->n_param_faces; i++) if (XFRAME(frame)->output_data.ns->param_faces[i]) ensure_face_ready (f,i); } #else { Lisp_Object tail, frame, result; result = Qnil; FOR_EACH_FRAME (tail, frame) if (FRAME_NS_P (XFRAME (frame)) && XFRAME (frame) != f) { result = frame; break; } /* If we didn't find any NS frames other than f, then we don't need any faces other than 0 and 1, so we're okay. Otherwise, make sure that all faces valid on the selected frame are also valid on this new frame. */ if (FRAMEP (result)) { int i; int n_faces = FRAME_N_PARAM_FACES (XFRAME (result)); struct ns_face **faces = FRAME_PARAM_FACES (XFRAME (result)); for (i = 2; i < n_faces; i++) if (faces[i]) ensure_face_ready (f, i); } } #endif } void ns_free_frame_faces (struct frame *f) { int i; for(i=0; i< f->output_data.ns->n_param_faces; i++) if (f->output_data.ns->param_faces[i]) xfree (f->output_data.ns->param_faces[i]); for(i=0; i< f->output_data.ns->n_computed_faces; i++) if (f->output_data.ns->computed_faces[i]) xfree (f->output_data.ns->computed_faces[i]); xfree (f->output_data.ns->param_faces); f->output_data.ns->param_faces =0; f->output_data.ns->n_param_faces =0; xfree (f->output_data.ns->computed_faces); f->output_data.ns->computed_faces =0; f->output_data.ns->n_computed_faces =0; } /* Interning faces in a frame's face array. */ static int new_computed_face (struct frame *f, struct ns_face *new_face) { int i; if (f->output_data.ns->n_computed_faces >= f->output_data.ns->size_computed_faces) { int new_size = f->output_data.ns->n_computed_faces + 32; f->output_data.ns->computed_faces = (struct ns_face **) xrealloc (f->output_data.ns->computed_faces, new_size * sizeof (struct ns_face *)); f->output_data.ns->size_computed_faces = new_size; } i = f->output_data.ns->n_computed_faces++; f->output_data.ns->computed_faces[i] = (struct ns_face *) xmalloc (sizeof(struct ns_face)); *(f->output_data.ns->computed_faces[i]) = *new_face; return i; } /* Find a match for NEW_FACE in a FRAME's computed face array, and add it if we don't find one. */ static int intern_computed_face (struct frame *f, struct ns_face *new_face) { int i; /* Search for a computed face already on F equivalent to FACE. */ for (i = 0; i < f->output_data.ns->n_computed_faces; i++) { if (! f->output_data.ns->computed_faces[i]) abort (); if (face_eql(new_face,f->output_data.ns->computed_faces[i])) return i; } /* We didn't find one; add a new one. */ return new_computed_face (f, new_face); } /* Make parameter face id ID valid on frame F. */ static void ensure_face_ready (struct frame *f, int fid) { if (f->output_data.ns->n_param_faces <= fid) { int n = fid + 10; f->output_data.ns->param_faces = (struct ns_face **) xrealloc (f->output_data.ns->param_faces,sizeof (struct ns_face *) * n); bzero (f->output_data.ns->param_faces + f->output_data.ns->n_param_faces, (n - f->output_data.ns->n_param_faces) * sizeof (struct ns_face *)); f->output_data.ns->n_param_faces = n; } if (f->output_data.ns->param_faces [fid] == 0) { struct ns_face *nface=(struct ns_face *) xmalloc(sizeof (*nface)); nface->underline=-1; nface->font=0; nface->name=0; nface->size=-1; nface->foreground_color=default_color; nface->background_color=default_color; nface->stipple = nil; f->output_data.ns->param_faces [fid] = nface; } } DEFUN ("ns-pixmap-spec-p", Fns_pixmap_spec_p, Sns_pixmap_spec_p, 1, 1, 0, "Return t if OBJECT is a valid pixmap specification.") (object) Lisp_Object object; { Lisp_Object height, width; return ((STRINGP (object) || (CONSP (object) && CONSP (XCONS (object)->cdr) && CONSP (XCONS (XCONS (object)->cdr)->cdr) && NILP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->cdr) && (width = XCONS (object)->car, INTEGERP (width)) && (height = XCONS (XCONS (object)->cdr)->car, INTEGERP (height)) && STRINGP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car) && XINT (width) > 0 && XINT (height) > 0 /* The string must have enough bits for width * height. */ && ((XSTRING (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car)->size * (BITS_PER_INT / sizeof (int))) >= XFASTINT (width) * XFASTINT (height))) || (CONSP (object) && CONSP (XCONS (object)->cdr) && CONSP (XCONS (XCONS (object)->cdr)->cdr) && NILP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->cdr) && (width = XCONS (object)->car, INTEGERP (width)) && (height = XCONS (XCONS (object)->cdr)->car, INTEGERP (height)) && CONSP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car) && XINT (width) > 0 && XINT (height) > 0)) ? Qt : Qnil); } /* Load a bitmap according to NAME (which is either a file name or a pixmap spec). Return the EmacsImage object or get an error if NAME is invalid. Store the bitmap width in *W_PTR and height in *H_PTR. */ static id load_pixmap (f, name, w_ptr, h_ptr) FRAME_PTR f; Lisp_Object name; unsigned int *w_ptr, *h_ptr; { id bitmap_id = nil; Lisp_Object tem; NXSize s; if (NILP (name)) return nil; tem = Fns_pixmap_spec_p (name); if (NILP (tem)) wrong_type_argument (Qpixmap_spec_p, name); if (CONSP (name)) { /* Decode a bitmap spec into a bitmap. */ int h, w; Lisp_Object bits; w = XINT (Fcar (name)); h = XINT (Fcar (Fcdr (name))); bits = Fcar (Fcdr (Fcdr (name))); if (STRINGP (bits)) bitmap_id = [[EmacsImage alloc] initFromXBM:XSTRING (bits)->data width:w height:h]; else if (CONSP (bits) && !strcmp ((char *) XSYMBOL (XCONS (bits)->car)->name->data, "xbm")) { bits = Fcdr (bits); bitmap_id = [[EmacsImage alloc] initFromSkipXBM:XSTRING (bits)->data width:w height:h length:XSTRING (bits)->size]; } } else /* It must be a string -- a file name. */ bitmap_id = [EmacsImage allocInitFromFile:name]; if (! bitmap_id) Fsignal (Qerror, Fcons (build_string ("invalid or undefined bitmap"), Fcons (name, Qnil))); [[bitmap_id stippleRep] getSize:&s]; *w_ptr = s.width; *h_ptr = s.height; return bitmap_id; } /* Return non-zero if FONT1 and FONT2 have the same width. We do not check the height, because we can now deal with different heights. We assume that they're both character-cell fonts. */ int ns_same_size_fonts (struct ns_face *font1, struct ns_face *font2) { return (font1->width == font2->width); } /* Update the line_height of frame F according to the biggest font in any face. Return nonzero if if line_height changes. */ int ns_frame_update_line_height (struct frame *f) { int i,shift; int biggest = (int)rint(f->output_data.ns->face->height); for (i = 0; i < f->output_data.ns->n_computed_faces; i++) if (f->output_data.ns->computed_faces[i]!=0) { if (f->output_data.ns->computed_faces[i]->font==0) ns_load_font(f->output_data.ns->computed_faces[i]); if ((f->output_data.ns->computed_faces[i]->height) > biggest) biggest = (int)rint(f->output_data.ns->computed_faces[i]->height); } if (biggest == f->output_data.ns->line_height) return 0; f->output_data.ns->line_height = biggest; return 1; } /* Modify face TO by copying from FROM all properties which have nondefault settings. */ static void merge_faces (struct ns_face *from, struct ns_face *to) { if (from->name && to->name!=from->name) { to->name=from->name; to->font=0; } if (from->size!=-1 && to->size!=from->size) { to->size=from->size; to->font=0; } if (from->underline != -1) to->underline = from->underline; if (!NXEqualColor(from->foreground_color,default_color)) to->foreground_color = from->foreground_color; if (!NXEqualColor(from->background_color,default_color)) to->background_color = from->background_color; if (from->stipple && to->stipple != from->stipple) { to->stipple = from->stipple; to->pixmap_w = from->pixmap_w; to->pixmap_h = from->pixmap_h; } } /* Set up the basic set of facial parameters, based on the frame's data; all faces are deltas applied to this. */ static void compute_base_face (struct frame *f, struct ns_face *face) { *face = *f->output_data.ns->face; } /* Return the face ID to use to display a special glyph which selects FACE_CODE as the face ID, assuming that ordinarily the face would be CURRENT_FACE. F is the frame. */ int ns_compute_glyph_face (struct frame *f, int face_code, int current_face) { struct ns_face face; face = *f->output_data.ns->param_faces[current_face]; if (face_code >= 0 && face_code < f->output_data.ns->n_param_faces && f->output_data.ns->param_faces[face_code] != 0) merge_faces (f->output_data.ns->param_faces[face_code], &face); return intern_computed_face (f, &face); } /* Return the face ID to use to display a special glyph which selects FACE_CODE as the face ID, assuming that ordinarily the face would be CURRENT_FACE. F is the frame. */ int ns_compute_glyph_face_1 (struct frame *f, Lisp_Object face_name, int current_face) { struct ns_face face; face = *f->output_data.ns->param_faces[current_face]; if (!NILP (face_name)) { int face_code = ns_face_name_id_number (f, face_name); if (face_code >= 0 && face_code < f->output_data.ns->n_param_faces && f->output_data.ns->param_faces[face_code] != 0) merge_faces (f->output_data.ns->param_faces[face_code], &face); } return intern_computed_face (f, &face); } /* Return the face ID associated with a buffer position POS. Store into *ENDPTR the position at which a different face is needed. This does not take account of glyphs that specify their own face codes. F is the frame in use for display, and W is a window displaying the current buffer. REGION_BEG, REGION_END delimit the region, so it can be highlighted. LIMIT is a position not to scan beyond. That is to limit the time this function can take. If MOUSE is nonzero, use the character's mouse-face, not its face. */ int ns_compute_char_face (struct frame *f, struct window *w, int pos, int region_beg, int region_end, int *endptr, int limit, int mouse) { struct ns_face face; Lisp_Object prop, position; int i, j, noverlays; int facecode; Lisp_Object *overlay_vec; Lisp_Object frame; int endpos; Lisp_Object propname; /* W must display the current buffer. We could write this function to use the frame and buffer of W, but right now it doesn't. */ if (XBUFFER (w->buffer) != current_buffer) abort (); XSETFRAME (frame, f); endpos = ZV; if (pos < region_beg && region_beg < endpos) endpos = region_beg; XSETFASTINT (position, pos); if (mouse) propname = Qmouse_face; else propname = Qface; prop = Fget_text_property (position, propname, w->buffer); { Lisp_Object limit1, end; XSETFASTINT (limit1, (limit < endpos ? limit : endpos)); end = Fnext_single_property_change (position, propname, w->buffer, limit1); if (INTEGERP (end)) endpos = XINT (end); } { int next_overlay; int len; /* First try with room for 40 overlays. */ len = 40; overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); noverlays = overlays_at (pos, 0, &overlay_vec, &len, &next_overlay, (int *) 0); /* If there are more than 40, make enough space for all, and try again. */ if (noverlays > len) { len = noverlays; overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); noverlays = overlays_at (pos, 0, &overlay_vec, &len, &next_overlay, (int *) 0); } if (next_overlay < endpos) endpos = next_overlay; } *endptr = endpos; /* Optimize the default case. */ if (noverlays == 0 && NILP (prop) && !(pos >= region_beg && pos < region_end)) return 0; compute_base_face (f, &face); if (CONSP (prop)) { /* We have a list of faces, merge them in reverse order */ Lisp_Object length; int len; Lisp_Object *faces; length = Fsafe_length (prop); len = XFASTINT (length); /* Put them into an array */ faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); for (j = 0; j < len; j++) { faces[j] = Fcar (prop); prop = Fcdr (prop); } /* So that we can merge them in the reverse order */ for (j = len - 1; j >= 0; j--) { facecode = ns_face_name_id_number (f, faces[j]); if (facecode >= 0 && facecode < f->output_data.ns->n_param_faces && f->output_data.ns->param_faces [facecode] != 0) merge_faces (f->output_data.ns->param_faces [facecode], &face); } } else if (!NILP (prop)) { facecode = ns_face_name_id_number (f, prop); if (facecode >= 0 && facecode < f->output_data.ns->n_param_faces && f->output_data.ns->param_faces [facecode] != 0) merge_faces (f->output_data.ns->param_faces [facecode], &face); } noverlays = sort_overlays (overlay_vec, noverlays, w); /* Now merge the overlay data in that order. */ for (i = 0; i < noverlays; i++) { prop = Foverlay_get (overlay_vec[i], propname); if (CONSP (prop)) { /* We have a list of faces, merge them in reverse order */ Lisp_Object length; int len; Lisp_Object *faces; int i; length = Fsafe_length (prop); len = XFASTINT (length); /* Put them into an array */ faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); for (j = 0; j < len; j++) { faces[j] = Fcar (prop); prop = Fcdr (prop); } /* So that we can merge them in the reverse order */ for (j = len - 1; j >= 0; j--) { facecode = ns_face_name_id_number (f, faces[j]); if (facecode >= 0 && facecode < f->output_data.ns->n_param_faces && f->output_data.ns->param_faces [facecode] != 0) merge_faces (f->output_data.ns->param_faces [facecode], &face); } /* FIXME/cl maybe should calc endpos here as well !? */ } else if (!NILP (prop)) { Lisp_Object oend; int oendpos; facecode = ns_face_name_id_number (f, prop); if (facecode >= 0 && facecode < f->output_data.ns->n_param_faces && f->output_data.ns->param_faces[facecode] != 0) merge_faces (f->output_data.ns->param_faces[facecode], &face); oend = OVERLAY_END (overlay_vec[i]); oendpos = OVERLAY_POSITION (oend); if (oendpos < endpos) endpos = oendpos; } } if (pos >= region_beg && pos < region_end) { if (region_end < endpos) endpos = region_end; if (region_face >= 0 && region_face < ns_next_face_id) merge_faces (f->output_data.ns->param_faces[region_face], &face); } *endptr = endpos; return intern_computed_face (f, &face); } /* Recompute the GC's for the default and modeline faces. We call this after changing frame parameters on which those GC's depend. */ void ns_recompute_basic_faces (struct frame *f) { /* If the frame's faces haven't been initialized yet, don't worry about this stuff. */ if (f->output_data.ns->n_param_faces < 2) return; compute_base_face (f, f->output_data.ns->computed_faces[0]); compute_base_face (f, f->output_data.ns->computed_faces[1]); merge_faces (f->output_data.ns->param_faces[0], f->output_data.ns->computed_faces[0]); merge_faces (f->output_data.ns->param_faces[1], f->output_data.ns->computed_faces[1]); } DEFUN ("ns-make-face-internal", Fns_make_face_internal, Sns_make_face_internal, 1, 1, 0, "Create face number FACE-ID on all frames.") (face_id) Lisp_Object face_id; { Lisp_Object rest, frame; int id = XINT (face_id); CHECK_NUMBER (face_id, 0); if (id < 0 || id >= ns_next_face_id) error ("Face id out of range"); FOR_EACH_FRAME (rest, frame) { if (FRAME_NS_P (XFRAME (frame))) ensure_face_ready (XFRAME (frame), id); } return Qnil; } DEFUN ("ns-set-face-attribute-internal", Fns_set_face_attribute_internal, Sns_set_face_attribute_internal, 4, 4, 0, "") (face_id, attr_name, attr_value, frame) Lisp_Object face_id, attr_name, attr_value, frame; { struct ns_face *face; struct frame *f; int fid; int garbaged=0; CHECK_FRAME (frame, 0); CHECK_NUMBER (face_id, 0); CHECK_SYMBOL (attr_name, 0); f = XFRAME (frame); fid = XINT (face_id); if (fid < 0 || fid >= ns_next_face_id) error ("Face id out of range"); if (! FRAME_NS_P (f)) return; ensure_face_ready (f, fid); face = f->output_data.ns->param_faces[XINT (face_id)]; if (EQ (attr_name, Qfont)) { if (NILP(attr_value)) { face->name=0; } else { CHECK_STRING(attr_value,0); face->name=NXUniqueString(XSTRING (attr_value)->data); } face->font=0; if (ns_frame_update_line_height (f)) ns_set_window_size (f, 0, f->width, f->height); garbaged=1; } else if (EQ (attr_name, Qfontsize)) { if (NILP(attr_value)) face->size=-1; else { CHECK_NUMBER_OR_FLOAT (attr_value, 0); face->size=XFLOATINT(attr_value); if (face->size<=0) error("Facesize non-positive."); } face->font=0; if (ns_frame_update_line_height (f)) ns_set_window_size (f, 0, f->width, f->height); garbaged=1; } else if (EQ (attr_name, intern ("foreground"))) { if (NILP(attr_value)) face->foreground_color=default_color; else if (ns_lisp_to_color(attr_value,&face->foreground_color)) error("Unknown color."); garbaged=1; } else if (EQ (attr_name, intern ("background"))) { if (NILP(attr_value)) face->background_color=default_color; else if (ns_lisp_to_color(attr_value,&face->background_color)) error("Unknown color."); garbaged=1; } else if (EQ (attr_name, intern ("background-pixmap"))) { unsigned int w, h; id new_pixmap = load_pixmap (f, attr_value, &w, &h); [face->stipple free]; face->stipple = new_pixmap; face->pixmap_w = w; face->pixmap_h = h; garbaged = 1; } else if (EQ (attr_name, Qunderline)) { if (NILP(attr_value)) face->underline=-1; else if (EQ(attr_value,Qt)) face->underline=1; else face->underline=0; garbaged=1; } else error ("unknown face attribute"); if (fid == 0 || fid == 1) ns_recompute_basic_faces (f); if (garbaged) SET_FRAME_GARBAGED (f); return Qnil; } DEFUN ("ns-internal-next-face-id", Fns_internal_next_face_id, Sns_internal_next_face_id, 0, 0, 0, "") () { return make_number (ns_next_face_id++); } DEFUN ("ns-convert-font-trait-internal", Fns_convert_font_trait_internal, Sns_convert_font_trait_internal, 2, 2, 0, "") (Lisp_Object name, Lisp_Object attribute) { id fm; id font; check_ns(); CHECK_STRING(name,0); CHECK_SYMBOL(attribute,0); fm=[FontManager new]; font=[Font newFont:XSTRING(name)->data size:10.0]; if (!fm || !font) error ("Unknown font."); if (EQ(attribute, intern ("italic"))) font=[fm convert:font toHaveTrait:NX_ITALIC]; else if (EQ(attribute, intern ("unitalic"))) font=[fm convert:font toNotHaveTrait:NX_ITALIC]; else if (EQ(attribute, intern ("bold"))) font=[fm convert:font toHaveTrait:NX_BOLD]; else if (EQ(attribute, intern ("unbold"))) font=[fm convert:font toNotHaveTrait:NX_BOLD]; else if (EQ(attribute, intern ("nonstandardcharset"))) font=[fm convert:font toHaveTrait:NX_NONSTANDARDCHARSET]; else if (EQ(attribute, intern ("unnonstandardcharset"))) font=[fm convert:font toNotHaveTrait:NX_NONSTANDARDCHARSET]; else if (EQ(attribute, intern ("narrow"))) font=[fm convert:font toHaveTrait:NX_NARROW]; else if (EQ(attribute, intern ("unnarrow"))) font=[fm convert:font toNotHaveTrait:NX_NARROW]; else if (EQ(attribute, intern ("expanded"))) font=[fm convert:font toHaveTrait:NX_EXPANDED]; else if (EQ(attribute, intern ("unexpanded"))) font=[fm convert:font toNotHaveTrait:NX_EXPANDED]; else if (EQ(attribute, intern ("condensed"))) font=[fm convert:font toHaveTrait:NX_CONDENSED]; else if (EQ(attribute, intern ("uncondensed"))) font=[fm convert:font toNotHaveTrait:NX_CONDENSED]; else if (EQ(attribute, intern ("smallcaps"))) font=[fm convert:font toHaveTrait:NX_SMALLCAPS]; else if (EQ(attribute, intern ("unsmallcaps"))) font=[fm convert:font toNotHaveTrait:NX_SMALLCAPS]; else if (EQ(attribute, intern ("poster"))) font=[fm convert:font toHaveTrait:NX_POSTER]; else if (EQ(attribute, intern ("unposter"))) font=[fm convert:font toNotHaveTrait:NX_POSTER]; else if (EQ(attribute, intern ("compressed"))) font=[fm convert:font toHaveTrait:NX_COMPRESSED]; else if (EQ(attribute, intern ("uncompressed"))) font=[fm convert:font toNotHaveTrait:NX_COMPRESSED]; return build_string([font name]); } int ns_face_name_id_number (struct frame *f, Lisp_Object name) { Lisp_Object tem; tem= Fcdr (assq_no_quit (name, f->face_alist)); if (NILP (tem)) return 0; CHECK_VECTOR (tem, 0); tem = XVECTOR (tem)->contents[2]; CHECK_NUMBER (tem, 0); return XINT (tem); } void syms_of_nsfaces () { default_color=NX_COLORCLEAR; defsubr (&Sns_pixmap_spec_p); defsubr (&Sns_make_face_internal); defsubr (&Sns_set_face_attribute_internal); defsubr (&Sns_internal_next_face_id); defsubr (&Sns_convert_font_trait_internal); } #endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.