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. */