← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/graphic_dependencies into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/graphic_dependencies into lp:widelands.

Commit message:
Split graphics into multiple libraries. This includes some changes to wordwrap (used by the old font renderer and the edit boxes). Shifted some functions from align to text_layout. Moved TextStyle from text_layout to font.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/graphic_dependencies/+merge/318982

Untangling dependencies, the never-ending story...

Codecheck will pick up on missing/superfluous "DEPENDS" entries, but can't double-check "USES_...".
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/graphic_dependencies into lp:widelands.
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt	2016-05-17 15:57:06 +0000
+++ src/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -97,6 +97,7 @@
     wlapplication_messages.h
   USES_SDL2
   USES_SDL2_IMAGE
+  USES_SDL2_TTF
   DEPENDS
     base_exceptions
     base_geometry
@@ -106,8 +107,10 @@
     build_info
     editor
     graphic
+    graphic_fonthandler
+    graphic_fonthandler_legacy
     graphic_text
-    graphic_text_layout
+    graphic_text_constants
     helper
     io_filesystem
     logic

=== modified file 'src/base/CMakeLists.txt'
--- src/base/CMakeLists.txt	2016-10-22 11:22:34 +0000
+++ src/base/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -27,7 +27,6 @@
   SRCS
     i18n.h
     i18n.cc
-    utf8.h
   USES_INTL
   DEPENDS
     base_log
@@ -35,6 +34,11 @@
     third_party_gettext
 )
 
+wl_library(base_utf8
+  SRCS
+    utf8.h
+)
+
 wl_library(base_geometry
   SRCS
     rect.h

=== modified file 'src/base/utf8.h'
--- src/base/utf8.h	2017-01-25 18:55:59 +0000
+++ src/base/utf8.h	2017-03-04 08:03:56 +0000
@@ -33,28 +33,6 @@
 		return (ch & 0xc0) == 0x80;
 	}
 
