← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/1535296-cleanup-and-autofit into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/1535296-cleanup-and-autofit into lp:widelands.

Commit message:
Various font face and font size related fixes and cleanups:

- Fixed bug where font face types were not recognized by the new font renderer ("Font file not found. Falling back to serif")
- Changed the fallback font to sans.
- Cleanup: UI::TextStyle is now only used in the old font handler and in wordwrap (wordwrap still needs some of its functions for efficiency). Removed ui_big() and ui_small().

- Added sigclicked signal to TabPanel.
- Textareas with fixed width will now automatically resize the text to fit the width. The new function is used by the building statistics, spinboxes, and the waresdisplay.
- Cleanup: Removed prerendering of text in WaresDisplay, because the flickering has been fixed with the recent graphics changes.

- Added helptext to Editor CategorizedItemSelectionMenu when nothing has been selected.
- Editor CategorizedItemSelectionMenu no longer grows excessively wide when multiple items are selected: There is a limit of maximum items displayed, and the label will autoexpand to the bottom.


Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1524994 in widelands: "[editor] tools windows gets wider in editor when multiselect"
  https://bugs.launchpad.net/widelands/+bug/1524994
  Bug #1535296 in widelands: "Font file not found"
  https://bugs.launchpad.net/widelands/+bug/1535296

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/1535296-cleanup-and-autofit/+merge/285405

I originally set out to make sure that warenames will always fit in the warehouse window for all translations, and the whole thing snowballed a bit with some preliminary bug fixing and some cleanup.

See the commit message for details.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/1535296-cleanup-and-autofit into lp:widelands.
=== modified file 'data/i18n/fonts.lua'
--- data/i18n/fonts.lua	2016-01-23 14:50:23 +0000
+++ data/i18n/fonts.lua	2016-02-08 20:18:15 +0000
@@ -9,64 +9,64 @@
 return {
    -- This is the default set and always needs to be complete. It covers all possible font styles.
    default = {
-      -- If your language doesn't distinguish between serif and sans serif fonts, please use the serif set.
-       -- Your font set should always define "serif".
+      -- If your language doesn't distinguish between serif and sans serif fonts, please use the sans set.
+      -- Your font set should always define "sans".
+      sans = "DejaVu/DejaVuSans.ttf",
+      sans_bold = "DejaVu/DejaVuSans-Bold.ttf",
+      sans_italic = "DejaVu/DejaVuSans-Oblique.ttf",
+      sans_bold_italic = "DejaVu/DejaVuSans-BoldOblique.ttf",
+      -- If your font set doesn't have serif or condensed variants, sans will be used instead.
       serif = "DejaVu/DejaVuSerif.ttf",
-       -- Add bold and italic variants if your font set has them.
+      -- Add bold and italic variants if your font set has them.
       serif_bold = "DejaVu/DejaVuSerif-Bold.ttf",
       serif_italic = "DejaVu/DejaVuSerif-Italic.ttf",
       serif_bold_italic = "DejaVu/DejaVuSerif-BoldItalic.ttf",
-      -- If your font set doesn't have sans or condensed variants, serif will be used instead.
-      sans = "DejaVu/DejaVuSans.ttf",
-      sans_bold = "DejaVu/DejaVuSans-Bold.ttf",
-      sans_italic = "DejaVu/DejaVuSans-Oblique.ttf",
-      sans_bold_italic = "DejaVu/DejaVuSans-BoldOblique.ttf",
       condensed = "DejaVu/DejaVuSansCondensed.ttf",
       condensed_bold = "DejaVu/DejaVuSansCondensed-Bold.ttf",
       condensed_italic = "DejaVu/DejaVuSansCondensed-Oblique.ttf",
       condensed_bold_italic = "DejaVu/DejaVuSansCondensed-BoldOblique.ttf",
-      -- If the diection isn't defined, your font set will default to "ltr" = left-to-right.
+      -- If the direction isn't defined, your font set will default to "ltr" = left-to-right.
       -- For right-to-left or bidirectional (BiDi) languages, use "rtl".
       direction = "ltr",
       size_offset = 0
    },
 
    arabic = {
-      serif = "amiri/amiri-regular.ttf",
-      serif_bold = "amiri/amiri-bold.ttf",
-      serif_italic = "amiri/amiri-slanted.ttf",
-      serif_bold_italic = "amiri/amiri-boldslanted.ttf",
+      sans = "amiri/amiri-regular.ttf",
+      sans_bold = "amiri/amiri-bold.ttf",
+      sans_italic = "amiri/amiri-slanted.ttf",
+      sans_bold_italic = "amiri/amiri-boldslanted.ttf",
       direction = "rtl",
       size_offset = 4
    },
 
    cjk = {
-      serif = "MicroHei/wqy-microhei.ttc",
+      sans = "MicroHei/wqy-microhei.ttc",
    },
 
    devanagari = {
-      serif = "Nakula/nakula.ttf",
+      sans = "Nakula/nakula.ttf",
       direction = "rtl",
       size_offset = 2
    },
 
    hebrew = {
+      sans = "Culmus/TaameyFrankCLM-Medium.ttf",
+      sans_bold = "TaameyFrankCLM-Bold.ttf",
+      sans_italic = "Culmus/TaameyFrankCLM-MediumOblique.ttf",
       serif = "Culmus/TaameyFrankCLM-Medium.ttf",
       serif_bold = "TaameyFrankCLM-Bold.ttf",
       serif_italic = "Culmus/TaameyFrankCLM-MediumOblique.ttf",
-      sans = "Culmus/TaameyFrankCLM-Medium.ttf",
-      sans_bold = "TaameyFrankCLM-Bold.ttf",
-      sans_italic = "Culmus/TaameyFrankCLM-MediumOblique.ttf",
       direction = "rtl",
       size_offset = 4
    },
 
    myanmar = {
-      serif = "mmrCensus/mmrCensus.ttf",
+      sans = "mmrCensus/mmrCensus.ttf",
       size_offset = 2
    },
 
    sinhala = {
-      serif = "Sinhala/lklug.ttf",
+      sans = "Sinhala/lklug.ttf",
    }
 }

=== modified file 'src/editor/ui_menus/categorized_item_selection_menu.h'
--- src/editor/ui_menus/categorized_item_selection_menu.h	2016-01-29 08:37:22 +0000
+++ src/editor/ui_menus/categorized_item_selection_menu.h	2016-02-08 20:18:15 +0000
@@ -20,8 +20,11 @@
 #ifndef WL_EDITOR_UI_MENUS_CATEGORIZED_ITEM_SELECTION_MENU_H
 #define WL_EDITOR_UI_MENUS_CATEGORIZED_ITEM_SELECTION_MENU_H
 
+#include <algorithm>
+#include <cmath>
 #include <string>
-#include <cmath>
+
+#include "boost/format.hpp"
 
 #include "base/i18n.h"
 #include "graphic/image.h"
@@ -29,9 +32,9 @@
 #include "logic/map_objects/world/editor_category.h"
 #include "ui_basic/box.h"
 #include "ui_basic/checkbox.h"
+#include "ui_basic/multilinetextarea.h"
 #include "ui_basic/panel.h"
 #include "ui_basic/tabpanel.h"
-#include "ui_basic/textarea.h"
 
 template <typename DescriptionType, typename ToolType>
 class CategorizedItemSelectionMenu : public UI::Box {
@@ -60,7 +63,8 @@
 	const DescriptionMaintainer<DescriptionType>& descriptions_;
 	std::function<void()> select_correct_tool_;
 	bool protect_against_recursive_select_;
-	UI::Textarea current_selection_names_;
+	UI::TabPanel tab_panel_;
+	UI::MultilineTextarea current_selection_names_;
 	std::map<int, UI::Checkbox*> checkboxes_;
 	ToolType* const tool_;  // not owned
 };
@@ -78,11 +82,12 @@
 	descriptions_(descriptions),
 	select_correct_tool_(select_correct_tool),
 	protect_against_recursive_select_(false),
-	current_selection_names_(this, 0, 0, 0, 20, UI::Align::kCenter),
+	tab_panel_(this, 0, 0, nullptr),
+	current_selection_names_(this, 0, 0, 20, 20, "", UI::Align::kCenter,
+									 UI::MultilineTextarea::ScrollMode::kNoScrolling),
 	tool_(tool)
 {
-	UI::TabPanel* tab_panel = new UI::TabPanel(this, 0, 0, nullptr);
-	add(tab_panel, UI::Align::kCenter);
+	add(&tab_panel_, UI::Align::kCenter);
 
 	for (uint32_t category_index = 0; category_index < categories.size(); ++category_index) {
 		const Widelands::EditorCategory& category = categories.get(category_index);
@@ -95,7 +100,7 @@
 			item_indices.push_back(j);
 		}
 
-		UI::Box* vertical = new UI::Box(tab_panel, 0, 0, UI::Box::Vertical);
+		UI::Box* vertical = new UI::Box(&tab_panel_, 0, 0, UI::Box::Vertical);
 		const int kSpacing = 5;
 		vertical->add_space(kSpacing);
 
@@ -121,9 +126,11 @@
 			horizontal->add_space(kSpacing);
 			++nitems_handled;
 		}
