Mercurial > emacs
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 |