Mercurial > emacs
changeset 109349:c82f3023b7f2
Make font-get to get :otf value dynamically from a font-object.
author | Kenichi Handa <handa@etlken> |
---|---|
date | Thu, 08 Jul 2010 16:56:21 +0900 |
parents | 52a665d72788 |
children | c11d07f3d731 |
files | src/font.c src/font.h |
diffstat | 2 files changed, 167 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/src/font.c Thu Jul 01 15:26:36 2010 +0900 +++ b/src/font.c Thu Jul 08 16:56:21 2010 +0900 @@ -3078,7 +3078,7 @@ return Qnil; ASET (entity, FONT_OBJLIST_INDEX, Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX))); - ASET (font_object, FONT_OBJLIST_INDEX, Qnil); + ASET (font_object, FONT_ENTITY_INDEX, entity); num_fonts++; font = XFONT_OBJECT (font_object); @@ -4231,16 +4231,25 @@ DEFUN ("font-get", Ffont_get, Sfont_get, 2, 2, 0, doc: /* Return the value of FONT's property KEY. FONT is a font-spec, a font-entity, or a font-object. -KEY must be one of these symbols: +KEY is any symbol, but these are reserved for specific meanings: :family, :weight, :slant, :width, :foundry, :adstyle, :registry, - :size, :name, :script + :size, :name, :script, :otf See the documentation of `font-spec' for their meanings. -If FONT is a font-entity or font-object, the value of :script may be -a list of scripts that are supported by the font. */) +In addition, if FONT is a font-entity or a font-object, values of +:script and :otf are different from those of a font-spec as below: + +The value of :script may be a list of scripts that are supported by the font. + +The value of :otf is a cons (GSUB . GPOS) where GSUB and GPOS are lists +representing the OpenType features supported by the font by this form: + ((SCRIPT (LANGSYS FEATURE ...) ...) ...) +SCRIPT, LANGSYS, and FEATURE are all symbols representing OpenType +Layout tags. */) (font, key) Lisp_Object font, key; { int idx; + Lisp_Object val; CHECK_FONT (font); CHECK_SYMBOL (key); @@ -4250,7 +4259,28 @@ return font_style_symbolic (font, idx, 0); if (idx >= 0 && idx < FONT_EXTRA_INDEX) return AREF (font, idx); - return Fcdr (Fassq (key, AREF (font, FONT_EXTRA_INDEX))); + val = Fassq (key, AREF (font, FONT_EXTRA_INDEX)); + if (NILP (val) && EQ (key, QCotf) && FONT_OBJECT_P (font)) + { + struct font *fontp = XFONT_OBJECT (font); + Lisp_Object entity = AREF (font, FONT_ENTITY_INDEX); + + val = Fassq (key, AREF (entity, FONT_EXTRA_INDEX)); + if (NILP (val)) + { + if (fontp->driver->otf_capability) + val = fontp->driver->otf_capability (fontp); + else + val = Fcons (Qnil, Qnil); + font_put_extra (font, QCotf, val); + font_put_extra (entity, QCotf, val); + } + else + val = Fcdr (val); + } + else + val = Fcdr (val); + return val; } #ifdef HAVE_WINDOW_SYSTEM @@ -4342,18 +4372,37 @@ #endif DEFUN ("font-put", Ffont_put, Sfont_put, 3, 3, 0, - doc: /* Set one property of FONT-SPEC: give property PROP value VAL. */) - (font_spec, prop, val) - Lisp_Object font_spec, prop, val; + doc: /* Set one property of FONT: give property KEY value VAL. +FONT is a font-spec, a font-entity, or a font-object. + +If FONT is a font-spec, KEY can be any symbol. But if KEY is the one +accepted by the function `font-spec' (which see), VAL must be what +allowed in `font-spec'. + +If FONT is a font-entity or a font-object, KEY must not be the one +accepted by `font-spec'. */) + (font, prop, val) + Lisp_Object font, prop, val; { int idx; - CHECK_FONT_SPEC (font_spec); idx = get_font_prop_index (prop); if (idx >= 0 && idx < FONT_EXTRA_INDEX) - ASET (font_spec, idx, font_prop_validate (idx, Qnil, val)); + { + CHECK_FONT_SPEC (font); + ASET (font, idx, font_prop_validate (idx, Qnil, val)); + } else - font_put_extra (font_spec, prop, font_prop_validate (0, prop, val)); + { + if (EQ (prop, QCname) + || EQ (prop, QCscript) + || EQ (prop, QClang) + || EQ (prop, QCotf)) + CHECK_FONT_SPEC (font); + else + CHECK_FONT (font); + font_put_extra (font, prop, font_prop_validate (0, prop, val)); + } return val; } @@ -4906,25 +4955,99 @@ return val; } -DEFUN ("get-font-glyphs", Fget_font_glyphs, Sget_font_glyphs, 2, 2, 0, - doc: /* Return a vector of glyphs of FONT-OBJECT for drawing STRING. -Each element is a vector [GLYPH-CODE LBEARING RBEARING WIDTH ASCENT DESCENT]. */) - (font_object, string) - Lisp_Object font_object, string; +DEFUN ("font-get-glyphs", Ffont_get_glyphs, Sfont_get_glyphs, 3, 4, 0, + doc: + /* Return a vector of FONT-OBJECT's glyphs for the specified characters. +FROM and TO are positions (integers or markers) specifying a region +of the current buffer. +If the optional fourth arg OBJECT is not nil, it is a string or a +vector containing the target characters. + +Each element is a vector containing information of a glyph in this format: + [FROM-IDX TO-IDX C CODE WIDTH LBEARING RBEARING ASCENT DESCENT ADJUSTMENT] +where + FROM is an index numbers of a character the glyph corresponds to. + TO is the same as FROM. + C is the character of the glyph. + CODE is the glyph-code of C in FONT-OBJECT. + WIDTH thru DESCENT are the metrics (in pixels) of the glyph. + ADJUSTMENT is always nil. +If FONT-OBJECT doesn't have a glyph for a character, +the corresponding element is nil. */) + (font_object, from, to, object) + Lisp_Object font_object, from, to, object; { struct font *font; - int i, len; - Lisp_Object vec; + int i, len, c; + Lisp_Object *chars, vec; + USE_SAFE_ALLOCA; CHECK_FONT_GET_OBJECT (font_object, font); - CHECK_STRING (string); - len = SCHARS (string); + if (NILP (object)) + { + EMACS_INT charpos, bytepos; + + validate_region (&from, &to); + if (EQ (from, to)) + return Qnil; + len = XFASTINT (to) - XFASTINT (from); + SAFE_ALLOCA_LISP (chars, len); + charpos = XFASTINT (from); + bytepos = CHAR_TO_BYTE (charpos); + for (i = 0; charpos < XFASTINT (to); i++) + { + FETCH_CHAR_ADVANCE (c, charpos, bytepos); + chars[i] = make_number (c); + } + } + else if (STRINGP (object)) + { + const unsigned char *p; + + CHECK_NUMBER (from); + CHECK_NUMBER (to); + if (XINT (from) < 0 || XINT (from) > XINT (to) + || XINT (to) > SCHARS (object)) + args_out_of_range_3 (object, from, to); + if (EQ (from, to)) + return Qnil; + len = XFASTINT (to) - XFASTINT (from); + SAFE_ALLOCA_LISP (chars, len); + p = SDATA (object); + if (STRING_MULTIBYTE (object)) + for (i = 0; i < len; i++) + { + c = STRING_CHAR_ADVANCE (p); + chars[i] = make_number (c); + } + else + for (i = 0; i < len; i++) + chars[i] = make_number (p[i]); + } + else + { + CHECK_VECTOR (object); + CHECK_NUMBER (from); + CHECK_NUMBER (to); + if (XINT (from) < 0 || XINT (from) > XINT (to) + || XINT (to) > ASIZE (object)) + args_out_of_range_3 (object, from, to); + if (EQ (from, to)) + return Qnil; + len = XFASTINT (to) - XFASTINT (from); + for (i = 0; i < len; i++) + { + Lisp_Object elt = AREF (object, XFASTINT (from) + i); + CHECK_CHARACTER (elt); + } + chars = &(AREF (object, XFASTINT (from))); + } + vec = Fmake_vector (make_number (len), Qnil); for (i = 0; i < len; i++) { - Lisp_Object ch = Faref (string, make_number (i)); - Lisp_Object val; - int c = XINT (ch); + Lisp_Object g; + int c = XFASTINT (chars[i]); unsigned code; EMACS_INT cod; struct font_metrics metrics; @@ -4932,20 +5055,21 @@ cod = code = font->driver->encode_char (font, c); if (code == FONT_INVALID_CODE) continue; - val = Fmake_vector (make_number (6), Qnil); - if (cod <= MOST_POSITIVE_FIXNUM) - ASET (val, 0, make_number (code)); - else - ASET (val, 0, Fcons (make_number (code >> 16), - make_number (code & 0xFFFF))); + g = Fmake_vector (make_number (LGLYPH_SIZE), Qnil); + LGLYPH_SET_FROM (g, i); + LGLYPH_SET_TO (g, i); + LGLYPH_SET_CHAR (g, c); + LGLYPH_SET_CODE (g, code); font->driver->text_extents (font, &code, 1, &metrics); - ASET (val, 1, make_number (metrics.lbearing)); - ASET (val, 2, make_number (metrics.rbearing)); - ASET (val, 3, make_number (metrics.width)); - ASET (val, 4, make_number (metrics.ascent)); - ASET (val, 5, make_number (metrics.descent)); - ASET (vec, i, val); + LGLYPH_SET_WIDTH (g, metrics.width); + LGLYPH_SET_LBEARING (g, metrics.lbearing); + LGLYPH_SET_RBEARING (g, metrics.rbearing); + LGLYPH_SET_ASCENT (g, metrics.ascent); + LGLYPH_SET_DESCENT (g, metrics.descent); + ASET (vec, i, g); } + if (! VECTORP (object)) + SAFE_FREE (); return vec; } @@ -5347,7 +5471,7 @@ defsubr (&Sopen_font); defsubr (&Sclose_font); defsubr (&Squery_font); - defsubr (&Sget_font_glyphs); + defsubr (&Sfont_get_glyphs); defsubr (&Sfont_match_p); defsubr (&Sfont_at); #if 0
--- a/src/font.h Thu Jul 01 15:26:36 2010 +0900 +++ b/src/font.h Thu Jul 08 16:56:21 2010 +0900 @@ -159,14 +159,19 @@ /* This value is the length of font-spec vector. */ FONT_SPEC_MAX, - /* The followings are used only for a font-entity. */ + /* The followings are used only for a font-entity and a font-object. */ /* List of font-objects opened from the font-entity. */ FONT_OBJLIST_INDEX = FONT_SPEC_MAX, + /* Font-entity from which the font-object is opened. */ + FONT_ENTITY_INDEX = FONT_SPEC_MAX, + /* This value is the length of font-entity vector. */ FONT_ENTITY_MAX, + /* The followings are used only for a font-object. */ + /* XLFD name of the font (string). */ FONT_NAME_INDEX = FONT_ENTITY_MAX,