-		tab_panel->add(category.name(), category.picture(), vertical, category.descname());
+		tab_panel_.add(category.name(), category.picture(), vertical, category.descname());
 	}
 	add(&current_selection_names_, UI::Align::kCenter, true);
+	tab_panel_.sigclicked.connect(boost::bind(&CategorizedItemSelectionMenu::update_label, this));
+	update_label();
 }
 
 template <typename DescriptionType, typename ToolType>
@@ -160,15 +167,29 @@
 
 template <typename DescriptionType, typename ToolType>
 void CategorizedItemSelectionMenu<DescriptionType, ToolType>::update_label() {
-	std::string buf = _("Current:");
+	current_selection_names_.set_size(tab_panel_.get_inner_w(), 20);
+	std::string buf = "";
+	constexpr int max_string_size = 100;
 	int j = tool_->get_nr_enabled();
-	for (int i = 0; j; ++i) {
+	for (int i = 0; j && buf.size() < max_string_size; ++i) {
 		if (tool_->is_enabled(i)) {
-			buf += " ";
+			if (j < tool_->get_nr_enabled()) {
+				buf += " • ";
+			}
 			buf += descriptions_.get(i).descname();
 			--j;
 		}
 	}
+	if (buf.size() > max_string_size) {
+		/** TRANSLATORS: %s are the currently selected items in an editor tool*/
+		buf = (boost::format(_("Current: %s …")) % buf).str();
+	} else if (buf.empty()) {
+		/** TRANSLATORS: Help text in an editor tool*/
+		buf = _("Click to select an item. Use the Ctrl key to select multiple items.");
+	} else {
+		/** TRANSLATORS: %s are the currently selected items in an editor tool*/
+		buf = (boost::format(_("Current: %s")) % buf).str();
+	}
 	current_selection_names_.set_text(buf);
 }
 

=== modified file 'src/graphic/text/font_set.cc'
--- src/graphic/text/font_set.cc	2016-01-28 05:24:34 +0000
+++ src/graphic/text/font_set.cc	2016-02-08 20:18:15 +0000
@@ -123,7 +123,7 @@
 					std::unique_ptr<LuaTable> font_set_table = fonts_table->get_table(fontsetname);
 					font_set_table->do_not_warn_about_unaccessed_keys();
 
-					set_fonts(*font_set_table, serif_);
+					set_fonts(*font_set_table, sans_);
 					direction_string = get_string_with_default(*font_set_table, "direction", "ltr");
 					if (font_set_table->has_key("size_offset")) {
 						size_offset_ = font_set_table->get_int("size_offset");
@@ -150,12 +150,12 @@
 
 // The documentation on the fonts fallback scheme is in the 'data/i18n/fonts.lua' data file.
 void FontSet::set_fonts(const LuaTable& table, const std::string& fallback) {
-	set_font_group(table, "serif", fallback,
+	set_font_group(table, "sans", fallback,
+						&sans_, &sans_bold_, &sans_italic_, &sans_bold_italic_);
+
+	set_font_group(table, "serif", sans_,
 						&serif_, &serif_bold_, &serif_italic_, &serif_bold_italic_);
 
-	set_font_group(table, "sans", serif_,
-						&sans_, &sans_bold_, &sans_italic_, &sans_bold_italic_);
-
 	set_font_group(table, "condensed", sans_,
 						&condensed_, &condensed_bold_, &condensed_italic_, &condensed_bold_italic_);
 }

=== modified file 'src/graphic/text/font_set.h'
--- src/graphic/text/font_set.h	2016-01-28 05:24:34 +0000
+++ src/graphic/text/font_set.h	2016-02-08 20:18:15 +0000
@@ -29,7 +29,13 @@
 // Contains font information for a locale
 struct FontSet {
 
-	static constexpr const char* kFallbackFont = "DejaVu/DejaVuSerif.ttf";
+	enum class Face {
+		kSans,
+		kSerif,
+		kCondensed
+	};
+
+	static constexpr const char* kFallbackFont = "DejaVu/DejaVuSans.ttf";
 
 	/// Create the fontset for a locale from configuration file
 	FontSet(const std::string& localename);

=== modified file 'src/graphic/text/rt_render.cc'
--- src/graphic/text/rt_render.cc	2016-01-31 12:16:38 +0000
+++ src/graphic/text/rt_render.cc	2016-02-08 20:18:15 +0000
@@ -622,6 +622,13 @@
 }
 
 IFont& FontCache::get_font(NodeStyle* ns) {
+	if (ns->font_face == "condensed") {
+		ns->font_face = ns->fontset->condensed();
+	} else if (ns->font_face == "serif") {
+		ns->font_face = ns->fontset->serif();
+	} else if (ns->font_face == "sans") {
+		ns->font_face = ns->fontset->sans();
+	}
 	const bool is_bold = ns->font_style & IFont::BOLD;
 	const bool is_italic = ns->font_style & IFont::ITALIC;
 	if (is_bold && is_italic) {
@@ -669,8 +676,8 @@
 	try {
 		font.reset(load_font(ns->font_face, font_size));
 	} catch (FileNotFoundError& e) {
-		log("Font file not found. Falling back to serif: %s\n%s\n", ns->font_face.c_str(), e.what());
-		font.reset(load_font(ns->fontset->serif(), font_size));
+		log("Font file not found. Falling back to sans: %s\n%s\n", ns->font_face.c_str(), e.what());
+		font.reset(load_font(ns->fontset->sans(), font_size));
 	}
 	assert(font != nullptr);
 
@@ -1142,7 +1149,7 @@
 Renderer::Renderer(ImageCache* image_cache, TextureCache* texture_cache, UI::FontSet* fontset) :
 	font_cache_(new FontCache()), parser_(new Parser()),
 	image_cache_(image_cache), texture_cache_(texture_cache), fontset_(fontset),
-	renderer_style_(fontset->serif(), 16, INFINITE_WIDTH, INFINITE_WIDTH) {
+	renderer_style_(fontset->sans(), 16, INFINITE_WIDTH, INFINITE_WIDTH) {
 	TextureCache* render
 		(const std::string&, uint16_t, const TagSet&);
 }

=== modified file 'src/graphic/text/rt_render.h'
--- src/graphic/text/rt_render.h	2015-09-26 11:12:28 +0000
+++ src/graphic/text/rt_render.h	2016-02-08 20:18:15 +0000
@@ -58,7 +58,7 @@
  * Fonts in our sense are defined by the general font shape (given by the font
  * name) and the size of the font. Note that Bold and Italic are special in the
  * regard that we expect that this is already handled by the Font File, so, the
- * font loader directly loads DejaVuSerif-Bold.ttf for example.
+ * font loader directly loads DejaVuSans-Bold.ttf for example.
  */
 class IFont {
 public:

=== modified file 'src/graphic/text_constants.h'
--- src/graphic/text_constants.h	2015-12-13 21:04:01 +0000
+++ src/graphic/text_constants.h	2016-02-08 20:18:15 +0000
@@ -26,6 +26,7 @@
 #define UI_FONT_SIZE_BIG        22
 #define UI_FONT_SIZE_SMALL      14
 #define UI_FONT_SIZE_ULTRASMALL 10
+constexpr int kMinimumFontSize = 6;
 
 /// Font colors
 

=== modified file 'src/graphic/text_layout.cc'
--- src/graphic/text_layout.cc	2016-01-31 12:43:15 +0000
+++ src/graphic/text_layout.cc	2016-02-08 20:18:15 +0000
@@ -64,28 +64,29 @@
 }
 
 std::string as_window_title(const std::string& txt) {
-	static boost::format f("<rt><p><font face=serif size=13 bold=1 color=%s>%s</font></p></rt>");
+	static boost::format f("<rt><p><font face=sans size=13 bold=1 color=%s>%s</font></p></rt>");
 
 	f % UI_FONT_CLR_FG.hex_value();
 	f % txt;
 	return f.str();
 }
 
-std::string as_uifont(const std::string & txt, int size, const RGBColor& clr) {
-	return as_aligned(txt, UI::Align::kLeft, size, clr);
+std::string as_uifont(const std::string & txt, int size, const RGBColor& clr, UI::FontSet::Face face) {
+	return as_aligned(txt, UI::Align::kLeft, size, clr, face);
 }
 
 std::string as_editorfont(const std::string& text, int ptsize, const RGBColor& clr) {
 	// UI Text is always bold due to historic reasons
 	static boost::format
-			f("<rt keep_spaces=1><p><font face=serif size=%i bold=1 shadow=1 color=%s>%s</font></p></rt>");
+			f("<rt keep_spaces=1><p><font face=sans size=%i bold=1 shadow=1 color=%s>%s</font></p></rt>");
 	f % ptsize;
 	f % clr.hex_value();
 	f % richtext_escape(text);
 	return f.str();
 }
 
-std::string as_aligned(const std::string & txt, UI::Align align, int ptsize, const RGBColor& clr) {
+std::string as_aligned(const std::string & txt, UI::Align align, int ptsize, const RGBColor& clr,
+							  UI::FontSet::Face face) {
 	std::string alignment = "left";
 	if ((align & UI::Align::kHorizontal) == UI::Align::kRight) {
 		alignment = "right";
@@ -93,10 +94,25 @@
 		alignment = "center";
 	}
 
+	std::string font_face = "sans";
+
+	switch (face) {
+	case UI::FontSet::Face::kCondensed:
+		font_face = "condensed";
+		break;
+	case UI::FontSet::Face::kSerif:
+		font_face = "serif";
+		break;
+	case UI::FontSet::Face::kSans:
+		font_face = "sans";
+		break;
+	}
+
 	// UI Text is always bold due to historic reasons
 	static boost::format
-			f("<rt><p align=%s><font face=serif size=%i bold=1 shadow=1 color=%s>%s</font></p></rt>");
+			f("<rt><p align=%s><font face=%s size=%i bold=1 shadow=1 color=%s>%s</font></p></rt>");
 	f % alignment;
+	f % font_face;
 	f % ptsize;
 	f % clr.hex_value();
 	f % txt;
@@ -104,7 +120,7 @@
 }
 
 std::string as_tooltip(const std::string & txt) {
-	static boost::format f("<rt><p><font face=serif size=%i bold=1 color=%s>%s</font></p></rt>");
+	static boost::format f("<rt><p><font face=sans size=%i bold=1 color=%s>%s</font></p></rt>");
 
 	f % UI_FONT_SIZE_SMALL;
 	f % UI_FONT_TOOLTIP_CLR.hex_value();
@@ -210,27 +226,12 @@
 =============================
 */
 
-
-const TextStyle & TextStyle::ui_big()
-{
-	static TextStyle style;
-
-	style.font = Font::get(UI::g_fh1->fontset().serif(), UI_FONT_SIZE_BIG);
-	style.fg = UI_FONT_CLR_FG;
-	style.bold = true;
-
-	return style;
-}
-
-const TextStyle & TextStyle::ui_small()
-{
-	static TextStyle style;
-
-	style.font = Font::get(UI::g_fh1->fontset().serif(), UI_FONT_SIZE_SMALL);
-	style.fg = UI_FONT_CLR_FG;
-	style.bold = true;
-
-	return style;
-}
+TextStyle::TextStyle() :
+	font(Font::get(UI::g_fh1->fontset().sans(), UI_FONT_SIZE_SMALL)),
+	fg(UI_FONT_CLR_FG),
+	bold(true),
+	italics(false),
+	underline(false)
+{}
 
 } // namespace UI

=== modified file 'src/graphic/text_layout.h'
--- src/graphic/text_layout.h	2016-01-31 12:43:15 +0000
+++ src/graphic/text_layout.h	2016-02-08 20:18:15 +0000
@@ -27,6 +27,7 @@
 #include "graphic/font.h"
 #include "graphic/color.h"
 #include "graphic/text_constants.h"
+#include "graphic/text/font_set.h"
 
 /**
  * This function replaces some HTML entities in strings, e.g. %nbsp;.
@@ -64,13 +65,15 @@
  * of rich text which can be rendered.
  */
 std::string as_uifont
-	(const std::string&, int ptsize = UI_FONT_SIZE_SMALL, const RGBColor& clr = UI_FONT_CLR_FG);
+	(const std::string&, int ptsize = UI_FONT_SIZE_SMALL, const RGBColor& clr = UI_FONT_CLR_FG,
+	 UI::FontSet::Face face = UI::FontSet::Face::kSans);
 
 std::string as_editorfont(const std::string& text, int ptsize = UI_FONT_SIZE_SMALL,
 								  const RGBColor& clr = UI_FONT_CLR_FG);
 
 std::string as_aligned(const std::string & txt, UI::Align align, int ptsize = UI_FONT_SIZE_SMALL,
-							  const RGBColor& clr = UI_FONT_CLR_FG);
+							  const RGBColor& clr = UI_FONT_CLR_FG,
+							  UI::FontSet::Face face = UI::FontSet::Face::kSans);
 
 std::string as_tooltip(const std::string&);
 std::string as_waresinfo(const std::string&);
@@ -85,13 +88,7 @@
  */
 // TODO(GunChleoc): This struct will disappear with the old font handler
 struct TextStyle {
-	TextStyle() :
-		font(nullptr),
-		fg(255, 255, 255),
-		bold(false),
-		italics(false),
-		underline(false)
-	{}
+	TextStyle();
 
 	static TextStyle makebold(Font * font, RGBColor fg) {
 		TextStyle ts;
@@ -101,8 +98,6 @@
 		return ts;
 	}
 
-	static const TextStyle & ui_big();
-	static const TextStyle & ui_small();
 	uint32_t calc_bare_width(const std::string & text) const;
 	uint32_t calc_width_for_wrapping(const UChar& c) const;
 	uint32_t calc_width_for_wrapping(const std::string & text) const;

=== modified file 'src/logic/map_objects/tribes/ship.cc'
--- src/logic/map_objects/tribes/ship.cc	2016-02-08 08:01:21 +0000
+++ src/logic/map_objects/tribes/ship.cc	2016-02-08 20:18:15 +0000
@@ -1000,9 +1000,9 @@
 	if (picture.size() > 3) {
 		rt_description = "<rt image=";
 		rt_description += picture;
-		rt_description += "><p font-size=14 font-face=DejaVuSerif>";
+		rt_description += "><p font-size=14 font-face=serif>";
 	} else
-		rt_description = "<rt><p font-size=14 font-face=DejaVuSerif>";
+		rt_description = "<rt><p font-size=14 font-face=serif>";
 	rt_description += description;
 	rt_description += "</p></rt>";
 

=== modified file 'src/ui_basic/listselect.cc'
--- src/ui_basic/listselect.cc	2016-02-03 18:09:15 +0000
+++ src/ui_basic/listselect.cc	2016-02-08 20:18:15 +0000
@@ -383,11 +383,12 @@
 			1;
 
 		std::string font_face = er.font_face.empty() ? fontname_ : er.font_face;
+		RGBColor color = er.use_clr ? er.clr : UI_FONT_CLR_FG;
 
 		// Horizontal center the string
 		UI::g_fh->draw_text
 			(dst,
-			 TextStyle::makebold(Font::get(font_face, fontsize_), er.use_clr ? er.clr : UI_FONT_CLR_FG),
+			 TextStyle::makebold(Font::get(font_face, fontsize_), color),
 			 Point
 			 	(x,
 			 	 y +

=== modified file 'src/ui_basic/listselect.h'
--- src/ui_basic/listselect.h	2016-02-03 18:09:15 +0000
+++ src/ui_basic/listselect.h	2016-02-08 20:18:15 +0000
@@ -78,8 +78,7 @@
 	void switch_entries(uint32_t, uint32_t);
 
 	void set_entry_color(uint32_t, RGBColor);
-	void set_font(const std::string & fontname, int32_t const fontsize) {
-		fontname_ = fontname;
+	void set_fontsize(int32_t const fontsize) {
 		fontsize_ = fontsize;
 	}
 

=== modified file 'src/ui_basic/multilineeditbox.cc'
--- src/ui_basic/multilineeditbox.cc	2016-02-03 18:09:15 +0000
+++ src/ui_basic/multilineeditbox.cc	2016-02-08 20:18:15 +0000
@@ -104,7 +104,6 @@
 :
 scrollbar(&o, o.get_w() - ms_scrollbar_w, 0, ms_scrollbar_w, o.get_h(), false),
 cursor_pos(0),
-textstyle(UI::TextStyle::ui_small()),
 maxbytes(0xffff),
 ww_valid(false),
 owner(o)
@@ -154,19 +153,6 @@
 }
 
 /**
- * Set the text style.
- */
-void MultilineEditbox::set_textstyle(const UI::TextStyle & ts)
-{
-	if (d_->textstyle == ts)
-		return;
-
-	d_->textstyle = ts;
-	d_->update();
-
-}
-
-/**
  * Set the maximum number of bytes in the scrollbar text.
  *
  * This will shorten the currently stored text when necessary.

=== modified file 'src/ui_basic/multilineeditbox.h'
--- src/ui_basic/multilineeditbox.h	2016-02-03 18:09:15 +0000
+++ src/ui_basic/multilineeditbox.h	2016-02-08 20:18:15 +0000
@@ -44,7 +44,6 @@
 
 	const std::string & get_text() const;
 	void set_text(const std::string &);
-	void set_textstyle(const TextStyle &);
 
 	void set_maximum_bytes(uint32_t n);
 	uint32_t get_maximum_bytes() const;

=== modified file 'src/ui_basic/multilinetextarea.cc'
--- src/ui_basic/multilinetextarea.cc	2016-02-03 18:09:15 +0000
+++ src/ui_basic/multilinetextarea.cc	2016-02-08 20:18:15 +0000
@@ -40,12 +40,12 @@
 	:
 	Panel       (parent, x, y, w, h),
 	text_      (text),
-	style_(UI::TextStyle::ui_small()),
+	color_(UI_FONT_CLR_FG),
 	isrichtext(false),
 	scrollbar_ (this, get_w() - scrollbar_w(), 0, scrollbar_w(), h, false),
 	scrollmode_(scroll_mode)
 {
-	assert(scrollbar_w() <= w);
+	assert(scrollmode_ == MultilineTextarea::ScrollMode::kNoScrolling || scrollbar_w() <= w);
 	set_thinks(false);
 
 	//  do not allow vertical alignment as it does not make sense
@@ -88,7 +88,7 @@
 			isrichtext = false;
 			std::string text_to_render = richtext_escape(text_);
 			boost::replace_all(text_to_render, "\n", "<br>");
-			const Image* text_im = UI::g_fh1->render(as_uifont(text_to_render, style_.font->size(), style_.fg),
+			const Image* text_im = UI::g_fh1->render(as_uifont(text_to_render, UI_FONT_SIZE_SMALL, color_),
 																  get_eff_w() - 2 * RICHTEXT_MARGIN);
 			height = text_im->height();
 		} else {
@@ -148,7 +148,7 @@
 		std::string text_to_render = richtext_escape(text_);
 		boost::replace_all(text_to_render, "\n", "<br>");
 		const Image* text_im =
-				UI::g_fh1->render(as_aligned(text_to_render, align_, style_.font->size(), style_.fg),
+				UI::g_fh1->render(as_aligned(text_to_render, align_, UI_FONT_SIZE_SMALL, color_),
 										get_eff_w() - 2 * RICHTEXT_MARGIN);
 
 		uint32_t blit_width = std::min(text_im->width(), static_cast<int>(get_eff_w()));

=== modified file 'src/ui_basic/multilinetextarea.h'
--- src/ui_basic/multilinetextarea.h	2016-02-03 18:09:15 +0000
+++ src/ui_basic/multilinetextarea.h	2016-02-08 20:18:15 +0000
@@ -59,7 +59,7 @@
 	uint32_t scrollbar_w() const {return 24;}
 	uint32_t get_eff_w() const {return scrollbar_.is_enabled() ? get_w() - scrollbar_w() : get_w();}
 
-	void set_color(RGBColor fg) {style_.fg = fg;}
+	void set_color(RGBColor fg) {color_ = fg;}
 
 	// Drawing and event handlers
 	void draw(RenderTarget&) override;
@@ -75,7 +75,7 @@
 	void scrollpos_changed(int32_t pixels);
 
 	std::string text_;
-	UI::TextStyle style_;
+	RGBColor color_;
 	Align align_;
 
 	bool isrichtext;

=== modified file 'src/ui_basic/panel.cc'
--- src/ui_basic/panel.cc	2016-02-06 09:32:59 +0000
+++ src/ui_basic/panel.cc	2016-02-08 20:18:15 +0000
@@ -1114,18 +1114,4 @@
 	dst.blit(r.origin() + Point(2, 2), rendered_text);
 	return true;
 }
-
-std::string Panel::ui_fn() {
-	std::string style(UI::g_fh1->fontset().serif());
-	if (g_fs->file_exists("i18n/fonts/" + style)) {
-		return style;
-	}
-	log
-		("Could not find font file \"%s\"\n"
-		 "Make sure the path is given relative to Widelands font directory. "
-		 "Widelands will use standard font.\n",
-		 style.c_str());
-	return UI::FontSet::kFallbackFont;
-}
-
 }

=== modified file 'src/ui_basic/panel.h'
--- src/ui_basic/panel.h	2016-02-03 18:09:15 +0000
+++ src/ui_basic/panel.h	2016-02-08 20:18:15 +0000
@@ -241,9 +241,6 @@
 	void set_tooltip(const std::string& text) {_tooltip = text;}
 	const std::string& tooltip() const {return _tooltip;}
 
-	///\return the current set UI font
-	std::string ui_fn();
-
 	virtual void die();
 
 protected:

=== modified file 'src/ui_basic/spinbox.cc'
--- src/ui_basic/spinbox.cc	2016-02-01 17:17:45 +0000
+++ src/ui_basic/spinbox.cc	2016-02-08 20:18:15 +0000
@@ -187,7 +187,7 @@
 		sbi_->text->set_fixed_width(unit_w
 											 - 2 * sbi_->button_ten_plus->get_w()
 											 - 2 * sbi_->button_minus->get_w()
-											 - 4 * padding);
+											 - 2 * padding);
 
 		box_->add(sbi_->button_ten_minus, UI::Align::kTop);
 		box_->add(sbi_->button_minus, UI::Align::kTop);
@@ -195,7 +195,7 @@
 		box_->add(sbi_->button_plus, UI::Align::kTop);
 		box_->add(sbi_->button_ten_plus, UI::Align::kTop);
 	} else {
-		sbi_->text->set_fixed_width(unit_w - 2 * sbi_->button_minus->get_w() - 2 * padding);
+		sbi_->text->set_fixed_width(unit_w - 2 * sbi_->button_minus->get_w());
 
 		box_->add(sbi_->button_minus, UI::Align::kHCenter);
 		box_->add(sbi_->text, UI::Align::kHCenter);

=== modified file 'src/ui_basic/spinbox.h'
--- src/ui_basic/spinbox.h	2016-01-28 05:24:34 +0000
+++ src/ui_basic/spinbox.h	2016-02-08 20:18:15 +0000
@@ -32,7 +32,6 @@
 
 struct SpinBoxImpl;
 struct IntValueTextReplacement;
-struct TextStyle;
 
 /// A spinbox is an UI element for setting the integer value of a variable.
 /// w is the overall width of the SpinBox and must be wide enough to fit 2 labels and the buttons.

=== modified file 'src/ui_basic/tabpanel.cc'
--- src/ui_basic/tabpanel.cc	2016-01-31 21:03:15 +0000
+++ src/ui_basic/tabpanel.cc	2016-02-08 20:18:15 +0000
@@ -243,6 +243,7 @@
 	active_ = idx;
 
 	update_desired_size();
+	sigclicked();
 }
 
 void TabPanel::activate(const std::string & name)

=== modified file 'src/ui_basic/tabpanel.h'
--- src/ui_basic/tabpanel.h	2016-01-28 05:24:34 +0000
+++ src/ui_basic/tabpanel.h	2016-02-08 20:18:15 +0000
@@ -22,6 +22,8 @@
 
 #include <vector>
 
+#include <boost/signals2.hpp>
+
 #include "ui_basic/panel.h"
 
 namespace UI {
@@ -114,6 +116,8 @@
 	void activate(const std::string &);
 	uint32_t active() {return active_;}
 
+	boost::signals2::signal<void ()> sigclicked;
+
 protected:
 	void layout() override;
 	void update_desired_size() override;

=== modified file 'src/ui_basic/textarea.cc'
--- src/ui_basic/textarea.cc	2016-02-03 18:09:15 +0000
+++ src/ui_basic/textarea.cc	2016-02-08 20:18:15 +0000
@@ -83,38 +83,48 @@
 	fixed_width_ = 0;
 	set_handle_mouse(false);
 	set_thinks(false);
-	set_textstyle(UI::TextStyle::ui_small());
-}
-
-/**
- * Set the font of the textarea.
- */
-void Textarea::set_textstyle(const TextStyle & style)
+	color_ = UI_FONT_CLR_FG;
+	fontsize_ = UI_FONT_SIZE_SMALL;
+	fontface_ = UI::FontSet::Face::kSans;
+	update();
+}
+
+void Textarea::set_color(RGBColor color) {
+	if (color_ != color) {
+		color_ = color;
+		update();
+	}
+}
+
+void Textarea::set_fontsize(int fontsize) {
+	if (fontsize_ != fontsize) {
+		fontsize_ = fontsize;
+		update();
+	}
+}
+
+void Textarea::set_fontface(UI::FontSet::Face face) {
+	if (fontface_ != face) {
+		fontface_ = face;
+		update();
+	}
+}
+
+void Textarea::update()
 {
-	if (textstyle_ == style)
-		return;
-
-	if (layoutmode_ == AutoMove)
-		collapse();
-	textstyle_ = style;
-	rendered_text_ = UI::g_fh1->render(
-									as_uifont(text_,
-												 textstyle_.font->size() - UI::g_fh1->fontset().size_offset(),
-												 textstyle_.fg));
-
-	if (layoutmode_ == AutoMove)
+	if (layoutmode_ == AutoMove) {
+		collapse(); // collapse() implicitly updates the size and position
+	}
+
+	fit_text();
+
+	if (layoutmode_ == AutoMove) {
 		expand();
-	else if (layoutmode_ == Layouted)
+	} else if (layoutmode_ == Layouted) {
 		update_desired_size();
+	}
 }
 
-/**
- * @deprecated
- */
-void Textarea::set_font(const std::string & name, int size, RGBColor clr)
-{
-	set_textstyle(TextStyle::makebold(Font::get(name, size), clr));
-}
 
 /**
  * Set the text of the Textarea. Size (or desired size) is automatically
@@ -122,21 +132,10 @@
  */
 void Textarea::set_text(const std::string & text)
 {
-	if (text_ == text)
-		return;
-
-	if (layoutmode_ == AutoMove)
-		collapse(); // collapse() implicitly updates
-
-	text_ = text;
-	rendered_text_ = UI::g_fh1->render(
-									as_uifont(text_,
-												 textstyle_.font->size() - UI::g_fh1->fontset().size_offset(),
-												 textstyle_.fg));
-	if (layoutmode_ == AutoMove)
-		expand();
-	else if (layoutmode_ == Layouted)
-		update_desired_size();
+	if (text_ != text) {
+		text_ = text;
+		update();
+	}
 }
 
 const std::string& Textarea::get_text()
@@ -147,9 +146,13 @@
 
 /**
  * Set the fixed width. The Textarea will still collapse, but then restore this width when expand() is called.
+ * If this is set, text will also autoshrink to fit the width.
  */
-void Textarea::set_fixed_width(uint32_t w) {
-	fixed_width_ = w;
+void Textarea::set_fixed_width(int w) {
+	if (fixed_width_ != w) {
+		fixed_width_ = w;
+		update();
+	}
 }
 
 
@@ -236,11 +239,21 @@
 		if (text_.empty()) {
 			h = UI::g_fh1->render(
 					 as_uifont(".",
-								  textstyle_.font->size() - UI::g_fh1->fontset().size_offset(),
-								  textstyle_.fg))->height();
+								  fontsize_ - UI::g_fh1->fontset().size_offset()))->height();
 		}
 	}
 	set_desired_size(w, h);
 }
 
+
+void Textarea::fit_text() {
+	rendered_text_ = UI::g_fh1->render(as_uifont(text_, fontsize_, color_, fontface_));
+
+	if (fixed_width_ > 0) { // Autofit
+		for (int size = fontsize_; rendered_text_->width() > fixed_width_ && size > kMinimumFontSize; --size) {
+			rendered_text_ = UI::g_fh1->render(as_uifont(text_, size, color_, UI::FontSet::Face::kCondensed));
+		}
+	}
+}
+
 }

=== modified file 'src/ui_basic/textarea.h'
--- src/ui_basic/textarea.h	2016-02-03 18:09:15 +0000
+++ src/ui_basic/textarea.h	2016-02-08 20:18:15 +0000
@@ -73,7 +73,7 @@
 	 * Use this if you need a Textarea that keeps changing its contents, but you don't want the
 	 * surrounding elements to shift, e.g. in a Box.
 	 */
-	void set_fixed_width(uint32_t w);
+	void set_fixed_width(int w);
 
 	void set_text(const std::string &);
 	const std::string& get_text();
@@ -81,10 +81,9 @@
 	// Drawing and event handlers
 	void draw(RenderTarget &) override;
 
-	void set_textstyle(const UI::TextStyle & style);
-	const UI::TextStyle & get_textstyle() const {return textstyle_;}
-
-	void set_font(const std::string & name, int size, RGBColor clr);
+	void set_color(RGBColor color);
+	void set_fontsize(int fontsize);
+	void set_fontface(UI::FontSet::Face face);
 
 protected:
 	void update_desired_size() override;
@@ -99,13 +98,23 @@
 	void init();
 	void collapse();
 	void expand();
+	void update();
+
+	/**
+	 * This rerenders the text. If fixed_width_ is set, it will also use the condensed
+	 * Fontset if needed and then make the text smaller until it fits.
+	 */
+	void fit_text();
 
 	LayoutMode layoutmode_;
 	std::string text_;
 	const Image* rendered_text_;
 	Align align_;
-	UI::TextStyle textstyle_;
-	uint32_t fixed_width_;
+	RGBColor color_;
+	int fontsize_;
+	UI::FontSet::Face fontface_;
+
+	int fixed_width_;
 };
 
 }

=== modified file 'src/ui_fsmenu/base.cc'
--- src/ui_fsmenu/base.cc	2016-01-28 05:24:34 +0000
+++ src/ui_fsmenu/base.cc	2016-02-08 20:18:15 +0000
@@ -23,11 +23,10 @@
 
 #include "base/log.h"
 #include "base/wexception.h"
-#include "graphic/font.h"
 #include "graphic/graphic.h"
+#include "graphic/image.h"
 #include "graphic/rendertarget.h"
 #include "graphic/text_constants.h"
-#include "graphic/text_layout.h"
 #include "io/filesystem/filesystem.h"
 #include "wlapplication.h"
 
@@ -71,11 +70,11 @@
 	                   BlendMode::UseAlpha);
 }
 
-uint32_t FullscreenMenuBase::fs_small() {
+int FullscreenMenuBase::fs_small() {
 	return UI_FONT_SIZE_SMALL * get_h() / 600;
 }
 
-uint32_t FullscreenMenuBase::fs_big() {
+int FullscreenMenuBase::fs_big() {
 	return UI_FONT_SIZE_BIG * get_h() / 600;
 }
 

=== modified file 'src/ui_fsmenu/base.h'
--- src/ui_fsmenu/base.h	2016-02-04 09:10:44 +0000
+++ src/ui_fsmenu/base.h	2016-02-08 20:18:15 +0000
@@ -21,18 +21,9 @@
 #define WL_UI_FSMENU_BASE_H
 
 #include <string>
-#include <memory>
 
-#include "graphic/text_layout.h"
 #include "ui_basic/panel.h"
 
-namespace UI {
-struct Font;
-struct TextStyle;
-}
-
-class Image;
-
 /**
  * This class is the base class for a fullscreen menu.
  * A fullscreen menu is a menu which takes the full screen; it has the size
@@ -85,8 +76,8 @@
 	void draw(RenderTarget &) override;
 
 	///\return the size for texts fitting to current resolution
-	uint32_t fs_small();
-	uint32_t fs_big();
+	int fs_small();
+	int fs_big();
 
 	/// Handle keypresses
 	bool handle_key(bool down, SDL_Keysym code) override;

=== modified file 'src/ui_fsmenu/campaign_select.cc'
--- src/ui_fsmenu/campaign_select.cc	2016-02-04 09:10:44 +0000
+++ src/ui_fsmenu/campaign_select.cc	2016-02-08 20:18:15 +0000
@@ -86,7 +86,7 @@
 		 get_right_column_w(right_column_x_ + indent_),
 		 buty_ - get_y_from_preceding(label_description_) - 4 * padding_)
 {
-	title_.set_textstyle(UI::TextStyle::ui_big());
+	title_.set_fontsize(UI_FONT_SIZE_BIG);
 	back_.set_tooltip(_("Return to the main menu"));
 	ok_.set_tooltip(_("Play this campaign"));
 	ta_campname_.set_tooltip(_("The name of this campaign"));
@@ -325,7 +325,7 @@
 
 	is_tutorial_(is_tutorial)
 {
-	title_.set_textstyle(UI::TextStyle::ui_big());
+	title_.set_fontsize(UI_FONT_SIZE_BIG);
 	back_.set_tooltip(_("Return to the main menu"));
 	if (is_tutorial_) {
 		ok_.set_tooltip(_("Play this tutorial"));

=== modified file 'src/ui_fsmenu/fileview.cc'
--- src/ui_fsmenu/fileview.cc	2016-01-29 08:37:22 +0000
+++ src/ui_fsmenu/fileview.cc	2016-02-08 20:18:15 +0000
@@ -74,7 +74,7 @@
 								boost::ref(*this),
 								FullscreenMenuBase::MenuTarget::kBack));
 
-	title.set_font(ui_fn(), fs_big(), UI_FONT_CLR_FG);
+	title.set_fontsize(fs_big());
 	title.set_pos
 		(Point((get_inner_w() - title.get_w()) / 2, get_h() * 167 / 1000));
 }

=== modified file 'src/ui_fsmenu/internet_lobby.cc'
--- src/ui_fsmenu/internet_lobby.cc	2016-02-04 09:10:44 +0000
+++ src/ui_fsmenu/internet_lobby.cc	2016-02-08 20:18:15 +0000
@@ -46,7 +46,6 @@
 	lisw_ (get_w() * 623 / 1000),
 	fs_   (fs_small()),
 	prev_clientlist_len_(1000),
-	fn_   (ui_fn()),
 
 // Text labels
 	title
@@ -119,10 +118,10 @@
 	// Set the texts and style of UI elements
 	Section & s = g_options.pull_section("global"); //  for playername
 
-	title       .set_font(fn_, fs_big(), UI_FONT_CLR_FG);
-	opengames_ .set_font(fn_, fs_, UI_FONT_CLR_FG);
-	clients_     .set_font(fn_, fs_, UI_FONT_CLR_FG);
-	servername_.set_font(fn_, fs_, UI_FONT_CLR_FG);
+	title       .set_fontsize(fs_big());
+	opengames_ .set_fontsize(fs_);
+	clients_     .set_fontsize(fs_);
+	servername_.set_fontsize(fs_);
 	std::string server = s.get_string("servername", "");
 	servername  .set_text (server);
 	servername  .changed.connect
@@ -149,7 +148,7 @@
 		(0, boost::bind(&FullscreenMenuInternetLobby::compare_clienttype, this, _1, _2));
 	clientsonline .double_clicked.connect
 		(boost::bind(&FullscreenMenuInternetLobby::client_doubleclicked, this, _1));
-	opengames   .set_font(fn_, fs_);
+	opengames   .set_fontsize(fs_);
 	opengames   .selected.connect
 		(boost::bind(&FullscreenMenuInternetLobby::server_selected, this));
 	opengames   .double_clicked.connect

=== modified file 'src/ui_fsmenu/internet_lobby.h'
--- src/ui_fsmenu/internet_lobby.h	2016-01-28 19:58:46 +0000
+++ src/ui_fsmenu/internet_lobby.h	2016-02-08 20:18:15 +0000
@@ -50,7 +50,6 @@
 	uint32_t lisw_;
 	uint32_t fs_;
 	uint32_t prev_clientlist_len_;
-	std::string fn_;
 	UI::Textarea title, clients_, opengames_;
 	UI::Textarea servername_;
 	UI::Button joingame, hostgame, back;

=== modified file 'src/ui_fsmenu/intro.cc'
--- src/ui_fsmenu/intro.cc	2016-02-04 09:10:44 +0000
+++ src/ui_fsmenu/intro.cc	2016-02-08 20:18:15 +0000
@@ -31,7 +31,8 @@
 	 get_w() / 2, get_h() * 19 / 20,
 	 _("Press any key or click to continue ..."), UI::Align::kHCenter)
 {
-	message_.set_font(ui_fn(), fs_small() * 6 / 5, RGBColor(192, 192, 128));
+	message_.set_fontsize(fs_small());
+	message_.set_color(RGBColor(192, 192, 128));
 }
 
 bool FullscreenMenuIntro::handle_mousepress  (uint8_t, int32_t, int32_t)

=== modified file 'src/ui_fsmenu/launch_mpg.cc'
--- src/ui_fsmenu/launch_mpg.cc	2016-02-06 12:49:40 +0000
+++ src/ui_fsmenu/launch_mpg.cc	2016-02-08 20:18:15 +0000
@@ -114,7 +114,6 @@
 	butw_ (get_w() / 4),
 	buth_ (get_h() * 9 / 200),
 	fs_   (fs_small()),
-	fn_   (ui_fn()),
 	// TODO(GunChleoc): We still need to use these consistently. Just getting them in for now
 	// so we can have the SuggestedTeamsBox
 	padding_(4),
@@ -204,11 +203,15 @@
 	lua_ = new LuaInterface();
 	win_condition_clicked();
 
-	title_      .set_font(fn_, fs_big(), UI_FONT_CLR_FG);
-	mapname_    .set_font(fn_, fs_, RGBColor(255, 255, 127));
-	clients_    .set_font(fn_, fs_, RGBColor(0, 255, 0));
-	players_    .set_font(fn_, fs_, RGBColor(0, 255, 0));
-	map_        .set_font(fn_, fs_, RGBColor(0, 255, 0));
+	title_      .set_fontsize(fs_big());
+	mapname_    .set_fontsize(fs_);
+	mapname_    .set_color(RGBColor(255, 255, 127));
+	clients_    .set_fontsize(fs_);
+	clients_    .set_color(RGBColor(0, 255, 0));
+	players_    .set_fontsize(fs_);
+	players_    .set_color(RGBColor(0, 255, 0));
+	map_        .set_fontsize(fs_);
+	map_        .set_color(RGBColor(0, 255, 0));
 
 	mapname_ .set_text(_("(no map)"));
 	map_info_.set_text(_("The host has not yet selected a map or saved game."));
@@ -217,7 +220,7 @@
 		new MultiPlayerSetupGroup
 			(this,
 			 get_w() / 50, get_h() / 8, get_w() * 57 / 80, get_h() / 2,
-			 settings, butw_, buth_, fn_, fs_);
+			 settings, butw_, buth_);
 
 	// If we are the host, open the map or save selection menu at startup
 	if (settings_->settings().usernum == 0 && settings_->settings().mapname.empty()) {

=== modified file 'src/ui_fsmenu/launch_mpg.h'
--- src/ui_fsmenu/launch_mpg.h	2016-01-28 19:58:46 +0000
+++ src/ui_fsmenu/launch_mpg.h	2016-02-08 20:18:15 +0000
@@ -75,7 +75,7 @@
 	uint32_t    butw_;
 	uint32_t    buth_;
 	uint32_t    fs_;
-	std::string fn_;
+
 	// TODO(GunChleoc): We still need to use these consistently. Just getting them in for now
 	// so we can have the SuggestedTeamsBox
 	int32_t const padding_;               // Common padding between panels

=== modified file 'src/ui_fsmenu/launch_spg.cc'
--- src/ui_fsmenu/launch_spg.cc	2016-02-04 09:10:44 +0000
+++ src/ui_fsmenu/launch_spg.cc	2016-02-08 20:18:15 +0000
@@ -144,16 +144,14 @@
 	cur_wincondition_ = -1;
 	win_condition_clicked();
 
-	title_.set_textstyle(UI::TextStyle::ui_big());
+	title_.set_fontsize(UI_FONT_SIZE_BIG);
 
-	UI::TextStyle tsmaller
-		(UI::TextStyle::makebold
-		 (UI::Font::get(ui_fn(), fs_small() * 4 / 5), UI_FONT_CLR_FG));
-	name_.set_textstyle(tsmaller);
-	type_.set_textstyle(tsmaller);
-	team_.set_textstyle(tsmaller);
-	tribe_.set_textstyle(tsmaller);
-	init_.set_textstyle(tsmaller);
+	int smaller_fontsize = fs_small() * 4 / 5;
+	name_.set_fontsize(smaller_fontsize);
+	type_.set_fontsize(smaller_fontsize);
+	team_.set_fontsize(smaller_fontsize);
+	tribe_.set_fontsize(smaller_fontsize);
+	init_.set_fontsize(smaller_fontsize);
 
 	uint32_t y = get_h() * 3 / 10 - buth_;
 	for (uint32_t i = 0; i < MAX_PLAYERS; ++i) {

=== modified file 'src/ui_fsmenu/loadgame.cc'
--- src/ui_fsmenu/loadgame.cc	2016-02-06 12:49:40 +0000
+++ src/ui_fsmenu/loadgame.cc	2016-02-08 20:18:15 +0000
@@ -153,7 +153,7 @@
 	settings_(gsp),
 	ctrl_(gc)
 {
-	title_.set_textstyle(UI::TextStyle::ui_big());
+	title_.set_fontsize(UI_FONT_SIZE_BIG);
 	ta_gametime_.set_tooltip(_("The time that elapsed inside this game"));
 	ta_players_.set_tooltip(_("The number of players"));
 	ta_version_.set_tooltip(_("The version of Widelands that this game was played under"));

=== modified file 'src/ui_fsmenu/mapselect.cc'
--- src/ui_fsmenu/mapselect.cc	2016-02-06 11:11:24 +0000
+++ src/ui_fsmenu/mapselect.cc	2016-02-08 20:18:15 +0000
@@ -60,7 +60,7 @@
 	has_translated_mapname_(false)
 {
 	curdir_ = basedir_,
-	title_.set_textstyle(UI::TextStyle::ui_big());
+	title_.set_fontsize(UI_FONT_SIZE_BIG);
 	if (settings_->settings().multiplayer) {
 		back_.set_tooltip(_("Return to the multiplayer game setup"));
 	} else {

=== modified file 'src/ui_fsmenu/multiplayer.cc'
--- src/ui_fsmenu/multiplayer.cc	2016-02-04 09:10:44 +0000
+++ src/ui_fsmenu/multiplayer.cc	2016-02-08 20:18:15 +0000
@@ -60,7 +60,7 @@
 			 (&FullscreenMenuMultiPlayer::end_modal<FullscreenMenuBase::MenuTarget>, boost::ref(*this),
 			  FullscreenMenuBase::MenuTarget::kBack));
 
-	title.set_font(ui_fn(), fs_big(), UI_FONT_CLR_FG);
+	title.set_fontsize(fs_big());
 
 	vbox.add(&metaserver, UI::Align::kHCenter);
 	vbox.add(&lan, UI::Align::kHCenter);

=== modified file 'src/ui_fsmenu/netsetup_lan.cc'
--- src/ui_fsmenu/netsetup_lan.cc	2016-02-04 09:10:44 +0000
+++ src/ui_fsmenu/netsetup_lan.cc	2016-02-08 20:18:15 +0000
@@ -105,7 +105,7 @@
 
 	Section & s = g_options.pull_section("global"); //  for playername
 
-	title       .set_textstyle(UI::TextStyle::ui_big());
+	title       .set_fontsize(UI_FONT_SIZE_BIG);
 	hostname    .changed.connect
 		(boost::bind(&FullscreenMenuNetSetupLAN::change_hostname, this));
 	playername  .set_text  (s.get_string("nickname", (_("nobody"))));

=== modified file 'src/ui_fsmenu/options.cc'
--- src/ui_fsmenu/options.cc	2016-02-07 09:16:18 +0000
+++ src/ui_fsmenu/options.cc	2016-02-08 20:18:15 +0000
@@ -234,7 +234,7 @@
 	os_(opt)
 {
 	// Set up UI Elements
-	title_           .set_textstyle(UI::TextStyle::ui_big());
+	title_           .set_fontsize(UI_FONT_SIZE_BIG);
 
 	tabs_.add("options_interface", _("Interface"), &box_interface_, "");
 	tabs_.add("options_windows", _("Windows"), &box_windows_, "");

=== modified file 'src/ui_fsmenu/singleplayer.cc'
--- src/ui_fsmenu/singleplayer.cc	2016-02-04 09:10:44 +0000
+++ src/ui_fsmenu/singleplayer.cc	2016-02-08 20:18:15 +0000
@@ -69,7 +69,7 @@
 			 boost::ref(*this),
 			 FullscreenMenuBase::MenuTarget::kBack));
 
-	title.set_font(ui_fn(), fs_big(), UI_FONT_CLR_FG);
+	title.set_fontsize(fs_big());
 
 	vbox.add(&new_game, UI::Align::kHCenter);
 	vbox.add(&campaign, UI::Align::kHCenter);

=== modified file 'src/wui/attack_box.cc'
--- src/wui/attack_box.cc	2016-01-29 08:37:22 +0000
+++ src/wui/attack_box.cc	2016-02-08 20:18:15 +0000
@@ -70,16 +70,10 @@
 }
 
 UI::Textarea& AttackBox::add_text(UI::Box& parent,
-                                  std::string str,
-											 UI::Align alignment,
-                                  const std::string& fontname,
-                                  uint32_t fontsize) {
+											 std::string str,
+											 UI::Align alignment, int fontsize) {
 	UI::Textarea& result = *new UI::Textarea(&parent, str.c_str());
-	UI::TextStyle textstyle;
-	textstyle.font = UI::Font::get(fontname, fontsize);
-	textstyle.bold = true;
-	textstyle.fg = UI_FONT_CLR_FG;
-	result.set_textstyle(textstyle);
+	result.set_fontsize(fontsize);
 	parent.add(&result, alignment);
 	return result;
 }
@@ -149,11 +143,7 @@
 	const std::string attack_string =
 	   (boost::format(_("%1% / %2%")) % (max_attackers > 0 ? 1 : 0) % max_attackers).str();
 
-	soldiers_text_.reset(&add_text(columnbox,
-	                               attack_string,
-	                               UI::Align::kHCenter,
-	                               UI::g_fh1->fontset().serif(),
-	                               UI_FONT_SIZE_ULTRASMALL));
+	soldiers_text_.reset(&add_text(columnbox, attack_string, UI::Align::kHCenter, UI_FONT_SIZE_ULTRASMALL));
 
 	soldiers_slider_ = add_slider(columnbox,
 	                              100,

=== modified file 'src/wui/attack_box.h'
--- src/wui/attack_box.h	2016-01-29 08:37:22 +0000
+++ src/wui/attack_box.h	2016-02-08 20:18:15 +0000
@@ -68,8 +68,7 @@
 	UI::Textarea& add_text(UI::Box& parent,
 								  std::string str,
 								  UI::Align alignment = UI::Align::kTop,
-								  const std::string& fontname = UI::g_fh1->fontset().serif(),
-								  uint32_t fontsize = UI_FONT_SIZE_SMALL);
+								  int fontsize = UI_FONT_SIZE_SMALL);
 	std::unique_ptr<UI::Button> add_button(UI::Box& parent,
 	                                       const std::string& text,
 	                                       void (AttackBox::*fn)(),

=== modified file 'src/wui/building_statistics_menu.cc'
--- src/wui/building_statistics_menu.cc	2016-02-07 11:20:45 +0000
+++ src/wui/building_statistics_menu.cc	2016-02-08 20:18:15 +0000
@@ -49,7 +49,7 @@
 
 namespace {
 void set_label_font(UI::Textarea* label) {
-	label->set_font(UI::g_fh1->fontset().serif(), kLabelFontSize, UI_FONT_CLR_FG);
+	label->set_fontsize(kLabelFontSize);
 }
 }  // namespace
 
@@ -399,10 +399,14 @@
 
 	owned_labels_[id] =
 		new UI::Textarea(button_box, 0, 0, kBuildGridCellWidth, kLabelHeight, UI::Align::kCenter);
+	owned_labels_[id]->set_fontsize(kLabelFontSize);
+	owned_labels_[id]->set_fixed_width(kBuildGridCellWidth);
 	button_box->add(owned_labels_[id], UI::Align::kHCenter);
 
 	productivity_labels_[id] =
 		new UI::Textarea(button_box, 0, 0, kBuildGridCellWidth, kLabelHeight, UI::Align::kCenter);
+	productivity_labels_[id]->set_fontsize(kLabelFontSize);
+	productivity_labels_[id]->set_fixed_width(kBuildGridCellWidth);
 	button_box->add(productivity_labels_[id], UI::Align::kHCenter);
 
 	row.add(button_box, UI::Align::kLeft);
@@ -678,7 +682,7 @@
 				/** TRANSLATORS: Percent in building statistics window, e.g. 85% */
 				/** TRANSLATORS: If you wish to add a space, translate as '%i %%' */
 				const std::string perc_str = (boost::format(_("%i%%")) % percent).str();
-				set_labeltext_autosize(productivity_labels_[id], perc_str, color);
+				set_labeltext(productivity_labels_[id], perc_str, color);
 			}
 			if (has_selection_ && id == current_building_type_) {
 				no_unproductive_label_.set_text(nr_unproductive > 0 ? std::to_string(nr_unproductive) :
@@ -708,7 +712,7 @@
 				}
 				const std::string perc_str = (boost::format(_("%1%/%2%")) % total_stationed_soldiers %
 														total_soldier_capacity).str();
-				set_labeltext_autosize(productivity_labels_[id], perc_str, color);
+				set_labeltext(productivity_labels_[id], perc_str, color);
 			}
 			if (has_selection_ && id == current_building_type_) {
 				no_unproductive_label_.set_text(nr_unproductive > 0 ? std::to_string(nr_unproductive) :
@@ -734,7 +738,7 @@
 		} else {
 			owned_text = (boost::format(_("%1%/%2%")) % nr_owned % "–").str();
 		}
-		set_labeltext_autosize(owned_labels_[id], owned_text, UI_FONT_CLR_FG);
+		set_labeltext(owned_labels_[id], owned_text, UI_FONT_CLR_FG);
 		owned_labels_[id]->set_visible((nr_owned + nr_build) > 0);
 
 		building_buttons_[id]->set_enabled((nr_owned + nr_build) > 0);
@@ -760,33 +764,11 @@
 	}
 }
 
-void BuildingStatisticsMenu::set_labeltext_autosize(UI::Textarea* textarea,
+void BuildingStatisticsMenu::set_labeltext(UI::Textarea* textarea,
 																	 const std::string& text,
 																	 const RGBColor& color) {
-
-	constexpr int kMinFontSize = 6;
-	constexpr int kMaxWidth = kBuildGridCellWidth - 2;
-	constexpr int kMaxHeight = kLabelHeight - 2;
-
-	int font_size = UI_FONT_SIZE_SMALL;
-	std::string fontset = UI::g_fh1->fontset().serif();
-
-	textarea->set_font(fontset, font_size, color);
+	textarea->set_color(color);
 	textarea->set_text(text);
-
-	while (textarea->get_h() > kMaxHeight && font_size > kMinFontSize) {
-		--font_size;
-		textarea->set_font(fontset, font_size, color);
-	}
-
-	if (textarea->get_w() > kMaxWidth) {
-		fontset = UI::g_fh1->fontset().condensed();
-		while (textarea->get_w() > kMaxWidth && font_size > kMinFontSize) {
-			--font_size;
-			textarea->set_font(fontset, font_size, color);
-		}
-	}
-
 	textarea->set_visible(true);
 }
 

=== modified file 'src/wui/building_statistics_menu.h'
--- src/wui/building_statistics_menu.h	2015-12-04 18:27:36 +0000
+++ src/wui/building_statistics_menu.h	2016-02-08 20:18:15 +0000
@@ -75,7 +75,7 @@
 	void jump_building(JumpTarget target, bool reverse);
 
 	/// Sets the label for id type to text in the chosen color with dynamic font size
-	void set_labeltext_autosize(UI::Textarea* textarea,
+	void set_labeltext(UI::Textarea* textarea,
 	                            const std::string& text,
 	                            const RGBColor& color);
 

=== modified file 'src/wui/game_summary.cc'
--- src/wui/game_summary.cc	2016-01-31 21:03:15 +0000
+++ src/wui/game_summary.cc	2016-02-08 20:18:15 +0000
@@ -122,7 +122,7 @@
 	players_table_->add_column(100, _("Time"));
 
 	// Prepare Elements
-	title_area_->set_textstyle(UI::TextStyle::ui_big());
+	title_area_->set_fontsize(UI_FONT_SIZE_BIG);
 
 	// Connections
 	continue_button_->sigclicked.connect

=== modified file 'src/wui/multiplayersetupgroup.cc'
--- src/wui/multiplayersetupgroup.cc	2016-01-29 08:37:22 +0000
+++ src/wui/multiplayersetupgroup.cc	2016-02-08 20:18:15 +0000
@@ -67,8 +67,7 @@
 	MultiPlayerClientGroup
 		(UI::Panel            * const parent, uint8_t id,
 		 int32_t const /* x */, int32_t const /* y */, int32_t const w, int32_t const h,
-		 GameSettingsProvider * const settings,
-		 UI::Font * font)
+		 GameSettingsProvider * const settings)
 		 :
 		 UI::Box(parent, 0, 0, UI::Box::Horizontal, w, h),
 		 type_icon(nullptr),
@@ -80,7 +79,6 @@
 		set_size(w, h);
 		name = new UI::Textarea
 			(this, 0, 0, w - h - UI::Scrollbar::Size * 11 / 5, h);
-		name->set_textstyle(UI::TextStyle::makebold(font, UI_FONT_CLR_FG));
 		add(name, UI::Align::kHCenter);
 		// Either Button if changeable OR text if not
 		if (id == settings->settings().usernum) { // Our Client
@@ -402,19 +400,16 @@
 	(UI::Panel            * const parent,
 	 int32_t const x, int32_t const y, int32_t const w, int32_t const h,
 	 GameSettingsProvider * const settings,
-	 uint32_t /* butw */, uint32_t buth,
-	 const std::string & fname, uint32_t const fsize)
+	 uint32_t /* butw */, uint32_t buth)
 :
 UI::Panel(parent, x, y, w, h),
 s(settings),
 npsb(new NetworkPlayerSettingsBackend(s)),
 clientbox(this, 0, buth, UI::Box::Vertical, w / 3, h - buth),
 playerbox(this, w * 6 / 15, buth, UI::Box::Vertical, w * 9 / 15, h - buth),
-buth_(buth),
-fsize_(fsize),
-fname_(fname)
+buth_(buth)
 {
-	UI::TextStyle tsmaller(UI::TextStyle::makebold(UI::Font::get(fname, fsize * 3 / 4), UI_FONT_CLR_FG));
+	int small_font = UI_FONT_SIZE_SMALL * 3 / 4;
 
 	// Clientbox and labels
 	labels.push_back
@@ -423,7 +418,7 @@
 			 UI::Scrollbar::Size * 6 / 5, buth / 3,
 			 w / 3 - buth - UI::Scrollbar::Size * 2, buth));
 	labels.back()->set_text(_("Client name"));
-	labels.back()->set_textstyle(tsmaller);
+	labels.back()->set_fontsize(small_font);
 
 	labels.push_back
 		(new UI::Textarea
@@ -431,7 +426,7 @@
 			 w / 3 - buth - UI::Scrollbar::Size * 6 / 5, buth / 3,
 			 buth * 2, buth));
 	labels.back()->set_text(_("Role"));
