diff --git a/libs/gfx/resources/font_9x12.pbm b/libs/gfx/resources/font_9x12.pbm
index 6c65e962..dc215b32 100644
--- a/libs/gfx/resources/font_9x12.pbm
+++ b/libs/gfx/resources/font_9x12.pbm
@@ -1,3 +1,3 @@
 P4
-144 72
-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû÷ÿÿÿÿÿÿÿÿûò~¿ÿïû÷ýÿÿÿÿÿûÿûöþ¾>¿ÿï÷ûð~ÿÿÿÿûÿûöý}ÿÏï÷ûýþÿÿÿÿ÷ÿûÿø=ÿÏ¿ï÷ûúþÿÿÿÿ÷ÿûÿý~>?¿ÿ÷ûúðþÿïÿÿÿø=¿ßWÿ÷ûÿþÿÿÿÿïÿÿÿý|¯oÿ÷ûÿþÿ?ÿŸßÿûÿúÿß—ÿû÷ÿþÿÿŸßÿÿÿúÿÿÿÿû÷ÿÿþÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãóøüŸÇƒãñÿÿÿÿÿÿÿÝû÷{¿_¿»ÝîÿÿÿŸþçÝûÿ¿_ûÝîùþÿ¿ÛÝûþþ~ß÷ãîùþ|þÏûÝûýÿ½ßïw÷Ýðÿÿûÿÿ÷÷Ýûûÿ¼ïw÷ÝþÿÿüþÏïÝû÷{¿ÞïwïÝýùþÿ¿ÿãàð|��ïããùüÿŸþÏÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝóàü8|Ãˆàøq|F#ÇÝû÷{½¾ïw»Ýûþû¾þO7»Ùõ÷{ýÞ¿_¿Ýûþû~þO7»ÕõðûýÞ?¿Áûþúþþ¯W»Õõ÷{ýÞ¿_±Ýûöøþþ¯W»Ùà÷{ýÞÿ»Ýûöû~ÞïW»ßî÷{½¾ï»Ýûöû¾Þïg»ÝÄ`üx|?ÇˆàùñœF'ÇãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÃñàü¸F#œÄp}ýÿßßÿíî÷{;nïw»Ýî÷}þÿßßÿíî÷{ÿ~ïw»ëõþýþÿß¯ÿíî÷|~ï¯«÷õýýþÿßwÿãîðÿ¿~ï¯«÷ûýýÿßÿÿïîöÿ¿~ï¯«ëûûýÿßÿÿïî÷y¿~ïß«Ýû÷}ÿ¿ßÿÿÇñãº~?ß×œñð}ÿ¿ßÿÿÿøÿÿÿÿÿÿÿÿÿÿü¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿçÿÿŸÿÇÿŸûýóþÿÿÿÿÿ÷ÿÿßÿ¿ÿßÿÿûÿÿÿÿÿñôü>_ÉÓãðú?|^OÇÿîó{½žï¿³Íûþû~¯7»ÿð÷{ýÞ¿»Ýûþøÿ~¯w»ÿî÷{ýÞÿ¿»Ýûþúÿ~¯w»ÿî÷{½Þÿ¿»Ýûþû~¯w»ÿð`ü~Ãˆàþò<#ÇÿÿÿÿÿÿÿÿûÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÿÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ¿·ÿÿÿÿÿýÿÿÿÿÿÿÿþÿ¿Oÿ“òr|8<Î#ÌÄp~ÿ¿ÿÿÍìùû½þïw»íîöþÿ¿ÿÿÝîûü}þïw«óöýýÿßÿÿÝîûÿ½þï¯«óõûþÿ¿ÿÿÝîûû½ÞÏ¯«íù÷~ÿ¿ÿÿÃððx~?'ß×Ìûð~ÿ¿ÿÿßþÿÿÿÿÿÿÿÿûÿÿÿÿÿ�üÿÿÿÿÿÿÿáÿÿÿÿÿÿÿ
\ No newline at end of file
+176 84
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿÿÿÿÿÿÿÿÿÿ“ý¿ïÿÿßýþÿïÿÿÿÿÿÿ÷ÿÿ·ý×ÿÿßûÿƒýÿÿÿÿÿ÷ÿÿ·úþÿïþßûÿïýÿÿÿÿÿïÿÿÿð~ÿùýÿßûÿ×ýÿÿÿÿÿïÿÿÿúÿÇýÿÿûÿ×à?ÿÁÿÿßÿÿÿÿð~ßûú¿ÿûÿÿýÿÿÿÿÿßÿÿÿÿúþ?õûÿûÿÿýÿŸÿüÿ¿ÿÿÿõÿ¿ûü¿ÿýþÿÿýÿ¿ÿüÿ¿ÿÿÿÿõÿ¿ÿÿÿÿýþÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñþÇøÿÏáþ?ñþ?ÿÿÿÿÿÿÿÿîÿ»÷¯ïýÿwîýßÿÿÿÏÿóÿÏîÿûÿ¯ïûÿ÷îýßÏüÿ¿ÿýÿ·îÿ÷üÿoãøïñýßÏüþÁþ÷îÿïÿ~ïýû¿ïîþÿÿýÿÿÿ¿ïîÿßÿ~ýû¿ïîÿßÿÿþÁþßîÿ»÷ïÝû¿ßîÿ¿Ïüÿ¿ÿýÿÿñüƒøÿÇãüßñüÏùÿÏÿóÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîþø|?�ð?‡Ä|Ãâ>?ˆñ�îÿ»÷~ßÝû¿wîÿ÷÷Éù¿wìþ¿»÷þï×úÿîÿ÷öÿÉù¿wêþ¿‡÷þïÇøÿàÿ÷õÿÕú¿wêþ¿»÷þï×úÿcîÿ·ñÿÕú¿wìü»÷þïßûÿwîÿ·öÿoÝú¿wïýß»÷~ßÝûÿwîÿ·÷oÝû?wîø�øü?�ñÿ�Ä|Ïã>ˆñ?�ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿãÿÿÿáþ?ù|ˆñ#Îx�ƒûþÿûþÿÿöýß»ö}·Ýû¿wîýß»ûÿûþÿÿöýß»÷ÿ¿Ýû¿wõþ¿÷ûÿûýÿöýß»øÿ¿ÝýWûþ¿ïûÿûû¿ÿñýß‡ÿ¿ÝýWûÿïûÿ¿ûÿÿÿ÷ýß·ÿ¿ÝýWõÿßûÿ¿ûÿÿÿ÷ýß»ó¿ÝþÿWîÿ»ûÿßûÿÿÿãþ?ôÿãþÿ¯Î~?ƒûÿßûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿßãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿ?ÿÿÏÿþ?ÿÏÿïçÿ?ÿÿÿÿÿÿÿ¿ÿÿïÿýÿÿïÿÿÿ÷ÿ¿ÿÿÿÿÿþ?§ø/ãø?“éü‡ô¿‹ò�ÿýß›÷~ÏÝýÿgæÿ÷öÿ¿Õù¿wÿþ»÷þïÁýÿwîÿ÷ñÿ¿Õû¿wÿýß»÷þïßýÿwîÿ÷õÿ¿Õû¿wÿýß»÷~ïßýÿwîÿ÷öÿ¿Õû¿wÿþøÿáø?‡Ä|÷ä~€ñ�ÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�ÿÿÿ�ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ¿ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿ¿÷ý¿ÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿýÿ¿÷úÿÉþO“ø|™ñ#æx�ƒýÿ¿÷ÿÿÿæýŸÏ÷~ÿÝû¿wöýß·ýÿ¿÷ÿÿÿîýßßøþÿÝû¿Wùþßïûÿ¿ûÿÿÿîýßßÿ~ÿÝýWùþ¿ßýÿ¿÷ÿÿÿîýßß÷~ïÙýWöÿ?»ýÿ¿÷ÿÿÿáþƒðÿäþÿ¯æƒýÿ¿÷ÿÿÿïÿßÿÿÿÿÿÿÿÿÿÿÿþÿÿïÿÿÿÇÿ�ÿÿÿÿÿÿÿÿÿü?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
\ No newline at end of file
diff --git a/libs/gfx/source/painter.cpp b/libs/gfx/source/painter.cpp
index 79639647..c317ec63 100644
--- a/libs/gfx/source/painter.cpp
+++ b/libs/gfx/source/painter.cpp
@@ -5,6 +5,7 @@
 #include <psemek/gfx/resource/font_9x12.hpp>
 #include <psemek/geom/constants.hpp>
 #include <psemek/util/memory_stream.hpp>
+#include <psemek/log/log.hpp>
 
 static const char vertex_source[] =
 R"(#version 330
@@ -40,6 +41,7 @@ static const char text_vertex_source[] =
 R"(#version 330
 
 uniform mat4 u_transform;
+uniform ivec2 u_texture_size;
 
 layout (location = 0) in vec4 in_position;
 layout (location = 1) in vec4 in_color;
@@ -52,7 +54,7 @@ void main()
 {
 	gl_Position = u_transform * in_position;
 	color = in_color;
-	texcoord = in_texcoord;
+	texcoord = in_texcoord / vec2(u_texture_size);
 }
 )";
 
@@ -106,7 +108,7 @@ namespace psemek::gfx
 		impl()
 		{
 			mesh.setup<geom::vector<float, 3>, gfx::normalized<color_rgba>>();
-			text_mesh.setup<geom::point<float, 2>, gfx::normalized<color_rgba>, gfx::normalized<geom::point<std::uint16_t, 2>>>();
+			text_mesh.setup<geom::point<float, 2>, gfx::normalized<color_rgba>, geom::point<std::uint16_t, 2>>();
 
 			util::memory_istream font_data(resource::font_9x12);
 			font_texture.load(gfx::read_pbm(font_data));
@@ -117,6 +119,8 @@ namespace psemek::gfx
 			gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_SWIZZLE_A, gl::RED);
 			gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST);
 			gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST);
