diff --git a/ui/allg5ui/renderer.go b/ui/allg5ui/renderer.go
index 34ddbef..e199e77 100644
--- a/ui/allg5ui/renderer.go
+++ b/ui/allg5ui/renderer.go
@@ -3,6 +3,7 @@ package allg5ui
 import (
 	"image"
 	"image/color"
+	"math"
 
 	"opslag.de/schobers/geom"
 
@@ -223,7 +224,9 @@ func (r *Renderer) Text(p geom.PointF32, font string, c color.Color, t string) {
 	if f == nil {
 		return
 	}
-	f.f.Draw(p.X, p.Y, newColor(c), allg5.AlignLeft, t)
+	x := float32(math.Round(float64(p.X)))
+	y := float32(math.Round(float64(p.Y)))
+	f.f.Draw(x, y, newColor(c), allg5.AlignLeft, t)
 }
 
 // Utility functions
diff --git a/ui/button.go b/ui/button.go
index 9a109f2..819d352 100644
--- a/ui/button.go
+++ b/ui/button.go
@@ -17,7 +17,7 @@ func BuildButton(text string, factory func(b *Button)) *Button {
 }
 
 func (b *Button) DesiredSize(ctx Context) geom.PointF32 {
-	var fontName = b.fontName(ctx)
+	var fontName = b.FontName(ctx)
 	var font = ctx.Renderer().Font(fontName)
 	var width = font.WidthOf(b.Text)
 	var height = font.Height()
@@ -33,7 +33,7 @@ func (b *Button) Handle(ctx Context, e Event) {
 }
 
 func (b *Button) Render(ctx Context) {
-	var fore = b.FontColor
+	var fore = b.Font.Color
 	var style = ctx.Style()
 	if fore == nil {
 		fore = style.Palette.TextOnPrimary
@@ -43,7 +43,7 @@ func (b *Button) Render(ctx Context) {
 		fill = style.Palette.PrimaryHighlight
 	}
 	var pad = style.Dimensions.TextPadding
-	var font = b.fontName(ctx)
+	var font = b.FontName(ctx)
 	ctx.Renderer().FillRectangle(b.bounds, fill)
 	ctx.Renderer().Text(b.bounds.Min.Add(geom.PtF32(pad, pad)), font, fore, b.Text)
 }
diff --git a/ui/controlbase.go b/ui/controlbase.go
index dc7d2f7..06adaf4 100644
--- a/ui/controlbase.go
+++ b/ui/controlbase.go
@@ -28,8 +28,7 @@ type ControlBase struct {
 	onDragStart DragStartFn
 
 	Background color.Color
-	FontName   string
-	FontColor  color.Color
+	Font       FontStyle
 }
 
 func (c *ControlBase) Arrange(ctx Context, bounds geom.RectangleF32, offset geom.PointF32) {
@@ -93,6 +92,22 @@ func (c *ControlBase) Handle(ctx Context, e Event) {
 	}
 }
 
+func (c *ControlBase) FontColor(ctx Context) color.Color {
+	var text = c.Font.Color
+	if text == nil {
+		text = ctx.Style().Palette.Text
+	}
+	return text
+}
+
+func (c *ControlBase) FontName(ctx Context) string {
+	var name = c.Font.Name
+	if len(name) == 0 {
+		name = ctx.Style().Fonts.Default
+	}
+	return name
+}
+
 func (c *ControlBase) IsOver() bool { return c.over }
 
 func (c *ControlBase) IsPressed() bool { return c.pressed }
@@ -123,11 +138,3 @@ func (c *ControlBase) RenderBackground(ctx Context) {
 
 func (c *ControlBase) Render(Context) {
 }
-
-func (c *ControlBase) fontName(ctx Context) string {
-	var name = c.FontName
-	if len(name) == 0 {
-		name = ctx.Style().Fonts.Default
-	}
-	return name
-}
diff --git a/ui/font.go b/ui/font.go
index 8062ad3..226fc38 100644
--- a/ui/font.go
+++ b/ui/font.go
@@ -1,6 +1,8 @@
 package ui
 
 import (
+	"image/color"
+
 	"opslag.de/schobers/geom"
 )
 
@@ -9,3 +11,8 @@ type Font interface {
 	Measure(t string) geom.RectangleF32
 	WidthOf(t string) float32
 }
+
+type FontStyle struct {
+	Name  string
+	Color color.Color
+}
diff --git a/ui/label.go b/ui/label.go
index 5d5985e..eba42fe 100644
--- a/ui/label.go
+++ b/ui/label.go
@@ -17,7 +17,7 @@ func BuildLabel(text string, factory func(*Label)) *Label {
 }
 
 func (l *Label) DesiredSize(ctx Context) geom.PointF32 {
-	var fontName = l.fontName(ctx)
+	var fontName = l.FontName(ctx)
 	var font = ctx.Renderer().Font(fontName)
 	var width = font.WidthOf(l.Text)
 	var height = font.Height()
@@ -27,11 +27,8 @@ func (l *Label) DesiredSize(ctx Context) geom.PointF32 {
 
 func (l *Label) Render(ctx Context) {
 	l.RenderBackground(ctx)
-	var c = l.FontColor
-	if c == nil {
-		c = ctx.Style().Palette.Text
-	}
-	var f = l.fontName(ctx)
+	var c = l.FontColor(ctx)
+	var f = l.FontName(ctx)
 	var pad = ctx.Style().Dimensions.TextPadding
 	ctx.Renderer().Text(l.bounds.Min.Add(geom.PtF32(pad, pad)), f, c, l.Text)
 }