+/* This function is also used in frame.c by `generate_title_string' */
+void
+generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
+ struct window *w, struct display_line *dl,
+ struct display_block *db, face_index findex,
+ int min_pixpos, int max_pixpos, int type)
+{
+ struct frame *f = XFRAME (w->frame);
+ struct device *d = XDEVICE (f->device);
+
+ pos_data data;
+ int c_pixpos;
+ Charcount offset = 0;
+
+ xzero (data);
+ data.d = d;
+ data.db = db;
+ data.dl = dl;
+ data.findex = findex;
+ data.pixpos = min_pixpos;
+ data.max_pixpos = max_pixpos;
+ data.cursor_type = NO_CURSOR;
+ data.last_charset = Qunbound;
+ data.last_findex = DEFAULT_INDEX;
+ data.result_str = result_str;
+ data.is_modeline = 1;
+ data.string = Qnil;
+ XSETWINDOW (data.window, w);
+
+ Dynarr_reset (formatted_string_extent_dynarr);
+ Dynarr_reset (formatted_string_extent_start_dynarr);
+ Dynarr_reset (formatted_string_extent_end_dynarr);
+
+ /* result_str is nil when we're building a frame or icon title. Otherwise,
+ we're building a modeline, so the offset starts at the modeline
+ horizontal scrolling ammount */
+ if (! NILP (result_str))
+ offset = w->modeline_hscroll;
+ generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
+ max_pixpos - min_pixpos, findex, type, &offset,
+ Qnil);
+
+ if (Dynarr_length (db->runes))
+ {
+ struct rune *rb =
+ Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
+ c_pixpos = rb->xpos + rb->width;
+ }
+ else
+ c_pixpos = min_pixpos;
+
+ /* If we don't reach the right side of the window, add a blank rune
+ to make up the difference. This usually only occurs if the
+ modeline face is using a proportional width font or a fixed width
+ font of a different size from the default face font. */
+
+ if (c_pixpos < max_pixpos)
+ {
+ data.pixpos = c_pixpos;
+ data.blank_width = max_pixpos - data.pixpos;
+
+ add_blank_rune (&data, NULL, 0);
+ }
+
+ /* Now create the result string and frob the extents into it. */
+ if (!NILP (result_str))
+ {
+ int elt;
+ Bytecount len;
+ Bufbyte *strdata;
+ struct buffer *buf = XBUFFER (WINDOW_BUFFER (w));
+
+ detach_all_extents (result_str);
+ resize_string (XSTRING (result_str), -1,
+ data.bytepos - XSTRING_LENGTH (result_str));
+
+ strdata = XSTRING_DATA (result_str);
+
+ for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
+ {
+ if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
+ {
+ len += (set_charptr_emchar
+ (strdata + len, Dynarr_atp (db->runes,
+ elt)->object.chr.ch));
+ }
+ }
+
+ for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
+ elt++)
+ {
+ Lisp_Object extent = Qnil;
+ Lisp_Object child;
+
+ XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt));
+ child = Fgethash (extent, buf->modeline_extent_table, Qnil);
+ if (NILP (child))
+ {
+ child = Fmake_extent (Qnil, Qnil, result_str);
+ Fputhash (extent, child, buf->modeline_extent_table);
+ }
+ Fset_extent_parent (child, extent);
+ set_extent_endpoints
+ (XEXTENT (child),
+ Dynarr_at (formatted_string_extent_start_dynarr, elt),
+ Dynarr_at (formatted_string_extent_end_dynarr, elt),
+ result_str);
+ }
+ }
+}
+