-	/**
-	 * Convert a unicode character into a multi-byte utf8 string.
-	 */
-	static std::string unicode_to_utf8(uint16_t unicode) {
-		unsigned char buf[4];
-
-		if (unicode < 0x80) {
-			buf[0] = unicode;
-			buf[1] = 0;
-		} else if (unicode < 0x800) {
-			buf[0] = ((unicode & 0x7c0) >> 6) | 0xc0;
-			buf[1] = (unicode & 0x3f) | 0x80;
-			buf[2] = 0;
-		} else {
-			buf[0] = ((unicode & 0xf000) >> 12) | 0xe0;
-			buf[1] = ((unicode & 0xfc0) >> 6) | 0x80;
-			buf[2] = (unicode & 0x3f) | 0x80;
-			buf[3] = 0;
-		}
-
-		return reinterpret_cast<char*>(buf);
-	}
 
 	/**
 	 * Decode the unicode character starting at \p pos and return it. Upon returning,

=== modified file 'src/editor/CMakeLists.txt'
--- src/editor/CMakeLists.txt	2017-02-28 12:59:39 +0000
+++ src/editor/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -93,6 +93,7 @@
     base_macros
     base_scoped_timer
     graphic
+    graphic_fonthandler
     graphic_playercolor
     graphic_surface
     io_filesystem

=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt	2017-02-28 12:59:39 +0000
+++ src/graphic/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -3,16 +3,12 @@
 # TODO(sirver): Separate this directory into a base directory and one
 # that is Widelands aware (can include logic stuff).
 
-wl_library(graphic_build_texture_atlas
+# Align and color
+
+wl_library(graphic_align
   SRCS
-    build_texture_atlas.h
-    build_texture_atlas.cc
-  DEPENDS
-    graphic
-    graphic_image_io
-    graphic_surface
-    graphic_texture_atlas
-    io_filesystem
+    align.h
+    align.cc
 )
 
 wl_library(graphic_color
@@ -31,31 +27,19 @@
     graphic_surface
 )
 
-wl_library(graphic_render_queue
-  SRCS
-    render_queue.cc
-    render_queue.h
-  DEPENDS
-    base_exceptions
-    base_geometry
-    base_macros
-    graphic_color
-    graphic_terrain_programs
-    graphic_draw_programs
-    logic
-)
-
-wl_library(graphic_text_layout
-  SRCS
-    text_layout.cc
-    text_layout.h
-    text_constants.h
-  DEPENDS
-    base_i18n
+
+# Rendering utils
+
+wl_library(graphic_build_texture_atlas
+  SRCS
+    build_texture_atlas.h
+    build_texture_atlas.cc
+  DEPENDS
     graphic
-    graphic_color
+    graphic_image_io
     graphic_surface
-    graphic_text
+    graphic_texture_atlas
+    io_filesystem
 )
 
 wl_library(graphic_image_io
@@ -113,49 +97,6 @@
     io_filesystem
 )
 
-wl_library(graphic_terrain_programs
-  SRCS
-    gl/fields_to_draw.h
-    gl/road_program.cc
-    gl/road_program.h
-    gl/terrain_program.cc
-    gl/terrain_program.h
-    gl/dither_program.cc
-    gl/dither_program.h
-  DEPENDS
-    base_exceptions
-    base_geometry
-    base_log
-    base_macros
-    graphic
-    graphic_gl_utils
-    graphic_image_io
-    graphic_surface
-    io_filesystem
-    logic
-    logic_constants
-    logic_widelands_geometry
-)
-
-wl_library(graphic_draw_programs
-  SRCS
-    blend_mode.h
-    blit_mode.h
-    gl/blit_program.cc
-    gl/blit_program.h
-    gl/draw_line_program.cc
-    gl/draw_line_program.h
-    gl/fill_rect_program.cc
-    gl/fill_rect_program.h
-  DEPENDS
-    base_exceptions
-    base_macros
-    base_geometry
-    graphic_gl_utils
-    base_log
-    graphic_color
-)
-
 wl_library(graphic_surface
   SRCS
     image.h
@@ -167,7 +108,6 @@
     texture.h
     texture_cache.cc
     texture_cache.h
-  USES_OPENGL
   USES_SDL2
   DEPENDS
     base_exceptions
@@ -192,6 +132,42 @@
     graphic_surface
 )
 
+wl_library(graphic_draw_programs
+  SRCS
+    blend_mode.h
+    blit_mode.h
+    gl/blit_program.cc
+    gl/blit_program.h
+    gl/draw_line_program.cc
+    gl/draw_line_program.h
+    gl/fill_rect_program.cc
+    gl/fill_rect_program.h
+  DEPENDS
+    base_exceptions
+    base_macros
+    base_geometry
+    graphic_gl_utils
+    base_log
+    graphic_color
+)
+
+
+# Logic-aware stuff
+
+wl_library(graphic_render_queue
+  SRCS
+    render_queue.cc
+    render_queue.h
+  DEPENDS
+    base_exceptions
+    base_geometry
+    base_macros
+    graphic_color
+    graphic_terrain_programs
+    graphic_draw_programs
+    logic
+)
+
 wl_library(graphic_game_renderer
   SRCS
     game_renderer.cc
@@ -225,33 +201,132 @@
     wui_mapview_pixelfunctions
 )
 
-wl_library(graphic
-  SRCS
-    align.cc
-    align.h
-    animation.cc
-    animation.h
-    default_resolution.h
-    diranimations.h
+wl_library(graphic_terrain_programs
+  SRCS
+    gl/fields_to_draw.h
+    gl/road_program.cc
+    gl/road_program.h
+    gl/terrain_program.cc
+    gl/terrain_program.h
+    gl/dither_program.cc
+    gl/dither_program.h
+  DEPENDS
+    base_exceptions
+    base_geometry
+    base_log
+    base_macros
+    graphic
+    graphic_gl_utils
+    graphic_image_io
+    graphic_surface
+    io_filesystem
+    logic
+    logic_constants
+    logic_widelands_geometry
+)
+
+
+# Font handlers and text
+
+wl_library(graphic_fonthandler_legacy
+  SRCS
     font.cc
     font.h
     font_handler.cc
     font_handler.h
+    richtext.cc
+    richtext.h
+    text_parser.cc
+    text_parser.h
+  USES_ICU
+  USES_SDL2_TTF
+  DEPENDS
+    base_exceptions
+    base_geometry
+    base_i18n
+    base_log
+    base_utf8
+    graphic
+    graphic_align
+    graphic_color
+    graphic_fonthandler
+    graphic_surface
+    graphic_text
+    graphic_text_constants
+    graphic_text_layout
+    graphic_wordwrap
+    helper
+    io_fileread
+    io_filesystem
+)
+
+wl_library(graphic_fonthandler
+  SRCS
     font_handler1.cc
     font_handler1.h
+  DEPENDS
+    base_exceptions
+    base_geometry
+    base_log
+    base_macros
+    graphic
+    graphic_align
+    graphic_image_cache
+    graphic_surface
+    graphic_text
+    io_filesystem
+)
+
+wl_library(graphic_text_constants
+  SRCS
+    text_constants.h
+)
+
+wl_library(graphic_text_layout
+  SRCS
+    text_layout.cc
+    text_layout.h
+  DEPENDS
+    graphic_align
+    graphic_color
+    graphic_surface
+    graphic_text
+    graphic_text_constants
+    graphic_fonthandler
+)
+
+wl_library(graphic_wordwrap
+  SRCS
+    wordwrap.cc
+    wordwrap.h
+  USES_ICU
+  USES_SDL2_TTF
+  DEPENDS
+    base_geometry
+    base_log
+    graphic
+    graphic_align
+    graphic_color
+    graphic_fonthandler
+    graphic_text
+    graphic_text_constants
+    graphic_text_layout
+)
+
+
+# Base library
+
+wl_library(graphic
+  SRCS
+    animation.cc
+    animation.h
+    default_resolution.h
+    diranimations.h
     graphic.cc
     graphic.h
     rendertarget.cc
     rendertarget.h
-    richtext.cc
-    richtext.h
-    text_parser.cc
-    text_parser.h
-    wordwrap.cc
-    wordwrap.h
-  USES_OPENGL
   USES_SDL2
-  USES_SDL2_TTF
   DEPENDS
     base_exceptions
     base_geometry
@@ -259,6 +334,7 @@
     base_log
     base_macros
     build_info
+    graphic_align
     graphic_build_texture_atlas
     graphic_color
     graphic_draw_programs
@@ -268,10 +344,7 @@
     graphic_playercolor
     graphic_render_queue
     graphic_surface
-    graphic_text
     graphic_text_layout
-    helper
-    io_fileread
     io_filesystem
     io_stream
     logic_constants

=== modified file 'src/graphic/align.cc'
--- src/graphic/align.cc	2017-02-24 19:22:36 +0000
+++ src/graphic/align.cc	2017-03-04 08:03:56 +0000
@@ -19,53 +19,4 @@
 
 #include "graphic/align.h"
 
-#include "graphic/font_handler1.h"
-#include "graphic/text/font_set.h"
-
-namespace UI {
-
-/**
- * This mirrors the horizontal alignment for RTL languages.
- *
- * Do not store this value as it is based on the global font setting.
- */
-Align mirror_alignment(Align alignment) {
-	if (UI::g_fh1->fontset()->is_rtl()) {
-		switch (alignment) {
-		case Align::kLeft:
-			alignment = Align::kRight;
-			break;
-		case Align::kRight:
-			alignment = Align::kLeft;
-			break;
-		case Align::kCenter:
-			break;
-		}
-	}
-	return alignment;
-}
-
-/**
- * Align pt horizontally to match align based on width w.
- *
- * When correcting for align, we never move from pixel boundaries to
- * sub-pixels, because this might lead from pixel-perfect rendering to
- * subsampled rendering - this can lead to blurry texts. That is why we
- * never do float divisions in this function.
- */
-void correct_for_align(Align align, uint32_t w, Vector2f* pt) {
-
-	if (align == Align::kCenter)
-		pt->x -= w / 2;
-	else if (align == Align::kRight)
-		pt->x -= w;
-}
-
-/**
- * Adjust the y coordinate in 'point 'pt' to vertically center an element with height 'h'.
- */
-void center_vertically(uint32_t h, Vector2f* pt) {
-	pt->y -= h / 2;
-}
-
-}  // namespace UI
+// Dummy

=== modified file 'src/graphic/align.h'
--- src/graphic/align.h	2017-02-24 19:22:36 +0000
+++ src/graphic/align.h	2017-03-04 08:03:56 +0000
@@ -20,8 +20,6 @@
 #ifndef WL_GRAPHIC_ALIGN_H
 #define WL_GRAPHIC_ALIGN_H
 
-#include "base/vector.h"
-
 namespace UI {
 
 // TODO(GunChleoc): Step 1: Clean up superfluous usages of kLeft/kTop, especially with dalls to
@@ -35,10 +33,5 @@
 	kTop = kLeft,
 	kBottom = kRight,
 };
-
-Align mirror_alignment(Align alignment);
-
-void center_vertically(uint32_t h, Vector2f* pt);
-void correct_for_align(Align, uint32_t w, Vector2f* pt);
 }
 #endif  // end of include guard: WL_GRAPHIC_ALIGN_H

