Mercurial > hg > xemacs-beta
comparison src/redisplay.c @ 265:8efd647ea9ca r20-5b31
Import from CVS: tag r20-5b31
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:25:37 +0200 |
parents | 11cf20601dec |
children | 966663fcf606 |
comparison
equal
deleted
inserted
replaced
264:682d2a9d41a5 | 265:8efd647ea9ca |
---|---|
245 int start_col, prop_block_dynarr **prop, | 245 int start_col, prop_block_dynarr **prop, |
246 int type); | 246 int type); |
247 static void generate_modeline (struct window *w, struct display_line *dl, | 247 static void generate_modeline (struct window *w, struct display_line *dl, |
248 int type); | 248 int type); |
249 static int ensure_modeline_generated (struct window *w, int type); | 249 static int ensure_modeline_generated (struct window *w, int type); |
250 #ifdef MODELINE_IS_SCROLLABLE | |
250 static void generate_formatted_string_db (Lisp_Object format_str, | 251 static void generate_formatted_string_db (Lisp_Object format_str, |
251 Lisp_Object result_str, | 252 Lisp_Object result_str, |
252 struct window *w, | 253 struct window *w, |
253 struct display_line *dl, | 254 struct display_line *dl, |
254 struct display_block *db, | 255 struct display_block *db, |
259 Charcount pos, Charcount min_pos, | 260 Charcount pos, Charcount min_pos, |
260 Charcount max_pos, int no_limit, | 261 Charcount max_pos, int no_limit, |
261 Lisp_Object elt, | 262 Lisp_Object elt, |
262 int depth, int max_pixsize, | 263 int depth, int max_pixsize, |
263 face_index findex, int type); | 264 face_index findex, int type); |
265 #else /* MODELINE_IS_SCROLLABLE */ | |
266 static void generate_formatted_string_db (Lisp_Object format_str, | |
267 Lisp_Object result_str, | |
268 struct window *w, | |
269 struct display_line *dl, | |
270 struct display_block *db, | |
271 face_index findex, int min_pixpos, | |
272 int max_pixpos, int type); | |
273 static Charcount generate_fstring_runes (struct window *w, pos_data *data, | |
274 Charcount pos, Charcount min_pos, | |
275 Charcount max_pos, Lisp_Object elt, | |
276 int depth, int max_pixsize, | |
277 face_index findex, int type); | |
278 #endif /* not MODELINE_IS_SCROLLABLE */ | |
264 static prop_block_dynarr *add_emchar_rune (pos_data *data); | 279 static prop_block_dynarr *add_emchar_rune (pos_data *data); |
265 static prop_block_dynarr *add_bufbyte_string_runes (pos_data *data, | 280 static prop_block_dynarr *add_bufbyte_string_runes (pos_data *data, |
266 Bufbyte *c_string, | 281 Bufbyte *c_string, |
267 Bytecount c_length, | 282 Bytecount c_length, |
268 int no_prop); | 283 int no_prop); |
1905 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX); | 1920 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX); |
1906 else | 1921 else |
1907 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX); | 1922 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX); |
1908 data.max_pixpos -= end_glyph_width; | 1923 data.max_pixpos -= end_glyph_width; |
1909 | 1924 |
1910 if (cursor_in_echo_area) | 1925 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f)) |
1911 { | 1926 { |
1912 if (MINI_WINDOW_P (w) && echo_area_active (f)) | 1927 data.bi_cursor_bufpos = BI_BUF_ZV (b); |
1913 { | 1928 data.cursor_type = CURSOR_ON; |
1914 data.bi_cursor_bufpos = BI_BUF_ZV (b); | |
1915 data.cursor_type = CURSOR_ON; | |
1916 } | |
1917 else | |
1918 data.cursor_type = NO_CURSOR; | |
1919 } | 1929 } |
1920 else if (MINI_WINDOW_P (w) && !active_minibuffer) | 1930 else if (MINI_WINDOW_P (w) && !active_minibuffer) |
1921 data.cursor_type = NO_CURSOR; | 1931 data.cursor_type = NO_CURSOR; |
1922 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) && | 1932 else if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)) && |
1923 EQ(DEVICE_CONSOLE(d), Vselected_console) && | 1933 EQ(DEVICE_CONSOLE(d), Vselected_console) && |
3563 max_pixpos -= shadow_thickness; | 3573 max_pixpos -= shadow_thickness; |
3564 } | 3574 } |
3565 else | 3575 else |
3566 ypos_adj = 0; | 3576 ypos_adj = 0; |
3567 | 3577 |
3578 #ifdef MODELINE_IS_SCROLLABLE | |
3568 generate_formatted_string_db (b->modeline_format, | 3579 generate_formatted_string_db (b->modeline_format, |
3569 b->generated_modeline_string, w, dl, db, | 3580 b->generated_modeline_string, w, dl, db, |
3570 MODELINE_INDEX, min_pixpos, max_pixpos, type, | 3581 MODELINE_INDEX, min_pixpos, max_pixpos, type, |
3571 1 /* generate a modeline */); | 3582 1 /* generate a modeline */); |
3572 | 3583 #else |
3584 generate_formatted_string_db (b->modeline_format, | |
3585 b->generated_modeline_string, w, dl, db, | |
3586 MODELINE_INDEX, min_pixpos, max_pixpos, type); | |
3587 #endif /* not MODELINE_IS_SCROLLABLE */ | |
3588 | |
3573 /* The modeline is at the bottom of the gutters. We have to wait to | 3589 /* The modeline is at the bottom of the gutters. We have to wait to |
3574 set this until we've generated teh modeline in order to account | 3590 set this until we've generated teh modeline in order to account |
3575 for any embedded faces. */ | 3591 for any embedded faces. */ |
3576 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; | 3592 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; |
3577 } | 3593 } |
3578 | 3594 |
3595 /* This define is for the experimental horizontal modeline scrolling. It's not | |
3596 functionnal for 20.5, but might be for 21.1 */ | |
3597 #ifdef MODELINE_IS_SCROLLABLE | |
3579 static void | 3598 static void |
3580 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, | 3599 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, |
3581 struct window *w, struct display_line *dl, | 3600 struct window *w, struct display_line *dl, |
3582 struct display_block *db, face_index findex, | 3601 struct display_block *db, face_index findex, |
3583 int min_pixpos, int max_pixpos, int type, | 3602 int min_pixpos, int max_pixpos, int type, |
3714 { | 3733 { |
3715 if (*cur_pos) | 3734 if (*cur_pos) |
3716 INC_CHARPTR (cur_pos); | 3735 INC_CHARPTR (cur_pos); |
3717 pos += 1; | 3736 pos += 1; |
3718 } | 3737 } |
3719 else /* Maybe add something */ | 3738 else /* pos > 0, things will be visible */ |
3720 { | 3739 { |
3721 if (*cur_pos) | 3740 if (*cur_pos) /* some stuff to add */ |
3722 { | 3741 { |
3723 CONST Bufbyte *old_cur_pos = cur_pos; | 3742 CONST Bufbyte *old_cur_pos = cur_pos; |
3724 int succeeded; | 3743 int succeeded; |
3725 | 3744 |
3726 data->ch = charptr_emchar (cur_pos); | 3745 data->ch = charptr_emchar (cur_pos); |
3731 pos += 1; | 3750 pos += 1; |
3732 data->modeline_charpos++; | 3751 data->modeline_charpos++; |
3733 data->bytepos += cur_pos - old_cur_pos; | 3752 data->bytepos += cur_pos - old_cur_pos; |
3734 } | 3753 } |
3735 } | 3754 } |
3755 /* no characters to add */ | |
3756 /* If there 's room enough, add space */ | |
3736 else if (data->pixpos + data->blank_width <= data->max_pixpos) | 3757 else if (data->pixpos + data->blank_width <= data->max_pixpos) |
3737 { | 3758 { |
3738 add_blank_rune (data, NULL, 0); | 3759 add_blank_rune (data, NULL, 0); |
3760 pos += 1; | |
3739 } | 3761 } |
3740 else /* pretend to add something */ | 3762 /* otherwise, just pretend we added something */ |
3763 else | |
3741 { | 3764 { |
3742 if (*cur_pos) | 3765 if (*cur_pos) |
3743 INC_CHARPTR (cur_pos); | 3766 INC_CHARPTR (cur_pos); |
3744 pos += 1; | 3767 pos += 1; |
3745 } | 3768 } |
4012 */ | 4035 */ |
4013 if (no_limit) | 4036 if (no_limit) |
4014 max_pos = pos - lim; | 4037 max_pos = pos - lim; |
4015 else | 4038 else |
4016 max_pos = min (max_pos, pos - lim); | 4039 max_pos = min (max_pos, pos - lim); |
4040 no_limit = 0; | |
4017 } | 4041 } |
4018 else if (lim > 0) | 4042 else if (lim > 0) |
4019 { | 4043 { |
4020 /* Padding specified. Don't let it be more than | 4044 /* Padding specified. Don't let it be more than |
4021 * current maximum. | 4045 * current maximum. |
4028 * that is beyond the current truncation point. | 4052 * that is beyond the current truncation point. |
4029 */ | 4053 */ |
4030 if (lim > min_pos) | 4054 if (lim > min_pos) |
4031 min_pos = lim; | 4055 min_pos = lim; |
4032 } | 4056 } |
4033 no_limit = 0; | |
4034 goto tail_recurse; | 4057 goto tail_recurse; |
4035 } | 4058 } |
4036 else if (STRINGP (car) || CONSP (car)) | 4059 else if (STRINGP (car) || CONSP (car)) |
4037 { | 4060 { |
4038 int limit = 50; | 4061 int limit = 50; |
4110 0, /* no limit */ 1); | 4133 0, /* no limit */ 1); |
4111 } | 4134 } |
4112 | 4135 |
4113 return pos; | 4136 return pos; |
4114 } | 4137 } |
4138 #else /* MODELINE_IS_SCROLLABLE */ | |
4139 static void | |
4140 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, | |
4141 struct window *w, struct display_line *dl, | |
4142 struct display_block *db, face_index findex, | |
4143 int min_pixpos, int max_pixpos, int type) | |
4144 { | |
4145 struct frame *f = XFRAME (w->frame); | |
4146 struct device *d = XDEVICE (f->device); | |
4147 | |
4148 pos_data data; | |
4149 int c_pixpos; | |
4150 | |
4151 memset (&data, 0, sizeof (data)); | |
4152 data.d = d; | |
4153 data.db = db; | |
4154 data.dl = dl; | |
4155 data.findex = findex; | |
4156 data.pixpos = min_pixpos; | |
4157 data.max_pixpos = max_pixpos; | |
4158 data.cursor_type = NO_CURSOR; | |
4159 data.last_charset = Qunbound; | |
4160 data.last_findex = DEFAULT_INDEX; | |
4161 data.result_str = result_str; | |
4162 data.is_modeline = 1; | |
4163 XSETWINDOW (data.window, w); | |
4164 | |
4165 Dynarr_reset (formatted_string_extent_dynarr); | |
4166 Dynarr_reset (formatted_string_extent_start_dynarr); | |
4167 Dynarr_reset (formatted_string_extent_end_dynarr); | |
4168 | |
4169 /* This recursively builds up the modeline. */ | |
4170 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0, | |
4171 max_pixpos - min_pixpos, findex, type); | |
4172 | |
4173 if (Dynarr_length (db->runes)) | |
4174 { | |
4175 struct rune *rb = | |
4176 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); | |
4177 c_pixpos = rb->xpos + rb->width; | |
4178 } | |
4179 else | |
4180 c_pixpos = min_pixpos; | |
4181 | |
4182 /* If we don't reach the right side of the window, add a blank rune | |
4183 to make up the difference. This usually only occurs if the | |
4184 modeline face is using a proportional width font or a fixed width | |
4185 font of a different size from the default face font. */ | |
4186 | |
4187 if (c_pixpos < max_pixpos) | |
4188 { | |
4189 data.pixpos = c_pixpos; | |
4190 data.blank_width = max_pixpos - data.pixpos; | |
4191 | |
4192 add_blank_rune (&data, NULL, 0); | |
4193 } | |
4194 | |
4195 /* Now create the result string and frob the extents into it. */ | |
4196 if (!NILP (result_str)) | |
4197 { | |
4198 int elt; | |
4199 Bytecount len; | |
4200 Bufbyte *strdata; | |
4201 struct buffer *buf = XBUFFER (WINDOW_BUFFER (w)); | |
4202 | |
4203 detach_all_extents (result_str); | |
4204 resize_string (XSTRING (result_str), -1, | |
4205 data.bytepos - XSTRING_LENGTH (result_str)); | |
4206 | |
4207 strdata = XSTRING_DATA (result_str); | |
4208 | |
4209 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++) | |
4210 { | |
4211 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR) | |
4212 { | |
4213 len += (set_charptr_emchar | |
4214 (strdata + len, Dynarr_atp (db->runes, | |
4215 elt)->object.chr.ch)); | |
4216 } | |
4217 } | |
4218 | |
4219 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr); | |
4220 elt++) | |
4221 { | |
4222 Lisp_Object extent = Qnil; | |
4223 Lisp_Object child; | |
4224 | |
4225 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt)); | |
4226 child = Fgethash (extent, buf->modeline_extent_table, Qnil); | |
4227 if (NILP (child)) | |
4228 { | |
4229 child = Fmake_extent (Qnil, Qnil, result_str); | |
4230 Fputhash (extent, child, buf->modeline_extent_table); | |
4231 } | |
4232 Fset_extent_parent (child, extent); | |
4233 set_extent_endpoints | |
4234 (XEXTENT (child), | |
4235 Dynarr_at (formatted_string_extent_start_dynarr, elt), | |
4236 Dynarr_at (formatted_string_extent_end_dynarr, elt), | |
4237 result_str); | |
4238 } | |
4239 } | |
4240 } | |
4241 | |
4242 static Charcount | |
4243 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str, | |
4244 Charcount pos, Charcount min_pos, Charcount max_pos) | |
4245 { | |
4246 /* This function has been Mule-ized. */ | |
4247 Charcount end; | |
4248 CONST Bufbyte *cur_pos = str; | |
4249 struct display_block *db = data->db; | |
4250 | |
4251 data->blank_width = space_width (XWINDOW (data->window)); | |
4252 while (Dynarr_length (db->runes) < pos) | |
4253 add_blank_rune (data, NULL, 0); | |
4254 | |
4255 end = (Dynarr_length (db->runes) + | |
4256 bytecount_to_charcount (str, strlen ((CONST char *) str))); | |
4257 if (max_pos != -1) | |
4258 end = min (max_pos, end); | |
4259 | |
4260 while (pos < end && *cur_pos) | |
4261 { | |
4262 CONST Bufbyte *old_cur_pos = cur_pos; | |
4263 int succeeded; | |
4264 | |
4265 data->ch = charptr_emchar (cur_pos); | |
4266 succeeded = (add_emchar_rune (data) != ADD_FAILED); | |
4267 INC_CHARPTR (cur_pos); | |
4268 if (succeeded) | |
4269 { | |
4270 pos++; | |
4271 data->modeline_charpos++; | |
4272 data->bytepos += cur_pos - old_cur_pos; | |
4273 } | |
4274 } | |
4275 | |
4276 while (Dynarr_length (db->runes) < min_pos && | |
4277 (data->pixpos + data->blank_width <= data->max_pixpos)) | |
4278 add_blank_rune (data, NULL, 0); | |
4279 | |
4280 return Dynarr_length (db->runes); | |
4281 } | |
4282 | |
4283 /* #### Urk! Should also handle begin-glyphs and end-glyphs in | |
4284 modeline extents. */ | |
4285 static Charcount | |
4286 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph, | |
4287 Charcount pos, Charcount min_pos, Charcount max_pos) | |
4288 { | |
4289 /* This function has been Mule-ized. */ | |
4290 Charcount end; | |
4291 struct display_block *db = data->db; | |
4292 struct glyph_block gb; | |
4293 | |
4294 data->blank_width = space_width (XWINDOW (data->window)); | |
4295 while (Dynarr_length (db->runes) < pos) | |
4296 add_blank_rune (data, NULL, 0); | |
4297 | |
4298 end = Dynarr_length (db->runes) + 1; | |
4299 if (max_pos != -1) | |
4300 end = min (max_pos, end); | |
4301 | |
4302 gb.glyph = glyph; | |
4303 gb.extent = Qnil; | |
4304 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); | |
4305 pos++; | |
4306 | |
4307 while (Dynarr_length (db->runes) < pos && | |
4308 (data->pixpos + data->blank_width <= data->max_pixpos)) | |
4309 add_blank_rune (data, NULL, 0); | |
4310 | |
4311 return Dynarr_length (db->runes); | |
4312 } | |
4313 | |
4314 /* If max_pos is == -1, it is considered to be infinite. The same is | |
4315 true of max_pixsize. */ | |
4316 #define SET_CURRENT_MODE_CHARS_PIXSIZE \ | |
4317 if (Dynarr_length (data->db->runes)) \ | |
4318 cur_pixsize = data->pixpos - Dynarr_atp (data->db->runes, 0)->xpos; \ | |
4319 else \ | |
4320 cur_pixsize = 0; | |
4321 | |
4322 /* Note that this function does "positions" in terms of characters and | |
4323 not in terms of columns. This is necessary to make the formatting | |
4324 work correctly when proportional width fonts are used in the | |
4325 modeline. */ | |
4326 static Charcount | |
4327 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos, | |
4328 Charcount min_pos, Charcount max_pos, | |
4329 Lisp_Object elt, int depth, int max_pixsize, | |
4330 face_index findex, int type) | |
4331 { | |
4332 /* This function has been Mule-ized. */ | |
4333 /* #### The other losing things in this function are: | |
4334 | |
4335 -- C zero-terminated-string lossage. | |
4336 -- Non-printable characters should be converted into something | |
4337 appropriate (e.g. ^F) instead of blindly being printed anyway. | |
4338 */ | |
4339 | |
4340 tail_recurse: | |
4341 if (depth > 10) | |
4342 goto invalid; | |
4343 | |
4344 depth++; | |
4345 | |
4346 if (STRINGP (elt)) | |
4347 { | |
4348 /* A string. Add to the display line and check for %-constructs | |
4349 within it. */ | |
4350 | |
4351 Bufbyte *this = XSTRING_DATA (elt); | |
4352 | |
4353 while ((pos < max_pos || max_pos == -1) && *this) | |
4354 { | |
4355 Bufbyte *last = this; | |
4356 | |
4357 while (*this && *this != '%') | |
4358 this++; | |
4359 | |
4360 if (this != last) | |
4361 { | |
4362 /* The string is just a string. */ | |
4363 Charcount size = | |
4364 bytecount_to_charcount (last, this - last) + pos; | |
4365 Charcount tmp_max = (max_pos == -1 ? size : min (size, max_pos)); | |
4366 | |
4367 pos = add_string_to_fstring_db_runes (data, last, pos, pos, | |
4368 tmp_max); | |
4369 } | |
4370 else /* *this == '%' */ | |
4371 { | |
4372 Charcount spec_width = 0; | |
4373 | |
4374 this++; /* skip over '%' */ | |
4375 | |
4376 /* We can't allow -ve args due to the "%-" construct. | |
4377 * Argument specifies minwidth but not maxwidth | |
4378 * (maxwidth can be specified by | |
4379 * (<negative-number> . <stuff>) modeline elements) | |
4380 */ | |
4381 while (isdigit (*this)) | |
4382 { | |
4383 spec_width = spec_width * 10 + (*this - '0'); | |
4384 this++; | |
4385 } | |
4386 spec_width += pos; | |
4387 | |
4388 if (*this == 'M') | |
4389 { | |
4390 pos = generate_fstring_runes (w, data, pos, spec_width, | |
4391 max_pos, Vglobal_mode_string, | |
4392 depth, max_pixsize, findex, | |
4393 type); | |
4394 } | |
4395 else if (*this == '-') | |
4396 { | |
4397 Charcount num_to_add; | |
4398 | |
4399 if (max_pixsize < 0) | |
4400 num_to_add = 0; | |
4401 else if (max_pos != -1) | |
4402 num_to_add = max_pos - pos; | |
4403 else | |
4404 { | |
4405 int cur_pixsize; | |
4406 int dash_pixsize; | |
4407 Bufbyte ch = '-'; | |
4408 SET_CURRENT_MODE_CHARS_PIXSIZE; | |
4409 | |
4410 dash_pixsize = | |
4411 redisplay_text_width_string (w, findex, &ch, Qnil, 0, | |
4412 1); | |
4413 | |
4414 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize; | |
4415 num_to_add++; | |
4416 } | |
4417 | |
4418 while (num_to_add--) | |
4419 pos = add_string_to_fstring_db_runes | |
4420 (data, (CONST Bufbyte *) "-", pos, pos, max_pos); | |
4421 } | |
4422 else if (*this != 0) | |
4423 { | |
4424 Bufbyte *str; | |
4425 Emchar ch = charptr_emchar (this); | |
4426 decode_mode_spec (w, ch, type); | |
4427 | |
4428 str = Dynarr_atp (mode_spec_bufbyte_string, 0); | |
4429 pos = add_string_to_fstring_db_runes (data,str, pos, pos, | |
4430 max_pos); | |
4431 } | |
4432 | |
4433 /* NOT this++. There could be any sort of character at | |
4434 the current position. */ | |
4435 INC_CHARPTR (this); | |
4436 } | |
4437 | |
4438 if (max_pixsize > 0) | |
4439 { | |
4440 int cur_pixsize; | |
4441 SET_CURRENT_MODE_CHARS_PIXSIZE; | |
4442 | |
4443 if (cur_pixsize >= max_pixsize) | |
4444 break; | |
4445 } | |
4446 } | |
4447 } | |
4448 else if (SYMBOLP (elt)) | |
4449 { | |
4450 /* A symbol: process the value of the symbol recursively | |
4451 as if it appeared here directly. */ | |
4452 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer); | |
4453 | |
4454 if (!UNBOUNDP (tem)) | |
4455 { | |
4456 /* If value is a string, output that string literally: | |
4457 don't check for % within it. */ | |
4458 if (STRINGP (tem)) | |
4459 { | |
4460 pos = | |
4461 add_string_to_fstring_db_runes | |
4462 (data, XSTRING_DATA (tem), pos, min_pos, max_pos); | |
4463 } | |
4464 /* Give up right away for nil or t. */ | |
4465 else if (!EQ (tem, elt)) | |
4466 { | |
4467 elt = tem; | |
4468 goto tail_recurse; | |
4469 } | |
4470 } | |
4471 } | |
4472 else if (CONSP (elt)) | |
4473 { | |
4474 /* A cons cell: four distinct cases. | |
4475 * If first element is a string or a cons, process all the elements | |
4476 * and effectively concatenate them. | |
4477 * If first element is a negative number, truncate displaying cdr to | |
4478 * at most that many characters. If positive, pad (with spaces) | |
4479 * to at least that many characters. | |
4480 * If first element is a symbol, process the cadr or caddr recursively | |
4481 * according to whether the symbol's value is non-nil or nil. | |
4482 * If first element is a face, process the cdr recursively | |
4483 * without altering the depth. | |
4484 */ | |
4485 Lisp_Object car, tem; | |
4486 | |
4487 car = XCAR (elt); | |
4488 if (SYMBOLP (car)) | |
4489 { | |
4490 elt = XCDR (elt); | |
4491 if (!CONSP (elt)) | |
4492 goto invalid; | |
4493 tem = symbol_value_in_buffer (car, w->buffer); | |
4494 /* elt is now the cdr, and we know it is a cons cell. | |
4495 Use its car if CAR has a non-nil value. */ | |
4496 if (!UNBOUNDP (tem)) | |
4497 { | |
4498 if (!NILP (tem)) | |
4499 { | |
4500 elt = XCAR (elt); | |
4501 goto tail_recurse; | |
4502 } | |
4503 } | |
4504 /* Symbol's value is nil (or symbol is unbound) | |
4505 * Get the cddr of the original list | |
4506 * and if possible find the caddr and use that. | |
4507 */ | |
4508 elt = XCDR (elt); | |
4509 if (NILP (elt)) | |
4510 ; | |
4511 else if (!CONSP (elt)) | |
4512 goto invalid; | |
4513 else | |
4514 { | |
4515 elt = XCAR (elt); | |
4516 goto tail_recurse; | |
4517 } | |
4518 } | |
4519 else if (INTP (car)) | |
4520 { | |
4521 Charcount lim = XINT (car); | |
4522 | |
4523 elt = XCDR (elt); | |
4524 | |
4525 if (lim < 0) | |
4526 { | |
4527 /* Negative int means reduce maximum width. | |
4528 * DO NOT change MIN_PIXPOS here! | |
4529 * (20 -10 . foo) should truncate foo to 10 col | |
4530 * and then pad to 20. | |
4531 */ | |
4532 if (max_pos == -1) | |
4533 max_pos = pos - lim; | |
4534 else | |
4535 max_pos = min (max_pos, pos - lim); | |
4536 } | |
4537 else if (lim > 0) | |
4538 { | |
4539 /* Padding specified. Don't let it be more than | |
4540 * current maximum. | |
4541 */ | |
4542 lim += pos; | |
4543 if (max_pos != -1 && lim > max_pos) | |
4544 lim = max_pos; | |
4545 /* If that's more padding than already wanted, queue it. | |
4546 * But don't reduce padding already specified even if | |
4547 * that is beyond the current truncation point. | |
4548 */ | |
4549 if (lim > min_pos) | |
4550 min_pos = lim; | |
4551 } | |
4552 goto tail_recurse; | |
4553 } | |
4554 else if (STRINGP (car) || CONSP (car)) | |
4555 { | |
4556 int limit = 50; | |
4557 /* LIMIT is to protect against circular lists. */ | |
4558 while (CONSP (elt) && --limit > 0 | |
4559 && (pos < max_pos || max_pos == -1)) | |
4560 { | |
4561 pos = generate_fstring_runes (w, data, pos, pos, max_pos, | |
4562 XCAR (elt), depth, | |
4563 max_pixsize, findex, type); | |
4564 elt = XCDR (elt); | |
4565 } | |
4566 } | |
4567 else if (EXTENTP (car)) | |
4568 { | |
4569 struct extent *ext = XEXTENT (car); | |
4570 | |
4571 if (EXTENT_LIVE_P (ext)) | |
4572 { | |
4573 face_index old_findex = data->findex; | |
4574 Lisp_Object face; | |
4575 Lisp_Object font_inst; | |
4576 face_index new_findex; | |
4577 Bytecount start = data->bytepos; | |
4578 | |
4579 face = extent_face (ext); | |
4580 if (FACEP (face)) | |
4581 { | |
4582 /* #### needs to merge faces, sigh */ | |
4583 /* #### needs to handle list of faces */ | |
4584 new_findex = get_builtin_face_cache_index (w, face); | |
4585 /* !!#### not right; needs to compute the max height of | |
4586 all the charsets */ | |
4587 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex, | |
4588 Vcharset_ascii); | |
4589 | |
4590 data->dl->ascent = max (data->dl->ascent, | |
4591 XFONT_INSTANCE (font_inst)->ascent); | |
4592 data->dl->descent = max (data->dl->descent, | |
4593 XFONT_INSTANCE (font_inst)-> | |
4594 descent); | |
4595 } | |
4596 else | |
4597 new_findex = old_findex; | |
4598 | |
4599 data->findex = new_findex; | |
4600 pos = generate_fstring_runes (w, data, pos, pos, max_pos, | |
4601 XCDR (elt), depth - 1, | |
4602 max_pixsize, new_findex, type); | |
4603 data->findex = old_findex; | |
4604 Dynarr_add (formatted_string_extent_dynarr, ext); | |
4605 Dynarr_add (formatted_string_extent_start_dynarr, start); | |
4606 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos); | |
4607 } | |
4608 } | |
4609 } | |
4610 else if (GLYPHP (elt)) | |
4611 { | |
4612 pos = add_glyph_to_fstring_db_runes (data, elt, pos, pos, max_pos); | |
4613 } | |
4614 else | |
4615 { | |
4616 invalid: | |
4617 pos = | |
4618 add_string_to_fstring_db_runes | |
4619 (data, (CONST Bufbyte *) GETTEXT ("*invalid*"), pos, min_pos, | |
4620 max_pos); | |
4621 } | |
4622 | |
4623 if (min_pos > pos) | |
4624 { | |
4625 add_string_to_fstring_db_runes (data, (CONST Bufbyte *) "", pos, min_pos, | |
4626 -1); | |
4627 } | |
4628 | |
4629 return pos; | |
4630 } | |
4631 #endif /* not MODELINE_IS_SCROLLABLE */ | |
4115 | 4632 |
4116 /* The caller is responsible for freeing the returned string. */ | 4633 /* The caller is responsible for freeing the returned string. */ |
4117 Bufbyte * | 4634 Bufbyte * |
4118 generate_formatted_string (struct window *w, Lisp_Object format_str, | 4635 generate_formatted_string (struct window *w, Lisp_Object format_str, |
4119 Lisp_Object result_str, face_index findex, int type) | 4636 Lisp_Object result_str, face_index findex, int type) |
4124 | 4641 |
4125 dl = &formatted_string_display_line; | 4642 dl = &formatted_string_display_line; |
4126 db = get_display_block_from_line (dl, TEXT); | 4643 db = get_display_block_from_line (dl, TEXT); |
4127 Dynarr_reset (db->runes); | 4644 Dynarr_reset (db->runes); |
4128 | 4645 |
4646 #ifdef MODELINE_IS_SCROLLABLE | |
4129 /* D. Verna Feb. 1998. | 4647 /* D. Verna Feb. 1998. |
4130 Currently, only update_frame_title can make us come here. This is not | 4648 Currently, only update_frame_title can make us come here. This is not |
4131 to build a modeline */ | 4649 to build a modeline */ |
4132 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, | 4650 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, |
4133 -1, type, 0 /* not a modeline */); | 4651 -1, type, 0 /* not a modeline */); |
4652 #else /* not MODELINE_IS_SCROLLABLE */ | |
4653 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, | |
4654 -1, type); | |
4655 #endif /* not MODELINE_IS_SCROLLABLE */ | |
4134 | 4656 |
4135 Dynarr_reset (formatted_string_emchar_dynarr); | 4657 Dynarr_reset (formatted_string_emchar_dynarr); |
4136 while (elt < Dynarr_length (db->runes)) | 4658 while (elt < Dynarr_length (db->runes)) |
4137 { | 4659 { |
4138 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR) | 4660 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR) |
5906 obj = XFRAME (w->frame)->name; | 6428 obj = XFRAME (w->frame)->name; |
5907 break; | 6429 break; |
5908 | 6430 |
5909 /* indicate TEXT or BINARY */ | 6431 /* indicate TEXT or BINARY */ |
5910 case 't': | 6432 case 't': |
5911 #ifdef DOS_NT | 6433 /* #### NT does not use this any more. Now what? */ |
5912 str = NILP (b->buffer_file_type) ? "T" : "B"; | |
5913 #else /* not DOS_NT */ | |
5914 str = "T"; | 6434 str = "T"; |
5915 #endif /* not DOS_NT */ | |
5916 break; | 6435 break; |
5917 | 6436 |
5918 /* print percent of buffer above top of window, or Top, Bot or All */ | 6437 /* print percent of buffer above top of window, or Top, Bot or All */ |
5919 case 'p': | 6438 case 'p': |
5920 { | 6439 { |