Mercurial > emacs
comparison src/xdisp.c @ 107604:9e8415b885ee
Retrospective commit from 2009-12-12.
Begin working on faces support. First version of handle_stop_backwards.
Rearrange struct bidi_it for more efficient push/pop ops.
dispextern.h (struct it): New members prev_stop and
base_level_stop.
xdisp.c (handle_stop_backwards): New function.
(next_element_from_buffer): Handle the situation where we
overstepped stop_charpos due to non-linearity of the bidi
iteration. Likewise for when we back up beyond the previous
stop_charpos.
(reseat_1, pop_it, push_it): Set prev_stop and base_level_stop.
dispextern.h (BIDI_AT_BASE_LEVEL): New macro.
bidi.c (bidi_copy_it): Fix compiler warning due to cast of a
pointer to `int'. Don't preserve the first_elt member, as it is
no longer copied, because its position in the structure was
changed, see below.
dispextern.h (struct bidi_it): Move first_elt, new_paragraph,
separator_limit, and paragraph_dir to after bidi_stack. Add a
note that anything beyond the level stack is not preserved when
the bidi iterator state is copied/saved.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Fri, 01 Jan 2010 09:46:25 -0500 |
parents | 0e2486128193 |
children | 297c59e52ecf |
comparison
equal
deleted
inserted
replaced
107603:0e2486128193 | 107604:9e8415b885ee |
---|---|
2657 it->dp = window_display_table (w); | 2657 it->dp = window_display_table (w); |
2658 | 2658 |
2659 /* Are multibyte characters enabled in current_buffer? */ | 2659 /* Are multibyte characters enabled in current_buffer? */ |
2660 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); | 2660 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); |
2661 | 2661 |
2662 /* Do we need to reorded bidirectional text? */ | 2662 /* Do we need to reorder bidirectional text? */ |
2663 it->bidi_p = !NILP (current_buffer->bidi_display_reordering); | 2663 it->bidi_p = !NILP (current_buffer->bidi_display_reordering); |
2664 | 2664 |
2665 /* Non-zero if we should highlight the region. */ | 2665 /* Non-zero if we should highlight the region. */ |
2666 highlight_region_p | 2666 highlight_region_p |
2667 = (!NILP (Vtransient_mark_mode) | 2667 = (!NILP (Vtransient_mark_mode) |
5141 | 5141 |
5142 xassert (it->sp < IT_STACK_SIZE); | 5142 xassert (it->sp < IT_STACK_SIZE); |
5143 p = it->stack + it->sp; | 5143 p = it->stack + it->sp; |
5144 | 5144 |
5145 p->stop_charpos = it->stop_charpos; | 5145 p->stop_charpos = it->stop_charpos; |
5146 p->prev_stop = it->prev_stop; | |
5147 p->base_level_stop = it->base_level_stop; | |
5146 p->cmp_it = it->cmp_it; | 5148 p->cmp_it = it->cmp_it; |
5147 xassert (it->face_id >= 0); | 5149 xassert (it->face_id >= 0); |
5148 p->face_id = it->face_id; | 5150 p->face_id = it->face_id; |
5149 p->string = it->string; | 5151 p->string = it->string; |
5150 p->method = it->method; | 5152 p->method = it->method; |
5191 | 5193 |
5192 xassert (it->sp > 0); | 5194 xassert (it->sp > 0); |
5193 --it->sp; | 5195 --it->sp; |
5194 p = it->stack + it->sp; | 5196 p = it->stack + it->sp; |
5195 it->stop_charpos = p->stop_charpos; | 5197 it->stop_charpos = p->stop_charpos; |
5198 it->prev_stop = p->prev_stop; | |
5199 it->base_level_stop = p->base_level_stop; | |
5196 it->cmp_it = p->cmp_it; | 5200 it->cmp_it = p->cmp_it; |
5197 it->face_id = p->face_id; | 5201 it->face_id = p->face_id; |
5198 it->current = p->current; | 5202 it->current = p->current; |
5199 it->position = p->position; | 5203 it->position = p->position; |
5200 it->string = p->string; | 5204 it->string = p->string; |
5567 it->face_before_selective_p = 0; | 5571 it->face_before_selective_p = 0; |
5568 if (it->bidi_p) | 5572 if (it->bidi_p) |
5569 it->bidi_it.first_elt = 1; | 5573 it->bidi_it.first_elt = 1; |
5570 | 5574 |
5571 if (set_stop_p) | 5575 if (set_stop_p) |
5572 it->stop_charpos = CHARPOS (pos); | 5576 { |
5577 it->stop_charpos = CHARPOS (pos); | |
5578 it->base_level_stop = CHARPOS (pos); | |
5579 } | |
5573 } | 5580 } |
5574 | 5581 |
5575 | 5582 |
5576 /* Set up IT for displaying a string, starting at CHARPOS in window W. | 5583 /* Set up IT for displaying a string, starting at CHARPOS in window W. |
5577 If S is non-null, it is a C string to iterate over. Otherwise, | 5584 If S is non-null, it is a C string to iterate over. Otherwise, |
5671 | 5678 |
5672 | 5679 |
5673 | 5680 |
5674 /*********************************************************************** | 5681 /*********************************************************************** |
5675 Iteration | 5682 Iteration |
5676 ***********************************************************************/ | 5683 ***********************************************************************/ |
5677 | 5684 |
5678 /* Map enum it_method value to corresponding next_element_from_* function. */ | 5685 /* Map enum it_method value to corresponding next_element_from_* function. */ |
5679 | 5686 |
5680 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) = | 5687 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) = |
5681 { | 5688 { |
5744 if (success_p && it->dpvec == NULL) | 5751 if (success_p && it->dpvec == NULL) |
5745 { | 5752 { |
5746 Lisp_Object dv; | 5753 Lisp_Object dv; |
5747 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); | 5754 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); |
5748 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } | 5755 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } |
5749 nbsp_or_shy = char_is_other; | 5756 nbsp_or_shy = char_is_other; |
5750 int decoded = it->c; | 5757 int decoded = it->c; |
5751 | 5758 |
5752 if (it->dp | 5759 if (it->dp |
5753 && (dv = DISP_CHAR_VECTOR (it->dp, it->c), | 5760 && (dv = DISP_CHAR_VECTOR (it->dp, it->c), |
5754 VECTORP (dv))) | 5761 VECTORP (dv))) |
5962 { | 5969 { |
5963 /* It's an invalid character, which shouldn't | 5970 /* It's an invalid character, which shouldn't |
5964 happen actually, but due to bugs it may | 5971 happen actually, but due to bugs it may |
5965 happen. Let's print the char as is, there's | 5972 happen. Let's print the char as is, there's |
5966 not much meaningful we can do with it. */ | 5973 not much meaningful we can do with it. */ |
5967 str[0] = it->c; | 5974 str[0] = it->c; |
5968 str[1] = it->c >> 8; | 5975 str[1] = it->c >> 8; |
5969 str[2] = it->c >> 16; | 5976 str[2] = it->c >> 16; |
5970 str[3] = it->c >> 24; | 5977 str[3] = it->c >> 24; |
5971 len = 4; | 5978 len = 4; |
5972 } | 5979 } |
5973 | 5980 |
5974 for (i = 0; i < len; i++) | 5981 for (i = 0; i < len; i++) |
5975 { | 5982 { |
5976 int g; | 5983 int g; |
5977 XSETINT (it->ctl_chars[i * 4], escape_glyph); | 5984 XSETINT (it->ctl_chars[i * 4], escape_glyph); |
6304 xassert (it->dpvec && it->current.dpvec_index >= 0); | 6311 xassert (it->dpvec && it->current.dpvec_index >= 0); |
6305 | 6312 |
6306 it->face_id = it->saved_face_id; | 6313 it->face_id = it->saved_face_id; |
6307 | 6314 |
6308 /* KFS: This code used to check ip->dpvec[0] instead of the current element. | 6315 /* KFS: This code used to check ip->dpvec[0] instead of the current element. |
6309 That seemed totally bogus - so I changed it... */ | 6316 That seemed totally bogus - so I changed it... */ |
6310 gc = it->dpvec[it->current.dpvec_index]; | 6317 gc = it->dpvec[it->current.dpvec_index]; |
6311 | 6318 |
6312 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc)) | 6319 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc)) |
6313 { | 6320 { |
6314 it->c = GLYPH_CODE_CHAR (gc); | 6321 it->c = GLYPH_CODE_CHAR (gc); |
6539 { | 6546 { |
6540 it->what = IT_STRETCH; | 6547 it->what = IT_STRETCH; |
6541 return 1; | 6548 return 1; |
6542 } | 6549 } |
6543 | 6550 |
6551 /* Scan forward from CHARPOS in the current buffer, until we find a | |
6552 stop position > current IT's position, handling all the stop | |
6553 positions in between. | |
6554 | |
6555 This is called when we are reordering bidirectional text. The | |
6556 caller should save and restore IT and in particular the bidi_p | |
6557 flag, because this function modifies them. */ | |
6558 | |
6559 static void | |
6560 handle_stop_backwards (it, charpos) | |
6561 struct it *it; | |
6562 EMACS_INT charpos; | |
6563 { | |
6564 struct text_pos pos1; | |
6565 EMACS_INT where_we_are = IT_CHARPOS (*it); | |
6566 | |
6567 /* Scan in strict logical order. */ | |
6568 it->bidi_p = 0; | |
6569 do | |
6570 { | |
6571 it->prev_stop = charpos; | |
6572 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos)); | |
6573 reseat_1 (it, pos1, 0); | |
6574 handle_stop (it); | |
6575 /* We must advance forward, right? */ | |
6576 if (it->stop_charpos <= it->prev_stop) | |
6577 abort (); | |
6578 } | |
6579 while (it->stop_charpos <= where_we_are); | |
6580 } | |
6544 | 6581 |
6545 /* Load IT with the next display element from current_buffer. Value | 6582 /* Load IT with the next display element from current_buffer. Value |
6546 is zero if end of buffer reached. IT->stop_charpos is the next | 6583 is zero if end of buffer reached. IT->stop_charpos is the next |
6547 position at which to stop and check for text properties or buffer | 6584 position at which to stop and check for text properties or buffer |
6548 end. */ | 6585 end. */ |
6629 it->what = IT_EOB; | 6666 it->what = IT_EOB; |
6630 it->position = it->current.pos; | 6667 it->position = it->current.pos; |
6631 success_p = 0; | 6668 success_p = 0; |
6632 } | 6669 } |
6633 } | 6670 } |
6671 else if (it->bidi_p && !BIDI_AT_BASE_LEVEL (it->bidi_it)) | |
6672 { | |
6673 /* With bidi non-linear iteration, we could find ourselves | |
6674 far beyond the last computed stop_charpos, with several | |
6675 other stop positions in between that we missed. Scan | |
6676 them all now, in buffer's logical order. */ | |
6677 struct it save_it = *it; | |
6678 | |
6679 handle_stop_backwards (it, it->stop_charpos); | |
6680 save_it.stop_charpos = it->stop_charpos; | |
6681 save_it.prev_stop = it->prev_stop; | |
6682 *it = save_it; | |
6683 return GET_NEXT_DISPLAY_ELEMENT (it); | |
6684 } | |
6634 else | 6685 else |
6635 { | 6686 { |
6636 handle_stop (it); | 6687 handle_stop (it); |
6688 /* We are at base paragraph embedding level, so take note of | |
6689 the last stop_pos seen at this level. */ | |
6690 it->base_level_stop = it->stop_charpos; | |
6637 return GET_NEXT_DISPLAY_ELEMENT (it); | 6691 return GET_NEXT_DISPLAY_ELEMENT (it); |
6638 } | 6692 } |
6693 } | |
6694 else if (it->bidi_p && IT_CHARPOS (*it) < it->prev_stop) | |
6695 { | |
6696 struct it save_it = *it; | |
6697 | |
6698 if (it->base_level_stop <= 0) | |
6699 abort (); | |
6700 if (IT_CHARPOS (*it) < it->base_level_stop) | |
6701 abort (); | |
6702 if (BIDI_AT_BASE_LEVEL (it->bidi_it)) | |
6703 abort (); | |
6704 handle_stop_backwards (it, it->base_level_stop); | |
6705 save_it.stop_charpos = it->stop_charpos; | |
6706 save_it.prev_stop = it->prev_stop; | |
6707 *it = save_it; | |
6708 return GET_NEXT_DISPLAY_ELEMENT (it); | |
6639 } | 6709 } |
6640 else | 6710 else |
6641 { | 6711 { |
6642 /* No face changes, overlays etc. in sight, so just return a | 6712 /* No face changes, overlays etc. in sight, so just return a |
6643 character from current_buffer. */ | 6713 character from current_buffer. */ |