comparison src/font.c @ 90541:b7130e76c2f9

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.
author Kenichi Handa <handa@m17n.org>
date Mon, 24 Jul 2006 04:42:53 +0000
parents 76d717f9ceda
children 5dab62a4573c
comparison
equal deleted inserted replaced
90540:a4c3599e9f9b 90541:b7130e76c2f9
27 #include <ctype.h> 27 #include <ctype.h>
28 28
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"
35 #include "composite.h" 36 #include "composite.h"
36 #include "fontset.h" 37 #include "fontset.h"
1414 ASET (spec, FONT_REGISTRY_INDEX, 1415 ASET (spec, FONT_REGISTRY_INDEX,
1415 intern_downcase ((char *) SDATA (registry), SBYTES (registry))); 1416 intern_downcase ((char *) SDATA (registry), SBYTES (registry)));
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
1422 #ifdef HAVE_LIBOTF 1440 #ifdef HAVE_LIBOTF
1423 #include <otf.h> 1441 #include <otf.h>
1841 /* glyph-string handler */ 1859 /* glyph-string handler */
1842 1860
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.
1850 CODE is a glyph-code of C in FONT-OBJECT. 1868 CODE is a glyph-code of C in FONT-OBJECT.
1851 X-OFF and Y-OFF are offests to the base position for the glyph. 1869 X-OFF and Y-OFF are offests to the base position for the glyph.
1869 cmp->descent = font->descent; 1887 cmp->descent = font->descent;
1870 1888
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);
1880 metrics.rbearing += LGLYPH_XOFF (g); 1901 metrics.rbearing += LGLYPH_XOFF (g);
1881 metrics.ascent += LGLYPH_YOFF (g); 1902 metrics.ascent += LGLYPH_YOFF (g);
2314 void 2335 void
2315 font_close_object (f, font_object) 2336 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
2346 font_has_char (f, font, c) 2367 font_has_char (f, font, c)
2347 FRAME_PTR f; 2368 FRAME_PTR f;
2676 free (f->font_driver_list); 2697 free (f->font_driver_list);
2677 f->font_driver_list = next; 2698 f->font_driver_list = next;
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
2684 DEFUN ("fontp", Ffontp, Sfontp, 1, 1, 0, 2735 DEFUN ("fontp", Ffontp, Sfontp, 1, 1, 0,
2685 doc: /* Return t if object is a font-spec or font-entity. */) 2736 doc: /* Return t if object is a font-spec or font-entity. */)
2730 (font, prop) 2781 (font, prop)
2731 Lisp_Object font, prop; 2782 Lisp_Object font, prop;
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);
2739 if (FONT_ENTITY_P (font)) 2793 if (FONT_ENTITY_P (font))
2740 return Qnil; 2794 return Qnil;
2996 gstring = Fmake_vector (make_number (len), Qnil); 3050 gstring = Fmake_vector (make_number (len), Qnil);
2997 g = Fmake_vector (make_number (6), Qnil); 3051 g = Fmake_vector (make_number (6), Qnil);
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
3005 DEFUN ("font-fill-gstring", Ffont_fill_gstring, Sfont_fill_gstring, 4, 5, 0, 3059 DEFUN ("font-fill-gstring", Ffont_fill_gstring, Sfont_fill_gstring, 4, 5, 0,
3006 doc: /* Fillin glyph-string GSTRING by characters for FONT-OBJECT. 3060 doc: /* Fillin glyph-string GSTRING by characters for FONT-OBJECT.
3015 unsigned code; 3069 unsigned code;
3016 struct font *font; 3070 struct font *font;
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))
3024 { 3078 {
3025 const unsigned char *p; 3079 const unsigned char *p;
3026 3080
3027 CHECK_NATNUM (start); 3081 CHECK_NATNUM (start);
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);
3035 p = SDATA (object) + string_char_to_byte (object, XINT (start)); 3089 p = SDATA (object) + string_char_to_byte (object, XINT (start));
3036 for (i = 0; i < len; i++) 3090 for (i = 0; i < len; i++)
3039 3093
3040 c = STRING_CHAR_ADVANCE (p); 3094 c = STRING_CHAR_ADVANCE (p);
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 }
3049 } 3103 }
3050 else 3104 else
3052 int pos, pos_byte; 3106 int pos, pos_byte;
3053 3107
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);
3061 pos_byte = CHAR_TO_BYTE (pos); 3115 pos_byte = CHAR_TO_BYTE (pos);
3062 for (i = 0; i < len; i++) 3116 for (i = 0; i < len; i++)
3065 3119
3066 FETCH_CHAR_ADVANCE (c, pos, pos_byte); 3120 FETCH_CHAR_ADVANCE (c, pos, pos_byte);
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 }
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);
3075 } 3135 }
3076 return Qnil; 3136 return Qnil;
3077 } 3137 }
3078 3138
3079 3139
3197 CHECK_FONT_SPEC (font); 3257 CHECK_FONT_SPEC (font);
3198 3258
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.
3205 The value is a number of glyphs drawn. 3290 The value is a number of glyphs drawn.
3206 Type C-l to recover what previously shown. */) 3291 Type C-l to recover what previously shown. */)
3321 defsubr (&Sopen_font); 3406 defsubr (&Sopen_font);
3322 defsubr (&Sclose_font); 3407 defsubr (&Sclose_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
3329 #endif /* FONT_DEBUG */ 3415 #endif /* FONT_DEBUG */
3330 3416