=== modified file 'src/graphic/font.cc'
--- src/graphic/font.cc	2017-01-25 18:55:59 +0000
+++ src/graphic/font.cc	2017-03-04 08:03:56 +0000
@@ -21,8 +21,12 @@
 
 #include <map>
 
+#include <unicode/unistr.h>
+
+#include "base/i18n.h"
 #include "base/utf8.h"
 #include "graphic/font_handler1.h"  // We need the fontset for the size offset
+#include "graphic/text/bidi.h"
 #include "graphic/text/font_set.h"
 #include "graphic/text_constants.h"
 #include "io/filesystem/layered_filesystem.h"
@@ -154,4 +158,97 @@
 	}
 }
 
+
+
+/**
+ * Prepare the TTF style settings for rendering in this style.
+ */
+void TextStyle::setup() const {
+	int32_t font_style = TTF_STYLE_NORMAL;
+	if (bold)
+		font_style |= TTF_STYLE_BOLD;
+	if (italics)
+		font_style |= TTF_STYLE_ITALIC;
+	if (underline)
+		font_style |= TTF_STYLE_UNDERLINE;
+	TTF_SetFontStyle(font->get_ttf_font(), font_style);
+}
+
+/**
+ * Get a width estimate for text wrapping.
+ */
+uint32_t TextStyle::calc_width_for_wrapping(const UChar& c) const {
+	int result = 0;
+	TTF_GlyphMetrics(font->get_ttf_font(), c, nullptr, nullptr, nullptr, nullptr, &result);
+	return result;
+}
+
+/**
+ * Get a width estimate for text wrapping.
+ */
+uint32_t TextStyle::calc_width_for_wrapping(const std::string& text) const {
+	int result = 0;
+	const icu::UnicodeString parseme(text.c_str(), "UTF-8");
+	for (int i = 0; i < parseme.length(); ++i) {
+		UChar c = parseme.charAt(i);
+		if (!i18n::is_diacritic(c)) {
+			result += calc_width_for_wrapping(c);
+		}
+	}
+	return result;
+}
+
+/**
+ * Compute the bare width (without caret padding) of the given string.
+ */
+uint32_t TextStyle::calc_bare_width(const std::string& text) const {
+	int w, h;
+	setup();
+
+	TTF_SizeUTF8(font->get_ttf_font(), text.c_str(), &w, &h);
+	return w;
+}
+
+/**
+ * \note Please only use this function once you understand the definitions
+ * of ascent/descent etc.
+ *
+ * Computes the actual line height we should use for rendering the given text.
+ * This is heuristic, because it pre-initializes the miny and maxy values to
+ * the ones that are typical for Latin scripts, so that lineskips should always
+ * be the same for such scripts.
+ */
+void TextStyle::calc_bare_height_heuristic(const std::string& text,
+														 int32_t& miny,
+														 int32_t& maxy) const {
+	miny = font->computed_typical_miny_;
+	maxy = font->computed_typical_maxy_;
+
+	setup();
+	std::string::size_type pos = 0;
+	while (pos < text.size()) {
+		uint16_t ch = Utf8::utf8_to_unicode(text, pos);
+		int32_t glyphminy, glyphmaxy;
+		TTF_GlyphMetrics(font->get_ttf_font(), ch, nullptr, nullptr, &glyphminy, &glyphmaxy, nullptr);
+		miny = std::min(miny, glyphminy);
+		maxy = std::max(maxy, glyphmaxy);
+	}
+}
+
+/*
+=============================
+
+Default styles
+
+=============================
+*/
+
+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/font.h'
--- src/graphic/font.h	2017-01-25 18:55:59 +0000
+++ src/graphic/font.h	2017-03-04 08:03:56 +0000
@@ -21,12 +21,15 @@
 #define WL_GRAPHIC_FONT_H
 
 #include <SDL_ttf.h>
+#include <unicode/uchar.h>
 
 #include "graphic/color.h"
 #include "io/fileread.h"
 
 namespace UI {
 
+struct TextStyle;
+
 /**
  * Margin around text that is kept to make space for the caret.
  */
@@ -70,6 +73,46 @@
 	int size_;
 };
 
+
+
+/**
+ * Text style combines font with other characteristics like color
+ * and style (italics, bold).
+ */
+// TODO(GunChleoc): This struct will disappear with the old font handler
+struct TextStyle {
+	TextStyle();
+
+	static TextStyle makebold(Font* font, RGBColor fg) {
+		TextStyle ts;
+		ts.font = font;
+		ts.bold = true;
+		ts.fg = fg;
+		return ts;
+	}
+
+	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;
+	void calc_bare_height_heuristic(const std::string& text, int32_t& miny, int32_t& maxy) const;
+	void setup() const;
+
+	Font* font;
+	RGBColor fg;
+	bool bold : 1;
+	bool italics : 1;
+	bool underline : 1;
+
+	bool operator==(const TextStyle& o) const {
+		return font == o.font && fg == o.fg && bold == o.bold && italics == o.italics &&
+				 underline == o.underline;
+	}
+	bool operator!=(const TextStyle& o) const {
+		return !(*this == o);
+	}
+};
+
+
 }  // namespace UI
 
 #endif  // end of include guard: WL_GRAPHIC_FONT_H

=== modified file 'src/graphic/font_handler.cc'
--- src/graphic/font_handler.cc	2017-02-23 19:38:51 +0000
+++ src/graphic/font_handler.cc	2017-03-04 08:03:56 +0000
@@ -30,10 +30,12 @@
 
 #include "base/log.h"
 #include "base/wexception.h"
+#include "graphic/font.h"
 #include "graphic/font_handler1.h"  // We need the fontset for the BiDi algorithm
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "graphic/text/bidi.h"
+#include "graphic/text_layout.h"
 #include "graphic/texture.h"
 #include "graphic/wordwrap.h"
 