+			gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE);
+			gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE);
 		}
 	};
 
@@ -259,9 +263,9 @@ namespace psemek::gfx
 		geom::vector<float, 2> const sx = {9.f * opts.scale, 0.f};
 		geom::vector<float, 2> const sy = {0.f, 12.f * opts.scale};
 
-		auto to_texcoord = [](int tx, int ty)
+		auto to_texcoord = [](int tx, int ty, int ix, int iy)
 		{
-			return geom::point<std::uint16_t, 2>{ (tx * 65535) / 16, (ty * 65535) / 6 };
+			return geom::point<std::uint16_t, 2>{ tx * 11 + (ix == 0 ? 1 : 10), ty * 14 + (iy == 0 ? 1 : 13) };
 		};
 
 		for (char c : str)
@@ -277,10 +281,10 @@ namespace psemek::gfx
 
 			std::uint32_t const base = impl().text_vertices.size();
 
-			impl().text_vertices.push_back({pen, opts.c, to_texcoord(tx, ty)});
-			impl().text_vertices.push_back({pen + sx, opts.c, to_texcoord(tx + 1, ty)});
-			impl().text_vertices.push_back({pen + sy, opts.c, to_texcoord(tx, ty + 1)});
-			impl().text_vertices.push_back({pen + sx + sy, opts.c, to_texcoord(tx + 1, ty + 1)});
+			impl().text_vertices.push_back({pen, opts.c, to_texcoord(tx, ty, 0, 0)});
+			impl().text_vertices.push_back({pen + sx, opts.c, to_texcoord(tx, ty, 1, 0)});
+			impl().text_vertices.push_back({pen + sy, opts.c, to_texcoord(tx, ty, 0, 1)});
+			impl().text_vertices.push_back({pen + sx + sy, opts.c, to_texcoord(tx, ty, 1, 1)});
 
 			impl().text_indices.push_back(base + 0);
 			impl().text_indices.push_back(base + 1);
@@ -435,6 +439,7 @@ namespace psemek::gfx
 		impl().text_program.bind();
 		impl().text_program["u_transform"] = transform;
 		impl().text_program["u_texture"] = 0;
+		impl().text_program["u_texture_size"] = impl().font_texture.size();
 		impl().font_texture.bind();
 		impl().text_mesh.draw(gl::TRIANGLES);
 	}
