aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2014-09-27 18:38:04 +0300
committerEli Zaretskii2014-09-27 18:38:04 +0300
commite8207eb00d5be19c9e3678cc9697504da60b68c5 (patch)
treeeb1db39a33c1c65cfb0d9bd10c599681baf700e8 /src
parentd51702fd71cf2d350c72079011075556f4eb6531 (diff)
downloademacs-e8207eb00d5be19c9e3678cc9697504da60b68c5.tar.gz
emacs-e8207eb00d5be19c9e3678cc9697504da60b68c5.zip
Finished writing code for isolates and fixed a few bugs (no parens yet).
Diffstat (limited to 'src')
-rw-r--r--src/bidi.c142
-rw-r--r--src/dispextern.h1
2 files changed, 100 insertions, 43 deletions
diff --git a/src/bidi.c b/src/bidi.c
index 5ef2dd1c31c..1cceccf0119 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -406,7 +406,7 @@ bidi_set_sos_type (struct bidi_it *bidi_it, int level_before, int level_after)
406 /* FIXME: should the default sos direction be user selectable? */ 406 /* FIXME: should the default sos direction be user selectable? */
407 bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R); /* X10 */ 407 bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R); /* X10 */
408 408
409 bidi_it->prev.type = UNKNOWN_BT; 409 bidi_it->prev.type = bidi_it->prev.type_after_w1 = UNKNOWN_BT;
410 bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 410 bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1
411 = bidi_it->last_strong.orig_type = UNKNOWN_BT; 411 = bidi_it->last_strong.orig_type = UNKNOWN_BT;
412 bidi_it->prev_for_neutral.type = (bidi_it->sos == R2L ? STRONG_R : STRONG_L); 412 bidi_it->prev_for_neutral.type = (bidi_it->sos == R2L ? STRONG_R : STRONG_L);
@@ -436,7 +436,6 @@ bidi_push_embedding_level (struct bidi_it *bidi_it,
436 st->last_strong = bidi_it->last_strong; 436 st->last_strong = bidi_it->last_strong;
437 st->prev_for_neutral = bidi_it->prev_for_neutral; 437 st->prev_for_neutral = bidi_it->prev_for_neutral;
438 st->next_for_neutral = bidi_it->next_for_neutral; 438 st->next_for_neutral = bidi_it->next_for_neutral;
439 st->next_for_ws = bidi_it->next_for_ws;
440 st->sos = bidi_it->sos; 439 st->sos = bidi_it->sos;
441 } 440 }
442} 441}
@@ -472,7 +471,6 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it)
472 bidi_it->last_strong = st.last_strong; 471 bidi_it->last_strong = st.last_strong;
473 bidi_it->prev_for_neutral = st.prev_for_neutral; 472 bidi_it->prev_for_neutral = st.prev_for_neutral;
474 bidi_it->next_for_neutral = st.next_for_neutral; 473 bidi_it->next_for_neutral = st.next_for_neutral;
475 bidi_it->next_for_ws = st.next_for_ws;
476 bidi_it->sos = st.sos; 474 bidi_it->sos = st.sos;
477 } 475 }
478 bidi_it->stack_idx--; 476 bidi_it->stack_idx--;
@@ -2003,8 +2001,8 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
2003 X10). */ 2001 X10). */
2004 bidi_set_sos_type (bidi_it, prev_level, new_level); 2002 bidi_set_sos_type (bidi_it, prev_level, new_level);
2005 } 2003 }
2006 else if (type == NEUTRAL_S || type == NEUTRAL_WS 2004 if (type == NEUTRAL_S || type == NEUTRAL_WS
2007 || type == WEAK_BN || type == STRONG_AL) 2005 || type == WEAK_BN || type == STRONG_AL)
2008 bidi_it->type_after_w1 = type; /* needed in L1 */ 2006 bidi_it->type_after_w1 = type; /* needed in L1 */
2009 bidi_check_type (bidi_it->type_after_w1); 2007 bidi_check_type (bidi_it->type_after_w1);
2010 2008
@@ -2025,12 +2023,20 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
2025 current level run, and thus not relevant to this NSM. 2023 current level run, and thus not relevant to this NSM.
2026 This is why NSM gets the type_after_w1 of the previous 2024 This is why NSM gets the type_after_w1 of the previous
2027 character. */ 2025 character. */
2026 /* bidi_set_sos_type sets type_after_w1 to UNKNOWN_BT. */
2028 if (bidi_it->prev.type_after_w1 != UNKNOWN_BT 2027 if (bidi_it->prev.type_after_w1 != UNKNOWN_BT
2029 /* if type_after_w1 is NEUTRAL_B, this NSM is at sos */ 2028 /* If type_after_w1 is NEUTRAL_B, this NSM is at sos. */
2030 && bidi_it->prev.type_after_w1 != NEUTRAL_B) 2029 && bidi_it->prev.type_after_w1 != NEUTRAL_B)
2031 { 2030 {
2032 if (bidi_isolate_fmt_char (bidi_it->prev.type_after_w1)) 2031 if (bidi_isolate_fmt_char (bidi_it->prev.type_after_w1))
2033 type = NEUTRAL_ON; 2032 {
2033 /* From W1: "Note that in an isolating run sequence,
2034 an isolate initiator followed by an NSM or any
2035 type other than PDI must be an overflow isolate
2036 initiator." */
2037 eassert (bidi_it->invalid_isolates > 0);
2038 type = NEUTRAL_ON;
2039 }
2034 else 2040 else
2035 type = bidi_it->prev.type_after_w1; 2041 type = bidi_it->prev.type_after_w1;
2036 } 2042 }
@@ -2071,8 +2077,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
2071 bidi_copy_it (&saved_it, bidi_it); 2077 bidi_copy_it (&saved_it, bidi_it);
2072 while (bidi_resolve_explicit (bidi_it) == new_level 2078 while (bidi_resolve_explicit (bidi_it) == new_level
2073 && bidi_it->type == WEAK_BN) 2079 && bidi_it->type == WEAK_BN)
2074 ; 2080 type_of_next = bidi_it->type;
2075 type_of_next = bidi_it->type;
2076 bidi_copy_it (bidi_it, &saved_it); 2081 bidi_copy_it (bidi_it, &saved_it);
2077 } 2082 }
2078 2083
@@ -2115,6 +2120,12 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
2115 } 2120 }
2116 else if (bidi_it->next_en_pos >=0) 2121 else if (bidi_it->next_en_pos >=0)
2117 { 2122 {
2123 /* We overstepped the last known position for ET
2124 resolution but there could be other such characters
2125 in this paragraph (when we are sure there are no more
2126 such positions, we set next_en_pos to a negative
2127 value). Try to find the next position for ET
2128 resolution. */
2118 ptrdiff_t en_pos = bidi_it->charpos + bidi_it->nchars; 2129 ptrdiff_t en_pos = bidi_it->charpos + bidi_it->nchars;
2119 const unsigned char *s = (STRINGP (bidi_it->string.lstring) 2130 const unsigned char *s = (STRINGP (bidi_it->string.lstring)
2120 ? SDATA (bidi_it->string.lstring) 2131 ? SDATA (bidi_it->string.lstring)
@@ -2137,9 +2148,20 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
2137 while (bidi_resolve_explicit (bidi_it) == new_level 2148 while (bidi_resolve_explicit (bidi_it) == new_level
2138 && (bidi_it->type == WEAK_BN 2149 && (bidi_it->type == WEAK_BN
2139 || bidi_it->type == WEAK_ET)) 2150 || bidi_it->type == WEAK_ET))
2140 ; 2151 type_of_next = bidi_it->type;
2141 type_of_next = bidi_it->type; 2152 if (type == WEAK_BN
2142 en_pos = bidi_it->charpos; 2153 && bidi_it->charpos == saved_it.charpos + saved_it.nchars)
2154 {
2155 /* If we entered the above loop with a BN that
2156 changes the level, the type of next
2157 character, which is in a different level, is
2158 not relevant to resolving this series of ET
2159 and BN. */
2160 en_pos = saved_it.charpos;
2161 type_of_next = type;
2162 }
2163 else
2164 en_pos = bidi_it->charpos;
2143 bidi_copy_it (bidi_it, &saved_it); 2165 bidi_copy_it (bidi_it, &saved_it);
2144 } 2166 }
2145 /* Remember this position, to speed up processing of the 2167 /* Remember this position, to speed up processing of the
@@ -2199,7 +2221,8 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
2199static bidi_type_t 2221static bidi_type_t
2200bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) 2222bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev)
2201{ 2223{
2202 /* N1: European and Arabic numbers are treated as though they were R. */ 2224 /* N1: "European and Arabic numbers act as if they were R in terms
2225 of their influence on NIs." */
2203 if (next_type == WEAK_EN || next_type == WEAK_AN) 2226 if (next_type == WEAK_EN || next_type == WEAK_AN)
2204 next_type = STRONG_R; 2227 next_type = STRONG_R;
2205 if (prev_type == WEAK_EN || prev_type == WEAK_AN) 2228 if (prev_type == WEAK_EN || prev_type == WEAK_AN)
@@ -2221,21 +2244,27 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
2221 int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; 2244 int current_level = bidi_it->level_stack[bidi_it->stack_idx].level;
2222 bool is_neutral = bidi_get_category (type) == NEUTRAL; 2245 bool is_neutral = bidi_get_category (type) == NEUTRAL;
2223 2246
2224 eassert ((type == STRONG_R 2247 eassert (type == STRONG_R
2225 || type == STRONG_L 2248 || type == STRONG_L
2226 || type == WEAK_BN 2249 || type == WEAK_BN
2227 || type == WEAK_EN 2250 || type == WEAK_EN
2228 || type == WEAK_AN 2251 || type == WEAK_AN
2229 || type == NEUTRAL_B 2252 || type == NEUTRAL_B
2230 || type == NEUTRAL_S 2253 || type == NEUTRAL_S
2231 || type == NEUTRAL_WS 2254 || type == NEUTRAL_WS
2232 || type == NEUTRAL_ON)); 2255 || type == NEUTRAL_ON
2256 || type == LRI
2257 || type == RLI
2258 || type == PDI);
2233 2259
2234 eassert (prev_level >= 0); 2260 eassert (prev_level >= 0);
2235 eassert (current_level >= 0); 2261 eassert (current_level >= 0);
2262
2263 /* FIXME: Insert the code for N0 here. */
2264
2236 if ((type != NEUTRAL_B /* Don't risk entering the long loop below if 2265 if ((type != NEUTRAL_B /* Don't risk entering the long loop below if
2237 we are already at paragraph end. */ 2266 we are already at paragraph end. */
2238 && is_neutral) 2267 && (is_neutral || bidi_isolate_fmt_char (type)))
2239 /* N1-N2/Retaining */ 2268 /* N1-N2/Retaining */
2240 || (type == WEAK_BN && bidi_explicit_dir_char (bidi_it->ch))) 2269 || (type == WEAK_BN && bidi_explicit_dir_char (bidi_it->ch)))
2241 { 2270 {
@@ -2258,7 +2287,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
2258 entering the expensive loop in the "else" clause. */ 2287 entering the expensive loop in the "else" clause. */
2259 else if (current_level == 0 2288 else if (current_level == 0
2260 && bidi_it->prev_for_neutral.type == STRONG_L 2289 && bidi_it->prev_for_neutral.type == STRONG_L
2261 && !bidi_explicit_dir_char (bidi_it->ch)) 2290 && !bidi_explicit_dir_char (bidi_it->ch)
2291 && !bidi_isolate_fmt_char (type))
2262 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, 2292 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type,
2263 STRONG_L, current_level); 2293 STRONG_L, current_level);
2264 else if (/* current level is 1 */ 2294 else if (/* current level is 1 */
@@ -2270,7 +2300,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
2270 && (bidi_it->prev_for_neutral.type == STRONG_R 2300 && (bidi_it->prev_for_neutral.type == STRONG_R
2271 || bidi_it->prev_for_neutral.type == WEAK_EN 2301 || bidi_it->prev_for_neutral.type == WEAK_EN
2272 || bidi_it->prev_for_neutral.type == WEAK_AN) 2302 || bidi_it->prev_for_neutral.type == WEAK_AN)
2273 && !bidi_explicit_dir_char (bidi_it->ch)) 2303 && !bidi_explicit_dir_char (bidi_it->ch)
2304 && !bidi_isolate_fmt_char (type))
2274 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, 2305 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type,
2275 STRONG_R, current_level); 2306 STRONG_R, current_level);
2276 else 2307 else
@@ -2295,32 +2326,43 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
2295 character, and then use that to resolve the neutral we 2326 character, and then use that to resolve the neutral we
2296 are dealing with now. We also cache the scanned iterator 2327 are dealing with now. We also cache the scanned iterator
2297 states, to salvage some of the effort later. */ 2328 states, to salvage some of the effort later. */
2298 bidi_cache_iterator_state (bidi_it, 0);
2299 do { 2329 do {
2330 /* Paragraph separators have their levels fully resolved
2331 at this point, so cache them as resolved. */
2332 bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B);
2300 /* Record the info about the previous character, so that 2333 /* Record the info about the previous character, so that
2301 it will be cached below with this state. */ 2334 it will be cached with this state. */
2302 if (bidi_it->type_after_w1 != WEAK_BN /* W1/Retaining */ 2335 if (bidi_it->type_after_w1 != WEAK_BN /* W1/Retaining */
2303 && bidi_it->type != WEAK_BN) 2336 && bidi_it->type != WEAK_BN)
2304 bidi_remember_char (&bidi_it->prev, bidi_it); 2337 bidi_remember_char (&bidi_it->prev, bidi_it);
2305 type = bidi_resolve_weak (bidi_it); 2338 type = bidi_resolve_weak (bidi_it);
2339 /* Skip level runs excluded from this isolating run sequence. */
2340 if (bidi_it->level_stack[bidi_it->stack_idx].level > current_level
2341 && bidi_it->level_stack[bidi_it->stack_idx].isolate_status)
2342 {
2343 while (bidi_it->level_stack[bidi_it->stack_idx].level
2344 > current_level)
2345 {
2346 bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B);
2347 type = bidi_resolve_weak (bidi_it);
2348 }
2349 }
2306 if (!adjacent_to_neutrals 2350 if (!adjacent_to_neutrals
2307 && bidi_get_category (type) == NEUTRAL) 2351 && (bidi_get_category (type) == NEUTRAL
2352 || bidi_isolate_fmt_char (type)))
2308 adjacent_to_neutrals = true; 2353 adjacent_to_neutrals = true;
2309 /* Paragraph separators have their levels fully resolved
2310 at this point, so cache them as resolved. */
2311 bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B);
2312 /* FIXME: implement L1 here, by testing for a newline and
2313 resetting the level for any sequence of whitespace
2314 characters adjacent to it. */
2315 } while (!(type == NEUTRAL_B 2354 } while (!(type == NEUTRAL_B
2316 || (type != WEAK_BN 2355 || (type != WEAK_BN
2317 && bidi_get_category (type) != NEUTRAL) 2356 && bidi_get_category (type) != NEUTRAL
2357 && !bidi_isolate_fmt_char (type))
2318 /* This is all per level run, so stop when we 2358 /* This is all per level run, so stop when we
2319 reach the end of this level run. */ 2359 reach the end of this level run. */
2320 || (bidi_it->level_stack[bidi_it->stack_idx].level 2360 || (bidi_it->level_stack[bidi_it->stack_idx].level
2321 != current_level))); 2361 != current_level)));
2322 2362
2363 /* Record the character we stopped at. */
2323 bidi_remember_char (&saved_it.next_for_neutral, bidi_it); 2364 bidi_remember_char (&saved_it.next_for_neutral, bidi_it);
2365
2324 if ((bidi_it->level_stack[bidi_it->stack_idx].level != current_level) 2366 if ((bidi_it->level_stack[bidi_it->stack_idx].level != current_level)
2325 || type == NEUTRAL_B) 2367 || type == NEUTRAL_B)
2326 { 2368 {
@@ -2352,8 +2394,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
2352 break; 2394 break;
2353 case WEAK_EN: 2395 case WEAK_EN:
2354 case WEAK_AN: 2396 case WEAK_AN:
2355 /* N1: ``European and Arabic numbers are treated as 2397 /* N1: "European and Arabic numbers act as if they
2356 though they were R.'' */ 2398 were R in terms of their influence on NIs." */
2357 next_type = STRONG_R; 2399 next_type = STRONG_R;
2358 break; 2400 break;
2359 default: 2401 default:
@@ -2361,12 +2403,17 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
2361 break; 2403 break;
2362 } 2404 }
2363 } 2405 }
2406 /* Resolve the type of all the NIs found during the above loop. */
2364 type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, 2407 type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type,
2365 next_type, current_level); 2408 next_type, current_level);
2409 /* Update next_for_neutral with the resolved type, so we
2410 could use it for all the other NIs up to the place where
2411 we exited the loop. */
2366 saved_it.next_for_neutral.type = next_type; 2412 saved_it.next_for_neutral.type = next_type;
2413 bidi_check_type (type);
2414 /* Update the character which caused us to enter the above loop. */
2367 saved_it.type = type; 2415 saved_it.type = type;
2368 bidi_check_type (next_type); 2416 bidi_check_type (next_type);
2369 bidi_check_type (type);
2370 bidi_copy_it (bidi_it, &saved_it); 2417 bidi_copy_it (bidi_it, &saved_it);
2371 } 2418 }
2372 } 2419 }
@@ -2402,6 +2449,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2402 int level, prev_level = -1; 2449 int level, prev_level = -1;
2403 struct bidi_saved_info next_for_neutral; 2450 struct bidi_saved_info next_for_neutral;
2404 ptrdiff_t next_char_pos = -2; 2451 ptrdiff_t next_char_pos = -2;
2452 bool need_to_update_cache = false;
2405 2453
2406 if (bidi_it->scan_dir == 1) 2454 if (bidi_it->scan_dir == 1)
2407 { 2455 {
@@ -2519,6 +2567,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2519 eassert (bidi_it->resolved_level >= 0); 2567 eassert (bidi_it->resolved_level >= 0);
2520 return bidi_it->resolved_level; 2568 return bidi_it->resolved_level;
2521 } 2569 }
2570 else
2571 {
2572 /* Take note when we've got a cached state that is not fully
2573 resolved, so that we could make sure we update the cache
2574 below, when we do resolve it. */
2575 need_to_update_cache = true;
2576 }
2522 } 2577 }
2523 if (bidi_it->scan_dir == -1) 2578 if (bidi_it->scan_dir == -1)
2524 /* If we are going backwards, the iterator state is already cached 2579 /* If we are going backwards, the iterator state is already cached
@@ -2535,7 +2590,8 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2535 } 2590 }
2536 2591
2537 level = bidi_it->level_stack[bidi_it->stack_idx].level; 2592 level = bidi_it->level_stack[bidi_it->stack_idx].level;
2538 if (bidi_get_category (type) == NEUTRAL /* && type != NEUTRAL_B */) 2593 if (bidi_get_category (type) == NEUTRAL /* && type != NEUTRAL_B */
2594 || bidi_isolate_fmt_char (type))
2539 { 2595 {
2540 if (bidi_it->next_for_neutral.type == UNKNOWN_BT) 2596 if (bidi_it->next_for_neutral.type == UNKNOWN_BT)
2541 emacs_abort (); 2597 emacs_abort ();
@@ -2558,7 +2614,8 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2558 /* For L1 below, we need to know, for each WS character, whether 2614 /* For L1 below, we need to know, for each WS character, whether
2559 it belongs to a sequence of WS characters preceding a newline 2615 it belongs to a sequence of WS characters preceding a newline
2560 or a TAB or a paragraph separator. */ 2616 or a TAB or a paragraph separator. */
2561 if (bidi_it->orig_type == NEUTRAL_WS 2617 if ((bidi_it->orig_type == NEUTRAL_WS
2618 || bidi_isolate_fmt_char (bidi_it->orig_type))
2562 && bidi_it->next_for_ws.type == UNKNOWN_BT) 2619 && bidi_it->next_for_ws.type == UNKNOWN_BT)
2563 { 2620 {
2564 int ch; 2621 int ch;
@@ -2579,6 +2636,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2579 bidi_it->w, fwp, &clen, &nc); 2636 bidi_it->w, fwp, &clen, &nc);
2580 chtype = bidi_get_type (ch, NEUTRAL_DIR); 2637 chtype = bidi_get_type (ch, NEUTRAL_DIR);
2581 } while (chtype == NEUTRAL_WS || chtype == WEAK_BN 2638 } while (chtype == NEUTRAL_WS || chtype == WEAK_BN
2639 || bidi_isolate_fmt_char (chtype)
2582 || bidi_explicit_dir_char (ch)); /* L1/Retaining */ 2640 || bidi_explicit_dir_char (ch)); /* L1/Retaining */
2583 bidi_it->next_for_ws.type = chtype; 2641 bidi_it->next_for_ws.type = chtype;
2584 bidi_check_type (bidi_it->next_for_ws.type); 2642 bidi_check_type (bidi_it->next_for_ws.type);
@@ -2607,9 +2665,9 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2607 level++; 2665 level++;
2608 } 2666 }
2609 2667
2610 /* FIXME: Exempt explicit directional characters from the assignment
2611 below, and remove the PDF hack above. */
2612 bidi_it->resolved_level = level; 2668 bidi_it->resolved_level = level;
2669 if (need_to_update_cache)
2670 bidi_cache_iterator_state (bidi_it, 1);
2613 return level; 2671 return level;
2614} 2672}
2615 2673
diff --git a/src/dispextern.h b/src/dispextern.h
index c823194bd6b..d61b2a388d5 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1915,7 +1915,6 @@ struct bidi_stack {
1915 struct bidi_saved_info last_strong; 1915 struct bidi_saved_info last_strong;
1916 struct bidi_saved_info next_for_neutral; 1916 struct bidi_saved_info next_for_neutral;
1917 struct bidi_saved_info prev_for_neutral; 1917 struct bidi_saved_info prev_for_neutral;
1918 struct bidi_saved_info next_for_ws;
1919 unsigned level : 7; 1918 unsigned level : 7;
1920 bool_bf isolate_status : 1; 1919 bool_bf isolate_status : 1;
1921 unsigned override : 2; 1920 unsigned override : 2;