aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2006-07-24 04:42:53 +0000
committerKenichi Handa2006-07-24 04:42:53 +0000
commit10d16101060a14542ce23344ef897d5b7ec81562 (patch)
treec3a98557ac378540bb880764ceeb3312dc1705e8 /src
parentfcc1aec2970a41996982af76c4acd4085846326f (diff)
downloademacs-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.c142
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
1420static Lisp_Object
1421font_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
2345int 2366int
@@ -2678,6 +2699,36 @@ free_font_driver_list (f)
2678 } 2699 }
2679} 2700}
2680 2701
2702Lisp_Object
2703font_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
3262DEFUN ("font-at", Ffont_at, Sfont_at, 1, 2, 0,
3263 doc: /* Return a font-object for displaying a character at POSISTION.
3264Optional second arg WINDOW, if non-nil, is a window displaying
3265the 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
3203DEFUN ("draw-string", Fdraw_string, Sdraw_string, 2, 2, 0, 3288DEFUN ("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