@@ -243,7 +245,7 @@
  */
 void FontHandler::get_size(
    const TextStyle& textstyle, const std::string& text, uint32_t& w, uint32_t& h, uint32_t wrap) {
-	WordWrap ww(textstyle, wrap);
+	WordWrap ww(textstyle.font->size(), textstyle.fg, wrap);
 	ww.wrap(text);
 	w = ww.width();
 	h = ww.height();

=== modified file 'src/graphic/font_handler1.cc'
--- src/graphic/font_handler1.cc	2017-01-25 18:55:59 +0000
+++ src/graphic/font_handler1.cc	2017-03-04 08:03:56 +0000
@@ -25,7 +25,6 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/utility.hpp>
 
-#include "base/i18n.h"
 #include "base/log.h"
 #include "base/wexception.h"
 #include "graphic/graphic.h"
@@ -110,10 +109,10 @@
 // be a problem.
 class FontHandler1 : public IFontHandler1 {
 public:
-	FontHandler1(ImageCache* image_cache)
+	FontHandler1(ImageCache* image_cache, const std::string& locale)
 	   : texture_cache_(new TextureCache(RICHTEXT_TEXTURE_CACHE)),
 	     fontsets_(),
-	     fontset_(fontsets_.get_fontset(i18n::get_locale())),
+		  fontset_(fontsets_.get_fontset(locale)),
 	     rt_renderer_(new RT::Renderer(image_cache, texture_cache_.get(), fontsets_)),
 	     image_cache_(image_cache) {
 	}
@@ -137,8 +136,8 @@
 		return fontset_;
 	}
 
-	void reinitialize_fontset() override {
-		fontset_ = fontsets_.get_fontset(i18n::get_locale());
+	void reinitialize_fontset(const std::string& locale) override {
+		fontset_ = fontsets_.get_fontset(locale);
 		texture_cache_.get()->flush();
 		rt_renderer_.reset(new RT::Renderer(image_cache_, texture_cache_.get(), fontsets_));
 	}
@@ -151,8 +150,8 @@
 	ImageCache* const image_cache_;  // not owned
 };
 
-IFontHandler1* create_fonthandler(ImageCache* image_cache) {
-	return new FontHandler1(image_cache);
+IFontHandler1* create_fonthandler(ImageCache* image_cache, const std::string& locale) {
+	return new FontHandler1(image_cache, locale);
 }
 
 IFontHandler1* g_fh1 = nullptr;

=== modified file 'src/graphic/font_handler1.h'
--- src/graphic/font_handler1.h	2017-01-25 18:55:59 +0000
+++ src/graphic/font_handler1.h	2017-03-04 08:03:56 +0000
@@ -56,13 +56,13 @@
 	/// Loads the FontSet for the currently active locale into the
 	/// font handler. This needs to be called after the language of the
 	/// game has changed.
-	virtual void reinitialize_fontset() = 0;
+	virtual void reinitialize_fontset(const std::string& locale) = 0;
 
 	DISALLOW_COPY_AND_ASSIGN(IFontHandler1);
 };
 
 // Create a new FontHandler1.
-IFontHandler1* create_fonthandler(ImageCache* image_cache);
+IFontHandler1* create_fonthandler(ImageCache* image_cache, const std::string& locale);
 
 extern IFontHandler1* g_fh1;
 }

=== modified file 'src/graphic/graphic.cc'
--- src/graphic/graphic.cc	2017-01-25 18:55:59 +0000
+++ src/graphic/graphic.cc	2017-03-04 08:03:56 +0000
@@ -28,9 +28,6 @@
 #include "graphic/align.h"
 #include "graphic/animation.h"
 #include "graphic/build_texture_atlas.h"
-#include "graphic/font.h"
-#include "graphic/font_handler.h"
-#include "graphic/font_handler1.h"
 #include "graphic/gl/initialize.h"
 #include "graphic/gl/system_headers.h"
 #include "graphic/image.h"
