# HG changeset patch # User Chong Yidong # Date 1213558931 0 # Node ID e427600f176b471a938bb7125f408b9378ab4708 # Parent 15c2fa76f0d5f827ef7792e3f537df3f0ade4614 (font_parse_fcname): Only only one decimal point. (font_unparse_fcname): Handle data in family and foundry indices as symbols, not strings. (font_unparse_gtkname, Ffont_face_attributes): New functions. diff -r 15c2fa76f0d5 -r e427600f176b src/font.c --- a/src/font.c Sun Jun 15 19:41:54 2008 +0000 +++ b/src/font.c Sun Jun 15 19:42:11 2008 +0000 @@ -126,7 +126,9 @@ extern Lisp_Object Qnormal; /* Symbols representing keys of normal font properties. */ -extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth, QCsize, QCname; +extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth; +extern Lisp_Object QCheight, QCsize, QCname; + Lisp_Object QCfoundry, QCadstyle, QCregistry; /* Symbols representing keys of font extra info. */ Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript, QCavgwidth; @@ -1372,12 +1374,16 @@ } else if (*p == '-') { - int size_found = 1; + int decimal = 0, size_found = 1; for (q = p + 1; *q && *q != ':'; q++) - if (! isdigit(*q) && *q != '.') + if (! isdigit(*q)) { - size_found = 0; - break; + if (*q != '.' || decimal) + { + size_found = 0; + break; + } + decimal = 1; } if (size_found) { @@ -1593,6 +1599,7 @@ char *name; int nbytes; { + Lisp_Object family, foundry; Lisp_Object tail, val; int point_size; int dpi; @@ -1602,9 +1609,17 @@ char *style_names[3] = { "weight", "slant", "width" }; char work[256]; - val = AREF (font, FONT_FAMILY_INDEX); - if (STRINGP (val)) - len += SBYTES (val); + family = AREF (font, FONT_FAMILY_INDEX); + if (! NILP (family)) + { + if (SYMBOLP (family)) + { + family = SYMBOL_NAME (family); + len += SBYTES (family); + } + else + family = Qnil; + } val = AREF (font, FONT_SIZE_INDEX); if (INTEGERP (val)) @@ -1621,10 +1636,17 @@ len += 11; /* for "-NUM" */ } - val = AREF (font, FONT_FOUNDRY_INDEX); - if (STRINGP (val)) - /* ":foundry=NAME" */ - len += 9 + SBYTES (val); + foundry = AREF (font, FONT_FOUNDRY_INDEX); + if (! NILP (foundry)) + { + if (SYMBOLP (foundry)) + { + foundry = SYMBOL_NAME (foundry); + len += 9 + SBYTES (foundry); /* ":foundry=NAME" */ + } + else + foundry = Qnil; + } for (i = 0; i < 3; i++) { @@ -1656,8 +1678,8 @@ if (len > nbytes) return -1; p = name; - if (! NILP (AREF (font, FONT_FAMILY_INDEX))) - p += sprintf(p, "%s", SDATA (SYMBOL_NAME (AREF (font, FONT_FAMILY_INDEX)))); + if (! NILP (family)) + p += sprintf (p, "%s", SDATA (family)); if (point_size > 0) { if (p == name) @@ -1688,6 +1710,94 @@ return (p - name); } +/* Store GTK-style font name of FONT (font-spec or font-entity) in + NAME (NBYTES length), and return the name length. F is the frame + on which the font is displayed; it is used to calculate the point + size. */ + +int +font_unparse_gtkname (font, f, name, nbytes) + Lisp_Object font; + struct frame *f; + char *name; + int nbytes; +{ + char *p; + int len = 1; + Lisp_Object family, weight, slant, size; + int point_size = -1; + + family = AREF (font, FONT_FAMILY_INDEX); + if (! NILP (family)) + { + if (! SYMBOLP (family)) + return -1; + family = SYMBOL_NAME (family); + len += SBYTES (family); + } + + weight = font_style_symbolic (font, FONT_WEIGHT_INDEX, 0); + if (weight == Qnormal) + weight = Qnil; + else if (! NILP (weight)) + { + weight = SYMBOL_NAME (weight); + len += SBYTES (weight); + } + + slant = font_style_symbolic (font, FONT_SLANT_INDEX, 0); + if (slant == Qnormal) + slant = Qnil; + else if (! NILP (slant)) + { + slant = SYMBOL_NAME (slant); + len += SBYTES (slant); + } + + size = AREF (font, FONT_SIZE_INDEX); + /* Convert pixel size to point size. */ + if (INTEGERP (size)) + { + Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX); + int dpi = 75; + if (INTEGERP (font_dpi)) + dpi = XINT (font_dpi); + else if (f) + dpi = f->resy; + point_size = PIXEL_TO_POINT (XINT (size), dpi); + len += 11; + } + else if (FLOATP (size)) + { + point_size = (int) XFLOAT_DATA (size); + len += 11; + } + + if (len > nbytes) + return -1; + + p = name + sprintf (name, "%s", SDATA (family)); + + if (! NILP (weight)) + { + char *q = p; + p += sprintf (p, " %s", SDATA (weight)); + q[1] = toupper (q[1]); + } + + if (! NILP (slant)) + { + char *q = p; + p += sprintf (p, " %s", SDATA (slant)); + q[1] = toupper (q[1]); + } + + if (point_size > 0) + p += sprintf (p, " %d", point_size); + + return (p - name); +} + /* Parse NAME (null terminated) and store information in FONT (font-spec or font-entity). If NAME is successfully parsed, return 0. Otherwise return -1. */ @@ -3659,6 +3769,75 @@ return Fcdr (Fassq (key, AREF (font, FONT_EXTRA_INDEX))); } +DEFUN ("font-face-attributes", Ffont_face_attributes, Sfont_face_attributes, 1, 2, 0, + doc: /* Return a plist of face attributes generated by FONT. +FONT is a font name, a font-spec, a font-entity, or a font-object. +The return value is a list of the form + +(:family FAMILY :height HEIGHT :weight WEIGHT :slant SLANT :width WIDTH) + +where FAMILY, FOUNDRY, HEIGHT, WEIGHT, SLANT, and WIDTH are face +attribute values compatible with `set-face-attribute'. + +The optional argument FRAME specifies the frame that the face +attributes are to be displayed on. If omitted, the selected frame is +used. */) + (font, frame) + Lisp_Object font; +{ + struct frame *f; + Lisp_Object plist[10]; + Lisp_Object val; + + if (NILP (frame)) + frame = selected_frame; + CHECK_LIVE_FRAME (frame); + f = XFRAME (frame); + + if (STRINGP (font)) + { + int fontset = fs_query_fontset (font, 0); + Lisp_Object name = font; + if (fontset >= 0) + font = fontset_ascii (fontset); + font = font_spec_from_name (name); + if (! FONTP (font)) + signal_error ("Invalid font name", name); + } + else if (! FONTP (font)) + signal_error ("Invalid font object", font); + + plist[0] = QCfamily; + val = AREF (font, FONT_FAMILY_INDEX); + plist[1] = NILP (val) ? Qnil : SYMBOL_NAME (val); + + plist[2] = QCheight; + val = AREF (font, FONT_SIZE_INDEX); + if (INTEGERP (val)) + { + Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX); + int dpi = INTEGERP (font_dpi) ? XINT (font_dpi) : f->resy; + plist[3] = make_number (10 * PIXEL_TO_POINT (XINT (val), dpi)); + } + else if (FLOATP (val)) + plist[3] = make_number (10 * (int) XFLOAT_DATA (val)); + else + plist[3] = Qnil; + + plist[4] = QCweight; + val = FONT_WEIGHT_FOR_FACE (font); + plist[5] = NILP (val) ? Qnormal : val; + + plist[6] = QCslant; + val = FONT_SLANT_FOR_FACE (font); + plist[7] = NILP (val) ? Qnormal : val; + + plist[8] = QCwidth; + val = FONT_WIDTH_FOR_FACE (font); + plist[9] = NILP (val) ? Qnormal : val; + + return Flist (10, plist); +} DEFUN ("font-put", Ffont_put, Sfont_put, 3, 3, 0, doc: /* Set one property of FONT-SPEC: give property PROP value VAL. */) @@ -4701,6 +4880,7 @@ defsubr (&Sfontp); defsubr (&Sfont_spec); defsubr (&Sfont_get); + defsubr (&Sfont_face_attributes); defsubr (&Sfont_put); defsubr (&Slist_fonts); defsubr (&Sfont_family_list);