Index: uspace/lib/gfxfont/include/types/gfx/text.h
===================================================================
--- uspace/lib/gfxfont/include/types/gfx/text.h	(revision 0e80e40d465209db1058a14f81079dee22378462)
+++ uspace/lib/gfxfont/include/types/gfx/text.h	(revision 5c27e77a873b434a25145576e18fe857dc490921)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
+ * Copyright (c) 2022 Jiri Svoboda
  * All rights reserved.
  *
@@ -37,4 +37,5 @@
 #define _TYPES_GFX_TEXT_H
 
+#include <stdbool.h>
 #include <types/gfx/coord.h>
 #include <types/gfx/color.h>
@@ -74,4 +75,6 @@
 	/** Vertical alignment */
 	gfx_valign_t valign;
+	/** Underline */
+	bool underline;
 } gfx_text_fmt_t;
 
Index: uspace/lib/gfxfont/include/types/gfx/typeface.h
===================================================================
--- uspace/lib/gfxfont/include/types/gfx/typeface.h	(revision 0e80e40d465209db1058a14f81079dee22378462)
+++ uspace/lib/gfxfont/include/types/gfx/typeface.h	(revision 5c27e77a873b434a25145576e18fe857dc490921)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
+ * Copyright (c) 2022 Jiri Svoboda
  * All rights reserved.
  *
@@ -50,4 +50,8 @@
 	/** Leading */
 	gfx_coord_t leading;
+	/** Underline start Y coordinate (inclusive) */
+	gfx_coord_t underline_y0;
+	/** Underline end Y coordinate (exclusive) */
+	gfx_coord_t underline_y1;
 } gfx_font_metrics_t;
 
Index: uspace/lib/gfxfont/private/tpf_file.h
===================================================================
--- uspace/lib/gfxfont/private/tpf_file.h	(revision 0e80e40d465209db1058a14f81079dee22378462)
+++ uspace/lib/gfxfont/private/tpf_file.h	(revision 5c27e77a873b434a25145576e18fe857dc490921)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
+ * Copyright (c) 2022 Jiri Svoboda
  * All rights reserved.
  *
@@ -76,4 +76,6 @@
 	uint16_t descent;
 	uint16_t leading;
+	int16_t underline_y0;
+	int16_t underline_y1;
 } tpf_font_metrics_t;
 
Index: uspace/lib/gfxfont/src/font.c
===================================================================
--- uspace/lib/gfxfont/src/font.c	(revision 0e80e40d465209db1058a14f81079dee22378462)
+++ uspace/lib/gfxfont/src/font.c	(revision 5c27e77a873b434a25145576e18fe857dc490921)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
+ * Copyright (c) 2022 Jiri Svoboda
  * All rights reserved.
  *
@@ -546,4 +546,6 @@
 	metrics->descent = uint16_t_le2host(tmetrics.descent);
 	metrics->leading = uint16_t_le2host(tmetrics.leading);
+	metrics->underline_y0 = uint16_t_le2host(tmetrics.underline_y0);
+	metrics->underline_y1 = uint16_t_le2host(tmetrics.underline_y1);
 	return EOK;
 }
@@ -565,4 +567,6 @@
 	tmetrics.descent = host2uint16_t_le(metrics->descent);
 	tmetrics.leading = host2uint16_t_le(metrics->leading);
+	tmetrics.underline_y0 = host2uint16_t_le(metrics->underline_y0);
+	tmetrics.underline_y1 = host2uint16_t_le(metrics->underline_y1);
 
 	rc = riff_wchunk_start(riffw, CKID_fmtr, &mtrck);
Index: uspace/lib/gfxfont/src/text.c
===================================================================
--- uspace/lib/gfxfont/src/text.c	(revision 0e80e40d465209db1058a14f81079dee22378462)
+++ uspace/lib/gfxfont/src/text.c	(revision 5c27e77a873b434a25145576e18fe857dc490921)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2021 Jiri Svoboda
+ * Copyright (c) 2022 Jiri Svoboda
  * All rights reserved.
  *
@@ -229,15 +229,18 @@
 {
 	gfx_glyph_metrics_t gmetrics;
+	gfx_font_metrics_t fmetrics;
 	size_t stradv;
 	const char *cp;
 	gfx_glyph_t *glyph;
 	gfx_coord2_t cpos;
+	gfx_coord2_t spos;
+	gfx_rect_t rect;
 	errno_t rc;
 
-	gfx_text_start_pos(font, pos, fmt, str, &cpos);
+	gfx_text_start_pos(font, pos, fmt, str, &spos);
 
 	/* Text mode */
 	if ((font->finfo->props.flags & gff_text_mode) != 0)
-		return gfx_puttext_textmode(font, &cpos, fmt->color, str);
+		return gfx_puttext_textmode(font, &spos, fmt->color, str);
 
 	rc = gfx_set_color(font->typeface->gc, fmt->color);
@@ -245,4 +248,5 @@
 		return rc;
 
+	cpos = spos;
 	cp = str;
 	while (*cp != '\0') {
@@ -261,4 +265,18 @@
 		cp += stradv;
 		cpos.x += gmetrics.advance;
+	}
+
+	/* Text underlining */
+	if (fmt->underline) {
+		gfx_font_get_metrics(font, &fmetrics);
+
+		rect.p0.x = spos.x;
+		rect.p0.y = spos.y + fmetrics.underline_y0;
+		rect.p1.x = cpos.x;
+		rect.p1.y = spos.y + fmetrics.underline_y1;
+
+		rc = gfx_fill_rect(font->typeface->gc, &rect);
+		if (rc != EOK)
+			return rc;
 	}
 