-	labels.back()->set_textstyle(tsmaller);
+	labels.back()->set_fontsize(small_font);
 
 	clientbox.set_size(w / 3, h - buth);
 	clientbox.set_scrolling(true);
@@ -443,7 +438,7 @@
 			 w * 6 / 15, buth / 3,
 			 buth, buth));
 	labels.back()->set_text(_("Start"));
-	labels.back()->set_textstyle(tsmaller);
+	labels.back()->set_fontsize(small_font);
 
 	labels.push_back
 		(new UI::Textarea
@@ -451,7 +446,7 @@
 			 w * 6 / 15 + buth, buth / 3 - 10,
 			 buth, buth));
 	labels.back()->set_text(_("Type"));
-	labels.back()->set_textstyle(tsmaller);
+	labels.back()->set_fontsize(small_font);
 
 	labels.push_back
 		(new UI::Textarea
@@ -459,7 +454,7 @@
 			 w * 6 / 15 + buth * 2, buth / 3,
 			 buth, buth));
 	labels.back()->set_text(_("Tribe"));
-	labels.back()->set_textstyle(tsmaller);
+	labels.back()->set_fontsize(small_font);
 
 	labels.push_back
 		(new UI::Textarea
@@ -467,11 +462,11 @@
 			 w * 6 / 15 + buth * 3, buth / 3,
 			 w * 9 / 15 - 4 * buth, buth, UI::Align::kHCenter));
 	labels.back()->set_text(_("Initialization"));
