X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/dacbc44ca3fc825c9e5ffa799f1a0937c1da0020..e7a526e3beb2ddadaad24ccd26d75fb55f7965bd:/src/font.c diff --git a/src/font.c b/src/font.c index 9f9d381706..231df2ef71 100644 --- a/src/font.c +++ b/src/font.c @@ -287,7 +287,7 @@ font_pixel_size (FRAME_PTR f, Lisp_Object spec) if (INTEGERP (val)) dpi = XINT (val); else - dpi = f->resy; + dpi = FRAME_RES_Y (f); pixel_size = POINT_TO_PIXEL (point_size, dpi); return pixel_size; #else @@ -717,7 +717,7 @@ font_put_extra (Lisp_Object font, Lisp_Object prop, Lisp_Object val) } -/* Font name parser and unparser */ +/* Font name parser and unparser. */ static int parse_matrix (const char *); static int font_expand_wildcards (Lisp_Object *, int); @@ -1219,7 +1219,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) return -1; f[j] = p = alloca (alloc); sprintf (p, "%s%s-*", SDATA (val), - "*" + (SDATA (val)[SBYTES (val) - 1] == '*')); + &"*"[SDATA (val)[SBYTES (val) - 1] == '*']); } else f[j] = SSDATA (val); @@ -1234,8 +1234,21 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) f[j] = "*"; else { + int c, k, l; + ptrdiff_t alloc; + val = SYMBOL_NAME (val); - f[j] = SSDATA (val); + alloc = SBYTES (val) + 1; + if (nbytes <= alloc) + return -1; + f[j] = p = alloca (alloc); + /* Copy the name while excluding '-', '?', ',', and '"'. */ + for (k = l = 0; k < alloc; k++) + { + c = SREF (val, k); + if (c != '-' && c != '?' && c != ',' && c != '"') + p[l++] = c; + } } } @@ -1605,7 +1618,7 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes) } if (point_size > 0) { - int len = snprintf (p, lim - p, "-%d" + (p == name), point_size); + int len = snprintf (p, lim - p, &"-%d"[p == name], point_size); if (! (0 <= len && len < lim - p)) return -1; p += len; @@ -1733,7 +1746,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec /* This part (through the next ^L) is still experimental and not tested much. We may drastically change codes. */ -/* OTF handler */ +/* OTF handler. */ #if 0 @@ -1844,11 +1857,11 @@ otf_open (Lisp_Object file) OTF *otf; if (! NILP (val)) - otf = XSAVE_VALUE (XCDR (val))->pointer; + otf = XSAVE_POINTER (XCDR (val), 0); else { otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; - val = make_save_value (otf, 0); + val = make_save_pointer (otf); otf_list = Fcons (Fcons (file, val), otf_list); } return otf; @@ -2022,7 +2035,7 @@ font_otf_Anchor (OTF_Anchor *anchor) #endif /* 0 */ -/* Font sorting */ +/* Font sorting. */ static unsigned font_score (Lisp_Object, Lisp_Object *); static int font_compare (const void *, const void *); @@ -2088,9 +2101,7 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop) { EMACS_INT diff = ((XINT (AREF (entity, i)) >> 8) - (XINT (spec_prop[i]) >> 8)); - if (diff < 0) - diff = - diff; - score |= min (diff, 127) << sort_shift_bits[i]; + score |= min (eabs (diff), 127) << sort_shift_bits[i]; } /* Score the size. Maximum difference is 127. */ @@ -2105,10 +2116,7 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop) if (CONSP (Vface_font_rescale_alist)) pixel_size *= font_rescale_ratio (entity); - diff = pixel_size - XINT (AREF (entity, FONT_SIZE_INDEX)); - if (diff < 0) - diff = - diff; - diff <<= 1; + diff = eabs (pixel_size - XINT (AREF (entity, FONT_SIZE_INDEX))) << 1; if (! NILP (spec_prop[FONT_DPI_INDEX]) && ! EQ (spec_prop[FONT_DPI_INDEX], AREF (entity, FONT_DPI_INDEX))) diff |= 1; @@ -2557,7 +2565,6 @@ font_get_cache (FRAME_PTR f, struct font_driver *driver) return val; } -static int num_fonts; static void font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver) @@ -2590,7 +2597,6 @@ font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver) { eassert (font && driver == font->driver); driver->close (f, font); - num_fonts--; } } if (driver->free_entity) @@ -2658,9 +2664,7 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) { int diff = XINT (AREF (entity, FONT_SIZE_INDEX)) - size; - if (diff != 0 - && (diff < 0 ? -diff > FONT_PIXEL_SIZE_QUANTUM - : diff > FONT_PIXEL_SIZE_QUANTUM)) + if (eabs (diff) > FONT_PIXEL_SIZE_QUANTUM) prop = FONT_SPEC_MAX; } if (prop < FONT_SPEC_MAX @@ -2815,7 +2819,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size) struct font_driver_list *driver_list; Lisp_Object objlist, size, val, font_object; struct font *font; - int min_width, height; + int min_width, height, psize; eassert (FONT_ENTITY_P (entity)); size = AREF (entity, FONT_SIZE_INDEX); @@ -2842,15 +2846,21 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size) } } - font_object = driver_list->driver->open (f, entity, pixel_size); - if (!NILP (font_object)) - ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size)); + /* We always open a font of manageable size; i.e non-zero average + width and height. */ + for (psize = pixel_size; ; psize++) + { + font_object = driver_list->driver->open (f, entity, psize); + if (NILP (font_object)) + return Qnil; + font = XFONT_OBJECT (font_object); + if (font->average_width > 0 && font->height > 0) + break; + } + ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size)); FONT_ADD_LOG ("open", entity, font_object); - if (NILP (font_object)) - return Qnil; ASET (entity, FONT_OBJLIST_INDEX, Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX))); - num_fonts++; font = XFONT_OBJECT (font_object); min_width = (font->min_width ? font->min_width @@ -2895,7 +2905,6 @@ font_close_object (FRAME_PTR f, Lisp_Object font_object) eassert (FRAME_X_DISPLAY_INFO (f)->n_fonts); FRAME_X_DISPLAY_INFO (f)->n_fonts--; #endif - num_fonts--; } @@ -3115,7 +3124,9 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c) { double pt = XINT (attrs[LFACE_HEIGHT_INDEX]); - pixel_size = POINT_TO_PIXEL (pt / 10, f->resy); + pixel_size = POINT_TO_PIXEL (pt / 10, FRAME_RES_Y (f)); + if (pixel_size < 1) + pixel_size = 1; } ASET (work, FONT_SIZE_INDEX, Qnil); foundry[0] = AREF (work, FONT_FOUNDRY_INDEX); @@ -3245,12 +3256,13 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O } pt /= 10; - size = POINT_TO_PIXEL (pt, f->resy); + size = POINT_TO_PIXEL (pt, FRAME_RES_Y (f)); #ifdef HAVE_NS if (size == 0) { Lisp_Object ffsize = get_frame_param (f, Qfontsize); - size = NUMBERP (ffsize) ? POINT_TO_PIXEL (XINT (ffsize), f->resy) : 0; + size = (NUMBERP (ffsize) + ? POINT_TO_PIXEL (XINT (ffsize), FRAME_RES_Y (f)) : 0); } #endif } @@ -3572,7 +3584,7 @@ font_filter_properties (Lisp_Object font, Lisp_Object it; int i; - /* Set boolean values to Qt or Qnil */ + /* Set boolean values to Qt or Qnil. */ for (i = 0; boolean_properties[i] != NULL; ++i) for (it = alist; ! NILP (it); it = XCDR (it)) { @@ -3687,11 +3699,11 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, #ifdef HAVE_WINDOW_SYSTEM -/* Check how many characters after POS (at most to *LIMIT) can be - displayed by the same font in the window W. FACE, if non-NULL, is - the face selected for the character at POS. If STRING is not nil, - it is the string to check instead of the current buffer. In that - case, FACE must be not NULL. +/* Check how many characters after character/byte position POS/POS_BYTE + (at most to *LIMIT) can be displayed by the same font in the window W. + FACE, if non-NULL, is the face selected for the character at POS. + If STRING is not nil, it is the string to check instead of the current + buffer. In that case, FACE must be not NULL. The return value is the font-object for the character at POS. *LIMIT is set to the position where that font can't be used. @@ -3699,15 +3711,15 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, It is assured that the current buffer (or STRING) is multibyte. */ Lisp_Object -font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face, Lisp_Object string) +font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, + struct window *w, struct face *face, Lisp_Object string) { - ptrdiff_t pos_byte, ignore; + ptrdiff_t ignore; int c; Lisp_Object font_object = Qnil; if (NILP (string)) { - pos_byte = CHAR_TO_BYTE (pos); if (! face) { int face_id; @@ -3718,10 +3730,7 @@ font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face } } else - { - eassert (face); - pos_byte = string_char_to_byte (string, pos); - } + eassert (face); while (pos < *limit) { @@ -3751,7 +3760,7 @@ font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face #endif -/* Lisp API */ +/* Lisp API. */ DEFUN ("fontp", Ffontp, Sfontp, 1, 2, 0, doc: /* Return t if OBJECT is a font-spec, font-entity, or font-object. @@ -3854,7 +3863,8 @@ usage: (font-spec ARGS...) */) if (EQ (key, QCname)) { CHECK_STRING (val); - font_parse_name (SSDATA (val), SBYTES (val), spec); + if (font_parse_name (SSDATA (val), SBYTES (val), spec) < 0) + error ("Invalid font name: %s", SSDATA (val)); font_put_extra (spec, key, val); } else @@ -3993,16 +4003,11 @@ The optional argument FRAME specifies the frame that the face attributes are to be displayed on. If omitted, the selected frame is used. */) (Lisp_Object font, Lisp_Object frame) { - struct frame *f; + struct frame *f = decode_live_frame (frame); Lisp_Object plist[10]; Lisp_Object val; int n = 0; - if (NILP (frame)) - frame = selected_frame; - CHECK_LIVE_FRAME (frame); - f = XFRAME (frame); - if (STRINGP (font)) { int fontset = fs_query_fontset (font, 0); @@ -4027,7 +4032,7 @@ are to be displayed on. If omitted, the selected frame is used. */) if (INTEGERP (val)) { Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX); - int dpi = INTEGERP (font_dpi) ? XINT (font_dpi) : f->resy; + int dpi = INTEGERP (font_dpi) ? XINT (font_dpi) : FRAME_RES_Y (f); plist[n++] = QCheight; plist[n++] = make_number (PIXEL_TO_POINT (XINT (val) * 10, dpi)); } @@ -4152,18 +4157,15 @@ how close they are to PREFER. */) DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0, doc: /* List available font families on the current frame. -Optional argument FRAME, if non-nil, specifies the target frame. */) +If FRAME is omitted or nil, the selected frame is used. */) (Lisp_Object frame) { - FRAME_PTR f; + struct frame *f = decode_live_frame (frame); struct font_driver_list *driver_list; - Lisp_Object list; + Lisp_Object list = Qnil; + + XSETFRAME (frame, f); - if (NILP (frame)) - frame = selected_frame; - CHECK_LIVE_FRAME (frame); - f = XFRAME (frame); - list = Qnil; for (driver_list = f->font_driver_list; driver_list; driver_list = driver_list->next) if (driver_list->driver->list_family) @@ -4531,11 +4533,9 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0, (Lisp_Object font_entity, Lisp_Object size, Lisp_Object frame) { EMACS_INT isize; + struct frame *f = decode_live_frame (frame); CHECK_FONT_ENTITY (font_entity); - if (NILP (frame)) - frame = selected_frame; - CHECK_LIVE_FRAME (frame); if (NILP (size)) isize = XINT (AREF (font_entity, FONT_SIZE_INDEX)); @@ -4543,7 +4543,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0, { CHECK_NUMBER_OR_FLOAT (size); if (FLOATP (size)) - isize = POINT_TO_PIXEL (XFLOAT_DATA (size), XFRAME (frame)->resy); + isize = POINT_TO_PIXEL (XFLOAT_DATA (size), FRAME_RES_Y (f)); else isize = XINT (size); if (! (INT_MIN <= isize && isize <= INT_MAX)) @@ -4551,7 +4551,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0, if (isize == 0) isize = 120; } - return font_open_entity (XFRAME (frame), font_entity, isize); + return font_open_entity (f, font_entity, isize); } DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0, @@ -4559,10 +4559,7 @@ DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0, (Lisp_Object font_object, Lisp_Object frame) { CHECK_FONT_OBJECT (font_object); - if (NILP (frame)) - frame = selected_frame; - CHECK_LIVE_FRAME (frame); - font_close_object (XFRAME (frame), font_object); + font_close_object (decode_live_frame (frame), font_object); return Qnil; } @@ -4614,7 +4611,7 @@ If the font is not OpenType font, CAPABILITY is nil. */) CHECK_FONT_GET_OBJECT (font_object, font); - val = Fmake_vector (make_number (9), Qnil); + val = make_uninit_vector (9); ASET (val, 0, AREF (font_object, FONT_NAME_INDEX)); ASET (val, 1, AREF (font_object, FONT_FILE_INDEX)); ASET (val, 2, make_number (font->pixel_size)); @@ -4625,6 +4622,8 @@ If the font is not OpenType font, CAPABILITY is nil. */) ASET (val, 7, make_number (font->average_width)); if (font->driver->otf_capability) ASET (val, 8, Fcons (Qopentype, font->driver->otf_capability (font))); + else + ASET (val, 8, Qnil); return val; } @@ -4717,7 +4716,7 @@ the corresponding element is nil. */) chars = aref_addr (object, XFASTINT (from)); } - vec = Fmake_vector (make_number (len), Qnil); + vec = make_uninit_vector (len); for (i = 0; i < len; i++) { Lisp_Object g; @@ -4727,8 +4726,11 @@ the corresponding element is nil. */) code = font->driver->encode_char (font, c); if (code == FONT_INVALID_CODE) - continue; - g = Fmake_vector (make_number (LGLYPH_SIZE), Qnil); + { + ASET (vec, i, Qnil); + continue; + } + g = LGLYPH_NEW (); LGLYPH_SET_FROM (g, i); LGLYPH_SET_TO (g, i); LGLYPH_SET_CHAR (g, c); @@ -4765,21 +4767,15 @@ Optional third arg STRING, if non-nil, is a string containing the target character at index specified by POSITION. */) (Lisp_Object position, Lisp_Object window, Lisp_Object string) { - struct window *w; - ptrdiff_t pos; + struct window *w = decode_live_window (window); - if (NILP (window)) - window = selected_window; - CHECK_LIVE_WINDOW (window); - w = XWINDOW (window); if (NILP (string)) { - if (XBUFFER (w->buffer) != current_buffer) + if (XBUFFER (w->contents) != current_buffer) error ("Specified window is not displaying the current buffer."); CHECK_NUMBER_COERCE_MARKER (position); if (! (BEGV <= XINT (position) && XINT (position) < ZV)) args_out_of_range_3 (position, make_number (BEGV), make_number (ZV)); - pos = XINT (position); } else { @@ -4787,10 +4783,9 @@ character at index specified by POSITION. */) CHECK_STRING (string); if (! (0 <= XINT (position) && XINT (position) < SCHARS (string))) args_out_of_range (string, position); - pos = XINT (position); } - return font_at (-1, pos, NULL, w, string); + return font_at (-1, XINT (position), NULL, w, string); } #if 0 @@ -4847,26 +4842,21 @@ where OPENED-NAME is the name used for opening the font, FULL-NAME is the full name of the font, SIZE is the pixelsize of the font, - HEIGHT is the pixel-height of the font (i.e ascent + descent), + HEIGHT is the pixel-height of the font (i.e., ascent + descent), BASELINE-OFFSET is the upward offset pixels from ASCII baseline, RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling how to compose characters. If the named font is not yet loaded, return nil. */) (Lisp_Object name, Lisp_Object frame) { - FRAME_PTR f; + struct frame *f; struct font *font; Lisp_Object info; Lisp_Object font_object; - (*check_window_system_func) (); - if (! FONTP (name)) CHECK_STRING (name); - if (NILP (frame)) - frame = selected_frame; - CHECK_LIVE_FRAME (frame); - f = XFRAME (frame); + f = decode_window_system_frame (frame); if (STRINGP (name)) { @@ -4891,7 +4881,7 @@ If the named font is not yet loaded, return nil. */) return Qnil; font = XFONT_OBJECT (font_object); - info = Fmake_vector (make_number (7), Qnil); + info = make_uninit_vector (7); ASET (info, 0, AREF (font_object, FONT_NAME_INDEX)); ASET (info, 1, AREF (font_object, FONT_FULLNAME_INDEX)); ASET (info, 2, make_number (font->pixel_size)); @@ -4920,7 +4910,7 @@ build_style_table (const struct table_entry *entry, int nelement) int i, j; Lisp_Object table, elt; - table = Fmake_vector (make_number (nelement), Qnil); + table = make_uninit_vector (nelement); for (i = 0; i < nelement; i++) { for (j = 0; entry[i].names[j]; j++); @@ -5184,7 +5174,7 @@ See `font-weight-table' for the format of the vector. */); XSYMBOL (intern_c_string ("font-width-table"))->constant = 1; staticpro (&font_style_table); - font_style_table = Fmake_vector (make_number (3), Qnil); + font_style_table = make_uninit_vector (3); ASET (font_style_table, 0, Vfont_weight_table); ASET (font_style_table, 1, Vfont_slant_table); ASET (font_style_table, 2, Vfont_width_table);