- pos = generate_fstring_runes (w, data, pos, pos, max_pos,
- XCDR (elt), depth - 1,
- max_pixsize, new_findex, type,
- offset, car);
- data->findex = old_findex;
- Dynarr_add (formatted_string_extent_dynarr, ext);
- Dynarr_add (formatted_string_extent_start_dynarr, start);
- Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
- }
- }
- }
- else if (GLYPHP (elt))
- {
- /* Glyphs are considered as one character with respect to the modeline
- horizontal scrolling facility. -- dv */
- if (*offset > 0)
- *offset -= 1;
- else
- pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos,
- cur_ext);
- }
- else
- {
- invalid:
- {
- char *str = GETTEXT ("*invalid*");
- Charcount size = (Charcount) strlen (str); /* is this ok ?? -- dv */
-
- if (size <= *offset)
- *offset -= size;
- else
- {
- CONST Bufbyte *tmp_str =
- charptr_n_addr ((CONST Bufbyte *) str, *offset);
-
- /* ### NOTE: I don't understand why a tmp_max is not computed and
- used here as in the plain string case above. -- dv */
- pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
- min_pos, max_pos);
- *offset = 0;
- }
- }
- }
-
- if (min_pos > pos)
- {
- add_string_to_fstring_db_runes (data, (CONST Bufbyte *) "", pos,
- min_pos, -1);
- }
-
- return pos;
-}
-
-/* Update just the modeline. Assumes the desired display structs. If
- they do not have a modeline block, it does nothing. */
-static void
-regenerate_modeline (struct window *w)
-{
- display_line_dynarr *dla = window_display_lines (w, DESIRED_DISP);
-
- if (!Dynarr_length (dla) || !Dynarr_atp (dla, 0)->modeline)
- return;
- else
- {
- generate_modeline (w, Dynarr_atp (dla, 0), DESIRED_DISP);
- redisplay_update_line (w, 0, 0, 0);
- }
-}
-
-/* Make sure that modeline display line is present in the given
- display structs if the window has a modeline and update that
- line. Returns true if a modeline was needed. */
-static int
-ensure_modeline_generated (struct window *w, int type)
-{
- int need_modeline;
-
- /* minibuffer windows don't have modelines */
- if (MINI_WINDOW_P (w))
- need_modeline = 0;
- /* windows which haven't had it turned off do */
- else if (WINDOW_HAS_MODELINE_P (w))
- need_modeline = 1;
- /* windows which have it turned off don't have a divider if there is
- a horizontal scrollbar */
- else if (window_scrollbar_height (w))
- need_modeline = 0;
- /* and in this case there is none */
- else
- need_modeline = 1;
-
- if (need_modeline)
- {
- display_line_dynarr *dla;
-
- dla = window_display_lines (w, type);
-
- /* We don't care if there is a display line which is not
- currently a modeline because it is definitely going to become
- one if we have gotten to this point. */
- if (Dynarr_length (dla) == 0)
- {
- if (Dynarr_largest (dla) > 0)
- {
- struct display_line *mlp = Dynarr_atp (dla, 0);
- Dynarr_add (dla, *mlp);
- }
- else
- {
- struct display_line modeline;
- xzero (modeline);
- Dynarr_add (dla, modeline);
- }
- }
-
- /* If we're adding a new place marker go ahead and generate the
- modeline so that it is available for use by
- window_modeline_height. */
- generate_modeline (w, Dynarr_atp (dla, 0), type);
- }
-
- return need_modeline;
-}
-
-/* #### Kludge or not a kludge. I tend towards the former. */
-int
-real_current_modeline_height (struct window *w)
-{
- Fset_marker (w->start[CMOTION_DISP], w->start[CURRENT_DISP], w->buffer);
- Fset_marker (w->pointm[CMOTION_DISP], w->pointm[CURRENT_DISP], w->buffer);
-
- if (ensure_modeline_generated (w, CMOTION_DISP))
- {
- display_line_dynarr *dla = window_display_lines (w, CMOTION_DISP);
-
- if (Dynarr_length (dla))
- {
- if (Dynarr_atp (dla, 0)->modeline)
- return (Dynarr_atp (dla, 0)->ascent +
- Dynarr_atp (dla, 0)->descent);
- }
- }
- return 0;
-}
-
-\f
-/***************************************************************************/
-/* */
-/* displayable string routines */
-/* */
-/***************************************************************************/
-
-/* Given a position for a string in a window, ensure that the given
- display line DL accurately represents the text on a line starting
- at the given position.
-
- Yes, this is duplicating the code of create_text_block, but it
- looked just too hard to change create_text_block to handle strings
- *and* buffers. We already make a distinction between the two
- elsewhere in the code so I think unifying them would require a
- complete MULE rewrite. Besides, the other distinction is that these
- functions cover text that the user *cannot edit* so we can remove
- everything to do with cursors, minibuffers etc. Eventually the
- modeline routines should be modified to use this code as it copes
- with many more types of display situation. */
-
-static Bufpos
-create_string_text_block (struct window *w, Lisp_Object disp_string,
- struct display_line *dl,
- Bufpos start_pos,
- prop_block_dynarr **prop,
- face_index default_face)
-{
- struct frame *f = XFRAME (w->frame);
- /* Note that a lot of the buffer controlled stuff has been left in
- because you might well want to make use of it (selective display
- etc), its just the buffer text that we do not use. However, it
- seems to be possible for buffer to be nil sometimes so protect
- against this case. */
- struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
- struct device *d = XDEVICE (f->device);
- struct Lisp_String* s = XSTRING (disp_string);
-
- /* we're working with these a lot so precalculate them */
- Bytecount slen = XSTRING_LENGTH (disp_string);
- Bytecount bi_string_zv = slen;
- Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
-
- pos_data data;
-
- int truncate_win = b ? window_truncation_on (w) : 0;
- int end_glyph_width = 0;
-
- /* we're going to ditch selective display for static text, its an
- FSF thing and invisble extents are the way to go
- here. Implementing it also relies on a number of buffer-specific
- functions that we don't have the luxury of being able to use
- here. */
-
- /* The variable ctl-arrow allows the user to specify what characters
- can actually be displayed and which octal should be used for.
- #### This variable should probably have some rethought done to
- it.
-
- #### It would also be really nice if you could specify that
- the characters come out in hex instead of in octal. Mule
- does that by adding a ctl-hexa variable similar to ctl-arrow,
- but that's bogus -- we need a more general solution. I
- think you need to extend the concept of display tables
- into a more general conversion mechanism. Ideally you
- could specify a Lisp function that converts characters,
- but this violates the Second Golden Rule and besides would
- make things way way way way slow.
-
- So instead, we extend the display-table concept, which was
- historically limited to 256-byte vectors, to one of the
- following:
-
- a) A 256-entry vector, for backward compatibility;
- b) char-table, mapping characters to values;
- c) range-table, mapping ranges of characters to values;
- d) a list of the above.
-
- The (d) option allows you to specify multiple display tables
- instead of just one. Each display table can specify conversions
- for some characters and leave others unchanged. The way the
- character gets displayed is determined by the first display table
- with a binding for that character. This way, you could call a
- function `enable-hex-display' that adds a hex display-table to
- the list of display tables for the current buffer.
-
- #### ...not yet implemented... Also, we extend the concept of
- "mapping" to include a printf-like spec. Thus you can make all
- extended characters show up as hex with a display table like
- this:
-
- #s(range-table data ((256 524288) (format "%x")))
-
- Since more than one display table is possible, you have
- great flexibility in mapping ranges of characters. */
- Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
- ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
- : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
- ? 255 : 160)) : 255;
-
- Lisp_Object face_dt, window_dt;
-
- /* The text display block for this display line. */
- struct display_block *db = get_display_block_from_line (dl, TEXT);
-
- /* The first time through the main loop we need to force the glyph
- data to be updated. */
- int initial = 1;
-
- /* Apparently the new extent_fragment_update returns an end position
- equal to the position passed in if there are no more runs to be
- displayed. */
- int no_more_frags = 0;
-
- dl->used_prop_data = 0;
- dl->num_chars = 0;
-
- /* set up faces to use for clearing areas, used by
- output_display_line */
- dl->default_findex = default_face;
- if (default_face)
- {
- dl->left_margin_findex = default_face;
- dl->right_margin_findex = default_face;
- }
- else
- {
- dl->left_margin_findex =
- get_builtin_face_cache_index (w, Vleft_margin_face);
- dl->right_margin_findex =
- get_builtin_face_cache_index (w, Vright_margin_face);
- }
-
- xzero (data);
- data.ef = extent_fragment_new (disp_string, f);
-
- /* These values are used by all of the rune addition routines. We add
- them to this structure for ease of passing. */
- data.d = d;
- XSETWINDOW (data.window, w);
- data.db = db;
- data.dl = dl;
-
- data.bi_bufpos = bi_start_pos;
- data.pixpos = dl->bounds.left_in;
- data.last_charset = Qunbound;
- data.last_findex = default_face;
- data.result_str = Qnil;
- data.string = disp_string;
-
- /* Set the right boundary adjusting it to take into account any end
- glyph. Save the width of the end glyph for later use. */
- data.max_pixpos = dl->bounds.right_in;
-#if 0
- if (truncate_win)
- end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
- else
- end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
-#endif
- data.max_pixpos -= end_glyph_width;
-
- data.cursor_type = NO_CURSOR;
- data.cursor_x = -1;
-
- data.start_col = 0;
- /* I don't think we want this, string areas should not scroll with
- the window
- data.start_col = w->hscroll;
- data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
- */
- data.bi_start_col_enabled = 0;
- data.hscroll_glyph_width_adjust = 0;
-
- /* We regenerate the line from the very beginning. */
- Dynarr_reset (db->runes);
-
- /* Why is this less than or equal and not just less than? If the
- starting position is already equal to the maximum we can't add
- anything else, right? Wrong. We might still have a newline to
- add. A newline can use the room allocated for an end glyph since
- if we add it we know we aren't going to be adding any end
- glyph. */
-
- /* #### Chuck -- I think this condition should be while (1).
- Otherwise if (e.g.) there is one begin-glyph and one end-glyph
- and the begin-glyph ends exactly at the end of the window, the
- end-glyph and text might not be displayed. while (1) ensures
- that the loop terminates only when either (a) there is
- propagation data or (b) the end-of-line or end-of-buffer is hit.
-
- #### Also I think you need to ensure that the operation
- "add begin glyphs; add end glyphs; add text" is atomic and
- can't get interrupted in the middle. If you run off the end
- of the line during that operation, then you keep accumulating
- propagation data until you're done. Otherwise, if the (e.g.)
- there's a begin glyph at a particular position and attempting
- to display that glyph results in window-end being hit and
- propagation data being generated, then the character at that
- position won't be displayed.
-
- #### See also the comment after the end of this loop, below.
- */
- while (data.pixpos <= data.max_pixpos)
- {
- /* #### This check probably should not be necessary. */
- if (data.bi_bufpos > bi_string_zv)
- {
- /* #### urk! More of this lossage! */
- data.bi_bufpos--;
- goto done;
- }
-
- /* Check for face changes. */
- if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
- {
- /* Now compute the face and begin/end-glyph information. */
- data.findex =
- /* Remember that the extent-fragment routines deal in Bytind's. */
- extent_fragment_update (w, data.ef, data.bi_bufpos);
- /* This is somewhat cheesy but the alternative is to
- propagate default_face into extent_fragment_update. */
- if (data.findex == DEFAULT_INDEX)
- data.findex = default_face;
-
- get_display_tables (w, data.findex, &face_dt, &window_dt);
-
- if (data.bi_bufpos == data.ef->end)
- no_more_frags = 1;
- }
- initial = 0;
-
- /* Determine what is next to be displayed. We first handle any
- glyphs returned by glyphs_at_bufpos. If there are no glyphs to
- display then we determine what to do based on the character at the
- current buffer position. */
-
- /* If the current position is covered by an invisible extent, do
- nothing (except maybe add some ellipses).
-
- #### The behavior of begin and end-glyphs at the edge of an
- invisible extent should be investigated further. This is
- fairly low priority though. */
- if (data.ef->invisible)
- {
- /* #### Chuck, perhaps you could look at this code? I don't
- really know what I'm doing. */
- if (*prop)
- {
- Dynarr_free (*prop);
- *prop = 0;
- }
-
- /* The extent fragment code only sets this when we should
- really display the ellipses. It makes sure the ellipses
- don't get displayed more than once in a row. */
- if (data.ef->invisible_ellipses)
- {
- struct glyph_block gb;
-
- data.ef->invisible_ellipses_already_displayed = 1;
- data.ef->invisible_ellipses = 0;
- gb.extent = Qnil;
- gb.glyph = Vinvisible_text_glyph;
- *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
- GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
- /* Perhaps they shouldn't propagate if the very next thing
- is to display a newline (for compatibility with
- selective-display-ellipses)? Maybe that's too
- abstruse. */
- if (*prop)
- goto done;
- }
-
- /* #### What if we we're dealing with a display table? */
- if (data.start_col)
- data.start_col--;
-
- if (data.bi_bufpos == bi_string_zv)
- goto done;
- else
- INC_CHARBYTIND (string_data (s), data.bi_bufpos);
- }
-
- /* If there is propagation data, then it represents the current
- buffer position being displayed. Add them and advance the
- position counter. This might also add the minibuffer
- prompt. */
- else if (*prop)
- {
- dl->used_prop_data = 1;
- *prop = add_propagation_runes (prop, &data);
-
- if (*prop)
- goto done; /* gee, a really narrow window */
- else if (data.bi_bufpos == bi_string_zv)
- goto done;
- else if (data.bi_bufpos < 0)
- /* #### urk urk urk! Aborts are not very fun! Fix this please! */
- data.bi_bufpos = 0;
- else
- INC_CHARBYTIND (string_data (s), data.bi_bufpos);
- }
-
- /* If there are end glyphs, add them to the line. These are
- the end glyphs for the previous run of text. We add them
- here rather than doing them at the end of handling the
- previous run so that glyphs at the beginning and end of
- a line are handled correctly. */
- else if (Dynarr_length (data.ef->end_glyphs) > 0)
- {
- *prop = add_glyph_runes (&data, END_GLYPHS);
- if (*prop)
- goto done;
- }
-
- /* If there are begin glyphs, add them to the line. */
- else if (Dynarr_length (data.ef->begin_glyphs) > 0)
- {
- *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
- if (*prop)
- goto done;
- }
-
- /* If at end-of-buffer, we've already processed begin and
- end-glyphs at this point and there's no text to process,
- so we're done. */
- else if (data.bi_bufpos == bi_string_zv)
- goto done;
-
- else
- {
- Lisp_Object entry = Qnil;
- /* Get the character at the current buffer position. */
- data.ch = string_char (s, data.bi_bufpos);
- if (!NILP (face_dt) || !NILP (window_dt))
- entry = display_table_entry (data.ch, face_dt, window_dt);
-
- /* If there is a display table entry for it, hand it off to
- add_disp_table_entry_runes and let it worry about it. */
- if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
- {
- *prop = add_disp_table_entry_runes (&data, entry);
-
- if (*prop)
- goto done;
- }
-
- /* Check if we have hit a newline character. If so, add a marker
- to the line and end this loop. */
- else if (data.ch == '\n')
- {
- /* We aren't going to be adding an end glyph so give its
- space back in order to make sure that the cursor can
- fit. */
- data.max_pixpos += end_glyph_width;
- goto done;
- }
-
- /* If the current character is considered to be printable, then
- just add it. */
- else if (data.ch >= printable_min)
- {
- *prop = add_emchar_rune (&data);
- if (*prop)
- goto done;
- }
-
- /* If the current character is a tab, determine the next tab
- starting position and add a blank rune which extends from the
- current pixel position to that starting position. */
- else if (data.ch == '\t')
- {
- int tab_start_pixpos = data.pixpos;
- int next_tab_start;
- int char_tab_width;
- int prop_width = 0;
-
- if (data.start_col > 1)
- tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
-
- next_tab_start =
- next_tab_position (w, tab_start_pixpos,
- dl->bounds.left_in +
- data.hscroll_glyph_width_adjust);
- if (next_tab_start > data.max_pixpos)
- {
- prop_width = next_tab_start - data.max_pixpos;
- next_tab_start = data.max_pixpos;
- }
- data.blank_width = next_tab_start - data.pixpos;
- char_tab_width =
- (next_tab_start - tab_start_pixpos) / space_width (w);
-
- *prop = add_blank_rune (&data, w, char_tab_width);
-
- /* add_blank_rune is only supposed to be called with
- sizes guaranteed to fit in the available space. */
- assert (!(*prop));
-
- if (prop_width)
- {
- struct prop_block pb;
- *prop = Dynarr_new (prop_block);
-
- pb.type = PROP_BLANK;
- pb.data.p_blank.width = prop_width;
- pb.data.p_blank.findex = data.findex;
- Dynarr_add (*prop, pb);
-
- goto done;
- }
- }
-
- /* If character is a control character, pass it off to
- add_control_char_runes.
-
- The is_*() routines have undefined results on
- arguments outside of the range [-1, 255]. (This
- often bites people who carelessly use `char' instead
- of `unsigned char'.)
- */
- else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
- {
- *prop = add_control_char_runes (&data, b);
-
- if (*prop)
- goto done;
- }
-
- /* If the character is above the ASCII range and we have not
- already handled it, then print it as an octal number. */
- else if (data.ch >= 0200)
- {
- *prop = add_octal_runes (&data);
-
- if (*prop)
- goto done;
- }
-
- /* Assume the current character is considered to be printable,
- then just add it. */
- else
- {
- *prop = add_emchar_rune (&data);
- if (*prop)
- goto done;
- }
-
- INC_CHARBYTIND (string_data (s), data.bi_bufpos);
- }
- }
-
-done:
-
- /* Determine the starting point of the next line if we did not hit the
- end of the buffer. */
- if (data.bi_bufpos < bi_string_zv)
- {
- /* #### This check is not correct. If the line terminated
- due to a begin-glyph or end-glyph hitting window-end, then
- data.ch will not point to the character at data.bi_bufpos. If
- you make the two changes mentioned at the top of this loop,
- you should be able to say '(if (*prop))'. That should also
- make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
- check. */
-
- /* The common case is that the line ended because we hit a newline.
- In that case, the next character is just the next buffer
- position. */
- if (data.ch == '\n')
- {
- INC_CHARBYTIND (string_data (s), data.bi_bufpos);
- }
-
- /* Otherwise we have a buffer line which cannot fit on one display
- line. */
- else
- {
- struct glyph_block gb;
- struct glyph_cachel *cachel;
-
- /* If the line is to be truncated then we actually have to look
- for the next newline. We also add the end-of-line glyph which
- we know will fit because we adjusted the right border before
- we starting laying out the line. */
- data.max_pixpos += end_glyph_width;
- data.findex = default_face;
- gb.extent = Qnil;
-
- if (truncate_win)
- {
- Bytind bi_pos;
-
- /* Now find the start of the next line. */
- bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
-
- data.cursor_type = NO_CURSOR;
- data.bi_bufpos = bi_pos;
- gb.glyph = Vtruncation_glyph;
- cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
- }
- else
- {
- /* The cursor can never be on the continuation glyph. */
- data.cursor_type = NO_CURSOR;
-
- /* data.bi_bufpos is already at the start of the next line. */
-
- gb.glyph = Vcontinuation_glyph;
- cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
- }
-
- if (end_glyph_width)
- add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
-
- if (truncate_win && data.bi_bufpos == bi_string_zv)
- {
- CONST Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
- DEC_CHARPTR (endb);
- if (charptr_emchar (endb) != '\n')
- {
- /* #### Damn this losing shit. */
- data.bi_bufpos++;
- }
- }
- }
- }
- else if (data.bi_bufpos == bi_string_zv)
- {
- /* create_text_block () adds a bogus \n marker here which screws
- up subwindow display. Since we never have a cursor in the
- gutter we can safely ignore it. */
- }
- /* Calculate left whitespace boundary. */
- {
- int elt = 0;
-
- /* Whitespace past a newline is considered right whitespace. */
- while (elt < Dynarr_length (db->runes))
- {
- struct rune *rb = Dynarr_atp (db->runes, elt);
-
- if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
- || rb->type == RUNE_BLANK)
- {
- dl->bounds.left_white += rb->width;
- elt++;
- }
- else
- elt = Dynarr_length (db->runes);
- }
- }
-
- /* Calculate right whitespace boundary. */
- {
- int elt = Dynarr_length (db->runes) - 1;
- int done = 0;
-
- while (!done && elt >= 0)
- {
- struct rune *rb = Dynarr_atp (db->runes, elt);
-
- if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
- && isspace (rb->object.chr.ch))
- && !rb->type == RUNE_BLANK)
- {
- dl->bounds.right_white = rb->xpos + rb->width;
- done = 1;
- }
-
- elt--;
-
- }
-
- /* The line is blank so everything is considered to be right
- whitespace. */
- if (!done)
- dl->bounds.right_white = dl->bounds.left_in;
- }
-
- /* Set the display blocks bounds. */
- db->start_pos = dl->bounds.left_in;
- if (Dynarr_length (db->runes))
- {
- struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
-
- db->end_pos = rb->xpos + rb->width;
- }
- else
- db->end_pos = dl->bounds.right_white;
-
- /* update line height parameters */
- if (!data.new_ascent && !data.new_descent)
- {
- /* We've got a blank line so initialize these values from the default
- face. */
- default_face_font_info (data.window, &data.new_ascent,
- &data.new_descent, 0, 0, 0);
- }
-
- if (data.max_pixmap_height)
- {
- int height = data.new_ascent + data.new_descent;
- int pix_ascent, pix_descent;
-
- pix_descent = data.max_pixmap_height * data.new_descent / height;
- pix_ascent = data.max_pixmap_height - pix_descent;
-
- data.new_ascent = max (data.new_ascent, pix_ascent);
- data.new_descent = max (data.new_descent, pix_descent);
- }
-
- dl->ascent = data.new_ascent;
- dl->descent = data.new_descent;
-
- {
- unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
-
- if (dl->ascent < ascent)
- dl->ascent = ascent;
- }
- {
- unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
-
- if (dl->descent < descent)
- dl->descent = descent;
- }
-
- dl->cursor_elt = data.cursor_x;
- /* #### lossage lossage lossage! Fix this shit! */
- if (data.bi_bufpos > bi_string_zv)
- dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
- else
- dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
- if (truncate_win)
- data.dl->num_chars =
- string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
- else
- /* This doesn't correctly take into account tabs and control
- characters but if the window isn't being truncated then this
- value isn't going to end up being used anyhow. */
- data.dl->num_chars = dl->end_bufpos - dl->bufpos;
-
- /* #### handle horizontally scrolled line with text none of which
- was actually laid out. */
-
- /* #### handle any remainder of overlay arrow */
-
- if (*prop == ADD_FAILED)
- *prop = NULL;
-
- if (truncate_win && *prop)