From 3528e709a4eb8eb0f4346804a4c5166fe3cc594f Mon Sep 17 00:00:00 2001 From: Kenichi Handa Date: Wed, 14 May 2008 01:43:03 +0000 Subject: (xftfont_list): Adjusted for the change of `list' callback function. (xftfont_match): Adjusted for the fontmat change of font-entity. (xftfont_open): Adjusted for the format change of font-entity and font-object. Adjusted for the change of struct font. Return a font-object. Don't update dpyinfo->smallest_font_height and dpyinfo->smallest_char_width. (xftfont_close): Block input while calling XftFontClose. (xftfont_prepare_face): Don't block input while calling xftfont_get_colors. Adjusted for the change of struct font. (xftfont_shape): Return value of error case fixed. --- src/xftfont.c | 199 +++++++++++++++++++++++----------------------------------- 1 file changed, 80 insertions(+), 119 deletions(-) diff --git a/src/xftfont.c b/src/xftfont.c index 55d0b943c1..da72df4539 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -137,7 +137,7 @@ xftfont_get_colors (f, face, gc, xftface_info, fg, bg) static Lisp_Object xftfont_list P_ ((Lisp_Object, Lisp_Object)); static Lisp_Object xftfont_match P_ ((Lisp_Object, Lisp_Object)); -static struct font *xftfont_open P_ ((FRAME_PTR, Lisp_Object, int)); +static Lisp_Object xftfont_open P_ ((FRAME_PTR, Lisp_Object, int)); static void xftfont_close P_ ((FRAME_PTR, struct font *)); static int xftfont_prepare_face P_ ((FRAME_PTR, struct face *)); static void xftfont_done_face P_ ((FRAME_PTR, struct face *)); @@ -157,13 +157,12 @@ xftfont_list (frame, spec) Lisp_Object frame; Lisp_Object spec; { - Lisp_Object val = ftfont_driver.list (frame, spec); + Lisp_Object list = ftfont_driver.list (frame, spec), tail; int i; - if (! NILP (val)) - for (i = 0; i < ASIZE (val); i++) - ASET (AREF (val, i), FONT_TYPE_INDEX, Qxft); - return val; + for (tail = list; CONSP (tail); tail = XCDR (tail)) + ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft); + return list; } static Lisp_Object @@ -173,7 +172,7 @@ xftfont_match (frame, spec) { Lisp_Object entity = ftfont_driver.match (frame, spec); - if (VECTORP (entity)) + if (! NILP (entity)) ASET (entity, FONT_TYPE_INDEX, Qxft); return entity; } @@ -182,7 +181,7 @@ extern Lisp_Object ftfont_font_format P_ ((FcPattern *)); static FcChar8 ascii_printable[95]; -static struct font * +static Lisp_Object xftfont_open (f, entity, pixel_size) FRAME_PTR f; Lisp_Object entity; @@ -190,7 +189,7 @@ xftfont_open (f, entity, pixel_size) { Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); Display *display = FRAME_X_DISPLAY (f); - Lisp_Object val; + Lisp_Object val, font_object; FcPattern *pattern, *pat = NULL; FcChar8 *file; struct xftfont_info *xftfont_info = NULL; @@ -199,18 +198,19 @@ xftfont_open (f, entity, pixel_size) double size = 0; XftFont *xftfont = NULL; int spacing; - char *name; - int len; + char name[256]; + int len, i; XGlyphInfo extents; FT_Face ft_face; - val = AREF (entity, FONT_EXTRA_INDEX); - if (XTYPE (val) != Lisp_Misc - || XMISCTYPE (val) != Lisp_Misc_Save_Value) - return NULL; - pattern = XSAVE_VALUE (val)->pointer; + val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); + if (! CONSP (val) + || XTYPE (XCDR (val)) != Lisp_Misc + || XMISCTYPE (XCDR (val)) != Lisp_Misc_Save_Value) + return Qnil; + pattern = XSAVE_VALUE (XCDR (val))->pointer; if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch) - return NULL; + return Qnil; size = XINT (AREF (entity, FONT_SIZE_INDEX)); if (size == 0) @@ -228,49 +228,39 @@ xftfont_open (f, entity, pixel_size) BLOCK_INPUT; XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat); xftfont = XftFontOpenPattern (display, pat); + UNBLOCK_INPUT; + if (! xftfont) + return Qnil; /* We should not destroy PAT here because it is kept in XFTFONT and destroyed automatically when XFTFONT is closed. */ - if (! xftfont) - goto err; - - xftfont_info = malloc (sizeof (struct xftfont_info)); - if (! xftfont_info) - goto err; - xfont = malloc (sizeof (XFontStruct)); - if (! xfont) - goto err; + font_object = font_make_object (VECSIZE (struct xftfont_info)); + ASET (font_object, FONT_TYPE_INDEX, Qxft); + for (i = 1; i < FONT_ENTITY_MAX; i++) + ASET (font_object, i, AREF (entity, i)); + ASET (font_object, FONT_SIZE_INDEX, make_number (size)); + len = font_unparse_xlfd (entity, size, name, 256); + if (len > 0) + ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len)); + len = font_unparse_fcname (entity, size, name, 256); + if (len > 0) + ASET (font_object, FONT_FULLNAME_INDEX, make_unibyte_string (name, len)); + else + ASET (font_object, FONT_FULLNAME_INDEX, + AREF (font_object, FONT_NAME_INDEX)); + ASET (font_object, FONT_FILE_INDEX, + make_unibyte_string ((char *) file, strlen ((char *) file))); + ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (pattern)); + font = XFONT_OBJECT (font_object); + font->pixel_size = pixel_size; + font->driver = &xftfont_driver; + font->encoding_charset = font->repertory_charset = -1; + + xftfont_info = (struct xftfont_info *) font; xftfont_info->display = display; xftfont_info->screen = FRAME_X_SCREEN_NUMBER (f); xftfont_info->xftfont = xftfont; -#ifdef HAVE_LIBOTF - ft_face = XftLockFace (xftfont); - xftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; - XftUnlockFace (xftfont); - xftfont_info->otf = NULL; -#endif /* HAVE_LIBOTF */ - - font = (struct font *) xftfont_info; - font->format = ftfont_font_format (xftfont->pattern); - font->entity = entity; font->pixel_size = size; font->driver = &xftfont_driver; - len = 96; - name = malloc (len); - while (name && font_unparse_fcname (entity, pixel_size, name, len) < 0) - { - char *new = realloc (name, len += 32); - - if (! new) - free (name); - name = new; - } - if (! name) - goto err; - font->font.full_name = font->font.name = name; - font->file_name = (char *) file; - font->font.size = xftfont->max_advance_width; - font->font.charset = font->encoding_charset = font->repertory_charset = -1; - if (FcPatternGetInteger (xftfont->pattern, FC_SPACING, 0, &spacing) != FcResultMatch) spacing = FC_PROPORTIONAL; @@ -280,21 +270,22 @@ xftfont_open (f, entity, pixel_size) for (i = 0; i < 95; i++) ascii_printable[i] = ' ' + i; } + BLOCK_INPUT; if (spacing != FC_PROPORTIONAL) { - font->font.average_width = font->font.space_width + font->min_width = font->average_width = font->space_width = xftfont->max_advance_width; XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents); } else { XftTextExtents8 (display, xftfont, ascii_printable, 1, &extents); - font->font.space_width = extents.xOff; - if (font->font.space_width <= 0) + font->space_width = extents.xOff; + if (font->space_width <= 0) /* dirty workaround */ - font->font.space_width = pixel_size; + font->space_width = pixel_size; XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents); - font->font.average_width = (font->font.space_width + extents.xOff) / 95; + font->average_width = (font->space_width + extents.xOff) / 95; } UNBLOCK_INPUT; @@ -304,57 +295,37 @@ xftfont_open (f, entity, pixel_size) font->descent = xftfont->descent; if (font->descent < extents.height - extents.y) font->descent = extents.height - extents.y; - font->font.height = font->ascent + font->descent; + font->height = font->ascent + font->descent; - /* Unfortunately Xft doesn't provide a way to get minimum char - width. So, we use space_width instead. */ - font->min_width = font->font.space_width; - - font->font.baseline_offset = 0; - font->font.relative_compose = 0; - font->font.default_ascent = 0; - font->font.vertical_centering = 0; - - /* Setup pseudo XFontStruct */ - xfont->fid = 0; - xfont->ascent = font->ascent; - xfont->descent = font->descent; - xfont->max_bounds.descent = font->descent; - xfont->max_bounds.width = xftfont->max_advance_width; - xfont->min_bounds.width = font->font.space_width; - font->font.font = xfont; - - dpyinfo->n_fonts++; - - /* Set global flag fonts_changed_p to non-zero if the font loaded - has a character with a smaller width than any other character - before, or if the font loaded has a smaller height than any other - font loaded before. If this happens, it will make a glyph matrix - reallocation necessary. */ - if (dpyinfo->n_fonts == 1) + ft_face = XftLockFace (xftfont); + if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0) { - dpyinfo->smallest_font_height = font->font.height; - dpyinfo->smallest_char_width = font->min_width; - fonts_changed_p = 1; + int upEM = ft_face->units_per_EM; + + font->underline_position = -ft_face->underline_position * size / upEM; + font->underline_thickness = -ft_face->underline_thickness * size / upEM; } else { - if (dpyinfo->smallest_font_height > font->font.height) - dpyinfo->smallest_font_height = font->font.height, - fonts_changed_p |= 1; - if (dpyinfo->smallest_char_width > font->min_width) - dpyinfo->smallest_char_width = font->min_width, - fonts_changed_p |= 1; + font->underline_position = -1; + font->underline_thickness = 0; } +#ifdef HAVE_LIBOTF + xftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; + xftfont_info->otf = NULL; +#endif /* HAVE_LIBOTF */ + XftUnlockFace (xftfont); - return font; + /* Unfortunately Xft doesn't provide a way to get minimum char + width. So, we use space_width instead. */ + font->min_width = font->space_width; - err: - if (xftfont) XftFontClose (display, xftfont); - UNBLOCK_INPUT; - if (xftfont_info) free (xftfont_info); - if (xfont) free (xfont); - return NULL; + font->baseline_offset = 0; + font->relative_compose = 0; + font->default_ascent = 0; + font->vertical_centering = 0; + + return font_object; } static void @@ -368,11 +339,9 @@ xftfont_close (f, font) if (xftfont_info->otf) OTF_close (xftfont_info->otf); #endif + BLOCK_INPUT; XftFontClose (xftfont_info->display, xftfont_info->xftfont); - if (font->font.name) - free (font->font.name); - free (font); - FRAME_X_DISPLAY_INFO (f)->n_fonts--; + UNBLOCK_INPUT; } static int @@ -394,12 +363,8 @@ xftfont_prepare_face (f, face) xftface_info = malloc (sizeof (struct xftface_info)); if (! xftface_info) return -1; - - BLOCK_INPUT; xftfont_get_colors (f, face, face->gc, NULL, &xftface_info->xft_fg, &xftface_info->xft_bg); - UNBLOCK_INPUT; - face->extra = xftface_info; return 0; } @@ -491,7 +456,7 @@ xftfont_draw (s, from, to, x, y, with_background) { FRAME_PTR f = s->f; struct face *face = s->face; - struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font_info; + struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font; struct xftface_info *xftface_info = NULL; XftDraw *xft_draw = xftfont_get_xft_draw (f); FT_UInt *code; @@ -500,7 +465,7 @@ xftfont_draw (s, from, to, x, y, with_background) int len = to - from; int i; - if (s->font_info == face->font_info) + if (s->font == face->font) xftface_info = (struct xftface_info *) face->extra; xftfont_get_colors (f, face, s->gc, xftface_info, &fg, with_background ? &bg : NULL); @@ -511,12 +476,8 @@ xftfont_draw (s, from, to, x, y, with_background) XftDrawSetClip (xft_draw, NULL); if (with_background) - { - struct font *font = (struct font *) face->font_info; - - XftDrawRect (xft_draw, &bg, - x, y - face->font->ascent, s->width, font->font.height); - } + XftDrawRect (xft_draw, &bg, + x, y - face->font->ascent, s->width, face->font->height); code = alloca (sizeof (FT_UInt) * len); for (i = 0; i < len; i++) code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8) @@ -584,7 +545,7 @@ xftfont_shape (lgstring) { struct font *font; struct xftfont_info *xftfont_info; - int result; + Lisp_Object result; FT_Face ft_face; CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring), font); @@ -602,7 +563,7 @@ xftfont_shape (lgstring) OTF_close (otf); xftfont_info->maybe_otf = 0; XftUnlockFace (xftfont_info->xftfont); - return 0; + return Qnil; } xftfont_info->otf = otf; } -- cgit v1.2.3