-	labels.back()->set_textstyle(tsmaller);
+	labels.back()->set_fontsize(small_font);
 
 	labels.push_back(new UI::Textarea(this, w - buth, buth / 3, buth, buth, UI::Align::kRight));
 	labels.back()->set_text(_("Team"));
-	labels.back()->set_textstyle(tsmaller);
+	labels.back()->set_fontsize(small_font);
 
 	playerbox.set_size(w * 9 / 15, h - buth);
 	multi_player_player_groups.resize(MAX_PLAYERS);
@@ -506,7 +501,7 @@
 	for (uint32_t i = 0; i < settings.users.size(); ++i) {
 		if (!multi_player_client_groups.at(i)) {
 			multi_player_client_groups.at(i) = new MultiPlayerClientGroup(
-				&clientbox, i, 0, 0, clientbox.get_w(), buth_, s, UI::Font::get(fname_, fsize_));
+				&clientbox, i, 0, 0, clientbox.get_w(), buth_, s);
 			clientbox.add(&*multi_player_client_groups.at(i), UI::Align::kHCenter);
 		}
 		multi_player_client_groups.at(i)->refresh();

=== modified file 'src/wui/multiplayersetupgroup.h'
--- src/wui/multiplayersetupgroup.h	2016-01-24 20:11:53 +0000
+++ src/wui/multiplayersetupgroup.h	2016-02-08 20:18:15 +0000
@@ -49,9 +49,7 @@
 		(UI::Panel * parent,
 		 int32_t x, int32_t y, int32_t w, int32_t h,
 		 GameSettingsProvider * settings,
-		 uint32_t butw, uint32_t buth,
-		 const std::string & fname = UI::g_fh1->fontset().serif(),
-		 uint32_t fsize = UI_FONT_SIZE_SMALL);
+		 uint32_t butw, uint32_t buth);
 	~MultiPlayerSetupGroup();
 
 	void refresh();