@@ -120,10 +117,6 @@
 }
 
 Graphic::~Graphic() {
-	// TODO(unknown): this should really not be needed, but currently is :(
-	if (UI::g_fh)
-		UI::g_fh->flush();
-
 	if (sdl_window_) {
 		SDL_DestroyWindow(sdl_window_);
 		sdl_window_ = nullptr;

=== modified file 'src/graphic/rendertarget.cc'
--- src/graphic/rendertarget.cc	2017-02-28 12:59:39 +0000
+++ src/graphic/rendertarget.cc	2017-03-04 08:03:56 +0000
@@ -23,6 +23,7 @@
 #include "graphic/animation.h"
 #include "graphic/graphic.h"
 #include "graphic/surface.h"
+#include "graphic/text_layout.h"
 
 /**
  * Build a render target for the given surface.

=== modified file 'src/graphic/text/CMakeLists.txt'
--- src/graphic/text/CMakeLists.txt	2016-02-10 16:37:45 +0000
+++ src/graphic/text/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -28,6 +28,7 @@
     base_log
     base_macros
     graphic
+    graphic_align
     graphic_color
     graphic_image_cache
     graphic_image_io

=== modified file 'src/graphic/text/sdl_ttf_font.h'
--- src/graphic/text/sdl_ttf_font.h	2017-01-25 18:55:59 +0000
+++ src/graphic/text/sdl_ttf_font.h	2017-03-04 08:03:56 +0000
@@ -54,6 +54,7 @@
 	virtual const Texture& render(const std::string&, const RGBColor& clr, int, TextureCache*) = 0;
 
 	virtual uint16_t ascent(int) const = 0;
+	virtual TTF_Font* get_ttf_font() const = 0;
 };
 
 // Implementation of a Font object using SDL_ttf.
@@ -65,6 +66,9 @@
 	void dimensions(const std::string&, int, uint16_t* w, uint16_t* h) override;
 	const Texture& render(const std::string&, const RGBColor& clr, int, TextureCache*) override;
 	uint16_t ascent(int) const override;
+	TTF_Font* get_ttf_font() const override {
+		return font_;
+	}
 
 private:
 	void set_style(int);

=== modified file 'src/graphic/text_constants.h'
--- src/graphic/text_constants.h	2017-01-25 18:55:59 +0000
+++ src/graphic/text_constants.h	2017-03-04 08:03:56 +0000
@@ -27,6 +27,7 @@
 #define UI_FONT_SIZE_SMALL 14
 #define UI_FONT_SIZE_ULTRASMALL 10
 constexpr int kMinimumFontSize = 6;
+constexpr int kLineMargin = 1;
 
 /// Font colors
 

=== modified file 'src/graphic/text_layout.cc'
--- src/graphic/text_layout.cc	2017-02-23 17:58:25 +0000
+++ src/graphic/text_layout.cc	2017-03-04 08:03:56 +0000
@@ -25,7 +25,6 @@
 #include <boost/algorithm/string.hpp>
 #include <boost/format.hpp>
 
-#include "base/utf8.h"
 #include "graphic/font_handler1.h"
 #include "graphic/image.h"
 #include "graphic/text/bidi.h"
@@ -159,95 +158,48 @@
 
 namespace UI {
 
-/**
- * Prepare the TTF style settings for rendering in this style.
- */
-void TextStyle::setup() const {
-	int32_t font_style = TTF_STYLE_NORMAL;
-	if (bold)
-		font_style |= TTF_STYLE_BOLD;
-	if (italics)
-		font_style |= TTF_STYLE_ITALIC;
-	if (underline)
-		font_style |= TTF_STYLE_UNDERLINE;
-	TTF_SetFontStyle(font->get_ttf_font(), font_style);
-}
-
-/**
- * Get a width estimate for text wrapping.
- */
-uint32_t TextStyle::calc_width_for_wrapping(const UChar& c) const {
-	int result = 0;
-	TTF_GlyphMetrics(font->get_ttf_font(), c, nullptr, nullptr, nullptr, nullptr, &result);
-	return result;
-}
-
-/**
- * Get a width estimate for text wrapping.
- */
-uint32_t TextStyle::calc_width_for_wrapping(const std::string& text) const {
-	int result = 0;
-	const icu::UnicodeString parseme(text.c_str(), "UTF-8");
-	for (int i = 0; i < parseme.length(); ++i) {
-		UChar c = parseme.charAt(i);
-		if (!i18n::is_diacritic(c)) {
-			result += calc_width_for_wrapping(c);
+
+/**
+ * This mirrors the horizontal alignment for RTL languages.
+ *
+ * Do not store this value as it is based on the global font setting.
+ */
+Align mirror_alignment(Align alignment) {
+	if (UI::g_fh1->fontset()->is_rtl()) {
+		switch (alignment) {
+		case Align::kLeft:
+			alignment = Align::kRight;
+			break;
+		case Align::kRight:
+			alignment = Align::kLeft;
+			break;
+		case Align::kCenter:
+			break;
 		}
 	}
-	return result;
-}
-
-/**
- * Compute the bare width (without caret padding) of the given string.
- */
-uint32_t TextStyle::calc_bare_width(const std::string& text) const {
-	int w, h;
-	setup();
-
-	TTF_SizeUTF8(font->get_ttf_font(), text.c_str(), &w, &h);
-	return w;
-}
-
-/**
- * \note Please only use this function once you understand the definitions
- * of ascent/descent etc.
+	return alignment;
+}
+
+/**
+ * Align pt horizontally to match align based on width w.
  *
- * Computes the actual line height we should use for rendering the given text.
- * This is heuristic, because it pre-initializes the miny and maxy values to
- * the ones that are typical for Latin scripts, so that lineskips should always
- * be the same for such scripts.
- */
-void TextStyle::calc_bare_height_heuristic(const std::string& text,
-                                           int32_t& miny,
-                                           int32_t& maxy) const {
-	miny = font->computed_typical_miny_;
-	maxy = font->computed_typical_maxy_;
-
-	setup();
-	std::string::size_type pos = 0;
-	while (pos < text.size()) {
-		uint16_t ch = Utf8::utf8_to_unicode(text, pos);
-		int32_t glyphminy, glyphmaxy;
-		TTF_GlyphMetrics(font->get_ttf_font(), ch, nullptr, nullptr, &glyphminy, &glyphmaxy, nullptr);
-		miny = std::min(miny, glyphminy);
-		maxy = std::max(maxy, glyphmaxy);
-	}
-}
-
-/*
-=============================
-
-Default styles
-
-=============================
-*/
-
-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) {
-}
-
+ * When correcting for align, we never move from pixel boundaries to
+ * sub-pixels, because this might lead from pixel-perfect rendering to
+ * subsampled rendering - this can lead to blurry texts. That is why we
+ * never do float divisions in this function.
+ */
+void correct_for_align(Align align, uint32_t w, Vector2f* pt) {
+
+	if (align == Align::kCenter)
+		pt->x -= w / 2;
+	else if (align == Align::kRight)
+		pt->x -= w;
+}
+
+/**
+ * Adjust the y coordinate in 'point 'pt' to vertically center an element with height 'h'.
+ */
+void center_vertically(uint32_t h, Vector2f* pt) {
+	pt->y -= h / 2;
+}
 }  // namespace UI

=== modified file 'src/graphic/text_layout.h'
--- src/graphic/text_layout.h	2017-02-23 17:58:25 +0000
+++ src/graphic/text_layout.h	2017-03-04 08:03:56 +0000
@@ -21,12 +21,9 @@
 #define WL_GRAPHIC_TEXT_LAYOUT_H
 
 #include <string>
-#include <unicode/uchar.h>
 
 #include "graphic/align.h"
 #include "graphic/color.h"
-#include "graphic/font.h"
-#include "graphic/font_handler1.h"
 #include "graphic/image.h"
 #include "graphic/text/font_set.h"
 #include "graphic/text_constants.h"
@@ -104,42 +101,10 @@
 
 namespace UI {
 
-/**
- * Text style combines font with other characteristics like color
- * and style (italics, bold).
- */
-// TODO(GunChleoc): This struct will disappear with the old font handler
-struct TextStyle {
-	TextStyle();
-
-	static TextStyle makebold(Font* font, RGBColor fg) {
-		TextStyle ts;
-		ts.font = font;
-		ts.bold = true;
-		ts.fg = fg;
-		return ts;
-	}
-
-	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;
-	void calc_bare_height_heuristic(const std::string& text, int32_t& miny, int32_t& maxy) const;
-	void setup() const;
-
-	Font* font;
-	RGBColor fg;
-	bool bold : 1;
-	bool italics : 1;
-	bool underline : 1;
-
-	bool operator==(const TextStyle& o) const {
-		return font == o.font && fg == o.fg && bold == o.bold && italics == o.italics &&
-		       underline == o.underline;
-	}
-	bool operator!=(const TextStyle& o) const {
-		return !(*this == o);
-	}
-};
+Align mirror_alignment(Align alignment);
+
+void center_vertically(uint32_t h, Vector2f* pt);
+void correct_for_align(Align, uint32_t w, Vector2f* pt);
 
 }  // namespace UI
 

=== modified file 'src/graphic/wordwrap.cc'
--- src/graphic/wordwrap.cc	2017-02-23 17:58:25 +0000
+++ src/graphic/wordwrap.cc	2017-03-04 08:03:56 +0000
@@ -23,45 +23,62 @@
 
 #include "graphic/wordwrap.h"
 
+#include <SDL_ttf.h>
 #include <boost/format.hpp>
 #include <unicode/uchar.h>
 #include <unicode/unistr.h>
 
 #include "base/log.h"
+#include "graphic/color.h"
 #include "graphic/font_handler1.h"
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "graphic/text/bidi.h"
+#include "graphic/text/font_io.h"
+#include "graphic/text/sdl_ttf_font.h"
+#include "graphic/text_layout.h"
+
+namespace {
+
+/**
+ * Get a width estimate for text wrapping.
+ */
+uint32_t quick_width(const UChar& c, int ptsize) {
+	// Editor font is sans bold.
+	RT::IFont* font = RT::load_font(UI::g_fh1->fontset()->sans_bold(), ptsize);
+	int result = 0;
+	TTF_GlyphMetrics(font->get_ttf_font(), c, nullptr, nullptr, nullptr, nullptr, &result);
+	return result;
+}
+
+uint32_t quick_width(const std::string& text, int ptsize) {
+	int result = 0;
+	const icu::UnicodeString parseme(text.c_str(), "UTF-8");
+	for (int i = 0; i < parseme.length(); ++i) {
+		UChar c = parseme.charAt(i);
+		if (!i18n::is_diacritic(c)) {
+			result += quick_width(c, ptsize);
+		}
+	}
+	return result;
+}
+}
 
 namespace UI {
 
-/**
- * Initialize the wordwrap object with an unlimited line length
- * and a default-constructed text style.
- */
-WordWrap::WordWrap() : wrapwidth_(std::numeric_limits<uint32_t>::max()), draw_caret_(false) {
-}
-
-WordWrap::WordWrap(const TextStyle& style, uint32_t gwrapwidth)
-   : style_(style), draw_caret_(false) {
+WordWrap::WordWrap(int fontsize, const RGBColor& color, uint32_t gwrapwidth)
+	: draw_caret_(false), fontsize_(fontsize), color_(color) {
 	wrapwidth_ = gwrapwidth;
 
 	if (wrapwidth_ < std::numeric_limits<uint32_t>::max()) {
-		if (wrapwidth_ < 2 * LINE_MARGIN)
+		if (wrapwidth_ < 2 * kLineMargin)
 			wrapwidth_ = 0;
 		else
-			wrapwidth_ -= 2 * LINE_MARGIN;
+			wrapwidth_ -= 2 * kLineMargin;
 	}
 }
 
 /**
- * Set the text style for future wrapping operations.
- */
-void WordWrap::set_style(const TextStyle& style) {
-	style_ = style;
-}
-
-/**
  * Set the wrap width (i.e. line width limit in pixels) for future wrapping operations.
  */
 void WordWrap::set_wrapwidth(uint32_t gwrapwidth) {
@@ -84,7 +101,7 @@
 	lines_.clear();
 
 	std::string::size_type line_start = 0;
-	uint32_t margin = style_.calc_width_for_wrapping(0x2003);  // Em space
+	uint32_t margin = quick_width(0x2003, fontsize_);  // Em space
 
 	while (line_start <= text.size()) {
 		std::string::size_type next_line_start;
@@ -127,7 +144,7 @@
 	}
 
 	// Optimism: perhaps the entire line fits?
-	if (text_width(text.substr(line_start, orig_end - line_start), style_.font->size()) <=
+	if (text_width(text.substr(line_start, orig_end - line_start), fontsize_) <=
 	    wrapwidth_ - safety_margin) {
 		line_end = orig_end;
 		next_line_start = orig_end + 1;
@@ -192,7 +209,7 @@
 		// Diacritics do not add to the line width
 		if (!i18n::is_diacritic(c)) {
 			// This only estimates the width
-			line_width += style_.calc_width_for_wrapping(c);
+			line_width += quick_width(c, fontsize_);
 		}
 		unicode_line += c;
 	}
@@ -200,7 +217,7 @@
 	// Now make sure that it really fits.
 	std::string::size_type test_cutoff = line_start + end * 2 / 3;
 	while ((end > 0) && (static_cast<uint32_t>(line_start + end) > test_cutoff)) {
-		if (text_width(text.substr(line_start, end), style_.font->size()) >
+		if (text_width(text.substr(line_start, end), fontsize_) >
 		    wrapwidth_ - safety_margin) {
 			--end;
 		} else {
@@ -231,9 +248,9 @@
 bool WordWrap::line_fits(const std::string& text, uint32_t safety_margin) const {
 	// calc_width_for_wrapping is fast, but it will underestimate the width.
 	// So, we test again with text_width to make sure that the line really fits.
-	return style_.calc_width_for_wrapping(i18n::make_ligatures(text.c_str())) <=
+	return quick_width(i18n::make_ligatures(text.c_str()), fontsize_) <=
 	          wrapwidth_ - safety_margin &&
-	       text_width(text, style_.font->size()) <= wrapwidth_ - safety_margin;
+			 text_width(text, fontsize_) <= wrapwidth_ - safety_margin;
 }
 
 /**
@@ -245,12 +262,12 @@
 	uint32_t calculated_width = 0;
 
 	for (uint32_t line = 0; line < lines_.size(); ++line) {
-		uint32_t linewidth = text_width(lines_[line].text, style_.font->size());
+		uint32_t linewidth = text_width(lines_[line].text, fontsize_);
 		if (linewidth > calculated_width)
 			calculated_width = linewidth;
 	}
 
-	return calculated_width + 2 * LINE_MARGIN;
+	return calculated_width + 2 * kLineMargin;
 }
 
 /**
@@ -259,10 +276,10 @@
 uint32_t WordWrap::height() const {
 	uint16_t fontheight = 0;
 	if (!lines_.empty()) {
-		fontheight = text_height(lines_[0].text, style_.font->size());
+		fontheight = text_height(lines_[0].text, fontsize_);
 	}
 
-	return fontheight * (lines_.size()) + 2 * LINE_MARGIN;
+	return fontheight * (lines_.size()) + 2 * kLineMargin;
 }
 
 /**
@@ -315,7 +332,7 @@
 
 	Align alignment = mirror_alignment(align);
 
-	uint16_t fontheight = text_height(lines_[0].text, style_.font->size());
+	uint16_t fontheight = text_height(lines_[0].text, fontsize_);
 	for (uint32_t line = 0; line < lines_.size(); ++line, where.y += fontheight) {
 		if (where.y >= dst.height() || int32_t(where.y + fontheight) <= 0)
 			continue;
@@ -323,22 +340,22 @@
 		Vector2f point(where.x, where.y);
 
 		if (alignment == UI::Align::kRight) {
-			point.x += wrapwidth_ - LINE_MARGIN;
+			point.x += wrapwidth_ - kLineMargin;
 		}
 
 		const Image* entry_text_im = UI::g_fh1->render(as_editorfont(
-		   lines_[line].text, style_.font->size() - UI::g_fh1->fontset()->size_offset(), style_.fg));
+			lines_[line].text, fontsize_ - UI::g_fh1->fontset()->size_offset(), color_));
 		UI::correct_for_align(alignment, entry_text_im->width(), &point);
 		dst.blit(point, entry_text_im);
 
 		if (draw_caret_ && line == caretline) {
 			std::string line_to_caret = lines_[line].text.substr(0, caretpos);
 			// TODO(GunChleoc): Arabic: Fix cursor position for BIDI text.
-			int caret_x = text_width(line_to_caret, style_.font->size());
+			int caret_x = text_width(line_to_caret, fontsize_);
 
 			const Image* caret_image = g_gr->images().get("images/ui_basic/caret.png");
 			Vector2f caretpt;
-			caretpt.x = point.x + caret_x - caret_image->width() + LINE_MARGIN;
+			caretpt.x = point.x + caret_x - caret_image->width() + kLineMargin;
 			caretpt.y = point.y + (fontheight - caret_image->height()) / 2.f;
 			dst.blit(caretpt, caret_image);
 		}

=== modified file 'src/graphic/wordwrap.h'
--- src/graphic/wordwrap.h	2017-02-23 19:38:51 +0000
+++ src/graphic/wordwrap.h	2017-03-04 08:03:56 +0000
@@ -20,10 +20,12 @@
 #define WL_GRAPHIC_WORDWRAP_H
 
 #include <string>
+#include <vector>
 
 #include "base/vector.h"
 #include "graphic/align.h"
-#include "graphic/text_layout.h"
+#include "graphic/color.h"
+#include "graphic/text_constants.h"
 
 class RenderTarget;
 
@@ -33,10 +35,8 @@
  * Helper struct that provides word wrapping and related functionality.
  */
 struct WordWrap {
-	WordWrap();
-	WordWrap(const TextStyle& style, uint32_t wrapwidth = std::numeric_limits<uint32_t>::max());
+	WordWrap(int fontsize = UI_FONT_SIZE_SMALL, const RGBColor& color = UI_FONT_CLR_FG, uint32_t wrapwidth = std::numeric_limits<uint32_t>::max());
 
-	void set_style(const TextStyle& style);
 	void set_wrapwidth(uint32_t wrapwidth);
 
 	uint32_t wrapwidth() const;
@@ -77,10 +77,13 @@
 
 	bool line_fits(const std::string& text, uint32_t safety_margin) const;
 
-	TextStyle style_;
 	uint32_t wrapwidth_;
 	bool draw_caret_;
 
+	// TODO(GunChleoc): We can tie these to constexpr once the old font renderer is gone.
+	int fontsize_;
+	RGBColor color_;
+
 	std::vector<LineData> lines_;
 };
 

=== modified file 'src/logic/CMakeLists.txt'
--- src/logic/CMakeLists.txt	2017-02-28 12:59:39 +0000
+++ src/logic/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -229,9 +229,11 @@
     game_io
     graphic
     graphic_color
+    graphic_fonthandler
     graphic_image_io
     graphic_playercolor
     graphic_surface
+    graphic_text_constants
     graphic_text_layout
     helper
     io_fileread

=== modified file 'src/ui_basic/CMakeLists.txt'
--- src/ui_basic/CMakeLists.txt	2016-11-01 06:19:50 +0000
+++ src/ui_basic/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -59,11 +59,17 @@
     base_i18n
     base_log
     base_macros
+    base_utf8
     graphic
+    graphic_align
     graphic_color
+    graphic_fonthandler
+    graphic_fonthandler_legacy
     graphic_surface
     graphic_text
+    graphic_text_constants
     graphic_text_layout
+    graphic_wordwrap
     io_filesystem
     notifications
     profile

=== modified file 'src/ui_basic/button.h'
--- src/ui_basic/button.h	2017-01-25 18:55:59 +0000
+++ src/ui_basic/button.h	2017-03-04 08:03:56 +0000
@@ -30,8 +30,6 @@
 
 namespace UI {
 
-struct Font;
-
 /// This is simply a button. Override void clicked() to react to the click.
 /// This is all that is needed in most cases, but if there is a need to give a
 /// callback function to the button, there are some templates for that below.

=== modified file 'src/ui_basic/editbox.cc'
--- src/ui_basic/editbox.cc	2017-02-24 10:21:37 +0000
+++ src/ui_basic/editbox.cc	2017-03-04 08:03:56 +0000
@@ -31,6 +31,7 @@
 #include "graphic/text/font_set.h"
 #include "graphic/text/rt_errors.h"
 #include "graphic/text_constants.h"
+#include "graphic/text_layout.h"
 #include "ui_basic/mouse_constants.h"
 
 // TODO(GunChleoc): Arabic: Fix positioning for Arabic
@@ -428,7 +429,7 @@
 
 		const Image* caret_image = g_gr->images().get("images/ui_basic/caret.png");
 		Vector2f caretpt;
-		caretpt.x = point.x + m_->scrolloffset + caret_x - caret_image->width() + LINE_MARGIN;
+		caretpt.x = point.x + m_->scrolloffset + caret_x - caret_image->width() + kLineMargin;
 		caretpt.y = point.y + (fontheight - caret_image->height()) / 2.f;
 		dst.blit(caretpt, caret_image);
 	}

=== modified file 'src/ui_basic/multilineeditbox.cc'
--- src/ui_basic/multilineeditbox.cc	2017-02-23 17:58:25 +0000
+++ src/ui_basic/multilineeditbox.cc	2017-03-04 08:03:56 +0000
@@ -22,6 +22,7 @@
 #include <boost/bind.hpp>
 
 #include "base/utf8.h"
+#include "graphic/font_handler1.h"
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "graphic/text_layout.h"
@@ -47,8 +48,7 @@
 	/// text.size() inidicates that the cursor is after the last character.
 	uint32_t cursor_pos;
 
-	/// Font and style
-	UI::TextStyle textstyle;
+	int lineheight;
 
 	/// Maximum length of the text string, in bytes
 	uint32_t maxbytes;
@@ -91,6 +91,7 @@
                                    const Image* button_background)
    : Panel(parent, x, y, w, h), d_(new Data(*this, button_background)) {
 	d_->background = background;
+	d_->lineheight = text_height(g_fh1->fontset()->representative_character(), UI_FONT_SIZE_SMALL);
 	set_handle_mouse(true);
 	set_can_focus(true);
 	set_thinks(false);
@@ -107,8 +108,8 @@
      owner(o) {
 	scrollbar.moved.connect(boost::bind(&MultilineEditbox::scrollpos_changed, &o, _1));
 
-	scrollbar.set_pagesize(owner.get_h() - 2 * textstyle.font->height());
-	scrollbar.set_singlestepsize(textstyle.font->height());
+	scrollbar.set_pagesize(owner.get_h() - 2 * lineheight);
+	scrollbar.set_singlestepsize(lineheight);
 }
 
 /**
@@ -491,9 +492,7 @@
 	uint32_t cursorline, cursorpos;
 	ww.calc_wrapped_pos(cursor_pos, cursorline, cursorpos);
 
-	int32_t lineheight = textstyle.font->height();
-	int32_t lineskip = textstyle.font->lineskip();
-	int32_t top = cursorline * lineskip;
+	int32_t top = cursorline * lineheight;
 
 	if (top < int32_t(scrollbar.get_scrollpos())) {
 		scrollbar.set_scrollpos(top - lineheight);
@@ -517,7 +516,6 @@
 	if (ww_valid)
 		return;
 
-	ww.set_style(textstyle);
 	ww.set_wrapwidth(owner.get_w() - Scrollbar::kSize);
 
 	ww.wrap(text);

=== modified file 'src/ui_basic/multilineeditbox.h'
--- src/ui_basic/multilineeditbox.h	2017-01-25 18:55:59 +0000
+++ src/ui_basic/multilineeditbox.h	2017-03-04 08:03:56 +0000
@@ -29,8 +29,6 @@
 
 namespace UI {
 
-struct TextStyle;
-
 /**
  * A panel that allows entering multi-line string, i.e. like a hybrid between
  * @ref Editbox and @ref MultilineTextarea

=== modified file 'src/ui_basic/multilinetextarea.cc'
--- src/ui_basic/multilinetextarea.cc	2017-02-23 19:38:51 +0000
+++ src/ui_basic/multilinetextarea.cc	2017-03-04 08:03:56 +0000
@@ -26,6 +26,7 @@
 #include "graphic/rendertarget.h"
 #include "graphic/text/font_set.h"
 #include "graphic/text_constants.h"
+#include "graphic/text_layout.h"
 
 namespace UI {
 

=== modified file 'src/ui_basic/table.cc'
--- src/ui_basic/table.cc	2017-02-26 11:57:15 +0000
+++ src/ui_basic/table.cc	2017-03-04 08:03:56 +0000
@@ -21,7 +21,6 @@
 
 #include <boost/bind.hpp>
 
-#include "graphic/font.h"
 #include "graphic/font_handler1.h"
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"

=== modified file 'src/ui_fsmenu/CMakeLists.txt'
--- src/ui_fsmenu/CMakeLists.txt	2016-10-20 19:29:28 +0000
+++ src/ui_fsmenu/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -43,11 +43,12 @@
     build_info
     game_io
     graphic
+    graphic_fonthandler
     graphic_image_io
     graphic_playercolor
     graphic_surface
     graphic_text
-    graphic_text_layout
+    graphic_text_constants
     helper
     io_filesystem
     logic

=== modified file 'src/ui_fsmenu/mapselect.cc'
--- src/ui_fsmenu/mapselect.cc	2017-02-26 11:57:15 +0000
+++ src/ui_fsmenu/mapselect.cc	2017-03-04 08:03:56 +0000
@@ -26,6 +26,7 @@
 #include "base/i18n.h"
 #include "base/log.h"
 #include "base/wexception.h"
+#include "graphic/font_handler1.h"
 #include "graphic/graphic.h"
 #include "io/filesystem/layered_filesystem.h"
 #include "logic/game_controller.h"

=== modified file 'src/ui_fsmenu/options.cc'
--- src/ui_fsmenu/options.cc	2017-02-23 19:38:51 +0000
+++ src/ui_fsmenu/options.cc	2017-03-04 08:03:56 +0000
@@ -631,7 +631,7 @@
 
 	WLApplication::get()->set_input_grab(opt.inputgrab);
 	i18n::set_locale(opt.language);
-	UI::g_fh1->reinitialize_fontset();
+	UI::g_fh1->reinitialize_fontset(i18n::get_locale());
 	g_sound_handler.set_disable_music(!opt.music);
 	g_sound_handler.set_disable_fx(!opt.fx);
 }

=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc	2017-02-26 11:57:15 +0000
+++ src/wlapplication.cc	2017-03-04 08:03:56 +0000
@@ -33,6 +33,7 @@
 #include <string>
 
 #include <SDL_image.h>
+#include <SDL_ttf.h>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/format.hpp>
 #include <boost/regex.hpp>
@@ -337,7 +338,7 @@
 		throw wexception("True Type library did not initialize: %s\n", TTF_GetError());
 
 	UI::g_fh1 = UI::create_fonthandler(
-	   &g_gr->images());  // This will create the fontset, so loading it first.
+		&g_gr->images(), i18n::get_locale());  // This will create the fontset, so loading it first.
 	UI::g_fh = new UI::FontHandler();
 
 	g_gr->initialize(
@@ -798,6 +799,10 @@
 }
 
 void WLApplication::shutdown_hardware() {
+	if (UI::g_fh) {
+		// TODO(unknown): this should really not be needed, but currently is :(
+		UI::g_fh->flush();
+	}
 	delete g_gr;
 	g_gr = nullptr;
 

=== modified file 'src/wui/CMakeLists.txt'
--- src/wui/CMakeLists.txt	2017-03-02 12:21:57 +0000
+++ src/wui/CMakeLists.txt	2017-03-04 08:03:56 +0000
@@ -15,6 +15,7 @@
     chat
     graphic
     graphic_color
+    graphic_fonthandler
     graphic_text
     graphic_text_layout
     logic
@@ -85,8 +86,9 @@
     base_i18n
     base_log
     graphic
+    graphic_fonthandler
     graphic_playercolor
-    graphic_text_layout
+    graphic_text_constants
     io_filesystem
     logic
     logic_game_controller
@@ -131,6 +133,7 @@
     base_exceptions
     base_i18n
     graphic
+    graphic_fonthandler
     graphic_text_layout
     logic
     ui_basic
@@ -244,11 +247,14 @@
     economy
     game_io
     graphic
+    graphic_align
     graphic_color
+    graphic_fonthandler
     graphic_minimap_renderer
     graphic_playercolor
     graphic_surface
     graphic_text
+    graphic_text_constants
     graphic_text_layout
     io_fileread
     io_filesystem

=== modified file 'src/wui/playerdescrgroup.h'
--- src/wui/playerdescrgroup.h	2017-01-25 18:55:59 +0000
+++ src/wui/playerdescrgroup.h	2017-03-04 08:03:56 +0000
@@ -25,10 +25,6 @@
 
 #include "ui_basic/panel.h"
 
-namespace UI {
-struct Font;
-}
-
 struct GameSettingsProvider;
 struct PlayerDescriptionGroupImpl;
 


Follow ups