+/**
+ * Render text with printf()-like formatting at a specified row/column position.
+ *
+ * \see text_xyprintf()
+ */
+int PGM_FUNC(text_xprintf)(struct Bitmap *bm,
+ uint8_t row, uint8_t col, uint16_t style, const char * PGM_ATTR fmt, ...)
+{
+ int len;
+ va_list ap;
+
+ va_start(ap, fmt);
+ len = PGM_FUNC(text_xyvprintf)(
+ bm, col * bm->font->width, row * bm->font->height,
+ style, fmt, ap);
+ va_end(ap);
+
+ return len;
+}
+
+
+struct TextWidthData
+{
+ Bitmap *bitmap;
+ coord_t width;
+};
+
+/**
+ * Compute width in pixels of a character.
+ *
+ * Compute the on screen width of a character, taking the
+ * current style and font into account.
+ *
+ * The width is accumulated in the WidthData structure
+ * passed as second argument.
+ *
+ * This is a formatted_write() callback used by text_vwidthf()
+ * to compute the length of a formatted string.
+ */
+static int text_charWidth(int c, struct TextWidthData *twd)
+{
+ unsigned char index = (unsigned char)c;
+ Bitmap *bm = twd->bitmap;
+ coord_t glyph_width;
+
+
+ if (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index)))
+ {
+ if (!FONT_HAS_GLYPH(bm->font, '?'))
+ index = '?';
+ else
+ index = bm->font->first;
+ }
+
+ /* Make character relative to font start */
+ index -= bm->font->first;
+
+ if (bm->font->offset)
+ /* Proportional font */
+ glyph_width = bm->font->widths[index]; /* TODO: optimize away */
+ else
+ /* Fixed width font */
+ glyph_width = bm->font->width;
+
+ if (bm->styles & STYLEF_CONDENSED)
+ --glyph_width;
+
+ if (bm->styles & STYLEF_EXPANDED)
+ glyph_width *= 2;
+
+ twd->width += glyph_width;
+
+ return c;
+}
+