@@ -64,8 +62,7 @@
 	UI::Box                  clientbox, playerbox;
 	std::vector<UI::Textarea *> labels;
 
-	uint32_t    buth_, fsize_;
-	std::string fname_;
+	uint32_t    buth_;
 
 	std::map<std::string, const Image* > tribepics_;
 	std::map<std::string, std::string> tribenames_;

=== modified file 'src/wui/waresdisplay.cc'
--- src/wui/waresdisplay.cc	2016-01-31 21:03:15 +0000
+++ src/wui/waresdisplay.cc	2016-02-08 20:18:15 +0000
@@ -67,13 +67,6 @@
 		selected_.insert(std::make_pair(index, false));
 		hidden_.insert(std::make_pair(index, false));
 		in_selection_.insert(std::make_pair(index, false));
-
-		// Prerender all texts to avoid flickering with mouseover
-		curware_.set_text(index != Widelands::INVALID_INDEX ?
-									 (type_ == Widelands::wwWORKER ?
-										  tribe_.get_worker_descr(index)->descname() :
-										  tribe_.get_ware_descr(index)->descname()) :
-									 "");
 	}
 
 	curware_.set_text(_("Stock"));
@@ -102,11 +95,14 @@
 {
 	const Widelands::DescriptionIndex index = ware_at_point(x, y);
 
+	curware_.set_fixed_width(get_inner_w());
+
 	curware_.set_text(index != Widelands::INVALID_INDEX ?
 	                      (type_ == Widelands::wwWORKER ?
 	                          tribe_.get_worker_descr(index)->descname() :
 	                          tribe_.get_ware_descr(index)->descname()) :
 	                      "");
+
 	if (selection_anchor_ != Widelands::INVALID_INDEX) {
 		// Ensure mouse button is still pressed as some
 		// mouse release events do not reach us


Follow ups