diff options
| author | Kenichi Handa | 2006-07-24 04:42:53 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2006-07-24 04:42:53 +0000 |
| commit | 10d16101060a14542ce23344ef897d5b7ec81562 (patch) | |
| tree | c3a98557ac378540bb880764ceeb3312dc1705e8 /src | |
| parent | fcc1aec2970a41996982af76c4acd4085846326f (diff) | |
| download | emacs-10d16101060a14542ce23344ef897d5b7ec81562.tar.gz emacs-10d16101060a14542ce23344ef897d5b7ec81562.zip | |
Include window.h.
(font_lispy_object): New function.
(font_prepare_composition): Check LGLYPH_FORM (g) to detect the
end of valid glyph.
(font_close_object): Fix getting (struct font *).
(font_at): New function.
(Ffont_get): If FONT is a font-object, get entity from it.
(Ffont_make_gstring): Initialize elements of glyphs with nil.
(Ffont_fill_gstring): Use macro LGSTRING_XXX and LGLYPH_XXX. Fix
range check.
(Ffont_at): New function.
(syms_of_font): Defsubr Sfont_at.
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.c | 142 |
1 files changed, 114 insertions, 28 deletions
diff --git a/src/font.c b/src/font.c index 80e23b4ec67..eddea78f8d6 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -29,6 +29,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 29 | #include "lisp.h" | 29 | #include "lisp.h" |
| 30 | #include "buffer.h" | 30 | #include "buffer.h" |
| 31 | #include "frame.h" | 31 | #include "frame.h" |
| 32 | #include "window.h" | ||
| 32 | #include "dispextern.h" | 33 | #include "dispextern.h" |
| 33 | #include "charset.h" | 34 | #include "charset.h" |
| 34 | #include "character.h" | 35 | #include "character.h" |
| @@ -1416,6 +1417,23 @@ font_merge_old_spec (name, family, registry, spec) | |||
| 1416 | } | 1417 | } |
| 1417 | } | 1418 | } |
| 1418 | 1419 | ||
| 1420 | static Lisp_Object | ||
| 1421 | font_lispy_object (font) | ||
| 1422 | struct font *font; | ||
| 1423 | { | ||
| 1424 | Lisp_Object objlist = AREF (font->entity, FONT_OBJLIST_INDEX); | ||
| 1425 | |||
| 1426 | for (; ! NILP (objlist); objlist = XCDR (objlist)) | ||
| 1427 | { | ||
| 1428 | struct Lisp_Save_Value *p = XSAVE_VALUE (XCAR (objlist)); | ||
| 1429 | |||
| 1430 | if (font == (struct font *) p->pointer) | ||
| 1431 | break; | ||
| 1432 | } | ||
| 1433 | xassert (! NILP (objlist)); | ||
| 1434 | return XCAR (objlist); | ||
| 1435 | } | ||
| 1436 | |||
| 1419 | 1437 | ||
| 1420 | /* OTF handler */ | 1438 | /* OTF handler */ |
| 1421 | 1439 | ||
| @@ -1843,7 +1861,7 @@ font_otf_gpos (font, gpos_spec, gstring, from, to) | |||
| 1843 | /* GSTRING is a vector of this form: | 1861 | /* GSTRING is a vector of this form: |
| 1844 | [ [FONT-OBJECT LBEARING RBEARING WIDTH ASCENT DESCENT] GLYPH ... ] | 1862 | [ [FONT-OBJECT LBEARING RBEARING WIDTH ASCENT DESCENT] GLYPH ... ] |
| 1845 | and GLYPH is a vector of this form: | 1863 | and GLYPH is a vector of this form: |
| 1846 | [ FROM-IDX TO-IDX C CODE [ [X-OFF Y-OFF WIDTH WADJUST] | nil] ] | 1864 | [ FROM-IDX TO-IDX C CODE WIDTH [ [X-OFF Y-OFF WADJUST] | nil] ] |
| 1847 | where | 1865 | where |
| 1848 | FROM-IDX and TO-IDX are used internally and should not be touched. | 1866 | FROM-IDX and TO-IDX are used internally and should not be touched. |
| 1849 | C is a character of the glyph. | 1867 | C is a character of the glyph. |
| @@ -1871,9 +1889,12 @@ font_prepare_composition (cmp) | |||
| 1871 | for (i = 0; i < len; i++) | 1889 | for (i = 0; i < len; i++) |
| 1872 | { | 1890 | { |
| 1873 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); | 1891 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); |
| 1874 | unsigned code = XINT (LGLYPH_CODE (g)); | 1892 | unsigned code; |
| 1875 | struct font_metrics metrics; | 1893 | struct font_metrics metrics; |
| 1876 | 1894 | ||
| 1895 | if (NILP (LGLYPH_FROM (g))) | ||
| 1896 | break; | ||
| 1897 | code = XINT (LGLYPH_CODE (g)); | ||
| 1877 | font->driver->text_extents (font, &code, 1, &metrics); | 1898 | font->driver->text_extents (font, &code, 1, &metrics); |
| 1878 | LGLYPH_SET_WIDTH (g, make_number (metrics.width)); | 1899 | LGLYPH_SET_WIDTH (g, make_number (metrics.width)); |
| 1879 | metrics.lbearing += LGLYPH_XOFF (g); | 1900 | metrics.lbearing += LGLYPH_XOFF (g); |
| @@ -2316,30 +2337,30 @@ font_close_object (f, font_object) | |||
| 2316 | FRAME_PTR f; | 2337 | FRAME_PTR f; |
| 2317 | Lisp_Object font_object; | 2338 | Lisp_Object font_object; |
| 2318 | { | 2339 | { |
| 2319 | struct font *font; | 2340 | struct font *font = XSAVE_VALUE (font_object)->pointer; |
| 2320 | Lisp_Object objlist = AREF (font->entity, FONT_OBJLIST_INDEX); | 2341 | Lisp_Object objlist; |
| 2321 | Lisp_Object tail, prev = Qnil; | 2342 | Lisp_Object tail, prev = Qnil; |
| 2322 | 2343 | ||
| 2344 | XSAVE_VALUE (font_object)->integer--; | ||
| 2345 | xassert (XSAVE_VALUE (font_object)->integer >= 0); | ||
| 2346 | if (XSAVE_VALUE (font_object)->integer > 0) | ||
| 2347 | return; | ||
| 2348 | |||
| 2349 | objlist = AREF (font->entity, FONT_OBJLIST_INDEX); | ||
| 2323 | for (prev = Qnil, tail = objlist; CONSP (tail); | 2350 | for (prev = Qnil, tail = objlist; CONSP (tail); |
| 2324 | prev = tail, tail = XCDR (tail)) | 2351 | prev = tail, tail = XCDR (tail)) |
| 2325 | if (EQ (font_object, XCAR (tail))) | 2352 | if (EQ (font_object, XCAR (tail))) |
| 2326 | { | 2353 | { |
| 2327 | struct Lisp_Save_Value *p = XSAVE_VALUE (font_object); | 2354 | if (font->driver->close) |
| 2328 | 2355 | font->driver->close (f, font); | |
| 2329 | xassert (p->integer > 0); | 2356 | XSAVE_VALUE (font_object)->pointer = NULL; |
| 2330 | p->integer--; | 2357 | if (NILP (prev)) |
| 2331 | if (p->integer == 0) | 2358 | ASET (font->entity, FONT_OBJLIST_INDEX, XCDR (objlist)); |
| 2332 | { | 2359 | else |
| 2333 | if (font->driver->close) | 2360 | XSETCDR (prev, XCDR (objlist)); |
| 2334 | font->driver->close (f, p->pointer); | 2361 | return; |
| 2335 | p->pointer = NULL; | ||
| 2336 | if (NILP (prev)) | ||
| 2337 | ASET (font->entity, FONT_OBJLIST_INDEX, XCDR (objlist)); | ||
| 2338 | else | ||
| 2339 | XSETCDR (prev, XCDR (objlist)); | ||
| 2340 | } | ||
| 2341 | break; | ||
| 2342 | } | 2362 | } |
| 2363 | abort (); | ||
| 2343 | } | 2364 | } |
| 2344 | 2365 | ||
| 2345 | int | 2366 | int |
| @@ -2678,6 +2699,36 @@ free_font_driver_list (f) | |||
| 2678 | } | 2699 | } |
| 2679 | } | 2700 | } |
| 2680 | 2701 | ||
| 2702 | Lisp_Object | ||
| 2703 | font_at (c, pos, face, w, object) | ||
| 2704 | int c; | ||
| 2705 | EMACS_INT pos; | ||
| 2706 | struct face *face; | ||
| 2707 | struct window *w; | ||
| 2708 | Lisp_Object object; | ||
| 2709 | { | ||
| 2710 | FRAME_PTR f; | ||
| 2711 | int face_id; | ||
| 2712 | int dummy; | ||
| 2713 | |||
| 2714 | f = XFRAME (w->frame); | ||
| 2715 | if (! face) | ||
| 2716 | { | ||
| 2717 | if (STRINGP (object)) | ||
| 2718 | face_id = face_at_string_position (w, object, pos, 0, -1, -1, &dummy, | ||
| 2719 | DEFAULT_FACE_ID, 0); | ||
| 2720 | else | ||
| 2721 | face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, | ||
| 2722 | pos + 100, 0); | ||
| 2723 | face = FACE_FROM_ID (f, face_id); | ||
| 2724 | } | ||
| 2725 | face_id = FACE_FOR_CHAR (f, face, c, pos, object); | ||
| 2726 | face = FACE_FROM_ID (f, face_id); | ||
| 2727 | if (! face->font_info) | ||
| 2728 | return Qnil; | ||
| 2729 | return font_lispy_object ((struct font *) face->font_info); | ||
| 2730 | } | ||
| 2731 | |||
| 2681 | 2732 | ||
| 2682 | /* Lisp API */ | 2733 | /* Lisp API */ |
| 2683 | 2734 | ||
| @@ -2732,7 +2783,10 @@ If FONT is font-entity and PROP is :extra, always nil is returned. */) | |||
| 2732 | { | 2783 | { |
| 2733 | enum font_property_index idx; | 2784 | enum font_property_index idx; |
| 2734 | 2785 | ||
| 2735 | CHECK_FONT (font); | 2786 | if (FONT_OBJECT_P (font)) |
| 2787 | font = ((struct font *) XSAVE_VALUE (font)->pointer)->entity; | ||
| 2788 | else | ||
| 2789 | CHECK_FONT (font); | ||
| 2736 | idx = get_font_prop_index (prop, 0); | 2790 | idx = get_font_prop_index (prop, 0); |
| 2737 | if (idx < FONT_EXTRA_INDEX) | 2791 | if (idx < FONT_EXTRA_INDEX) |
| 2738 | return AREF (font, idx); | 2792 | return AREF (font, idx); |
| @@ -2998,7 +3052,7 @@ FONT-OBJECT may be nil if it is not yet known. */) | |||
| 2998 | ASET (g, 0, font_object); | 3052 | ASET (g, 0, font_object); |
| 2999 | ASET (gstring, 0, g); | 3053 | ASET (gstring, 0, g); |
| 3000 | for (i = 1; i < len; i++) | 3054 | for (i = 1; i < len; i++) |
| 3001 | ASET (gstring, i, Fmake_vector (make_number (8), make_number (0))); | 3055 | ASET (gstring, i, Fmake_vector (make_number (8), Qnil)); |
| 3002 | return gstring; | 3056 | return gstring; |
| 3003 | } | 3057 | } |
| 3004 | 3058 | ||
| @@ -3017,7 +3071,7 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3017 | 3071 | ||
| 3018 | CHECK_VECTOR (gstring); | 3072 | CHECK_VECTOR (gstring); |
| 3019 | if (NILP (font_object)) | 3073 | if (NILP (font_object)) |
| 3020 | font_object = Faref (Faref (gstring, make_number (0)), make_number (0)); | 3074 | font_object = LGSTRING_FONT (gstring); |
| 3021 | CHECK_FONT_GET_OBJECT (font_object, font); | 3075 | CHECK_FONT_GET_OBJECT (font_object, font); |
| 3022 | 3076 | ||
| 3023 | if (STRINGP (object)) | 3077 | if (STRINGP (object)) |
| @@ -3028,7 +3082,7 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3028 | CHECK_NATNUM (end); | 3082 | CHECK_NATNUM (end); |
| 3029 | if (XINT (start) > XINT (end) | 3083 | if (XINT (start) > XINT (end) |
| 3030 | || XINT (end) > ASIZE (object) | 3084 | || XINT (end) > ASIZE (object) |
| 3031 | || XINT (end) - XINT (start) >= XINT (Flength (gstring))) | 3085 | || XINT (end) - XINT (start) > LGSTRING_LENGTH (gstring)) |
| 3032 | args_out_of_range (start, end); | 3086 | args_out_of_range (start, end); |
| 3033 | 3087 | ||
| 3034 | len = XINT (end) - XINT (start); | 3088 | len = XINT (end) - XINT (start); |
| @@ -3041,8 +3095,8 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3041 | code = font->driver->encode_char (font, c); | 3095 | code = font->driver->encode_char (font, c); |
| 3042 | if (code > MOST_POSITIVE_FIXNUM) | 3096 | if (code > MOST_POSITIVE_FIXNUM) |
| 3043 | error ("Glyph code 0x%X is too large", code); | 3097 | error ("Glyph code 0x%X is too large", code); |
| 3044 | ASET (g, 0, make_number (i)); | 3098 | LGLYPH_SET_FROM (g, make_number (i)); |
| 3045 | ASET (g, 1, make_number (i + 1)); | 3099 | LGLYPH_SET_TO (g, make_number (i + 1)); |
| 3046 | LGLYPH_SET_CHAR (g, make_number (c)); | 3100 | LGLYPH_SET_CHAR (g, make_number (c)); |
| 3047 | LGLYPH_SET_CODE (g, make_number (code)); | 3101 | LGLYPH_SET_CODE (g, make_number (code)); |
| 3048 | } | 3102 | } |
| @@ -3054,7 +3108,7 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3054 | if (! NILP (object)) | 3108 | if (! NILP (object)) |
| 3055 | Fset_buffer (object); | 3109 | Fset_buffer (object); |
| 3056 | validate_region (&start, &end); | 3110 | validate_region (&start, &end); |
| 3057 | if (XINT (end) - XINT (start) > len) | 3111 | if (XINT (end) - XINT (start) > LGSTRING_LENGTH (gstring)) |
| 3058 | args_out_of_range (start, end); | 3112 | args_out_of_range (start, end); |
| 3059 | len = XINT (end) - XINT (start); | 3113 | len = XINT (end) - XINT (start); |
| 3060 | pos = XINT (start); | 3114 | pos = XINT (start); |
| @@ -3067,12 +3121,18 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3067 | code = font->driver->encode_char (font, c); | 3121 | code = font->driver->encode_char (font, c); |
| 3068 | if (code > MOST_POSITIVE_FIXNUM) | 3122 | if (code > MOST_POSITIVE_FIXNUM) |
| 3069 | error ("Glyph code 0x%X is too large", code); | 3123 | error ("Glyph code 0x%X is too large", code); |
| 3070 | ASET (g, 0, make_number (i)); | 3124 | LGLYPH_SET_FROM (g, make_number (i)); |
| 3071 | ASET (g, 1, make_number (i + 1)); | 3125 | LGLYPH_SET_TO (g, make_number (i + 1)); |
| 3072 | LGLYPH_SET_CHAR (g, make_number (c)); | 3126 | LGLYPH_SET_CHAR (g, make_number (c)); |
| 3073 | LGLYPH_SET_CODE (g, make_number (code)); | 3127 | LGLYPH_SET_CODE (g, make_number (code)); |
| 3074 | } | 3128 | } |
| 3075 | } | 3129 | } |
| 3130 | for (i = LGSTRING_LENGTH (gstring) - 1; i >= len; i--) | ||
| 3131 | { | ||
| 3132 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); | ||
| 3133 | |||
| 3134 | LGLYPH_SET_FROM (g, Qnil); | ||
| 3135 | } | ||
| 3076 | return Qnil; | 3136 | return Qnil; |
| 3077 | } | 3137 | } |
| 3078 | 3138 | ||
| @@ -3199,6 +3259,31 @@ FONT is a font-spec, font-entity, or font-object. */) | |||
| 3199 | return (font_match_p (spec, font) ? Qt : Qnil); | 3259 | return (font_match_p (spec, font) ? Qt : Qnil); |
| 3200 | } | 3260 | } |
| 3201 | 3261 | ||
| 3262 | DEFUN ("font-at", Ffont_at, Sfont_at, 1, 2, 0, | ||
| 3263 | doc: /* Return a font-object for displaying a character at POSISTION. | ||
| 3264 | Optional second arg WINDOW, if non-nil, is a window displaying | ||
| 3265 | the current buffer. It defaults to the currently selected window. */) | ||
| 3266 | (position, window) | ||
| 3267 | Lisp_Object position, window; | ||
| 3268 | { | ||
| 3269 | struct window *w; | ||
| 3270 | EMACS_INT pos, pos_byte; | ||
| 3271 | int c; | ||
| 3272 | |||
| 3273 | CHECK_NUMBER_COERCE_MARKER (position); | ||
| 3274 | pos = XINT (position); | ||
| 3275 | if (pos < BEGV || pos >= ZV) | ||
| 3276 | args_out_of_range_3 (position, make_number (BEGV), make_number (ZV)); | ||
| 3277 | pos_byte = CHAR_TO_BYTE (pos); | ||
| 3278 | c = FETCH_CHAR (pos_byte); | ||
| 3279 | if (NILP (window)) | ||
| 3280 | window = selected_window; | ||
| 3281 | CHECK_LIVE_WINDOW (window); | ||
| 3282 | w = XWINDOW (selected_window); | ||
| 3283 | |||
| 3284 | return font_at (c, pos, NULL, w, Qnil); | ||
| 3285 | } | ||
| 3286 | |||
| 3202 | #if 0 | 3287 | #if 0 |
| 3203 | DEFUN ("draw-string", Fdraw_string, Sdraw_string, 2, 2, 0, | 3288 | DEFUN ("draw-string", Fdraw_string, Sdraw_string, 2, 2, 0, |
| 3204 | doc: /* Draw STRING by FONT-OBJECT on the top left corner of the current frame. | 3289 | doc: /* Draw STRING by FONT-OBJECT on the top left corner of the current frame. |
| @@ -3323,6 +3408,7 @@ syms_of_font () | |||
| 3323 | defsubr (&Squery_font); | 3408 | defsubr (&Squery_font); |
| 3324 | defsubr (&Sget_font_glyphs); | 3409 | defsubr (&Sget_font_glyphs); |
| 3325 | defsubr (&Sfont_match_p); | 3410 | defsubr (&Sfont_match_p); |
| 3411 | defsubr (&Sfont_at); | ||
| 3326 | #if 0 | 3412 | #if 0 |
| 3327 | defsubr (&Sdraw_string); | 3413 | defsubr (&Sdraw_string); |
| 3328 | #endif | 3414 | #endif |