| 1 | /* Header for composite sequence handler. |
| 2 | Copyright (C) 2001-2011 Free Software Foundation, Inc. |
| 3 | Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
| 4 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 5 | Registration Number H14PRO021 |
| 6 | Copyright (C) 2003, 2006 |
| 7 | National Institute of Advanced Industrial Science and Technology (AIST) |
| 8 | Registration Number H13PRO009 |
| 9 | |
| 10 | This file is part of GNU Emacs. |
| 11 | |
| 12 | GNU Emacs is free software: you can redistribute it and/or modify |
| 13 | it under the terms of the GNU General Public License as published by |
| 14 | the Free Software Foundation, either version 3 of the License, or |
| 15 | (at your option) any later version. |
| 16 | |
| 17 | GNU Emacs is distributed in the hope that it will be useful, |
| 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | GNU General Public License for more details. |
| 21 | |
| 22 | You should have received a copy of the GNU General Public License |
| 23 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 24 | |
| 25 | #ifndef EMACS_COMPOSITE_H |
| 26 | #define EMACS_COMPOSITE_H |
| 27 | |
| 28 | /* Methods to display a sequence of components of a composition. */ |
| 29 | enum composition_method { |
| 30 | /* Compose relatively without alternate characters. */ |
| 31 | COMPOSITION_RELATIVE, |
| 32 | /* Compose by specified composition rules. This is not used in |
| 33 | Emacs 21 but we need it to decode files saved in the older |
| 34 | versions of Emacs. */ |
| 35 | COMPOSITION_WITH_RULE, |
| 36 | /* Compose relatively with alternate characters. */ |
| 37 | COMPOSITION_WITH_ALTCHARS, |
| 38 | /* Compose by specified composition rules with alternate characters. */ |
| 39 | COMPOSITION_WITH_RULE_ALTCHARS, |
| 40 | /* This is not a method. */ |
| 41 | COMPOSITION_NO |
| 42 | }; |
| 43 | |
| 44 | /* Maximum number of compoments a single composition can have. */ |
| 45 | #define MAX_COMPOSITION_COMPONENTS 16 |
| 46 | |
| 47 | /* These macros access information about a composition that |
| 48 | has `composition' property PROP. PROP is: |
| 49 | ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) |
| 50 | or |
| 51 | (COMPOSITION-ID . (LENGTH COMPONENTS . MODIFICATION-FUNC)) |
| 52 | They don't check validity of PROP. */ |
| 53 | |
| 54 | /* Temporary variable used only in the following macros. */ |
| 55 | extern Lisp_Object composition_temp; |
| 56 | |
| 57 | /* Return 1 if the composition is already registered. */ |
| 58 | #define COMPOSITION_REGISTERD_P(prop) INTEGERP (XCAR (prop)) |
| 59 | |
| 60 | /* Return ID number of the already registered composition. */ |
| 61 | #define COMPOSITION_ID(prop) XINT (XCAR (prop)) |
| 62 | |
| 63 | /* Return length of the composition. */ |
| 64 | #define COMPOSITION_LENGTH(prop) \ |
| 65 | (COMPOSITION_REGISTERD_P (prop) \ |
| 66 | ? XINT (XCAR (XCDR (prop))) \ |
| 67 | : XINT (XCAR (XCAR (prop)))) |
| 68 | |
| 69 | /* Return components of the composition. */ |
| 70 | #define COMPOSITION_COMPONENTS(prop) \ |
| 71 | (COMPOSITION_REGISTERD_P (prop) \ |
| 72 | ? XCAR (XCDR (XCDR (prop))) \ |
| 73 | : XCDR (XCAR (prop))) |
| 74 | |
| 75 | /* Return modification function of the composition. */ |
| 76 | #define COMPOSITION_MODIFICATION_FUNC(prop) \ |
| 77 | (COMPOSITION_REGISTERD_P (prop) \ |
| 78 | ? XCDR (XCDR (XCDR (prop))) \ |
| 79 | : CONSP (prop) ? XCDR (prop) : Qnil) |
| 80 | |
| 81 | /* Return the method of composition. */ |
| 82 | #define COMPOSITION_METHOD(prop) \ |
| 83 | (COMPOSITION_REGISTERD_P (prop) \ |
| 84 | ? composition_table[COMPOSITION_ID (prop)]->method \ |
| 85 | : (composition_temp = XCDR (XCAR (prop)), \ |
| 86 | (NILP (composition_temp) \ |
| 87 | ? COMPOSITION_RELATIVE \ |
| 88 | : (INTEGERP (composition_temp) || STRINGP (composition_temp)) \ |
| 89 | ? COMPOSITION_WITH_ALTCHARS \ |
| 90 | : COMPOSITION_WITH_RULE_ALTCHARS))) |
| 91 | |
| 92 | /* Return 1 if the composition is valid. It is valid if length of |
| 93 | the composition equals to (END - START). */ |
| 94 | #define COMPOSITION_VALID_P(start, end, prop) \ |
| 95 | (CONSP (prop) \ |
| 96 | && (COMPOSITION_REGISTERD_P (prop) \ |
| 97 | ? (COMPOSITION_ID (prop) >= 0 \ |
| 98 | && COMPOSITION_ID (prop) <= n_compositions \ |
| 99 | && CONSP (XCDR (prop))) \ |
| 100 | : (composition_temp = XCAR (prop), \ |
| 101 | (CONSP (composition_temp) \ |
| 102 | && (composition_temp = XCDR (composition_temp), \ |
| 103 | (NILP (composition_temp) \ |
| 104 | || STRINGP (composition_temp) \ |
| 105 | || VECTORP (composition_temp) \ |
| 106 | || INTEGERP (composition_temp) \ |
| 107 | || CONSP (composition_temp)))))) \ |
| 108 | && (end - start) == COMPOSITION_LENGTH (prop)) |
| 109 | |
| 110 | /* Return the Nth glyph of composition specified by CMP. CMP is a |
| 111 | pointer to `struct composition'. */ |
| 112 | #define COMPOSITION_GLYPH(cmp, n) \ |
| 113 | XINT (XVECTOR (XVECTOR (XHASH_TABLE (composition_hash_table) \ |
| 114 | ->key_and_value) \ |
| 115 | ->contents[cmp->hash_index * 2]) \ |
| 116 | ->contents[cmp->method == COMPOSITION_WITH_RULE_ALTCHARS \ |
| 117 | ? (n) * 2 : (n)]) |
| 118 | |
| 119 | /* Return the encoded composition rule to compose the Nth glyph of |
| 120 | rule-base composition specified by CMP. CMP is a pointer to |
| 121 | `struct composition'. */ |
| 122 | #define COMPOSITION_RULE(cmp, n) \ |
| 123 | XINT (XVECTOR (XVECTOR (XHASH_TABLE (composition_hash_table) \ |
| 124 | ->key_and_value) \ |
| 125 | ->contents[cmp->hash_index * 2]) \ |
| 126 | ->contents[(n) * 2 - 1]) |
| 127 | |
| 128 | /* Decode encoded composition rule RULE_CODE into GREF (global |
| 129 | reference point code), NREF (new ref. point code). Don't check RULE_CODE; |
| 130 | always set GREF and NREF to valid values. By side effect, |
| 131 | RULE_CODE is modified. */ |
| 132 | |
| 133 | #define COMPOSITION_DECODE_REFS(rule_code, gref, nref) \ |
| 134 | do { \ |
| 135 | rule_code &= 0xFF; \ |
| 136 | gref = (rule_code) / 12; \ |
| 137 | if (gref > 12) gref = 11; \ |
| 138 | nref = (rule_code) % 12; \ |
| 139 | } while (0) |
| 140 | |
| 141 | /* Like COMPOSITION_DECODE_REFS (RULE_CODE, GREF, NREF), but also |
| 142 | decode RULE_CODE into XOFF and YOFF (vertical offset). */ |
| 143 | |
| 144 | #define COMPOSITION_DECODE_RULE(rule_code, gref, nref, xoff, yoff) \ |
| 145 | do { \ |
| 146 | xoff = (rule_code) >> 16; \ |
| 147 | yoff = ((rule_code) >> 8) & 0xFF; \ |
| 148 | COMPOSITION_DECODE_REFS (rule_code, gref, nref); \ |
| 149 | } while (0) |
| 150 | |
| 151 | /* Nonzero if the global reference point GREF and new reference point NREF are |
| 152 | valid. */ |
| 153 | #define COMPOSITION_ENCODE_RULE_VALID(gref, nref) \ |
| 154 | ((unsigned) (gref) < 12 && (unsigned) (nref) < 12) |
| 155 | |
| 156 | /* Return encoded composition rule for the pair of global reference |
| 157 | point GREF and new reference point NREF. Arguments must be valid. */ |
| 158 | #define COMPOSITION_ENCODE_RULE(gref, nref) \ |
| 159 | ((gref) * 12 + (nref)) |
| 160 | |
| 161 | /* Data structure that records information about a composition |
| 162 | currently used in some buffers or strings. |
| 163 | |
| 164 | When a composition is assigned an ID number (by |
| 165 | get_composition_id), this structure is allocated for the |
| 166 | composition and linked in composition_table[ID]. |
| 167 | |
| 168 | Identical compositions appearing at different places have the same |
| 169 | ID, and thus share the same instance of this structure. */ |
| 170 | |
| 171 | struct composition { |
| 172 | /* Number of glyphs of the composition components. */ |
| 173 | unsigned glyph_len; |
| 174 | |
| 175 | /* Width, ascent, and descent pixels of the composition. */ |
| 176 | short pixel_width, ascent, descent; |
| 177 | |
| 178 | short lbearing, rbearing; |
| 179 | |
| 180 | /* How many columns the overall glyphs occupy on the screen. This |
| 181 | gives an approximate value for column calculation in |
| 182 | Fcurrent_column, and etc. */ |
| 183 | unsigned short width; |
| 184 | |
| 185 | /* Method of the composition. */ |
| 186 | enum composition_method method; |
| 187 | |
| 188 | /* Index to the composition hash table. */ |
| 189 | EMACS_INT hash_index; |
| 190 | |
| 191 | /* For which font we have calculated the remaining members. The |
| 192 | actual type is device dependent. */ |
| 193 | void *font; |
| 194 | |
| 195 | /* Pointer to an array of x-offset and y-offset (by pixels) of |
| 196 | glyphs. This points to a sufficient memory space (sizeof (int) * |
| 197 | glyph_len * 2) that is allocated when the composition is |
| 198 | registered in composition_table. X-offset and Y-offset of Nth |
| 199 | glyph are (2N)th and (2N+1)th elements respectively. */ |
| 200 | short *offsets; |
| 201 | }; |
| 202 | |
| 203 | /* Table of pointers to the structure `composition' indexed by |
| 204 | COMPOSITION-ID. */ |
| 205 | extern struct composition **composition_table; |
| 206 | /* Number of the currently registered compositions. */ |
| 207 | extern int n_compositions; |
| 208 | |
| 209 | /* Mask bits for CHECK_MASK arg to update_compositions. |
| 210 | For a change in the region FROM and TO, check compositions ... */ |
| 211 | #define CHECK_HEAD 1 /* adjacent to FROM */ |
| 212 | #define CHECK_TAIL 2 /* adjacent to TO */ |
| 213 | #define CHECK_INSIDE 4 /* between FROM and TO */ |
| 214 | #define CHECK_BORDER (CHECK_HEAD | CHECK_TAIL) |
| 215 | #define CHECK_ALL (CHECK_BORDER | CHECK_INSIDE) |
| 216 | |
| 217 | extern Lisp_Object Qcomposition; |
| 218 | extern Lisp_Object composition_hash_table; |
| 219 | extern int get_composition_id (EMACS_INT, EMACS_INT, EMACS_INT, |
| 220 | Lisp_Object, Lisp_Object); |
| 221 | extern int find_composition (EMACS_INT, EMACS_INT, EMACS_INT *, EMACS_INT *, |
| 222 | Lisp_Object *, Lisp_Object); |
| 223 | extern void update_compositions (EMACS_INT, EMACS_INT, int); |
| 224 | extern void make_composition_value_copy (Lisp_Object); |
| 225 | extern void compose_region (int, int, Lisp_Object, Lisp_Object, |
| 226 | Lisp_Object); |
| 227 | extern void syms_of_composite (void); |
| 228 | extern void compose_text (EMACS_INT, EMACS_INT, Lisp_Object, Lisp_Object, |
| 229 | Lisp_Object); |
| 230 | |
| 231 | /* Macros for lispy glyph-string. This is completely different from |
| 232 | struct glyph_string. */ |
| 233 | |
| 234 | #define LGSTRING_HEADER(lgs) AREF (lgs, 0) |
| 235 | #define LGSTRING_SET_HEADER(lgs, header) ASET (lgs, 0, header) |
| 236 | |
| 237 | #define LGSTRING_FONT(lgs) AREF (LGSTRING_HEADER (lgs), 0) |
| 238 | #define LGSTRING_CHAR(lgs, i) AREF (LGSTRING_HEADER (lgs), (i) + 1) |
| 239 | #define LGSTRING_CHAR_LEN(lgs) (ASIZE (LGSTRING_HEADER (lgs)) - 1) |
| 240 | |
| 241 | #define LGSTRING_SET_FONT(lgs, val) ASET (LGSTRING_HEADER (lgs), 0, (val)) |
| 242 | #define LGSTRING_SET_CHAR(lgs, i, c) ASET (LGSTRING_HEADER (lgs), (i) + 1, (c)) |
| 243 | |
| 244 | #define LGSTRING_ID(lgs) AREF (lgs, 1) |
| 245 | #define LGSTRING_SET_ID(lgs, id) ASET (lgs, 1, id) |
| 246 | |
| 247 | #define LGSTRING_GLYPH_LEN(lgs) (ASIZE ((lgs)) - 2) |
| 248 | #define LGSTRING_GLYPH(lgs, idx) AREF ((lgs), (idx) + 2) |
| 249 | #define LGSTRING_SET_GLYPH(lgs, idx, val) ASET ((lgs), (idx) + 2, (val)) |
| 250 | |
| 251 | /* Vector size of Lispy glyph. */ |
| 252 | enum lglyph_indices |
| 253 | { |
| 254 | LGLYPH_IX_FROM, LGLYPH_IX_TO, LGLYPH_IX_CHAR, LGLYPH_IX_CODE, |
| 255 | LGLYPH_IX_WIDTH, LGLYPH_IX_LBEARING, LGLYPH_IX_RBEARING, |
| 256 | LGLYPH_IX_ASCENT, LGLYPH_IX_DESCENT, LGLYPH_IX_ADJUSTMENT, |
| 257 | /* Not an index. */ |
| 258 | LGLYPH_SIZE |
| 259 | }; |
| 260 | |
| 261 | #define LGLYPH_NEW() Fmake_vector (make_number (LGLYPH_SIZE), Qnil) |
| 262 | #define LGLYPH_FROM(g) XINT (AREF ((g), LGLYPH_IX_FROM)) |
| 263 | #define LGLYPH_TO(g) XINT (AREF ((g), LGLYPH_IX_TO)) |
| 264 | #define LGLYPH_CHAR(g) XINT (AREF ((g), LGLYPH_IX_CHAR)) |
| 265 | #define LGLYPH_CODE(g) \ |
| 266 | (NILP (AREF ((g), LGLYPH_IX_CODE)) \ |
| 267 | ? FONT_INVALID_CODE \ |
| 268 | : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned))) |
| 269 | #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) |
| 270 | #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) |
| 271 | #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) |
| 272 | #define LGLYPH_ASCENT(g) XINT (AREF ((g), LGLYPH_IX_ASCENT)) |
| 273 | #define LGLYPH_DESCENT(g) XINT (AREF ((g), LGLYPH_IX_DESCENT)) |
| 274 | #define LGLYPH_ADJUSTMENT(g) AREF ((g), LGLYPH_IX_ADJUSTMENT) |
| 275 | #define LGLYPH_SET_FROM(g, val) ASET ((g), LGLYPH_IX_FROM, make_number (val)) |
| 276 | #define LGLYPH_SET_TO(g, val) ASET ((g), LGLYPH_IX_TO, make_number (val)) |
| 277 | #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) |
| 278 | /* Callers must assure that VAL is not negative! */ |
| 279 | #define LGLYPH_SET_CODE(g, val) \ |
| 280 | ASET (g, LGLYPH_IX_CODE, \ |
| 281 | val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val)) |
| 282 | |
| 283 | #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) |
| 284 | #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) |
| 285 | #define LGLYPH_SET_RBEARING(g, val) ASET ((g), LGLYPH_IX_RBEARING, make_number (val)) |
| 286 | #define LGLYPH_SET_ASCENT(g, val) ASET ((g), LGLYPH_IX_ASCENT, make_number (val)) |
| 287 | #define LGLYPH_SET_DESCENT(g, val) ASET ((g), LGLYPH_IX_DESCENT, make_number (val)) |
| 288 | #define LGLYPH_SET_ADJUSTMENT(g, val) ASET ((g), LGLYPH_IX_ADJUSTMENT, (val)) |
| 289 | |
| 290 | #define LGLYPH_XOFF(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \ |
| 291 | ? XINT (AREF (LGLYPH_ADJUSTMENT (g), 0)) : 0) |
| 292 | #define LGLYPH_YOFF(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \ |
| 293 | ? XINT (AREF (LGLYPH_ADJUSTMENT (g), 1)) : 0) |
| 294 | #define LGLYPH_WADJUST(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \ |
| 295 | ? XINT (AREF (LGLYPH_ADJUSTMENT (g), 2)) : 0) |
| 296 | |
| 297 | struct composition_it; |
| 298 | struct face; |
| 299 | struct font_metrics; |
| 300 | |
| 301 | extern Lisp_Object composition_gstring_put_cache (Lisp_Object, EMACS_INT); |
| 302 | extern Lisp_Object composition_gstring_from_id (int); |
| 303 | extern int composition_gstring_p (Lisp_Object); |
| 304 | extern int composition_gstring_width (Lisp_Object, EMACS_INT, EMACS_INT, |
| 305 | struct font_metrics *); |
| 306 | |
| 307 | extern void composition_compute_stop_pos (struct composition_it *, |
| 308 | EMACS_INT, EMACS_INT, EMACS_INT, |
| 309 | Lisp_Object); |
| 310 | extern int composition_reseat_it (struct composition_it *, |
| 311 | EMACS_INT, EMACS_INT, EMACS_INT, |
| 312 | struct window *, struct face *, |
| 313 | Lisp_Object); |
| 314 | extern int composition_update_it (struct composition_it *, |
| 315 | EMACS_INT, EMACS_INT, Lisp_Object); |
| 316 | |
| 317 | extern EMACS_INT composition_adjust_point (EMACS_INT, EMACS_INT); |
| 318 | |
| 319 | #endif /* not EMACS_COMPOSITE_H */ |