← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~sirver/widelands/autocache into lp:widelands

 

SirVer has proposed merging lp:~sirver/widelands/autocache into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~sirver/widelands/autocache/+merge/147559

So, this is my stab at a Surface and ImageCache. It turned out to be quite a lot of work, but now I am quite satisfied. 
I realize it is a lot to look over, but maybe someone finds the time to skim this quickly and give me some feedback.

A summary of the changes:
- Added a volatile SurfaceCache that is limited by the total size of images in it. All surfaces cached in it can disappear at any point in time.
- IPicture (now called Image) is a proxy for a surface now. There are various implementations that do something (like loading images from disk, calculating grayscale image), cache them in the SurfaceCache and return them. As many parts of Widelands expect IPictures to life forever and/or do not take ownership of them, I introduced the image cache which just keeps all (well, most) images ever created around.
- Moved all of Animation Code to use IPictures only. This means that we now calculate animation frames on a when-needed basis and we drop them again when no longer needed.
- Kicked non-alpha channel surfaces. The were only used in SDL rendering and there we do not really care that much about the memory. Most surfaces were with alpha channel anyways and this got rid of some special casing.
- Refactored big chunks of graphic.cc, it now contains significantly less code and responsibilities. This also got rid of IGraphic interface.
-- 
https://code.launchpad.net/~sirver/widelands/autocache/+merge/147559
Your team Widelands Developers is requested to review the proposed merge of lp:~sirver/widelands/autocache into lp:widelands.
=== modified file 'cmake/codecheck/CodeCheck.py'
--- cmake/codecheck/CodeCheck.py	2012-06-08 22:22:39 +0000
+++ cmake/codecheck/CodeCheck.py	2013-02-10 14:53:26 +0000
@@ -23,15 +23,15 @@
     but preserve new lines so that line-numbering is not affected.
     """
     new_lines = "".join(input_lines)
-        
+
     def fixup(match):
         "Remove everything except newlines"
         orig_string = match.string[match.start():match.end()]
         return "\n" * orig_string.count("\n")
-        
+
     # Strip multi-line c-style comments
     new_lines = re.sub(r"/\*.*?\*/", fixup, new_lines, flags=re.DOTALL | re.M)
-    
+
     return new_lines.splitlines(True)
 
 class Preprocessor(object):
@@ -78,12 +78,12 @@
             # Strings are replaced with blanks
             line = self._literal_chars.sub(lambda k: "'%s'" % ((len(k.group(0))-2)*" "),line)
             line = self._literal_strings.sub(lambda k: '"%s"' % ((len(k.group(0))-2)*" "),line)
-            
+
             # Remove whitespace followed by single-line comment (old behaviour)
             line = re.sub(r"\s*//.*$", "", line)
 
             new_lines.append( line )
-    
+
         new_lines = strip_multi_line_c_comments(new_lines)
 
         self._stripped_comments_and_strings[fn] = new_lines
@@ -344,7 +344,7 @@
                 print("%s %s    %s" % (percentage,time,n))
 
     def main():
-        opts, files = getopt.getopt(sys.argv[1:], "hbcp", ["help", "benchmark","color", "colour", "profile"])
+        opts, given_paths = getopt.getopt(sys.argv[1:], "hbcp", ["help", "benchmark","color", "colour", "profile"])
 
         benchmark = False
         color = False
@@ -362,15 +362,31 @@
             if o in ('-p','--profile'):
                 profile = True
 
-        if not len(files):
+        if not len(given_paths):
             usage()
             sys.exit(0)
 
+        given_paths = set(given_paths)
+        files = set()
+        for f in given_paths:
+            if os.path.isdir(f):
+                for (dirpath, dirnames, filenames) in os.walk(f):
+                    for fn in filenames:
+                        files.add(os.path.abspath(os.path.join(dirpath, fn)))
+                continue
+            files.add(os.path.abspath(f))
+
+        source_files = []
+        for f in files:
+            extension = os.path.splitext(f)[-1].lower()
+            if extension in ('.cc', '.h'):
+                source_files.append(f)
+
         if profile:
             import cProfile
-            cProfile.runctx("check_files(files,color,benchmark)",globals(),locals(),"Profile.prof")
+            cProfile.runctx("check_files(source_files,color,benchmark)",globals(),locals(),"Profile.prof")
         else:
-            check_files(files,color,benchmark)
+            check_files(source_files,color,benchmark)
 
     main()
 

=== renamed file 'src/ui_basic/align.h' => 'src/align.h'
--- src/ui_basic/align.h	2012-02-15 21:25:34 +0000
+++ src/align.h	2013-02-10 14:53:26 +0000
@@ -20,6 +20,8 @@
 #ifndef ALIGN_H
 #define ALIGN_H
 
+#include "point.h"
+
 namespace UI {
 
 enum Align {
@@ -47,6 +49,7 @@
 	Align_BottomRight  = Align_Right|Align_Bottom,
 };
 
+void correct_for_align(Align, uint32_t w, uint32_t h, Point* pt);
+
 }
-
 #endif

=== modified file 'src/constants.h'
--- src/constants.h	2012-12-16 19:08:53 +0000
+++ src/constants.h	2013-02-10 14:53:26 +0000
@@ -20,6 +20,8 @@
 #ifndef CONSTANTS_H
 #define CONSTANTS_H
 
+#include <stdint.h>
+
 /**
  * \file constants.h
  * \brief Global compile time configuration and important constants
@@ -105,6 +107,15 @@
 #define WIDELANDS_PORT               7396
 //@}
 
+/// Maximum numbers of players in a game. The game logic code reserves 5 bits
+/// for player numbers, so it can keep track of 32 different player numbers, of
+/// which the value 0 means neutral and the values 1 .. 31 can be used as the
+/// numbers for actual players. So the upper limit of this value is 31.
+#define MAX_PLAYERS 8
+
+/// How often are statistics to be sampled.
+#define STATISTICS_SAMPLE_TIME 30000
+
 /// Constants for user-defined SDL events that get handled by SDL's mainloop
 //@{
 enum {
@@ -118,4 +129,9 @@
  */
 #define NUMBER_OF_WORKAREA_PICS static_cast<Workarea_Info::size_type>(3)
 
+/// The size of the surface cache in bytes. This is the amount of graphics
+/// memory widelands uses  approximately. Note that not every Surface is also in
+/// the cache, so the actual value will be different - but not by much.
+const uint32_t SURFACE_CACHE_SIZE = 30 << 20;   // 30MB
+
 #endif

=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2013-01-05 18:52:13 +0000
+++ src/editor/editorinteractive.cc	2013-02-10 14:53:26 +0000
@@ -54,7 +54,7 @@
 
 #define INIT_BUTTON(picture, name, tooltip)                         \
 	TOOLBAR_BUTTON_COMMON_PARAMETERS(name),                                      \
-	g_gr->imgcache().load(PicMod_Game, "pics/" picture ".png"),                      \
+	g_gr->images().get("pics/" picture ".png"),                      \
 	tooltip                                                                      \
 
 	m_toggle_main_menu
@@ -126,10 +126,10 @@
 	iterate_player_numbers(p, nr_players) {
 		if (fname[20] == '9') {fname[20] = '0'; ++fname[19];} else ++fname[20];
 		if (Widelands::Coords const sp = map.get_starting_pos(p)) {
-			const IPicture* pic = g_gr->imgcache().load(PicMod_Game, fname);
+			const Image* pic = g_gr->images().get(fname);
 			assert(pic);
 			map.overlay_manager().register_overlay
-				(sp, pic, 8, Point(pic->get_w() / 2, STARTING_POS_HOTSPOT_Y));
+				(sp, pic, 8, Point(pic->width() / 2, STARTING_POS_HOTSPOT_Y));
 		}
 	}
 
@@ -145,7 +145,7 @@
 			    (amount);
 			if (immname.size())
 				overlay_manager.register_overlay
-				(fc, g_gr->imgcache().load(PicMod_Menu, immname.c_str()), 4);
+				(fc, g_gr->images().get(immname.c_str()), 4);
 		}
 	}
 
@@ -580,7 +580,6 @@
 		std::vector<std::string> tipstext;
 		tipstext.push_back("editor");
 		GameTips editortips(loader_ui, tipstext);
-		g_gr->imgcache().flush(PicMod_Menu);
 
 		{
 			Widelands::Map & map = *new Widelands::Map;
@@ -618,7 +617,6 @@
 
 	editor.cleanup_objects();
 
-	g_gr->imgcache().flush(PicMod_Game);
 	g_gr->flush_animations();
 	g_anim.flush();
 }

=== modified file 'src/editor/tools/editor_decrease_resources_tool.cc'
--- src/editor/tools/editor_decrease_resources_tool.cc	2012-12-14 20:09:35 +0000
+++ src/editor/tools/editor_decrease_resources_tool.cc	2013-02-10 14:53:26 +0000
@@ -64,7 +64,7 @@
 			std::string str =
 			    map.world().get_resource(res)->get_editor_pic
 			    (mr.location().field->get_resources_amount());
-			const IPicture* pic = g_gr->imgcache().load(PicMod_Menu, str.c_str());
+			const Image* pic = g_gr->images().get(str);
 			map.overlay_manager().remove_overlay(mr.location(), pic);
 			if (!amount) {
 				mr.location().field->set_resources(0, 0);
@@ -74,7 +74,7 @@
 				mr.location().field->set_starting_res_amount(amount);
 				//  set new overlay
 				str = map.world().get_resource(args.cur_res)->get_editor_pic(amount);
-				pic = g_gr->imgcache().load(PicMod_Menu, str.c_str());
+				pic = g_gr->images().get(str);
 				map.overlay_manager().register_overlay(mr.location(), pic, 4);
 				map.recalc_for_field_area
 				(Widelands::Area<Widelands::FCoords>(mr.location(), 0));

=== modified file 'src/editor/tools/editor_increase_resources_tool.cc'
--- src/editor/tools/editor_increase_resources_tool.cc	2012-12-14 20:09:35 +0000
+++ src/editor/tools/editor_increase_resources_tool.cc	2013-02-10 14:53:26 +0000
@@ -103,11 +103,10 @@
 		        Editor_Change_Resource_Tool_Callback(mr.location(), &map, args.cur_res))
 		{
 			//  Ok, we're doing something. First remove the current overlays.
-			const IPicture* pic =
-			    g_gr->imgcache().load
-			    (PicMod_Menu,
-			     world.get_resource(res)->get_editor_pic
-			     (mr.location().field->get_resources_amount()).c_str());
+			const Image* pic =
+			    g_gr->images().get
+			    (world.get_resource(res)->get_editor_pic
+			     (mr.location().field->get_resources_amount()));
 			overlay_manager.remove_overlay(mr.location(), pic);
 
 			if (not amount) {
@@ -117,9 +116,8 @@
 				mr.location().field->set_resources(args.cur_res, amount);
 				mr.location().field->set_starting_res_amount(amount);
 				//  set new overlay
-				pic = g_gr->imgcache().load
-				        (PicMod_Menu,
-				         world.get_resource(args.cur_res)->get_editor_pic(amount).c_str());
+				pic = g_gr->images().get
+				        (world.get_resource(args.cur_res)->get_editor_pic(amount));
 				overlay_manager.register_overlay(mr.location(), pic, 4);
 				map.recalc_for_field_area
 				(Widelands::Area<Widelands::FCoords>(mr.location(), 0));

=== modified file 'src/editor/tools/editor_set_port_space_tool.cc'
--- src/editor/tools/editor_set_port_space_tool.cc	2013-01-16 22:45:43 +0000
+++ src/editor/tools/editor_set_port_space_tool.cc	2013-02-10 14:53:26 +0000
@@ -21,7 +21,6 @@
 
 #include "logic/building.h"
 #include "editor_tool.h"
-#include "graphic/graphic.h"
 #include "logic/map.h"
 #include "logic/mapfringeregion.h"
 #include "wui/overlay_manager.h"

=== modified file 'src/editor/tools/editor_set_resources_tool.cc'
--- src/editor/tools/editor_set_resources_tool.cc	2012-12-14 20:09:35 +0000
+++ src/editor/tools/editor_set_resources_tool.cc	2013-02-10 14:53:26 +0000
@@ -58,11 +58,8 @@
 
 		if (Editor_Change_Resource_Tool_Callback(mr.location(), &map, args.cur_res)) {
 			//  Ok, we're doing something. First remove the current overlays.
-			const IPicture* pic =
-			    g_gr->imgcache().load
-			    (PicMod_Menu,
-			     world.get_resource(res)->get_editor_pic
-			     (mr.location().field->get_resources_amount()).c_str());
+			const Image* pic = g_gr->images().get
+				(world.get_resource(res)->get_editor_pic (mr.location().field->get_resources_amount()));
 			overlay_manager.remove_overlay(mr.location(), pic);
 
 			if (not amount) {
@@ -73,10 +70,7 @@
 				mr.location().field->set_starting_res_amount(amount);
 				//  set new overlay
 				pic =
-				    g_gr->imgcache().load
-				    (PicMod_Menu,
-				     world.get_resource(args.cur_res)->get_editor_pic(amount)
-				     .c_str());
+				    g_gr->images().get(world.get_resource(args.cur_res)->get_editor_pic(amount));
 				overlay_manager.register_overlay(mr.location(), pic, 4);
 				map.recalc_for_field_area
 				(Widelands::Area<Widelands::FCoords>(mr.location(), 0));
@@ -107,11 +101,9 @@
 		if (amount > max_amount)
 			amount = max_amount;
 
-		const IPicture* pic =
-		    g_gr->imgcache().load
-		    (PicMod_Menu,
-		     world.get_resource(res)->get_editor_pic
-		     (mr.location().field->get_resources_amount()).c_str());
+		const Image* pic =
+		    g_gr->images().get
+		    (world.get_resource(res)->get_editor_pic(mr.location().field->get_resources_amount()));
 		overlay_manager.remove_overlay(mr.location(), pic);
 
 		if (not amount) {
@@ -121,11 +113,7 @@
 			mr.location().field->set_resources(*it, amount);
 			mr.location().field->set_starting_res_amount(amount);
 			//  set new overlay
-			pic =
-			    g_gr->imgcache().load
-			    (PicMod_Menu,
-			     world.get_resource(*it)->get_editor_pic(amount)
-			     .c_str());
+			pic = g_gr->images().get(world.get_resource(*it)->get_editor_pic(amount));
 			overlay_manager.register_overlay(mr.location(), pic, 4);
 			map.recalc_for_field_area
 			(Widelands::Area<Widelands::FCoords>(mr.location(), 0));

=== modified file 'src/editor/tools/editor_set_starting_pos_tool.cc'
--- src/editor/tools/editor_set_starting_pos_tool.cc	2012-12-14 20:09:35 +0000
+++ src/editor/tools/editor_set_starting_pos_tool.cc	2013-02-10 14:53:26 +0000
@@ -89,7 +89,7 @@
 		char picname[] = "pics/editor_player_00_starting_pos.png";
 		picname[19] += m_current_player / 10;
 		picname[20] += m_current_player % 10;
-		const IPicture* pic = g_gr->imgcache().load(PicMod_Game,  picname);
+		const Image* pic = g_gr->images().get(picname);
 
 		//  check if field is valid
 		if
@@ -102,7 +102,7 @@
 
 			//  add new overlay
 			overlay_manager.register_overlay
-			(center.node, pic, 8, Point(pic->get_w() / 2, STARTING_POS_HOTSPOT_Y));
+			(center.node, pic, 8, Point(pic->width() / 2, STARTING_POS_HOTSPOT_Y));
 
 			//  set new player pos
 			map.set_starting_pos(m_current_player, center.node);

=== modified file 'src/editor/ui_menus/editor_main_menu.cc'
--- src/editor/ui_menus/editor_main_menu.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_main_menu.cc	2013-02-10 14:53:26 +0000
@@ -51,37 +51,37 @@
 	m_button_new_map
 		(this, "new_map",
 		 hmargin, vmargin + 0 * (height + vspacing), width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("New Map")),
 	m_button_new_random_map
 		(this, "new_random_map",
 		 hmargin, vmargin + 1 * (height + vspacing), width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("New Random Map")),
 	m_button_load_map
 		(this, "load_map",
 		 hmargin, vmargin + 2 * (height + vspacing), width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Load Map")),
 	m_button_save_map
 		(this, "save_map",
 		 hmargin, vmargin + 3 * (height + vspacing), width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Save Map")),
 	m_button_map_options
 		(this, "map_options",
 		 hmargin, vmargin + 4 * (height + vspacing), width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Map Options")),
 	m_button_view_readme
 		(this, "readme",
 		 hmargin, vmargin + 5 * (height + vspacing), width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("View Readme")),
 	m_button_exit_editor
 		(this, "exit",
 		 hmargin, vmargin + 6 * (height + vspacing), width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Exit Editor"))
 {
 	m_button_new_map.sigclicked.connect(boost::bind(&Editor_Main_Menu::new_map_btn, this));

=== modified file 'src/editor/ui_menus/editor_main_menu_load_map.cc'
--- src/editor/ui_menus/editor_main_menu_load_map.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_main_menu_load_map.cc	2013-02-10 14:53:26 +0000
@@ -116,7 +116,7 @@
 	m_ok_btn = new UI::Button
 		(this, "ok",
 		 get_inner_w() / 2 - spacing - 80, posy, 80, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("OK"),
 		 std::string(),
 		 false);
@@ -125,7 +125,7 @@
 	UI::Button * cancelbtn = new UI::Button
 		(this, "cancel",
 		 posx, posy, 80, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Cancel"));
 	cancelbtn->sigclicked.connect(boost::bind(&Main_Menu_Load_Map::die, this));
 
@@ -222,7 +222,7 @@
 		m_ls->add
 			(_("<parent>"),
 			 m_parentdir.c_str(),
-			 g_gr->imgcache().load(PicMod_Game, "pics/ls_dir.png"));
+			 g_gr->images().get("pics/ls_dir.png"));
 	}
 
 	const filenameset_t::const_iterator mapfiles_end = m_mapfiles.end();
@@ -241,7 +241,7 @@
 		m_ls->add
 			(FileSystem::FS_Filename(name),
 			 name,
-			 g_gr->imgcache().load(PicMod_Game, "pics/ls_dir.png"));
+			 g_gr->images().get("pics/ls_dir.png"));
 	}
 
 	Widelands::Map map;
@@ -259,10 +259,8 @@
 				m_ls->add
 					(FileSystem::FS_Filename(name),
 					 name,
-					 g_gr->imgcache().load
-					 	(PicMod_Game,
-					 	 dynamic_cast<WL_Map_Loader const *>(m_ml) ?
-					 	 "pics/ls_wlmap.png" : "pics/ls_s2map.png"));
+					 g_gr->images().get
+						 (dynamic_cast<WL_Map_Loader const *>(m_ml) ? "pics/ls_wlmap.png" : "pics/ls_s2map.png"));
 			} catch (_wexception const &) {} //  we simply skip illegal entries
 			delete m_ml;
 		}

=== modified file 'src/editor/ui_menus/editor_main_menu_map_options.cc'
--- src/editor/ui_menus/editor_main_menu_map_options.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_main_menu_map_options.cc	2013-02-10 14:53:26 +0000
@@ -20,6 +20,7 @@
 #include "editor_main_menu_map_options.h"
 
 #include "editor/editorinteractive.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
 #include "logic/map.h"
 #include "profile/profile.h"
@@ -59,7 +60,7 @@
 			(this,
 			 posx + ta->get_w() + spacing, posy,
 			 get_inner_w() - (posx + ta->get_w() + spacing) - spacing, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 g_gr->images().get("pics/but1.png"));
 	m_name->changed.connect(boost::bind(&Main_Menu_Map_Options::changed, this, 0));
 	posy += height + spacing;
 	ta = new UI::Textarea(this, posx, posy - 2, _("Size:"));
@@ -82,7 +83,7 @@
 			(this,
 			 posx + ta->get_w() + spacing, posy,
 			 get_inner_w() - (posx + ta->get_w() + spacing) - spacing, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 g_gr->images().get("pics/but1.png"));
 	m_author->changed.connect(boost::bind(&Main_Menu_Map_Options::changed, this, 1));
 	posy += height + spacing;
 	m_descr =
@@ -97,7 +98,7 @@
 		new UI::Button
 			(this, "set_origin",
 			 5, get_inner_h() - 25, get_inner_w() - 10, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+			 g_gr->images().get("pics/but0.png"),
 			 _("Set origin"),
 			 _
 				("Set the position that will have the coordinates (0, 0). This will "

=== modified file 'src/editor/ui_menus/editor_main_menu_new_map.cc'
--- src/editor/ui_menus/editor_main_menu_new_map.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_main_menu_new_map.cc	2013-02-10 14:53:26 +0000
@@ -68,15 +68,15 @@
 	UI::Button * widthupbtn = new UI::Button
 		(this, "width_up",
 		 get_inner_w() - spacing - 20, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"));
 	widthupbtn->sigclicked.connect(boost::bind(&Main_Menu_New_Map::button_clicked, this, 0));
 
 	UI::Button * widthdownbtn = new UI::Button
 		(this, "width_down",
 		 posx, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"));
 	widthdownbtn->sigclicked.connect(boost::bind(&Main_Menu_New_Map::button_clicked, this, 1));
 
 	posy += 20 + spacing + spacing;
@@ -89,15 +89,15 @@
 	UI::Button * heightupbtn = new UI::Button
 		(this, "height_up",
 		 get_inner_w() - spacing - 20, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"));
 	heightupbtn->sigclicked.connect(boost::bind(&Main_Menu_New_Map::button_clicked, this, 2));
 
 	UI::Button * heightdownbtn = new UI::Button
 		(this, "height_down",
 		 posx, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"));
 	heightdownbtn->sigclicked.connect(boost::bind(&Main_Menu_New_Map::button_clicked, this, 3));
 
 	posy += 20 + spacing + spacing;
@@ -111,7 +111,7 @@
 	m_world = new UI::Button
 		(this, "world",
 		 posx, posy, width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 Widelands::World(m_worlds[m_currentworld].c_str()).get_name());
 	m_world->sigclicked.connect(boost::bind(&Main_Menu_New_Map::button_clicked, this, 4));
 
@@ -120,7 +120,7 @@
 	UI::Button * createbtn = new UI::Button
 		(this, "create_map",
 		 posx, posy, width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Create Map"));
 	createbtn->sigclicked.connect(boost::bind(&Main_Menu_New_Map::clicked_create_map, this));
 

=== modified file 'src/editor/ui_menus/editor_main_menu_random_map.cc'
--- src/editor/ui_menus/editor_main_menu_random_map.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_main_menu_random_map.cc	2013-02-10 14:53:26 +0000
@@ -74,7 +74,7 @@
 			(this,
 			 posx, posy,
 			 width, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 g_gr->images().get("pics/but1.png"));
 	m_nrEditbox->changed.connect
 		(boost::bind(&Main_Menu_New_Random_Map::nr_edit_box_changed, this));
 	RNG rng;
@@ -101,16 +101,16 @@
 	UI::Button * widthupbtn = new UI::Button
 		(this, "width_up",
 		 get_inner_w() - spacing - 20, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"));
 	widthupbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, MAP_W_PLUS));
 
 	UI::Button * widthdownbtn = new UI::Button
 		(this, "width_down",
 		 posx, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"));
 	widthdownbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, MAP_W_MINUS));
 
@@ -131,16 +131,16 @@
 	UI::Button * heightupbtn = new UI::Button
 		(this, "height_up",
 		 get_inner_w() - spacing - 20, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"));
 	heightupbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, MAP_H_PLUS));
 
 	UI::Button * heightdownbtn = new UI::Button
 		(this, "height_down",
 		 posx, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"));
 	heightdownbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, MAP_H_MINUS));
 
@@ -152,16 +152,16 @@
 	UI::Button * waterupbtn = new UI::Button
 		(this, "water_up",
 		 get_inner_w() - spacing - 20, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"));
 	waterupbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, WATER_PLUS));
 
 	UI::Button * waterdownbtn = new UI::Button
 		(this, "water_down",
 		 posx, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"));
 	waterdownbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, WATER_MINUS));
 
@@ -177,16 +177,16 @@
 	UI::Button * landupbtn = new UI::Button
 		(this, "land_up",
 		 get_inner_w() - spacing - 20, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"));
 	landupbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, LAND_PLUS));
 
 	UI::Button * landdownbtn = new UI::Button
 		(this, "land_down",
 		 posx, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"));
 	landdownbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, LAND_MINUS));
 
@@ -203,16 +203,16 @@
 	UI::Button * wastelandupbtn = new UI::Button
 		(this, "wasteland_up",
 		 get_inner_w() - spacing - 20, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"));
 	wastelandupbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, WASTE_PLUS));
 
 	UI::Button * wastelanddownbtn = new UI::Button
 		(this, "wasteland_down",
 		 posx, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"));
 	wastelanddownbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, WASTE_MINUS));
 
@@ -262,7 +262,7 @@
 	m_res = new UI::Button
 		(this, "resources",
 		 posx, posy, width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 m_res_amounts[m_res_amount].c_str());
 	m_res->sigclicked.connect(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, SWITCH_RES));
 
@@ -281,7 +281,7 @@
 	m_world = new UI::Button
 		(this, "world",
 		 posx, posy, width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 Widelands::World(m_worlds[m_currentworld].c_str()).get_name());
 	m_world->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, SWITCH_WORLD));
@@ -300,7 +300,7 @@
 			(this,
 			 posx, posy,
 			 width, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 g_gr->images().get("pics/but1.png"));
 	m_idEditbox->setText("abcd-efgh-ijkl-mnop");
 	m_idEditbox->changed.connect
 		(boost::bind(&Main_Menu_New_Random_Map::id_edit_box_changed, this));
@@ -313,16 +313,16 @@
 	UI::Button * playerupbtn = new UI::Button
 		(this, "player_up",
 		 get_inner_w() - spacing - 20, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"));
 	playerupbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, PLAYER_PLUS));
 
 	UI::Button * playerdownbtn = new UI::Button
 		(this, "player_down",
 		 posx, posy, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"));
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"));
 	playerdownbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_New_Random_Map::button_clicked, this, PLAYER_MINUS));
 
@@ -338,7 +338,7 @@
 	m_goButton = new UI::Button
 		(this, "generate_map",
 		 posx, posy, width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Generate Map"));
 	m_goButton->sigclicked.connect(boost::bind(&Main_Menu_New_Random_Map::clicked_create_map, this));
 	posy += height + spacing;

=== modified file 'src/editor/ui_menus/editor_main_menu_save_map.cc'
--- src/editor/ui_menus/editor_main_menu_save_map.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_main_menu_save_map.cc	2013-02-10 14:53:26 +0000
@@ -72,7 +72,7 @@
 			(this,
 			 posx, posy + get_inner_h() - spacing - offsy - 60 + 3,
 			 get_inner_w() / 2 - spacing, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 g_gr->images().get("pics/but1.png"));
 	m_editbox->setText(parent.egbase().map().get_name());
 	m_editbox->changed.connect(boost::bind(&Main_Menu_Save_Map::edit_box_changed, this));
 
@@ -129,21 +129,21 @@
 	m_ok_btn = new UI::Button
 		(this, "ok",
 		 get_inner_w() / 2 - spacing - 80, posy, 80, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("OK"));
 	m_ok_btn->sigclicked.connect(boost::bind(&Main_Menu_Save_Map::clicked_ok, boost::ref(*this)));
 
 	UI::Button * cancelbtn = new UI::Button
 		(this, "cancel",
 		 posx, posy, 80, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Cancel"));
 	cancelbtn->sigclicked.connect(boost::bind(&Main_Menu_Save_Map::die, boost::ref(*this)));
 
 	UI::Button * make_directorybtn = new UI::Button
 		(this, "make_directory",
 		 spacing, posy, 120, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Make Directory"));
 	make_directorybtn->sigclicked.connect
 		(boost::bind(&Main_Menu_Save_Map::clicked_make_directory, boost::ref(*this)));
@@ -293,7 +293,7 @@
 		m_ls->add
 			(_("<parent>"),
 			 m_parentdir.c_str(),
-			 g_gr->imgcache().load(PicMod_Game, "pics/ls_dir.png"));
+			 g_gr->images().get("pics/ls_dir.png"));
 	}
 
 	const filenameset_t::const_iterator mapfiles_end = m_mapfiles.end();
@@ -312,7 +312,7 @@
 		m_ls->add
 			(FileSystem::FS_Filename(name),
 			 name,
-			 g_gr->imgcache().load(PicMod_Game, "pics/ls_dir.png"));
+			 g_gr->images().get("pics/ls_dir.png"));
 	}
 
 	Widelands::Map map;
@@ -331,7 +331,7 @@
 				m_ls->add
 					(FileSystem::FS_Filename(name),
 					 name,
-					 g_gr->imgcache().load(PicMod_Game, "pics/ls_wlmap.png"));
+					 g_gr->images().get("pics/ls_wlmap.png"));
 			} catch (_wexception const &) {} //  we simply skip illegal entries
 			delete ml;
 		}

=== modified file 'src/editor/ui_menus/editor_main_menu_save_map_make_directory.cc'
--- src/editor/ui_menus/editor_main_menu_save_map_make_directory.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_main_menu_save_map_make_directory.cc	2013-02-10 14:53:26 +0000
@@ -20,6 +20,7 @@
 #include "editor_main_menu_save_map_make_directory.h"
 
 #include "constants.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
 
 #include "ui_basic/button.h"
@@ -42,7 +43,7 @@
 	m_edit =
 		new UI::EditBox
 			(this, spacing, posy, get_inner_w() - 2 * spacing, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 g_gr->images().get("pics/but1.png"));
 	m_edit->setText(dirname);
 	m_dirname = dirname;
 	m_edit->changed.connect(boost::bind(&Main_Menu_Save_Map_Make_Directory::edit_changed, this));
@@ -53,7 +54,7 @@
 		UI::Button
 		(this, "ok",
 		 get_inner_w() / 2 - spacing - 80, posy, 80, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("OK"),
 		 std::string(),
 		 m_dirname.size());
@@ -63,7 +64,7 @@
 	UI::Button * cancelbtn = new UI::Button
 		(this, "cancel",
 		 get_inner_w() / 2 + spacing, posy, 80, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Cancel"));
 	cancelbtn->sigclicked.connect
 		(boost::bind(&Main_Menu_Save_Map_Make_Directory::end_modal, boost::ref(*this), 0));

=== modified file 'src/editor/ui_menus/editor_player_menu.cc'
--- src/editor/ui_menus/editor_player_menu.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_player_menu.cc	2013-02-10 14:53:26 +0000
@@ -43,15 +43,15 @@
 	m_add_player
 		(this, "add_player",
 		 get_inner_w() - 5 - 20, 5, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"),
 		 _("Add player"),
 		 parent.egbase().map().get_nrplayers() < MAX_PLAYERS),
 	m_remove_last_player
 		(this, "remove_last_player",
 		 5, 5, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"),
 		 _("Remove last player"),
 		 1 < parent.egbase().map().get_nrplayers())
 {
@@ -140,7 +140,7 @@
 			m_plr_names[p - 1] =
 				new UI::EditBox
 					(this, posx, posy, 140, size,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"));
+					 g_gr->images().get("pics/but0.png"));
 			m_plr_names[p - 1]->changed.connect
 				(boost::bind(&Editor_Player_Menu::name_changed, this, p - 1));
 			posx += 140 + spacing;
@@ -152,8 +152,8 @@
 				new UI::Button
 					(this, "tribe",
 					 posx, posy, 140, size,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-					 std::string());
+					 g_gr->images().get("pics/but0.png"),
+					 "");
 			m_plr_set_tribes_buts[p - 1]->sigclicked.connect
 				(boost::bind(&Editor_Player_Menu::player_tribe_clicked, boost::ref(*this), p - 1));
 			posx += 140 + spacing;
@@ -176,9 +176,9 @@
 				new UI::Button
 					(this, "starting_pos",
 					 posx, posy, size, size,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+					 g_gr->images().get("pics/but0.png"),
 					 NULL,
-					 std::string());
+					 "");
 			m_plr_set_pos_buts[p - 1]->sigclicked.connect
 				(boost::bind(&Editor_Player_Menu::set_starting_pos_clicked, boost::ref(*this), p));
 			posx += size + spacing;
@@ -186,7 +186,7 @@
 		char text[] = "pics/fsel_editor_set_player_00_pos.png";
 		text[28] += p / 10;
 		text[29] += p % 10;
-		m_plr_set_pos_buts[p - 1]->set_pic(g_gr->imgcache().load(PicMod_Game, text));
+		m_plr_set_pos_buts[p - 1]->set_pic(g_gr->images().get(text));
 		posy += size + spacing;
 	}
 	set_inner_size(get_inner_w(), posy + spacing);
@@ -230,7 +230,7 @@
 			picsname[19] += old_nr_players / 10;
 			picsname[20] += old_nr_players % 10;
 			map.overlay_manager().remove_overlay
-				(sp, g_gr->imgcache().load(PicMod_Game, picsname));
+				(sp, g_gr->images().get(picsname));
 		}
 	}
 	map.set_nrplayers(nr_players);
@@ -431,7 +431,7 @@
 		picsname += static_cast<char>((n % 10) + 0x30);
 		picsname += "_starting_pos.png";
 		overlay_manager.remove_overlay
-			(start_pos, g_gr->imgcache().load(PicMod_Game,  picsname));
+			(start_pos, g_gr->images().get(picsname));
 	}
 
 	parent.select_tool(parent.tools.make_infrastructure, Editor_Tool::First);

=== modified file 'src/editor/ui_menus/editor_player_menu_allowed_buildings_menu.cc'
--- src/editor/ui_menus/editor_player_menu_allowed_buildings_menu.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_player_menu_allowed_buildings_menu.cc	2013-02-10 14:53:26 +0000
@@ -19,10 +19,11 @@
 
 #include "editor_player_menu_allowed_buildings_menu.h"
 
+#include "graphic/graphic.h"
 #include "i18n.h"
 #include "logic/map.h"
+#include "logic/player.h"
 #include "logic/tribe.h"
-#include "logic/player.h"
 
 using Widelands::Building_Index;
 
@@ -79,7 +80,7 @@
 		 m_allowed.get_y()
 		 + (list_height - middle_button_height * 2 - vspacing) / 2,
 		 middle_button_width, middle_button_height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 ("->"),
 		 _("Forbid"),
 		 false),
@@ -88,7 +89,7 @@
 		 m_forbid_button.get_x(),
 		 m_forbid_button.get_y() + middle_button_height + vspacing,
 		 middle_button_width, middle_button_height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("<-"),
 		 _("Allow"),
 		 false)

=== modified file 'src/editor/ui_menus/editor_tool_change_height_options_menu.cc'
--- src/editor/ui_menus/editor_tool_change_height_options_menu.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_tool_change_height_options_menu.cc	2013-02-10 14:53:26 +0000
@@ -48,8 +48,8 @@
 		 get_inner_w() - hmargin() - width,
 		 m_change_by_label.get_y() + m_change_by_label.get_h() + spacing(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"),
 		 std::string(),
 		 increase_tool.get_change_by() < MAX_FIELD_HEIGHT_DIFF),
 	m_change_by_decrease
@@ -57,8 +57,8 @@
 		 hmargin(),
 		 m_change_by_increase.get_y(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"),
 		 std::string(),
 		 1 < increase_tool.get_change_by()),
 	m_change_by_value
@@ -84,8 +84,8 @@
 		 m_change_by_increase.get_x(),
 		 m_set_to_label.get_y() + m_set_to_label.get_h() + vspacing(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"),
 		 std::string(),
 		 increase_tool.set_tool().get_interval().min < MAX_FIELD_HEIGHT),
 	m_set_to_decrease
@@ -93,8 +93,8 @@
 		 hmargin(),
 		 m_set_to_increase.get_y(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"),
 		 std::string(),
 		 0 < increase_tool.set_tool().get_interval().min),
 	m_set_to_value

=== modified file 'src/editor/ui_menus/editor_tool_change_resources_options_menu.cc'
--- src/editor/ui_menus/editor_tool_change_resources_options_menu.cc	2012-12-15 18:40:59 +0000
+++ src/editor/ui_menus/editor_tool_change_resources_options_menu.cc	2013-02-10 14:53:26 +0000
@@ -32,8 +32,9 @@
 
 #include <cstdio>
 
-#define width  20
-#define height 20
+const static int BUTTON_WIDTH = 20;
+const static int BUTTON_HEIGHT = 20;
+
 Editor_Tool_Change_Resources_Options_Menu::
 Editor_Tool_Change_Resources_Options_Menu
 		(Editor_Interactive             & parent,
@@ -44,22 +45,22 @@
 		(parent, registry, 164, 120, _("Resources Tools Options")),
 	m_change_by_label
 		(this,
-		 hmargin(), vmargin(), get_inner_w() - 2 * hmargin(), height,
+		 hmargin(), vmargin(), get_inner_w() - 2 * hmargin(), BUTTON_HEIGHT,
 		 _("In-/Decrease Value"), UI::Align_BottomCenter),
 	m_change_by_increase
 		(this, "incr_change_by",
-		 get_inner_w() - hmargin() - width,
+		 get_inner_w() - hmargin() - BUTTON_WIDTH,
 		 m_change_by_label.get_y() + m_change_by_label.get_h() + spacing(),
-		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_up.png")),
+		 BUTTON_WIDTH, BUTTON_HEIGHT,
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png")),
 	m_change_by_decrease
 		(this, "decr_change_by",
 		 hmargin(),
 		 m_change_by_increase.get_y(),
-		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_down.png")),
+		 BUTTON_WIDTH, BUTTON_HEIGHT,
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png")),
 	m_change_by_value
 		(this,
 		 m_change_by_increase.get_x() + m_change_by_increase.get_w() +
@@ -69,31 +70,31 @@
 		 -
 		 (m_change_by_increase.get_x() + m_change_by_increase.get_w() +
 		  hspacing()),
-		 height,
+		 BUTTON_HEIGHT,
 		 UI::Align_BottomCenter),
 	m_set_to_label
 		(this,
 		 vmargin(),
 		 m_change_by_increase.get_y() + m_change_by_increase.get_h() + vspacing(),
-		 get_inner_w() - 2 * hmargin(), height,
+		 get_inner_w() - 2 * hmargin(), BUTTON_HEIGHT,
 		 _("Set Value"), UI::Align_BottomCenter),
 	m_set_to_increase
 		(this, "incr_set_to",
 		 m_change_by_increase.get_x(),
 		 m_set_to_label.get_y() + m_set_to_label.get_h() + vspacing(),
-		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_up.png")),
+		 BUTTON_WIDTH, BUTTON_HEIGHT,
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png")),
 	m_set_to_decrease
 		(this, "decr_set_to",
 		 hmargin(),
-		 m_set_to_increase.get_y(), width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_down.png")),
+		 m_set_to_increase.get_y(), BUTTON_WIDTH, BUTTON_HEIGHT,
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png")),
 	m_set_to_value
 		(this,
 		 m_change_by_value.get_x(), m_set_to_increase.get_y(),
-		 m_change_by_value.get_w(), height,
+		 m_change_by_value.get_w(), BUTTON_HEIGHT,
 		 UI::Align_BottomCenter),
 	m_cur_selection(this, 0, 0, _("Current Selection"), UI::Align_BottomCenter),
 	m_increase_tool(increase_tool)
@@ -127,15 +128,14 @@
 	Widelands::Resource_Index const nr_resources = world.get_nr_resources();
 
 	//  Find the maximal width and height for the resource pictures.
-	uint32_t resource_pic_max_width = 0, resource_pic_max_height = 0;
+	uint16_t resource_pic_max_width = 0, resource_pic_max_height = 0;
 	for (Widelands::Resource_Index i = 0; i < nr_resources; ++i) {
-		const IPicture* pic = g_gr->imgcache().load
-			(PicMod_Game, world.get_resource(i)->get_editor_pic(100000).c_str());
-		resource_pic_max_width  = std::max(resource_pic_max_width,  pic->get_w());
-		resource_pic_max_height = std::max(resource_pic_max_height, pic->get_h());
+		const Image* pic = g_gr->images().get(world.get_resource(i)->get_editor_pic(100000).c_str());
+		resource_pic_max_width  = std::max(resource_pic_max_width,  pic->width());
+		resource_pic_max_height = std::max(resource_pic_max_height, pic->height());
 	}
 
-	const uint32_t resources_in_row =
+	const uint16_t resources_in_row =
 		(get_inner_w() - 2 * hmargin() + spacing())
 		/
 		(resource_pic_max_width + spacing());
@@ -145,7 +145,7 @@
 	m_radiogroup.clicked.connect
 		(boost::bind(&Editor_Tool_Change_Resources_Options_Menu::selected, this));
 
-	uint32_t cur_x = 0;
+	uint16_t cur_x = 0;
 	Point pos
 		(hmargin(), m_set_to_value.get_y() + m_set_to_value.get_h() + vspacing());
 	for
@@ -161,9 +161,7 @@
 		m_radiogroup.add_button
 			(this,
 			 pos,
-			 g_gr->imgcache().load
-			 	(PicMod_Game,
-			 	 world.get_resource(i)->get_editor_pic(100000).c_str()));
+			 g_gr->images().get(world.get_resource(i)->get_editor_pic(100000)));
 	}
 	pos.y += resource_pic_max_height + vspacing();
 

=== modified file 'src/editor/ui_menus/editor_tool_menu.cc'
--- src/editor/ui_menus/editor_tool_menu.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_tool_menu.cc	2013-02-10 14:53:26 +0000
@@ -59,8 +59,7 @@
    m_radioselect.add_button                                                   \
       (this,                                                                  \
        pos,                                                                   \
-       g_gr->imgcache().load                                                      \
-          (PicMod_Game, "pics/editor_menu_tool_" pic ".png"),                 \
+       g_gr->images().get("pics/editor_menu_tool_" pic ".png"),       \
        tooltip);                                                              \
    pos.x += width + spacing;                                                  \
 

=== modified file 'src/editor/ui_menus/editor_tool_noise_height_options_menu.cc'
--- src/editor/ui_menus/editor_tool_noise_height_options_menu.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_tool_noise_height_options_menu.cc	2013-02-10 14:53:26 +0000
@@ -56,8 +56,8 @@
 		 (get_inner_w() - 2 * hmargin() - hspacing() - 4 * width) / 4,
 		 m_lower_label.get_y() + m_lower_label.get_h() + vspacing(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_down.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"),
 		 std::string(),
 		 0 < noise_tool.get_interval().min),
 	m_lower_increase
@@ -65,8 +65,8 @@
 		 m_lower_decrease.get_x() + m_lower_decrease.get_w(),
 		 m_lower_decrease.get_y(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"),
 		 std::string(),
 		 noise_tool.get_interval().min < MAX_FIELD_HEIGHT),
 	m_upper_decrease
@@ -77,8 +77,8 @@
 		 hspacing(),
 		 m_lower_decrease.get_y(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_down.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"),
 		 std::string(),
 		 0 < noise_tool.get_interval().max),
 	m_upper_increase
@@ -86,8 +86,8 @@
 		 m_upper_decrease.get_x() + m_upper_decrease.get_w(),
 		 m_upper_decrease.get_y(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_up.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"),
 		 std::string(),
 		 noise_tool.get_interval().max < MAX_FIELD_HEIGHT),
 	m_set_label
@@ -101,8 +101,8 @@
 		 get_inner_w() / 2 - width,
 		 m_set_label.get_y() + m_set_label.get_h() + vspacing(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_down.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"),
 		 std::string(),
 		 0 < noise_tool.set_tool().get_interval().min),
 	m_setto_increase
@@ -110,8 +110,8 @@
 		 get_inner_w() / 2,
 		 m_setto_decrease.get_y(),
 		 width, height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_up.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"),
 		 std::string(),
 		 noise_tool.set_tool().get_interval().max < MAX_FIELD_HEIGHT)
 {

=== modified file 'src/editor/ui_menus/editor_tool_place_bob_options_menu.cc'
--- src/editor/ui_menus/editor_tool_place_bob_options_menu.cc	2012-12-14 20:09:35 +0000
+++ src/editor/ui_menus/editor_tool_place_bob_options_menu.cc	2013-02-10 14:53:26 +0000
@@ -45,7 +45,7 @@
 :
 Editor_Tool_Options_Menu(parent, registry, 100, 100, _("Bobs Menu")),
 
-m_tabpanel          (this, 0, 0, g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+m_tabpanel          (this, 0, 0, g_gr->images().get("pics/but1.png")),
 m_pit               (pit),
 m_click_recursion_protect(false)
 {
@@ -63,17 +63,17 @@
 
 	uint32_t width = 0, height = 0;
 	for (int32_t j = 0; j < nr_bobs; ++j) {
-		const IPicture* pic = g_gr->imgcache().load(PicMod_Game, world.get_bob_descr(j)->get_picture());
-		uint32_t w = pic->get_w();
-		uint32_t h = pic->get_h();
+		const Image* pic = g_gr->images().get(world.get_bob_descr(j)->get_picture());
+		uint16_t w = pic->width();
+		uint16_t h = pic->height();
 		if (w > width)
 			width = w;
 		if (h > height)
 			height = h;
 	}
 
-	const IPicture* tab_icon =
-		g_gr->imgcache().load(PicMod_Game, "pics/list_first_entry.png");
+	const Image* tab_icon =
+		g_gr->images().get("pics/list_first_entry.png");
 	Point pos;
 	uint32_t cur_x = bobs_in_row;
 	int32_t i = 0;
@@ -91,7 +91,7 @@
 		UI::Checkbox & cb = *new UI::Checkbox
 			(box,
 			 pos,
-			 g_gr->imgcache().load(PicMod_Game, descr.get_picture()),
+			 g_gr->images().get(descr.get_picture()),
 			 critter_descr ? critter_descr->descname() : std::string());
 
 		cb.set_desired_size(width, height);

=== modified file 'src/editor/ui_menus/editor_tool_place_immovable_options_menu.cc'
--- src/editor/ui_menus/editor_tool_place_immovable_options_menu.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_tool_place_immovable_options_menu.cc	2013-02-10 14:53:26 +0000
@@ -43,7 +43,7 @@
 		 UI::UniqueWindow::Registry  & registry)
 :
 Editor_Tool_Options_Menu(parent, registry, 100, 100, _("Immovable Bobs Menu")),
-m_tabpanel(this, 0, 0, g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+m_tabpanel(this, 0, 0, g_gr->images().get("pics/but1.png")),
 m_pit     (pit),
 m_click_recursion_protect(false)
 {
@@ -59,9 +59,9 @@
 	uint32_t width = 0, height = 0;
 	for (int32_t j = 0; j < nr_immovables; ++j) {
 		const Immovable_Descr & descr = *world.get_immovable_descr(j);
-		const IPicture* pic = g_gr->imgcache().load(PicMod_Game, descr.get_picture());
-		uint32_t w = pic->get_w();
-		uint32_t h = pic->get_h();
+		const Image* pic = g_gr->images().get(descr.get_picture());
+		uint16_t w = pic->width();
+		uint16_t h = pic->height();
 		if (w > width)
 			width  = w;
 		if (h > height)
@@ -70,8 +70,8 @@
 
 	//box->set_inner_size((immovables_in_row)*(width+1+space)+xstart,
 	//                     (immovables_in_row)*(height+1+space)+ystart+yend);
-	const IPicture* tab_icon =
-		g_gr->imgcache().load(PicMod_Game, "pics/list_first_entry.png");
+	const Image* tab_icon =
+		g_gr->images().get("pics/list_first_entry.png");
 
 	Point pos;
 	uint32_t cur_x = immovables_in_row;
@@ -91,8 +91,7 @@
 
 		UI::Checkbox & cb = *new UI::Checkbox
 			(box, pos,
-			 g_gr->imgcache().load
-			 	(PicMod_Game, world.get_immovable_descr(i)->get_picture()));
+			 g_gr->images().get(world.get_immovable_descr(i)->get_picture()));
 
 		cb.set_desired_size(width, height);
 		cb.set_state(m_pit.is_enabled(i));

=== modified file 'src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc'
--- src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc	2012-12-15 18:40:59 +0000
+++ src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc	2013-02-10 14:53:26 +0000
@@ -23,8 +23,9 @@
 #include "editor/editorinteractive.h"
 #include "editor/tools/editor_set_terrain_tool.h"
 #include "graphic/graphic.h"
-#include "graphic/iblitable_surface.h"
+#include "graphic/in_memory_image.h"
 #include "graphic/rendertarget.h"
+#include "graphic/surface.h"
 #include "graphic/texture.h"
 #include "i18n.h"
 #include "logic/map.h"
@@ -64,18 +65,18 @@
 
 	m_checkboxes.resize(nr_terrains);
 
-	const IPicture* green =
-		g_gr->imgcache().load(PicMod_Game, "pics/terrain_green.png");
-	const IPicture* water =
-		g_gr->imgcache().load(PicMod_Game, "pics/terrain_water.png");
-	const IPicture* mountain =
-		g_gr->imgcache().load(PicMod_Game, "pics/terrain_mountain.png");
-	const IPicture* dead =
-		g_gr->imgcache().load(PicMod_Game, "pics/terrain_dead.png");
-	const IPicture* unpassable =
-		g_gr->imgcache().load(PicMod_Game, "pics/terrain_unpassable.png");
-	const IPicture* dry =
-		g_gr->imgcache().load(PicMod_Game, "pics/terrain_dry.png");
+	const Image* green =
+		g_gr->images().get("pics/terrain_green.png");
+	const Image* water =
+		g_gr->images().get("pics/terrain_water.png");
+	const Image* mountain =
+		g_gr->images().get("pics/terrain_mountain.png");
+	const Image* dead =
+		g_gr->images().get("pics/terrain_dead.png");
+	const Image* unpassable =
+		g_gr->images().get("pics/terrain_unpassable.png");
+	const Image* dry =
+		g_gr->images().get("pics/terrain_dry.png");
 
 	static const int small_pich = 20;
 	static const int small_picw = 20;
@@ -94,41 +95,41 @@
 				pos.y += TEXTURE_HEIGHT + vspacing();
 			}
 
-			IBlitableSurface* surf = g_gr->create_surface(64, 64);
-			const IPicture* tex = g_gr->imgcache().load
-				(PicMod_Game, g_gr->get_maptexture_data(world.terrain_descr(i).get_texture())
-						->get_texture_picture());
-			surf->blit(Point(0, 0), tex, Rect(0, 0, tex->get_w(), tex->get_h()));
+			Surface* surf = Surface::create(64, 64);
+			const Image* tex = g_gr->images().get
+				(g_gr->get_maptexture_data(world.terrain_descr(i).get_texture())->get_texture_image());
+			surf->blit(Point(0, 0), tex->surface(), Rect(0, 0, tex->width(), tex->height()));
 
 			Point pt(1, 64 - small_pich - 1);
 
 			//  check is green
 			if (ter_is == 0) {
-				surf->blit(pt, green, Rect(0, 0, green->get_w(), green->get_h()));
+				surf->blit(pt, green->surface(), Rect(0, 0, green->width(), green->height()));
 				pt.x += small_picw + 1;
 			} else {
 				if (ter_is & TERRAIN_WATER) {
-					surf->blit(pt, water, Rect(0, 0, water->get_w(), water->get_h()));
+					surf->blit(pt, water->surface(), Rect(0, 0, water->width(), water->height()));
 					pt.x += small_picw + 1;
 				}
 				if (ter_is & TERRAIN_MOUNTAIN) {
-					surf->blit(pt, mountain, Rect(0, 0, mountain->get_w(), mountain->get_h()));
+					surf->blit(pt, mountain->surface(), Rect(0, 0, mountain->width(), mountain->height()));
 					pt.x += small_picw + 1;
 				}
 				if (ter_is & TERRAIN_ACID) {
-					surf->blit(pt, dead, Rect(0, 0, dead->get_w(), dead->get_h()));
+					surf->blit(pt, dead->surface(), Rect(0, 0, dead->width(), dead->height()));
 					pt.x += small_picw + 1;
 				}
 				if (ter_is & TERRAIN_UNPASSABLE) {
-					surf->blit(pt, unpassable, Rect(0, 0, unpassable->get_w(), unpassable->get_h()));
+					surf->blit(pt, unpassable->surface(), Rect(0, 0, unpassable->width(), unpassable->height()));
 					pt.x += small_picw + 1;
 				}
 				if (ter_is & TERRAIN_DRY)
-					surf->blit(pt, dry, Rect(0, 0, dry->get_w(), dry->get_h()));
+					surf->blit(pt, dry->surface(), Rect(0, 0, dry->width(), dry->height()));
 			}
-			offscreen_surfaces_.push_back(surf); // Make sure we delete this later on.
+			// Make sure we delete this later on.
+			offscreen_images_.push_back(new_in_memory_image("dummy_hash", surf));
 
-			UI::Checkbox & cb = *new UI::Checkbox(this, pos, surf);
+			UI::Checkbox & cb = *new UI::Checkbox(this, pos, offscreen_images_.back());
 			cb.set_size(TEXTURE_WIDTH + 1, TEXTURE_HEIGHT + 1);
 			cb.set_state(m_tool.is_enabled(i));
 			cb.changedto.connect
@@ -162,9 +163,9 @@
 
 Editor_Tool_Set_Terrain_Options_Menu::~Editor_Tool_Set_Terrain_Options_Menu()
 {
-	BOOST_FOREACH(IPicture* pic, offscreen_surfaces_)
+	BOOST_FOREACH(const Image* pic, offscreen_images_)
 		delete pic;
-	offscreen_surfaces_.clear();
+	offscreen_images_.clear();
 }
 
 void Editor_Tool_Set_Terrain_Options_Menu::selected

=== modified file 'src/editor/ui_menus/editor_tool_set_terrain_options_menu.h'
--- src/editor/ui_menus/editor_tool_set_terrain_options_menu.h	2012-12-02 17:22:14 +0000
+++ src/editor/ui_menus/editor_tool_set_terrain_options_menu.h	2013-02-10 14:53:26 +0000
@@ -41,7 +41,7 @@
 private:
 	// When we are using an offscreen surface, we have to delete it,
 	// when we are closed. So we keep a pointer around.
-	std::vector<IPicture*>  offscreen_surfaces_;
+	std::vector<const Image*>  offscreen_images_;
 	UI::Textarea                m_cur_selection;
 	Editor_Set_Terrain_Tool   & m_tool;
 	void selected(int32_t, bool);

=== modified file 'src/editor/ui_menus/editor_toolsize_menu.cc'
--- src/editor/ui_menus/editor_toolsize_menu.cc	2012-12-13 10:41:22 +0000
+++ src/editor/ui_menus/editor_toolsize_menu.cc	2013-02-10 14:53:26 +0000
@@ -42,15 +42,15 @@
 	m_increase
 		(this, "incr",
 		 80, 25, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_up.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/scrollbar_up.png"),
 		 std::string(),
 		 parent.get_sel_radius() < MAX_TOOL_AREA),
 	m_decrease
 		(this, "decr",
 		 60, 25, 20, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/scrollbar_down.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/scrollbar_down.png"),
 		 std::string(),
 		 0 < parent.get_sel_radius())
 {

=== modified file 'src/graphic/animation.cc'
--- src/graphic/animation.cc	2012-02-15 21:25:34 +0000
+++ src/graphic/animation.cc	2013-02-10 14:53:26 +0000
@@ -44,7 +44,7 @@
 ///
 /// \sa RenderTarget::drawanim
 void AnimationData::trigger_soundfx
-	(uint32_t const framenumber, uint32_t const stereo_position) const
+	(uint32_t framenumber, uint32_t stereo_position) const
 {
 	std::map<uint32_t, std::string>::const_iterator const sfx_cue =
 		sfx_cues.find(framenumber);
@@ -86,14 +86,14 @@
  * The sound effects reside in the given directory and are described by
  * the given section.
  *
- * This function looks for pictures in this order:
+ * This function looks for image files in this order:
  *    key 'pics', if present
  *    picnametempl, if not null
  *    \<sectionname\>_??.bmp
  *
  * \param directory     which directory to look in for image and sound files
  * \param s             conffile section to search for data on this animation
- * \param picnametempl  a template for the picture names
+ * \param picnametempl  a template for the image names
 */
 uint32_t AnimationManager::get
 	(char       const * const directory,
@@ -108,7 +108,7 @@
 	ad.hotspot.y = 0;
 	ad.picnametempl = "";
 
-	// Determine picture name template
+	// Determine image name template
 
 	char templbuf[256];
 	if (char const * const pics = s.get_string("pics"))
@@ -181,16 +181,15 @@
 
 /*
 ===============
-Return AnimationData for this animation.
-Returns 0 if the animation doesn't exist.
+Return AnimationData for this animation or throws if this id is unknown.
 ===============
 */
-AnimationData const * AnimationManager::get_animation(uint32_t const id) const
+const AnimationData& AnimationManager::get_animation(uint32_t id) const
 {
 	if (!id || id > m_animations.size())
-		return 0;
+		throw wexception("Requested unknown animation with id: %i", id);
 
-	return &m_animations[id - 1];
+	return m_animations[id - 1];
 }
 
 

=== modified file 'src/graphic/animation.h'
--- src/graphic/animation.h	2012-02-15 21:25:34 +0000
+++ src/graphic/animation.h	2013-02-10 14:53:26 +0000
@@ -71,7 +71,7 @@
 
 	// for use by the graphics subsystem
 	uint32_t get_nranimations() const;
-	AnimationData const * get_animation(uint32_t id) const;
+	const AnimationData& get_animation(uint32_t id) const;
 
 private:
 	std::vector<AnimationData> m_animations;

=== renamed file 'src/graphic/render/animationgfx.cc' => 'src/graphic/animation_gfx.cc'
--- src/graphic/render/animationgfx.cc	2013-01-25 12:09:49 +0000
+++ src/graphic/animation_gfx.cc	2013-02-10 14:53:26 +0000
@@ -17,41 +17,24 @@
  *
  */
 
-#include "io/fileread.h"
+#include <cassert>
+
+#include <SDL.h>
+
 #include "io/filesystem/layered_filesystem.h"
-#include "io/streamwrite.h"
-
-#include "graphic/graphic.h"
-#include "graphic/image_loader.h"
-#include "graphic/picture.h"
-
 #include "log.h"
-#include "upcast.h"
-
-#include <SDL.h>
-
-/*
-==============================================================================
-
-AnimationGfx -- contains graphics data for an animtion
-
-==============================================================================
-*/
-
-/*
-===============
-AnimationGfx::AnimationGfx
-
-Load the animation
-===============
-*/
+#include "wexception.h"
+
+#include "animation.h"
+#include "animation_gfx.h"
+#include "image.h"
+#include "image_cache.h"
+#include "image_transformations.h"
+
 static const uint32_t nextensions = 2;
 static const char extensions[nextensions][5] = {".png", ".jpg"};
-AnimationGfx::AnimationGfx(const IImageLoader& il, AnimationData const * const data) :
-	m_hotspot(data->hotspot)
-{
-	m_hasplrclrs = data->hasplrclrs;
-
+AnimationGfx::AnimationGfx(const AnimationData& data, ImageCache* image_cache)
+	: m_hotspot(data.hotspot), m_hasplrclrs(data.hasplrclrs), image_cache_(image_cache) {
 	//  In the filename template, the last sequence of '?' characters (if any)
 	//  is replaced with a number, for example the template "idle_??" is
 	//  replaced with "idle_00". Then the code looks if there is a file with
@@ -62,18 +45,18 @@
 	//  animation.
 
 	//  Allocate a buffer for the filename. It must be large enough to hold the
-	//  picture name template, the "_pc" (3 characters) part for playercolor
+	//  image name template, the "_pc" (3 characters) part for playercolor
 	//  masks, the extension (4 characters including the dot) and the null
-	//  terminator. Copy the picture name template into the buffer.
+	//  terminator. Copy the image name template into the buffer.
 	char filename[256];
-	std::string::size_type const picnametempl_size = data->picnametempl.size();
+	std::string::size_type const picnametempl_size = data.picnametempl.size();
 	if (sizeof(filename) < picnametempl_size + 3 + 4 + 1)
 		throw wexception
-			("buffer too small (%lu) for picture name temlplate of size %lu\n",
+			("buffer too small (%lu) for image name template of size %lu\n",
 			 static_cast<long unsigned>(sizeof(filename)), static_cast<long unsigned>(picnametempl_size));
-	strcpy(filename, data->picnametempl.c_str());
+	strcpy(filename, data.picnametempl.c_str());
 
-	//  Find out where in the picture name template the number is. Search
+	//  Find out where in the image name template the number is. Search
 	//  backwards from the end.
 	char * const after_basename = filename + picnametempl_size;
 	char * last_digit = after_basename;
@@ -85,13 +68,6 @@
 		--before_first_digit;
 	}
 	unsigned int width = 0, height = 0;
-#ifndef NDEBUG
-	//#define VALIDATE_ANIMATION_CROPPING
-#endif
-#ifdef VALIDATE_ANIMATION_CROPPING
-	bool data_in_x_min = false, data_in_x_max = false;
-	bool data_in_y_min = false, data_in_y_max = false;
-#endif
 
 	for (;;) {
 		// Load the base image
@@ -99,67 +75,17 @@
 			strcpy(after_basename, extensions[extnr]);
 			if (g_fs->FileExists(filename)) { //  Is the frame actually there?
 				try {
-					IPicture* pic = il.load(filename, true);
+					const Image* image = image_cache->get(filename);
 					if (width == 0) { //  This is the first frame.
-						width  = pic->get_w();
-						height = pic->get_h();
-					} else if (width != pic->get_w() or height != pic->get_h())
+						width  = image->width();
+						height = image->height();
+					} else if (width != image->width() or height != image->height())
 						throw wexception
 							("wrong size: (%u, %u), should be (%u, %u) like the "
 							 "first frame",
-							 pic->get_w(), pic->get_h(), width, height);
+							 image->width(), image->height(), width, height);
 					//  Get a new AnimFrame.
-					m_plrframes[0].push_back(pic);
-#ifdef VALIDATE_ANIMATION_CROPPING
-					if (not data_in_x_min)
-						for (int y = 0; y < height; ++y) {
-							uint8_t r, g, b, a;
-							SDL_GetRGBA
-								(frame.get_pixel(0,         y),
-								 surface.format,
-								 &r, &g, &b, &a);
-							if (a) {
-								data_in_x_min = true;
-								break;
-							}
-						}
-					if (not data_in_x_max)
-						for (int y = 0; y < height; ++y) {
-							uint8_t r, g, b, a;
-							SDL_GetRGBA
-								(frame.get_pixel(width - 1, y),
-								 surface.format,
-								 &r, &g, &b, &a);
-							if (a) {
-								data_in_x_max = true;
-								break;
-							}
-						}
-					if (not data_in_y_min)
-						for (int x = 0; x < width; ++x) {
-							uint8_t r, g, b, a;
-							SDL_GetRGBA
-								(frame.get_pixel(x,         0),
-								 surface.format,
-								 &r, &g, &b, &a);
-							if (a) {
-								data_in_y_min = true;
-								break;
-							}
-						}
-					if (not data_in_y_max)
-						for (int x = 0; x < width; ++x) {
-							uint8_t r, g, b, a;
-							SDL_GetRGBA
-								(frame.get_pixel(x,         height - 1),
-								 surface.format,
-								 &r, &g, &b, &a);
-							if (a) {
-								data_in_y_max = true;
-								break;
-							}
-						}
-#endif
+					m_frames.push_back(image);
 				} catch (std::exception const & e) {
 					throw wexception
 						("could not load animation frame %s: %s\n",
@@ -179,13 +105,13 @@
 				strcpy(after_basename + 3, extensions[extnr]);
 				if (g_fs->FileExists(filename)) {
 					try {
-						IPicture* picture = il.load(filename, true);
-						if (width != picture->get_w() or height != picture->get_h())
+						const Image* image = image_cache->get(filename);
+						if (width != image->width() or height != image->height())
 							throw wexception
 								("playercolor mask has wrong size: (%u, %u), should "
 								 "be (%u, %u) like the animation frame",
-								 picture->get_w(), picture->get_h(), width, height);
-						m_pcmasks.push_back(picture);
+								 image->width(), image->height(), width, height);
+						m_pcmasks.push_back(image);
 						break;
 					} catch (std::exception const & e) {
 						throw wexception
@@ -203,7 +129,7 @@
 			if (digit_to_increment == before_first_digit)
 				goto end; //  The number wrapped around to all zeros.
 			assert('0' <= *digit_to_increment);
-			assert        (*digit_to_increment <= '9');
+			assert(*digit_to_increment <= '9');
 			if (*digit_to_increment == '9') {
 				*digit_to_increment = '0';
 				--digit_to_increment;
@@ -214,111 +140,31 @@
 		}
 	}
 end:
-	if (m_plrframes[0].empty())
+	if (m_frames.empty())
 		throw wexception
-			("animation %s has no frames", data->picnametempl.c_str());
+			("animation %s has no frames", data.picnametempl.c_str());
 
-	if (m_pcmasks.size() and m_pcmasks.size() < m_plrframes[0].size())
+	if (m_pcmasks.size() and m_pcmasks.size() < m_frames.size())
 		throw wexception
 			("animation has %"PRIuS" frames but playercolor mask has only %"PRIuS" frames",
-			 m_plrframes[0].size(), m_pcmasks.size());
-#ifdef VALIDATE_ANIMATION_CROPPING
-	if
-		(char const * const where =
-		 	not data_in_x_min ? "left column"  :
-		 	not data_in_x_max ? "right column" :
-		 	not data_in_y_min ? "top row"      :
-		 	not data_in_y_max ? "bottom row"   :
-		 	0)
-		log
-			("The animation %s is not properly cropped (the %s has only fully "
-			 "transparent pixels in each frame. Therefore the %s should be "
-			 "removed (and the hotspot adjusted accordingly). Otherwise "
-			 "rendering will be slowed down by needless painting of fully "
-			 "transparent pixels.\n",
-			 data->picnametempl.c_str(), where, where);
-#endif
-}
-
-
-AnimationGfx::~AnimationGfx()
-{
-}
-
-
-/*
-===============
-Encodes the given surface into a frame
-===============
-*/
-void AnimationGfx::encode(uint8_t const plr, const RGBColor & player_color)
-{
-	assert(m_plrframes[0].size() == m_pcmasks.size());
-	std::vector<IPicture* > & frames = m_plrframes[plr];
-
-	for (uint32_t i = 0; i < m_plrframes[0].size(); ++i) {
-		//  Copy the old surface.
-		IPicture* origpic = m_plrframes[0][i];
-		uint32_t w = origpic->get_w();
-		uint32_t h = origpic->get_h();
-		upcast(Surface, orig_surface, m_plrframes[0][i]);
-		upcast(Surface, pcmask_surface, m_pcmasks[i]);
-
-		Surface* new_surface = g_gr->create_surface(w, h, true);
-
-		const SDL_PixelFormat & fmt = orig_surface->format();
-		const SDL_PixelFormat & fmt_pc = pcmask_surface->format();
-		const SDL_PixelFormat & destfmt = new_surface->format();
-
-		orig_surface->lock(Surface::Lock_Normal);
-		pcmask_surface->lock(Surface::Lock_Normal);
-		new_surface->lock(Surface::Lock_Discard);
-		// This could be done significantly faster, but since we
-		// cache the result, let's keep it simple for now.
-		for (uint32_t y = 0; y < h; ++y) {
-			for (uint32_t x = 0; x < w; ++x) {
-				RGBAColor source;
-				RGBAColor mask;
-				RGBAColor product;
-
-				source.set(fmt, orig_surface->get_pixel(x, y));
-				mask.set(fmt_pc, pcmask_surface->get_pixel(x, y));
-
-				if
-					(uint32_t const influence =
-					 	static_cast<uint32_t>(mask.r) * mask.a)
-				{
-					uint32_t const intensity =
-						(luminance_table_r[source.r] +
-						 luminance_table_g[source.g] +
-						 luminance_table_b[source.b] +
-						 8388608U) //  compensate for truncation:  .5 * 2^24
-						>> 24;
-					RGBAColor plrclr;
-
-					plrclr.r = (player_color.r * intensity) >> 8;
-					plrclr.g = (player_color.g * intensity) >> 8;
-					plrclr.b = (player_color.b * intensity) >> 8;
-
-					product.r =
-						(plrclr.r * influence + source.r * (65536 - influence)) >> 16;
-					product.g =
-						(plrclr.g * influence + source.g * (65536 - influence)) >> 16;
-					product.b =
-						(plrclr.b * influence + source.b * (65536 - influence)) >> 16;
-					product.a = source.a;
-				} else {
-					product = source;
-				}
-
-				new_surface->set_pixel(x, y, product.map(destfmt));
-			}
-		}
-		orig_surface->unlock(Surface::Unlock_NoChange);
-		pcmask_surface->unlock(Surface::Unlock_NoChange);
-		new_surface->unlock(Surface::Unlock_Update);
-
-		frames.push_back(new_surface);
-	}
-}
+			 m_frames.size(), m_pcmasks.size());
+}
+
+const Image& AnimationGfx::get_frame(size_t i, const RGBColor& playercolor) {
+	assert(i < nr_frames());
+
+	const Image& original = get_frame(i);
+	if (!m_hasplrclrs)
+		return original;
+
+	assert(m_frames.size() == m_pcmasks.size());
+
+	return *ImageTransformations::player_colored(playercolor, &original, m_pcmasks[i]);
+}
+
+const Image& AnimationGfx::get_frame(size_t i) const {
+	assert(i < nr_frames());
+	return *m_frames[i];
+}
+
 

=== modified file 'src/graphic/animation_gfx.h'
--- src/graphic/animation_gfx.h	2012-12-13 21:10:32 +0000
+++ src/graphic/animation_gfx.h	2013-02-10 14:53:26 +0000
@@ -20,54 +20,29 @@
 #ifndef ANIMATION_GFX_H
 #define ANIMATION_GFX_H
 
-class IImageLoader;
-class IPicture;
-
-#include "animation.h"
-#include "logic/widelands.h"
-#include "rgbcolor.h"
+#include <vector>
+
+#include "point.h"
+
+class AnimationData;
+class Image;
+class ImageCache;
+struct RGBColor;
 
 struct AnimationGfx { /// The graphics belonging to an animation.
-	AnimationGfx(const IImageLoader&, AnimationData const * data);
-	~AnimationGfx();
-
-	const Point get_hotspot() const throw () {return m_hotspot;}
-	typedef std::vector<IPicture* > Frames;
-	typedef Frames::size_type Index;
-	Index nr_frames() const
-	{
-		assert((*m_plrframes)[0]); return m_plrframes[0].size();
-	}
-
-	const IPicture* get_frame
-		(Index                    const i,
-		 Widelands::Player_Number const player_number,
-		 const RGBColor & playercolor)
-	{
-		assert(i < nr_frames());
-		assert(1 <= player_number);
-		assert     (player_number <= MAX_PLAYERS);
-		if (!m_hasplrclrs)
-			return get_frame(i);
-
-		// Encode for this player
-		if (not m_plrframes[player_number].size())
-			encode(player_number, playercolor);
-		return m_plrframes[player_number][i];
-	}
-
-	const IPicture* get_frame(Index const i) const {
-		assert(i < nr_frames());
-		return m_plrframes[0][i];
-	}
+	AnimationGfx(const AnimationData& data, ImageCache*);
+
+	size_t nr_frames() const {return m_frames.size();}
+	const Point& hotspot() const throw () {return m_hotspot;}
+	const Image& get_frame(size_t i, const RGBColor& playercolor);
+	const Image& get_frame(size_t i) const;
 
 private:
-	void encode(uint8_t plyr, const RGBColor &);
-
-	Frames m_plrframes[MAX_PLAYERS + 1];
-	Frames m_pcmasks;
+	std::vector<const Image*> m_frames;
+	std::vector<const Image*> m_pcmasks;
+	Point m_hotspot;
 	bool m_hasplrclrs;
-	Point m_hotspot;
+	ImageCache* const image_cache_; // Not owned.
 };
 
 #endif

=== modified file 'src/graphic/font_handler.cc'
--- src/graphic/font_handler.cc	2012-12-18 18:41:45 +0000
+++ src/graphic/font_handler.cc	2013-02-10 14:53:26 +0000
@@ -26,6 +26,8 @@
 #include "graphic.h"
 #include "log.h"
 #include "rendertarget.h"
+#include "surface.h"
+#include "in_memory_image.h"
 #include "wexception.h"
 #include "wordwrap.h"
 
@@ -46,7 +48,7 @@
 	/*@}*/
 
 	/*@{*/
-	IPicture* picture;
+	const Image* image;
 	uint32_t width;
 	uint32_t height;
 	/*@}*/
@@ -115,21 +117,23 @@
 		return *it;
 	}
 
-	// Cache miss; render a new picture
+	// Cache miss; render a new image.
 	LineCache::iterator it = linecache.insert(linecache.begin(), LineCacheEntry());
 	it->style = style;
 	it->text = text;
-	it->picture = 0;
+	it->image = NULL;
 	render_line(*it);
 
-	while (linecache.size() > MaxLineCacheSize)
+	while (linecache.size() > MaxLineCacheSize) {
+		delete linecache.back().image;
 		linecache.pop_back();
+	}
 
 	return *it;
 }
 
 /**
- * Render the picture of a \ref LineCacheEntry whose key data has
+ * Render the image of a \ref LineCacheEntry whose key data has
  * already been filled in.
  */
 void Font_Handler::Data::render_line(LineCacheEntry & lce)
@@ -148,7 +152,7 @@
 
 	lce.style.setup();
 
-	SDL_Surface * text_surface = TTF_RenderUTF8_Blended(font, lce.text.c_str(), sdl_fg);
+	SDL_Surface* text_surface = TTF_RenderUTF8_Blended(font, lce.text.c_str(), sdl_fg);
 	if (!text_surface) {
 		log
 			("Font_Handler::render_line, an error : %s\n",
@@ -157,9 +161,9 @@
 		return;
 	}
 
-	lce.picture = g_gr->convert_sdl_surface_to_picture(text_surface, true);
-	lce.width = lce.picture->get_w();
-	lce.height = lce.picture->get_h();
+	lce.image = new_in_memory_image("dummy_hash", Surface::create(text_surface));
+	lce.width = lce.image->width();
+	lce.height = lce.image->height();
 }
 
 /**
@@ -175,10 +179,10 @@
 {
 	const LineCacheEntry & lce = d->get_line(style, text);
 
-	do_align(align, dstpoint.x, dstpoint.y, lce.width + 2 * LINE_MARGIN, lce.height);
+	UI::correct_for_align(align, lce.width + 2 * LINE_MARGIN, lce.height, &dstpoint);
 
-	if (lce.picture)
-		dst.blit(Point(dstpoint.x + LINE_MARGIN, dstpoint.y), lce.picture);
+	if (lce.image)
+		dst.blit(Point(dstpoint.x + LINE_MARGIN, dstpoint.y), lce.image);
 
 	if (caret <= text.size())
 		draw_caret(dst, style, dstpoint, text, caret);
@@ -214,8 +218,8 @@
 {
 	const LineCacheEntry & lce = d->get_line(style, text);
 
-	if (lce.picture)
-		dst.blit(dstpoint, lce.picture);
+	if (lce.image)
+		dst.blit(dstpoint, lce.image);
 
 	return lce.width;
 }
@@ -235,36 +239,12 @@
 
 	int caret_x = style.calc_bare_width(sub);
 
-	const IPicture* caretpic = g_gr->imgcache().load(PicMod_UI, "pics/caret.png");
+	const Image* caret_image = g_gr->images().get("pics/caret.png");
 	Point caretpt;
-	caretpt.x = dstpoint.x + caret_x + LINE_MARGIN - caretpic->get_w();
-	caretpt.y = dstpoint.y + (style.font->height() - caretpic->get_h()) / 2;
-
-	dst.blit(caretpt, caretpic);
-}
-
-
-//Sets dstx and dsty to values for a specified align
-void Font_Handler::do_align
-	(Align const align,
-	 int32_t & dstx, int32_t & dsty,
-	 int32_t const w, int32_t const h)
-{
-	//Vertical Align
-	if (align & (Align_VCenter | Align_Bottom)) {
-		if (align & Align_VCenter)
-			dsty -= (h + 1) / 2; //  +1 for slight bias to top
-		else
-			dsty -= h;
-	}
-
-	//Horizontal Align
-	if ((align & Align_Horizontal) != Align_Left) {
-		if (align & Align_HCenter)
-			dstx -= w / 2;
-		else if (align & Align_Right)
-			dstx -= w;
-	}
+	caretpt.x = dstpoint.x + caret_x + LINE_MARGIN - caret_image->width();
+	caretpt.y = dstpoint.y + (style.font->height() - caret_image->height()) / 2;
+
+	dst.blit(caretpt, caret_image);
 }
 
 /**

=== modified file 'src/graphic/font_handler.h'
--- src/graphic/font_handler.h	2012-12-31 11:21:15 +0000
+++ src/graphic/font_handler.h	2013-02-10 14:53:26 +0000
@@ -23,7 +23,7 @@
 #include <boost/scoped_ptr.hpp>
 
 #include "point.h"
-#include "ui_basic/align.h"
+#include "align.h"
 
 class RenderTarget;
 

=== modified file 'src/graphic/font_handler1.cc'
--- src/graphic/font_handler1.cc	2012-12-17 20:01:04 +0000
+++ src/graphic/font_handler1.cc	2013-02-10 14:53:26 +0000
@@ -17,14 +17,18 @@
  *
  */
 
+#include <boost/lexical_cast.hpp>
 #include <boost/utility.hpp>
 
 #include "io/filesystem/filesystem.h"
 #include "wexception.h"
 
 #include "graphic.h"
-#include "picture.h"
+#include "image.h"
+#include "image_cache.h"
 #include "rendertarget.h"
+#include "surface.h"
+#include "surface_cache.h"
 #include "text/rt_errors.h"
 #include "text/rt_render.h"
 #include "text/sdl_ttf_font.h"
@@ -34,65 +38,86 @@
 using namespace std;
 using namespace boost;
 
+namespace {
+
+// An Image implementation that recreates a rich text surface when needed on
+// the fly. It is meant to be saved into the ImageCache.
+class RTImage : public Image {
+public:
+	RTImage
+		(const string& hash, SurfaceCache* surface_cache, RT::IRenderer*
+		 rt_renderer, const string& text, uint16_t width)
+		: hash_(hash),
+		surface_cache_(surface_cache),
+		  rt_renderer_(rt_renderer),
+		  text_(text), width_(width)
+	{}
+	virtual ~RTImage() {}
+
+	// Implements Image.
+	virtual uint16_t width() const {return surface()->width();}
+	virtual uint16_t height() const {return surface()->height();}
+	virtual const string& hash() const {return hash_;}
+	virtual Surface* surface() const {
+		Surface* surf = surface_cache_->get(hash_);
+		if (surf)
+			return surf;
+
+		try {
+			surf = rt_renderer_->render(text_, width_);
+			surface_cache_->insert(hash_, surf);
+		} catch (RT::Exception& e) {
+			throw wexception("Richtext rendering error: %s", e.what());
+		}
+		return surf;
+	}
+
+private:
+	const string hash_;
+	const string text_;
+	uint16_t width_;
+
+	// Nothing owned.
+	SurfaceCache* const surface_cache_;
+	RT::IRenderer* const rt_renderer_;
+};
+
+}
+
 namespace UI {
 
+// Utility class to render a rich text string. The returned string is cached in
+// the ImageCache, so repeated calls to render with the same arguments should not
+// be a problem.
 class Font_Handler1 : public IFont_Handler1 {
 public:
-	Font_Handler1(IGraphic& gr, FileSystem* fs);
-	virtual ~Font_Handler1();
-
-	void draw_text
-		(RenderTarget & dst,
-		 Point dstpoint,
-		 const std::string & text,
-		 uint32_t = 0,
-		 Align = Align_TopLeft);
-
-	const IPicture* render(const string& text, uint32_t w = 0);
+	Font_Handler1(ImageCache* image_cache, SurfaceCache* surface_cache, RT::IRenderer* renderer) :
+		surface_cache_(surface_cache), image_cache_(image_cache), renderer_(renderer) {};
+	virtual ~Font_Handler1() {}
+
+	const Image* render(const string& text, uint16_t w = 0) {
+		const string hash = boost::lexical_cast<string>(w) + text;
+
+		if (image_cache_->has(hash))
+			return image_cache_->get(hash);
+
+		return image_cache_->insert(new RTImage(hash, surface_cache_, renderer_.get(), text, w));
+	}
 
 private:
+	SurfaceCache* const surface_cache_;  // not owned
+	ImageCache* const image_cache_;  // not owned
 	boost::scoped_ptr<RT::IRenderer> renderer_;
 };
 
-Font_Handler1::Font_Handler1(IGraphic& gr, FileSystem* fs) {
-	RT::IFontLoader * floader = RT::ttf_fontloader_from_filesystem(fs);
-	renderer_.reset(RT::setup_renderer(gr, floader));
-}
-Font_Handler1::~Font_Handler1() {
-}
-
-const IPicture* Font_Handler1::render(const string& text, uint32_t w) {
-	const IPicture* p = 0;
-	try {
-		p = renderer_->render(text, w);
-	} catch (RT::Exception& e) {
-		throw wexception("Richtext rendering error: %s", e.what());
-	}
-	return p;
-}
-
-void Font_Handler1::draw_text
-		(RenderTarget & dst, Point dstpoint, const std::string & text, uint32_t w, Align align)
-{
-	if (text.empty())
-		return;
-
-	const IPicture* p = render(text, w);
-	if (!p)
-		return;
-
-	if (align & Align_HCenter) dstpoint.x -= p->get_w() / 2;
-	else if (align & Align_Right) dstpoint.x -= p->get_w();
-	if (align & Align_VCenter) dstpoint.y -= p->get_h() / 2;
-	else if (align & Align_Bottom) dstpoint.y -= p->get_h();
-
-	dst.blit(Point(dstpoint.x, dstpoint.y), p);
-}
-
-IFont_Handler1 * create_fonthandler(IGraphic& gr, FileSystem* lfs) {
-	return new Font_Handler1(gr, lfs);
+IFont_Handler1 * create_fonthandler(Graphic* gr, FileSystem* fs) {
+	return
+		new Font_Handler1
+		(&gr->images(), &gr->surfaces(),
+		 RT::setup_renderer
+		 (&gr->images(), &gr->surfaces(), RT::ttf_fontloader_from_filesystem(fs)));
 }
 
 IFont_Handler1 * g_fh1 = 0;
 
-} // namespace UIae
+} // namespace UI

=== modified file 'src/graphic/font_handler1.h'
--- src/graphic/font_handler1.h	2013-01-08 17:05:51 +0000
+++ src/graphic/font_handler1.h	2013-02-10 14:53:26 +0000
@@ -25,14 +25,11 @@
 #include <boost/noncopyable.hpp>
 
 #include "point.h"
-
-#include "ui_basic/align.h"
-
-class RenderTarget;
+#include "align.h"
+
 class FileSystem;
-
-class IPicture;
-class IGraphic;
+class Image;
+class Graphic;
 
 namespace UI {
 
@@ -43,22 +40,15 @@
 public:
 	virtual ~IFont_Handler1() {};
 
-	virtual void draw_text
-		(RenderTarget &,
-		 Point dstpoint,
-		 const std::string & text,
-		 uint32_t w = 0,
-		 Align = Align_TopLeft) = 0;
-
 	/*
-	 * Renders the given text into an image. Will return NULL on error or if the
-	 * resulting image would have no size. The image is cached and therefore
-	 * ownership remains with this class.
+	 * Renders the given text into an image. The image is cached and therefore
+	 * ownership remains with this class. Will throw on error.
 	 */
-	virtual const IPicture* render(const std::string& text, uint32_t w = 0) = 0;
+	virtual const Image* render(const std::string& text, uint16_t w = 0) = 0;
 };
 
-IFont_Handler1 * create_fonthandler(IGraphic& gr, FileSystem* lfs);
+// Create a new Font_Handler1. Ownership for the objects is not taken.
+IFont_Handler1 * create_fonthandler(Graphic* gr, FileSystem* fs);
 
 extern IFont_Handler1 * g_fh1;
 

=== modified file 'src/graphic/graphic.cc'
--- src/graphic/graphic.cc	2013-01-05 20:11:57 +0000
+++ src/graphic/graphic.cc	2013-02-10 14:53:26 +0000
@@ -17,81 +17,46 @@
  *
  */
 
+#include <cstring>
+#include <iostream>
+
+#include <SDL_image.h>
+#include <config.h>
+
+#include "build_info.h"
 #include "compile_diagnostics.h"
-#include "graphic.h"
-
-#include "build_info.h"
+#include "constants.h"
 #include "container_iterate.h"
 #include "diranimations.h"
 #include "i18n.h"
-#include "log.h"
-#include "upcast.h"
-#include "wexception.h"
-
 #include "io/fileread.h"
 #include "io/filesystem/layered_filesystem.h"
 #include "io/streamwrite.h"
-
-#include "font_handler.h"
-#include "image_loader.h"
-#include "picture.h"
-#include "rendertarget.h"
-#include "texture.h"
-
-#include "render/gl_surface_screen.h"
-#include "render/sdl_surface.h"
-
+#include "log.h"
 #include "logic/roadtype.h"
 #include "logic/widelands_fileread.h"
-
+#include "surface_cache.h"
 #include "ui_basic/progresswindow.h"
-
-#include <config.h>
-
-#include <SDL_image.h>
-#include <SDL_rotozoom.h>
-
-#include <cstring>
-#include <iostream>
+#include "upcast.h"
+#include "wexception.h"
+
+#include "animation.h"
+#include "animation_gfx.h"
+#include "image.h"
+#include "image_loader_impl.h"
+#include "image_transformations.h"
+#include "render/gl_surface_screen.h"
+#include "render/sdl_surface.h"
+#include "rendertarget.h"
+#include "texture.h"
+
+#include "graphic.h"
 
 using namespace std;
 
 Graphic * g_gr;
 bool g_opengl;
 
-// This table is used by create_grayed_out_pic()
-// to map colors to grayscle
-uint32_t luminance_table_r[0x100];
-uint32_t luminance_table_g[0x100];
-uint32_t luminance_table_b[0x100];
-
-// Helper stuff {{{
-namespace {
-class ImageLoader : public IImageLoader {
-public:
-	ImageLoader(Graphic& gr) : gr_(gr) {}
-	virtual ~ImageLoader() {}
-
-	IPicture* load(const string& fname, bool alpha) const {
-		FileRead fr;
-		SDL_Surface * sdlsurf;
-
-		//fastOpen tries to use mmap
-		fr.fastOpen(*g_fs, fname.c_str());
-
-		sdlsurf = IMG_Load_RW(SDL_RWFromMem(fr.Data(0), fr.GetSize()), 1);
-
-		if (!sdlsurf)
-			throw wexception("%s", IMG_GetError());
-
-		return gr_.convert_sdl_surface_to_picture(sdlsurf, alpha);
-	}
-private:
-	Graphic& gr_;
-};
-}  // namespace
-// End: Helper stuff }}}
-
 /**
  * Initialize the SDL video mode.
 */
@@ -104,21 +69,11 @@
 	m_rendertarget     (0),
 	m_nr_update_rects  (0),
 	m_update_fullscreen(true),
-	m_roadtextures     (0),
-	img_loader_(new ImageLoader(*this)),
-	img_cache_(create_image_cache(img_loader_.get()))
+	image_loader_(new ImageLoaderImpl()),
+	surface_cache_(create_surface_cache(SURFACE_CACHE_SIZE)),
+	image_cache_(create_image_cache(image_loader_.get(), surface_cache_.get()))
 {
-	// Initialize the table used to create grayed pictures
-	for
-		(uint32_t i = 0, r = 0, g = 0, b = 0;
-		 i < 0x100;
-		 ++i, r += 5016388U, g += 9848226U, b += 1912603U)
-	{
-		luminance_table_r[i] = r;
-		luminance_table_g[i] = g;
-		luminance_table_b[i] = b;
-	}
-
+	ImageTransformations::initialize();
 
 	//fastOpen tries to use mmap
 	FileRead fr;
@@ -332,7 +287,7 @@
 	else
 #endif
 	{
-		screen_.reset(new SDLSurface(*sdlsurface));
+		screen_.reset(new SDLSurface(sdlsurface));
 	}
 
 	m_sdl_screen = sdlsurface;
@@ -345,7 +300,6 @@
 Graphic::~Graphic()
 {
 	delete m_rendertarget;
-	delete m_roadtextures;
 
 #if USE_OPENGL
 	if (g_opengl)
@@ -358,7 +312,7 @@
 */
 int32_t Graphic::get_xres() const
 {
-	return screen_->get_w();
+	return screen_->width();
 }
 
 /**
@@ -366,7 +320,7 @@
 */
 int32_t Graphic::get_yres() const
 {
-	return screen_->get_h();
+	return screen_->height();
 }
 
 /**
@@ -384,8 +338,14 @@
 */
 void Graphic::toggle_fullscreen()
 {
-	log("Try DL_WM_ToggleFullScreen...\n");
-	//ToDo Make this work again
+	log("Try SDL_WM_ToggleFullScreen...\n");
+	// TODO: implement proper fullscreening here. The way it can work is to
+	// recreate SurfaceCache but keeping ImageCache around. Then exiting and
+	// reinitalizing the SDL Video Mode should just work: all surface are
+	// recreated dynamically and correctly.
+	// Note: Not all Images are cached in the ImageCache, at time of me writing
+	// this, only InMemoryImage does not safe itself in the ImageCache. And this
+	// should only be a problem for Images loaded from maps.
 	SDL_WM_ToggleFullScreen(m_sdl_screen);
 }
 
@@ -458,117 +418,15 @@
 }
 
 /**
- * Produces a resized version of the specified picture
- *
- * Might return same id if dimensions are the same
- */
-const IPicture* Graphic::get_resized_picture(const IPicture* src, uint32_t w, uint32_t h) {
-	if (src->get_w() == w and src->get_h() == h) {
-		return src;
-	}
-
-	// First step: compute scaling factors
-	Rect srcrect = Rect(Point(0, 0), src->get_w(), src->get_h());
-
-	// Second step: get source material
-	SDL_Surface * srcsdl = 0;
-	bool free_source = true;
-
-	if (upcast(const SDLSurface, srcsurf, src)) {
-		srcsdl = srcsurf->get_sdl_surface();
-		free_source = false;
-	} else {
-		// I guess this is just in OpenGL
-		srcsdl = extract_sdl_surface
-			(*static_cast<Surface*>(const_cast<IPicture*>(src)), srcrect);
-	}
-
-	// Third step: perform the zoom and placement
-	SDL_Surface * zoomed = zoomSurface
-		(srcsdl, double(w) / srcsdl->w, double(h) / srcsdl->h, 1);
-	if (free_source)
-		SDL_FreeSurface(srcsdl);
-
-	if (uint32_t(zoomed->w) != w || uint32_t(zoomed->h) != h) {
-		const SDL_PixelFormat & fmt = *zoomed->format;
-		SDL_Surface * placed = SDL_CreateRGBSurface
-			(SDL_SWSURFACE, w, h,
-			 fmt.BitsPerPixel, fmt.Rmask, fmt.Gmask, fmt.Bmask, fmt.Amask);
-		SDL_Rect srcrc =
-			{0, 0,
-			 static_cast<Uint16>(zoomed->w), static_cast<Uint16>(zoomed->h)
-			};  // For some reason SDL_Surface and SDL_Rect express w,h in different types
-		SDL_Rect dstrc = {0, 0, 0, 0};
-		SDL_SetAlpha(zoomed, 0, 0);
-		SDL_BlitSurface(zoomed, &srcrc, placed, &dstrc); // Updates dstrc
-
-		Uint32 fillcolor = SDL_MapRGBA(zoomed->format, 0, 0, 0, 255);
-
-		if (zoomed->w < placed->w) {
-			dstrc.x = zoomed->w;
-			dstrc.y = 0;
-			dstrc.w = placed->w - zoomed->w;
-			dstrc.h = zoomed->h;
-			SDL_FillRect(placed, &dstrc, fillcolor);
-		}
-		if (zoomed->h < placed->h) {
-			dstrc.x = 0;
-			dstrc.y = zoomed->h;
-			dstrc.w = placed->w;
-			dstrc.h = placed->h - zoomed->h;
-			SDL_FillRect(placed, &dstrc, fillcolor);
-		}
-
-		SDL_FreeSurface(zoomed);
-		zoomed = placed;
-	}
-
-	return convert_sdl_surface_to_picture(zoomed);
-}
-
-/**
- * Create and return an \ref SDL_Surface that contains the given sub-rectangle
- * of the given pixel region.
- */
-SDL_Surface * Graphic::extract_sdl_surface(Surface & surf, Rect srcrect) const
-{
-	assert(srcrect.x >= 0);
-	assert(srcrect.y >= 0);
-	assert(srcrect.x + srcrect.w <= surf.get_w());
-	assert(srcrect.y + srcrect.h <= surf.get_h());
-
-	const SDL_PixelFormat & fmt = surf.format();
-	SDL_Surface * dest = SDL_CreateRGBSurface
-		(SDL_SWSURFACE, srcrect.w, srcrect.h,
-		 fmt.BitsPerPixel, fmt.Rmask, fmt.Gmask, fmt.Bmask, fmt.Amask);
-
-	surf.lock(Surface::Lock_Normal);
-	SDL_LockSurface(dest);
-
-	uint32_t srcpitch = surf.get_pitch();
-	uint32_t rowsize = srcrect.w * fmt.BytesPerPixel;
-	uint8_t * srcpix = surf.get_pixels() + srcpitch * srcrect.y + fmt.BytesPerPixel * srcrect.x;
-	uint8_t * dstpix = static_cast<uint8_t *>(dest->pixels);
-
-	for (uint32_t y = 0; y < srcrect.h; ++y) {
-		memcpy(dstpix, srcpix, rowsize);
-		srcpix += srcpitch;
-		dstpix += dest->pitch;
-	}
-
-	SDL_UnlockSurface(dest);
-	surf.unlock(Surface::Unlock_NoChange);
-
-	return dest;
-}
-
-/**
  * Saves a pixel region to a png. This can be a file or part of a stream.
  *
  * @param surf The Surface to save
  * @param sw a StreamWrite where the png is written to
  */
-void Graphic::save_png(const IPicture* pic, StreamWrite * sw) const
+void Graphic::save_png(const Image* image, StreamWrite * sw) const {
+	save_png_(*image->surface(), sw);
+}
+void Graphic::save_png_(Surface & surf, StreamWrite * sw) const
 {
 	// Save a png
 	png_structp png_ptr =
@@ -601,19 +459,17 @@
 		 sw,
 		 &Graphic::m_png_write_function, &Graphic::m_png_flush_function);
 
-	Surface& surf = *static_cast<Surface*>(const_cast<IPicture*>(pic));
-
 	// Fill info struct
 	png_set_IHDR
-		(png_ptr, info_ptr, surf.get_w(), surf.get_h(),
+		(png_ptr, info_ptr, surf.width(), surf.height(),
 		 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
 		 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
 
 	// Start writing
 	png_write_info(png_ptr, info_ptr);
 	{
-		uint32_t surf_w = surf.get_w();
-		uint32_t surf_h = surf.get_h();
+		uint16_t surf_w = surf.width();
+		uint16_t surf_h = surf.height();
 		uint32_t row_size = 4 * surf_w;
 
 		boost::scoped_array<png_byte> row(new png_byte[row_size]);
@@ -644,161 +500,6 @@
 	png_destroy_write_struct(&png_ptr, &info_ptr);
 }
 
-/**
- * Create a Picture from an SDL_Surface.
- *
- * @param surf a SDL_Surface from which the Surface will be created; this function
- * takes ownership of surf
- * @param alpha if true the surface is created with alpha channel
- * @return the new Surface created from the SDL_Surface
- */
-IPicture* Graphic::convert_sdl_surface_to_picture(SDL_Surface * surf, bool alpha) const
-{
-#ifdef USE_OPENGL
-	if (g_opengl) {
-		return new GLSurfaceTexture(surf);
-	}
-#endif
-	SDL_Surface * surface;
-	if (alpha)
-		surface = SDL_DisplayFormatAlpha(surf);
-	else
-		surface = SDL_DisplayFormat(surf);
-	SDL_FreeSurface(surf);
-	return new SDLSurface(*surface);
-}
-
-/**
- * Create an surface of specified size. The surface in not blanked and will be random.
- *
- * \note Handle surfaces with an alpha channel carefully, since SDL does not
- * support to blit two surfaces with alpha channel on top of each other. The
- * results when trying are rather funny at times and tend to crash.
- *
- * @param w width of the new surface
- * @param h height of the new surface
- * @return the new created surface
- */
-Surface* Graphic::create_surface(int32_t w, int32_t h, bool alpha) const
-{
-#ifdef USE_OPENGL
-	if (g_opengl)
-	{
-		return new GLSurfaceTexture(w, h, alpha);
-	}
-	else
-#endif
-	{
-		const SDL_PixelFormat & format = *m_sdl_screen->format;
-		SDL_Surface & tsurf = *SDL_CreateRGBSurface
-			(SDL_SWSURFACE,
-			 w, h,
-			 format.BitsPerPixel,
-			 format.Rmask, format.Gmask, format.Bmask, format.Amask);
-		if (alpha) {
-			SDL_Surface & surf = *SDL_DisplayFormatAlpha(&tsurf);
-			SDL_FreeSurface(&tsurf);
-			return new SDLSurface(surf);
-		}
-		return new SDLSurface(tsurf);
-	}
-}
-
-/**
- * Create a grayed version of the given picture.
- *
- * @param picture to be grayed out
- * @return the gray version of the picture
- */
-const IPicture* Graphic::create_grayed_out_pic(const IPicture* pic)
-{
-	if (!pic)
-		return 0;
-
-	Surface& surf = *static_cast<Surface*>(const_cast<IPicture*>(pic));
-
-	uint32_t w = pic->get_w();
-	uint32_t h = pic->get_h();
-	const SDL_PixelFormat & origfmt = surf.format();
-
-	Surface* dest = create_surface(w, h, origfmt.Amask);
-	const SDL_PixelFormat & destfmt = dest->format();
-
-	surf.lock(Surface::Lock_Normal);
-	dest->lock(Surface::Lock_Discard);
-	for (uint32_t y = 0; y < h; ++y) {
-		for (uint32_t x = 0; x < w; ++x) {
-			RGBAColor color;
-
-			color.set(origfmt, surf.get_pixel(x, y));
-
-			//  Halve the opacity to give some difference for pictures that are
-			//  grayscale to begin with.
-			color.a >>= 1;
-
-			color.r = color.g = color.b =
-				(luminance_table_r[color.r] +
-				 luminance_table_g[color.g] +
-				 luminance_table_b[color.b] +
-				 8388608U) //  compensate for truncation:  .5 * 2^24
-				>> 24;
-
-			dest->set_pixel(x, y, color.map(destfmt));
-		}
-	}
-	surf.unlock(Surface::Unlock_NoChange);
-	dest->unlock(Surface::Unlock_Update);
-
-	return dest;
-}
-
-/**
- * Creates an picture with changed luminosity from the given picture.
- *
- * @param picture to modify
- * @param factor the factor the luminosity should be changed by
- * @param half_alpha whether the opacity should be halved or not
- * @return a new picture with 50% luminosity
- */
-const IPicture* Graphic::create_changed_luminosity_pic
-	(const IPicture* pic, float factor, bool halve_alpha)
-{
-	if (!pic)
-		return 0;
-
-	Surface& surf = *static_cast<Surface*>(const_cast<IPicture*>(pic));
-
-	uint32_t w = pic->get_w();
-	uint32_t h = pic->get_h();
-	const SDL_PixelFormat & origfmt = surf.format();
-
-	Surface* dest = create_surface(w, h, origfmt.Amask);
-	const SDL_PixelFormat & destfmt = dest->format();
-
-	surf.lock(Surface::Lock_Normal);
-	dest->lock(Surface::Lock_Discard);
-	for (uint32_t y = 0; y < h; ++y) {
-		for (uint32_t x = 0; x < w; ++x) {
-			RGBAColor color;
-
-			color.set(origfmt, surf.get_pixel(x, y));
-
-			if (halve_alpha)
-				color.a >>= 1;
-
-			color.r = color.r * factor > 255 ? 255 : color.r * factor;
-			color.g = color.g * factor > 255 ? 255 : color.g * factor;
-			color.b = color.b * factor > 255 ? 255 : color.b * factor;
-
-			dest->set_pixel(x, y, color.map(destfmt));
-		}
-	}
-	surf.unlock(Surface::Unlock_NoChange);
-	dest->unlock(Surface::Unlock_Update);
-
-	return dest;
-}
-
 
 /**
  * Creates a terrain texture.
@@ -810,7 +511,6 @@
  * frametime is in milliseconds.
  * \return 0 if the texture couldn't be loaded.
  * \note Terrain textures are not reused, even if fnametempl matches.
- * These textures are freed when PicMod_Game is flushed.
 */
 uint32_t Graphic::get_maptexture(const string& fnametempl, uint32_t frametime)
 {
@@ -861,14 +561,14 @@
 	if (!m_animations.at(anim - 1))
 	{
 	  m_animations.at(anim - 1) =
-		  new AnimationGfx(*img_loader_.get(), g_anim.get_animation(anim));
+		  new AnimationGfx(g_anim.get_animation(anim), image_cache_.get());
 	}
 }
 
 /**
  * Return the number of frames in this animation
  */
-AnimationGfx::Index Graphic::nr_frames(uint32_t anim)
+size_t Graphic::nr_frames(uint32_t anim)
 {
 	return get_animation(anim)->nr_frames();
 }
@@ -879,18 +579,17 @@
 void Graphic::get_animation_size
 	(uint32_t anim, uint32_t time, uint32_t & w, uint32_t & h)
 {
-	const AnimationData* data = g_anim.get_animation(anim);
+	const AnimationData& data = g_anim.get_animation(anim);
 	const AnimationGfx* gfx  =        get_animation(anim);
 
-	if (!data || !gfx) {
+	if (!gfx) {
 		log("WARNING: Animation %u does not exist\n", anim);
 		w = h = 0;
 	} else {
-		// Get the frame and its data. Ignore playerclrs.
-		const IPicture* frame =
-			gfx->get_frame((time / data->frametime) % gfx->nr_frames());
-		w = frame->get_w();
-		h = frame->get_h();
+		const Image& frame =
+			gfx->get_frame((time / data.frametime) % gfx->nr_frames());
+		w = frame.width();
+		h = frame.height();
 	}
 }
 
@@ -901,7 +600,8 @@
 {
 	log("Save screenshot to %s\n", fname.c_str());
 	StreamWrite * sw = g_fs->OpenStreamWrite(fname);
-	save_png(screen_.get(), sw);
+	Surface& screen = *screen_.get();
+	save_png_(screen, sw);
 	delete sw;
 }
 
@@ -962,37 +662,32 @@
 void Graphic::set_world(string worldname) {
 	char buf[255];
 
-	if (m_roadtextures)
-		delete m_roadtextures;
-
 	// Load the road textures
-	m_roadtextures = new Road_Textures();
 	snprintf(buf, sizeof(buf), "worlds/%s/pics/roadt_normal.png", worldname.c_str());
-	m_roadtextures->pic_road_normal = imgcache().load(PicMod_Game, buf, false);
+	pic_road_normal_.reset(image_loader_->load(buf));
 	snprintf(buf, sizeof(buf), "worlds/%s/pics/roadt_busy.png", worldname.c_str());
-	m_roadtextures->pic_road_busy = imgcache().load(PicMod_Game, buf, false);
+	pic_road_busy_.reset(image_loader_->load(buf));
 
 	// load edge texture
 	snprintf(buf, sizeof(buf), "worlds/%s/pics/edge.png", worldname.c_str());
-	m_edgetexture = imgcache().load(PicMod_Game, buf, false);
+	edgetexture_.reset(image_loader_->load(buf));
 }
 
 /**
- * Retrives the texture of the road type. This loads the road texture
- * if not done yet.
+ * Retrives the texture of the road type.
  * \return The road texture
  */
-const IPicture* Graphic::get_road_texture(int32_t roadtex)
+Surface& Graphic::get_road_texture(int32_t roadtex)
 {
 	return
-		(roadtex == Widelands::Road_Normal ? m_roadtextures->pic_road_normal : m_roadtextures->pic_road_busy);
+		roadtex == Widelands::Road_Normal ? *pic_road_normal_.get() : *pic_road_busy_.get();
 }
 
 /**
  * Returns the alpha mask texture for edges.
  * \return The edge texture (alpha mask)
  */
-const IPicture* Graphic::get_edge_texture()
+Surface& Graphic::get_edge_texture()
 {
-	return m_edgetexture;
+	return *edgetexture_;
 }

=== modified file 'src/graphic/graphic.h'
--- src/graphic/graphic.h	2013-01-05 18:52:13 +0000
+++ src/graphic/graphic.h	2013-02-10 14:53:26 +0000
@@ -23,34 +23,27 @@
 #include <vector>
 #include <map>
 
+#include <SDL.h>
 #include <boost/scoped_ptr.hpp>
 #include <png.h>
 
-#include "animation_gfx.h"
-#include "igraphic.h"
 #include "image_cache.h"
 #include "rect.h"
-#include "surface.h"
 
 #define MAX_RECTS 20
 
 namespace UI {struct ProgressWindow;}
 
+class AnimationGfx;
+class ImageLoaderImpl;
 class RenderTarget;
+class Screen;
+class Surface;
+class SurfaceCache;
 struct Road_Textures;
-struct SDL_Rect;
 struct SDL_Surface;
 struct StreamWrite;
 struct Texture;
-class Screen;
-
-//@{
-/// This table is used by create_grayed_out_pic()to map colors to grayscale. It
-/// is initialized in Graphic::Graphic().
-extern uint32_t luminance_table_r[0x100];
-extern uint32_t luminance_table_g[0x100];
-extern uint32_t luminance_table_b[0x100];
-//@}
 
 /// Stores the capabilities of opengl
 struct GLCaps
@@ -87,20 +80,12 @@
 
 /**
  * A renderer to get pixels to a 16bit framebuffer.
- *
- * Picture IDs can be allocated using \ref get_picture() and used in
- * \ref RenderTarget::blit().
- *
- * Pictures are only loaded from disk once and thrown out of memory when the
- * graphics system is unloaded, or when \ref flush() is called with the
- * appropriate module flag; the user can request to flush one single picture
- * alone, but this is only used (and useful) in the editor.
  */
-struct Graphic : public IGraphic {
+struct Graphic {
 	Graphic
 		(int32_t w, int32_t h, int32_t bpp,
 		 bool fullscreen, bool opengl);
-	virtual ~Graphic();
+	~Graphic();
 
 	int32_t get_xres() const;
 	int32_t get_yres() const;
@@ -114,19 +99,12 @@
 	bool need_update() const;
 	void refresh(bool force = true);
 
-	ImageCache& imgcache() const {return *img_cache_.get();}
+	ImageCache& images() const {return *image_cache_.get();}
+	SurfaceCache& surfaces() const {return *surface_cache_.get();}
+
 	void flush_animations();
 
-	void save_png(const IPicture*, StreamWrite*) const;
-
-	virtual IPicture* convert_sdl_surface_to_picture(SDL_Surface *, bool alpha = false) const;
-
-	Surface* create_surface(int32_t w, int32_t h, bool alpha = false) const;
-
-	const IPicture* create_grayed_out_pic(const IPicture* pic);
-	const IPicture* create_changed_luminosity_pic
-		(const IPicture* pic, float factor, bool halve_alpha = false);
-	const IPicture* get_resized_picture(const IPicture*, uint32_t w, uint32_t h);
+	void save_png(const Image*, StreamWrite*) const;
 
 	uint32_t get_maptexture(const std::string& fnametempl, uint32_t frametime);
 	void animate_maptextures(uint32_t time);
@@ -134,7 +112,7 @@
 
 	void load_animations();
 	void ensure_animation_loaded(uint32_t anim);
-	AnimationGfx::Index nr_frames(uint32_t anim = 0);
+	size_t nr_frames(uint32_t anim = 0);
 	uint32_t get_animation_frametime(uint32_t anim) const;
 	void get_animation_size (uint32_t anim, uint32_t time, uint32_t & w, uint32_t & h);
 
@@ -143,13 +121,13 @@
 	AnimationGfx * get_animation(uint32_t);
 
 	void set_world(std::string);
-	const IPicture* get_road_texture(int32_t roadtex);
-	const IPicture* get_edge_texture();
+	Surface& get_road_texture(int32_t roadtex);
+	Surface& get_edge_texture();
 
 	const GraphicCaps& caps() const throw () {return m_caps;}
 
 private:
-	SDL_Surface * extract_sdl_surface(Surface & surf, Rect srcrect) const;
+	void save_png_(Surface & surf, StreamWrite*) const;
 
 protected:
 	// Static helper function for png writing
@@ -177,15 +155,22 @@
 	bool m_update_fullscreen;
 	/// stores which features the current renderer has
 	GraphicCaps m_caps;
-	Road_Textures * m_roadtextures;
-	const IPicture* m_edgetexture;
+
+	/// The class that gets images from disk.
+	boost::scoped_ptr<ImageLoaderImpl> image_loader_;
+	/// Volatile cache of Hardware dependant surfaces.
+	boost::scoped_ptr<SurfaceCache> surface_cache_;
+	/// Non-volatile cache of hardware independent images. The use the
+	/// surface_cache_ to cache their pixel data.
+	boost::scoped_ptr<ImageCache> image_cache_;
+
+	// The texture needed to draw roads.
+	boost::scoped_ptr<Surface> pic_road_normal_;
+	boost::scoped_ptr<Surface> pic_road_busy_;
+	boost::scoped_ptr<Surface> edgetexture_;
+
 	std::vector<Texture *> m_maptextures;
 	std::vector<AnimationGfx *> m_animations;
-
-	/// The class that gets images from disk.
-	boost::scoped_ptr<IImageLoader> img_loader_;
-	// The cache holding the images.
-	boost::scoped_ptr<ImageCache> img_cache_;
 };
 
 extern Graphic * g_gr;

=== removed file 'src/graphic/iblitable_surface.h'
--- src/graphic/iblitable_surface.h	2012-12-08 17:48:15 +0000
+++ src/graphic/iblitable_surface.h	1970-01-01 00:00:00 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright 2010 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- */
-
-#ifndef IBLITABLE_SURFACE_H
-#define IBLITABLE_SURFACE_H
-
-#include <boost/noncopyable.hpp>
-
-#include "compositemode.h"
-#include "picture.h"
-#include "point.h"
-#include "rgbcolor.h"
-#include "rect.h"
-
-/**
- * Interface to a basic surfaces that can be used as destination for blitting.
- */
-class IBlitableSurface : public IPicture {
-public:
-	virtual ~IBlitableSurface() {}
-
-	/// This draws a part of another surface to this surface
-	virtual void blit(const Point&, const IPicture*, const Rect& srcrc, Composite cm = CM_Normal) = 0;
-
-	/// Draws a filled rect to the surface.
-	virtual void fill_rect(const Rect&, RGBAColor) = 0;
-};
-
-#endif

=== removed file 'src/graphic/igraphic.h'
--- src/graphic/igraphic.h	2012-12-15 18:40:59 +0000
+++ src/graphic/igraphic.h	1970-01-01 00:00:00 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2006-2012 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef IGRAPHIC_H
-#define IGRAPHIC_H
-
-#include <string>
-
-#include "iblitable_surface.h"
-#include "picture.h"
-
-struct SDL_Surface;
-class ImageCache;
-
-class IGraphic {
-public:
-	virtual ~IGraphic() {};
-
-	virtual IPicture* convert_sdl_surface_to_picture(SDL_Surface*, bool alpha = false) const = 0;
-	virtual IBlitableSurface * create_surface(int32_t w, int32_t h, bool alpha = false) const = 0;
-
-	virtual ImageCache& imgcache() const = 0;
-};
-
-
-#endif /* end of include guard: IGRAPHIC_H */
-

=== renamed file 'src/graphic/picture.h' => 'src/graphic/image.h'
--- src/graphic/picture.h	2012-12-14 19:50:01 +0000
+++ src/graphic/image.h	2013-02-10 14:53:26 +0000
@@ -17,8 +17,8 @@
  *
  */
 
-#ifndef PICTURE_H
-#define PICTURE_H
+#ifndef IMAGE_H
+#define IMAGE_H
 
 #include <stdint.h>
 #include <string>
@@ -29,13 +29,19 @@
  * Interface to a bitmap that can act as the source of a rendering
  * operation.
  */
-class IPicture : boost::noncopyable {
+class Surface;
+
+class Image : boost::noncopyable {
 public:
-	IPicture() {}
-	virtual ~IPicture() {}
-
-	virtual uint32_t get_w() const = 0;
-	virtual uint32_t get_h() const = 0;
+	virtual ~Image() {}
+
+	virtual uint16_t width() const = 0;
+	virtual uint16_t height() const = 0;
+
+	// Internal functions needed for caching.
+	virtual Surface* surface() const = 0;
+	virtual const std::string& hash() const = 0;
 };
 
+
 #endif

=== modified file 'src/graphic/image_cache.cc'
--- src/graphic/image_cache.cc	2012-12-15 18:40:59 +0000
+++ src/graphic/image_cache.cc	2013-02-10 14:53:26 +0000
@@ -19,101 +19,114 @@
 
 #include <string>
 #include <map>
-#include <vector>
 
+#include <boost/foreach.hpp>
 #include <boost/scoped_ptr.hpp>
-#include <boost/foreach.hpp>
-
-#include "picture.h"
-
+
+#include "image.h"
 #include "image_loader.h"
+#include "log.h"
+#include "surface.h"
+#include "surface_cache.h"
+
 #include "image_cache.h"
 
 using namespace std;
 
+
+namespace  {
+
+// Image Implementation that loads images from disc when they should be drawn.
+// Uses SurfaceCache. These images are meant to be cached in ImageCache.
+class FromDiskImage : public Image {
+public:
+	FromDiskImage(const string& filename, SurfaceCache* surface_cache, IImageLoader* image_loader) :
+		filename_(filename),
+		image_loader_(image_loader),
+		surface_cache_(surface_cache) {
+			Surface* surf = reload_image_();
+			w_ = surf->width();
+			h_ = surf->height();
+		}
+	virtual ~FromDiskImage() {}
+
+	// Implements Image.
+	virtual uint16_t width() const {return w_; }
+	virtual uint16_t height() const {return h_;}
+	virtual const string& hash() const {return filename_;}
+	virtual Surface* surface() const {
+		Surface* surf = surface_cache_->get(filename_);
+		if (surf)
+			return surf;
+		return reload_image_();
+	}
+
+private:
+	Surface* reload_image_() const {
+		log("Loading image %s.\n", filename_.c_str());
+		Surface* surf = surface_cache_->insert(filename_, image_loader_->load(filename_));
+		return surf;
+	}
+	uint16_t w_, h_;
+	const string filename_;
+
+	// Nothing owned
+	IImageLoader* const image_loader_;
+	SurfaceCache* const surface_cache_;
+};
+
 class ImageCacheImpl : public ImageCache {
 public:
-	// Ownership of loader is not taken.
-	ImageCacheImpl(IImageLoader* loader) : img_loader_(loader) {}
-	~ImageCacheImpl();
+	// No ownership is taken here.
+	ImageCacheImpl(IImageLoader* loader, SurfaceCache* surface_cache)
+		: image_loader_(loader), surface_cache_(surface_cache) {
+		}
+	virtual ~ImageCacheImpl();
 
-	// Implements ImageCache
-	virtual const IPicture* get(PicMod, const string& hash) const;
-	virtual const IPicture* insert(PicMod, const string& hash, const IPicture*);
-	virtual const IPicture* load(PicMod, const string& fn, bool alpha);
-	virtual void flush(PicMod);
+	// Implements ImageCache.
+	const Image* insert(const Image*);
+	bool has(const std::string& hash) const;
+	virtual const Image* get(const std::string& hash);
 
 private:
-	struct PictureRec {
-		const IPicture* picture;
-
-		/// bit-mask of modules that this picture exists in
-		uint32_t modules;
-	};
-
-	typedef map<string, PictureRec> PictureMap;
-
-	/// hash of cached filename/picture pairs
-	PictureMap m_picturemap;
-
-	IImageLoader* img_loader_;
+	typedef map<string, const Image*> ImageMap;
+
+	// hash of cached filename/image pairs
+	ImageMap images_;
+
+	// None of these are owned.
+	IImageLoader* const image_loader_;
+	SurfaceCache* const surface_cache_;
 };
 
 ImageCacheImpl::~ImageCacheImpl() {
-	BOOST_FOREACH(PictureMap::value_type& p, m_picturemap)
-		delete p.second.picture;
-	m_picturemap.clear();
-}
-
-const IPicture* ImageCacheImpl::get(PicMod module, const string& hash) const {
-	PictureMap::const_iterator it = m_picturemap.find(hash);
-	if (it == m_picturemap.end())
-		return NULL;
-	return (it->second.modules & (1 << module)) ? it->second.picture : NULL;
-}
-
-const IPicture* ImageCacheImpl::insert(PicMod module, const string& name, const IPicture* pic) {
-	PictureRec rec;
-	rec.picture = pic;
-	rec.modules = 1 << module;
-	m_picturemap.insert(make_pair(name, rec));
-	return pic;
-}
-
-void ImageCacheImpl::flush(PicMod module) {
-	vector<string> eraselist;
-
-	BOOST_FOREACH(PictureMap::value_type& entry, m_picturemap) {
-		entry.second.modules &= ~(1 << module);
-		if (!entry.second.modules)
-			eraselist.push_back(entry.first);
-	}
-
-	while (!eraselist.empty()) {
-		m_picturemap.erase(eraselist.back());
-		eraselist.pop_back();
-	}
-}
-
-const IPicture* ImageCacheImpl::load
-		(PicMod module, const string& fname, bool alpha)
-{
-	//  Check if the picture is already loaded.
-	PictureMap::iterator it = m_picturemap.find(fname);
-
-	if (it == m_picturemap.end()) {
-		PictureRec rec;
-
-		rec.picture = img_loader_->load(fname, alpha);
-		rec.modules = 0;
-
-		it = m_picturemap.insert(make_pair(fname, rec)).first;
-	}
-
-	it->second.modules |= 1 << module;
-	return it->second.picture;
-}
-
-ImageCache* create_image_cache(IImageLoader* loader) {
-	return new ImageCacheImpl(loader);
-}
+	BOOST_FOREACH(ImageMap::value_type& p, images_)
+		delete p.second;
+	images_.clear();
+}
+
+bool ImageCacheImpl::has(const string& hash) const {
+	return images_.count(hash);
+}
+
+const Image* ImageCacheImpl::insert(const Image* image) {
+	assert(!has(image->hash()));
+	images_.insert(make_pair(image->hash(), image));
+	return image;
+}
+
+const Image* ImageCacheImpl::get(const string& hash) {
+	ImageMap::const_iterator it = images_.find(hash);
+	if (it == images_.end()) {
+		images_.insert(make_pair(hash, new FromDiskImage(hash, surface_cache_, image_loader_)));
+		return get(hash);
+	}
+	return it->second;
+}
+
+}  // namespace
+
+ImageCache* create_image_cache(IImageLoader* loader, SurfaceCache* surface_cache) {
+	return new ImageCacheImpl(loader, surface_cache);
+}
+

=== modified file 'src/graphic/image_cache.h'
--- src/graphic/image_cache.h	2012-12-13 21:10:32 +0000
+++ src/graphic/image_cache.h	2013-02-10 14:53:26 +0000
@@ -24,55 +24,38 @@
 
 #include <boost/utility.hpp>
 
-class IPicture;
+#include "image.h"
 class IImageLoader;
-
-/**
- * Picture caches (modules).
- *
- * This cache is separated into different modules, and can be flushed
- * per-module.
- */
-enum PicMod {
-	PicMod_UI = 0,
-	PicMod_Menu,
-	PicMod_Game,
-	PicMod_Text,
-	PicMod_RichText,
-
-	// Must be last
-	PicMod_Last
-};
-
-// This class can load and cache images, so that they are already available
-// when requested the next time. When another part of the program generates a
-// new picture, it can also choose to insert it into this cache. The pictures
-// in the cache are associated with a Picture Module. When a part of the
-// program knows that it no longer needs pictures from a certain module, it can
-// call flush to delete the images from the cache. The cache holds ownership
-// over each image it contains.
+class SurfaceCache;
+
+// For historic reasons, most part of the Widelands code base expect that an
+// Image stays valid for the whole duration of the program run. This class is
+// the one that keeps ownership of all Images to ensure that this is true. Also
+// for historic reasons, this class will try to load in Image from disk when
+// its hash is not found. Other parts of Widelands will create images when they
+// do not exist in the cache yet and then put it into the cache and therefore
+// releasing their ownership.
 class ImageCache : boost::noncopyable {
 public:
 	virtual ~ImageCache() {}
 
-	/// Returns an entry if it is cached, NULL otherwise.
-	virtual const IPicture* get(PicMod, const std::string& hash) const = 0;
-
-	/// Inserts this entry into the ImageCache. Overwrites existing entries /
-	//without freeing the image first, so be careful. Returns the picture just
-	//inserted / for convenience.
-	virtual const IPicture* insert(PicMod, const std::string& hash, const IPicture*) = 0;
-
-	/// Loads an Image from disk and caches it. If it was already
-	/// cached, it is simply returned.
-	virtual const IPicture* load(PicMod, const std::string& fn, bool alpha = true) = 0;
-
-	/// Clears the Cache for the given PicMod
-	virtual void flush(PicMod) = 0;
+	// Insert the given Image into the cache. The hash is defined by Image's hash()
+	// function. Ownership of the Image is taken. Will return a pointer to the freshly inserted
+	// image for convenience.
+	virtual const Image* insert(const Image*) = 0;
+
+	// Returns the image associated with the given hash. If no image by this
+	// hash is known, it will try to load one from disk with the filename =
+	// hash. If this fails, it will throw an error.
+	virtual const Image* get(const std::string& hash) = 0;
+
+	// Returns true if the given hash is stored in the cache.
+	virtual bool has(const std::string& hash) const = 0;
+
 };
 
-// Takes ownership of img_loader
-ImageCache* create_image_cache(IImageLoader*);
+// Create a new ImageCache. Takes no ownership.
+ImageCache* create_image_cache(IImageLoader*, SurfaceCache*);
 
 #endif /* end of include guard: IMAGE_CACHE_H */
 

=== modified file 'src/graphic/image_loader.h'
--- src/graphic/image_loader.h	2012-12-13 21:10:32 +0000
+++ src/graphic/image_loader.h	2013-02-10 14:53:26 +0000
@@ -22,15 +22,15 @@
 
 #include <string>
 
-class IPicture;
+class Surface;
 
-/// This only knows how to load an image. It is the only thing that is
-/// implementation dependant in the ImageCache.
+/// A thin interface that can load an Image from anywhere and turn it into a
+/// surface.
 class IImageLoader {
 public:
 	virtual ~IImageLoader() {}
 
-	virtual IPicture* load(const std::string& fn, bool alpha) const = 0;
+	virtual Surface* load(const std::string& fn) const = 0;
 };
 
 #endif /* end of include guard: IMAGE_LOADER_H */

=== added file 'src/graphic/image_loader_impl.cc'
--- src/graphic/image_loader_impl.cc	1970-01-01 00:00:00 +0000
+++ src/graphic/image_loader_impl.cc	2013-02-10 14:53:26 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2006-2012 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <SDL.h>
+#include <SDL_image.h>
+
+#include "io/fileread.h"
+#include "io/filesystem/layered_filesystem.h"
+#include "wexception.h"
+
+#include "surface.h"
+
+#include "image_loader_impl.h"
+
+using namespace std;
+
+Surface* ImageLoaderImpl::load(const string& fname) const {
+	FileRead fr;
+
+	fr.fastOpen(*g_fs, fname.c_str());
+	SDL_Surface* sdlsurf = IMG_Load_RW(SDL_RWFromMem(fr.Data(0), fr.GetSize()), 1);
+
+	if (!sdlsurf)
+		throw wexception("Could not open image %s: %s", fname.c_str(), IMG_GetError());
+
+	return Surface::create(sdlsurf);
+}
+

=== added file 'src/graphic/image_loader_impl.h'
--- src/graphic/image_loader_impl.h	1970-01-01 00:00:00 +0000
+++ src/graphic/image_loader_impl.h	2013-02-10 14:53:26 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2006-2012 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef IMAGE_LOADER_IMPL_H
+#define IMAGE_LOADER_IMPL_H
+
+#include <string>
+
+#include "image_loader.h"
+
+class Graphic;
+
+class ImageLoaderImpl : public IImageLoader {
+public:
+	virtual ~ImageLoaderImpl() {}
+
+	Surface* load(const std::string& fname) const;
+};
+
+
+#endif /* end of include guard: IMAGE_LOADER_IMPL_H */
+

=== added file 'src/graphic/image_transformations.cc'
--- src/graphic/image_transformations.cc	1970-01-01 00:00:00 +0000
+++ src/graphic/image_transformations.cc	2013-02-10 14:53:26 +0000
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2006-2013 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <string>
+
+#include <SDL.h>
+#include <SDL_rotozoom.h>
+#include <boost/format.hpp>
+
+#include "rgbcolor.h"
+#include "upcast.h"
+
+#include "graphic.h"
+#include "render/sdl_surface.h"
+#include "surface.h"
+#include "surface_cache.h"
+
+#include "image_transformations.h"
+
+using namespace std;
+
+namespace {
+
+// This table is used to transform colors.
+uint32_t luminance_table_r[0x100];
+uint32_t luminance_table_g[0x100];
+uint32_t luminance_table_b[0x100];
+
+/**
+ * Create and return an \ref SDL_Surface that contains the given sub-rectangle
+ * of the given pixel region.
+ */
+SDL_Surface* extract_sdl_surface(Surface & surf, Rect srcrect)
+{
+	assert(srcrect.x >= 0);
+	assert(srcrect.y >= 0);
+	assert(srcrect.x + srcrect.w <= surf.width());
+	assert(srcrect.y + srcrect.h <= surf.height());
+
+	const SDL_PixelFormat & fmt = surf.format();
+	SDL_Surface * dest = SDL_CreateRGBSurface
+		(SDL_SWSURFACE, srcrect.w, srcrect.h,
+		 fmt.BitsPerPixel, fmt.Rmask, fmt.Gmask, fmt.Bmask, fmt.Amask);
+
+	surf.lock(Surface::Lock_Normal);
+	SDL_LockSurface(dest);
+
+	uint32_t srcpitch = surf.get_pitch();
+	uint32_t rowsize = srcrect.w * fmt.BytesPerPixel;
+	uint8_t * srcpix = surf.get_pixels() + srcpitch * srcrect.y + fmt.BytesPerPixel * srcrect.x;
+	uint8_t * dstpix = static_cast<uint8_t *>(dest->pixels);
+
+	for (uint32_t y = 0; y < srcrect.h; ++y) {
+		memcpy(dstpix, srcpix, rowsize);
+		srcpix += srcpitch;
+		dstpix += dest->pitch;
+	}
+
+	SDL_UnlockSurface(dest);
+	surf.unlock(Surface::Unlock_NoChange);
+
+	return dest;
+}
+
+/**
+ * Produces a resized version of the specified image
+ */
+Surface* resize_surface(Surface* src, uint32_t w, uint32_t h) {
+	assert(w != src->width() || h != src->height());
+
+	// First step: compute scaling factors
+	Rect srcrect = Rect(Point(0, 0), src->width(), src->height());
+
+	// Second step: get source material
+	SDL_Surface * srcsdl = 0;
+	bool free_source = true;
+	if (upcast(const SDLSurface, sdlsrcsurf, src)) {
+		srcsdl = sdlsrcsurf->get_sdl_surface();
+		free_source = false;
+	} else {
+		// This is in OpenGL
+		srcsdl = extract_sdl_surface(*src, srcrect);
+	}
+
+	// Third step: perform the zoom and placement
+	SDL_Surface * zoomed = zoomSurface
+		(srcsdl, double(w) / srcsdl->w, double(h) / srcsdl->h, 1);
+	if (free_source)
+		SDL_FreeSurface(srcsdl);
+
+	if (uint32_t(zoomed->w) != w || uint32_t(zoomed->h) != h) {
+		const SDL_PixelFormat & fmt = *zoomed->format;
+		SDL_Surface * placed = SDL_CreateRGBSurface
+			(SDL_SWSURFACE, w, h,
+			 fmt.BitsPerPixel, fmt.Rmask, fmt.Gmask, fmt.Bmask, fmt.Amask);
+		SDL_Rect srcrc =
+			{0, 0,
+			 static_cast<Uint16>(zoomed->w), static_cast<Uint16>(zoomed->h)
+			};  // For some reason SDL_Surface and SDL_Rect express w,h in different types
+		SDL_Rect dstrc = {0, 0, 0, 0};
+		SDL_SetAlpha(zoomed, 0, 0);
+		SDL_BlitSurface(zoomed, &srcrc, placed, &dstrc); // Updates dstrc
+
+		Uint32 fillcolor = SDL_MapRGBA(zoomed->format, 0, 0, 0, 255);
+
+		if (zoomed->w < placed->w) {
+			dstrc.x = zoomed->w;
+			dstrc.y = 0;
+			dstrc.w = placed->w - zoomed->w;
+			dstrc.h = zoomed->h;
+			SDL_FillRect(placed, &dstrc, fillcolor);
+		}
+		if (zoomed->h < placed->h) {
+			dstrc.x = 0;
+			dstrc.y = zoomed->h;
+			dstrc.w = placed->w;
+			dstrc.h = placed->h - zoomed->h;
+			SDL_FillRect(placed, &dstrc, fillcolor);
+		}
+
+		SDL_FreeSurface(zoomed);
+		zoomed = placed;
+	}
+
+	return Surface::create(zoomed);
+}
+
+/**
+ * Create a grayed version of the given surface.
+ */
+Surface* gray_out_surface(Surface* surf) {
+	assert(surf);
+
+	uint16_t w = surf->width();
+	uint16_t h = surf->height();
+	const SDL_PixelFormat & origfmt = surf->format();
+
+	Surface* dest = Surface::create(w, h);
+	const SDL_PixelFormat & destfmt = dest->format();
+
+	surf->lock(Surface::Lock_Normal);
+	dest->lock(Surface::Lock_Discard);
+	for (uint32_t y = 0; y < h; ++y) {
+		for (uint32_t x = 0; x < w; ++x) {
+			RGBAColor color;
+
+			color.set(origfmt, surf->get_pixel(x, y));
+
+			//  Halve the opacity to give some difference for image that are
+			//  grayscale to begin with.
+			color.a >>= 1;
+
+			color.r = color.g = color.b =
+				(luminance_table_r[color.r] +
+				 luminance_table_g[color.g] +
+				 luminance_table_b[color.b] +
+				 8388608U) //  compensate for truncation:  .5 * 2^24
+				>> 24;
+
+			dest->set_pixel(x, y, color.map(destfmt));
+		}
+	}
+	surf->unlock(Surface::Unlock_NoChange);
+	dest->unlock(Surface::Unlock_Update);
+
+	return dest;
+}
+
+/**
+ * Creates an image with changed luminosity from the given surface.
+ */
+Surface* change_luminosity_of_surface(Surface* surf, float factor, bool halve_alpha) {
+	assert(surf);
+
+	uint16_t w = surf->width();
+	uint16_t h = surf->height();
+	const SDL_PixelFormat & origfmt = surf->format();
+
+	Surface* dest = Surface::create(w, h);
+	const SDL_PixelFormat & destfmt = dest->format();
+
+	surf->lock(Surface::Lock_Normal);
+	dest->lock(Surface::Lock_Discard);
+	for (uint32_t y = 0; y < h; ++y) {
+		for (uint32_t x = 0; x < w; ++x) {
+			RGBAColor color;
+
+			color.set(origfmt, surf->get_pixel(x, y));
+
+			if (halve_alpha)
+				color.a >>= 1;
+
+			color.r = color.r * factor > 255 ? 255 : color.r * factor;
+			color.g = color.g * factor > 255 ? 255 : color.g * factor;
+			color.b = color.b * factor > 255 ? 255 : color.b * factor;
+
+			dest->set_pixel(x, y, color.map(destfmt));
+		}
+	}
+	surf->unlock(Surface::Unlock_NoChange);
+	dest->unlock(Surface::Unlock_Update);
+
+	return dest;
+}
+
+// Encodes the given Image into the corresponding image for player color.
+// Takes the neutral set of images and the player color mask.
+Surface* make_playerclr_surface(Surface& orig_surface, Surface& pcmask_surface, const RGBColor& color) {
+	Surface* new_surface = Surface::create(orig_surface.width(), orig_surface.height());
+
+	const SDL_PixelFormat & fmt = orig_surface.format();
+	const SDL_PixelFormat & fmt_pc = pcmask_surface.format();
+	const SDL_PixelFormat & destfmt = new_surface->format();
+
+	orig_surface.lock(Surface::Lock_Normal);
+	pcmask_surface.lock(Surface::Lock_Normal);
+	new_surface->lock(Surface::Lock_Discard);
+	// This could be done significantly faster, but since we
+	// cache the result, let's keep it simple for now.
+	for (uint32_t y = 0; y < orig_surface.height(); ++y) {
+		for (uint32_t x = 0; x < orig_surface.width(); ++x) {
+			RGBAColor source;
+			RGBAColor mask;
+			RGBAColor product;
+
+			source.set(fmt, orig_surface.get_pixel(x, y));
+			mask.set(fmt_pc, pcmask_surface.get_pixel(x, y));
+
+			if
+				(uint32_t const influence =
+				 static_cast<uint32_t>(mask.r) * mask.a)
+				{
+					uint32_t const intensity =
+						(luminance_table_r[source.r] +
+						 luminance_table_g[source.g] +
+						 luminance_table_b[source.b] +
+						 8388608U) //  compensate for truncation:  .5 * 2^24
+						>> 24;
+					RGBAColor plrclr;
+
+					plrclr.r = (color.r * intensity) >> 8;
+					plrclr.g = (color.g * intensity) >> 8;
+					plrclr.b = (color.b * intensity) >> 8;
+
+					product.r =
+						(plrclr.r * influence + source.r * (65536 - influence)) >> 16;
+					product.g =
+						(plrclr.g * influence + source.g * (65536 - influence)) >> 16;
+					product.b =
+						(plrclr.b * influence + source.b * (65536 - influence)) >> 16;
+					product.a = source.a;
+				} else {
+					product = source;
+				}
+
+			new_surface->set_pixel(x, y, product.map(destfmt));
+		}
+	}
+	orig_surface.unlock(Surface::Unlock_NoChange);
+	pcmask_surface.unlock(Surface::Unlock_NoChange);
+	new_surface->unlock(Surface::Unlock_Update);
+
+	return new_surface;
+}
+
+// An Image implementation that is the transformation of another Image. Uses
+// the SurfaceCache to avoid recalculating the transformation too often. No
+// ownerships are taken.
+class TransformedImage : public Image {
+public:
+	TransformedImage(const string& hash, const Image& original, SurfaceCache* surface_cache) :
+		hash_(hash), original_(original), surface_cache_(surface_cache) {}
+	virtual ~TransformedImage() {}
+
+	// Implements Image.
+	virtual uint16_t width() const {return original_.width();}
+	virtual uint16_t height() const {return original_.height();}
+	virtual const string& hash() const {return hash_;}
+	virtual Surface* surface() const {
+		Surface* surf = surface_cache_->get(hash_);
+		if (surf)
+			return surf;
+
+		surf = recalculate_surface();
+		surface_cache_->insert(hash_, surf);
+		return surf;
+	}
+
+	virtual Surface* recalculate_surface() const = 0;
+
+protected:
+	const string hash_;
+	const Image& original_;
+	SurfaceCache* const surface_cache_;  // not owned
+};
+
+// A resized copy of an Image.
+class ResizedImage : public TransformedImage {
+public:
+	ResizedImage
+		(const string& hash, const Image& original,
+		 SurfaceCache* surface_cache, uint16_t w, uint16_t h)
+		: TransformedImage(hash, original, surface_cache), w_(w), h_(h) {
+			assert(w != original.width() || h != original.height());
+	}
+	virtual ~ResizedImage() {}
+
+	// Overwrites TransformedImage.
+	virtual uint16_t width() const {return w_;}
+	virtual uint16_t height() const {return h_;}
+
+	// Implements TransformedImage.
+	virtual Surface* recalculate_surface() const {
+		Surface* rv = resize_surface(original_.surface(), w_, h_);
+		return rv;
+	}
+
+private:
+	uint16_t w_, h_;
+};
+
+// A grayed out copy of an Image.
+class GrayedOutImage : public TransformedImage {
+public:
+	GrayedOutImage(const string& hash, const Image& original, SurfaceCache* surface_cache) :
+		TransformedImage(hash, original, surface_cache)
+	{}
+	virtual ~GrayedOutImage() {}
+
+	// Implements TransformedImage.
+	virtual Surface* recalculate_surface() const {
+		return gray_out_surface(original_.surface());
+	}
+};
+
+// A copy with another luminosity and maybe half the opacity.
+class ChangeLuminosityImage : public TransformedImage {
+public:
+	ChangeLuminosityImage
+		(const string& hash, const Image& original,
+		 SurfaceCache* surface_cache, float factor, bool halve_alpha)
+		: TransformedImage(hash, original, surface_cache),
+		  factor_(factor),
+		  halve_alpha_(halve_alpha)
+	{}
+	virtual ~ChangeLuminosityImage() {}
+
+	// Implements TransformedImage.
+	virtual Surface* recalculate_surface() const {
+		return change_luminosity_of_surface(original_.surface(), factor_, halve_alpha_);
+	}
+
+private:
+	float factor_;
+	bool halve_alpha_;
+};
+
+// A copy with applied player colors. Also needs a mask - ownership is not
+// taken.
+class PlayerColoredImage : public TransformedImage {
+public:
+	PlayerColoredImage
+		(const string& hash, const Image& original,
+		 SurfaceCache* surface_cache, const RGBColor& color, const Image& mask)
+		: TransformedImage(hash, original, surface_cache), color_(color), mask_(mask)
+		{}
+	virtual ~PlayerColoredImage() {}
+
+	// Implements TransformedImage.
+	virtual Surface* recalculate_surface() const {
+		return make_playerclr_surface(*original_.surface(), *mask_.surface(), color_);
+	}
+
+private:
+	const RGBColor& color_;
+	const Image& mask_;
+};
+
+}
+
+namespace ImageTransformations {
+
+void initialize() {
+	// Initialize the table used to create grayed image
+	for
+		(uint32_t i = 0, r = 0, g = 0, b = 0;
+		 i < 0x100;
+		 ++i, r += 5016388U, g += 9848226U, b += 1912603U)
+		{
+			luminance_table_r[i] = r;
+			luminance_table_g[i] = g;
+			luminance_table_b[i] = b;
+		}
+}
+
+const Image* resize(const Image* original, uint16_t w, uint16_t h) {
+	const string new_hash = (boost::format("%s:%i:%i") % original->hash() % w % h).str();
+	if (g_gr->images().has(new_hash))
+		return g_gr->images().get(new_hash);
+	return
+		g_gr->images().insert(new ResizedImage(new_hash, *original, &g_gr->surfaces(), w, h));
+}
+
+const Image* gray_out(const Image* original) {
+	const string new_hash = original->hash() + ":greyed_out";
+	if (g_gr->images().has(new_hash))
+		return g_gr->images().get(new_hash);
+	return
+		g_gr->images().insert(new GrayedOutImage(new_hash, *original, &g_gr->surfaces()));
+}
+
+const Image* change_luminosity(const Image* original, float factor, bool halve_alpha) {
+	const string new_hash =
+		(boost::format("%s:%i:%i") % original->hash() % static_cast<int>(factor * 1000) % halve_alpha).str();
+	if (g_gr->images().has(new_hash))
+		return g_gr->images().get(new_hash);
+	return
+		g_gr->images().insert
+			(new ChangeLuminosityImage(new_hash, *original, &g_gr->surfaces(), factor, halve_alpha));
+}
+
+const Image* player_colored(const RGBColor& clr, const Image* original, const Image* mask) {
+	const string new_hash =
+		(boost::format("%s:%02x%02x%02x") % original->hash() % static_cast<int>(clr.r) %
+		 static_cast<int>(clr.g) % static_cast<int>(clr.b))
+			.str();
+	if (g_gr->images().has(new_hash))
+		return g_gr->images().get(new_hash);
+	return
+		g_gr->images().insert
+			(new PlayerColoredImage(new_hash, *original, &g_gr->surfaces(), clr, *mask));
+}
+
+}  // namespace ImageTransformations

=== added file 'src/graphic/image_transformations.h'
--- src/graphic/image_transformations.h	1970-01-01 00:00:00 +0000
+++ src/graphic/image_transformations.h	2013-02-10 14:53:26 +0000
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2006-2013 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef IMAGE_TRANSFORMATIONS_H
+#define IMAGE_TRANSFORMATIONS_H
+
+struct RGBColor;
+class Image;
+
+// A set of image transformations used in Widelands.
+namespace ImageTransformations {
+
+// This must be called once before any of the functions below are called. This
+// is done when the graphics system is initialized.
+void initialize();
+
+// All of the functions below take an original image, transform it, cache the
+// newly created image in the global ImageCache and return it. It is therefore
+// safe to call the methods with the same arguments multiple times without
+// construction cost.
+
+// Returns a resized image of the original.
+const Image* resize(const Image* original, uint16_t w, uint16_t h);
+
+// Returns a grayed out image of the original.
+const Image* gray_out(const Image* original);
+
+// Returns an image with a modified luminosity by 'factor' and alpha value than
+// the original. If 'halve_alpha' is true, the opacity will be halfed,
+// otherwise it will not be touched.
+const Image* change_luminosity(const Image* original, float factor, bool halve_alpha);
+
+// Encodes the given Image into the corresponding image with a player color.
+// Takes the image and the player color mask and the new color the image should
+// be tainted in.
+const Image* player_colored(const RGBColor& clr, const Image* original, const Image* mask);
+}
+
+
+#endif /* end of include guard: IMAGE_TRANSFORMATIONS_H */
+

=== added file 'src/graphic/in_memory_image.cc'
--- src/graphic/in_memory_image.cc	1970-01-01 00:00:00 +0000
+++ src/graphic/in_memory_image.cc	2013-02-10 14:53:26 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006-2013 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <boost/scoped_ptr.hpp>
+
+#include "image.h"
+#include "surface.h"
+
+#include "in_memory_image.h"
+
+using namespace std;
+
+// An Image implementation the does !not! cache its Surface in the
+// SurfaceCache. Avoid using this whenever possible and also do not store it in
+// the ImageCache.
+//
+// This is only used when the surface can not be easily recalculated on the fly
+// or if ownership of the image is managed by the caller itself. Note that this
+// is always tricky because Widelands assumes in many places that Images can be
+// relied to exist forever. So when you pass out a pointer to your
+// InMemoryImage, be prepared to keep it valid forever, or check all callsites
+// or prepare for core dumps.
+class InMemoryImage : public Image {
+public:
+	InMemoryImage(const string& hash, Surface* surf) :
+		hash_(hash), surf_(surf) {}
+	virtual ~InMemoryImage() {}
+
+	// Implements Image.
+	virtual uint16_t width() const {return surf_->width();}
+	virtual uint16_t height() const {return surf_->height();}
+	// Note: hash will mostly be dummy values for this implementation. It should
+	// not wind up in ImageCache, otherwise the ownership question is not clear.
+	virtual const string& hash() const {return hash_;}
+	virtual Surface* surface() const {return surf_.get();}
+
+private:
+	const string hash_;
+	boost::scoped_ptr<Surface> surf_;
+};
+
+const Image* new_in_memory_image(const string& hash, Surface* surf) {
+	return new InMemoryImage(hash, surf);
+}
+
+
+
+

=== added file 'src/graphic/in_memory_image.h'
--- src/graphic/in_memory_image.h	1970-01-01 00:00:00 +0000
+++ src/graphic/in_memory_image.h	2013-02-10 14:53:26 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006-2013 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef IN_MEMORY_IMAGE_H
+#define IN_MEMORY_IMAGE_H
+
+#include <string>
+
+class Image;
+class Surface;
+
+const Image* new_in_memory_image(const std::string& hash, Surface* surf);
+
+#endif /* end of include guard: IN_MEMORY_IMAGE_H */
+

=== modified file 'src/graphic/render/gameview.cc'
--- src/graphic/render/gameview.cc	2012-12-14 20:09:35 +0000
+++ src/graphic/render/gameview.cc	2013-02-10 14:53:26 +0000
@@ -402,7 +402,7 @@
 										anim = csinf->becomes->get_animation("idle");
 									}
 								}
-								const AnimationGfx::Index nr_frames = g_gr->nr_frames(anim);
+								const size_t nr_frames = g_gr->nr_frames(anim);
 								uint32_t cur_frame =
 									csinf->totaltime ? csinf->completedtime * nr_frames / csinf->totaltime : 0;
 								uint32_t tanim = cur_frame * FRAME_LENGTH;
@@ -412,7 +412,7 @@
 								if (csinf->totaltime)
 									lines /= csinf->totaltime;
 								assert(h * cur_frame <= lines);
-								lines -= h * cur_frame; //  This won't work if pictures have various sizes.
+								lines -= h * cur_frame; //  This won't work if images have various sizes.
 
 								if (cur_frame) // not the first frame
 									// draw the prev frame from top to where next image will be drawing
@@ -420,7 +420,7 @@
 										(f_pos, anim, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
 								else if (csinf->was) {
 									// Is the first frame, but there was another building here before,
-									// get its last build picture and draw it instead.
+									// get its last build images and draw it instead.
 									uint32_t a;
 									try {
 										a = csinf->was->get_animation("unoccupied");
@@ -1345,7 +1345,6 @@
 
 	SDL_UnlockSurface(surface);
 
-	IPicture* picture = g_gr->convert_sdl_surface_to_picture(surface);
-
-	m_surface->blit(Point(rc.x, rc.y), picture, rc2);
+	boost::scoped_ptr<Surface> minimap_surface(Surface::create(surface));
+	m_surface->blit(Point(rc.x, rc.y), minimap_surface.get(), rc2);
 }

=== modified file 'src/graphic/render/gameview_sdl.cc'
--- src/graphic/render/gameview_sdl.cc	2012-12-07 20:25:12 +0000
+++ src/graphic/render/gameview_sdl.cc	2013-02-10 14:53:26 +0000
@@ -31,7 +31,6 @@
 #include "logic/map.h"
 #include "logic/player.h"
 
-#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "graphic/surface.h"
 #include "graphic/texture.h"

=== modified file 'src/graphic/render/gl_surface.cc'
--- src/graphic/render/gl_surface.cc	2013-01-05 23:08:45 +0000
+++ src/graphic/render/gl_surface.cc	2013-02-10 14:53:26 +0000
@@ -25,11 +25,11 @@
 
 #include "gl_surface.h"
 
-uint32_t GLSurface::get_w() const {
+uint16_t GLSurface::width() const {
 	return m_w;
 }
 
-uint32_t GLSurface::get_h() const {
+uint16_t GLSurface::height() const {
 	return m_h;
 }
 
@@ -38,7 +38,7 @@
 	return m_pixels.get();
 }
 
-uint32_t GLSurface::get_pixel(uint32_t x, uint32_t y) {
+uint32_t GLSurface::get_pixel(uint16_t x, uint16_t y) {
 	assert(m_pixels);
 	assert(x < m_w);
 	assert(y < m_h);
@@ -47,7 +47,7 @@
 	return *(reinterpret_cast<uint32_t *>(data));
 }
 
-void GLSurface::set_pixel(uint32_t x, uint32_t y, uint32_t clr) {
+void GLSurface::set_pixel(uint16_t x, uint16_t y, uint32_t clr) {
 	assert(m_pixels);
 	assert(x < m_w);
 	assert(y < m_h);
@@ -169,14 +169,14 @@
 }
 
 void GLSurface::blit
-	(const Point& dst, const IPicture* pic, const Rect& srcrc, Composite cm)
+	(const Point& dst, const Surface* image, const Rect& srcrc, Composite cm)
 {
 	// Note: This function is highly optimized and therefore does not restore
 	// all state. It also assumes that all other glStuff restores state to make
 	// this function faster.
 
 	assert(g_opengl);
-	const GLSurfaceTexture* src = static_cast<const GLSurfaceTexture*>(pic);
+	const GLSurfaceTexture& surf = *static_cast<const GLSurfaceTexture*>(image);
 
 	/* Set a texture scaling factor. Normally texture coordinates
 	* (see glBegin()...glEnd() Block below) are given in the range 0-1
@@ -189,8 +189,8 @@
 	glMatrixMode(GL_TEXTURE);
 	glLoadIdentity();
 	glScalef
-		(1.0f / static_cast<GLfloat>(src->get_tex_w()),
-		 1.0f / static_cast<GLfloat>(src->get_tex_h()), 1);
+		(1.0f / static_cast<GLfloat>(surf.get_tex_w()),
+		 1.0f / static_cast<GLfloat>(surf.get_tex_h()), 1);
 
 	// Enable Alpha blending
 	if (cm == CM_Normal) {
@@ -200,7 +200,7 @@
 		glDisable(GL_BLEND);
 	}
 
-	glBindTexture(GL_TEXTURE_2D, src->get_gl_texture());
+	glBindTexture(GL_TEXTURE_2D, surf.get_gl_texture());
 
 	glBegin(GL_QUADS); {
 		// set color white, otherwise textures get mixed with color

=== modified file 'src/graphic/render/gl_surface.h'
--- src/graphic/render/gl_surface.h	2012-12-15 18:40:59 +0000
+++ src/graphic/render/gl_surface.h	2013-02-10 14:53:26 +0000
@@ -33,13 +33,13 @@
 	virtual ~GLSurface() {}
 
 	/// Interface implementations
-	virtual uint32_t get_w() const;
-	virtual uint32_t get_h() const;
+	virtual uint16_t width() const;
+	virtual uint16_t height() const;
 	virtual uint8_t * get_pixels() const;
-	virtual void set_pixel(uint32_t x, uint32_t y, uint32_t clr);
-	virtual uint32_t get_pixel(uint32_t x, uint32_t y);
+	virtual void set_pixel(uint16_t x, uint16_t y, uint32_t clr);
+	virtual uint32_t get_pixel(uint16_t x, uint16_t y);
 
-	virtual void blit(const Point&, const IPicture*, const Rect& srcrc, Composite cm);
+	virtual void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm);
 	virtual void fill_rect(const Rect&, RGBAColor);
 	virtual void draw_rect(const Rect&, RGBColor);
 	virtual void brighten_rect(const Rect&, int32_t factor);
@@ -50,7 +50,7 @@
 protected:
 
 	/// Logical width and height of the surface
-	uint32_t m_w, m_h;
+	uint16_t m_w, m_h;
 
 	/// Pixel data, while the texture is locked
 	boost::scoped_array<uint8_t> m_pixels;

=== modified file 'src/graphic/render/gl_surface_screen.cc'
--- src/graphic/render/gl_surface_screen.cc	2012-12-15 12:04:36 +0000
+++ src/graphic/render/gl_surface_screen.cc	2013-02-10 14:53:26 +0000
@@ -19,7 +19,7 @@
 #include "gl_utils.h"
 #include "gl_surface_screen.h"
 
-GLSurfaceScreen::GLSurfaceScreen(uint32_t w, uint32_t h)
+GLSurfaceScreen::GLSurfaceScreen(uint16_t w, uint16_t h)
 {
 	m_w = w;
 	m_h = h;
@@ -36,7 +36,7 @@
 	uint8_t * end_row = m_pixels.get() + (m_w * (m_h - 1) * 4);
 
 	while (begin_row < end_row) {
-		for (uint32_t x = 0; x < m_w * 4; ++x)
+		for (uint16_t x = 0; x < m_w * 4; ++x)
 			std::swap(begin_row[x], end_row[x]);
 
 		begin_row += m_w * 4;
@@ -45,7 +45,7 @@
 }
 
 const SDL_PixelFormat & GLSurfaceScreen::format() const {
-	return gl_rgb_format();
+	return gl_rgba_format();
 }
 
 void GLSurfaceScreen::lock(Surface::LockMode mode)

=== modified file 'src/graphic/render/gl_surface_screen.h'
--- src/graphic/render/gl_surface_screen.h	2012-12-15 12:04:36 +0000
+++ src/graphic/render/gl_surface_screen.h	2013-02-10 14:53:26 +0000
@@ -28,7 +28,8 @@
  */
 class GLSurfaceScreen : public GLSurface {
 public:
-	GLSurfaceScreen(uint32_t w, uint32_t h);
+	GLSurfaceScreen(uint16_t w, uint16_t h);
+	virtual ~GLSurfaceScreen() {}
 
 	/// Interface implementations
 	virtual void lock(LockMode);

=== modified file 'src/graphic/render/gl_surface_texture.cc'
--- src/graphic/render/gl_surface_texture.cc	2013-01-04 09:59:13 +0000
+++ src/graphic/render/gl_surface_texture.cc	2013-02-10 14:53:26 +0000
@@ -16,7 +16,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 #include "wexception.h"
 #include "graphic/graphic.h"
 
@@ -70,9 +69,8 @@
  *
  * The initial data of the texture is undefined.
  */
-GLSurfaceTexture::GLSurfaceTexture(int w, int h, bool alpha)
+GLSurfaceTexture::GLSurfaceTexture(int w, int h)
 {
-	has_alpha_ = alpha;
 	init(w, h);
 
 	glTexImage2D
@@ -122,13 +120,11 @@
 		{
 			if (fmt.Amask == 0xff000000) {
 				pixels_format = GL_RGBA;
-				has_alpha_ = true;
 			} else {
 				pixels_format = GL_RGBA;
 				// Read four bytes per pixel but ignore the alpha value
 				glPixelTransferi(GL_ALPHA_SCALE, 0.0f);
 				glPixelTransferi(GL_ALPHA_BIAS, 1.0f);
-				has_alpha_ = false;
 			}
 		} else if
 			(fmt.Bmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
@@ -136,18 +132,15 @@
 		{
 			if (fmt.Amask == 0xff000000) {
 				pixels_format = GL_BGRA;
-				has_alpha_ = true;
 			} else {
 				pixels_format = GL_BGRA;
 				// Read four bytes per pixel but ignore the alpha value
 				glPixelTransferi(GL_ALPHA_SCALE, 0.0f);
 				glPixelTransferi(GL_ALPHA_BIAS, 1.0f);
-				has_alpha_ = false;
 			}
 		} else
 			throw wexception("OpenGL: Unknown pixel format");
 	} else  if (bpp == 3) {
-		has_alpha_ = false;
 		if
 			(fmt.Rmask == 0x000000ff and fmt.Gmask == 0x0000ff00 and
 			 fmt.Bmask == 0x00ff0000)
@@ -181,7 +174,7 @@
 	glDeleteTextures(1, &m_texture);
 }
 
-void GLSurfaceTexture::init(uint32_t w, uint32_t h)
+void GLSurfaceTexture::init(uint16_t w, uint16_t h)
 {
 	handle_glerror();
 	m_w = w;
@@ -208,7 +201,7 @@
 }
 
 const SDL_PixelFormat & GLSurfaceTexture::format() const {
-	return has_alpha_ ? gl_rgba_format() : gl_rgba_format();
+	return gl_rgba_format();
 }
 
 void GLSurfaceTexture::lock(LockMode mode) {
@@ -275,9 +268,9 @@
 }
 
 void GLSurfaceTexture::blit
-	(const Point& dst, const IPicture* src, const Rect& srcrc, Composite cm) {
+	(const Point& dst, const Surface* src, const Rect& srcrc, Composite cm) {
 	setup_gl();
-	GLSurface::blit(dst, static_cast<const GLSurfaceTexture*>(src), srcrc, cm);
+	GLSurface::blit(dst, src, srcrc, cm);
 	reset_gl();
 }
 

=== modified file 'src/graphic/render/gl_surface_texture.h'
--- src/graphic/render/gl_surface_texture.h	2012-12-15 18:40:59 +0000
+++ src/graphic/render/gl_surface_texture.h	2013-02-10 14:53:26 +0000
@@ -31,7 +31,7 @@
 	static void Cleanup();
 
 	GLSurfaceTexture(SDL_Surface * surface);
-	GLSurfaceTexture(int w, int h, bool alpha);
+	GLSurfaceTexture(int w, int h);
 	virtual ~GLSurfaceTexture();
 
 	/// Interface implementation
@@ -53,14 +53,14 @@
 	virtual void brighten_rect(const Rect&, int32_t factor);
 	virtual void draw_line
 		(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor&, uint8_t width);
-	virtual void blit(const Point&, const IPicture*, const Rect& srcrc, Composite cm);
+	virtual void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm);
 
 	GLuint get_gl_texture() const {return m_texture;}
-	uint32_t get_tex_w() const {return m_tex_w;}
-	uint32_t get_tex_h() const {return m_tex_h;}
+	uint16_t get_tex_w() const {return m_tex_w;}
+	uint16_t get_tex_h() const {return m_tex_h;}
 
 private:
-	void init(uint32_t w, uint32_t h);
+	void init(uint16_t w, uint16_t h);
 	void setup_gl();
 	void reset_gl();
 
@@ -69,7 +69,7 @@
 
 	/// Keep the size of the opengl texture. This is necessary because some
 	/// systems support only a power of two for texture sizes.
-	uint32_t m_tex_w, m_tex_h;
+	uint16_t m_tex_w, m_tex_h;
 
 	/// Internally, all surfaces are with alpha channel. We can ignore it, when
 	/// we should not have one, though.

=== modified file 'src/graphic/render/gl_utils.cc'
--- src/graphic/render/gl_utils.cc	2012-12-15 12:04:36 +0000
+++ src/graphic/render/gl_utils.cc	2013-02-10 14:53:26 +0000
@@ -60,29 +60,6 @@
 	return format;
 }
 
-const SDL_PixelFormat & gl_rgb_format()
-{
-	static SDL_PixelFormat format;
-	static bool init = false;
-	if (init)
-		return format;
-
-	init = true;
-	memset(&format, 0, sizeof(format));
-	format.BitsPerPixel = 32;
-	format.BytesPerPixel = 4;
-	format.Rmask = 0x000000ff;
-	format.Gmask = 0x0000ff00;
-	format.Bmask = 0x00ff0000;
-	format.Amask = 0x00000000;
-	format.Rshift = 0;
-	format.Gshift = 8;
-	format.Bshift = 16;
-	format.Ashift = 24;
-	return format;
-}
-
-
 GLenum _handle_glerror(const char * file, unsigned int line)
 {
 	GLenum err = glGetError();

=== modified file 'src/graphic/render/gl_utils.h'
--- src/graphic/render/gl_utils.h	2012-12-15 12:04:36 +0000
+++ src/graphic/render/gl_utils.h	2013-02-10 14:53:26 +0000
@@ -29,7 +29,6 @@
 
 uint32_t next_power_of_two(uint32_t x);
 const SDL_PixelFormat & gl_rgba_format();
-const SDL_PixelFormat & gl_rgb_format();
 GLenum _handle_glerror(const char * file, unsigned int line);
 
 /**

=== renamed file 'src/graphic/text/sdl_helper.cc' => 'src/graphic/render/sdl_helper.cc'
--- src/graphic/text/sdl_helper.cc	2012-12-15 18:40:59 +0000
+++ src/graphic/render/sdl_helper.cc	2013-02-10 14:53:26 +0000
@@ -17,18 +17,13 @@
  *
  */
 
-#include <boost/format.hpp>
+#include <cassert>
+
 #include <SDL.h>
 
-#include "rt_errors.h"
-
 #include "sdl_helper.h"
 
-using namespace boost;
-
-namespace RT {
-
-SDL_Surface * empty_sdl_surface(int32_t w, int32_t h, bool alpha) {
+SDL_Surface * empty_sdl_surface(int16_t w, int16_t h) {
 	SDL_Surface* surface;
 	Uint32 rmask, gmask, bmask, amask;
 	/* SDL interprets each pixel as a 32-bit number, so our masks must depend
@@ -37,22 +32,17 @@
 	rmask = 0xff000000;
 	gmask = 0x00ff0000;
 	bmask = 0x0000ff00;
-	amask = alpha ? 0x000000ff : 0;
+	amask = 0x000000ff;
 #else
 	rmask = 0x000000ff;
 	gmask = 0x0000ff00;
 	bmask = 0x00ff0000;
-	amask = alpha ? 0xff000000 : 0;
+	amask = 0xff000000;
 #endif
 
-	surface = SDL_CreateRGBSurface
-		(SDL_SWSURFACE, w, h, 32, rmask, gmask, bmask, amask);
-	if (!surface)
-		throw RenderError((format("Was unable to create a Surface: %s") % SDL_GetError()).str());
+	surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, rmask, gmask, bmask, amask);
+	assert(surface);
 
 	return surface;
 }
 
-}
-
-

=== renamed file 'src/graphic/text/sdl_helper.h' => 'src/graphic/render/sdl_helper.h'
--- src/graphic/text/sdl_helper.h	2012-12-02 21:11:05 +0000
+++ src/graphic/render/sdl_helper.h	2013-02-10 14:53:26 +0000
@@ -22,11 +22,7 @@
 
 struct SDL_Surface;
 
-namespace RT {
-
-SDL_Surface * empty_sdl_surface(int32_t w, int32_t h, bool alpha);
-
-};
+SDL_Surface * empty_sdl_surface(int16_t w, int16_t h);
 
 #endif /* end of include guard: SDL_HELPER_H */
 

=== modified file 'src/graphic/render/sdl_surface.cc'
--- src/graphic/render/sdl_surface.cc	2013-01-06 10:42:06 +0000
+++ src/graphic/render/sdl_surface.cc	2013-02-10 14:53:26 +0000
@@ -24,18 +24,9 @@
 #include "sdl_surface.h"
 
 SDLSurface::~SDLSurface() {
-	if (m_surface)
-		SDL_FreeSurface(m_surface);
-}
-
-void SDLSurface::set_sdl_surface(SDL_Surface & surface)
-{
-	if (m_surface)
-		SDL_FreeSurface(m_surface);
-
-	m_surface = &surface;
-	m_w = m_surface->w;
-	m_h = m_surface->h;
+	assert(m_surface);
+
+	SDL_FreeSurface(m_surface);
 }
 
 const SDL_PixelFormat & SDLSurface::format() const {
@@ -64,12 +55,12 @@
 		SDL_UnlockSurface(m_surface);
 }
 
-uint32_t SDLSurface::get_pixel(uint32_t x, uint32_t y) {
+uint32_t SDLSurface::get_pixel(uint16_t x, uint16_t y) {
 	x += m_offsx;
 	y += m_offsy;
 
-	assert(x < get_w());
-	assert(y < get_h());
+	assert(x < width());
+	assert(y < height());
 	assert(m_surface);
 
 	// Locking not needed: reading only
@@ -106,11 +97,11 @@
 	return 0; // Should never be here
 }
 
-void SDLSurface::set_pixel(uint32_t x, uint32_t y, const Uint32 clr) {
+void SDLSurface::set_pixel(uint16_t x, uint16_t y, const Uint32 clr) {
 	x += m_offsx;
 	y += m_offsy;
 
-	if (x >= get_w() || y >= get_h())
+	if (x >= width() || y >= height())
 		return;
 	assert(m_surface);
 
@@ -153,8 +144,7 @@
 	assert(m_surface);
 	assert(rc.x >= 0);
 	assert(rc.y >= 0);
-	assert(rc.w >= 1);
-	assert(rc.h >= 1);
+
 	const uint32_t color = clr.map(format());
 
 	const Point bl = rc.bottom_right() - Point(1, 1);
@@ -179,8 +169,7 @@
 	assert(m_surface);
 	assert(rc.x >= 0);
 	assert(rc.y >= 0);
-	assert(rc.w >= 1);
-	assert(rc.h >= 1);
+
 	const uint32_t color = clr.map(format());
 
 	SDL_Rect r = {
@@ -330,9 +319,9 @@
 
 
 void SDLSurface::blit
-	(const Point& dst, const IPicture* src, const Rect& srcrc, Composite cm)
+	(const Point& dst, const Surface* src, const Rect& srcrc, Composite cm)
 {
-	const SDLSurface* sdlsurf = static_cast<const SDLSurface*>(src);
+	SDL_Surface* sdlsurf = static_cast<const SDLSurface*>(src)->get_sdl_surface();
 	SDL_Rect srcrect = {
 		static_cast<Sint16>(srcrc.x), static_cast<Sint16>(srcrc.y),
 		static_cast<Uint16>(srcrc.w), static_cast<Uint16>(srcrc.h)
@@ -345,14 +334,14 @@
 	bool alpha;
 	uint8_t alphaval;
 	if (cm == CM_Solid || cm == CM_Copy) {
-		alpha = sdlsurf->get_sdl_surface()->flags & SDL_SRCALPHA;
-		alphaval = sdlsurf->get_sdl_surface()->format->alpha;
-		SDL_SetAlpha(sdlsurf->get_sdl_surface(), 0, 0);
+		alpha = sdlsurf->flags & SDL_SRCALPHA;
+		alphaval = sdlsurf->format->alpha;
+		SDL_SetAlpha(sdlsurf, 0, 0);
 	}
 
-	SDL_BlitSurface(sdlsurf->get_sdl_surface(), &srcrect, m_surface, &dstrect);
+	SDL_BlitSurface(sdlsurf, &srcrect, m_surface, &dstrect);
 
 	if (cm == CM_Solid || cm == CM_Copy) {
-		SDL_SetAlpha(sdlsurf->get_sdl_surface(), alpha?SDL_SRCALPHA:0, alphaval);
+		SDL_SetAlpha(sdlsurf, alpha?SDL_SRCALPHA:0, alphaval);
 	}
 }

=== modified file 'src/graphic/render/sdl_surface.h'
--- src/graphic/render/sdl_surface.h	2012-12-15 18:40:59 +0000
+++ src/graphic/render/sdl_surface.h	2013-02-10 14:53:26 +0000
@@ -30,23 +30,22 @@
 * way is to use the base struct Surface wherever possible. Everything which
 * needs to know about the underlying renderer should go to the graphics
 * subdirectory.
-* Surfaces are created through Graphic::create_surface() functions.
 */
 class SDLSurface : public Surface {
 public:
-	SDLSurface(SDL_Surface & surface) :
-		m_surface(&surface),
+	SDLSurface(SDL_Surface* surface) :
+		m_surface(surface),
 		m_offsx(0), m_offsy(0),
-		m_w(surface.w), m_h(surface.h)
+		m_w(surface->w), m_h(surface->h)
 	{}
 	virtual ~SDLSurface();
 
-	// Implements IPicture
-	virtual uint32_t get_w() const {return m_w;}
-	virtual uint32_t get_h() const {return m_h;}
+	// Implements Image
+	virtual uint16_t width() const {return m_w;}
+	virtual uint16_t height() const {return m_h;}
 
-	// Implements IBlitableSurface
-	virtual void blit(const Point&, const IPicture*, const Rect& srcrc, Composite cm);
+	// Implements Surface
+	virtual void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm);
 	virtual void fill_rect(const Rect&, RGBAColor);
 
 	// Implements Surface
@@ -58,13 +57,11 @@
 	virtual SDL_PixelFormat const & format() const;
 	virtual void lock(LockMode);
 	virtual void unlock(UnlockMode);
-	virtual uint32_t get_pixel(uint32_t x, uint32_t y);
-	virtual void set_pixel(uint32_t x, uint32_t y, Uint32 clr);
+	virtual uint32_t get_pixel(uint16_t x, uint16_t y);
+	virtual void set_pixel(uint16_t x, uint16_t y, Uint32 clr);
 	virtual uint16_t get_pitch() const {return m_surface->pitch;}
 	virtual uint8_t * get_pixels() const;
 
-	/// Set surface, only call once
-	void set_sdl_surface(SDL_Surface & surface);
 	SDL_Surface * get_sdl_surface() const {return m_surface;}
 
 	void set_subwin(const Rect& r);
@@ -74,7 +71,7 @@
 	SDL_Surface * m_surface;
 	int32_t m_offsx;
 	int32_t m_offsy;
-	uint32_t m_w, m_h;
+	uint16_t m_w, m_h;
 };
 
 

=== modified file 'src/graphic/render/terrain_opengl.h'
--- src/graphic/render/terrain_opengl.h	2012-12-07 07:32:24 +0000
+++ src/graphic/render/terrain_opengl.h	2013-02-10 14:53:26 +0000
@@ -90,8 +90,8 @@
 			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
 			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
 
-			GLuint edge = dynamic_cast<GLSurfaceTexture const &>
-				(*g_gr->get_edge_texture()).get_gl_texture();
+			GLuint edge = static_cast<const GLSurfaceTexture&>
+				(g_gr->get_edge_texture()).get_gl_texture();
 
 			// combine current and top texture
 			glActiveTextureARB(GL_TEXTURE2_ARB);
@@ -117,8 +117,8 @@
 			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
 			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
 
-			GLuint edge = dynamic_cast<GLSurfaceTexture const &>
-				(*g_gr->get_edge_texture()).get_gl_texture();
+			GLuint edge = static_cast<const GLSurfaceTexture&>
+				(g_gr->get_edge_texture()).get_gl_texture();
 
 			// combine current and left texture
 			glActiveTextureARB(GL_TEXTURE4_ARB);
@@ -271,11 +271,11 @@
 	uint8_t road;
 
 	GLuint rt_normal =
-		dynamic_cast<GLSurfaceTexture const &>
-		(*g_gr->get_road_texture(Widelands::Road_Normal)).get_gl_texture();
+		static_cast<const GLSurfaceTexture&>
+		(g_gr->get_road_texture(Widelands::Road_Normal)).get_gl_texture();
 	GLuint rt_busy   =
-		dynamic_cast<GLSurfaceTexture const &>
-		(*g_gr->get_road_texture(Widelands::Road_Busy)).get_gl_texture();
+		static_cast<const GLSurfaceTexture&>
+		(g_gr->get_road_texture(Widelands::Road_Busy)).get_gl_texture();
 
 	glDisable(GL_BLEND);
 	glColor4f(1.0f, 1.0f, 1.0f, 0.6f);

=== modified file 'src/graphic/render/terrain_sdl.h'
--- src/graphic/render/terrain_sdl.h	2012-12-15 18:40:59 +0000
+++ src/graphic/render/terrain_sdl.h	2013-02-10 14:53:26 +0000
@@ -131,10 +131,10 @@
 	}
 
 	// Cut off lines below screen
-	if (y + height > static_cast<int32_t>(dst.get_h()))
-		height = dst.get_h() - y;
+	if (y + height > static_cast<int32_t>(dst.height()))
+		height = dst.height() - y;
 
-	int32_t dstw = dst.get_w();
+	int32_t dstw = dst.width();
 	while (height > 0) {
 		int32_t leftx = FIXTOI(left->x0);
 		int32_t rightx = FIXTOI(right->x0);
@@ -370,8 +370,8 @@
 	// TODO: seed this depending on field coordinates
 	uint32_t rnd = 0;
 
-	const int32_t dstw = dst.get_w();
-	const int32_t dsth = dst.get_h();
+	const int32_t dstw = dst.width();
+	const int32_t dsth = dst.height();
 
 	int32_t ydiff = ITOFIX(end.y - start.y) / (end.x - start.x);
 	int32_t centery = ITOFIX(start.y);
@@ -467,8 +467,8 @@
 	// TODO: seed this depending on field coordinates
 	uint32_t rnd = 0;
 
-	const int32_t dstw = dst.get_w();
-	const int32_t dsth = dst.get_h();
+	const int32_t dstw = dst.width();
+	const int32_t dsth = dst.height();
 
 	int32_t xdiff = ITOFIX(end.x - start.x) / (end.y - start.y);
 	int32_t centerx = ITOFIX(start.x);
@@ -535,8 +535,8 @@
 template<typename T> static void render_road_horiz
 	(SDLSurface & dst, Point const start, Point const end, SDLSurface const & src)
 {
-	int32_t const dstw = dst.get_w();
-	int32_t const dsth = dst.get_h();
+	int32_t const dstw = dst.width();
+	int32_t const dsth = dst.height();
 
 	int32_t const ydiff = ((end.y - start.y) << 16) / (end.x - start.x);
 	int32_t centery = start.y << 16;
@@ -562,8 +562,8 @@
 template<typename T> static void render_road_vert
 	(SDLSurface & dst, Point const start, Point const end, SDLSurface const & src)
 {
-	int32_t const dstw = dst.get_w();
-	int32_t const dsth = dst.get_h();
+	int32_t const dstw = dst.width();
+	int32_t const dsth = dst.height();
 
 	int32_t const xdiff = ((end.x - start.x) << 16) / (end.y - start.y);
 	int32_t centerx = start.x << 16;
@@ -598,10 +598,8 @@
 	 Texture const &  f_d_texture,
 	 Texture const &  f_r_texture)
 {
-	SDLSurface* rt_busy = const_cast<SDLSurface*>
-		(static_cast<const SDLSurface*>(g_gr->get_road_texture(Widelands::Road_Busy)));
-	SDLSurface* rt_normal = const_cast<SDLSurface*>
-		(static_cast<const SDLSurface*>(g_gr->get_road_texture(Widelands::Road_Normal)));
+	SDLSurface& rt_busy = static_cast<SDLSurface&>(g_gr->get_road_texture(Widelands::Road_Busy));
+	SDLSurface& rt_normal = static_cast<SDLSurface&>(g_gr->get_road_texture(Widelands::Road_Normal));
 
 	dst.lock(Surface::Lock_Normal);
 
@@ -616,10 +614,10 @@
 		if (road) {
 			switch (road) {
 			case Widelands::Road_Normal:
-				render_road_horiz<T> (dst, f_vert, r_vert, *rt_normal);
+				render_road_horiz<T> (dst, f_vert, r_vert, rt_normal);
 				break;
 			case Widelands::Road_Busy:
-				render_road_horiz<T> (dst, f_vert, r_vert, *rt_busy);
+				render_road_horiz<T> (dst, f_vert, r_vert, rt_busy);
 				break;
 			default:
 				assert(false);
@@ -635,10 +633,10 @@
 		if (road) {
 			switch (road) {
 			case Widelands::Road_Normal:
-				render_road_vert<T> (dst, f_vert, br_vert, *rt_normal);
+				render_road_vert<T> (dst, f_vert, br_vert, rt_normal);
 				break;
 			case Widelands::Road_Busy:
-				render_road_vert<T> (dst, f_vert, br_vert, *rt_busy);
+				render_road_vert<T> (dst, f_vert, br_vert, rt_busy);
 				break;
 			default:
 				assert(false);
@@ -654,10 +652,10 @@
 		if (road) {
 			switch (road) {
 			case Widelands::Road_Normal:
-				render_road_vert<T> (dst, f_vert, bl_vert, *rt_normal);
+				render_road_vert<T> (dst, f_vert, bl_vert, rt_normal);
 				break;
 			case Widelands::Road_Busy:
-				render_road_vert<T> (dst, f_vert, bl_vert, *rt_busy);
+				render_road_vert<T> (dst, f_vert, bl_vert, rt_busy);
 				break;
 			default:
 				assert(false);

=== modified file 'src/graphic/rendertarget.cc'
--- src/graphic/rendertarget.cc	2012-12-16 17:06:00 +0000
+++ src/graphic/rendertarget.cc	2013-02-10 14:53:26 +0000
@@ -17,20 +17,21 @@
  *
  */
 
-#include "rendertarget.h"
-
-#include "graphic.h"
-#include "wui/mapviewpixelconstants.h"
-#include "wui/overlay_manager.h"
-
+#include "log.h"
 #include "logic/player.h"
 #include "logic/tribe.h"
+#include "upcast.h"
 #include "vertex.h"
+#include "wui/mapviewpixelconstants.h"
+#include "wui/overlay_manager.h"
 
+#include "animation.h"
+#include "animation_gfx.h"
+#include "graphic.h"
+#include "image_transformations.h"
 #include "surface.h"
 
-#include "log.h"
-#include "upcast.h"
+#include "rendertarget.h"
 
 using Widelands::BaseImmovable;
 using Widelands::Coords;
@@ -61,23 +62,23 @@
 
 	if (m_rect.x < 0) {
 		m_offset.x += m_rect.x;
-		m_rect.w = std::max(static_cast<int32_t>(m_rect.w) + m_rect.x, 0);
+		m_rect.w = std::max<int32_t>(m_rect.w + m_rect.x, 0);
 		m_rect.x = 0;
 	}
 
-	if (m_rect.x + m_rect.w > m_surface->get_w())
+	if (m_rect.x + m_rect.w > m_surface->width())
 		m_rect.w =
-			std::max(static_cast<int32_t>(m_surface->get_w()) - m_rect.x, 0);
+			std::max<int32_t>(m_surface->width() - m_rect.x, 0);
 
 	if (m_rect.y < 0) {
 		m_offset.y += m_rect.y;
-		m_rect.h = std::max(static_cast<int32_t>(m_rect.h) + m_rect.y, 0);
+		m_rect.h = std::max<int32_t>(m_rect.h + m_rect.y, 0);
 		m_rect.y = 0;
 	}
 
-	if (m_rect.y + m_rect.h > m_surface->get_h())
+	if (m_rect.y + m_rect.h > m_surface->height())
 		m_rect.h =
-			std::max(static_cast<int32_t>(m_surface->get_h()) - m_rect.y, 0);
+			std::max<int32_t>(m_surface->height() - m_rect.y, 0);
 }
 
 /**
@@ -111,17 +112,17 @@
 /**
  * Returns the true size of the render target (ignoring the window settings).
  */
-int32_t RenderTarget::get_w() const
+int32_t RenderTarget::width() const
 {
-	return m_surface->get_w();
+	return m_surface->width();
 }
 
 /**
  * Returns the true size of the render target (ignoring the window settings).
  */
-int32_t RenderTarget::get_h() const
+int32_t RenderTarget::height() const
 {
-	return m_surface->get_h();
+	return m_surface->height();
 }
 
 /**
@@ -159,41 +160,42 @@
 }
 
 /**
- * Blits a Picture on another Surface
+ * Blits a Image on another Surface
  *
  * This blit function copies the pixels to the destination surface.
  * If the source surface contains a alpha channel this is used during
  * the blit.
  */
-void RenderTarget::blit(const Point& dst, const IPicture* picture, Composite cm)
+void RenderTarget::blit(const Point& dst, const Image* image, Composite cm, UI::Align align)
 {
-	doblit
-		(dst,
-		 picture, Rect(Point(0, 0), picture->get_w(), picture->get_h()), cm);
+	Point dstpoint(dst);
+
+	UI::correct_for_align(align, image->width(), image->height(), &dstpoint);
+	doblit(dstpoint, image, Rect(Point(0, 0), image->width(), image->height()), cm);
 }
 
 /**
- * Like \ref blit, but use only a sub-rectangle of the source picture.
+ * Like \ref blit, but use only a sub-rectangle of the source image.
  */
 void RenderTarget::blitrect
-	(Point const dst, const IPicture* picture, Rect const srcrc, Composite cm)
+	(Point const dst, const Image* image, Rect const srcrc, Composite cm)
 {
 	assert(0 <= srcrc.x);
 	assert(0 <= srcrc.y);
 
-	doblit(Rect(dst, 0, 0), picture, srcrc, cm);
+	doblit(dst, image, srcrc, cm);
 }
 
 /**
- * Fill the given rectangle with the given picture.
+ * Fill the given rectangle with the given image.
  *
- * The pixel from ofs inside picture is placed at the top-left corner of
+ * The pixel from ofs inside image is placed at the top-left corner of
  * the filled rectangle.
  */
-void RenderTarget::tile(Rect r, const IPicture* picture, Point ofs, Composite cm)
+void RenderTarget::tile(Rect r, const Image* image, Point ofs, Composite cm)
 {
-	int32_t srcw = picture->get_w();
-	int32_t srch = picture->get_h();
+	int32_t srcw = image->width();
+	int32_t srch = image->height();
 
 	if (clip(r)) {
 		if (m_offset.x < 0)
@@ -213,7 +215,7 @@
 		if (ofs.y < 0)
 			ofs.y += srch;
 
-		// Blit the picture into the rectangle
+		// Blit the image into the rectangle
 		uint32_t ty = 0;
 
 		while (ty < r.h) {
@@ -234,7 +236,7 @@
 				if (tx + srcrc.w > r.w)
 					srcrc.w = r.w - tx;
 
-				m_surface->blit(r + Point(tx, ty), picture, srcrc, cm);
+				m_surface->blit(r + Point(tx, ty), image->surface(), srcrc, cm);
 
 				tx += srcrc.w;
 
@@ -268,33 +270,27 @@
 	 uint32_t       const time,
 	 Player const * const player)
 {
-	//log("RenderTarget::drawanim()\n");
-	AnimationData const * const data = g_anim.get_animation(animation);
+	const AnimationData& data = g_anim.get_animation(animation);
 	AnimationGfx        * const gfx  = g_gr-> get_animation(animation);
-	if (!data || !g_gr) {
+	if (!gfx) {
 		log("WARNING: Animation %u does not exist\n", animation);
 		return;
 	}
 
 	// Get the frame and its data
-	uint32_t const framenumber = time / data->frametime % gfx->nr_frames();
-	const IPicture* frame =
-		player ?
-		gfx->get_frame
-			(framenumber, player->player_number(), player->get_playercolor())
-		:
-		gfx->get_frame
-			(framenumber);
-
-	dst -= gfx->get_hotspot();
-
-	Rect srcrc(Point(0, 0), frame->get_w(), frame->get_h());
-
-	doblit(Rect(dst, 0, 0), frame, srcrc);
+	uint32_t const framenumber = time / data.frametime % gfx->nr_frames();
+	const Image& frame =
+		player ? gfx->get_frame(framenumber, player->get_playercolor()) : gfx->get_frame(framenumber);
+
+	dst -= gfx->hotspot();
+
+	Rect srcrc(Point(0, 0), frame.width(), frame.height());
+
+	doblit(dst, &frame, srcrc);
 
 	//  Look if there is a sound effect registered for this frame and trigger
 	//  the effect (see Sound_Handler::stereo_position).
-	data->trigger_soundfx(framenumber, 128);
+	data.trigger_soundfx(framenumber, 128);
 }
 
 void RenderTarget::drawstatic
@@ -302,28 +298,19 @@
 	 uint32_t       const animation,
 	 Player const * const player)
 {
-	AnimationData const * const data = g_anim.get_animation(animation);
+	const AnimationData& data = g_anim.get_animation(animation);
 	AnimationGfx        * const gfx  = g_gr-> get_animation(animation);
-	if (!data || !g_gr) {
+	if (!gfx) {
 		log("WARNING: Animation %u does not exist\n", animation);
 		return;
 	}
 
 	// Get the frame and its data
-	const IPicture* frame =
-		player ?
-		gfx->get_frame
-			(0, player->player_number(), player->get_playercolor())
-		:
-		gfx->get_frame
-			(0);
-
-	const IPicture* dark_frame = g_gr->create_changed_luminosity_pic(frame, 1.22, true);
-
-	dst -= Point(frame->get_w() / 2, frame->get_h() / 2);
-
-	Rect srcrc(Point(0, 0), frame->get_w(), frame->get_h());
-
+	const Image& frame = player ? gfx->get_frame(0, player->get_playercolor()) : gfx->get_frame(0);
+	const Image* dark_frame = ImageTransformations::change_luminosity(&frame, 1.22, true);
+
+	dst -= Point(frame.width() / 2, frame.height() / 2);
+	Rect srcrc(Point(0, 0), frame.width(), frame.height());
 	doblit(Rect(dst, 0, 0), dark_frame, srcrc);
 }
 
@@ -337,29 +324,28 @@
 	 Player const * const player,
 	 Rect                 srcrc)
 {
-	//log("RenderTarget::drawanimrect()\n");
-	AnimationData const * const data = g_anim.get_animation(animation);
+	const AnimationData& data = g_anim.get_animation(animation);
 	AnimationGfx        * const gfx  = g_gr-> get_animation(animation);
-	if (!data || !g_gr) {
+	if (!gfx) {
 		log("WARNING: Animation %u does not exist\n", animation);
 		return;
 	}
 
 	// Get the frame and its data
-	uint32_t const framenumber = time / data->frametime % gfx->nr_frames();
-	const IPicture* frame =
+	uint32_t const framenumber = time / data.frametime % gfx->nr_frames();
+	const Image& frame =
 		player ?
 		gfx->get_frame
-			(framenumber, player->player_number(), player->get_playercolor())
+			(framenumber, player->get_playercolor())
 		:
 		gfx->get_frame
 			(framenumber);
 
-	dst -= g_gr->get_animation(animation)->get_hotspot();
+	dst -= g_gr->get_animation(animation)->hotspot();
 
 	dst += srcrc;
 
-	doblit(Rect(dst, 0, 0), frame, srcrc);
+	doblit(dst, &frame, srcrc);
 }
 
 /**
@@ -369,8 +355,8 @@
 void RenderTarget::reset()
 {
 	m_rect.x = m_rect.y = 0;
-	m_rect.w = m_surface->get_w();
-	m_rect.h = m_surface->get_h();
+	m_rect.w = m_surface->width();
+	m_rect.h = m_surface->height();
 
 	m_offset.x = m_offset.y = 0;
 }
@@ -422,7 +408,7 @@
  * Clip against window and source bitmap, then call the Bitmap blit routine.
  */
 void RenderTarget::doblit
-	(Point dst, const IPicture* src, Rect srcrc, Composite cm)
+	(Point dst, const Image* src, Rect srcrc, Composite cm)
 {
 	assert(0 <= srcrc.x);
 	assert(0 <= srcrc.y);
@@ -459,5 +445,5 @@
 
 	dst += m_rect;
 
-	m_surface->blit(dst, src, srcrc, cm);
+	m_surface->blit(dst, src->surface(), srcrc, cm);
 }

=== modified file 'src/graphic/rendertarget.h'
--- src/graphic/rendertarget.h	2012-12-15 18:40:59 +0000
+++ src/graphic/rendertarget.h	2013-02-10 14:53:26 +0000
@@ -20,12 +20,14 @@
 #ifndef RENDERTARGET_H
 #define RENDERTARGET_H
 
-#include "compositemode.h"
-#include "picture.h"
+#include <vector>
+
+#include "align.h"
 #include "rect.h"
 #include "rgbcolor.h"
 
-#include <vector>
+#include "compositemode.h"
+#include "image.h"
 
 class Surface;
 
@@ -54,8 +56,8 @@
 	void set_window(Rect const & rc, Point const & ofs);
 	bool enter_window(Rect const & rc, Rect * previous, Point * prevofs);
 
-	int32_t get_w() const;
-	int32_t get_h() const;
+	int32_t width() const;
+	int32_t height() const;
 
 	void draw_line
 		(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t width = 1);
@@ -63,9 +65,9 @@
 	void fill_rect(Rect, RGBAColor);
 	void brighten_rect(Rect, int32_t factor);
 
-	void blit(const Point& dst, const IPicture* picture, Composite cm = CM_Normal);
-	void blitrect(Point dst, const IPicture* picture, Rect src, Composite cm = CM_Normal);
-	void tile(Rect, const IPicture* picture, Point ofs, Composite cm = CM_Normal);
+	void blit(const Point& dst, const Image* image, Composite cm = CM_Normal, UI::Align = UI::Align_TopLeft);
+	void blitrect(Point dst, const Image* image, Rect src, Composite cm = CM_Normal);
+	void tile(Rect, const Image* image, Point ofs, Composite cm = CM_Normal);
 
 	void drawanim
 		(Point                     dst,
@@ -92,7 +94,7 @@
 protected:
 	bool clip(Rect & r) const throw ();
 
-	void doblit(Point dst, const IPicture* src, Rect srcrc, Composite cm = CM_Normal);
+	void doblit(Point dst, const Image* src, Rect srcrc, Composite cm = CM_Normal);
 
 	///The target surface
 	Surface* m_surface;

=== modified file 'src/graphic/richtext.cc'
--- src/graphic/richtext.cc	2012-12-13 10:41:22 +0000
+++ src/graphic/richtext.cc	2013-02-10 14:53:26 +0000
@@ -20,12 +20,12 @@
 #include "richtext.h"
 
 #include "font.h"
+#include "font_handler.h"
 #include "graphic.h"
-#include "picture.h"
+#include "image.h"
 #include "rect.h"
+#include "rendertarget.h"
 #include "text_parser.h"
-#include "rendertarget.h"
-#include "font_handler.h"
 
 namespace UI {
 
@@ -51,7 +51,7 @@
 };
 
 struct ImageElement : Element {
-	ImageElement(const Rect & _bbox, const IPicture* _image)
+	ImageElement(const Rect & _bbox, const Image* _image)
 		: Element(_bbox), image(_image) {}
 
 	virtual void draw(RenderTarget & dst)
@@ -59,7 +59,7 @@
 		dst.blit(Point(0, 0), image);
 	}
 
-	const IPicture* image;
+	const Image* image;
 };
 
 struct TextlineElement : Element {
@@ -333,19 +333,19 @@
 		text.images_width = 0;
 
 		for
-			(std::vector<std::string>::const_iterator img_it = cur_block_images.begin();
-			 img_it != cur_block_images.end();
-			 ++img_it)
+			(std::vector<std::string>::const_iterator image_it = cur_block_images.begin();
+			 image_it != cur_block_images.end();
+			 ++image_it)
 		{
-			const IPicture* image = g_gr->imgcache().load(PicMod_Game, *img_it);
+			const Image* image = g_gr->images().get(*image_it);
 			if (!image)
 				continue;
 
 			Rect bbox;
 			bbox.x = text.images_width;
 			bbox.y = m->height;
-			bbox.w = image->get_w();
-			bbox.h = image->get_h();
+			bbox.w = image->width();
+			bbox.h = image->height();
 
 			text.images_height = std::max(text.images_height, bbox.h);
 			text.images_width += bbox.w;

=== added file 'src/graphic/surface.cc'
--- src/graphic/surface.cc	1970-01-01 00:00:00 +0000
+++ src/graphic/surface.cc	2013-02-10 14:53:26 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006-2013 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <SDL.h>
+
+#include "render/gl_surface_texture.h"
+#include "render/sdl_helper.h"
+#include "render/sdl_surface.h"
+
+#include "surface.h"
+
+extern bool g_opengl;
+
+Surface* Surface::create(SDL_Surface* surf) {
+#ifdef USE_OPENGL
+	if (g_opengl) {
+		return new GLSurfaceTexture(surf);
+	}
+#endif
+	SDL_Surface * surface = SDL_DisplayFormatAlpha(surf);
+	SDL_FreeSurface(surf);
+	return new SDLSurface(surface);
+}
+
+Surface* Surface::create(uint16_t w, uint16_t h) {
+#ifdef USE_OPENGL
+	if (g_opengl) {
+		return new GLSurfaceTexture(w, h);
+	} else
+#endif
+	{
+		SDL_Surface* tsurf = empty_sdl_surface(w, h);
+		SDL_Surface* surf = SDL_DisplayFormatAlpha(tsurf);
+		SDL_FreeSurface(tsurf);
+		return new SDLSurface(surf);
+	}
+}
+
+

=== modified file 'src/graphic/surface.h'
--- src/graphic/surface.h	2012-12-15 18:40:59 +0000
+++ src/graphic/surface.h	2013-02-10 14:53:26 +0000
@@ -22,18 +22,36 @@
 
 #include <boost/noncopyable.hpp>
 
-#include "iblitable_surface.h"
 #include "rect.h"
 #include "rgbcolor.h"
 
+#include "compositemode.h"
+
 /**
  * Interface to a basic surfaces that can be used as destination for blitting and drawing.
  * It also allows low level pixel access.
  */
-class Surface : public IBlitableSurface {
+class Surface : boost::noncopyable {
 public:
+	// Create a new surface from an SDL_Surface. Ownership is taken.
+	static Surface* create(SDL_Surface*);
+
+	// Create a new empty (that is randomly filled) Surface with the given
+	// dimensions.
+	static Surface* create(uint16_t w, uint16_t h);
+
 	virtual ~Surface() {}
 
+	/// Dimensions.
+	virtual uint16_t width() const = 0;
+	virtual uint16_t height() const = 0;
+
+	/// This draws a part of another surface to this surface
+	virtual void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm = CM_Normal) = 0;
+
+	/// Draws a filled rect to the surface.
+	virtual void fill_rect(const Rect&, RGBAColor) = 0;
+
 	/// Draws a rect (frame only) to the surface.
 	virtual void draw_rect(const Rect&, RGBColor) = 0;
 
@@ -94,8 +112,8 @@
 	//@}
 
 	//@{
-	virtual uint32_t get_pixel(uint32_t x, uint32_t y) = 0;
-	virtual void set_pixel(uint32_t x, uint32_t y, uint32_t clr) = 0;
+	virtual uint32_t get_pixel(uint16_t x, uint16_t y) = 0;
+	virtual void set_pixel(uint16_t x, uint16_t y, uint32_t clr) = 0;
 	//@}
 
 	/**

=== added file 'src/graphic/surface_cache.cc'
--- src/graphic/surface_cache.cc	1970-01-01 00:00:00 +0000
+++ src/graphic/surface_cache.cc	2013-02-10 14:53:26 +0000
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2006-2013 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <map>
+#include <list>
+
+#include <SDL.h>
+#include <boost/scoped_ptr.hpp>
+
+#include "surface.h"
+#include "log.h"
+
+#include "surface_cache.h"
+
+using namespace std;
+
+// I took inspiration from http://timday.bitbucket.org/lru.html, but our use
+// case here is a little different.
+namespace  {
+class SurfaceCacheImpl : public SurfaceCache {
+public:
+	SurfaceCacheImpl(uint32_t max_memory) :
+		max_memory_(max_memory), used_memory_(0) {}
+	virtual ~SurfaceCacheImpl();
+
+	// Implements SurfaceCache.
+	virtual Surface* get(const std::string& hash);
+	virtual Surface* insert(const std::string& hash, Surface*);
+
+private:
+	void drop();
+
+	typedef list<string> AccessHistory;
+	struct Entry {
+		Entry(Surface* gs, const AccessHistory::iterator& it) :
+			surface(gs), last_access(SDL_GetTicks()), list_iterator(it) {}
+
+		boost::scoped_ptr<Surface> surface;
+		uint32_t last_access;  // Mainly for debugging and analysis.
+		const AccessHistory::iterator list_iterator;
+	};
+	typedef map<string, Entry*> Container;
+
+	uint32_t max_memory_;
+	uint32_t used_memory_;
+	Container map_;
+	AccessHistory hist_;
+};
+
+SurfaceCacheImpl::~SurfaceCacheImpl() {
+}
+
+Surface* SurfaceCacheImpl::get(const std::string& hash) {
+	const Container::iterator it = map_.find(hash);
+	if (it == map_.end())
+		return NULL;
+
+	// Move this to the back of the access list to signal that we have used this
+	// recently and update last access time.
+	hist_.splice(hist_.end(), hist_, it->second->list_iterator);
+	it->second->last_access = SDL_GetTicks();
+	return it->second->surface.get();
+}
+
+Surface* SurfaceCacheImpl::insert(const std::string& hash, Surface* surf) {
+	assert(map_.find(hash) == map_.end());
+
+	uint32_t surface_size = surf->width() * surf->height() * 4;
+	while (used_memory_ + surface_size > max_memory_)
+		drop();
+
+	// Record hash as most-recently-used.
+	AccessHistory::iterator it = hist_.insert(hist_.end(), hash);
+	used_memory_ += surface_size;
+	map_.insert(make_pair(hash, new Entry(surf, it)));
+
+	log("SurfaceCache: inserted %s, now using %.2f mb.\n", hash.c_str(), used_memory_ / 1048576.0);
+	return surf;
+}
+
+void SurfaceCacheImpl::drop() {
+	assert(!hist_.empty());
+
+	// Identify least recently used key
+	const Container::iterator it = map_.find(hist_.front());
+	assert(it != map_.end());
+
+	uint32_t surface_size = it->second->surface->width() * it->second->surface->height() * 4;
+	used_memory_ -= surface_size;
+
+	log
+		("SurfaceCache: dropping %s, which was unused for %.2f sec. Now using %.2f mb.\n",
+			hist_.front().c_str(), (SDL_GetTicks() - it->second->last_access) / 1000., used_memory_ / 1048576.0);
+
+	// Erase both elements to completely purge record
+	delete it->second;
+	map_.erase(it);
+	hist_.pop_front();
+}
+
+}  // namespace
+
+SurfaceCache* create_surface_cache(uint32_t memory) {
+	return new SurfaceCacheImpl(memory);
+}
+

=== added file 'src/graphic/surface_cache.h'
--- src/graphic/surface_cache.h	1970-01-01 00:00:00 +0000
+++ src/graphic/surface_cache.h	2013-02-10 14:53:26 +0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2006-2012 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef SURFACE_CACHE_H
+#define SURFACE_CACHE_H
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/utility.hpp>
+#include <string>
+
+class Surface;
+
+// Caches Surfaces that are expensive to create. Is free to delete them at any
+// time when it feels like it uses too much memory. It will then delete the
+// surfaces that have been used the longest time ago. Users of this class
+// should therefore not hold onto the Surface they get back, instead, they
+// should use it only temporarily and request it whenever they need it.
+class SurfaceCache : boost::noncopyable {
+public:
+	SurfaceCache() {};
+	virtual ~SurfaceCache() {};
+
+	/// Returns an entry if it is cached, NULL otherwise.
+	virtual Surface* get(const std::string& hash) = 0;
+
+	// Inserts this entry into the SurfaceCache. asserts() that there is no entry
+	// with this hash already cached. Returns the given Surface for convenience.
+	virtual Surface* insert(const std::string& hash, Surface*) = 0;
+};
+
+// Create a new Cache whichs combined pixels in all Surfaces are always below
+// the given limit (Note: there is overhead for class members which is not
+// counted as the pixels make up the bulk of the size of a surface).
+SurfaceCache* create_surface_cache(uint32_t memory_in_bytes);
+
+#endif /* end of include guard: SURFACE_CACHE_H */
+

=== modified file 'src/graphic/text/rt_render.cc'
--- src/graphic/text/rt_render.cc	2013-01-24 06:35:48 +0000
+++ src/graphic/text/rt_render.cc	2013-02-10 14:53:26 +0000
@@ -28,7 +28,9 @@
 #include <boost/scoped_ptr.hpp>
 
 #include "graphic/image_cache.h"
+#include "graphic/surface.h"
 
+#include "rect.h"
 #include "rt_parse.h"
 #include "textstream.h"
 
@@ -41,7 +43,7 @@
 
 namespace RT {
 
-static const uint32_t INFINITE_WIDTH = 2147483647; // 2^31-1
+static const uint16_t INFINITE_WIDTH = 65535; // 2^16-1
 
 // Helper Stuff
 enum HAlign {
@@ -79,7 +81,7 @@
 	// There is a small difference...
 	// Rect::contains() excludes the bottom and right edges.
 	// Reference::contains() includes the bottom and right edges
-	// TODO(sirver): check this, likely that it is.
+	// TODO: check this, likely that it is with the test cases
 	inline bool contains(int16_t x, int16_t y) const {
 		return
 			dim.x <= x && x <= dim.x + static_cast<int32_t>(dim.w) &&
@@ -114,14 +116,14 @@
 		: m_floating(NO_FLOAT), m_halign(ns.halign), m_valign(ns.valign), m_x(0), m_y(0) {}
 	virtual ~RenderNode() {};
 
-	virtual uint32_t width() = 0;
-	virtual uint32_t height() = 0;
-	virtual uint32_t hotspot_y() = 0;
-	virtual IBlitableSurface* render(IGraphic& gr) = 0;
+	virtual uint16_t width() = 0;
+	virtual uint16_t height() = 0;
+	virtual uint16_t hotspot_y() = 0;
+	virtual Surface* render(SurfaceCache* surface_cache) = 0;
 
 	virtual bool is_non_mandatory_space() {return false;}
 	virtual bool is_expanding() {return false;}
-	virtual void set_w(uint32_t) {} // Only, when expanding
+	virtual void set_w(uint16_t) {} // Only, when expanding
 
 	virtual const vector<Reference> get_references() {return vector<Reference>();}
 
@@ -131,16 +133,16 @@
 	void set_halign(HAlign halign) {m_halign = halign;}
 	VAlign valign() {return m_valign;}
 	void set_valign(VAlign valign) {m_valign = valign;}
-	void set_x(uint32_t nx) {m_x = nx;}
-	void set_y(uint32_t ny) {m_y = ny;}
-	uint32_t x() {return m_x;}
-	uint32_t y() {return m_y;}
+	void set_x(uint16_t nx) {m_x = nx;}
+	void set_y(uint16_t ny) {m_y = ny;}
+	uint16_t x() {return m_x;}
+	uint16_t y() {return m_y;}
 
 private:
 	Floating m_floating;
 	HAlign m_halign;
 	VAlign m_valign;
-	uint32_t m_x, m_y;
+	uint16_t m_x, m_y;
 };
 
 class Layout {
@@ -148,15 +150,15 @@
 	Layout(vector<RenderNode*>& all) : m_h(0), m_idx(0), m_all_nodes(all) {}
 	virtual ~Layout() {}
 
-	uint32_t height() {return m_h;}
-	uint32_t fit_nodes(vector<RenderNode*>& rv, uint32_t w, Borders p);
+	uint16_t height() {return m_h;}
+	uint16_t fit_nodes(vector<RenderNode*>& rv, uint16_t w, Borders p);
 
 private:
 	// Represents a change in the rendering constraints. For example when an
 	// Image is inserted, the width will become wider after it. This is a
 	// constraint change.
 	struct ConstraintChange {
-		uint32_t at_y;
+		uint16_t at_y;
 		int32_t delta_w;
 		int32_t delta_offset_x;
 
@@ -165,22 +167,22 @@
 		}
 	};
 
-	uint32_t m_fit_line(vector<RenderNode*>& rv, uint32_t w, const Borders&);
+	uint16_t m_fit_line(vector<RenderNode*>& rv, uint16_t w, const Borders&);
 
-	uint32_t m_h;
+	uint16_t m_h;
 	size_t m_idx;
 	vector<RenderNode*>& m_all_nodes;
 	priority_queue<ConstraintChange> m_constraint_changes;
 };
-uint32_t Layout::m_fit_line(vector<RenderNode*>& rv, uint32_t w, const Borders& p) {
+uint16_t Layout::m_fit_line(vector<RenderNode*>& rv, uint16_t w, const Borders& p) {
 	while (m_idx < m_all_nodes.size() and m_all_nodes[m_idx]->is_non_mandatory_space())
 		delete m_all_nodes[m_idx++];
 
-	uint32_t x = p.left;
+	uint16_t x = p.left;
 	size_t first_idx = rv.size();
 	while (m_idx < m_all_nodes.size()) {
 		RenderNode* n = m_all_nodes[m_idx];
-		uint32_t nw = n->width();
+		uint16_t nw = n->width();
 		if (x + nw + p.right > w or n->get_floating())
 			break;
 
@@ -195,7 +197,7 @@
 	}
 
 	// Remaining space in this line
-	uint32_t rem_space = w - p.right - x;
+	uint16_t rem_space = w - p.right - x;
 
 	// Find expanding nodes
 	vector<size_t> expanding_nodes;
@@ -204,7 +206,7 @@
 			expanding_nodes.push_back(idx);
 
 	if (expanding_nodes.size()) { // If there are expanding nodes, we fill the space
-		uint32_t individual_w = rem_space / expanding_nodes.size();
+		uint16_t individual_w = rem_space / expanding_nodes.size();
 		foreach(size_t idx, expanding_nodes) {
 			rv[idx]->set_w(individual_w);
 			for (size_t nidx = idx + 1; nidx < rv.size(); ++nidx)
@@ -221,7 +223,7 @@
 	}
 
 	// Find the biggest hotspot of the truly remaining items.
-	uint32_t cur_line_hotspot = 0;
+	uint16_t cur_line_hotspot = 0;
 	for (size_t idx = first_idx; idx < rv.size(); ++idx)
 		cur_line_hotspot = max(cur_line_hotspot, rv[idx]->hotspot_y());
 
@@ -231,24 +233,24 @@
  * Take ownership of all nodes, delete those that we do not render anyways (for
  * example unneeded spaces), append the rest to the vector we got.
  */
-uint32_t Layout::fit_nodes(vector<RenderNode*>& rv, uint32_t w, Borders p) {
+uint16_t Layout::fit_nodes(vector<RenderNode*>& rv, uint16_t w, Borders p) {
 	m_h = p.top;
 
-	uint32_t max_line_width = 0;
+	uint16_t max_line_width = 0;
 	while (m_idx < m_all_nodes.size()) {
 		size_t first_idx = rv.size();
-		uint32_t biggest_hotspot = m_fit_line(rv, w, p);
-		uint32_t line_height = 0;
+		uint16_t biggest_hotspot = m_fit_line(rv, w, p);
+		int line_height = 0;
 		for (size_t j = first_idx; j < rv.size(); ++j) {
 			RenderNode* n = rv[j];
 			line_height = max(line_height, biggest_hotspot - n->hotspot_y() + n->height());
 			n->set_y(m_h + biggest_hotspot - n->hotspot_y());
-			max_line_width = max(max_line_width, n->x() + n->width() + p.right);
+			max_line_width = max<int>(max_line_width, n->x() + n->width() + p.right);
 		}
 
 		// Go over again and adjust position for VALIGN
 		for (size_t j = first_idx; j < rv.size(); ++j) {
-			uint32_t space = line_height - rv[j]->height();
+			uint16_t space = line_height - rv[j]->height();
 			if (!space or rv[j]->valign() == VALIGN_BOTTOM)
 				continue;
 			if (rv[j]->valign() == VALIGN_CENTER)
@@ -272,7 +274,7 @@
 				n->set_x(p.left);
 				p.left += n->width();
 				cc.delta_offset_x = -n->width();
-				max_line_width = max(max_line_width, n->x() + n->width() + p.right);
+				max_line_width = max<int>(max_line_width, n->x() + n->width() + p.right);
 			} else {
 				n->set_x(w - n->width() - p.right);
 				w -= n->width();
@@ -299,9 +301,9 @@
 	TextNode(IFont& font, NodeStyle&, const string& txt);
 	virtual ~TextNode() {};
 
-	virtual uint32_t width() {return m_w;}
-	virtual uint32_t height() {return m_h + m_s.spacing;}
-	virtual uint32_t hotspot_y();
+	virtual uint16_t width() {return m_w;}
+	virtual uint16_t height() {return m_h + m_s.spacing;}
+	virtual uint16_t hotspot_y();
 	virtual const vector<Reference> get_references() {
 		vector<Reference> rv;
 		if (!m_s.reference.empty()) {
@@ -311,10 +313,10 @@
 		return rv;
 	}
 
-	virtual IBlitableSurface* render(IGraphic& gr);
+	virtual Surface* render(SurfaceCache* surface_cache);
 
 protected:
-	uint32_t m_w, m_h;
+	uint16_t m_w, m_h;
 	const string m_txt;
 	NodeStyle m_s;
 	IFont& m_font;
@@ -325,13 +327,13 @@
 {
 	m_font.dimensions(m_txt, ns.font_style, &m_w, &m_h);
 }
-uint32_t TextNode::hotspot_y() {
+uint16_t TextNode::hotspot_y() {
 	return m_font.ascent(m_s.font_style);
 }
-IBlitableSurface* TextNode::render(IGraphic& gr) {
-	const IPicture& img = m_font.render(gr, m_txt, m_s.font_color, m_s.font_style);
-	IBlitableSurface* rv = gr.create_surface(img.get_w(), img.get_h(), true);
-	rv->blit(Point(0, 0), &img, Rect(0, 0, img.get_w(), img.get_h()), CM_Copy);
+Surface* TextNode::render(SurfaceCache* surface_cache) {
+	const Surface& img = m_font.render(m_txt, m_s.font_color, m_s.font_style, surface_cache);
+	Surface* rv = Surface::create(img.width(), img.height());
+	rv->blit(Point(0, 0), &img, Rect(0, 0, img.width(), img.height()), CM_Copy);
 	return rv;
 }
 
@@ -341,24 +343,24 @@
  */
 class FillingTextNode : public TextNode {
 public:
-	FillingTextNode(IFont& font, NodeStyle& ns, uint32_t w, const string& txt, bool expanding = false) :
+	FillingTextNode(IFont& font, NodeStyle& ns, uint16_t w, const string& txt, bool expanding = false) :
 		TextNode(font, ns, txt), m_expanding(expanding) {
 			m_w = w;
 		};
 	virtual ~FillingTextNode() {};
-	virtual IBlitableSurface* render(IGraphic& gr);
+	virtual Surface* render(SurfaceCache*);
 
 	virtual bool is_expanding() {return m_expanding;}
-	virtual void set_w(uint32_t w) {m_w = w;}
+	virtual void set_w(uint16_t w) {m_w = w;}
 
 private:
 	bool m_expanding;
 };
-IBlitableSurface* FillingTextNode::render(IGraphic& gr) {
-	const IPicture& t = m_font.render(gr, m_txt, m_s.font_color, m_s.font_style);
-	IBlitableSurface* rv = gr.create_surface(m_w, m_h, true);
-	for (uint32_t x = 0; x < m_w; x += t.get_w()) {
-		Rect srcrect(Point(0, 0), min(static_cast<uint32_t>(t.get_w()), m_w - x), m_h);
+Surface* FillingTextNode::render(SurfaceCache* surface_cache) {
+	const Surface& t = m_font.render(m_txt, m_s.font_color, m_s.font_style, surface_cache);
+	Surface* rv = Surface::create(m_w, m_h);
+	for (uint16_t x = 0; x < m_w; x += t.width()) {
+		Rect srcrect(Point(0, 0), min<int>(t.width(), m_w - x), m_h);
 		rv->blit(Point(x, 0), &t, srcrect, CM_Solid);
 	}
 	return rv;
@@ -373,13 +375,13 @@
 	WordSpacerNode(IFont& font, NodeStyle& ns) : TextNode(font, ns, " ") {}
 	static void show_spaces(bool t) {m_show_spaces = t;}
 
-	virtual IBlitableSurface* render(IGraphic& gr) {
+	virtual Surface* render(SurfaceCache* surface_cache) {
 		if (m_show_spaces) {
-			IBlitableSurface* rv = gr.create_surface(m_w, m_h, true);
+			Surface* rv = Surface::create(m_w, m_h);
 			rv->fill_rect(Rect(0, 0, m_w, m_h), RGBAColor(0xff, 0, 0, 0xff));
 			return rv;
 		}
-		return TextNode::render(gr);
+		return TextNode::render(surface_cache);
 	}
 	virtual bool is_non_mandatory_space() {return true;}
 
@@ -395,10 +397,10 @@
 class NewlineNode : public RenderNode {
 public:
 	NewlineNode(NodeStyle& ns) : RenderNode(ns) {}
-	virtual uint32_t height() {return 0;}
-	virtual uint32_t width() {return INFINITE_WIDTH; }
-	virtual uint32_t hotspot_y() {return 0;}
-	virtual IBlitableSurface* render(IGraphic& /* gr */) {
+	virtual uint16_t height() {return 0;}
+	virtual uint16_t width() {return INFINITE_WIDTH; }
+	virtual uint16_t hotspot_y() {return 0;}
+	virtual Surface* render(SurfaceCache* surface_cache) {
 		assert(false); // This should never be called
 	}
 	virtual bool is_non_mandatory_space() {return true;}
@@ -409,39 +411,39 @@
  */
 class SpaceNode : public RenderNode {
 public:
-	SpaceNode(NodeStyle& ns, uint32_t w, uint32_t h = 0, bool expanding = false) :
+	SpaceNode(NodeStyle& ns, uint16_t w, uint16_t h = 0, bool expanding = false) :
 		RenderNode(ns), m_w(w), m_h(h), m_bg(NULL), m_expanding(expanding) {}
 
-	virtual uint32_t height() {return m_h;}
-	virtual uint32_t width() {return m_w;}
-	virtual uint32_t hotspot_y() {return m_h;}
-	virtual IBlitableSurface* render(IGraphic& gr) {
-		IBlitableSurface* rv = gr.create_surface(m_w, m_h, m_bg != NULL);
+	virtual uint16_t height() {return m_h;}
+	virtual uint16_t width() {return m_w;}
+	virtual uint16_t hotspot_y() {return m_h;}
+	virtual Surface* render(SurfaceCache* surface_cache) {
+		Surface* rv = Surface::create(m_w, m_h);
 
 		// Draw background image (tiling)
 		if (m_bg) {
 			Point dst;
 			Rect srcrect(Point(0, 0), 1, 1);
-			for (uint32_t x = 0; x < m_w; x += m_bg->get_w()) {
+			for (uint16_t x = 0; x < m_w; x += m_bg->width()) {
 				dst.x = x;
 				dst.y = 0;
-				srcrect.w = min(static_cast<uint32_t>(m_bg->get_w()), m_w - x);
+				srcrect.w = min<int>(m_bg->width(), m_w - x);
 				srcrect.h = m_h;
-				rv->blit(dst, m_bg, srcrect, CM_Solid);
+				rv->blit(dst, m_bg->surface(), srcrect, CM_Solid);
 			}
 		}
 		return rv;
 	}
 	virtual bool is_expanding() {return m_expanding;}
-	virtual void set_w(uint32_t w) {m_w = w;}
+	virtual void set_w(uint16_t w) {m_w = w;}
 
-	void set_background(const IPicture* s) {
-		m_bg = s; m_h = s->get_h();
+	void set_background(const Image* s) {
+		m_bg = s; m_h = s->height();
 	}
 
 private:
-	uint32_t m_w, m_h;
-	const IPicture* m_bg;  // not owned
+	uint16_t m_w, m_h;
+	const Image* m_bg;  // not owned
 	bool m_expanding;
 };
 
@@ -460,15 +462,12 @@
 		m_nodes_to_render.clear();
 	}
 
-	virtual uint32_t width() {return m_w + m_margin.left + m_margin.right;}
-	virtual uint32_t height() {return m_h + m_margin.top + m_margin.bottom;}
-	virtual uint32_t hotspot_y() {return height();}
-	virtual IBlitableSurface* render(IGraphic& gr) {
-		if (!width() || !height()) {
-			return 0;
-		}
-		IBlitableSurface* rv = gr.create_surface(width(), height(), true);
-		rv->fill_rect(Rect(0, 0, rv->get_w(), rv->get_h()), RGBAColor(255, 255, 255, 0));
+	virtual uint16_t width() {return m_w + m_margin.left + m_margin.right;}
+	virtual uint16_t height() {return m_h + m_margin.top + m_margin.bottom;}
+	virtual uint16_t hotspot_y() {return height();}
+	virtual Surface* render(SurfaceCache* surface_cache) {
+		Surface* rv = Surface::create(width(), height());
+		rv->fill_rect(Rect(0, 0, rv->width(), rv->height()), RGBAColor(255, 255, 255, 0));
 
 		// Draw Solid background Color
 		bool set_alpha = true;
@@ -483,22 +482,22 @@
 			Point dst;
 			Rect src(0, 0, 0, 0);
 
-			for (uint32_t y = m_margin.top; y < m_h + m_margin.top; y += m_bg_img->get_h()) {
-				for (uint32_t x = m_margin.left; x < m_w + m_margin.left; x += m_bg_img->get_w()) {
+			for (uint16_t y = m_margin.top; y < m_h + m_margin.top; y += m_bg_img->height()) {
+				for (uint16_t x = m_margin.left; x < m_w + m_margin.left; x += m_bg_img->width()) {
 					dst.x = x; dst.y = y;
-					src.w = min(static_cast<uint32_t>(m_bg_img->get_w()), m_w + m_margin.left - x);
-					src.h = min(static_cast<uint32_t>(m_bg_img->get_h()), m_h + m_margin.top - y);
-					rv->blit(dst, m_bg_img, src, CM_Solid);
+					src.w = min<int>(m_bg_img->width(), m_w + m_margin.left - x);
+					src.h = min<int>(m_bg_img->height(), m_h + m_margin.top - y);
+					rv->blit(dst, m_bg_img->surface(), src, CM_Solid);
 				}
 			}
 			set_alpha = false;
 		}
 
 		foreach(RenderNode* n, m_nodes_to_render) {
-			IBlitableSurface* nsur = n->render(gr);
+			Surface* nsur = n->render(surface_cache);
 			if (nsur) {
 				Point dst = Point(n->x() + m_margin.left, n->y() + m_margin.top);
-				Rect src = Rect(0, 0, nsur->get_w(), nsur->get_h());
+				Rect src = Rect(0, 0, nsur->width(), nsur->height());
 
 				rv->blit(dst, nsur, src, set_alpha ? CM_Solid : CM_Normal);
 				delete nsur;
@@ -511,14 +510,14 @@
 		return rv;
 	}
 	virtual const vector<Reference> get_references() {return m_refs;}
-	void set_dimensions(uint32_t inner_w, uint32_t inner_h, Borders margin) {
+	void set_dimensions(uint16_t inner_w, uint16_t inner_h, Borders margin) {
 		m_w = inner_w; m_h = inner_h; m_margin = margin;
 	}
 	void set_background(RGBColor clr) {
 		m_bg_clr = clr;
 		m_bg_clr_set = true;
 	}
-	void set_background(const IPicture* img) {m_bg_img = img;}
+	void set_background(const Image* img) {m_bg_img = img;}
 	void set_nodes_to_render(vector<RenderNode*>& n) {m_nodes_to_render = n;}
 	void add_reference(int16_t x, int16_t y, uint16_t w, uint16_t h, const string& s) {
 		Reference r = {Rect(x, y, w, h), s};
@@ -526,32 +525,32 @@
 	}
 
 private:
-	uint32_t m_w, m_h;
+	uint16_t m_w, m_h;
 	vector<RenderNode*> m_nodes_to_render;
 	Borders m_margin;
 	RGBColor m_bg_clr;
 	bool m_bg_clr_set;
-	const IPicture* m_bg_img; // Not owned.
+	const Image* m_bg_img; // Not owned.
 	vector<Reference> m_refs;
 };
 
 class ImgRenderNode : public RenderNode {
 public:
-	ImgRenderNode(NodeStyle& ns, const IPicture& sur) : RenderNode(ns), m_picture(sur) {
+	ImgRenderNode(NodeStyle& ns, const Image& image) : RenderNode(ns), m_image(image) {
 	}
 
-	virtual uint32_t width() {return m_picture.get_w();}
-	virtual uint32_t height() {return m_picture.get_h();}
-	virtual uint32_t hotspot_y() {return m_picture.get_h();}
-	virtual IBlitableSurface* render(IGraphic& gr);
+	virtual uint16_t width() {return m_image.width();}
+	virtual uint16_t height() {return m_image.height();}
+	virtual uint16_t hotspot_y() {return m_image.height();}
+	virtual Surface* render(SurfaceCache* surface_cache);
 
 private:
-	const IPicture& m_picture;
+	const Image& m_image;
 };
 
-IBlitableSurface* ImgRenderNode::render(IGraphic& gr) {
-	IBlitableSurface* rv = gr.create_surface(m_picture.get_w(), m_picture.get_h(), true);
-	rv->blit(Point(0, 0), &m_picture, Rect(0, 0, m_picture.get_w(), m_picture.get_h()), CM_Copy);
+Surface* ImgRenderNode::render(SurfaceCache* surface_cache) {
+	Surface* rv = Surface::create(m_image.width(), m_image.height());
+	rv->blit(Point(0, 0), m_image.surface(), Rect(0, 0, m_image.width(), m_image.height()), CM_Copy);
 	return rv;
 }
 // End: Helper Stuff
@@ -606,12 +605,12 @@
 
 
 class TagHandler;
-TagHandler* create_taghandler(ITag& tag, FontCache& fc, NodeStyle& ns, ImageCache& img_cache);
+TagHandler* create_taghandler(ITag& tag, FontCache& fc, NodeStyle& ns, ImageCache* image_cache);
 
 class TagHandler {
 public:
-	TagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache) :
-		m_tag(tag), m_fc(fc), m_ns(ns), img_cache_(img_cache) {}
+	TagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache) :
+		m_tag(tag), m_fc(fc), m_ns(ns), image_cache_(image_cache) {}
 	virtual ~TagHandler() {};
 
 	virtual void enter() {};
@@ -624,7 +623,7 @@
 	ITag& m_tag;
 	FontCache& m_fc;
 	NodeStyle m_ns;
-	ImageCache& img_cache_;
+	ImageCache* image_cache_;  // Not owned
 };
 
 void TagHandler::m_make_text_nodes(const string& txt, vector<RenderNode*>& nodes, NodeStyle& ns) {
@@ -645,7 +644,7 @@
 void TagHandler::emit(vector<RenderNode*>& nodes) {
 	foreach(Child* c, m_tag.childs()) {
 		if (c->tag) {
-			boost::scoped_ptr<TagHandler> th(create_taghandler(*c->tag, m_fc, m_ns, img_cache_));
+			boost::scoped_ptr<TagHandler> th(create_taghandler(*c->tag, m_fc, m_ns, image_cache_));
 			th->enter();
 			th->emit(nodes);
 		} else
@@ -655,8 +654,8 @@
 
 class FontTagHandler : public TagHandler {
 public:
-	FontTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache)
-		: TagHandler(tag, fc, ns, img_cache) {}
+	FontTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache)
+		: TagHandler(tag, fc, ns, image_cache) {}
 
 	void enter() {
 		const IAttrMap& a = m_tag.attrs();
@@ -673,8 +672,8 @@
 
 class PTagHandler : public TagHandler {
 public:
-	PTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache)
-		: TagHandler(tag, fc, ns, img_cache), m_indent(0) {
+	PTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache)
+		: TagHandler(tag, fc, ns, image_cache), m_indent(0) {
 	}
 
 	void enter() {
@@ -705,18 +704,18 @@
 	}
 
 private:
-	uint32_t m_indent;
+	uint16_t m_indent;
 };
 
 class ImgTagHandler : public TagHandler {
 public:
-	ImgTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache) :
-		TagHandler(tag, fc, ns, img_cache) {
+	ImgTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache) :
+		TagHandler(tag, fc, ns, image_cache) {
 	}
 
 	void enter() {
 		const IAttrMap& a = m_tag.attrs();
-		m_rn = new ImgRenderNode(m_ns, *img_cache_.load(PicMod_RichText, a["src"].get_string(), true));
+		m_rn = new ImgRenderNode(m_ns, *image_cache_->get(a["src"].get_string()));
 	}
 	void emit(vector<RenderNode*>& nodes) {
 		nodes.push_back(m_rn);
@@ -728,8 +727,8 @@
 
 class VspaceTagHandler : public TagHandler {
 public:
-	VspaceTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache) :
-		TagHandler(tag, fc, ns, img_cache), m_space(0) {}
+	VspaceTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache) :
+		TagHandler(tag, fc, ns, image_cache), m_space(0) {}
 
 	void enter() {
 		const IAttrMap& a = m_tag.attrs();
@@ -742,13 +741,13 @@
 	}
 
 private:
-	uint32_t m_space;
+	uint16_t m_space;
 };
 
 class HspaceTagHandler : public TagHandler {
 public:
-	HspaceTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache) :
-		TagHandler(tag, fc, ns, img_cache), m_bg(NULL), m_space(0) {}
+	HspaceTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache) :
+		TagHandler(tag, fc, ns, image_cache), m_bg(NULL), m_space(0) {}
 
 	void enter() {
 		const IAttrMap& a = m_tag.attrs();
@@ -761,7 +760,7 @@
 		if (a.has("fill")) {
 			m_fill_text = a["fill"].get_string();
 			try {
-				m_bg = img_cache_.load(PicMod_RichText, m_fill_text, true);
+				m_bg = image_cache_->get(m_fill_text);
 				m_fill_text = "";
 			} catch (BadImage&) {
 			}
@@ -791,14 +790,14 @@
 
 private:
 	string m_fill_text;
-	const IPicture* m_bg;
-	uint32_t m_space;
+	const Image* m_bg;
+	uint16_t m_space;
 };
 
 class BrTagHandler : public TagHandler {
 public:
-	BrTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache) :
-		TagHandler(tag, fc, ns, img_cache) {
+	BrTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache) :
+		TagHandler(tag, fc, ns, image_cache) {
 	}
 
 	void emit(vector<RenderNode*>& nodes) {
@@ -810,14 +809,15 @@
 class SubTagHandler : public TagHandler {
 public:
 	SubTagHandler
-		(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache,
-		 uint32_t max_w = 0, bool shrink_to_fit = false)
+		(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache,
+		 uint16_t max_w = 0, bool shrink_to_fit = false)
 		:
-			TagHandler(tag, fc, ns, img_cache),
+			TagHandler(tag, fc, ns, image_cache),
 			shrink_to_fit_(shrink_to_fit),
 			m_w(max_w),
 			m_rn(new SubTagRenderNode(ns))
-	{}
+	{
+	}
 
 	void enter() {
 		Borders padding, margin;
@@ -830,7 +830,7 @@
 				clr = a["background"].get_color();
 				m_rn->set_background(clr);
 			} catch (InvalidColor&) {
-				m_rn->set_background(img_cache_.load(PicMod_RichText, a["background"].get_string(), false));
+				m_rn->set_background(image_cache_->get(a["background"].get_string()));
 			}
 		}
 		if (a.has("padding")) {
@@ -853,22 +853,23 @@
 			foreach(RenderNode* n, subnodes) {
 				if (n->width() >= INFINITE_WIDTH)
 					continue;
-				m_w = max(m_w, n->width() + padding.left + padding.right);
+				m_w = max<int>(m_w, n->width() + padding.left + padding.right);
 			}
 		}
 
 		// Layout takes ownership of subnodes
 		Layout layout(subnodes);
-		uint32_t max_line_width = layout.fit_nodes(nodes_to_render, m_w, padding);
+		uint16_t max_line_width = layout.fit_nodes(nodes_to_render, m_w, padding);
 		if (shrink_to_fit_) {
 			m_w = min(m_w, max_line_width);
 		}
 
 		// Collect all tags from children
-		foreach(RenderNode* rn, nodes_to_render)
-			foreach(const Reference& r, rn->get_references()) {
-				m_rn->add_reference(rn->x() + r.dim.x, rn->y() + r.dim.y, r.dim.w, r.dim.h, r.ref);
-			}
+	foreach(RenderNode* rn, nodes_to_render) {
+		foreach(const Reference& r, rn->get_references()) {
+			m_rn->add_reference(rn->x() + r.dim.x, rn->y() + r.dim.y, r.dim.w, r.dim.h, r.ref);
+		}
+	}
 
 		m_rn->set_dimensions(m_w, layout.height(), margin);
 		m_rn->set_nodes_to_render(nodes_to_render);
@@ -899,14 +900,14 @@
 
 private:
 	bool shrink_to_fit_;
-	uint32_t m_w;
+	uint16_t m_w;
 	SubTagRenderNode* m_rn;
 };
 
 class RTTagHandler : public SubTagHandler {
 public:
-	RTTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache& img_cache, uint32_t w) :
-		SubTagHandler(tag, fc, ns, img_cache, w, true) {
+	RTTagHandler(ITag& tag, FontCache& fc, NodeStyle ns, ImageCache* image_cache, uint16_t w) :
+		SubTagHandler(tag, fc, ns, image_cache, w, true) {
 	}
 
 	// Handle attributes that are in rt, but not in sub.
@@ -917,13 +918,13 @@
 };
 
 template<typename T> TagHandler* create_taghandler
-	(ITag& tag, FontCache& fc, NodeStyle& ns, ImageCache& gr)
+	(ITag& tag, FontCache& fc, NodeStyle& ns, ImageCache* image_cache)
 {
-	return new T(tag, fc, ns, gr);
+	return new T(tag, fc, ns, image_cache);
 }
 typedef map<const string, TagHandler* (*)
-	(ITag& tag, FontCache& fc, NodeStyle& ns, ImageCache& img_cache)> TagHandlerMap;
-TagHandler* create_taghandler(ITag& tag, FontCache& fc, NodeStyle& ns, ImageCache& img_cache) {
+	(ITag& tag, FontCache& fc, NodeStyle& ns, ImageCache* image_cache)> TagHandlerMap;
+TagHandler* create_taghandler(ITag& tag, FontCache& fc, NodeStyle& ns, ImageCache* image_cache) {
 	static TagHandlerMap map;
 	if (map.empty()) {
 		map["br"] = &create_taghandler<BrTagHandler>;
@@ -938,36 +939,37 @@
 	if (i == map.end())
 		throw RenderError
 			((format("No Tag handler for %s. This is a bug, please submit a report.") % tag.name()).str());
-	return i->second(tag, fc, ns, img_cache);
+	return i->second(tag, fc, ns, image_cache);
 }
 
 class Renderer : public IRenderer {
 public:
-	Renderer(IGraphic& gr, IFontLoader* fl, IParser* p);
+	Renderer(ImageCache* image_cache, SurfaceCache* surface_cache, IFontLoader* fl, IParser* p);
 	virtual ~Renderer();
 
-	virtual const IPicture* render(const string&, uint32_t, const TagSet&);
-	virtual IRefMap* make_reference_map(const std::string&, uint32_t, const TagSet&);
+	virtual Surface* render(const string&, uint16_t, const TagSet&);
+	virtual IRefMap* make_reference_map(const std::string&, uint16_t, const TagSet&);
 
 private:
-	RenderNode* layout_(const string& text, uint32_t width, const TagSet& allowed_tags);
+	RenderNode* layout_(const string& text, uint16_t width, const TagSet& allowed_tags);
 
-	IGraphic& gr_;
 	FontCache m_fc;
 	scoped_ptr<IParser> m_p;
+	ImageCache* const image_cache_;  // Not owned.
+	SurfaceCache* const surface_cache_;  // Not owned.
 };
 
-Renderer::Renderer(IGraphic& gr, IFontLoader* fl, IParser* p) :
-	gr_(gr), m_fc(fl), m_p(p) {
+Renderer::Renderer(ImageCache* image_cache, SurfaceCache* surface_cache, IFontLoader* fl, IParser* p) :
+	image_cache_(image_cache), surface_cache_(surface_cache), m_fc(fl), m_p(p) {
 }
 
 Renderer::~Renderer() {
 }
 
-RenderNode* Renderer::layout_(const string& text, uint32_t width, const TagSet& allowed_tags) {
+RenderNode* Renderer::layout_(const string& text, uint16_t width, const TagSet& allowed_tags) {
 	boost::scoped_ptr<ITag> rt(m_p->parse(text, allowed_tags));
 
-	NodeStyle default_fs = {
+	NodeStyle default_style = {
 		"DejaVuSerif", 16,
 		RGBColor(0, 0, 0), IFont::DEFAULT, 0, HALIGN_LEFT, VALIGN_BOTTOM,
 		""
@@ -976,34 +978,30 @@
 	if (!width)
 		width = INFINITE_WIDTH;
 
-	RTTagHandler rtrn(*rt, m_fc, default_fs, gr_.imgcache(), width);
+	RTTagHandler rtrn(*rt, m_fc, default_style, image_cache_, width);
 	vector<RenderNode*> nodes;
 	rtrn.enter();
 	rtrn.emit(nodes);
 
 	assert(nodes.size() == 1);
+	assert(nodes[0]);
 	return nodes[0];
 }
 
-const IPicture* Renderer::render(const string& text, uint32_t width, const TagSet& allowed_tags) {
-	const string cs = boost::lexical_cast<string>(width) + text;
-	const IPicture* rv = gr_.imgcache().get(PicMod_RichText, cs);
-	if (rv) {
-		return rv;
-	}
+Surface* Renderer::render(const string& text, uint16_t width, const TagSet& allowed_tags) {
+	boost::scoped_ptr<RenderNode> node(layout_(text, width, allowed_tags));
 
-	boost::scoped_ptr<RenderNode> node(layout_(text, width, allowed_tags));
-	return gr_.imgcache().insert(PicMod_RichText, cs, node->render(gr_));
+	return node->render(surface_cache_);
 }
 
-IRefMap* Renderer::make_reference_map(const string& text, uint32_t width, const TagSet& allowed_tags) {
+IRefMap* Renderer::make_reference_map(const string& text, uint16_t width, const TagSet& allowed_tags) {
 
 	boost::scoped_ptr<RenderNode> node(layout_(text, width, allowed_tags));
 	return new RefMap(node->get_references());
 }
 
-IRenderer* setup_renderer(IGraphic& gr, IFontLoader* fl) {
-	return new Renderer(gr, fl, setup_parser());
+IRenderer* setup_renderer(ImageCache* image_cache, SurfaceCache* surface_cache, IFontLoader* fl) {
+	return new Renderer(image_cache, surface_cache, fl, setup_parser());
 }
 
 };

=== modified file 'src/graphic/text/rt_render.h'
--- src/graphic/text/rt_render.h	2012-12-16 19:08:53 +0000
+++ src/graphic/text/rt_render.h	2013-02-10 14:53:26 +0000
@@ -24,11 +24,12 @@
 #include <string>
 #include <set>
 
-#include "graphic/iblitable_surface.h"
-#include "graphic/igraphic.h"
-#include "graphic/picture.h"
+#include "graphic/image.h"
 #include "rgbcolor.h"
 
+class SurfaceCache;
+class ImageCache;
+
 namespace RT {
 /**
  * Wrapper object around a font.
@@ -49,10 +50,10 @@
 	};
 	virtual ~IFont() {};
 
-	virtual void dimensions(const std::string&, int, uint32_t *, uint32_t *) = 0;
-	virtual const IPicture& render(IGraphic &, const std::string&, const RGBColor& clr, int) = 0;
+	virtual void dimensions(const std::string&, int, uint16_t *, uint16_t *) = 0;
+	virtual const Surface& render(const std::string&, const RGBColor& clr, int, SurfaceCache*) = 0;
 
-	virtual uint32_t ascent(int) const = 0;
+	virtual uint16_t ascent(int) const = 0;
 };
 
 /**
@@ -78,8 +79,8 @@
 };
 
 /**
- * This is the rendering engine. It caches heavily using ImageCache and
- * therefore, the returned images are not owned by the caller.
+ * This is the rendering engine. The returned images are not owned by the
+ * caller.
  */
 typedef std::set<std::string> TagSet;
 class IRenderer {
@@ -88,20 +89,18 @@
 	virtual ~IRenderer() {};
 
 	// Render the given string in the given width. Restricts the allowed tags to
-	// the ones in TagSet. The returned image is cached with the key (width,
-	// text, number of entries in the tagse), therefore never delete the return
-	// value and mind key collisions when using same string and text with
-	// another tag set with the same number of entries.
-	virtual const IPicture* render(const std::string&, uint32_t, const TagSet & = TagSet()) = 0;
+	// the ones in TagSet. The renderer does not do caching in the SurfaceCache
+	// for its individual nodes, but the font render does.
+	virtual Surface* render(const std::string&, uint16_t, const TagSet & = TagSet()) = 0;
 
 	// Returns a reference map of the clickable hyperlinks in the image. This
 	// will do no caching and needs to do all layouting, so do not call this too
 	// often. The returned object must be freed.
-	virtual IRefMap* make_reference_map(const std::string&, uint32_t, const TagSet & = TagSet()) = 0;
+	virtual IRefMap* make_reference_map(const std::string&, uint16_t, const TagSet & = TagSet()) = 0;
 };
 
-// Setup a renderer, takes ownership of fl but not of gr.
-IRenderer* setup_renderer(IGraphic& gr, IFontLoader* fl);
+// Setup a renderer, takes ownership of fl but of nothing else.
+IRenderer* setup_renderer(ImageCache* gr, SurfaceCache*, IFontLoader* fl);
 };
 
 #endif /* end of include guard: RT_RENDER_H */

=== modified file 'src/graphic/text/sdl_ttf_font_impl.cc'
--- src/graphic/text/sdl_ttf_font_impl.cc	2013-01-05 23:08:45 +0000
+++ src/graphic/text/sdl_ttf_font_impl.cc	2013-02-10 14:53:26 +0000
@@ -20,10 +20,10 @@
 #include <SDL_ttf.h>
 #include <boost/format.hpp>
 
-#include "graphic/image_cache.h"
-#include "md5.h"
+#include "graphic/render/sdl_helper.h"
+#include "graphic/surface.h"
+#include "graphic/surface_cache.h"
 #include "rt_errors.h"
-#include "sdl_helper.h"
 
 #include "sdl_ttf_font_impl.h"
 
@@ -44,7 +44,7 @@
 	font_ = 0;
 }
 
-void SDLTTF_Font::dimensions(const string& txt, int style, uint32_t * gw, uint32_t * gh) {
+void SDLTTF_Font::dimensions(const string& txt, int style, uint16_t * gw, uint16_t * gh) {
 	m_set_style(style);
 
 	int w, h;
@@ -56,20 +56,13 @@
 	*gw = w; *gh = h;
 }
 
-const IPicture& SDLTTF_Font::render(IGraphic & gr, const string& txt, const RGBColor& clr, int style) {
-	// TODO(sirver): Make this cheaper!
-	SimpleMD5Checksum checksum;
-	checksum.Data(font_name_.c_str(), font_name_.size());
-	checksum.Data(&ptsize_, sizeof(ptsize_));
-	checksum.Data(txt.c_str(), txt.size());
-	checksum.Data(&clr.r, 1);
-	checksum.Data(&clr.g, 1);
-	checksum.Data(&clr.b, 1);
-	checksum.Data(&style, sizeof(style));
-	checksum.FinishChecksum();
-	const string cs = checksum.GetChecksum().str();
-
-	const IPicture* rv = gr.imgcache().get(PicMod_Text, cs);
+const Surface& SDLTTF_Font::render
+	(const string& txt, const RGBColor& clr, int style, SurfaceCache* surface_cache) {
+	const string hash =
+		(boost::format("%s:%s:%i:%02x%02x%02x:%i") % font_name_ % ptsize_ % txt %
+		 static_cast<int>(clr.r) % static_cast<int>(clr.g) % static_cast<int>(clr.b) % style)
+			.str();
+	const Surface* rv = surface_cache->get(hash);
 	if (rv) return *rv;
 
 	m_set_style(style);
@@ -80,7 +73,7 @@
 	if (style & SHADOW) {
 		SDL_Surface * tsurf = TTF_RenderUTF8_Blended(font_, txt.c_str(), sdlclr);
 		SDL_Surface * shadow = TTF_RenderUTF8_Blended(font_, txt.c_str(), SHADOW_CLR);
-		text_surface = empty_sdl_surface(shadow->w + SHADOW_OFFSET, shadow->h + SHADOW_OFFSET, true);
+		text_surface = empty_sdl_surface(shadow->w + SHADOW_OFFSET, shadow->h + SHADOW_OFFSET);
 
 		if (text_surface->format->BitsPerPixel != 32)
 			throw RenderError("SDL_TTF did not return a 32 bit surface for shadow text. Giving up!");
@@ -121,12 +114,11 @@
 	if (not text_surface)
 		throw RenderError((format("Rendering '%s' gave the error: %s") % txt % TTF_GetError()).str());
 
-	return
-		*gr.imgcache().insert(PicMod_Text, cs, gr.convert_sdl_surface_to_picture(text_surface, true));
+	return *surface_cache->insert(hash, Surface::create(text_surface));
 }
 
-uint32_t SDLTTF_Font::ascent(int style) const {
-	uint32_t rv = TTF_FontAscent(font_);
+uint16_t SDLTTF_Font::ascent(int style) const {
+	uint16_t rv = TTF_FontAscent(font_);
 	if (style & SHADOW)
 		rv += SHADOW_OFFSET;
 	return rv;

=== modified file 'src/graphic/text/sdl_ttf_font_impl.h'
--- src/graphic/text/sdl_ttf_font_impl.h	2012-12-14 21:40:41 +0000
+++ src/graphic/text/sdl_ttf_font_impl.h	2013-02-10 14:53:26 +0000
@@ -35,9 +35,9 @@
 	SDLTTF_Font(TTF_Font* ttf, const std::string& face, int ptsize);
 	virtual ~SDLTTF_Font();
 
-	void dimensions(const std::string&, int, uint32_t * w, uint32_t * h);
-	virtual const IPicture& render(IGraphic &, const std::string&, const RGBColor& clr, int);
-	uint32_t ascent(int) const;
+	void dimensions(const std::string&, int, uint16_t * w, uint16_t * h);
+	virtual const Surface& render(const std::string&, const RGBColor& clr, int, SurfaceCache*);
+	uint16_t ascent(int) const;
 
 private:
 	void m_set_style(int);

=== modified file 'src/graphic/texture.cc'
--- src/graphic/texture.cc	2012-12-15 18:40:59 +0000
+++ src/graphic/texture.cc	2013-02-10 14:53:26 +0000
@@ -23,7 +23,6 @@
 
 #include "io/filesystem/layered_filesystem.h"
 #include "io/fileread.h"
-#include "graphic.h"
 
 #include "log.h"
 #include "constants.h"
@@ -32,12 +31,13 @@
 
 #include "texture.h"
 
+extern bool g_opengl;
 
 using namespace std;
 
 /**
- * Create a texture, taking the pixel data from a Pic.
- * Currently it converts a 16 bit pic to a 8 bit texture. This should
+ * Create a texture, taking the pixel data from an Image.
+ * Currently it converts a 16 bit image to a 8 bit texture. This should
  * be changed to load a 8 bit file directly, however.
  */
 Texture::Texture(const string& fnametmpl, uint32_t frametime, const SDL_PixelFormat& format)
@@ -50,7 +50,7 @@
 		is_32bit   (format.BytesPerPixel == 4),
 		m_was_animated(false)
 {
-	// Load the pictures one by one
+	// Load the images one by one
 	char fname[256];
 
 	for (;;) {
@@ -75,7 +75,7 @@
 
 		SDL_Surface * surf;
 
-		m_texture_picture = strdup(fname);
+		m_texture_image = strdup(fname);
 
 		FileRead fr;
 
@@ -203,7 +203,7 @@
 {
 	delete m_colormap;
 	free(m_pixels);
-	free(m_texture_picture);
+	free(m_texture_image);
 
 	BOOST_FOREACH(GLSurfaceTexture* surf, m_glFrames)
 		delete surf;

=== modified file 'src/graphic/texture.h'
--- src/graphic/texture.h	2012-12-08 23:20:53 +0000
+++ src/graphic/texture.h	2013-02-10 14:53:26 +0000
@@ -27,14 +27,6 @@
 #include "colormap.h"
 #include "graphic/render/gl_surface_texture.h"
 
-/**
- * This contains all the road textures needed to render roads
- */
-struct Road_Textures {
-	const IPicture* pic_road_normal;
-	const IPicture* pic_road_busy;
-};
-
 /** struct Texture
 *
 * Texture represents are terrain texture, which is strictly
@@ -50,7 +42,7 @@
 		(const std::string& fnametempl, uint32_t frametime, const SDL_PixelFormat&);
 	~Texture();
 
-	const char * get_texture_picture() const {return m_texture_picture;}
+	const char * get_texture_image() const {return m_texture_image;}
 
 	uint8_t * get_pixels   () const {return m_pixels;}
 	uint8_t * get_curpixels() const {return m_curframe;}
@@ -72,7 +64,7 @@
 	uint32_t   m_mmap_color[256];
 	uint8_t  * m_curframe;
 	int32_t    m_frame_num;
-	char     * m_texture_picture;
+	char     * m_texture_image;
 	uint32_t   m_nrframes;
 	uint32_t   m_frametime;
 	bool       is_32bit;

=== modified file 'src/graphic/wordwrap.cc'
--- src/graphic/wordwrap.cc	2012-02-15 21:25:34 +0000
+++ src/graphic/wordwrap.cc	2013-02-10 14:53:26 +0000
@@ -215,7 +215,7 @@
  */
 uint32_t WordWrap::height() const
 {
-	uint32_t fontheight = m_style.font->height();
+	uint16_t fontheight = m_style.font->height();
 	uint32_t lineskip = m_style.font->lineskip();
 
 	return fontheight + (m_lines.size() - 1) * lineskip;
@@ -263,7 +263,7 @@
  */
 void WordWrap::draw(RenderTarget & dst, Point where, Align align, uint32_t caret)
 {
-	uint32_t fontheight = m_style.font->height();
+	uint16_t fontheight = m_style.font->height();
 	uint32_t lineskip = m_style.font->lineskip();
 	uint32_t caretline, caretpos;
 
@@ -280,7 +280,7 @@
 
 	++where.y;
 	for (uint32_t line = 0; line < m_lines.size(); ++line, where.y += lineskip) {
-		if (where.y >= dst.get_h() || int32_t(where.y + fontheight) <= 0)
+		if (where.y >= dst.height() || int32_t(where.y + fontheight) <= 0)
 			continue;
 
 		g_fh->draw_text

=== modified file 'src/graphic/wordwrap.h'
--- src/graphic/wordwrap.h	2012-12-31 11:21:15 +0000
+++ src/graphic/wordwrap.h	2013-02-10 14:53:26 +0000
@@ -21,9 +21,10 @@
 
 #include <string>
 
+#include "point.h"
+#include "align.h"
+
 #include "font.h"
-#include "point.h"
-#include "ui_basic/align.h"
 
 class RenderTarget;
 

=== modified file 'src/logic/building.cc'
--- src/logic/building.cc	2012-12-16 19:08:53 +0000
+++ src/logic/building.cc	2013-02-10 14:53:26 +0000
@@ -25,15 +25,16 @@
 
 #include "economy/flag.h"
 #include "economy/request.h"
-#include "text_layout.h"
 #include "graphic/font.h"
 #include "graphic/font_handler.h"
 #include "graphic/font_handler1.h"
+#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "io/filesystem/filesystem.h"
 #include "io/filesystem/layered_filesystem.h"
 #include "profile/profile.h"
 #include "sound/sound_handler.h"
+#include "text_layout.h"
 #include "wui/interactive_player.h"
 
 #include "constructionsite.h"
@@ -224,7 +225,7 @@
 void Building_Descr::load_graphics()
 {
 	if (m_buildicon_fname.size())
-		m_buildicon = g_gr->imgcache().load(PicMod_Game, m_buildicon_fname.c_str());
+		m_buildicon = g_gr->images().get(m_buildicon_fname.c_str());
 }
 
 /*
@@ -757,11 +758,9 @@
 	uint32_t const dpyflags = igbase.get_display_flags();
 
 	if (dpyflags & Interactive_Base::dfShowCensus) {
-		UI::g_fh1->draw_text
-			(dst, pos - Point(0, 48),
-			 info_string(igbase.building_census_format()),
-			 0,
-			 UI::Align_Center);
+		dst.blit
+			(pos - Point(0, 48), UI::g_fh1->render(info_string(igbase.building_census_format())),
+			 CM_Normal, UI::Align_Center);
 	}
 
 	if (dpyflags & Interactive_Base::dfShowStatistics) {
@@ -770,11 +769,9 @@
 				(!iplayer->player().see_all() &&
 				 iplayer->player().is_hostile(*get_owner()))
 				return;
-		UI::g_fh1->draw_text
-			(dst, pos - Point(0, 35),
-			 info_string(igbase.building_statistics_format()),
-			 0,
-			 UI::Align_Center);
+		dst.blit
+			(pos - Point(0, 35), UI::g_fh1->render(info_string(igbase.building_statistics_format())),
+			 CM_Normal, UI::Align_Center);
 	}
 }
 
@@ -920,7 +917,7 @@
 	 uint32_t throttle_radius)
 {
 	std::string const & picnametempl =
-		g_anim.get_animation(descr().get_ui_anim())->picnametempl;
+		g_anim.get_animation(descr().get_ui_anim()).picnametempl;
 	std::string rt_description;
 	rt_description.reserve
 		(strlen("<rt image=") + picnametempl.size() + 1 +

=== modified file 'src/logic/building.h'
--- src/logic/building.h	2013-01-20 21:27:20 +0000
+++ src/logic/building.h	2013-02-10 14:53:26 +0000
@@ -39,7 +39,7 @@
 struct BuildingHints;
 class Interactive_GameBase;
 struct Profile;
-class IPicture;
+class Image;
 
 namespace Widelands {
 
@@ -68,7 +68,7 @@
 	bool is_enhanced    () const {return m_enhanced_building;}
 	bool global() const {return m_global;}
 	Buildcost const & buildcost() const throw () {return m_buildcost;}
-	const IPicture* get_buildicon() const {return m_buildicon;}
+	const Image* get_buildicon() const {return m_buildicon;}
 	int32_t get_size() const throw () {return m_size;}
 	bool get_ismine() const {return m_mine;}
 	bool get_isport() const {return m_port;}
@@ -121,7 +121,7 @@
 	bool          m_buildable;       // the player can build this himself
 	bool          m_destructible;    // the player can destruct this himself
 	Buildcost     m_buildcost;
-	const IPicture*     m_buildicon;       // if buildable: picture in the build dialog
+	const Image*     m_buildicon;       // if buildable: picture in the build dialog
 	std::string   m_buildicon_fname; // filename for this icon
 	int32_t       m_size;            // size of the building
 	bool          m_mine;

=== modified file 'src/logic/constructionsite.cc'
--- src/logic/constructionsite.cc	2012-11-16 17:14:21 +0000
+++ src/logic/constructionsite.cc	2013-02-10 14:53:26 +0000
@@ -372,7 +372,7 @@
 			anim = building().get_animation("idle");
 		}
 	}
-	const AnimationGfx::Index nr_frames = g_gr->nr_frames(anim);
+	const size_t nr_frames = g_gr->nr_frames(anim);
 	cur_frame = m_info->totaltime ? m_info->completedtime * nr_frames / m_info->totaltime : 0;
 	// Redefine tanim
 	tanim = cur_frame * FRAME_LENGTH;

=== modified file 'src/logic/editor_game_base.cc'
--- src/logic/editor_game_base.cc	2013-01-05 18:52:13 +0000
+++ src/logic/editor_game_base.cc	2013-02-10 14:53:26 +0000
@@ -29,6 +29,7 @@
 #include "economy/flag.h"
 #include "economy/road.h"
 #include "graphic/font_handler.h"
+#include "graphic/graphic.h"
 #include "scripting/scripting.h"
 #include "sound/sound_handler.h"
 #include "ui_basic/progresswindow.h"

=== modified file 'src/logic/game.cc'
--- src/logic/game.cc	2013-02-03 10:44:13 +0000
+++ src/logic/game.cc	2013-02-10 14:53:26 +0000
@@ -276,7 +276,6 @@
 	(UI::ProgressWindow * loaderUI, GameSettings const & settings)
 {
 	if (loaderUI) {
-		g_gr->imgcache().flush(PicMod_Menu);
 		loaderUI->step(_("Preloading map"));
 	}
 
@@ -352,7 +351,6 @@
 	(UI::ProgressWindow * loaderUI, GameSettings const & settings)
 {
 	if (loaderUI) {
-		g_gr->imgcache().flush(PicMod_Menu);
 		loaderUI->step(_("Preloading map"));
 	}
 
@@ -577,7 +575,6 @@
 		delete get_ibase();
 		set_ibase(0);
 
-		g_gr->imgcache().flush(PicMod_Game);
 		g_anim.flush();
 		g_gr->flush_animations();
 

=== modified file 'src/logic/immovable.cc'
--- src/logic/immovable.cc	2012-09-21 21:36:07 +0000
+++ src/logic/immovable.cc	2013-02-10 14:53:26 +0000
@@ -526,10 +526,10 @@
 	if (done > total)
 		done = total;
 
-	const AnimationGfx::Index nr_frames = g_gr->nr_frames(m_anim);
-	uint32_t frametime = g_anim.get_animation(m_anim)->frametime;
+	const size_t nr_frames = g_gr->nr_frames(m_anim);
+	uint32_t frametime = g_anim.get_animation(m_anim).frametime;
 	uint32_t units_per_frame = (total + nr_frames - 1) / nr_frames;
-	const AnimationGfx::Index current_frame = done / units_per_frame;
+	const size_t current_frame = done / units_per_frame;
 	uint32_t curw, curh;
 	g_gr->get_animation_size(m_anim, current_frame * frametime, curw, curh);
 

=== modified file 'src/logic/item_ware_descr.cc'
--- src/logic/item_ware_descr.cc	2012-12-13 10:41:22 +0000
+++ src/logic/item_ware_descr.cc	2013-02-10 14:53:26 +0000
@@ -17,12 +17,13 @@
  *
  */
 
-#include "item_ware_descr.h"
-
+#include "graphic/animation.h"
 #include "graphic/graphic.h"
 #include "i18n.h"
 #include "profile/profile.h"
 
+#include "item_ware_descr.h"
+
 namespace Widelands {
 
 Item_Ware_Descr::Item_Ware_Descr
@@ -34,7 +35,7 @@
 	m_tribe(tribe),
 	m_helptext(global_s.get_string("help", "")),
 	m_icon_fname(directory + "/menu.png"),
-	m_icon(g_gr ? g_gr->imgcache().load(PicMod_UI, "pics/but0.png") : 0) // because of dedicated
+	m_icon(g_gr ? g_gr->images().get("pics/but0.png") : 0) // because of dedicated
 {
 	m_default_target_quantity =
 		global_s.get_positive("default_target_quantity", std::numeric_limits<uint32_t>::max());
@@ -51,7 +52,7 @@
  */
 void Item_Ware_Descr::load_graphics()
 {
-	m_icon = g_gr->imgcache().load(PicMod_Game, m_icon_fname);
+	m_icon = g_gr->images().get(m_icon_fname);
 }
 
 }

=== modified file 'src/logic/item_ware_descr.h'
--- src/logic/item_ware_descr.h	2013-01-22 19:33:32 +0000
+++ src/logic/item_ware_descr.h	2013-02-10 14:53:26 +0000
@@ -32,7 +32,7 @@
 
 struct Profile;
 struct Section;
-class IPicture;
+class Image;
 
 #define WARE_MENU_PIC_WIDTH   24  //< Default width for ware's menu icons
 #define WARE_MENU_PIC_HEIGHT  24  //< Default height for ware's menu icons
@@ -68,7 +68,7 @@
 	const Tribe_Descr & tribe() const {return m_tribe;}
 
 	/// \return index to ware's icon inside picture stack
-	const IPicture* icon() const throw () {return m_icon;}
+	const Image* icon() const throw () {return m_icon;}
 	std::string icon_name() const throw () {return m_icon_fname;}
 
 	/// \return ware's localized descriptive text
@@ -105,7 +105,7 @@
 	std::string m_helptext;   ///< Long descriptive text
 	uint32_t    m_default_target_quantity;
 	std::string m_icon_fname; ///< Filename of ware's main picture
-	const IPicture* m_icon;       ///< Index of ware's picture in picture stack
+	const Image* m_icon;       ///< Index of ware's picture in picture stack
 	uint8_t     m_preciousness;
 };
 

=== modified file 'src/logic/map.h'
--- src/logic/map.h	2012-11-24 16:22:10 +0000
+++ src/logic/map.h	2013-02-10 14:53:26 +0000
@@ -40,7 +40,7 @@
 
 struct Overlay_Manager;
 struct S2_Map_Loader;
-class IPicture;
+class Image;
 
 namespace Widelands {
 
@@ -404,7 +404,7 @@
 		enum Type {
 			PIC,
 		};
-		const IPicture* data;
+		const Image* data;
 		std::string filename;
 		Type        type;
 	};

=== modified file 'src/logic/soldier.cc'
--- src/logic/soldier.cc	2012-12-13 10:41:22 +0000
+++ src/logic/soldier.cc	2013-02-10 14:53:26 +0000
@@ -211,16 +211,16 @@
 	m_defense_pics.resize(m_max_defense_level + 1);
 	m_evade_pics  .resize(m_max_evade_level   + 1);
 	for (uint32_t i = 0; i <= m_max_hp_level;      ++i)
-		m_hp_pics[i] = g_gr->imgcache().load(PicMod_Game,  m_hp_pics_fn[i].c_str());
+		m_hp_pics[i] = g_gr->images().get(m_hp_pics_fn[i].c_str());
 	for (uint32_t i = 0; i <= m_max_attack_level;  ++i)
 		m_attack_pics[i] =
-			g_gr->imgcache().load(PicMod_Game,  m_attack_pics_fn[i].c_str());
+			g_gr->images().get(m_attack_pics_fn[i].c_str());
 	for (uint32_t i = 0; i <= m_max_defense_level; ++i)
 		m_defense_pics[i] =
-			g_gr->imgcache().load(PicMod_Game,  m_defense_pics_fn[i].c_str());
+			g_gr->images().get(m_defense_pics_fn[i].c_str());
 	for (uint32_t i = 0; i <= m_max_evade_level;   ++i)
 		m_evade_pics[i] =
-			g_gr->imgcache().load(PicMod_Game,  m_evade_pics_fn[i].c_str());
+			g_gr->images().get(m_evade_pics_fn[i].c_str());
 	Worker_Descr::load_graphics();
 }
 
@@ -576,21 +576,22 @@
 	uint32_t w;
 	w = SOLDIER_HP_BAR_WIDTH;
 
-	const IPicture* hppic = get_hp_level_pic();
-	const IPicture* attackpic = get_attack_level_pic();
-	const IPicture* defensepic = get_defense_level_pic();
-	const IPicture* evadepic = get_evade_level_pic();
-	uint32_t hpw = hppic->get_w();
-	uint32_t hph = hppic->get_h();
-	uint32_t atw = attackpic->get_w();
-	uint32_t ath = attackpic->get_h();
-	uint32_t dew = defensepic->get_w();
-	uint32_t deh = defensepic->get_h();
-	uint32_t evw = evadepic->get_w();
-	uint32_t evh = evadepic->get_h();
-
-	uint32_t totalwidth = std::max(std::max(atw + dew, hpw + evw), 2 * w);
-	uint32_t totalheight = 5 + std::max(hph + ath, evh + deh);
+	const Image* hppic = get_hp_level_pic();
+	const Image* attackpic = get_attack_level_pic();
+	const Image* defensepic = get_defense_level_pic();
+	const Image* evadepic = get_evade_level_pic();
+
+	uint16_t hpw = hppic->width();
+	uint16_t hph = hppic->height();
+	uint16_t atw = attackpic->width();
+	uint16_t ath = attackpic->height();
+	uint16_t dew = defensepic->width();
+	uint16_t deh = defensepic->height();
+	uint16_t evw = evadepic->width();
+	uint16_t evh = evadepic->height();
+
+	uint32_t totalwidth = std::max<int>(std::max<int>(atw + dew, hpw + evw), 2 * w);
+	uint32_t totalheight = 5 + std::max<int>(hph + ath, evh + deh);
 
 	if (!anchor_below) {
 		pt.x += totalwidth / 2;
@@ -637,20 +638,20 @@
 {
 	const Soldier_Descr * soldierdesc = static_cast<const Soldier_Descr *>
 		(tribe.get_worker_descr(tribe.worker_index("soldier")));
-	const IPicture* hppic = soldierdesc->get_hp_level_pic(0);
-	const IPicture* attackpic = soldierdesc->get_attack_level_pic(0);
-	const IPicture* defensepic = soldierdesc->get_defense_level_pic(0);
-	const IPicture* evadepic = soldierdesc->get_evade_level_pic(0);
-	uint32_t hpw = hppic->get_w();
-	uint32_t hph = hppic->get_h();
-	uint32_t atw = attackpic->get_w();
-	uint32_t ath = attackpic->get_h();
-	uint32_t dew = defensepic->get_w();
-	uint32_t deh = defensepic->get_h();
-	uint32_t evw = evadepic->get_w();
-	uint32_t evh = evadepic->get_h();
+	const Image* hppic = soldierdesc->get_hp_level_pic(0);
+	const Image* attackpic = soldierdesc->get_attack_level_pic(0);
+	const Image* defensepic = soldierdesc->get_defense_level_pic(0);
+	const Image* evadepic = soldierdesc->get_evade_level_pic(0);
+	uint16_t hpw = hppic->width();
+	uint16_t hph = hppic->height();
+	uint16_t atw = attackpic->width();
+	uint16_t ath = attackpic->height();
+	uint16_t dew = defensepic->width();
+	uint16_t deh = defensepic->height();
+	uint16_t evw = evadepic->width();
+	uint16_t evh = evadepic->height();
 
-	uint32_t animw;
+	uint16_t animw;
 	animw = SOLDIER_HP_BAR_WIDTH;
 
 	w = std::max(std::max(atw + dew, hpw + evw), 2 * animw);

=== modified file 'src/logic/soldier.h'
--- src/logic/soldier.h	2012-11-24 16:22:10 +0000
+++ src/logic/soldier.h	2013-02-10 14:53:26 +0000
@@ -66,16 +66,16 @@
 	uint32_t get_defense_incr_per_level() const {return m_defense_incr;}
 	uint32_t get_evade_incr_per_level  () const {return m_evade_incr;}
 
-	const IPicture* get_hp_level_pic     (uint32_t const level) const {
+	const Image* get_hp_level_pic     (uint32_t const level) const {
 		assert(level <= m_max_hp_level);      return m_hp_pics     [level];
 	}
-	const IPicture* get_attack_level_pic (uint32_t const level) const {
+	const Image* get_attack_level_pic (uint32_t const level) const {
 		assert(level <= m_max_attack_level);  return m_attack_pics [level];
 	}
-	const IPicture* get_defense_level_pic(uint32_t const level) const {
+	const Image* get_defense_level_pic(uint32_t const level) const {
 		assert(level <= m_max_defense_level); return m_defense_pics[level];
 	}
-	const IPicture* get_evade_level_pic  (uint32_t const level) const {
+	const Image* get_evade_level_pic  (uint32_t const level) const {
 		assert(level <= m_max_evade_level);   return m_evade_pics  [level];
 	}
 
@@ -109,10 +109,10 @@
 	uint32_t m_max_evade_level;
 
 	//  level pictures
-	std::vector<const IPicture* >   m_hp_pics;
-	std::vector<const IPicture* >   m_attack_pics;
-	std::vector<const IPicture* >   m_evade_pics;
-	std::vector<const IPicture* >   m_defense_pics;
+	std::vector<const Image* >   m_hp_pics;
+	std::vector<const Image* >   m_attack_pics;
+	std::vector<const Image* >   m_evade_pics;
+	std::vector<const Image* >   m_defense_pics;
 	std::vector<std::string> m_hp_pics_fn;
 	std::vector<std::string> m_attack_pics_fn;
 	std::vector<std::string> m_evade_pics_fn;
@@ -226,16 +226,16 @@
 	uint32_t get_defense() const;
 	uint32_t get_evade() const;
 
-	const IPicture* get_hp_level_pic     () const {
+	const Image* get_hp_level_pic     () const {
 		return descr().get_hp_level_pic     (m_hp_level);
 	}
-	const IPicture* get_attack_level_pic () const {
+	const Image* get_attack_level_pic () const {
 		return descr().get_attack_level_pic (m_attack_level);
 	}
-	const IPicture* get_defense_level_pic() const {
+	const Image* get_defense_level_pic() const {
 		return descr().get_defense_level_pic(m_defense_level);
 	}
-	const IPicture* get_evade_level_pic  () const {
+	const Image* get_evade_level_pic  () const {
 		return descr().get_evade_level_pic  (m_evade_level);
 	}
 

=== modified file 'src/logic/widelands.h'
--- src/logic/widelands.h	2012-02-15 21:25:34 +0000
+++ src/logic/widelands.h	2013-02-10 14:53:26 +0000
@@ -30,15 +30,6 @@
 
 namespace Widelands {
 
-/// Maximum numbers of players in a game. The game logic code reserves 5 bits
-/// for player numbers, so it can keep track of 32 different player numbers, of
-/// which the value 0 means neutral and the values 1 .. 31 can be used as the
-/// numbers for actual players. So the upper limit of this value is 31.
-#define MAX_PLAYERS 8
-
-/// How often are statistics to be sampled.
-#define STATISTICS_SAMPLE_TIME 30000
-
 //  Type definitions for the game logic.
 
 typedef uint8_t Tribe_Index;

=== modified file 'src/logic/worker.cc'
--- src/logic/worker.cc	2013-01-20 08:50:06 +0000
+++ src/logic/worker.cc	2013-02-10 14:53:26 +0000
@@ -34,7 +34,6 @@
 #include "game.h"
 #include "game_data_error.h"
 #include "gamecontroller.h"
-#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "helper.h"
 #include "map_io/widelands_map_map_object_loader.h"

=== modified file 'src/logic/worker.h'
--- src/logic/worker.h	2012-11-24 16:22:10 +0000
+++ src/logic/worker.h	2013-02-10 14:53:26 +0000
@@ -89,7 +89,7 @@
 	uint32_t get_animation(char const * const str) const {
 		return descr().get_animation(str);
 	}
-	const IPicture* icon() const throw () {return descr().icon();}
+	const Image* icon() const throw () {return descr().icon();}
 	Ware_Index becomes() const throw () {return descr().becomes();}
 	Ware_Index worker_index() const throw () {return descr().worker_index();}
 	const Tribe_Descr * get_tribe() const throw () {return descr().get_tribe();}

=== modified file 'src/logic/worker_descr.cc'
--- src/logic/worker_descr.cc	2012-12-13 10:41:22 +0000
+++ src/logic/worker_descr.cc	2013-02-10 14:53:26 +0000
@@ -160,7 +160,7 @@
  */
 void Worker_Descr::load_graphics()
 {
-	m_icon = g_gr->imgcache().load(PicMod_Game, m_icon_fname.c_str());
+	m_icon = g_gr->images().get(m_icon_fname.c_str());
 }
 
 

=== modified file 'src/logic/worker_descr.h'
--- src/logic/worker_descr.h	2012-11-24 16:22:10 +0000
+++ src/logic/worker_descr.h	2013-02-10 14:53:26 +0000
@@ -26,7 +26,7 @@
 #include "immovable.h"
 #include "io/filewrite.h"
 
-class IPicture;
+class Image;
 
 namespace Widelands {
 
@@ -91,7 +91,7 @@
 			m_default_target_quantity = 1;
 	}
 
-	const IPicture* icon() const throw () {return m_icon;}
+	const Image* icon() const throw () {return m_icon;}
 	const DirAnimations & get_walk_anims() const throw () {return m_walk_anims;}
 	DirAnimations const & get_right_walk_anims(bool const carries_ware) const {
 		return carries_ware ? m_walkload_anims : m_walk_anims;
@@ -126,7 +126,7 @@
 	Point             m_ware_hotspot;
 	uint32_t          m_default_target_quantity;
 	std::string const m_icon_fname; ///< Filename of worker's icon
-	const IPicture* m_icon;       ///< Pointer to icon into picture stack
+	const Image* m_icon;       ///< Pointer to icon into picture stack
 	DirAnimations     m_walk_anims;
 	DirAnimations     m_walkload_anims;
 	bool              m_buildable;

=== modified file 'src/map_generator.cc'
--- src/map_generator.cc	2012-09-21 21:36:07 +0000
+++ src/map_generator.cc	2013-02-10 14:53:26 +0000
@@ -221,8 +221,8 @@
 	if (m_mapInfo.islandMode) {
 		int32_t const border_dist =
 			std::min
-				(std::min(c.x, static_cast<X_Coordinate>(m_mapInfo.w - c.x)),
-				 std::min(c.y, static_cast<Y_Coordinate>(m_mapInfo.h - c.y)));
+				(std::min<X_Coordinate>(c.x, m_mapInfo.w - c.x),
+				 std::min<Y_Coordinate>(c.y, m_mapInfo.h - c.y));
 		if (border_dist <= ISLAND_BORDER) {
 			res_h =
 				static_cast<uint8_t>

=== modified file 'src/map_io/widelands_map_building_data_packet.cc'
--- src/map_io/widelands_map_building_data_packet.cc	2012-06-06 19:32:13 +0000
+++ src/map_io/widelands_map_building_data_packet.cc	2013-02-10 14:53:26 +0000
@@ -19,17 +19,18 @@
 
 #include "widelands_map_building_data_packet.h"
 
+#include "economy/request.h"
+#include "graphic/graphic.h"
 #include "logic/constructionsite.h"
 #include "logic/editor_game_base.h"
-#include "wui/interactive_base.h"
 #include "logic/map.h"
 #include "logic/player.h"
-#include "economy/request.h"
 #include "logic/tribe.h"
 #include "logic/widelands_fileread.h"
 #include "logic/widelands_filewrite.h"
 #include "widelands_map_map_object_loader.h"
 #include "widelands_map_map_object_saver.h"
+#include "wui/interactive_base.h"
 
 #include "upcast.h"
 

=== modified file 'src/map_io/widelands_map_extradata_data_packet.cc'
--- src/map_io/widelands_map_extradata_data_packet.cc	2012-12-13 10:41:22 +0000
+++ src/map_io/widelands_map_extradata_data_packet.cc	2013-02-10 14:53:26 +0000
@@ -17,20 +17,20 @@
  *
  */
 
-#include "widelands_map_extradata_data_packet.h"
+#include <SDL_image.h>
 
+#include "graphic/graphic.h"
+#include "graphic/in_memory_image.h"
+#include "graphic/surface.h"
+#include "io/filewrite.h"
 #include "logic/editor_game_base.h"
-#include "io/filewrite.h"
 #include "logic/game_data_error.h"
-// Since we are lying about the path of the pictures
-// we also include graphic.h
-#include "graphic/graphic.h"
 #include "logic/map.h"
-#include "profile/profile.h"
 #include "logic/widelands_fileread.h"
 #include "logic/widelands_filewrite.h"
+#include "profile/profile.h"
 
-#include <SDL_image.h>
+#include "widelands_map_extradata_data_packet.h"
 
 namespace Widelands {
 
@@ -75,17 +75,17 @@
 					if (!surf)
 						continue; //  Illegal pic. Skip it.
 
-					IPicture* picture = g_gr->convert_sdl_surface_to_picture(surf);
-
-					std::string picname = FileSystem::FS_Filename(pname->c_str());
-					g_gr->imgcache().insert(PicMod_Game, "map:" + picname, picture);
+					const Image* image =
+					g_gr->images().insert
+					(new_in_memory_image
+					 (std::string("map:") + FileSystem::FS_Filename(pname->c_str()), Surface::create(surf)));
 
 					//  OK, the pic is now known to the game. But when the game is
 					//  saved, this data has to be regenerated.
 					Map::Extradata_Info info;
 					info.type     = Map::Extradata_Info::PIC;
 					info.filename = *pname;
-					info.data     = picture;
+					info.data     = image;
 					// replace \ with / in path or pics won't be saved on Windows
 					std::replace(info.filename.begin(), info.filename.end(), '\\', '/');
 					map.m_extradatainfos.push_back(info);

=== modified file 'src/map_io/widelands_map_map_object_saver.h'
--- src/map_io/widelands_map_map_object_saver.h	2012-02-15 21:25:34 +0000
+++ src/map_io/widelands_map_map_object_saver.h	2013-02-10 14:53:26 +0000
@@ -20,6 +20,7 @@
 #ifndef WIDELANDS_MAP_MAP_OBJECT_SAVER_H
 #define WIDELANDS_MAP_MAP_OBJECT_SAVER_H
 
+#include "constants.h"
 #include "logic/widelands.h"
 #include "widelands_map_message_saver.h"
 

=== modified file 'src/map_io/widelands_map_message_saver.h'
--- src/map_io/widelands_map_message_saver.h	2012-07-13 20:46:30 +0000
+++ src/map_io/widelands_map_message_saver.h	2013-02-10 14:53:26 +0000
@@ -20,12 +20,12 @@
 #ifndef WIDELANDS_MAP_MESSAGE_SAVER_H
 #define WIDELANDS_MAP_MESSAGE_SAVER_H
 
-#include "logic/message_id.h"
-
+#include <cassert>
 #include <map>
-
 #include <stdint.h>
 
+#include "logic/message_id.h"
+
 namespace Widelands {
 
 /// A map used during save to store the sequence number in the saved file of

=== modified file 'src/sound/sound_handler.cc'
--- src/sound/sound_handler.cc	2013-01-06 20:04:34 +0000
+++ src/sound/sound_handler.cc	2013-02-10 14:53:26 +0000
@@ -19,16 +19,17 @@
 
 #include "sound_handler.h"
 
+#include "graphic/graphic.h"
+#include "i18n.h"
 #include "io/fileread.h"
+#include "io/filesystem/layered_filesystem.h"
 #include "logic/game.h"
-#include "i18n.h"
+#include "logic/map.h"
+#include "profile/profile.h"
+#include "songset.h"
 #include "wui/interactive_base.h"
-#include "io/filesystem/layered_filesystem.h"
-#include "logic/map.h"
 #include "wui/mapview.h"
 #include "wui/mapviewpixelfunctions.h"
-#include "profile/profile.h"
-#include "songset.h"
 
 #include "log.h"
 

=== modified file 'src/text_parser.cc'
--- src/text_parser.cc	2012-12-16 19:08:53 +0000
+++ src/text_parser.cc	2013-02-10 14:53:26 +0000
@@ -20,7 +20,6 @@
 #include "text_parser.h"
 
 #include "constants.h"
-#include "graphic/graphic.h"
 #include "helper.h"
 #include "log.h"
 

=== modified file 'src/text_parser.h'
--- src/text_parser.h	2012-02-15 21:25:34 +0000
+++ src/text_parser.h	2013-02-10 14:53:26 +0000
@@ -23,7 +23,7 @@
 #include <vector>
 #include <string>
 
-#include "ui_basic/align.h"
+#include "align.h"
 #include "rgbcolor.h"
 
 namespace UI {

=== modified file 'src/ui_basic/button.cc'
--- src/ui_basic/button.cc	2012-12-14 20:09:35 +0000
+++ src/ui_basic/button.cc	2013-02-10 14:53:26 +0000
@@ -23,10 +23,11 @@
 
 #include "graphic/font.h"
 #include "graphic/font_handler.h"
-#include "graphic/picture.h"
+#include "graphic/image.h"
+#include "graphic/image_transformations.h"
 #include "graphic/rendertarget.h"
+#include "log.h"
 #include "wlapplication.h"
-#include "log.h"
 
 
 namespace UI {
@@ -35,7 +36,7 @@
 	(Panel * const parent,
 	 const std::string & name,
 	 int32_t const x, int32_t const y, uint32_t const w, uint32_t const h,
-	 const IPicture* background_picture_id,
+	 const Image* bg_pic,
 	 std::string const & title_text,
 	 std::string const & tooltip_text,
 	 bool const _enabled, bool const flat)
@@ -50,7 +51,7 @@
 	m_draw_flat_background(false),
 	m_time_nextact  (0),
 	m_title         (title_text),
-	m_pic_background(background_picture_id),
+	m_pic_background(bg_pic),
 	m_pic_custom    (NULL),
 	m_pic_custom_disabled(NULL),
 	m_font(UI::Font::ui_small()),
@@ -68,8 +69,8 @@
 	(Panel * const parent,
 	 const std::string & name,
 	 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
-	 const IPicture* background_picture_id,
-	 const IPicture* foreground_picture_id,
+	 const Image* bg_pic,
+	 const Image* fg_pic,
 	 const std::string & tooltip_text,
 	 bool const _enabled, bool const flat)
 	:
@@ -82,9 +83,9 @@
 	m_flat          (flat),
 	m_draw_flat_background(false),
 	m_time_nextact  (0),
-	m_pic_background(background_picture_id),
-	m_pic_custom    (foreground_picture_id),
-	m_pic_custom_disabled(g_gr->create_grayed_out_pic(foreground_picture_id)),
+	m_pic_background(bg_pic),
+	m_pic_custom    (fg_pic),
+	m_pic_custom_disabled(fg_pic ? ImageTransformations::gray_out(fg_pic) : NULL),
 	m_font(UI::Font::ui_small()),
 	m_clr_down      (229, 161, 2),
 	m_draw_caret    (false)
@@ -104,7 +105,7 @@
 /**
  * Sets a new picture for the Button.
 */
-void Button::set_pic(const IPicture* pic)
+void Button::set_pic(const Image* pic)
 {
 	m_title.clear();
 
@@ -112,7 +113,7 @@
 		return;
 
 	m_pic_custom = pic;
-	m_pic_custom_disabled = g_gr->create_grayed_out_pic(pic);
+	m_pic_custom_disabled = ImageTransformations::gray_out(pic);
 
 	update();
 }
@@ -175,8 +176,8 @@
 
 	//  if we got a picture, draw it centered
 	if (m_pic_custom) {
-		uint32_t cpw = m_pic_custom->get_w();
-		uint32_t cph = m_pic_custom->get_h();
+		uint16_t cpw = m_pic_custom->width();
+		uint16_t cph = m_pic_custom->height();
 
 		//  ">> 1" is almost like "/ 2", but simpler for signed types (difference
 		//  is that -1 >> 1 is -1 but -1 / 2 is 0).

=== modified file 'src/ui_basic/button.h'
--- src/ui_basic/button.h	2012-12-14 20:09:35 +0000
+++ src/ui_basic/button.h	2013-02-10 14:53:26 +0000
@@ -41,7 +41,7 @@
 		(Panel * const parent,
 		 std::string const & name,
 		 int32_t const x, int32_t const y, uint32_t const w, uint32_t const h,
-		 const IPicture* background_pictute_id,
+		 const Image* background_pictute_id,
 		 std::string const & title_text,
 		 std::string const & tooltip_text = std::string(),
 		 bool const _enabled = true,
@@ -50,14 +50,14 @@
 		(Panel * const parent,
 		 std::string const & name,
 		 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
-		 const IPicture* background_pictute_id,
-		 const IPicture* foreground_picture_id,
+		 const Image* background_pictute_id,
+		 const Image* foreground_picture_id,
 		 std::string const & tooltip_text = std::string(),
 		 bool const _enabled = true,
 		 bool const flat     = false);
 	~Button();
 
-	void set_pic(const IPicture* pic);
+	void set_pic(const Image* pic);
 	void set_title(const std::string &);
 	const std::string & get_title() const throw () {return m_title;}
 
@@ -105,9 +105,9 @@
 
 	std::string m_title;          //  title string used when _mypic == 0
 
-	const IPicture* m_pic_background; //  background texture (picture ID)
-	const IPicture* m_pic_custom;     //  custom icon on the button
-	const IPicture* m_pic_custom_disabled;
+	const Image* m_pic_background; //  background texture (picture ID)
+	const Image* m_pic_custom;     //  custom icon on the button
+	const Image* m_pic_custom_disabled;
 	Font * m_font;
 
 	RGBColor    m_clr_down; //  color of border while a flat button is "down"

=== modified file 'src/ui_basic/checkbox.cc'
--- src/ui_basic/checkbox.cc	2012-12-14 20:09:35 +0000
+++ src/ui_basic/checkbox.cc	2013-02-10 14:53:26 +0000
@@ -33,15 +33,15 @@
 Statebox::Statebox
 	(Panel             * const parent,
 	 Point               const p,
-	 const IPicture* pic,
+	 const Image* pic,
 	 std::string const &       tooltip_text)
 	:
 	Panel  (parent, p.x, p.y, STATEBOX_WIDTH, STATEBOX_HEIGHT, tooltip_text),
 	m_flags(Is_Enabled)
 {
 	if (pic) {
-		uint32_t w = pic->get_w();
-		uint32_t h = pic->get_h();
+		uint16_t w = pic->width();
+		uint16_t h = pic->height();
 		set_desired_size(w, h);
 		set_size(w, h);
 
@@ -49,7 +49,7 @@
 		m_pic_graphics = pic;
 	} else
 		m_pic_graphics =
-			g_gr->imgcache().load(PicMod_UI, "pics/checkbox_light.png");
+			g_gr->images().get("pics/checkbox_light.png");
 }
 
 
@@ -72,9 +72,7 @@
 	set_flags(Is_Enabled, enabled);
 
 	if (not (m_flags & Has_Custom_Picture)) {
-		m_pic_graphics = g_gr->imgcache().load
-			(PicMod_UI,
-			 enabled ? "pics/checkbox_light.png" : "pics/checkbox.png");
+		m_pic_graphics = g_gr->images().get(enabled ? "pics/checkbox_light.png" : "pics/checkbox.png");
 		set_flags
 			(Is_Highlighted, (m_flags & Is_Highlighted) and (m_flags & Is_Enabled));
 	}
@@ -105,8 +103,8 @@
 {
 	if (m_flags & Has_Custom_Picture) {
 		// center picture
-		uint32_t w = m_pic_graphics->get_w();
-		uint32_t h = m_pic_graphics->get_h();
+		uint16_t w = m_pic_graphics->width();
+		uint16_t h = m_pic_graphics->height();
 
 		dst.blit
 			(Point((get_inner_w() - w) / 2, (get_inner_h() - h) / 2),

=== modified file 'src/ui_basic/checkbox.h'
--- src/ui_basic/checkbox.h	2012-12-14 20:09:35 +0000
+++ src/ui_basic/checkbox.h	2013-02-10 14:53:26 +0000
@@ -39,7 +39,7 @@
 	Statebox
 		(Panel * parent,
 		 Point,
-		 const IPicture* pic                  = 0,
+		 const Image* pic                  = 0,
 		 std::string const & tooltip_text = std::string());
 	~Statebox();
 
@@ -81,7 +81,7 @@
 		if (enable)
 			m_flags |= flags;
 	}
-	const IPicture* m_pic_graphics;
+	const Image* m_pic_graphics;
 };
 
 
@@ -95,7 +95,7 @@
 	Checkbox
 		(Panel             * const parent,
 		 Point               const p,
-		 const IPicture* pic        = 0,
+		 const Image* pic        = 0,
 		 std::string const &       tooltip_text = std::string())
 		: Statebox(parent, p, pic, tooltip_text)
 	{}

=== modified file 'src/ui_basic/editbox.cc'
--- src/ui_basic/editbox.cc	2012-11-24 16:22:10 +0000
+++ src/ui_basic/editbox.cc	2013-02-10 14:53:26 +0000
@@ -42,7 +42,7 @@
 	/*@}*/
 
 	/// Background tile style.
-	const IPicture* background;
+	const Image* background;
 
 	/// Maximum number of characters in the input
 	uint32_t maxLength;
@@ -63,7 +63,7 @@
 EditBox::EditBox
 	(Panel * const parent,
 	 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
-	 const IPicture* background,
+	 const Image* background,
 	 Align _align)
 	:
 	Panel(parent, x, y, w, h),

=== modified file 'src/ui_basic/editbox.h'
--- src/ui_basic/editbox.h	2012-12-13 10:41:22 +0000
+++ src/ui_basic/editbox.h	2013-02-10 14:53:26 +0000
@@ -20,12 +20,14 @@
 #ifndef UI_EDITBOX_H
 #define UI_EDITBOX_H
 
-#include "align.h"
-#include "button.h"
-
+#include <SDL_keyboard.h>
 #include <boost/scoped_ptr.hpp>
 #include <boost/signal.hpp>
-#include <SDL_keyboard.h>
+
+#include "button.h"
+
+#include "align.h"
+#include "graphic/graphic.h"
 
 #define CHAT_HISTORY_SIZE 5
 
@@ -40,9 +42,7 @@
 	EditBox
 		(Panel *,
 		 int32_t x, int32_t y, uint32_t w, uint32_t h,
-		 const IPicture* background =
-		 	g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
-		 Align align = Align_Center);
+		 const Image* background = g_gr->images().get("pics/but2.png"), Align align = Align_Center);
 	virtual ~EditBox();
 
 	boost::signal<void ()> changed;

=== modified file 'src/ui_basic/helpwindow.cc'
--- src/ui_basic/helpwindow.cc	2012-12-13 10:41:22 +0000
+++ src/ui_basic/helpwindow.cc	2013-02-10 14:53:26 +0000
@@ -23,13 +23,14 @@
 #include "scripting/scripting.h"
 #include "io/filesystem/layered_filesystem.h"
 
-#include "log.h"
+#include "button.h"
 #include "constants.h"
+#include "graphic/font.h"
+#include "graphic/font_handler.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
+#include "log.h"
 #include "window.h"
-#include "button.h"
-#include "graphic/font.h"
-#include "graphic/font_handler.h"
 #include "wlapplication.h"
 
 #include "helpwindow.h"
@@ -79,7 +80,7 @@
 		(this, "ok",
 		 in_width / 3, in_height - but_height * 3 / 2,
 		 in_width / 3, but_height,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("OK"), std::string(), true, false);
 	btn->sigclicked.connect(boost::bind(&HelpWindow::pressedOk, boost::ref(*this)));
 	btn->set_font(Font::get(UI_FONT_NAME, (fontsize < 12 ? 12 : fontsize)));

=== modified file 'src/ui_basic/helpwindow.h'
--- src/ui_basic/helpwindow.h	2012-02-15 21:25:34 +0000
+++ src/ui_basic/helpwindow.h	2013-02-10 14:53:26 +0000
@@ -21,6 +21,7 @@
 #define UI_HELPWINDOW_H
 
 #include "align.h"
+
 #include "multilinetextarea.h"
 #include "unique_window.h"
 #include "window.h"

=== modified file 'src/ui_basic/icon.cc'
--- src/ui_basic/icon.cc	2012-11-29 21:01:10 +0000
+++ src/ui_basic/icon.cc	2013-02-10 14:53:26 +0000
@@ -17,16 +17,16 @@
  *
  */
 
+#include "graphic/image.h"
+#include "graphic/rendertarget.h"
 #include "icon.h"
-#include "graphic/rendertarget.h"
-#include "graphic/picture.h"
 
 namespace UI {
 
 Icon::Icon
 	(Panel * const parent,
 	 const int32_t x, const int32_t y, const int32_t w, const int32_t h,
-	 const IPicture* picture_id)
+	 const Image* picture_id)
 	:
 	Panel(parent, x, y, w, h),
 	m_pic(picture_id),
@@ -37,15 +37,15 @@
 	set_think(false);
 }
 
-void Icon::setIcon(const IPicture* picture_id) {
+void Icon::setIcon(const Image* picture_id) {
 	m_pic = picture_id;
 	update();
 }
 
 void Icon::draw(RenderTarget & dst) {
 	assert(m_pic);
-	int32_t w = (m_w - m_pic->get_w()) / 2;
-	int32_t h = (m_h - m_pic->get_h()) / 2;
+	int32_t w = (m_w - m_pic->width()) / 2;
+	int32_t h = (m_h - m_pic->height()) / 2;
 	dst.blit(Point(w, h), m_pic);
 }
 

=== modified file 'src/ui_basic/icon.h'
--- src/ui_basic/icon.h	2012-11-24 16:22:10 +0000
+++ src/ui_basic/icon.h	2013-02-10 14:53:26 +0000
@@ -31,13 +31,13 @@
 	Icon
 		(Panel * parent,
 		 int32_t x, int32_t y, int32_t w, int32_t h,
-		 const IPicture* picture_id);
+		 const Image* picture_id);
 
-	void setIcon(const IPicture* picture_id);
+	void setIcon(const Image* picture_id);
 	virtual void draw(RenderTarget &);
 
 private:
-	const IPicture* m_pic;
+	const Image* m_pic;
 	int32_t   m_w, m_h;
 };
 

=== modified file 'src/ui_basic/icongrid.cc'
--- src/ui_basic/icongrid.cc	2013-01-23 21:07:18 +0000
+++ src/ui_basic/icongrid.cc	2013-02-10 14:53:26 +0000
@@ -35,8 +35,8 @@
 		(Icon_Grid         & parent,
 		 const std::string & name,
 		 int32_t x, int32_t y, uint32_t w, uint32_t h,
-		 const IPicture* background_pictute_id,
-		 const IPicture* foreground_picture_id,
+		 const Image* background_pictute_id,
+		 const Image* foreground_picture_id,
 		 uint32_t callback_argument_id,
 		 const std::string & tooltip_text)
 		:
@@ -82,7 +82,7 @@
  * Returns the index of the newly added icon.
 */
 int32_t Icon_Grid::add
-	(const std::string & name, const IPicture* pic,
+	(const std::string & name, const Image* pic,
 	 void * data, const std::string & tooltip_text)
 {
 	Item it;

=== modified file 'src/ui_basic/icongrid.h'
--- src/ui_basic/icongrid.h	2013-01-23 15:11:30 +0000
+++ src/ui_basic/icongrid.h	2013-02-10 14:53:26 +0000
@@ -47,7 +47,7 @@
 
 	int32_t add
 		(std::string const & name,
-		 const IPicture* pic,
+		 const Image* pic,
 		 void              * data,
 		 const std::string & tooltip_text = "");
 	void * get_data(int32_t idx);

=== modified file 'src/ui_basic/listselect.cc'
--- src/ui_basic/listselect.cc	2013-01-05 18:52:13 +0000
+++ src/ui_basic/listselect.cc	2013-02-10 14:53:26 +0000
@@ -22,9 +22,10 @@
 #include "constants.h"
 #include "graphic/font.h"
 #include "graphic/font_handler.h"
+#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
+#include "log.h"
 #include "wlapplication.h"
-#include "log.h"
 
 #include "container_iterate.h"
 
@@ -70,9 +71,9 @@
 
 	if (show_check) {
 		uint32_t pic_h;
-		m_check_pic = g_gr->imgcache().load(PicMod_Game,  "pics/list_selected.png");
-		m_max_pic_width = m_check_pic->get_w();
-		pic_h = m_check_pic->get_h();
+		m_check_pic = g_gr->images().get("pics/list_selected.png");
+		m_max_pic_width = m_check_pic->width();
+		pic_h = m_check_pic->height();
 		if (pic_h > m_lineheight)
 			m_lineheight = pic_h;
 	}
@@ -116,7 +117,7 @@
 void BaseListselect::add
 	(char const * const   name,
 	 uint32_t             entry,
-	 const IPicture*   pic,
+	 const Image*   pic,
 	 bool         const   sel,
 	 std::string  const & tooltip_text)
 {
@@ -131,8 +132,8 @@
 	if (!pic) {
 		entry_height = g_fh->get_fontheight(m_fontname, m_fontsize);
 	} else {
-		uint32_t w = pic->get_w();
-		uint32_t h = pic->get_h();
+		uint16_t w = pic->width();
+		uint16_t h = pic->height();
 		entry_height = (h >= g_fh->get_fontheight(m_fontname, m_fontsize))
 			? h : g_fh->get_fontheight(m_fontname, m_fontsize);
 		if (m_max_pic_width < w)
@@ -154,7 +155,7 @@
 
 void BaseListselect::add_front
 	(char const * const   name,
-	 const IPicture*   pic,
+	 const Image*   pic,
 	 bool         const   sel,
 	 std::string  const & tooltip_text)
 {
@@ -173,8 +174,8 @@
 	if (!pic)
 		entry_height = g_fh->get_fontheight(m_fontname, m_fontsize);
 	else {
-		uint32_t w = pic->get_w();
-		uint32_t h = pic->get_h();
+		uint16_t w = pic->width();
+		uint16_t h = pic->height();
 		entry_height = (h >= g_fh->get_fontheight(m_fontname, m_fontsize))
 			? h : g_fh->get_fontheight(m_fontname, m_fontsize);
 		if (m_max_pic_width < w)
@@ -411,7 +412,7 @@
 
 		// Now draw pictures
 		if (er.pic) {
-			uint32_t h = er.pic->get_h();
+			uint16_t h = er.pic->height();
 			dst.blit(Point(1, y + (get_lineheight() - h) / 2), er.pic);
 		}
 

=== modified file 'src/ui_basic/listselect.h'
--- src/ui_basic/listselect.h	2012-12-14 20:09:35 +0000
+++ src/ui_basic/listselect.h	2013-02-10 14:53:26 +0000
@@ -21,17 +21,18 @@
 #ifndef UI_LISTSELECT_H
 #define UI_LISTSELECT_H
 
+#include <limits>
+#include <deque>
+
 #include <boost/signal.hpp>
 
 #include "align.h"
+#include "compile_assert.h"
+
 #include "panel.h"
+#include "rgbcolor.h"
 #include "scrollbar.h"
 
-#include "compile_assert.h"
-
-#include <limits>
-#include <deque>
-
 namespace UI {
 struct Scrollbar;
 
@@ -63,12 +64,12 @@
 	void add
 		(const char * const name,
 		 uint32_t value,
-		 const IPicture* pic = NULL,
+		 const Image* pic = NULL,
 		 const bool select_this = false,
 		 std::string const & tooltip_text = std::string());
 	void add_front
 		(const char * const name,
-		 const IPicture* pic = NULL,
+		 const Image* pic = NULL,
 		 const bool select_this = false,
 		 std::string const & tooltip_text = std::string());
 	void remove(uint32_t);
@@ -133,7 +134,7 @@
 		uint32_t m_entry;
 		bool use_clr;
 		RGBColor clr;
-		const IPicture* pic;
+		const Image* pic;
 		std::string name;
 		std::string tooltip;
 	};
@@ -149,7 +150,7 @@
 	int32_t m_last_click_time;
 	uint32_t m_last_selection;  // for double clicks
 	bool m_show_check; //  show a green arrow left of selected element
-	const IPicture* m_check_pic;
+	const Image* m_check_pic;
 
 	std::string m_fontname;
 	uint32_t    m_fontsize;
@@ -170,7 +171,7 @@
 	void add
 		(const char * const name,
 		 Entry value,
-		 const IPicture* pic = NULL,
+		 const Image* pic = NULL,
 		 const bool select_this = false,
 		 std::string const & tooltip_text = std::string())
 	{
@@ -180,7 +181,7 @@
 	void add_front
 		(const char * const name,
 		 Entry value,
-		 const IPicture* pic = NULL,
+		 const Image* pic = NULL,
 		 const bool select_this = false,
 		 std::string const & tooltip_text = std::string())
 	{
@@ -225,7 +226,7 @@
 	void add
 		(const char * const name,
 		 Entry      &       value,
-		 const IPicture* pic = NULL,
+		 const Image* pic = NULL,
 		 const bool select_this = false,
 		 std::string const & tooltip_text = std::string())
 	{
@@ -234,7 +235,7 @@
 	void add_front
 		(const char * const name,
 		 Entry      &       value,
-		 const IPicture* pic = NULL,
+		 const Image* pic = NULL,
 		 const bool select_this = false,
 		 std::string const & tooltip_text = std::string())
 	{

=== modified file 'src/ui_basic/messagebox.cc'
--- src/ui_basic/messagebox.cc	2012-12-13 10:41:22 +0000
+++ src/ui_basic/messagebox.cc	2013-02-10 14:53:26 +0000
@@ -19,12 +19,13 @@
 
 #include "messagebox.h"
 
+#include "button.h"
 #include "constants.h"
+#include "graphic/font_handler.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
+#include "multilinetextarea.h"
 #include "window.h"
-#include "multilinetextarea.h"
-#include "button.h"
-#include "graphic/font_handler.h"
 #include "wlapplication.h"
 
 namespace UI {
@@ -86,21 +87,21 @@
 		UI::Button * okbtn = new Button
 			(this, "ok",
 			 (get_inner_w() - 60) / 2, get_inner_h() - 30, 60, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+			 g_gr->images().get("pics/but0.png"),
 			 _("OK"));
 		okbtn->sigclicked.connect(boost::bind(&WLMessageBox::pressedOk, boost::ref(*this)));
 	} else if (type == YESNO) {
 		UI::Button * yesbtn = new Button
 			(this, "yes",
 			 (get_inner_w() / 2 - 60) / 2, get_inner_h() - 30, 60, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+			 g_gr->images().get("pics/but0.png"),
 			 _("Yes"));
 		yesbtn->sigclicked.connect(boost::bind(&WLMessageBox::pressedYes, boost::ref(*this)));
 		UI::Button * nobtn = new Button
 			(this, "no",
 			 (get_inner_w() / 2 - 60) / 2 + get_inner_w() / 2, get_inner_h() - 30,
 			 60, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+			 g_gr->images().get("pics/but1.png"),
 			 _("No"));
 		nobtn->sigclicked.connect(boost::bind(&WLMessageBox::pressedNo, boost::ref(*this)));
 	}

=== modified file 'src/ui_basic/messagebox.h'
--- src/ui_basic/messagebox.h	2012-02-15 21:25:34 +0000
+++ src/ui_basic/messagebox.h	2013-02-10 14:53:26 +0000
@@ -21,6 +21,7 @@
 #define UI_MESSAGEBOX_H
 
 #include "align.h"
+
 #include "window.h"
 
 #include <boost/scoped_ptr.hpp>

=== modified file 'src/ui_basic/multilinetextarea.h'
--- src/ui_basic/multilinetextarea.h	2012-02-15 21:25:34 +0000
+++ src/ui_basic/multilinetextarea.h	2013-02-10 14:53:26 +0000
@@ -20,7 +20,9 @@
 #ifndef UI_MULTILINE_TEXTAREA_H
 #define UI_MULTILINE_TEXTAREA_H
 
+#include "rgbcolor.h"
 #include "align.h"
+
 #include "panel.h"
 #include "scrollbar.h"
 

=== modified file 'src/ui_basic/panel.cc'
--- src/ui_basic/panel.cc	2013-01-05 20:27:32 +0000
+++ src/ui_basic/panel.cc	2013-02-10 14:53:26 +0000
@@ -22,13 +22,15 @@
 #include "constants.h"
 #include "graphic/font_handler.h"
 #include "graphic/font_handler1.h"
-#include "graphic/iblitable_surface.h"
+#include "graphic/graphic.h"
+#include "graphic/in_memory_image.h"
 #include "graphic/rendertarget.h"
+#include "graphic/surface.h"
 #include "log.h"
 #include "profile/profile.h"
 #include "sound/sound_handler.h"
+#include "text_layout.h"
 #include "wlapplication.h"
-#include "text_layout.h"
 
 #include "panel.h"
 
@@ -42,8 +44,8 @@
 // events are ignored and not passed on to any widget. This is only useful
 // for scripts that want to show off functionality without the user interfering.
 bool Panel::_g_allow_user_input = true;
-const IPicture* Panel::s_default_cursor = NULL;
-const IPicture* Panel::s_default_cursor_click = NULL;
+const Image* Panel::s_default_cursor = NULL;
+const Image* Panel::s_default_cursor_click = NULL;
 
 /**
  * Initialize a panel, link it into the parent's queue.
@@ -137,8 +139,8 @@
 	while (Panel * const p = forefather->_parent)
 		forefather = p;
 
-	s_default_cursor = g_gr->imgcache().load(PicMod_UI,  "pics/cursor.png");
-	s_default_cursor_click = g_gr->imgcache().load(PicMod_UI,  "pics/cursor_click.png");
+	s_default_cursor = g_gr->images().get("pics/cursor.png");
+	s_default_cursor_click = g_gr->images().get("pics/cursor_click.png");
 
 	// Loop
 	_running = true;
@@ -835,15 +837,15 @@
 
 		if
 			(!_cache ||
-			 _cache.get()->get_w() != innerw ||
-			 _cache.get()->get_h() != innerh)
+			 _cache.get()->width() != innerw ||
+			 _cache.get()->height() != innerh)
 		{
-			_cache.reset(g_gr->create_surface(innerw, innerh, false));
+			_cache.reset(new_in_memory_image("dummy_hash", Surface::create(innerw, innerh)));
 			_needdraw = true;
 		}
 
 		if (_needdraw) {
-			RenderTarget inner(_cache.get());
+			RenderTarget inner(_cache->surface());
 			do_draw_inner(inner);
 
 			_needdraw = false;
@@ -1079,8 +1081,8 @@
 		return;
 
 	Panel * p;
-	uint32_t w = s_default_cursor->get_w();
-	uint32_t h = s_default_cursor->get_h();
+	uint16_t w = s_default_cursor->width();
+	uint16_t h = s_default_cursor->height();
 
 	g_gr->update_rectangle(x - xdiff, y - ydiff, w, h);
 	g_gr->update_rectangle(x, y, w, h);
@@ -1117,12 +1119,12 @@
 	}
 
 	static const uint32_t TIP_WIDTH_MAX = 360;
-	const IPicture* rendered_text = UI::g_fh1->render(text_to_render, TIP_WIDTH_MAX);
+	const Image* rendered_text = g_fh1->render(text_to_render, TIP_WIDTH_MAX);
 	if (!rendered_text)
 		return;
 
-	uint32_t tip_width = rendered_text->get_w() + 4;
-	uint32_t tip_height = rendered_text->get_h() + 4;
+	uint16_t tip_width = rendered_text->width() + 4;
+	uint16_t tip_height = rendered_text->height() + 4;
 
 	Rect r
 		(WLApplication::get()->get_mouse_position() + Point(2, 32),

=== modified file 'src/ui_basic/panel.h'
--- src/ui_basic/panel.h	2012-12-31 11:21:15 +0000
+++ src/ui_basic/panel.h	2013-02-10 14:53:26 +0000
@@ -26,7 +26,6 @@
 #include <boost/signals/trackable.hpp>
 
 #include "point.h"
-#include "graphic/graphic.h"
 
 #include <SDL_keyboard.h>
 
@@ -35,6 +34,7 @@
 #include <cstring>
 
 class RenderTarget;
+class Image;
 
 namespace UI {
 
@@ -275,7 +275,7 @@
 	Panel * _focus; //  keyboard focus
 
 	uint32_t _flags;
-	boost::scoped_ptr<Surface> _cache;
+	boost::scoped_ptr<const Image> _cache;
 	bool _needdraw;
 
 	/**
@@ -297,8 +297,8 @@
 	static Panel * _g_mousegrab;
 	static Panel * _g_mousein;
 	static bool _g_allow_user_input;
-	static const IPicture* s_default_cursor;
-	static const IPicture* s_default_cursor_click;
+	static const Image* s_default_cursor;
+	static const Image* s_default_cursor_click;
 };
 
 inline void Panel::set_snap_windows_only_when_overlapping(const bool on) {

=== modified file 'src/ui_basic/progresswindow.cc'
--- src/ui_basic/progresswindow.cc	2012-12-13 10:41:22 +0000
+++ src/ui_basic/progresswindow.cc	2013-02-10 14:53:26 +0000
@@ -22,6 +22,8 @@
 #include "constants.h"
 #include "graphic/font.h"
 #include "graphic/font_handler.h"
+#include "graphic/graphic.h"
+#include "graphic/image_transformations.h"
 #include "graphic/rendertarget.h"
 #include "i18n.h"
 #include "io/filesystem/layered_filesystem.h"
@@ -65,14 +67,7 @@
 
 	if (!m_background_pic or xres != m_xres or yres != m_yres) {
 		// (Re-)Load background graphics
-		// Note that the old pic is freed automatically
-		const IPicture* background_original =
-			g_gr->imgcache().load(PicMod_Menu, m_background.c_str());
-
-		const IPicture* background_resized  =
-			g_gr->get_resized_picture(background_original, xres, yres);
-
-		m_background_pic = background_resized;
+		m_background_pic = ImageTransformations::resize(g_gr->images().get(m_background), xres, yres);
 
 		const uint32_t h = g_fh->get_fontheight (UI_FONT_SMALL);
 		m_label_rectangle.x = xres / 4;

=== modified file 'src/ui_basic/progresswindow.h'
--- src/ui_basic/progresswindow.h	2012-11-24 16:22:10 +0000
+++ src/ui_basic/progresswindow.h	2013-02-10 14:53:26 +0000
@@ -20,12 +20,16 @@
 #ifndef UI_PROGRESSWINDOW_H
 #define UI_PROGRESSWINDOW_H
 
-#include "graphic/graphic.h"
-
 #include <string>
 #include <cstring>
 #include <vector>
 
+#include "point.h"
+#include "rect.h"
+
+class Image;
+class RenderTarget;
+
 namespace UI {
 
 /// Manages a progress window on the screen.
@@ -64,7 +68,7 @@
 	Rect  m_label_rectangle;
 	VisualizationArray m_visualizations;
 	std::string m_background;
-	const IPicture* m_background_pic;
+	const Image* m_background_pic;
 
 	void draw_background(RenderTarget & rt, uint32_t xres, uint32_t yres);
 	void update(bool repaint);

=== modified file 'src/ui_basic/radiobutton.cc'
--- src/ui_basic/radiobutton.cc	2012-12-20 06:30:19 +0000
+++ src/ui_basic/radiobutton.cc	2013-02-10 14:53:26 +0000
@@ -29,7 +29,7 @@
 Radiobutton::Radiobutton
 	(Panel      * const parent,
 	 Point        const p,
-	 const IPicture* pic,
+	 const Image* pic,
 	 Radiogroup &       group,
 	 int32_t      const id)
 	:
@@ -96,7 +96,7 @@
 int32_t Radiogroup::add_button
 	(Panel      * const parent,
 	 Point        const p,
-	 const IPicture* pic,
+	 const Image* pic,
 	 const std::string& tooltip,
 	 Radiobutton **     ret_btn)
 {

=== modified file 'src/ui_basic/radiobutton.h'
--- src/ui_basic/radiobutton.h	2012-12-20 06:30:19 +0000
+++ src/ui_basic/radiobutton.h	2013-02-10 14:53:26 +0000
@@ -36,7 +36,7 @@
 	friend struct Radiogroup;
 
 	Radiobutton
-		(Panel * parent, Point, const IPicture* pic, Radiogroup &, int32_t id);
+		(Panel * parent, Point, const Image* pic, Radiogroup &, int32_t id);
 	~Radiobutton();
 
 private:
@@ -62,7 +62,7 @@
 	boost::signal<void ()> clicked; //  clicked without things changed
 
 	int32_t add_button
-		(Panel * parent, Point, const IPicture* pic, const std::string& tooltip = "", Radiobutton ** = NULL);
+		(Panel * parent, Point, const Image* pic, const std::string& tooltip = "", Radiobutton ** = NULL);
 
 	int32_t get_state() const throw () {return m_state;}
 	void set_state(int32_t state);

=== modified file 'src/ui_basic/scrollbar.cc'
--- src/ui_basic/scrollbar.cc	2012-12-13 10:41:22 +0000
+++ src/ui_basic/scrollbar.cc	2013-02-10 14:53:26 +0000
@@ -57,16 +57,12 @@
 	m_time_nextact  (0),
 	m_knob_grabdelta(0),
 	m_pic_minus
-		(g_gr->imgcache().load
-		 	(PicMod_UI,
-		 	 horiz ? "pics/scrollbar_left.png"  : "pics/scrollbar_up.png")),
+		(g_gr->images().get(horiz ? "pics/scrollbar_left.png"  : "pics/scrollbar_up.png")),
 	m_pic_plus
-		(g_gr->imgcache().load
-		 	(PicMod_UI,
-		 	 horiz ? "pics/scrollbar_right.png" : "pics/scrollbar_down.png")),
+		(g_gr->images().get(horiz ? "pics/scrollbar_right.png" : "pics/scrollbar_down.png")),
 	m_pic_background
-		(g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_background.png")),
-	m_pic_buttons   (g_gr->imgcache().load(PicMod_UI, "pics/but3.png"))
+		(g_gr->images().get("pics/scrollbar_background.png")),
+	m_pic_buttons   (g_gr->images().get("pics/but3.png"))
 {
 	set_think(true);
 }
@@ -253,15 +249,15 @@
 	dst.tile(r, m_pic_buttons, Point(get_x(), get_y()));
 
 	// Draw the picture
-	const IPicture* pic = NULL;
+	const Image* pic = NULL;
 	if (area == Minus)
 		pic = m_pic_minus;
 	else if (area == Plus)
 		pic = m_pic_plus;
 
 	if (pic) {
-		uint32_t cpw = pic->get_w();
-		uint32_t cph = pic->get_h();
+		uint16_t cpw = pic->width();
+		uint16_t cph = pic->height();
 
 		dst.blit(r + Point((r.w - cpw) / 2, (r.h - cph) / 2), pic);
 	}

=== modified file 'src/ui_basic/scrollbar.h'
--- src/ui_basic/scrollbar.h	2012-11-24 16:22:10 +0000
+++ src/ui_basic/scrollbar.h	2013-02-10 14:53:26 +0000
@@ -97,10 +97,10 @@
 	int32_t   m_time_nextact;
 	int32_t   m_knob_grabdelta; ///< only while m_pressed == Knob
 
-	const IPicture* m_pic_minus;      ///< left/up
-	const IPicture* m_pic_plus;       ///< right/down
-	const IPicture* m_pic_background;
-	const IPicture* m_pic_buttons;
+	const Image* m_pic_minus;      ///< left/up
+	const Image* m_pic_plus;       ///< right/down
+	const Image* m_pic_background;
+	const Image* m_pic_buttons;
 };
 
 }

=== modified file 'src/ui_basic/slider.cc'
--- src/ui_basic/slider.cc	2012-12-02 17:22:14 +0000
+++ src/ui_basic/slider.cc	2013-02-10 14:53:26 +0000
@@ -51,7 +51,7 @@
 	(Panel * const parent,
 	 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
 	 const int32_t min_value, const int32_t max_value, const int32_t value,
-	 const IPicture* background_picture_id,
+	 const Image* background_picture_id,
 	 const std::string & tooltip_text,
 	 const uint32_t cursor_size,
 	 const bool enabled,
@@ -552,7 +552,7 @@
 	 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
 	 const std::vector<std::string> labels_in,
 	 uint32_t m_value,
-	 const IPicture* background_picture_id,
+	 const Image* background_picture_id,
 	 const std::string & tooltip_text,
 	 const uint32_t cursor_size,
 	 const bool enabled)

=== modified file 'src/ui_basic/slider.h'
--- src/ui_basic/slider.h	2012-11-18 17:33:18 +0000
+++ src/ui_basic/slider.h	2013-02-10 14:53:26 +0000
@@ -42,7 +42,7 @@
 		(Panel * parent,
 		 int32_t x, int32_t y, uint32_t w, uint32_t h,
 		 int32_t min_value, int32_t max_value, int32_t value,
-		 const IPicture* background_picture_id,
+		 const Image* background_picture_id,
 		 const std::string & tooltip_text,
 		 uint32_t cursor_size,
 		 bool enabled,
@@ -98,7 +98,7 @@
 	bool m_pressed;           //  the cursor is pressed
 	bool m_enabled;           //  enabled widget
 
-	const IPicture* m_pic_background;    //  background texture (picture ID)
+	const Image* m_pic_background;    //  background texture (picture ID)
 
 protected:
 	int32_t m_x_gap;              //  draw positions
@@ -118,7 +118,7 @@
 		(Panel * const parent,
 		 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
 		 const int32_t min_value, const int32_t max_value, const int32_t value,
-		 const IPicture* background_picture_id,
+		 const Image* background_picture_id,
 		 const std::string & tooltip_text = std::string(),
 		 const uint32_t cursor_size = 20,
 		 const bool enabled = true)
@@ -153,7 +153,7 @@
 		(Panel * const parent,
 		 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
 		 const int32_t min_value, const int32_t max_value, const int32_t value,
-		 const IPicture* background_picture_id,
+		 const Image* background_picture_id,
 		 const uint32_t cursor_size = 20,
 		 const std::string & tooltip_text = std::string(),
 		 const bool enabled = true)
@@ -188,7 +188,7 @@
 		 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
 		 const std::vector<std::string> labels_in,
 		 uint32_t m_value,
-		 const IPicture* background_picture_id,
+		 const Image* background_picture_id,
 		 const std::string & tooltip_text = std::string(),
 		 const uint32_t cursor_size = 20,
 		 const bool enabled = true);

=== modified file 'src/ui_basic/spinbox.cc'
--- src/ui_basic/spinbox.cc	2013-01-04 16:39:48 +0000
+++ src/ui_basic/spinbox.cc	2013-02-10 14:53:26 +0000
@@ -49,7 +49,7 @@
 	std::string unit;
 
 	/// Background tile style of buttons.
-	const IPicture* background;
+	const Image* background;
 
 	/// Alignment of the text. Vertical alignment is always centered.
 	Align align;
@@ -77,7 +77,7 @@
 	 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
 	 int32_t const startval, int32_t const minval, int32_t const maxval,
 	 std::string const &       unit,
-	 const IPicture* background,
+	 const Image* background,
 	 bool                const big,
 	 Align               const alignm)
 	:

=== modified file 'src/ui_basic/spinbox.h'
--- src/ui_basic/spinbox.h	2013-01-04 16:39:48 +0000
+++ src/ui_basic/spinbox.h	2013-02-10 14:53:26 +0000
@@ -20,10 +20,12 @@
 #ifndef UI_SPINBOX_H
 #define UI_SPINBOX_H
 
+#include <cstring>
+
 #include "align.h"
+#include "graphic/graphic.h"
+
 #include "button.h"
-#include "graphic/graphic.h"
-#include <cstring>
 
 namespace UI {
 
@@ -38,8 +40,8 @@
 		 int32_t x, int32_t y, uint32_t w, uint32_t h,
 		 int32_t startval, int32_t minval, int32_t maxval,
 		 std::string const & unit             = std::string(),
-		 const IPicture* buttonbackground =
-		 	g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 const Image* buttonbackground =
+		 	g_gr->images().get("pics/but2.png"),
 		 bool big = false,
 		 Align align = Align_Center);
 	~SpinBox();

=== modified file 'src/ui_basic/table.cc'
--- src/ui_basic/table.cc	2013-01-18 13:23:13 +0000
+++ src/ui_basic/table.cc	2013-02-10 14:53:26 +0000
@@ -21,8 +21,8 @@
 
 #include "graphic/font.h"
 #include "graphic/font_handler.h"
+#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
-#include "graphic/surface.h"
 
 #include "button.h"
 #include "mouse_constants.h"
@@ -99,7 +99,7 @@
 				new Button
 					(this, title,
 					 complete_width, 0, width, m_headerheight,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+					 g_gr->images().get("pics/but3.png"),
 					 title, "", true, false);
 			c.btn->sigclicked.connect
 				(boost::bind(&Table::header_button_clicked, boost::ref(*this), m_columns.size()));
@@ -149,7 +149,7 @@
 			new Button
 				(this, title,
 				 complete_width, 0, column.width, m_headerheight,
-				 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+				 g_gr->images().get("pics/but3.png"),
 				 title, "", true, false);
 		column.btn->sigclicked.connect
 			(boost::bind(&Table::header_button_clicked, boost::ref(*this), col));
@@ -179,9 +179,7 @@
 
 	cell.d_checked = checked;
 	cell.d_picture =
-		g_gr->imgcache().load
-			(PicMod_UI,
-			 checked ? "pics/checkbox_checked.png" : "pics/checkbox_empty.png");
+		g_gr->images().get(checked ? "pics/checkbox_checked.png" : "pics/checkbox_empty.png");
 }
 
 void Table<void *>::Entry_Record::toggle(uint8_t const col)
@@ -273,15 +271,15 @@
 			uint32_t const curw      = column.width;
 			Align    const alignment = column.alignment;
 
-			const IPicture* entry_picture = er.get_picture(i);
+			const Image* entry_picture = er.get_picture(i);
 			std::string const &       entry_string  = er.get_string (i);
 			uint32_t picw = 0;
 			uint32_t pich = 0;
 			uint32_t stringw = 0;
 			uint32_t stringh = g_fh->get_fontheight(m_fontname, m_fontsize);
 			if (entry_picture) {
-				picw = entry_picture->get_w();
-				pich = entry_picture->get_h();
+				picw = entry_picture->width();
+				pich = entry_picture->height();
 			}
 			Point point =
 				Point(curx, y)
@@ -467,7 +465,7 @@
 		 i; ++i)
 		if (m_columns.at(i.current).is_checkbox_column) {
 			result.m_data.at(i.current).d_picture =
-				g_gr->imgcache().load(PicMod_UI, "pics/checkbox_empty.png");
+				g_gr->images().get("pics/checkbox_empty.png");
 		}
 
 	m_scrollbar->set_steps
@@ -588,7 +586,7 @@
 {}
 
 void Table<void *>::Entry_Record::set_picture
-	(uint8_t const col, const IPicture* pic, std::string const & str)
+	(uint8_t const col, const Image* pic, std::string const & str)
 {
 	assert(col < m_data.size());
 
@@ -603,7 +601,7 @@
 	m_data.at(col).d_picture = NULL;
 	m_data.at(col).d_string  = str;
 }
-const IPicture* Table<void *>::Entry_Record::get_picture(uint8_t const col) const
+const Image* Table<void *>::Entry_Record::get_picture(uint8_t const col) const
 {
 	assert(col < m_data.size());
 

=== modified file 'src/ui_basic/table.h'
--- src/ui_basic/table.h	2013-01-18 13:23:13 +0000
+++ src/ui_basic/table.h	2013-02-10 14:53:26 +0000
@@ -21,16 +21,19 @@
 #ifndef UI_TABLE_H
 #define UI_TABLE_H
 
-#include "align.h"
-#include "panel.h"
-
-#include "compile_assert.h"
-
 #include <limits>
 #include <vector>
+
 #include <boost/function.hpp>
 #include <boost/signal.hpp>
 
+#include "align.h"
+#include "compile_assert.h"
+#include "rgbcolor.h"
+
+#include "panel.h"
+
+
 namespace UI {
 struct Scrollbar;
 struct Button;
@@ -114,9 +117,9 @@
 		Entry_Record(void * entry);
 
 		void set_picture
-			(uint8_t col, const IPicture* pic, std::string const & = std::string());
+			(uint8_t col, const Image* pic, std::string const & = std::string());
 		void set_string(uint8_t col, std::string const &);
-		const IPicture* get_picture(uint8_t col) const;
+		const Image* get_picture(uint8_t col) const;
 		std::string const & get_string(uint8_t col) const;
 		void * entry() const throw () {return m_entry;}
 		void set_color(const  RGBColor c) {
@@ -137,7 +140,7 @@
 		bool     use_clr;
 		RGBColor clr;
 		struct _data {
-			const IPicture* d_picture;
+			const Image* d_picture;
 			std::string d_string;
 			bool d_checked;
 

=== modified file 'src/ui_basic/tabpanel.cc'
--- src/ui_basic/tabpanel.cc	2013-01-08 21:39:43 +0000
+++ src/ui_basic/tabpanel.cc	2013-02-10 14:53:26 +0000
@@ -21,7 +21,6 @@
 
 #include "mouse_constants.h"
 
-#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 
 #include "compile_assert.h"
@@ -42,7 +41,7 @@
 	(Tab_Panel         * const parent,
 	 uint32_t            const id,
 	 std::string const &       name,
-	 const IPicture* gpic,
+	 const Image* gpic,
 	 std::string const &       gtooltip,
 	 Panel             * const gpanel)
 	:
@@ -78,7 +77,7 @@
 Tab_Panel::Tab_Panel
 	(Panel * const parent,
 	 int32_t const x, int32_t const y,
-	 const IPicture* background)
+	 const Image* background)
 	:
 	Panel            (parent, x, y, 0, 0),
 	m_active         (0),
@@ -88,7 +87,7 @@
 Tab_Panel::Tab_Panel
 	(Panel * const parent,
 	 int32_t const x, int32_t const y, int32_t const w, int32_t const h,
-	 const IPicture* background)
+	 const Image* background)
 	:
 	Panel            (parent, x, y, w, h),
 	m_active         (0),
@@ -150,7 +149,7 @@
 */
 uint32_t Tab_Panel::add
 	(std::string const & name,
-	 const IPicture* pic,
+	 const Image* pic,
 	 Panel             * const panel,
 	 std::string const &       tooltip_text)
 {
@@ -231,8 +230,8 @@
 
 		// Draw the icon
 		assert(m_tabs[idx]->pic);
-		uint32_t cpw = m_tabs[idx]->pic->get_w();
-		uint32_t cph = m_tabs[idx]->pic->get_h();
+		uint16_t cpw = m_tabs[idx]->pic->width();
+		uint16_t cph = m_tabs[idx]->pic->height();
 		dst.blit
 			(Point(x + (TP_BUTTON_WIDTH - cpw) / 2, (TP_BUTTON_HEIGHT - cph) / 2),
 			 m_tabs[idx]->pic);

=== modified file 'src/ui_basic/tabpanel.h'
--- src/ui_basic/tabpanel.h	2012-12-14 20:09:35 +0000
+++ src/ui_basic/tabpanel.h	2013-02-10 14:53:26 +0000
@@ -39,7 +39,7 @@
 		(Tab_Panel * parent,
 		 uint32_t,
 		 std::string const & name,
-		 const IPicture*,
+		 const Image*,
 		 std::string const & gtooltip,
 		 Panel             * gpanel);
 
@@ -50,7 +50,7 @@
 	Tab_Panel * m_parent;
 	uint32_t    m_id;
 
-	const IPicture* pic;
+	const Image* pic;
 	std::string tooltip;
 	Panel     * panel;
 };
@@ -68,16 +68,16 @@
 struct Tab_Panel : public Panel {
 	friend struct Tab;
 
-	Tab_Panel(Panel * parent, int32_t x, int32_t y, const IPicture* background);
+	Tab_Panel(Panel * parent, int32_t x, int32_t y, const Image* background);
 	// For Fullscreen menus
 	Tab_Panel
 		(Panel * parent,
 		 int32_t x, int32_t y, int32_t w, int32_t h,
-		 const IPicture* background);
+		 const Image* background);
 
 	uint32_t add
 		(std::string const & name,
-		 const IPicture* pic,
+		 const Image* pic,
 		 Panel             * panel,
 		 std::string const & tooltip = std::string());
 
@@ -107,7 +107,7 @@
 	uint32_t         m_active;         ///< index of the currently active tab
 	int32_t          m_highlight;      ///< index of the highlighted button
 
-	const IPicture* m_pic_background; ///< picture used to draw background
+	const Image* m_pic_background; ///< picture used to draw background
 };
 };
 

=== modified file 'src/ui_basic/textarea.cc'
--- src/ui_basic/textarea.cc	2012-06-08 22:33:16 +0000
+++ src/ui_basic/textarea.cc	2013-02-10 14:53:26 +0000
@@ -210,7 +210,7 @@
 	int32_t x = get_x();
 	int32_t y = get_y();
 	uint32_t w = m_textstyle.calc_bare_width(m_text);
-	uint32_t h = m_textstyle.font->height();
+	uint16_t h = m_textstyle.font->height();
 
 	if      (m_align & Align_HCenter)
 		x -= w >> 1;
@@ -232,7 +232,7 @@
 void Textarea::update_desired_size()
 {
 	uint32_t w = m_textstyle.calc_bare_width(m_text);
-	uint32_t h = m_textstyle.font->height();
+	uint16_t h = m_textstyle.font->height();
 
 	set_desired_size(w, h);
 }
@@ -244,7 +244,7 @@
 void Textarea::set_fixed_size(const std::string & /* text */)
 {
 	uint32_t w = m_textstyle.calc_bare_width(m_text);
-	uint32_t h = m_textstyle.font->height();
+	uint16_t h = m_textstyle.font->height();
 	set_size(w, h);
 	set_desired_size(w, h);
 }

=== modified file 'src/ui_basic/textarea.h'
--- src/ui_basic/textarea.h	2012-02-15 21:25:34 +0000
+++ src/ui_basic/textarea.h	2013-02-10 14:53:26 +0000
@@ -23,6 +23,7 @@
 #include "align.h"
 #include "constants.h"
 #include "graphic/font.h"
+
 #include "panel.h"
 
 namespace UI {

=== modified file 'src/ui_basic/window.cc'
--- src/ui_basic/window.cc	2012-12-17 20:01:04 +0000
+++ src/ui_basic/window.cc	2013-02-10 14:53:26 +0000
@@ -22,6 +22,7 @@
 #include "constants.h"
 #include "graphic/font.h"
 #include "graphic/font_handler1.h"
+#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "log.h"
 #include "text_layout.h"
@@ -86,15 +87,15 @@
 		_drag_start_win_x(0), _drag_start_win_y(0),
 		_drag_start_mouse_x(0), _drag_start_mouse_y(0),
 		m_pic_lborder
-			(g_gr->imgcache().load(PicMod_UI, "pics/win_l_border.png")),
+			(g_gr->images().get("pics/win_l_border.png")),
 		m_pic_rborder
-			(g_gr->imgcache().load(PicMod_UI, "pics/win_r_border.png")),
+			(g_gr->images().get("pics/win_r_border.png")),
 		m_pic_top
-			(g_gr->imgcache().load(PicMod_UI, "pics/win_top.png")),
+			(g_gr->images().get("pics/win_top.png")),
 		m_pic_bottom
-			(g_gr->imgcache().load(PicMod_UI, "pics/win_bot.png")),
+			(g_gr->images().get("pics/win_bot.png")),
 		m_pic_background
-			(g_gr->imgcache().load(PicMod_UI, "pics/win_bg.png")),
+			(g_gr->images().get("pics/win_bg.png")),
 		m_center_panel(0),
 		m_fastclick_panel(0)
 {
@@ -319,11 +320,13 @@
 	}
 
 	// draw the title if we have one
-	if (!m_title.empty())
-		UI::g_fh1->draw_text
-			(dst,
-			 Point(get_lborder() + get_inner_w() / 2, TP_B_PIXMAP_THICKNESS / 2),
-			 m_title, 0, Align_Center);
+	if (!m_title.empty()) {
+		dst.blit
+			(Point(get_lborder() + get_inner_w() / 2, TP_B_PIXMAP_THICKNESS / 2),
+				UI::g_fh1->render(m_title),
+				CM_Normal,
+				Align_Center);
+	}
 
 	if (not _is_minimal) {
 		const int32_t vt_bar_end = get_h() -
@@ -527,9 +530,9 @@
 			const int32_t max_x = parent->get_inner_w();
 			const int32_t max_y = parent->get_inner_h();
 
-			left = min(static_cast<int32_t>(max_x - get_lborder()), left);
-			top  = min(static_cast<int32_t>(max_y - get_tborder()), top);
-			left = max(-static_cast<int32_t>(w - get_rborder()), left);
+			left = min<int32_t>(max_x - get_lborder(), left);
+			top  = min<int32_t>(max_y - get_tborder(), top);
+			left = max<int32_t>(get_rborder() - w, left);
 			top  = max
 				(-static_cast<int32_t>(h - ((_is_minimal) ? get_tborder() : get_bborder())), top);
 			new_left = left; new_top = top;

=== modified file 'src/ui_basic/window.h'
--- src/ui_basic/window.h	2013-01-17 21:44:05 +0000
+++ src/ui_basic/window.h	2013-02-10 14:53:26 +0000
@@ -101,11 +101,11 @@
 
 	std::string m_title;
 
-	const IPicture* m_pic_lborder;
-	const IPicture* m_pic_rborder;
-	const IPicture* m_pic_top;
-	const IPicture* m_pic_bottom;
-	const IPicture* m_pic_background;
+	const Image* m_pic_lborder;
+	const Image* m_pic_rborder;
+	const Image* m_pic_top;
+	const Image* m_pic_bottom;
+	const Image* m_pic_background;
 
 	Panel * m_center_panel;
 	Panel * m_fastclick_panel;

=== modified file 'src/ui_fsmenu/base.cc'
--- src/ui_fsmenu/base.cc	2013-01-08 08:29:36 +0000
+++ src/ui_fsmenu/base.cc	2013-02-10 14:53:26 +0000
@@ -20,14 +20,15 @@
 #include "base.h"
 
 #include "constants.h"
-#include "io/filesystem/filesystem.h"
 #include "graphic/font.h"
 #include "graphic/graphic.h"
+#include "graphic/image_transformations.h"
+#include "graphic/rendertarget.h"
+#include "io/filesystem/filesystem.h"
 #include "log.h"
 #include "profile/profile.h"
-#include "graphic/rendertarget.h"
+#include "wexception.h"
 #include "wlapplication.h"
-#include "wexception.h"
 
 #include <cstdio>
 
@@ -40,7 +41,7 @@
 */
 
 struct Fullscreen_Menu_Base::Data {
-	const IPicture* res_background;
+	const Image* res_background;
 	UI::TextStyle textstyle_small;
 	UI::TextStyle textstyle_big;
 };
@@ -57,13 +58,7 @@
 	// Load background graphics
 	char buffer[256];
 	snprintf(buffer, sizeof(buffer), "pics/%s", bgpic);
-	const IPicture* background = g_gr->imgcache().load(PicMod_Menu, buffer, false);
-	if (!background)
-		throw wexception
-			("could not open splash screen; make sure that all data files are "
-			 "installed");
-
-	d->res_background = g_gr->get_resized_picture(background, get_w(), get_h());
+	d->res_background = ImageTransformations::resize(g_gr->images().get(buffer), get_w(), get_h());
 
 	d->textstyle_small = UI::TextStyle::ui_small();
 	d->textstyle_small.font = UI::Font::get(ui_fn(), fs_small());

=== modified file 'src/ui_fsmenu/campaign_select.cc'
--- src/ui_fsmenu/campaign_select.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/campaign_select.cc	2013-02-10 14:53:26 +0000
@@ -69,12 +69,12 @@
 	b_ok
 		(this, "ok",
 		 get_w() * 71 / 100, get_h() * 9 / 10, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("OK"), std::string(), false, false),
 	back
 		(this, "back",
 		 get_w() * 71 / 100, get_h() * 17 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 
 // Campaign list
@@ -225,7 +225,7 @@
 			m_list.add
 				(s.get_string(cname, _("[No value found]")),
 				 s.get_string(csection),
-				 g_gr->imgcache().load(PicMod_Game, dif_picture_filenames[dif]));
+				 g_gr->images().get(dif_picture_filenames[dif]));
 
 		}
 
@@ -276,12 +276,12 @@
 	b_ok
 		(this, "ok",
 		 get_w() * 71 / 100, get_h() * 9 / 10, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("OK"), std::string(), false, false),
 	back
 		(this, "back",
 		 get_w() * 71 / 100, get_h() * 17 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 
 // Campaign map list
@@ -418,7 +418,7 @@
 			m_list.add
 				(s->get_string("name", _("[No value found]")),
 				 s->get_string("path"),
-				 g_gr->imgcache().load(PicMod_Game, "pics/ls_wlmap.png"));
+				 g_gr->images().get("pics/ls_wlmap.png"));
 		}
 
 		++i;

=== modified file 'src/ui_fsmenu/editor.cc'
--- src/ui_fsmenu/editor.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/editor.cc	2013-02-10 14:53:26 +0000
@@ -20,6 +20,7 @@
 #include "editor.h"
 
 #include "constants.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
 
 Fullscreen_Menu_Editor::Fullscreen_Menu_Editor() :
@@ -38,17 +39,17 @@
 	new_map
 		(this, "new_map",
 		 m_butx, get_h() * 6 / 25, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("New Map"), std::string(), true, false),
 	load_map
 		(this, "load_map",
 		 m_butx, get_h() * 61 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Load Map"), std::string(), true, false),
 	back
 		(this, "back",
 		 m_butx, get_h() * 3 / 4, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false)
 {
 	new_map.sigclicked.connect

=== modified file 'src/ui_fsmenu/editor_mapselect.cc'
--- src/ui_fsmenu/editor_mapselect.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/editor_mapselect.cc	2013-02-10 14:53:26 +0000
@@ -86,12 +86,12 @@
 	m_back
 		(this, "back",
 		 get_w() * 71 / 100, get_h() * 17 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 	m_ok
 		(this, "ok",
 		 get_w() * 71 / 100, get_h() * 9 / 10, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("OK"), std::string(), false, false),
 
 // Map list
@@ -228,7 +228,7 @@
 		m_list.add
 			(_("<parent>"),
 			 m_parentdir.c_str(),
-			 g_gr->imgcache().load(PicMod_Game, "pics/ls_dir.png"));
+			 g_gr->images().get("pics/ls_dir.png"));
 	}
 
 	const filenameset_t::const_iterator mapfiles_end = m_mapfiles.end();
@@ -248,7 +248,7 @@
 		m_list.add
 			(FileSystem::FS_Filename(name),
 			 name,
-			 g_gr->imgcache().load(PicMod_Game, "pics/ls_dir.png"));
+			 g_gr->images().get("pics/ls_dir.png"));
 	}
 
 	Widelands::Map map;
@@ -266,10 +266,8 @@
 				m_list.add
 					(FileSystem::FS_Filename(name),
 					 name,
-					 g_gr->imgcache().load
-					 	(PicMod_Game,
-					 	 dynamic_cast<WL_Map_Loader const *>(m_ml) ?
-					 	 "pics/ls_wlmap.png" : "pics/ls_s2map.png"));
+					 g_gr->images().get
+						 (dynamic_cast<WL_Map_Loader const *>(m_ml) ? "pics/ls_wlmap.png" : "pics/ls_s2map.png"));
 			} catch (_wexception const &) {} //  we simply skip illegal entries
 			delete m_ml;
 		}

=== modified file 'src/ui_fsmenu/fileview.cc'
--- src/ui_fsmenu/fileview.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/fileview.cc	2013-02-10 14:53:26 +0000
@@ -20,8 +20,9 @@
 #include "fileview.h"
 
 #include "constants.h"
+#include "graphic/graphic.h"
+#include "i18n.h"
 #include "io/filesystem/filesystem.h"
-#include "i18n.h"
 #include "profile/profile.h"
 
 
@@ -40,7 +41,7 @@
 	close_button
 		(this, "close",
 		 get_w() * 3 / 8, get_h() * 9 / 10, get_w() / 4, get_h() * 9 / 200,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Close"), std::string(), true, false)
 {
 	close_button.sigclicked.connect(boost::bind(&Fullscreen_Menu_TextView::end_modal, boost::ref(*this), 0));

=== modified file 'src/ui_fsmenu/internet_lobby.cc'
--- src/ui_fsmenu/internet_lobby.cc	2013-01-05 23:08:45 +0000
+++ src/ui_fsmenu/internet_lobby.cc	2013-02-10 14:53:26 +0000
@@ -77,23 +77,23 @@
 	joingame
 		(this, "join_game",
 		 get_w() * 17 / 25, get_h() * 55 / 100, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Join this game"), std::string(), false, false),
 	hostgame
 		(this, "host_game",
 		 get_w() * 17 / 25, get_h() * 81 / 100, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Open a new game"), std::string(), true, false),
 	back
 		(this, "back",
 		 get_w() * 17 / 25, get_h() * 90 / 100, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 
 // Edit boxes
 	servername
 		(this, get_w() * 17 / 25, get_h() * 68 / 100, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png")),
+		 g_gr->images().get("pics/but2.png")),
 
 // List
 	clientsonline
@@ -220,15 +220,15 @@
 	joingame.set_enabled(false);
 	std::string localservername = servername.text();
 	for (uint32_t i = 0; i < games.size(); ++i) {
-		const IPicture* pic;
+		const Image* pic;
 		if (games.at(i).connectable) {
 			if (games.at(i).build_id == build_id())
-				pic = g_gr->imgcache().load(PicMod_UI, "pics/continue.png");
+				pic = g_gr->images().get("pics/continue.png");
 			else {
-				pic = g_gr->imgcache().load(PicMod_UI, "pics/different.png");
+				pic = g_gr->images().get("pics/different.png");
 			}
 		} else {
-			pic = g_gr->imgcache().load(PicMod_UI, "pics/stop.png");
+			pic = g_gr->images().get("pics/stop.png");
 		}
 		// If one of the servers has the same name as the local name of the
 		// clients server, we disable the 'hostgame' button to avoid having more
@@ -275,19 +275,19 @@
 		er.set_string(2, client.points);
 		er.set_string(3, client.game);
 
-		const IPicture* pic;
+		const Image* pic;
 		switch (convert_clienttype(client.type)) {
 			case 0: // UNREGISTERED
-				pic = g_gr->imgcache().load(PicMod_UI, "pics/roadb_red.png");
+				pic = g_gr->images().get("pics/roadb_red.png");
 				er.set_picture(0, pic);
 				break;
 			case 1: // REGISTERED
-				pic = g_gr->imgcache().load(PicMod_UI, "pics/roadb_yellow.png");
+				pic = g_gr->images().get("pics/roadb_yellow.png");
 				er.set_picture(0, pic);
 				break;
 			case 2: // SUPERUSER
 			case 3: // BOT
-				pic = g_gr->imgcache().load(PicMod_UI, "pics/roadb_green.png");
+				pic = g_gr->images().get("pics/roadb_green.png");
 				er.set_color(RGBColor(0, 255, 0));
 				er.set_picture(0, pic);
 				break;

=== modified file 'src/ui_fsmenu/launchMPG.cc'
--- src/ui_fsmenu/launchMPG.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/launchMPG.cc	2013-02-10 14:53:26 +0000
@@ -61,7 +61,7 @@
 		UI::Button * btn = new UI::Button
 			(this, "map",
 			 space, y, butw, buth,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+			 g_gr->images().get("pics/but0.png"),
 			 _("Map"), _("Select a map"), true, false);
 		btn->sigclicked.connect
 			(boost::bind
@@ -71,7 +71,7 @@
 		btn = new UI::Button
 			(this, "saved_game",
 			 2 * space + butw, y, butw, buth,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+			 g_gr->images().get("pics/but0.png"),
 			 _("Saved game"), _("Select a saved game"), true, false);
 		btn->sigclicked.connect
 			(boost::bind
@@ -81,7 +81,7 @@
 		btn = new UI::Button
 			(this, "cancel",
 			 3 * space + 2 * butw, y, butw, buth,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+			 g_gr->images().get("pics/but1.png"),
 			 _("Cancel"), _("Cancel selection"), true, false);
 		btn->sigclicked.connect
 			(boost::bind
@@ -117,29 +117,29 @@
 	m_change_map_or_save
 		(this, "change_map_or_save",
 		 get_w() * 37 / 50 + m_butw - m_buth, get_h() * 3 / 20, m_buth, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/menu_toggle_minimap.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/menu_toggle_minimap.png"),
 		 _("Change map or saved game"), false, false),
 	m_ok
 		(this, "ok",
 		 get_w() * 37 / 50, get_h() * 12 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("Start game"), std::string(), false, false),
 	m_back
 		(this, "back",
 		 get_w() * 37 / 50, get_h() * 218 / 240, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 	m_wincondition
 		(this, "win_condition",
 		 get_w() * 37 / 50, get_h() * 11 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 "", std::string(), false, false),
 	m_help_button
 		(this, "help",
 		 get_w() * 37 / 50 + m_butw - m_buth, get_h() / 100, m_buth, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/menu_help.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/menu_help.png"),
 		 _("Show the help window"), true, false),
 
 // Text labels

=== modified file 'src/ui_fsmenu/launchSPG.cc'
--- src/ui_fsmenu/launchSPG.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/launchSPG.cc	2013-02-10 14:53:26 +0000
@@ -51,22 +51,22 @@
 	m_select_map
 		(this, "select_map",
 		 get_w() * 7 / 10, get_h() * 3 / 10, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Select map"), std::string(), false, false),
 	m_wincondition
 		(this, "win_condition",
 		 get_w() * 7 / 10, get_h() * 4 / 10, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 "", std::string(), false, false),
 	m_back
 		(this, "back",
 		 get_w() * 7 / 10, get_h() * 9 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 	m_ok
 		(this, "ok",
 		 get_w() * 7 / 10, get_h() * 1 / 2, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("Start game"), std::string(), false, false),
 
 // Text labels
@@ -155,8 +155,8 @@
 			new UI::Button
 				(this, "switch_to_position",
 				 get_w() / 100, y += m_buth, get_h() * 17 / 500, get_h() * 17 / 500,
-				 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-				 g_gr->imgcache().load(PicMod_Game, posIco),
+				 g_gr->images().get("pics/but1.png"),
+				 g_gr->images().get(posIco),
 				 _("Switch to position"), false);
 		m_pos[i]->sigclicked.connect
 			(boost::bind(&Fullscreen_Menu_LaunchSPG::switch_to_position, boost::ref(*this), i));

=== modified file 'src/ui_fsmenu/loadgame.cc'
--- src/ui_fsmenu/loadgame.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/loadgame.cc	2013-02-10 14:53:26 +0000
@@ -49,17 +49,17 @@
 	m_back
 		(this, "back",
 		 get_w() * 71 / 100, get_h() * 9 / 10, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 	m_ok
 		(this, "ok",
 		 get_w() * 71 / 100, get_h() * 15 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("OK"), std::string(), false, false),
 	m_delete
 		(this, "delete",
 		 get_w() * 71 / 100, get_h() * 17 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Delete"), std::string(), false, false),
 
 // Savegame list

=== modified file 'src/ui_fsmenu/loadreplay.cc'
--- src/ui_fsmenu/loadreplay.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/loadreplay.cc	2013-02-10 14:53:26 +0000
@@ -19,12 +19,13 @@
 
 #include "loadreplay.h"
 
-#include "logic/game.h"
 #include "game_io/game_loader.h"
 #include "game_io/game_preload_data_packet.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
 #include "io/filesystem/layered_filesystem.h"
 #include "log.h"
+#include "logic/game.h"
 #include "logic/replay.h"
 #include "ui_basic/messagebox.h"
 
@@ -39,17 +40,17 @@
 	m_back
 		(this, "back",
 		 get_w() * 71 / 100, get_h() * 9 / 10, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 	m_ok
 		(this, "ok",
 		 get_w() * 71 / 100, get_h() * 15 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("OK"), std::string(), false, false),
 	m_delete
 		(this, "delete",
 		 get_w() * 71 / 100, get_h() * 17 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Delete"), std::string(), false, false),
 
 // Replay list

=== modified file 'src/ui_fsmenu/main.cc'
--- src/ui_fsmenu/main.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/main.cc	2013-02-10 14:53:26 +0000
@@ -17,11 +17,12 @@
  *
  */
 
-#include "main.h"
-
 #include "build_info.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
 
+#include "main.h"
+
 Fullscreen_Menu_Main::Fullscreen_Menu_Main() :
 	Fullscreen_Menu_Base("mainmenu.jpg"),
 
@@ -35,47 +36,47 @@
 	playtutorial
 		(this, "play_tutorial",
 		 m_butx, get_h() * 42 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("Play Tutorial"), std::string(), true, false),
 	singleplayer
 		(this, "single_player",
 		 m_butx, get_h() * 61 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("Single Player"), std::string(), true, false),
 	multiplayer
 		(this, "multi_player",
 		 m_butx, get_h() * 37 / 100, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("Multi Player"), std::string(), true, false),
 	replay
 		(this, "replay",
 		 m_butx, get_h() * 87 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("Watch Replay"), std::string(), true, false),
 	editor
 		(this, "editor",
 		 m_butx, get_h() * 100 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("Editor"), std::string(), true, false),
 	options
 		(this, "options",
 		 m_butx, get_h() * 119 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("Options"), std::string(), true, false),
 	readme
 		(this, "readme",
 		 m_butx, get_h() * 138 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("View Readme"), std::string(), true, false),
 	license
 		(this, "license",
 		 m_butx, get_h() * 151 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("License"), std::string(), true, false),
 	exit
 		(this, "exit",
 		 m_butx, get_h() * 178 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but3.png"),
+		 g_gr->images().get("pics/but3.png"),
 		 _("Exit Game"), std::string(), true, false),
 
 // Textlabels

=== modified file 'src/ui_fsmenu/mapselect.cc'
--- src/ui_fsmenu/mapselect.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/mapselect.cc	2013-02-10 14:53:26 +0000
@@ -101,12 +101,12 @@
 	m_back
 		(this, "back",
 		 get_w() * 71 / 100, get_h() * 17 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 	m_ok
 		(this, "ok",
 		 get_w() * 71 / 100, get_h() * 9 / 10, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("OK"), std::string(), false, false),
 
 // Checkbox
@@ -341,7 +341,7 @@
 
 			te.set_string(0, "");
 			te.set_picture
-				(1,  g_gr->imgcache().load(PicMod_Game, "pics/ls_dir.png"),
+				(1,  g_gr->images().get("pics/ls_dir.png"),
 				_("<parent>"));
 
 			++ndirs;
@@ -372,7 +372,7 @@
 
 			te.set_string(0, "");
 			te.set_picture
-				(1,  g_gr->imgcache().load(PicMod_Game, "pics/ls_dir.png"),
+				(1,  g_gr->images().get("pics/ls_dir.png"),
 				FileSystem::FS_Filename(name));
 
 			++ndirs;
@@ -428,11 +428,9 @@
 					te.set_string(0, buf);
 					i18n::Textdomain td("maps");
 					te.set_picture
-						(1,  g_gr->imgcache().load
-						(PicMod_Game,
-						dynamic_cast<WL_Map_Loader const *>(ml) ?
-						(mapdata.scenario ? "pics/ls_wlscenario.png" : "pics/ls_wlmap.png")
-						:
+						(1,  g_gr->images().get
+						 (dynamic_cast<WL_Map_Loader const *>(ml) ?
+							  (mapdata.scenario ? "pics/ls_wlscenario.png" : "pics/ls_wlmap.png") :
 						"pics/ls_s2map.png"),
 						_(mapdata.name));
 				} catch (const std::exception & e) {
@@ -489,8 +487,7 @@
 				sprintf(buf, "(%i)", mapdata.nrplayers);
 				te.set_string(0, buf);
 				te.set_picture
-					(1, g_gr->imgcache().load
-						(PicMod_Game, (mapdata.scenario ? "pics/ls_wlscenario.png" : "pics/ls_wlmap.png")),
+					(1, g_gr->images().get((mapdata.scenario ? "pics/ls_wlscenario.png" : "pics/ls_wlmap.png")),
 					 mapdata.name.c_str());
 
 			} catch (...) {
@@ -517,9 +514,8 @@
 				sprintf(buf, "(%i)", mapdata.nrplayers);
 				te.set_string(0, buf);
 				te.set_picture
-					(1, g_gr->imgcache().load
-						(PicMod_Game, (mapdata.scenario ? "pics/ls_wlscenario.png" : "pics/ls_wlmap.png")),
-					 mapdata.name.c_str());
+					(1, g_gr->images().get
+					 ((mapdata.scenario ? "pics/ls_wlscenario.png" : "pics/ls_wlmap.png")), mapdata.name.c_str());
 			}
 
 			delete ml;

=== modified file 'src/ui_fsmenu/multiplayer.cc'
--- src/ui_fsmenu/multiplayer.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/multiplayer.cc	2013-02-10 14:53:26 +0000
@@ -44,17 +44,17 @@
 	metaserver
 		(this, "metaserver",
 		 m_butx, get_h() * 6 / 25, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Internet game"), std::string(), true, false),
 	lan
 		(this, "lan",
 		 m_butx, get_h() * 61 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("LAN / Direct IP"), std::string(), true, false),
 	back
 		(this, "back",
 		 m_butx, get_h() * 3 / 4, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false)
 {
 	metaserver.sigclicked.connect(boost::bind(&Fullscreen_Menu_MultiPlayer::internetLogin, boost::ref(*this)));
@@ -79,8 +79,8 @@
 			new UI::Button
 				(this, "login_dialog",
 				 m_butx + m_butw + m_buth / 4, get_h() * 6 / 25, m_buth, m_buth,
-				 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-				 g_gr->imgcache().load(PicMod_UI, "pics/continue.png"),
+				 g_gr->images().get("pics/but1.png"),
+				 g_gr->images().get("pics/continue.png"),
 				 _("Show login dialog"), true, false);
 		showloginbox->sigclicked.connect
 			(boost::bind

=== modified file 'src/ui_fsmenu/netsetup_lan.cc'
--- src/ui_fsmenu/netsetup_lan.cc	2013-01-05 23:08:45 +0000
+++ src/ui_fsmenu/netsetup_lan.cc	2013-02-10 14:53:26 +0000
@@ -57,32 +57,32 @@
 	joingame
 		(this, "join_game",
 		 get_w() * 16 / 25, get_h() * 5333 / 10000, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Join this game"), std::string(), true, false),
 	hostgame
 		(this, "host_game",
 		 get_w() * 16 / 25, get_h() * 6083 / 10000, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Host a new game"), std::string(), true, false),
 	back
 		(this, "back",
 		 get_w() * 16 / 25, get_h() * 8333 / 10000, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false),
 	loadlasthost
 		(this, "load_previous_host",
 		 get_w() * 171 / 200, get_h() * 19 / 40, m_buth, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/menu_load_game.png"),
+		 g_gr->images().get("pics/but1.png"),
+		 g_gr->images().get("pics/menu_load_game.png"),
 		 _("Load previous host"), true, false),
 
 // Edit boxes
 	playername
 		(this, get_w() * 16 / 25, get_h() * 3333 / 10000, m_butw,       m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png")),
+		 g_gr->images().get("pics/but2.png")),
 	hostname
 		(this, get_w() * 16 / 25, get_h() * 19 / 40,  get_w() * 17 / 80, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png")),
+		 g_gr->images().get("pics/but2.png")),
 
 // List
 	opengames

=== modified file 'src/ui_fsmenu/options.cc'
--- src/ui_fsmenu/options.cc	2013-01-07 20:36:46 +0000
+++ src/ui_fsmenu/options.cc	2013-02-10 14:53:26 +0000
@@ -47,17 +47,17 @@
 	m_advanced_options
 		(this, "advanced_options",
 		 get_w() * 9 / 80, get_h() * 19 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("Advanced Options"), std::string(), true, false),
 	m_cancel
 		(this, "cancel",
 		 get_w() * 51 / 80, get_h() * 19 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Cancel"), std::string(), true, false),
 	m_apply
 		(this, "apply",
 		 get_w() * 3 / 8, get_h() * 19 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("Apply"), std::string(), true, false),
 
 // Spinboxes
@@ -65,18 +65,18 @@
 		(this,
 		 (get_w() / 2) - (m_vbutw * 2), get_h() * 3833 / 10000, get_w() / 5, m_vbutw,
 		 opt.maxfps, 0, 100, "",
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+		 g_gr->images().get("pics/but1.png")),
 	m_sb_autosave
 		(this,
 		 get_w() * 6767 / 10000, get_h() * 8167 / 10000, get_w() / 4, m_vbutw,
 		 opt.autosave / 60, 0, 100, _("min."),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"), true),
+		 g_gr->images().get("pics/but1.png"), true),
 
 	m_sb_remove_replays
 		(this,
 		 get_w() * 6767 / 10000, get_h() * 8631 / 10000, get_w() / 4, m_vbutw,
 		 opt.remove_replays, 0, 365, _("days"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"), true),
+		 g_gr->images().get("pics/but1.png"), true),
 
 // Title
 	m_title
@@ -418,12 +418,12 @@
 	m_cancel
 		(this, "cancel",
 		 get_w() * 41 / 80, get_h() * 19 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Cancel"), std::string(), true, false),
 	m_apply
 		(this, "apply",
 		 get_w() / 4,   get_h() * 19 / 20, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+		 g_gr->images().get("pics/but2.png"),
 		 _("Apply"), std::string(), true, false),
 
 // Spinboxes
@@ -431,17 +431,17 @@
 		(this,
 		 get_w() * 18 / 25, get_h() * 63 / 100, get_w() / 4, m_vbutw,
 		 opt.speed_of_new_game / 1000, 0, 100, _("x"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+		 g_gr->images().get("pics/but1.png")),
 	m_sb_dis_panel
 		(this,
 		 get_w() * 18 / 25, get_h() * 6768 / 10000, get_w() / 4, m_vbutw,
 		 opt.panel_snap_distance, 0, 100, _("px."),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+		 g_gr->images().get("pics/but1.png")),
 	m_sb_dis_border
 		(this,
 		 get_w() * 18 / 25, get_h() * 7235 / 10000, get_w() / 4, m_vbutw,
 		 opt.border_snap_distance, 0, 100, _("px."),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+		 g_gr->images().get("pics/but1.png")),
 
 
 // Title

=== modified file 'src/ui_fsmenu/singleplayer.cc'
--- src/ui_fsmenu/singleplayer.cc	2012-12-13 10:41:22 +0000
+++ src/ui_fsmenu/singleplayer.cc	2013-02-10 14:53:26 +0000
@@ -20,6 +20,7 @@
 #include "singleplayer.h"
 
 #include "constants.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
 
 Fullscreen_Menu_SinglePlayer::Fullscreen_Menu_SinglePlayer() :
@@ -42,22 +43,22 @@
 	new_game
 		(this, "new_game",
 		 m_butx, get_h() * 6 / 25, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("New Game"), std::string(), true, false),
 	campaign
 		(this, "campaigns",
 		 m_butx, get_h() * 61 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Campaigns"), std::string(), true, false),
 	load_game
 		(this, "load_game",
 		 m_butx, get_h() * 87 / 200, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Load Game"), std::string(), true, false),
 	back
 		(this, "back",
 		 m_butx, get_h() * 3 / 4, m_butw, m_buth,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Back"), std::string(), true, false)
 {
 	new_game.sigclicked.connect

=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc	2013-01-06 22:07:04 +0000
+++ src/wlapplication.cc	2013-02-10 14:53:26 +0000
@@ -309,7 +309,7 @@
 		throw wexception("SDLNet_Init failed: %s\n", SDLNet_GetError());
 
 	UI::g_fh = new UI::Font_Handler();
-	UI::g_fh1 = UI::create_fonthandler(*g_gr, g_fs);
+	UI::g_fh1 = UI::create_fonthandler(g_gr, g_fs);
 
 	//make sure we didn't forget to read any global option
 	g_options.check_used();

=== modified file 'src/wui/attack_box.cc'
--- src/wui/attack_box.cc	2012-12-13 10:41:22 +0000
+++ src/wui/attack_box.cc	2013-02-10 14:53:26 +0000
@@ -19,6 +19,7 @@
 
 #include "attack_box.h"
 
+#include "graphic/graphic.h"
 #include "logic/soldier.h"
 
 #include "upcast.h"
@@ -82,7 +83,7 @@
 			 0, 0,
 			 width, height,
 			 min, max, initial,
-			 g_gr->imgcache().load(PicMod_Game, picname),
+			 g_gr->images().get(picname),
 			 hint);
 	parent.add(&result, UI::Box::AlignCenter);
 	return result;
@@ -115,7 +116,7 @@
 		new UI::Button
 			(&parent, text,
 			 8, 8, 26, 26,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+			 g_gr->images().get("pics/but2.png"),
 			 text,
 			 tooltip_text);
 	button->sigclicked.connect(boost::bind(fn, boost::ref(*this)));

=== modified file 'src/wui/building_statistics_menu.cc'
--- src/wui/building_statistics_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/building_statistics_menu.cc	2013-02-10 14:53:26 +0000
@@ -127,8 +127,8 @@
 		new UI::Button
 			(this, "previous_owned",
 			 JUMP_PREV_BUTTON_X, OWNED_Y, 24, 24,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_left.png"),
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get("pics/scrollbar_left.png"),
 			 _("Show previous"),
 			 false);
 	m_btn[Prev_Owned]->sigclicked.connect
@@ -138,8 +138,8 @@
 		new UI::Button
 			(this, "next_owned",
 			 JUMP_NEXT_BUTTON_X, OWNED_Y, 24, 24,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_right.png"),
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get("pics/scrollbar_right.png"),
 			 _("Show next"),
 			 false);
 	m_btn[Next_Owned]->sigclicked.connect
@@ -149,8 +149,8 @@
 		new UI::Button
 			(this, "previous_constructed",
 			 JUMP_PREV_BUTTON_X, IN_BUILD_Y, 24, 24,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_left.png"),
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get("pics/scrollbar_left.png"),
 			 _("Show previous"),
 			 false);
 	m_btn[Prev_Construction]->sigclicked.connect
@@ -160,8 +160,8 @@
 		new UI::Button
 			(this, "next_constructed",
 			 JUMP_NEXT_BUTTON_X, IN_BUILD_Y, 24, 24,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_right.png"),
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get("pics/scrollbar_right.png"),
 			 _("Show next"),
 			 false);
 	m_btn[Next_Construction]->sigclicked.connect
@@ -171,8 +171,8 @@
 		new UI::Button
 			(this, "previous_unproductive",
 			 JUMP_PREV_BUTTON_X, UNPRODUCTIVE_Y, 24, 24,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_left.png"),
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get("pics/scrollbar_left.png"),
 			 _("Show previous"),
 			 false);
 	m_btn[Prev_Unproductive]->sigclicked.connect
@@ -182,8 +182,8 @@
 		new UI::Button
 			(this, "next_unproductive",
 			 JUMP_NEXT_BUTTON_X, UNPRODUCTIVE_Y, 24, 24,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_right.png"),
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get("pics/scrollbar_right.png"),
 			 _("Show next"),
 			 false);
 	m_btn[Next_Unproductive]->sigclicked.connect
@@ -460,7 +460,7 @@
 				assert(false);
 				break;
 			}
-			te->set_picture(Columns::Size, g_gr->imgcache().load(PicMod_UI, pic));
+			te->set_picture(Columns::Size, g_gr->images().get(pic));
 		}
 
 		if (productionsite and nr_owned) {

=== modified file 'src/wui/buildingconfirm.cc'
--- src/wui/buildingconfirm.cc	2013-01-01 10:09:20 +0000
+++ src/wui/buildingconfirm.cc	2013-02-10 14:53:26 +0000
@@ -19,6 +19,7 @@
 
 #include "buildingconfirm.h"
 
+#include "graphic/graphic.h"
 #include "interactive_player.h"
 #include "logic/building.h"
 #include "logic/player.h"
@@ -125,16 +126,16 @@
 		new UI::Button
 			(this, "ok",
 			 6, 80, 80, 34,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_Game, "pics/menu_okay.png"));
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get("pics/menu_okay.png"));
 	okbtn->sigclicked.connect(boost::bind(&BuildingActionConfirm::ok, this));
 
 	UI::Button * cancelbtn =
 		new UI::Button
 			(this, "abort",
 			 114, 80, 80, 34,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_Game, "pics/menu_abort.png"));
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get("pics/menu_abort.png"));
 	cancelbtn->sigclicked.connect(boost::bind(&BuildingActionConfirm::die, this));
 
 	center_to_parent();

=== modified file 'src/wui/buildingwindow.cc'
--- src/wui/buildingwindow.cc	2013-01-23 21:07:18 +0000
+++ src/wui/buildingwindow.cc	2013-02-10 14:53:26 +0000
@@ -19,19 +19,20 @@
 
 #include "buildingconfirm.h"
 #include "game_debug_ui.h"
-#include "graphic/picture.h"
+#include "graphic/graphic.h"
+#include "graphic/image.h"
 #include "graphic/rendertarget.h"
 #include "interactive_player.h"
+#include "logic/dismantlesite.h"
 #include "logic/maphollowregion.h"
 #include "logic/militarysite.h"
 #include "logic/player.h"
 #include "logic/productionsite.h"
 #include "logic/tribe.h"
-#include "logic/dismantlesite.h"
+#include "ui_basic/helpwindow.h"
 #include "ui_basic/tabpanel.h"
 #include "upcast.h"
 #include "waresqueuedisplay.h"
-#include "ui_basic/helpwindow.h"
 
 #include "buildingwindow.h"
 
@@ -79,7 +80,7 @@
 	compile_assert(NUMBER_OF_WORKAREA_PICS <= 9);
 	for (Workarea_Info::size_type i = 0; i < NUMBER_OF_WORKAREA_PICS; ++i) {
 		++filename[13];
-		workarea_cumulative_pic[i] = g_gr->imgcache().load(PicMod_Game, filename);
+		workarea_cumulative_pic[i] = g_gr->images().get(filename);
 	}
 
 	show_workarea();
@@ -169,10 +170,8 @@
 				UI::Button * stopbtn =
 					new UI::Button
 						(capsbuttons, is_stopped ? "continue" : "stop", 0, 0, 34, 34,
-						 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-						 g_gr->imgcache().load
-						 	(PicMod_Game,
-						 	 (is_stopped ? "pics/continue.png" : "pics/stop.png")),
+						 g_gr->images().get("pics/but4.png"),
+						 g_gr->images().get((is_stopped ? "pics/continue.png" : "pics/stop.png")),
 						 is_stopped ? _("Continue") : _("Stop"));
 				stopbtn->sigclicked.connect(boost::bind(&Building_Window::act_start_stop, boost::ref(*this)));
 				capsbuttons->add
@@ -202,7 +201,7 @@
 					UI::Button * enhancebtn =
 						new UI::Button
 							(capsbuttons, "enhance", 0, 0, 34, 34,
-							 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+							 g_gr->images().get("pics/but4.png"),
 							 building_descr.get_buildicon(),
 							 std::string(buffer) + "<br><font size=11>" + _("Construction costs:") + "</font><br>" +
 								 waremap_to_richtext(tribe, building_descr.buildcost())); //  button id = building id
@@ -222,8 +221,8 @@
 			UI::Button * destroybtn =
 				new UI::Button
 					(capsbuttons, "destroy", 0, 0, 34, 34,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-					 g_gr->imgcache().load(PicMod_Game, pic_bulldoze),
+					 g_gr->images().get("pics/but4.png"),
+					 g_gr->images().get(pic_bulldoze),
 					 _("Destroy"));
 			destroybtn->sigclicked.connect
 				(boost::bind(&Building_Window::act_bulldoze, boost::ref(*this)));
@@ -240,8 +239,8 @@
 			UI::Button * dismantlebtn =
 				new UI::Button
 					(capsbuttons, "dismantle", 0, 0, 34, 34,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-					 g_gr->imgcache().load(PicMod_Game, pic_dismantle),
+					 g_gr->images().get("pics/but4.png"),
+					 g_gr->images().get(pic_dismantle),
 					 std::string(_("Dismantle")) + "<br><font size=11>" + _("Returns:") + "</font><br>" +
 						 waremap_to_richtext(owner.tribe(), wares));
 			dismantlebtn->sigclicked.connect(boost::bind(&Building_Window::act_dismantle, boost::ref(*this)));
@@ -266,8 +265,8 @@
 			m_toggle_workarea = new UI::Button
 				(capsbuttons, "workarea",
 				 0, 0, 34, 34,
-				 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-				 g_gr->imgcache().load(PicMod_Game,  "pics/workarea3cumulative.png"),
+				 g_gr->images().get("pics/but4.png"),
+				 g_gr->images().get("pics/workarea3cumulative.png"),
 				 _("Hide workarea"));
 			m_toggle_workarea->sigclicked.connect
 				(boost::bind(&Building_Window::toggle_workarea, boost::ref(*this)));
@@ -281,8 +280,8 @@
 			UI::Button * debugbtn =
 				new UI::Button
 					(capsbuttons, "debug", 0, 0, 34, 34,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-					 g_gr->imgcache().load(PicMod_Game,  pic_debug),
+					 g_gr->images().get("pics/but4.png"),
+					 g_gr->images().get(pic_debug),
 					 _("Debug"));
 			debugbtn->sigclicked.connect(boost::bind(&Building_Window::act_debug, boost::ref(*this)));
 			capsbuttons->add
@@ -293,8 +292,8 @@
 		UI::Button * gotobtn =
 			new UI::Button
 				(capsbuttons, "goto", 0, 0, 34, 34,
-				 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-				 g_gr->imgcache().load(PicMod_Game, "pics/menu_goto.png"), _("Center view on this"));
+				 g_gr->images().get("pics/but4.png"),
+				 g_gr->images().get("pics/menu_goto.png"), _("Center view on this"));
 		gotobtn->sigclicked.connect(boost::bind(&Building_Window::clicked_goto, boost::ref(*this)));
 		capsbuttons->add
 			(gotobtn,
@@ -310,8 +309,8 @@
 			UI::Button * helpbtn =
 				new UI::Button
 					(capsbuttons, "help", 0, 0, 34, 34,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-					 g_gr->imgcache().load(PicMod_Game, "pics/menu_help.png"),
+					 g_gr->images().get("pics/but4.png"),
+					 g_gr->images().get("pics/menu_help.png"),
 					 _("Help"));
 			helpbtn->sigclicked.connect
 				(boost::bind(&Building_Window::help_clicked, boost::ref(*this)));

=== modified file 'src/wui/buildingwindow.h'
--- src/wui/buildingwindow.h	2013-01-22 19:33:32 +0000
+++ src/wui/buildingwindow.h	2013-02-10 14:53:26 +0000
@@ -90,7 +90,7 @@
 	bool m_caps_setup;
 
 	Overlay_Manager::Job_Id m_workarea_job_id;
-	const IPicture* workarea_cumulative_pic[NUMBER_OF_WORKAREA_PICS];
+	const Image* workarea_cumulative_pic[NUMBER_OF_WORKAREA_PICS];
 };
 
 #endif // _BUILDINGWINDOW_H_

=== modified file 'src/wui/constructionsitewindow.cc'
--- src/wui/constructionsitewindow.cc	2012-12-13 10:41:22 +0000
+++ src/wui/constructionsitewindow.cc	2013-02-10 14:53:26 +0000
@@ -22,6 +22,7 @@
 
 #include "waresqueuedisplay.h"
 
+#include "graphic/graphic.h"
 #include "logic/constructionsite.h"
 #include "ui_basic/progressbar.h"
 #include "ui_basic/tabpanel.h"
@@ -71,7 +72,7 @@
 			 UI::Box::AlignLeft);
 
 
-	get_tabs()->add("wares", g_gr->imgcache().load(PicMod_UI, pic_tab_wares), &box, _("Building materials"));
+	get_tabs()->add("wares", g_gr->images().get(pic_tab_wares), &box, _("Building materials"));
 }
 
 

=== modified file 'src/wui/dismantlesitewindow.cc'
--- src/wui/dismantlesitewindow.cc	2012-12-13 10:41:22 +0000
+++ src/wui/dismantlesitewindow.cc	2013-02-10 14:53:26 +0000
@@ -19,6 +19,7 @@
 
 
 #include "buildingwindow.h"
+#include "graphic/graphic.h"
 #include "logic/dismantlesite.h"
 #include "ui_basic/progressbar.h"
 #include "ui_basic/tabpanel.h"
@@ -65,7 +66,7 @@
 	for (uint32_t i = 0; i < cs.get_nrwaresqueues(); ++i)
 		Building_Window::create_ware_queue_panel(&box, cs, cs.get_waresqueue(i), true);
 
-	get_tabs()->add("wares", g_gr->imgcache().load(PicMod_UI, pic_tab_wares), &box, _("Building materials"));
+	get_tabs()->add("wares", g_gr->images().get(pic_tab_wares), &box, _("Building materials"));
 }
 
 

=== modified file 'src/wui/encyclopedia_window.h'
--- src/wui/encyclopedia_window.h	2012-07-13 20:46:30 +0000
+++ src/wui/encyclopedia_window.h	2013-02-10 14:53:26 +0000
@@ -20,8 +20,6 @@
 #ifndef ENCYCLOPEDIA_WINDOW_H
 #define ENCYCLOPEDIA_WINDOW_H
 
-#include "graphic/graphic.h"
-
 #include "ui_basic/listselect.h"
 #include "ui_basic/window.h"
 #include "ui_basic/unique_window.h"

=== modified file 'src/wui/fieldaction.cc'
--- src/wui/fieldaction.cc	2013-01-23 21:07:18 +0000
+++ src/wui/fieldaction.cc	2013-02-10 14:53:26 +0000
@@ -231,7 +231,7 @@
 	bool m_fastclick; // if true, put the mouse over first button in first tab
 	uint32_t m_best_tab;
 	Overlay_Manager::Job_Id m_workarea_preview_job_id;
-	const IPicture* workarea_cumulative_pic[NUMBER_OF_WORKAREA_PICS];
+	const Image* workarea_cumulative_pic[NUMBER_OF_WORKAREA_PICS];
 
 	/// Variables to use with attack dialog.
 	AttackBox * m_attack_box;
@@ -287,7 +287,7 @@
 	m_map(&ib->egbase().map()),
 	m_overlay_manager(*m_map->get_overlay_manager()),
 	m_node(ib->get_sel_pos().node, &(*m_map)[ib->get_sel_pos().node]),
-	m_tabpanel(this, 0, 0, g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+	m_tabpanel(this, 0, 0, g_gr->images().get("pics/but1.png")),
 	m_fastclick(true),
 	m_best_tab(0),
 	m_workarea_preview_job_id(Overlay_Manager::Job_Id::Null()),
@@ -302,7 +302,7 @@
 	compile_assert(NUMBER_OF_WORKAREA_PICS <= 9);
 	for (Workarea_Info::size_type i = 0; i < NUMBER_OF_WORKAREA_PICS; ++i) {
 		++filename[13];
-		workarea_cumulative_pic[i] = g_gr->imgcache().load(PicMod_Game, filename);
+		workarea_cumulative_pic[i] = g_gr->images().get(filename);
 	}
 }
 
@@ -631,7 +631,7 @@
 {
 	return
 		m_tabpanel.add
-			(name, g_gr->imgcache().load(PicMod_Game, picname), panel, tooltip_text);
+			(name, g_gr->images().get(picname), panel, tooltip_text);
 }
 
 
@@ -647,8 +647,8 @@
 		*new UI::Button
 			(box, name,
 			 0, 0, 34, 34,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
-			 g_gr->imgcache().load(PicMod_Game, picname),
+			 g_gr->images().get("pics/but2.png"),
+			 g_gr->images().get(picname),
 			 tooltip_text);
 	button.sigclicked.connect(boost::bind(fn, this));
 	button.set_repeating(repeating);

=== modified file 'src/wui/game_debug_ui.cc'
--- src/wui/game_debug_ui.cc	2012-12-13 10:41:22 +0000
+++ src/wui/game_debug_ui.cc	2013-02-10 14:53:26 +0000
@@ -103,7 +103,7 @@
 	(Widelands::Editor_Game_Base const & egbase, UI::Tab_Panel & tabs)
 {
 	tabs.add
-		("debug", g_gr->imgcache().load(PicMod_Game, "pics/menu_debug.png"),
+		("debug", g_gr->images().get("pics/menu_debug.png"),
 		 new MapObjectDebugPanel(tabs, egbase, *this));
 }
 
@@ -148,7 +148,7 @@
 	m_object          (&obj),
 	m_tabs
 		(this, 0, 0,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"))
+		 g_gr->images().get("pics/but1.png"))
 {
 	char buffer[128];
 
@@ -243,7 +243,7 @@
 	m_ui_immovable
 		(this, "immovable",
 		 0, 280, 214, 24,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 ""),
 
 	m_ui_bobs(this, 0, 304, 214, 96)
@@ -342,12 +342,12 @@
 		switch (vision) {
 		case 0: str += "  never seen\n"; break;
 		case 1: {
-			AnimationData const * data = 0;
-			if (player_field.map_object_descr[Widelands::TCoords<>::None])
-				data =
-					g_anim.get_animation
-						(player_field.map_object_descr[Widelands::TCoords<>::None]
-						 ->main_animation());
+			std::string animation_name = "(none)";
+			if (player_field.map_object_descr[Widelands::TCoords<>::None]) {
+				animation_name = g_anim.get_animation
+					(player_field.map_object_descr[Widelands::TCoords<>::None]->main_animation()).picnametempl;
+			}
+
 			snprintf
 				(buffer, sizeof(buffer),
 				 "  last seen at %u:\n"
@@ -356,7 +356,7 @@
 				 "      ",
 				 player_field.time_node_last_unseen,
 				 player_field.owner,
-				 data ? data->picnametempl.c_str() : "(none)");
+				 animation_name.c_str());
 			str += buffer;
 			break;
 		}

=== modified file 'src/wui/game_main_menu.cc'
--- src/wui/game_main_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/game_main_menu.cc	2013-02-10 14:53:26 +0000
@@ -46,26 +46,26 @@
 general_stats
 	(this, "general_stats",
 	 posx(0, 4), posy(0, 3), buttonw(4), buttonh(1),
-	 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-	 g_gr->imgcache().load(PicMod_Game, "pics/menu_general_stats.png"),
+	 g_gr->images().get("pics/but4.png"),
+	 g_gr->images().get("pics/menu_general_stats.png"),
 	 _("General Statistics")),
 ware_stats
 	(this, "ware_stats",
 	 posx(1, 4), posy(0, 3), buttonw(4), buttonh(1),
-	 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-	 g_gr->imgcache().load(PicMod_Game, "pics/menu_ware_stats.png"),
+	 g_gr->images().get("pics/but4.png"),
+	 g_gr->images().get("pics/menu_ware_stats.png"),
 	 _("Ware Statistics")),
 building_stats
 	(this, "building_stats",
 	 posx(2, 4), posy(0, 3), buttonw(4), buttonh(1),
-	 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-	 g_gr->imgcache().load(PicMod_Game, "pics/menu_building_stats.png"),
+	 g_gr->images().get("pics/but4.png"),
+	 g_gr->images().get("pics/menu_building_stats.png"),
 	 _("Building Statistics")),
 stock
 	(this, "stock",
 	 posx(3, 4), posy(0, 3), buttonw(4), buttonh(1),
-	 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-	 g_gr->imgcache().load(PicMod_Game, "pics/menu_stock.png"),
+	 g_gr->images().get("pics/but4.png"),
+	 g_gr->images().get("pics/menu_stock.png"),
 	 _("Stock"))
 {
 	general_stats.sigclicked.connect

=== modified file 'src/wui/game_main_menu_save_game.cc'
--- src/wui/game_main_menu_save_game.cc	2012-12-13 10:41:22 +0000
+++ src/wui/game_main_menu_save_game.cc	2013-02-10 14:53:26 +0000
@@ -73,7 +73,7 @@
 	m_editbox =
 		new UI::EditBox
 			(this, HSPACING, EDITBOX_Y, LIST_WIDTH, EDITBOX_HEIGHT,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 g_gr->images().get("pics/but1.png"));
 	m_editbox->changed.connect(boost::bind(&Game_Main_Menu_Save_Game::edit_box_changed, this));
 	m_editbox->ok.connect(boost::bind(&Game_Main_Menu_Save_Game::ok, this));
 
@@ -81,7 +81,7 @@
 		new UI::Button
 			(this, "ok",
 			 DESCRIPTION_X, OK_Y, DESCRIPTION_WIDTH, BUTTON_HEIGHT,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+			 g_gr->images().get("pics/but4.png"),
 			 _("OK"),
 			 std::string(),
 			 false);
@@ -91,7 +91,7 @@
 		new UI::Button
 			(this, "cancel",
 			 DESCRIPTION_X, CANCEL_Y, DESCRIPTION_WIDTH, BUTTON_HEIGHT,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+			 g_gr->images().get("pics/but4.png"),
 			 _("Cancel"));
 	cancelbtn->sigclicked.connect(boost::bind(&Game_Main_Menu_Save_Game::die, this));
 
@@ -99,7 +99,7 @@
 		new UI::Button
 			(this, "delete",
 			 DESCRIPTION_X, DELETE_Y, DESCRIPTION_WIDTH, BUTTON_HEIGHT,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+			 g_gr->images().get("pics/but4.png"),
 			 _("Delete"));
 	deletebtn->sigclicked.connect(boost::bind(&Game_Main_Menu_Save_Game::delete_clicked, this));
 

=== modified file 'src/wui/game_message_menu.cc'
--- src/wui/game_message_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/game_message_menu.cc	2013-02-10 14:53:26 +0000
@@ -21,6 +21,7 @@
 
 #include <boost/bind.hpp>
 
+#include "graphic/graphic.h"
 #include "interactive_player.h"
 #include "logic/message_queue.h"
 #include "logic/player.h"
@@ -60,7 +61,7 @@
 		new UI::Button
 			(this, "clear_selection",
 			 5, 5, 70, 25,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+			 g_gr->images().get("pics/but0.png"),
 			 _("Clear"), _("Clear selection"));
 	clearselectionbtn->sigclicked.connect
 		(boost::bind(&GameMessageMenu::do_clear_selection, this));
@@ -69,7 +70,7 @@
 		new UI::Button
 			(this, "invert_selection",
 			 80, 5, 70, 25,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+			 g_gr->images().get("pics/but0.png"),
 			 _("Invert"), _("Invert selection"));
 	invertselectionbtn->sigclicked.connect
 		(boost::bind(&GameMessageMenu::do_invert_selection, this));
@@ -78,8 +79,8 @@
 		new UI::Button
 			(this, "archive_or_restore_selected_messages",
 			 155, 5, 25, 25,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
-			 g_gr->imgcache().load(PicMod_Game, "pics/message_archive.png"),
+			 g_gr->images().get("pics/but2.png"),
+			 g_gr->images().get("pics/message_archive.png"),
 			 _("Archive selected messages"));
 	m_archivebtn->sigclicked.connect
 		(boost::bind(&GameMessageMenu::archive_or_restore, this));
@@ -88,7 +89,7 @@
 		new UI::Button
 			(this, "toggle_between_inbox_or_archive",
 			 185, 5, 100, 25,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+			 g_gr->images().get("pics/but2.png"),
 			 _("Show Archive"));
 	m_togglemodebtn->sigclicked.connect
 		(boost::bind(&GameMessageMenu::toggle_mode, this));
@@ -97,8 +98,8 @@
 		new UI::Button
 			(this, "center_main_mapview_on_location",
 			 340, 5, 25, 25,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
-			 g_gr->imgcache().load(PicMod_Game, "pics/menu_goto.png"),
+			 g_gr->images().get("pics/but2.png"),
+			 g_gr->images().get("pics/menu_goto.png"),
 			 _("center main mapview on location"),
 			 false);
 	m_centerviewbtn->sigclicked.connect(boost::bind(&GameMessageMenu::center_view, this));
@@ -196,7 +197,7 @@
 {
 	er.set_picture
 		(ColStatus,
-		 g_gr->imgcache().load(PicMod_UI, status_picture_filename[message.status()]));
+		 g_gr->images().get(status_picture_filename[message.status()]));
 	er.set_string(ColTitle, message.title());
 
 	uint32_t time = message.sent();
@@ -368,14 +369,14 @@
 	case Inbox:
 		mode = Archive;
 		set_title(_("Message Menu: Archive"));
-		m_archivebtn->set_pic(g_gr->imgcache().load(PicMod_Game, "pics/message_restore.png"));
+		m_archivebtn->set_pic(g_gr->images().get("pics/message_restore.png"));
 		m_archivebtn->set_tooltip(_("Restore selected messages"));
 		m_togglemodebtn->set_title(_("Show Inbox"));
 		break;
 	case Archive:
 		mode = Inbox;
 		set_title(_("Message Menu: Inbox"));
-		m_archivebtn->set_pic(g_gr->imgcache().load(PicMod_Game, "pics/message_archive.png"));
+		m_archivebtn->set_pic(g_gr->images().get("pics/message_archive.png"));
 		m_archivebtn->set_tooltip(_("Archive selected messages"));
 		m_togglemodebtn->set_title(_("Show Archive"));
 		break;

=== modified file 'src/wui/game_objectives_menu.cc'
--- src/wui/game_objectives_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/game_objectives_menu.cc	2013-02-10 14:53:26 +0000
@@ -62,7 +62,7 @@
 		 25,
 		 5 + OBJECTIVE_LIST + 5 + FULL_OBJECTIVE_TEXT + 5,
 		 BUTTON_WIDTH, BUTTON_HEIGHT,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+		 g_gr->images().get("pics/but4.png"),
 		 &GameObjectivesMenu::claim_victory, *this,
 		 _("Claim Victory"), std::string(), false),
 	m_restart_mission
@@ -70,7 +70,7 @@
 		 25 + BUTTON_WIDTH + 25,
 		 5 + OBJECTIVE_LIST + 5 + FULL_OBJECTIVE_TEXT + 5,
 		 BUTTON_WIDTH, BUTTON_HEIGHT,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+		 g_gr->images().get("pics/but4.png"),
 		 &GameObjectivesMenu::restart_mission, *this,
 		 _("Restart Mission")),
 #endif

=== modified file 'src/wui/game_options_menu.cc'
--- src/wui/game_options_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/game_options_menu.cc	2013-02-10 14:53:26 +0000
@@ -52,36 +52,36 @@
 		 posx(0, 1),
 		 vmargin() + 0 * (20 + vspacing()) + 0 * vgap(),
 		 buttonw(1), 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+		 g_gr->images().get("pics/but4.png"),
 		 _("README")),
 	license
 		(this, "license",
 		 posx(0, 1),
 		 vmargin() + 1 * (20 + vspacing()) + 0 * vgap(),
 		 buttonw(1), 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+		 g_gr->images().get("pics/but4.png"),
 		 _("License")),
 	authors
 		(this, "authors",
 		 posx(0, 1),
 		 vmargin() + 2 * (20 + vspacing()) + 0 * vgap(),
 		 buttonw(1), 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+		 g_gr->images().get("pics/but4.png"),
 		 _("Authors")),
 	sound
 		(this, "sound_options",
 		 posx(0, 1),
 		 vmargin() + 3 * (20 + vspacing()) + 1 * vgap(),
 		 buttonw(1), 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
+		 g_gr->images().get("pics/but4.png"),
 		 _("Sound Options")),
 	save_game
 		(this, "save_game",
 		 posx(0, 1),
 		 vmargin() + 4 * (20 + vspacing()) + 2 * vgap(),
 		 buttonw(1), 35,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/menu_save_game.png"),
+		 g_gr->images().get("pics/but4.png"),
+		 g_gr->images().get("pics/menu_save_game.png"),
 		 _("Save Game")),
 	exit_game
 		(this, "exit_game",
@@ -89,8 +89,8 @@
 		 vmargin() + 4 * (20 + vspacing()) + 2 * vgap() +
 		 35 + vspacing(),
 		 buttonw(1), 35,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-		 g_gr->imgcache().load(PicMod_Game, "pics/menu_exit_game.png"),
+		 g_gr->images().get("pics/but4.png"),
+		 g_gr->images().get("pics/menu_exit_game.png"),
 		 _("Exit Game"))
 {
 	readme.sigclicked.connect
@@ -129,7 +129,7 @@
 
 	set_inner_size
 		(hmargin() + hmargin() +
-		 std::max(static_cast<int32_t>(get_inner_w()), readme.get_w()),
+		 std::max<int32_t>(get_inner_w(), readme.get_w()),
 		 get_inner_h());
 	if (get_usedefaultpos())
 		center_to_parent();

=== modified file 'src/wui/game_options_sound_menu.cc'
--- src/wui/game_options_sound_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/game_options_sound_menu.cc	2013-02-10 14:53:26 +0000
@@ -18,8 +18,9 @@
 
 #include "game_options_sound_menu.h"
 
+#include "graphic/graphic.h"
+#include "i18n.h"
 #include "sound/sound_handler.h"
-#include "i18n.h"
 
 GameOptionsSoundMenu::GameOptionsSoundMenu
 	(Interactive_GameBase & gb, UI::UniqueWindow::Registry & registry)
@@ -48,7 +49,7 @@
 	 + 1 * vspacing() + ingame_music_volume_label.get_h(),
 	 get_inner_w() - 2 * hmargin(), slideh(),
 	 0, g_sound_handler.get_max_volume(), g_sound_handler.get_music_volume(),
-	 g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+	 g_gr->images().get("pics/but1.png")),
 ingame_sound_volume_label
 	(this,
 	 hmargin(),
@@ -63,7 +64,7 @@
 	 + ingame_music_volume_label.get_h() + ingame_music_volume_label.get_h(),
 	 get_inner_w() - 2 * hmargin(), slideh(),
 	 0, g_sound_handler.get_max_volume(), g_sound_handler.get_fx_volume(),
-	 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"))
+	 g_gr->images().get("pics/but1.png"))
 {
 	ingame_music.set_state(not g_sound_handler.get_disable_music());
 	ingame_sound.set_state(not g_sound_handler.get_disable_fx   ());

=== modified file 'src/wui/game_tips.cc'
--- src/wui/game_tips.cc	2012-12-18 18:41:45 +0000
+++ src/wui/game_tips.cc	2013-02-10 14:53:26 +0000
@@ -20,13 +20,14 @@
 #include "game_tips.h"
 
 #include "constants.h"
-#include "io/fileread.h"
 #include "graphic/font.h"
 #include "graphic/font_handler1.h"
-#include "text_layout.h"
+#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "i18n.h"
+#include "io/fileread.h"
 #include "profile/profile.h"
+#include "text_layout.h"
 
 #define DEFAULT_INTERVAL 5  // seconds
 #define BG_IMAGE "pics/tips_bg.png"
@@ -105,21 +106,21 @@
 
 void GameTips::show_tip(int32_t index) {
 	// try to load a background
-	const IPicture* pic_background = g_gr->imgcache().load(PicMod_Menu, BG_IMAGE);
+	const Image* pic_background = g_gr->images().get(BG_IMAGE);
 	assert(pic_background);
 
 	RenderTarget & rt = *g_gr->get_render_target();
 	Rect tips_area;
 
-	uint32_t w = pic_background->get_w();
-	uint32_t h = pic_background->get_h();
+	uint16_t w = pic_background->width();
+	uint16_t h = pic_background->height();
 	Point pt((g_gr->get_xres() - w) / 2, (g_gr->get_yres() - h) / 2);
 	tips_area = Rect(pt, w, h);
 	rt.blit(pt, pic_background);
 
 	Point center(tips_area.x + tips_area.w / 2, tips_area.y + tips_area.h / 2);
-	const IPicture* rendered_text = UI::g_fh1->render(as_game_tip(m_tips[index].text), tips_area.w);
-	rt.blit(center - Point(rendered_text->get_w() / 2, rendered_text->get_h() / 2), rendered_text);
+	const Image* rendered_text = UI::g_fh1->render(as_game_tip(m_tips[index].text), tips_area.w);
+	rt.blit(center - Point(rendered_text->width() / 2, rendered_text->height() / 2), rendered_text);
 
 	g_gr->update_rectangle(tips_area);
 }

=== modified file 'src/wui/general_statistics_menu.cc'
--- src/wui/general_statistics_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/general_statistics_menu.cc	2013-02-10 14:53:26 +0000
@@ -148,8 +148,8 @@
 			*new UI::Button
 				(hbox1, "playerbutton",
 				 0, 0, 25, 25,
-				 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-				 g_gr->imgcache().load(PicMod_Game, buffer),
+				 g_gr->images().get("pics/but4.png"),
+				 g_gr->images().get(buffer),
 				 player->get_name().c_str());
 		cb.sigclicked.connect
 			(boost::bind(&General_Statistics_Menu::cb_changed_to, this, p));
@@ -170,7 +170,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_landsize.png"),
+		 g_gr->images().get("pics/genstats_landsize.png"),
 		 _("Land"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -178,7 +178,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_nrworkers.png"),
+		 g_gr->images().get("pics/genstats_nrworkers.png"),
 		 _("Workers"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -186,7 +186,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_nrbuildings.png"),
+		 g_gr->images().get("pics/genstats_nrbuildings.png"),
 		 _("Buildings"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -194,7 +194,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_nrwares.png"),
+		 g_gr->images().get("pics/genstats_nrwares.png"),
 		 _("Wares"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -202,7 +202,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_productivity.png"),
+		 g_gr->images().get("pics/genstats_productivity.png"),
 		 _("Productivity"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -210,7 +210,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_casualties.png"),
+		 g_gr->images().get("pics/genstats_casualties.png"),
 		 _("Casualties"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -218,7 +218,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_kills.png"),
+		 g_gr->images().get("pics/genstats_kills.png"),
 		 _("Kills"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -226,7 +226,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_msites_lost.png"),
+		 g_gr->images().get("pics/genstats_msites_lost.png"),
 		 _("Military buildings lost"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -234,7 +234,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_msites_defeated.png"),
+		 g_gr->images().get("pics/genstats_msites_defeated.png"),
 		 _("Military buildings defeated"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -242,7 +242,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_civil_blds_lost.png"),
+		 g_gr->images().get("pics/genstats_civil_blds_lost.png"),
 		 _("Civilian buildings lost"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -250,7 +250,7 @@
 	m_radiogroup.add_button
 		(hbox2,
 		 Point(0, 0),
-		 g_gr->imgcache().load(PicMod_Game, "pics/genstats_militarystrength.png"),
+		 g_gr->images().get("pics/genstats_militarystrength.png"),
 		 _("Military"),
 		 &btn);
 	hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -259,7 +259,7 @@
 		m_radiogroup.add_button
 			(hbox2,
 			 Point(0, 0),
-			 g_gr->imgcache().load(PicMod_Game, cs_pic),
+			 g_gr->images().get(cs_pic),
 			 cs_name.c_str(),
 			 &btn);
 		hbox2->add(btn, UI::Box::AlignLeft, false, true);
@@ -274,7 +274,7 @@
 	m_box.add
 		(new WUIPlot_Area_Slider
 			(&m_box, m_plot, 0, 0, 100, 45,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"))
+			 g_gr->images().get("pics/but1.png"))
 		, UI::Box::AlignTop
 		, true);
 

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2013-01-08 08:36:56 +0000
+++ src/wui/interactive_base.cc	2013-02-10 14:53:26 +0000
@@ -116,7 +116,7 @@
 
 	//  Having this in the initializer list (before Sys_InitGraphics) will give
 	//  funny results.
-	m_sel.pic = g_gr->imgcache().load(PicMod_Game, "pics/fsel.png");
+	m_sel.pic = g_gr->images().get("pics/fsel.png");
 
 	m_label_speed.set_visible(false);
 	m_label_speed_shadow.set_visible(false);
@@ -210,7 +210,7 @@
  * Set/Unset sel picture
  */
 void Interactive_Base::set_sel_picture(const char * const file) {
-	m_sel.pic = g_gr->imgcache().load(PicMod_Game, file);
+	m_sel.pic = g_gr->images().get(file);
 	set_sel_pos(get_sel_pos()); //  redraw
 }
 void Interactive_Base::unset_sel_picture() {
@@ -805,7 +805,7 @@
 
 		egbase().map().overlay_manager().register_overlay
 			(neighb,
-			 g_gr->imgcache().load(PicMod_Game, name),
+			 g_gr->images().get(name),
 			 7,
 			 Point::invalid(),
 			 m_road_buildhelp_overlay_jobid);

=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h	2013-01-06 20:04:34 +0000
+++ src/wui/interactive_base.h	2013-02-10 14:53:26 +0000
@@ -127,7 +127,7 @@
 			 		 Widelands::TCoords<>
 			 		 	(Widelands::Coords(0, 0), Widelands::TCoords<>::D)),
 			 const uint32_t Radius                   = 0,
-			 const IPicture* Pic                     = NULL,
+			 const Image* Pic                     = NULL,
 			 const Overlay_Manager::Job_Id Jobid = Overlay_Manager::Job_Id::Null())
 			:
 			freeze(Freeze), triangles(Triangles), pos(Pos), radius(Radius),
@@ -137,7 +137,7 @@
 		bool              triangles; //  otherwise nodes
 		Widelands::Node_and_Triangle<>     pos;
 		uint32_t              radius;
-		const IPicture* pic;
+		const Image* pic;
 		Overlay_Manager::Job_Id jobid;
 	} m_sel;
 
@@ -183,7 +183,7 @@
 	UI::UniqueWindow::Registry m_debugconsole;
 };
 
-#define PIC2 g_gr->imgcache().load(PicMod_UI, "pics/but2.png")
+#define PIC2 g_gr->images().get("pics/but2.png")
 #define TOOLBAR_BUTTON_COMMON_PARAMETERS(name) \
     &m_toolbar, name, 0, 0, 34U, 34U, PIC2
 

=== modified file 'src/wui/interactive_gamebase.h'
--- src/wui/interactive_gamebase.h	2013-01-20 21:27:20 +0000
+++ src/wui/interactive_gamebase.h	2013-02-10 14:53:26 +0000
@@ -22,7 +22,6 @@
 
 #include "interactive_base.h"
 #include "logic/game.h"
-#include "graphic/graphic.h"
 #include "general_statistics_menu.h"
 
 struct ChatOverlay;

=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc	2013-01-20 21:27:20 +0000
+++ src/wui/interactive_player.cc	2013-02-10 14:53:26 +0000
@@ -93,13 +93,13 @@
 
 #define INIT_BTN_this(picture, name, tooltip)                       \
  TOOLBAR_BUTTON_COMMON_PARAMETERS(name),                                      \
- g_gr->imgcache().load(PicMod_Game, "pics/" picture ".png"),                      \
+ g_gr->images().get("pics/" picture ".png"),                      \
  tooltip                                                                      \
 
 
 #define INIT_BTN(picture, name, tooltip)                            \
  TOOLBAR_BUTTON_COMMON_PARAMETERS(name),                                      \
- g_gr->imgcache().load(PicMod_Game, "pics/" picture ".png"),                      \
+ g_gr->images().get("pics/" picture ".png"),                      \
  tooltip                                                                      \
 
 
@@ -300,7 +300,7 @@
 				 nr_new_messages);
 			msg_tooltip = buffer;
 		}
-		m_toggle_message_menu.set_pic(g_gr->imgcache().load(PicMod_UI, msg_icon));
+		m_toggle_message_menu.set_pic(g_gr->images().get(msg_icon));
 		m_toggle_message_menu.set_tooltip(msg_tooltip);
 	}
 }

=== modified file 'src/wui/interactive_spectator.cc'
--- src/wui/interactive_spectator.cc	2012-12-13 10:41:22 +0000
+++ src/wui/interactive_spectator.cc	2013-02-10 14:53:26 +0000
@@ -47,7 +47,7 @@
 
 #define INIT_BTN(picture, name, tooltip)                            \
  TOOLBAR_BUTTON_COMMON_PARAMETERS(name),                                      \
- g_gr->imgcache().load(PicMod_Game, "pics/" picture ".png"),                      \
+ g_gr->images().get("pics/" picture ".png"),                      \
  tooltip                                                                      \
 
 	m_toggle_chat

=== modified file 'src/wui/itemwaresdisplay.h'
--- src/wui/itemwaresdisplay.h	2011-11-30 21:38:37 +0000
+++ src/wui/itemwaresdisplay.h	2013-02-10 14:53:26 +0000
@@ -20,6 +20,7 @@
 #ifndef WUI_ITEMWARESDISPLAY_H
 #define WUI_ITEMWARESDISPLAY_H
 
+#include "logic/widelands.h"
 #include "ui_basic/panel.h"
 
 namespace Widelands {

=== modified file 'src/wui/login_box.cc'
--- src/wui/login_box.cc	2012-12-13 10:41:22 +0000
+++ src/wui/login_box.cc	2013-02-10 14:53:26 +0000
@@ -33,13 +33,13 @@
 	eb_nickname =
 		new UI::EditBox
 			(this, 150, 5, 330, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"), UI::Align_Left);
+			 g_gr->images().get("pics/but2.png"), UI::Align_Left);
 
 	ta_password = new UI::Textarea(this, 10, 40, _("Password:"));
 	eb_password =
 		new UI::EditBox
 			(this, 150, 40, 330, 20,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"), UI::Align_Left);
+			 g_gr->images().get("pics/but2.png"), UI::Align_Left);
 
 	pwd_warning =
 		new UI::Textarea
@@ -59,13 +59,13 @@
 	UI::Button * loginbtn = new UI::Button
 		(this, "login",
 		 (get_inner_w() / 2 - 200) / 2, 175, 200, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 _("Login"));
 	loginbtn->sigclicked.connect(boost::bind(&LoginBox::pressedLogin, boost::ref(*this)));
 	UI::Button * cancelbtn = new UI::Button
 		(this, "cancel",
 		 (get_inner_w() / 2 - 200) / 2 + get_inner_w() / 2, 175, 200, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 _("Cancel"));
 	cancelbtn->sigclicked.connect(boost::bind(&LoginBox::pressedCancel, boost::ref(*this)));
 

=== modified file 'src/wui/military_box.cc'
--- src/wui/military_box.cc	2012-12-13 10:41:22 +0000
+++ src/wui/military_box.cc	2013-02-10 14:53:26 +0000
@@ -19,8 +19,9 @@
 
 #include "military_box.h"
 
+#include "graphic/graphic.h"
+#include "logic/editor_game_base.h"
 #include "logic/game.h"
-#include "logic/editor_game_base.h"
 #include "logic/playercommand.h"
 
 #include "upcast.h"
@@ -64,7 +65,7 @@
 			 0, 0,
 			 width, height,
 			 min, max, initial,
-			 g_gr->imgcache().load(PicMod_Game, picname),
+			 g_gr->images().get(picname),
 			 hint);
 	parent.add(&result, UI::Box::AlignTop);
 	return result;
@@ -94,7 +95,7 @@
 		new UI::Button
 			(&parent, name,
 			 8, 8, 26, 26,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but2.png"),
+			 g_gr->images().get("pics/but2.png"),
 			 text,
 			 tooltip_text);
 	button->sigclicked.connect(boost::bind(fn, boost::ref(*this)));

=== modified file 'src/wui/militarysitewindow.cc'
--- src/wui/militarysitewindow.cc	2012-12-13 10:41:22 +0000
+++ src/wui/militarysitewindow.cc	2013-02-10 14:53:26 +0000
@@ -18,6 +18,7 @@
  */
 
 #include "buildingwindow.h"
+#include "graphic/graphic.h"
 #include "logic/militarysite.h"
 #include "soldiercapacitycontrol.h"
 #include "soldierlist.h"
@@ -53,7 +54,7 @@
 Building_Window(parent, ms, registry)
 {
 	get_tabs()->add
-		("soldiers", g_gr->imgcache().load(PicMod_Game, pic_tab_military),
+		("soldiers", g_gr->images().get(pic_tab_military),
 		 create_soldier_list(*get_tabs(), parent, militarysite()),
 		 _("Soldiers"));
 }

=== modified file 'src/wui/minimap.cc'
--- src/wui/minimap.cc	2012-12-13 10:41:22 +0000
+++ src/wui/minimap.cc	2013-02-10 14:53:26 +0000
@@ -38,7 +38,7 @@
 	m_ibase       (ibase),
 	m_viewx       (0),
 	m_viewy       (0),
-	m_pic_map_spot(g_gr->imgcache().load(PicMod_Game, "pics/map_spot.png")),
+	m_pic_map_spot(g_gr->images().get("pics/map_spot.png")),
 	m_flags       (flags)
 {}
 
@@ -140,38 +140,38 @@
 	button_terrn
 		(this, "terrain",
 		 but_w() * 0, m_view.get_h() + but_h() * 0, but_w(), but_h(),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/button_terrn.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/button_terrn.png"),
 		 _("Terrain")),
 	button_owner
 		(this, "owner",
 		 but_w() * 1, m_view.get_h() + but_h() * 0, but_w(), but_h(),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/button_owner.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/button_owner.png"),
 		 _("Owner")),
 	button_flags
 		(this, "flags",
 		 but_w() * 2, m_view.get_h() + but_h() * 0, but_w(), but_h(),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/button_flags.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/button_flags.png"),
 		 _("Flags")),
 	button_roads
 		(this, "roads",
 		 but_w() * 0, m_view.get_h() + but_h() * 1, but_w(), but_h(),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/button_roads.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/button_roads.png"),
 		 _("Roads")),
 	button_bldns
 		(this, "buildings",
 		 but_w() * 1, m_view.get_h() + but_h() * 1, but_w(), but_h(),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/button_bldns.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/button_bldns.png"),
 		 _("Buildings")),
 	button_zoom
 		(this, "zoom",
 		 but_w() * 2, m_view.get_h() + but_h() * 1, but_w(), but_h(),
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/button_zoom.png"),
+		 g_gr->images().get("pics/but0.png"),
+		 g_gr->images().get("pics/button_zoom.png"),
 		 _("Zoom"))
 {
 	button_terrn.sigclicked.connect(boost::bind(&MiniMap::toggle, boost::ref(*this), Terrn));

=== modified file 'src/wui/minimap.h'
--- src/wui/minimap.h	2012-11-24 16:22:10 +0000
+++ src/wui/minimap.h	2013-02-10 14:53:26 +0000
@@ -77,7 +77,7 @@
 	private:
 		Interactive_Base & m_ibase;
 		int32_t                m_viewx, m_viewy;
-		const IPicture* m_pic_map_spot;
+		const Image* m_pic_map_spot;
 	public:
 		int8_t * m_flags;
 	};

=== modified file 'src/wui/multiplayersetupgroup.cc'
--- src/wui/multiplayersetupgroup.cc	2012-12-13 10:41:22 +0000
+++ src/wui/multiplayersetupgroup.cc	2013-02-10 14:53:26 +0000
@@ -20,6 +20,7 @@
 #include "multiplayersetupgroup.h"
 
 #include "gamesettings.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
 #include "log.h"
 #include "logic/game.h"
@@ -59,7 +60,7 @@
 			type = new UI::Button
 				(this, "client_type",
 				 0, 0, h, h,
-				 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+				 g_gr->images().get("pics/but1.png"),
 				 std::string(), std::string(), true, false);
 			type->sigclicked.connect
 				(boost::bind
@@ -69,7 +70,7 @@
 		} else { // just a shown client
 			type_icon = new UI::Icon
 				(this, 0, 0, h, h,
-				 g_gr->imgcache().load(PicMod_UI, "pics/menu_tab_watch.png"));
+				 g_gr->images().get("pics/menu_tab_watch.png"));
 			add(type_icon, UI::Box::AlignCenter);
 		}
 
@@ -119,11 +120,11 @@
 
 				// Either Button if changeable OR text if not
 				if (m_id == s->settings().usernum) {
-					type->set_pic(g_gr->imgcache().load(PicMod_UI, buf));
+					type->set_pic(g_gr->images().get(buf));
 					type->set_tooltip(buf2);
 					type->set_visible(true);
 				} else {
-					type_icon->setIcon(g_gr->imgcache().load(PicMod_UI, buf));
+					type_icon->setIcon(g_gr->images().get(buf));
 					type_icon->set_tooltip(buf2);
 					type_icon->set_visible(true);
 				}
@@ -147,7 +148,7 @@
 		 GameSettingsProvider * const settings,
 		 NetworkPlayerSettingsBackend * const npsb,
 		 UI::Font * font,
-		 std::map<std::string, const IPicture* > & tp,
+		 std::map<std::string, const Image* > & tp,
 		 std::map<std::string, std::string> & tn)
 		 :
 		 UI::Box(parent, 0, 0, UI::Box::Horizontal, w, h),
@@ -166,12 +167,12 @@
 		snprintf
 			(buf, sizeof(buf), "pics/fsel_editor_set_player_0%i_pos.png", id + 1);
 		player =
-			new UI::Icon(this, 0, 0, h, h, g_gr->imgcache().load(PicMod_UI, buf));
+			new UI::Icon(this, 0, 0, h, h, g_gr->images().get(buf));
 		add(player, UI::Box::AlignCenter);
 		type = new UI::Button
 			(this, "player_type",
 			 0, 0, h, h,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+			 g_gr->images().get("pics/but1.png"),
 			 std::string(), std::string(), true, false);
 		type->sigclicked.connect
 			(boost::bind
@@ -181,7 +182,7 @@
 		tribe = new UI::Button
 			(this, "player_tribe",
 			 0, 0, h, h,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+			 g_gr->images().get("pics/but1.png"),
 			 std::string(), std::string(), true, false);
 		tribe->sigclicked.connect
 			(boost::bind
@@ -192,7 +193,7 @@
 		init = new UI::Button
 			(this, "player_init",
 			 0, 0, w - 4 * h, h,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+			 g_gr->images().get("pics/but1.png"),
 			 std::string(), std::string(), true, false);
 		init->sigclicked.connect
 			(boost::bind
@@ -202,7 +203,7 @@
 		team = new UI::Button
 			(this, "player_team",
 			 0, 0, h, h,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+			 g_gr->images().get("pics/but1.png"),
 			 std::string(), std::string(), true, false);
 		team->sigclicked.connect
 			(boost::bind
@@ -253,7 +254,7 @@
 		type->set_enabled(typeaccess);
 		if (player.state == PlayerSettings::stateClosed) {
 			type ->set_tooltip(_("Closed"));
-			type ->set_pic(g_gr->imgcache().load(PicMod_UI, "pics/stop.png"));
+			type ->set_pic(g_gr->images().get("pics/stop.png"));
 			team ->set_visible(false);
 			team ->set_enabled(false);
 			tribe->set_visible(false);
@@ -264,7 +265,7 @@
 			return;
 		} else if (player.state == PlayerSettings::stateOpen) {
 			type ->set_tooltip(_("Open"));
-			type ->set_pic(g_gr->imgcache().load(PicMod_UI, "pics/continue.png"));
+			type ->set_pic(g_gr->images().get("pics/continue.png"));
 			team ->set_visible(false);
 			team ->set_enabled(false);
 			tribe->set_visible(false);
@@ -275,13 +276,13 @@
 			return;
 		} else if (player.state == PlayerSettings::stateShared) {
 			type ->set_tooltip(_("Shared in"));
-			type ->set_pic(g_gr->imgcache().load(PicMod_UI, "pics/shared_in.png"));
+			type ->set_pic(g_gr->images().get("pics/shared_in.png"));
 
 			char pic[42], hover[128];
 			snprintf(pic, sizeof(pic), "pics/fsel_editor_set_player_0%i_pos.png", player.shared_in);
 			snprintf(hover, sizeof(hover), _("Player %i"), player.shared_in);
 
-			tribe->set_pic(g_gr->imgcache().load(PicMod_UI, pic));
+			tribe->set_pic(g_gr->images().get(pic));
 			tribe->set_tooltip(hover);
 
 			team ->set_visible(false);
@@ -311,11 +312,11 @@
 				pic += "genstats_nrworkers.png";
 			}
 			type->set_tooltip(title.c_str());
-			type->set_pic(g_gr->imgcache().load(PicMod_UI, pic));
+			type->set_pic(g_gr->images().get(pic));
 			if (player.random_tribe) {
 				std::string random = _("Random");
 				if (!m_tribenames["random"].size())
-					m_tribepics[random] = g_gr->imgcache().load(PicMod_UI, "pics/random.png");
+					m_tribepics[random] = g_gr->images().get("pics/random.png");
 				tribe->set_tooltip(random.c_str());
 				tribe->set_pic(m_tribepics[random]);
 			} else {
@@ -326,7 +327,7 @@
 					Section & global = prof.get_safe_section("tribe");
 					m_tribenames[player.tribe] = global.get_safe_string("name");
 					m_tribepics[player.tribe] =
-						g_gr->imgcache().load(PicMod_UI, (tribepath + "/") + global.get_safe_string("icon"));
+						g_gr->images().get((tribepath + "/") + global.get_safe_string("icon"));
 				}
 				tribe->set_tooltip(m_tribenames[player.tribe].c_str());
 				tribe->set_pic(m_tribepics[player.tribe]);
@@ -375,7 +376,7 @@
 	GameSettingsProvider         * const s;
 	NetworkPlayerSettingsBackend * const n;
 	uint8_t                        const m_id;
-	std::map<std::string, const IPicture* >   & m_tribepics;
+	std::map<std::string, const Image* >   & m_tribepics;
 	std::map<std::string, std::string> & m_tribenames;
 };
 

=== modified file 'src/wui/multiplayersetupgroup.h'
--- src/wui/multiplayersetupgroup.h	2012-11-18 17:33:18 +0000
+++ src/wui/multiplayersetupgroup.h	2013-02-10 14:53:26 +0000
@@ -20,13 +20,14 @@
 #ifndef MULTIPLAYERSETUPGROUP_H
 #define MULTIPLAYERSETUPGROUP_H
 
+#include <map>
+#include <string>
+
 #include "constants.h"
 #include "ui_basic/box.h"
 #include "ui_basic/panel.h"
 #include "ui_basic/textarea.h"
 
-#include <string>
-
 #define MAXCLIENTS 64
 
 struct GameSettingsProvider;
@@ -63,7 +64,7 @@
 	uint32_t    m_buth, m_fsize;
 	std::string m_fname;
 
-	std::map<std::string, const IPicture* > m_tribepics;
+	std::map<std::string, const Image* > m_tribepics;
 	std::map<std::string, std::string> m_tribenames;
 };
 

=== modified file 'src/wui/overlay_manager.cc'
--- src/wui/overlay_manager.cc	2012-12-14 20:09:35 +0000
+++ src/wui/overlay_manager.cc	2013-02-10 14:53:26 +0000
@@ -155,7 +155,7 @@
  */
 void Overlay_Manager::register_overlay
 	(Widelands::TCoords<> const c,
-	 const IPicture* pic,
+	 const Image* pic,
 	 int32_t              const level,
 	 Point                      hotspot,
 	 Job_Id               const jobid)
@@ -164,7 +164,7 @@
 	assert(level != 5); //  level == 5 is undefined behavior
 
 	if (hotspot == Point::invalid()) {
-		hotspot = Point(pic->get_w() / 2, pic->get_h() / 2);
+		hotspot = Point(pic->width() / 2, pic->height() / 2);
 	}
 
 	Registered_Overlays_Map & overlay_map = m_overlays[c.t];
@@ -213,7 +213,7 @@
  * remove one (or many) overlays from a node or triangle
  */
 void Overlay_Manager::remove_overlay
-	(Widelands::TCoords<> const c, const IPicture* pic)
+	(Widelands::TCoords<> const c, const Image* pic)
 {
 	assert(c.t <= 2);
 
@@ -308,8 +308,8 @@
 	const char * const * filename = filenames;
 
 	//  Special case for flag, which has a different formula for hotspot_y.
-	buildhelp_info->pic = g_gr->imgcache().load(PicMod_Game, *filename);
-	buildhelp_info->hotspot = Point(buildhelp_info->pic->get_w() / 2, buildhelp_info->pic->get_h() - 1);
+	buildhelp_info->pic = g_gr->images().get(*filename);
+	buildhelp_info->hotspot = Point(buildhelp_info->pic->width() / 2, buildhelp_info->pic->height() - 1);
 
 	const Overlay_Info * const buildhelp_infos_end =
 		buildhelp_info + Widelands::Field::Buildhelp_None;
@@ -317,8 +317,8 @@
 		++buildhelp_info, ++filename;
 		if (buildhelp_info == buildhelp_infos_end)
 			break;
-		buildhelp_info->pic = g_gr->imgcache().load(PicMod_Game, *filename);
-		buildhelp_info->hotspot = Point(buildhelp_info->pic->get_w() / 2, buildhelp_info->pic->get_h() / 2);
+		buildhelp_info->pic = g_gr->images().get(*filename);
+		buildhelp_info->hotspot = Point(buildhelp_info->pic->width() / 2, buildhelp_info->pic->height() / 2);
 	}
 
 	m_are_graphics_loaded = true;

=== modified file 'src/wui/overlay_manager.h'
--- src/wui/overlay_manager.h	2012-12-14 20:09:35 +0000
+++ src/wui/overlay_manager.h	2013-02-10 14:53:26 +0000
@@ -24,11 +24,12 @@
 #include "boost/function.hpp"
 #include "logic/field.h"
 #include "logic/widelands_geometry.h"
-#include "graphic/graphic.h"
 
 #include <map>
 #include <set>
 
+class Image;
+
 /*
  * The Overlay Manager is responsible for the map overlays. He
  * manages overlays in the following way:
@@ -75,7 +76,7 @@
 		uint32_t id;
 	};
 	struct Overlay_Info {
-		const IPicture* pic;
+		const Image* pic;
 		Point hotspot;
 	};
 
@@ -120,13 +121,13 @@
 	 */
 	void register_overlay
 		(Widelands::TCoords<>,
-		 const IPicture* pic,
+		 const Image* pic,
 		 int32_t level,
 		 Point   hotspot = Point::invalid(),
 		 Job_Id          = Job_Id::Null());
 
 	// removes all overlays when pic is zero
-	void remove_overlay(Widelands::TCoords<>, const IPicture* pic);
+	void remove_overlay(Widelands::TCoords<>, const Image* pic);
 	void remove_overlay(Job_Id);
 
 	uint8_t get_overlays(Widelands::FCoords c, Overlay_Info *) const;
@@ -167,7 +168,7 @@
 	struct Registered_Overlays {
 		Registered_Overlays
 			(const Job_Id    Jobid,
-			 const IPicture* Picid,
+			 const Image* Picid,
 			 const Point     Hotspot,
 			 const int32_t   Level)
 			:
@@ -178,7 +179,7 @@
 			jobids.insert(Jobid);
 		}
 		std::set<Job_Id> jobids;
-		const IPicture*  pic;
+		const Image*  pic;
 		Point            hotspot;
 		int32_t level;
 	};

=== modified file 'src/wui/playerdescrgroup.cc'
--- src/wui/playerdescrgroup.cc	2012-12-13 10:41:22 +0000
+++ src/wui/playerdescrgroup.cc	2013-02-10 14:53:26 +0000
@@ -21,10 +21,11 @@
 
 #include "constants.h"
 #include "gamesettings.h"
+#include "graphic/graphic.h"
 #include "i18n.h"
 #include "logic/player.h"
+#include "logic/tribe.h"
 #include "profile/profile.h"
-#include "logic/tribe.h"
 #include "wexception.h"
 
 #include "ui_basic/button.h"
@@ -70,7 +71,7 @@
 	d->btnPlayerType = new UI::Button
 		(this, "player_type",
 		 xplayertype, 0, xplayerteam - xplayertype - 2, h,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 std::string(), std::string(),
 		 true, false);
 	d->btnPlayerType->sigclicked.connect
@@ -79,7 +80,7 @@
 	d->btnPlayerTeam = new UI::Button
 		(this, "player_team",
 		 xplayerteam, 0, xplayertribe - xplayerteam - 2, h,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 std::string(), std::string(),
 		 true, false);
 	d->btnPlayerTeam->sigclicked.connect
@@ -88,7 +89,7 @@
 	d->btnPlayerTribe = new UI::Button
 		(this, "player_tribe",
 		 xplayertribe, 0, xplayerinit - xplayertribe - 2, h,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 std::string(), std::string(),
 		 true, false);
 	d->btnPlayerTribe->sigclicked.connect
@@ -97,7 +98,7 @@
 	d->btnPlayerInit = new UI::Button
 		(this, "player_initialization",
 		 xplayerinit, 0, w - xplayerinit, h,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but1.png"),
+		 g_gr->images().get("pics/but1.png"),
 		 std::string(), _("Initialization"),
 		 true, false);
 	d->btnPlayerInit->sigclicked.connect

=== modified file 'src/wui/playerdescrgroup.h'
--- src/wui/playerdescrgroup.h	2012-02-15 21:25:34 +0000
+++ src/wui/playerdescrgroup.h	2013-02-10 14:53:26 +0000
@@ -20,11 +20,12 @@
 #ifndef PLAYERDESCRGROUP_H
 #define PLAYERDESCRGROUP_H
 
+#include <string>
+#include <map>
+
 #include "constants.h"
 #include "ui_basic/panel.h"
 
-#include <string>
-
 namespace UI {
 struct Font;
 }

=== modified file 'src/wui/plot_area.cc'
--- src/wui/plot_area.cc	2012-12-13 10:41:22 +0000
+++ src/wui/plot_area.cc	2013-02-10 14:53:26 +0000
@@ -352,7 +352,7 @@
 	// first, tile the background
 	dst.tile
 		(Rect(Point(0, 0), get_inner_w(), get_inner_h()),
-		 g_gr->imgcache().load(PicMod_Game, BG_PIC), Point(0, 0));
+		 g_gr->images().get(BG_PIC), Point(0, 0));
 
 	// Draw coordinate system
 	// X Axis

=== modified file 'src/wui/plot_area.h'
--- src/wui/plot_area.h	2012-11-18 17:33:18 +0000
+++ src/wui/plot_area.h	2013-02-10 14:53:26 +0000
@@ -146,7 +146,7 @@
 		(Panel * const parent,
 		 WUIPlot_Area & plot_area,
 		 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
-		 const IPicture* background_picture_id,
+		 const Image* background_picture_id,
 		 const std::string & tooltip_text = std::string(),
 		 const uint32_t cursor_size = 20,
 		 const bool enabled = true)

=== modified file 'src/wui/productionsitewindow.cc'
--- src/wui/productionsitewindow.cc	2013-02-04 21:52:38 +0000
+++ src/wui/productionsitewindow.cc	2013-02-10 14:53:26 +0000
@@ -22,6 +22,7 @@
 #include "waresqueuedisplay.h"
 
 #include "economy/request.h"
+#include "graphic/graphic.h"
 #include "logic/constructionsite.h"
 #include "logic/militarysite.h"
 #include "logic/trainingsite.h"
@@ -62,7 +63,7 @@
 				 UI::Box::AlignLeft);
 
 		get_tabs()->add
-			("wares", g_gr->imgcache().load(PicMod_Game, pic_tab_wares),
+			("wares", g_gr->images().get(pic_tab_wares),
 			 prod_box, _("Wares"));
 	}
 
@@ -89,8 +90,8 @@
 			m_worker_caps->add_inf_space();
 			UI::Button * evict_button = new UI::Button
 							(m_worker_caps, "evict", 0, 0, 34, 34,
-							 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-							 g_gr->imgcache().load(PicMod_Game, "pics/menu_drop_soldier.png"),
+							 g_gr->images().get("pics/but4.png"),
+							 g_gr->images().get("pics/menu_drop_soldier.png"),
 							 _("Terminate the employment of the selected worker"));
 			evict_button->sigclicked.connect
 					(boost::bind(&ProductionSite_Window::evict_worker, boost::ref(*this)));
@@ -100,7 +101,7 @@
 		worker_box->add(m_worker_table, UI::Box::AlignLeft, true);
 		worker_box->add(m_worker_caps, UI::Box::AlignLeft, true);
 		get_tabs()->add
-			("workers", g_gr->imgcache().load(PicMod_UI, pic_tab_workers),
+			("workers", g_gr->images().get(pic_tab_workers),
 			 worker_box,
 			 productionsite().descr().nr_working_positions() > 1 ?
 			 _("Workers") : _("Worker"));

=== modified file 'src/wui/shipwindow.cc'
--- src/wui/shipwindow.cc	2012-12-13 10:41:22 +0000
+++ src/wui/shipwindow.cc	2013-02-10 14:53:26 +0000
@@ -22,11 +22,12 @@
 #include "ui_basic/box.h"
 
 #include "economy/portdock.h"
-#include "logic/warehouse.h"
+#include "economy/ware_instance.h"
+#include "graphic/graphic.h"
 #include "interactive_gamebase.h"
 #include "itemwaresdisplay.h"
-#include <economy/ware_instance.h>
-#include <logic/worker.h>
+#include "logic/warehouse.h"
+#include "logic/worker.h"
 
 static const char pic_goto[] = "pics/menu_ship_goto.png";
 static const char pic_destination[] = "pics/menu_ship_destination.png";
@@ -134,8 +135,8 @@
 	UI::Button * btn =
 		new UI::Button
 			(parent, name, 0, 0, 34, 34,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-			 g_gr->imgcache().load(PicMod_Game, picname),
+			 g_gr->images().get("pics/but4.png"),
+			 g_gr->images().get(picname),
 			 title);
 	btn->sigclicked.connect(callback);
 	return btn;

=== modified file 'src/wui/soldiercapacitycontrol.cc'
--- src/wui/soldiercapacitycontrol.cc	2012-12-13 10:41:22 +0000
+++ src/wui/soldiercapacitycontrol.cc	2013-02-10 14:53:26 +0000
@@ -19,6 +19,7 @@
 
 #include "soldiercapacitycontrol.h"
 
+#include "graphic/graphic.h"
 #include "interactive_gamebase.h"
 #include "logic/player.h"
 #include "logic/soldiercontrol.h"
@@ -63,12 +64,12 @@
 m_building(building),
 m_decrease
 	(this, "decrease", 0, 0, 24, 24,
-	 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-	 g_gr->imgcache().load(PicMod_Game, pic_down_train), _("Decrease capacity")),
+	 g_gr->images().get("pics/but4.png"),
+	 g_gr->images().get(pic_down_train), _("Decrease capacity")),
 m_increase
 	(this, "increase", 0, 0, 24, 24,
-	 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-	 g_gr->imgcache().load(PicMod_Game, pic_up_train), _("Increase capacity")),
+	 g_gr->images().get("pics/but4.png"),
+	 g_gr->images().get(pic_up_train), _("Increase capacity")),
 m_value(this, "", UI::Align_Center)
 {
 	m_decrease.sigclicked.connect(boost::bind(&SoldierCapacityControl::click_decrease, boost::ref(*this)));

=== modified file 'src/wui/soldierlist.cc'
--- src/wui/soldierlist.cc	2012-06-08 22:33:16 +0000
+++ src/wui/soldierlist.cc	2013-02-10 14:53:26 +0000
@@ -221,7 +221,7 @@
 			if (icon_it.current->row <= icon.row)
 				insertpos = icon_it.current + 1;
 
-			icon.pos.x = std::max(icon.pos.x, static_cast<int32_t>(icon_it.current->pos.x + m_icon_width));
+			icon.pos.x = std::max<int32_t>(icon.pos.x, icon_it.current->pos.x + m_icon_width);
 		}
 
 		icon.cache_health = 0;

=== modified file 'src/wui/stock_menu.cc'
--- src/wui/stock_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/stock_menu.cc	2013-02-10 14:53:26 +0000
@@ -42,30 +42,30 @@
 {
 	UI::Tab_Panel * tabs =
 		 new UI::Tab_Panel
-			 (this, 0, 0, g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 (this, 0, 0, g_gr->images().get("pics/but1.png"));
 	set_center_panel(tabs);
 
 	m_all_wares = new WaresDisplay(tabs, 0, 0, plr.player().tribe(), Widelands::wwWARE, false);
 	tabs->add
-		("total_wares", g_gr->imgcache().load(PicMod_UI, pic_tab_wares),
+		("total_wares", g_gr->images().get(pic_tab_wares),
 		 m_all_wares, _("Wares (total)"));
 
 	m_all_workers = new WaresDisplay(tabs, 0, 0, plr.player().tribe(), Widelands::wwWORKER, false);
 	tabs->add
-		("workers_total", g_gr->imgcache().load(PicMod_UI, pic_tab_workers),
+		("workers_total", g_gr->images().get(pic_tab_workers),
 		 m_all_workers, _("Workers (total)"));
 
 	m_warehouse_wares = new WaresDisplay(tabs, 0, 0, plr.player().tribe(), Widelands::wwWARE, false);
 	tabs->add
 		("wares_in_warehouses",
-		 g_gr->imgcache().load (PicMod_UI, pic_tab_wares_warehouse),
+		 g_gr->images().get (pic_tab_wares_warehouse),
 		 m_warehouse_wares, _("Wares in warehouses")
 	);
 
 	m_warehouse_workers = new WaresDisplay(tabs, 0, 0, plr.player().tribe(), Widelands::wwWORKER, false);
 	tabs->add
 		("workers_in_warehouses",
-		 g_gr->imgcache().load(PicMod_UI, pic_tab_workers_warehouse),
+		 g_gr->images().get(pic_tab_workers_warehouse),
 		 m_warehouse_workers, _("Workers in warehouses")
 	);
 }

=== modified file 'src/wui/story_message_box.cc'
--- src/wui/story_message_box.cc	2012-12-13 10:41:22 +0000
+++ src/wui/story_message_box.cc	2013-02-10 14:53:26 +0000
@@ -65,7 +65,7 @@
 	UI::Button * okbtn = new UI::Button
 		(this, "ok",
 		 posx, posy, but_width, 20,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+		 g_gr->images().get("pics/but0.png"),
 		 button_text);
 	okbtn->sigclicked.connect(boost::bind(&Story_Message_Box::clicked_ok, boost::ref(*this)));
 		posx += but_width;

=== modified file 'src/wui/trainingsitewindow.cc'
--- src/wui/trainingsitewindow.cc	2012-12-13 10:41:22 +0000
+++ src/wui/trainingsitewindow.cc	2013-02-10 14:53:26 +0000
@@ -17,6 +17,7 @@
  *
  */
 
+#include "graphic/graphic.h"
 #include "logic/trainingsite.h"
 #include "productionsitewindow.h"
 #include "soldiercapacitycontrol.h"
@@ -52,7 +53,7 @@
 ProductionSite_Window  (parent, ts, registry)
 {
 	get_tabs()->add
-		("soldiers", g_gr->imgcache().load(PicMod_Game, pic_tab_military),
+		("soldiers", g_gr->images().get(pic_tab_military),
 		 create_soldier_list(*get_tabs(), parent, trainingsite()),
 		 _("Soldiers in training"));
 }

=== modified file 'src/wui/transport_ui.cc'
--- src/wui/transport_ui.cc	2012-12-13 10:41:22 +0000
+++ src/wui/transport_ui.cc	2013-02-10 14:53:26 +0000
@@ -19,11 +19,12 @@
 
 #include "economy/economy.h"
 #include "graphic/font_handler.h"
+#include "graphic/graphic.h"
+#include "graphic/rendertarget.h"
 #include "interactive_gamebase.h"
 #include "logic/item_ware_descr.h"
 #include "logic/player.h"
 #include "logic/playercommand.h"
-#include "graphic/rendertarget.h"
 #include "logic/tribe.h"
 #include "ui_basic/button.h"
 #include "ui_basic/tabpanel.h"
@@ -49,18 +50,18 @@
 		UI::UniqueWindow
 			(&parent, "economy_options", &economy.m_optionswindow_registry, 0, 0,
 			 _("Economy options")),
-		m_tabpanel(this, 0, 0, g_gr->imgcache().load(PicMod_UI, "pics/but1.png"))
+		m_tabpanel(this, 0, 0, g_gr->images().get("pics/but1.png"))
 	{
 		set_center_panel(&m_tabpanel);
 
 		m_tabpanel.add
 			("wares",
-			 g_gr->imgcache().load(PicMod_UI, pic_tab_wares),
+			 g_gr->images().get(pic_tab_wares),
 			 new Economy_Options_Ware_Panel(&m_tabpanel, parent, economy),
 			 _("Wares"));
 		m_tabpanel.add
 			("workers",
-			 g_gr->imgcache().load(PicMod_UI, pic_tab_workers),
+			 g_gr->images().get(pic_tab_workers),
 			 new Economy_Options_Worker_Panel(&m_tabpanel, parent, economy),
 			 _("Workers"));
 
@@ -139,7 +140,7 @@
 	b = new UI::Button                                    \
 		 (buttons, #callback,                                       \
 		  0, 0, 34, 34,                                             \
-		  g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),            \
+		  g_gr->images().get("pics/but4.png"),            \
 		  text, tooltip, m_can_act);                                \
 	b->sigclicked.connect(boost::bind(&Economy_Options_Ware_Panel::callback, this)); \
 	buttons->add(b, UI::Box::AlignCenter);
@@ -234,7 +235,7 @@
 	b = new UI::Button                                      \
 		 (buttons, #callback,                                         \
 		  0, 0, 34, 34,                                               \
-		  g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),              \
+		  g_gr->images().get("pics/but4.png"),              \
 		  text, tooltip, m_can_act);                                  \
 	b->sigclicked.connect(boost::bind(&Economy_Options_Worker_Panel::callback, this)); \
 	buttons->add(b, UI::Box::AlignCenter);

=== modified file 'src/wui/ware_statistics_menu.cc'
--- src/wui/ware_statistics_menu.cc	2012-12-13 10:41:22 +0000
+++ src/wui/ware_statistics_menu.cc	2013-02-10 14:53:26 +0000
@@ -168,7 +168,7 @@
 
 	UI::Tab_Panel * tabs =
 		 new UI::Tab_Panel
-			 (box, spacing, 0, g_gr->imgcache().load(PicMod_UI, "pics/but1.png"));
+			 (box, spacing, 0, g_gr->images().get("pics/but1.png"));
 
 
 	m_plot_production =
@@ -179,7 +179,7 @@
 	m_plot_production->set_plotmode(WUIPlot_Area::PLOTMODE_RELATIVE);
 
 	tabs->add
-		("production", g_gr->imgcache().load(PicMod_UI, pic_tab_production),
+		("production", g_gr->images().get(pic_tab_production),
 			m_plot_production, _("Production"));
 
 	m_plot_consumption =
@@ -190,7 +190,7 @@
 	m_plot_consumption->set_plotmode(WUIPlot_Area::PLOTMODE_RELATIVE);
 
 	tabs->add
-		("consumption", g_gr->imgcache().load(PicMod_UI, pic_tab_consumption),
+		("consumption", g_gr->images().get(pic_tab_consumption),
 			m_plot_consumption, _("Consumption"));
 
 	m_plot_economy =
@@ -201,7 +201,7 @@
 	m_plot_economy->set_plotmode(WUIPlot_Area::PLOTMODE_RELATIVE);
 
 	tabs->add
-		("economy_health", g_gr->imgcache().load(PicMod_UI, pic_tab_economy),
+		("economy_health", g_gr->images().get(pic_tab_economy),
 			m_plot_economy, _("Economy Health"));
 
 	m_plot_stock = new WUIPlot_Area
@@ -211,7 +211,7 @@
 	m_plot_stock->set_plotmode(WUIPlot_Area::PLOTMODE_ABSOLUTE);
 
 	tabs->add
-		("stock", g_gr->imgcache().load(PicMod_UI, pic_tab_stock),
+		("stock", g_gr->images().get(pic_tab_stock),
 			m_plot_stock, _("Stock"));
 
 	tabs->activate(0);
@@ -262,7 +262,7 @@
 		(new WUIPlot_Generic_Area_Slider
 			(this, *m_plot_production, this,
 			0, 0, 100, 45,
-			g_gr->imgcache().load(PicMod_UI, "pics/but1.png")),
+			g_gr->images().get("pics/but1.png")),
 		 UI::Box::AlignLeft, true);
 
 }

=== modified file 'src/wui/ware_statistics_menu.h'
--- src/wui/ware_statistics_menu.h	2012-11-18 17:33:18 +0000
+++ src/wui/ware_statistics_menu.h	2013-02-10 14:53:26 +0000
@@ -20,6 +20,7 @@
 #ifndef WARE_STATISTICS_MENU_H
 #define WARE_STATISTICS_MENU_H
 
+#include "logic/widelands.h"
 #include "ui_basic/unique_window.h"
 #include "plot_area.h"
 #include "differential_plot_area.h"
@@ -60,7 +61,7 @@
 		 WUIPlot_Area & plot_area,
 		 Ware_Statistics_Menu * signal_listener,
 		 const int32_t x, const int32_t y, const uint32_t w, const uint32_t h,
-		 const IPicture* background_picture_id,
+		 const Image* background_picture_id,
 		 const std::string & tooltip_text = std::string(),
 		 const uint32_t cursor_size = 20,
 		 const bool enabled = true)

=== modified file 'src/wui/warehousewindow.cc'
--- src/wui/warehousewindow.cc	2013-01-19 12:54:11 +0000
+++ src/wui/warehousewindow.cc	2013-02-10 14:53:26 +0000
@@ -18,6 +18,7 @@
  */
 
 #include "buildingwindow.h"
+#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "logic/player.h"
 #include "logic/playercommand.h"
@@ -69,12 +70,12 @@
 	WaresDisplay::draw_ware(dst, ware);
 
 	Warehouse::StockPolicy policy = m_warehouse.get_stock_policy(get_type(), ware);
-	const IPicture* pic;
+	const Image* pic;
 
 	switch (policy) {
-	case Warehouse::SP_Prefer: pic = g_gr->imgcache().load(PicMod_UI, pic_policy_prefer); break;
-	case Warehouse::SP_DontStock: pic = g_gr->imgcache().load(PicMod_UI, pic_policy_dontstock); break;
-	case Warehouse::SP_Remove: pic = g_gr->imgcache().load(PicMod_UI, pic_policy_remove); break;
+	case Warehouse::SP_Prefer: pic = g_gr->images().get(pic_policy_prefer); break;
+	case Warehouse::SP_DontStock: pic = g_gr->images().get(pic_policy_dontstock); break;
+	case Warehouse::SP_Remove: pic = g_gr->images().get(pic_policy_remove); break;
 	default:
 		// don't draw anything for the normal policy
 		return;
@@ -121,8 +122,8 @@
 #define ADD_POLICY_BUTTON(policy, policyname, tooltip)                                           \
 		b = new UI::Button                                                             \
 			(buttons, #policy, 0, 0, 34, 34,                                                  \
-			 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),                                   \
-			 g_gr->imgcache().load(PicMod_Game, "pics/stock_policy_button_" #policy ".png"),      \
+			 g_gr->images().get("pics/but4.png"),                                   \
+			 g_gr->images().get("pics/stock_policy_button_" #policy ".png"),      \
 			 tooltip),                                                                        \
 		b->sigclicked.connect \
 			(boost::bind(&WarehouseWaresPanel::set_policy, this, Warehouse::SP_##policyname)), \
@@ -184,7 +185,7 @@
 {
 	get_tabs()->add
 		("wares",
-		 g_gr->imgcache().load(PicMod_UI, pic_tab_wares),
+		 g_gr->images().get(pic_tab_wares),
 		 new WarehouseWaresPanel
 			(get_tabs(),
 			 Width,
@@ -194,7 +195,7 @@
 		 _("Wares"));
 	get_tabs()->add
 		("workers",
-		 g_gr->imgcache().load(PicMod_UI, pic_tab_workers),
+		 g_gr->images().get(pic_tab_workers),
 		 new WarehouseWaresPanel
 			(get_tabs(),
 			 Width,
@@ -206,12 +207,12 @@
 	if (Widelands::PortDock * pd = wh.get_portdock()) {
 		get_tabs()->add
 			("wares",
-			 g_gr->imgcache().load(PicMod_UI, pic_tab_dock_wares),
+			 g_gr->images().get(pic_tab_dock_wares),
 			 create_portdock_wares_display(get_tabs(), Width, *pd, Widelands::wwWARE),
 			 _("Wares in dock"));
 		get_tabs()->add
 			("workers",
-			 g_gr->imgcache().load(PicMod_UI, pic_tab_dock_workers),
+			 g_gr->images().get(pic_tab_dock_workers),
 			 create_portdock_wares_display(get_tabs(), Width, *pd, Widelands::wwWORKER),
 			 _("Workers in dock"));
 	}

=== modified file 'src/wui/waresdisplay.cc'
--- src/wui/waresdisplay.cc	2013-01-23 21:07:18 +0000
+++ src/wui/waresdisplay.cc	2013-02-10 14:53:26 +0000
@@ -21,17 +21,17 @@
 #include <boost/lexical_cast.hpp>
 #include <cstdio>
 
-#include "text_layout.h"
-#include "graphic/font.h"
 #include "graphic/font.h"
 #include "graphic/font_handler.h"
 #include "graphic/font_handler1.h"
+#include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "i18n.h"
 #include "logic/editor_game_base.h"
 #include "logic/player.h"
 #include "logic/tribe.h"
 #include "logic/worker.h"
+#include "text_layout.h"
 #include "wexception.h"
 
 #include "waresdisplay.h"
@@ -240,16 +240,13 @@
 	Point p = ware_position(id);
 
 	//  draw a background
-	const IPicture* bgpic =
-		g_gr->imgcache().load
-			(PicMod_Game,
-			 ware_selected(id) ?  "pics/ware_list_bg_selected.png"
-			                   :  "pics/ware_list_bg.png");
-	uint32_t w = bgpic->get_w();
+	const Image* bgpic =
+		g_gr->images().get(ware_selected(id) ?  "pics/ware_list_bg_selected.png" :  "pics/ware_list_bg.png");
+	uint16_t w = bgpic->width();
 
 	dst.blit(p, bgpic);
 
-	const IPicture* icon = m_type == Widelands::wwWORKER ? m_tribe.get_worker_descr(id)->icon()
+	const Image* icon = m_type == Widelands::wwWORKER ? m_tribe.get_worker_descr(id)->icon()
 		: m_tribe.get_ware_descr(id)->icon();
 
 	dst.blit(p + Point((w - WARE_MENU_PIC_WIDTH) / 2, 1), icon);
@@ -258,11 +255,11 @@
 		(Rect(p + Point(0, WARE_MENU_PIC_HEIGHT), w, WARE_MENU_INFO_SIZE),
 		 info_color_for_ware(id));
 
-	const IPicture* text = UI::g_fh1->render(as_waresinfo(info_for_ware(id)));
+	const Image* text = UI::g_fh1->render(as_waresinfo(info_for_ware(id)));
 	if (text) // might be zero when there is no info text.
 		dst.blit
 			(p + Point
-				(w - text->get_w() - 1, WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + 1 - text->get_h()), text);
+				(w - text->width() - 1, WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + 1 - text->height()), text);
 }
 
 // Wares highlighting/selecting

=== modified file 'src/wui/waresdisplay.h'
--- src/wui/waresdisplay.h	2013-01-23 21:07:18 +0000
+++ src/wui/waresdisplay.h	2013-02-10 14:53:26 +0000
@@ -26,8 +26,6 @@
 #include "logic/wareworker.h"
 #include "logic/tribe.h"
 
-#include "graphic/graphic.h"
-
 #include "ui_basic/textarea.h"
 
 #include <vector>

=== modified file 'src/wui/waresqueuedisplay.cc'
--- src/wui/waresqueuedisplay.cc	2013-01-05 18:52:13 +0000
+++ src/wui/waresqueuedisplay.cc	2013-02-10 14:53:26 +0000
@@ -23,6 +23,8 @@
 
 #include "economy/request.h"
 #include "economy/wares_queue.h"
+#include "graphic/graphic.h"
+#include "graphic/image_transformations.h"
 #include "graphic/rendertarget.h"
 #include "interactive_gamebase.h"
 #include "logic/player.h"
@@ -49,7 +51,7 @@
 m_decrease_max_fill(0),
 m_ware_index(queue->get_ware()),
 m_ware_type(Widelands::wwWARE),
-m_max_fill_indicator(g_gr->imgcache().load(PicMod_Game, pic_max_fill_indicator)),
+m_max_fill_indicator(g_gr->images().get(pic_max_fill_indicator)),
 m_cache_size(queue->get_max_size()),
 m_cache_filled(queue->get_filled()),
 m_cache_max_fill(queue->get_max_fill()),
@@ -61,16 +63,14 @@
 	set_tooltip(ware.descname().c_str());
 
 	m_icon = ware.icon();
-	m_icon_grey = g_gr->create_grayed_out_pic(m_icon);
-	m_icon_grey = g_gr->create_changed_luminosity_pic(m_icon_grey, 0.65);
+	m_icon_grey = ImageTransformations::change_luminosity(ImageTransformations::gray_out(m_icon), 0.65, false);
 
-	uint32_t ph = m_max_fill_indicator->get_h();
+	uint16_t ph = m_max_fill_indicator->height();
 
 	uint32_t priority_button_height = show_only ? 0 : 3 * PriorityButtonSize;
-	uint32_t picture_height = show_only ? WARE_MENU_PIC_HEIGHT :
-		std::max(WARE_MENU_PIC_HEIGHT, static_cast<int32_t>(ph));
+	uint32_t image_height = show_only ? WARE_MENU_PIC_HEIGHT : std::max<int32_t>(WARE_MENU_PIC_HEIGHT, ph);
 
-	m_total_height = std::max(priority_button_height, picture_height) + 2 * Border;
+	m_total_height = std::max(priority_button_height, image_height) + 2 * Border;
 
 	max_size_changed();
 
@@ -148,7 +148,7 @@
 		dst.blit(point, m_icon_grey);
 
 	if (not m_show_only) {
-		uint32_t pw = m_max_fill_indicator->get_w();
+		uint16_t pw = m_max_fill_indicator->width();
 		point.y = Border;
 		point.x = Border + CellWidth + CellSpacing +
 			(m_queue->get_max_fill() * (CellWidth + CellSpacing)) - CellSpacing / 2 - pw / 2;
@@ -172,16 +172,13 @@
 	pos.y = Border + (m_total_height - 2 * Border - 3 * PriorityButtonSize) / 2;
 
 	m_priority_radiogroup->add_button
-		(this, pos, g_gr->imgcache().load(PicMod_Game,  pic_priority_high),
-		 _("Highest priority"));
-	pos.y += PriorityButtonSize;
-	m_priority_radiogroup->add_button
-			(this, pos, g_gr->imgcache().load(PicMod_Game,  pic_priority_normal),
-			 _("Normal priority"));
-	pos.y += PriorityButtonSize;
-	m_priority_radiogroup->add_button
-			(this, pos, g_gr->imgcache().load(PicMod_Game,  pic_priority_low),
-			 _("Lowest priority"));
+		(this, pos, g_gr->images().get(pic_priority_high), _("Highest priority"));
+	pos.y += PriorityButtonSize;
+	m_priority_radiogroup->add_button
+			(this, pos, g_gr->images().get(pic_priority_normal), _("Normal priority"));
+	pos.y += PriorityButtonSize;
+	m_priority_radiogroup->add_button
+			(this, pos, g_gr->images().get(pic_priority_low), _("Lowest priority"));
 
 	int32_t priority = m_building.get_priority(m_ware_type, m_ware_index, false);
 	switch (priority) {
@@ -224,8 +221,8 @@
 	m_decrease_max_fill = new UI::Button
 		(this, "decrease_max_fill",
 		 x, y, WARE_MENU_PIC_WIDTH, WARE_MENU_PIC_HEIGHT,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_left.png"),
+		 g_gr->images().get("pics/but4.png"),
+		 g_gr->images().get("pics/scrollbar_left.png"),
 		 _("Decrease the number of wares you want to be stored here."));
 	m_decrease_max_fill->sigclicked.connect
 		(boost::bind(&WaresQueueDisplay::decrease_max_fill_clicked, boost::ref(*this)));
@@ -234,8 +231,8 @@
 	m_increase_max_fill = new UI::Button
 		(this, "increase_max_fill",
 		 x, y, WARE_MENU_PIC_WIDTH, WARE_MENU_PIC_HEIGHT,
-		 g_gr->imgcache().load(PicMod_UI, "pics/but4.png"),
-		 g_gr->imgcache().load(PicMod_UI, "pics/scrollbar_right.png"),
+		 g_gr->images().get("pics/but4.png"),
+		 g_gr->images().get("pics/scrollbar_right.png"),
 		 _("Increase the number of wares you want to be stored here."));
 	m_increase_max_fill->sigclicked.connect
 		(boost::bind(&WaresQueueDisplay::increase_max_fill_clicked, boost::ref(*this)));

=== modified file 'src/wui/waresqueuedisplay.h'
--- src/wui/waresqueuedisplay.h	2013-01-20 21:27:20 +0000
+++ src/wui/waresqueuedisplay.h	2013-02-10 14:53:26 +0000
@@ -75,9 +75,9 @@
 	UI::Button   * m_decrease_max_fill;
 	Widelands::Ware_Index   m_ware_index;
 	int32_t          m_ware_type;
-	const IPicture* m_icon;            //< Index to ware's picture
-	const IPicture* m_icon_grey;
-	const IPicture* m_max_fill_indicator;
+	const Image* m_icon;            //< Index to ware's picture
+	const Image* m_icon_grey;
+	const Image* m_max_fill_indicator;
 
 
 	uint32_t         m_cache_size;

=== modified file 'src/wui/watchwindow.cc'
--- src/wui/watchwindow.cc	2012-12-13 10:41:22 +0000
+++ src/wui/watchwindow.cc	2013-02-10 14:53:26 +0000
@@ -106,8 +106,8 @@
 		new UI::Button
 			(this, "follow",
 			 0, h - 34, 34, 34,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-			 g_gr->imgcache().load(PicMod_UI, "pics/menu_watch_follow.png"),
+			 g_gr->images().get("pics/but0.png"),
+			 g_gr->images().get("pics/menu_watch_follow.png"),
 			 _("Follow"));
 	followbtn->sigclicked.connect(boost::bind(&WatchWindow::do_follow, this));
 
@@ -115,8 +115,8 @@
 		new UI::Button
 			(this, "center_mainview_here",
 			 34, h - 34, 34, 34,
-			 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-			 g_gr->imgcache().load(PicMod_UI, "pics/menu_goto.png"),
+			 g_gr->images().get("pics/but0.png"),
+			 g_gr->images().get("pics/menu_goto.png"),
 			 _("Center mainview on this"));
 	gotobtn->sigclicked.connect(boost::bind(&WatchWindow::do_goto, this));
 
@@ -126,7 +126,7 @@
 				new UI::Button
 					(this, "view",
 					 74 + (17 * i), 200 - 34, 17, 34,
-					 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
+					 g_gr->images().get("pics/but0.png"),
 					 "-", std::string(),
 					 false);
 			view_btns[i]->sigclicked.connect
@@ -137,8 +137,8 @@
 			new UI::Button
 				(this, "close",
 				 w - 34, h - 34, 34, 34,
-				 g_gr->imgcache().load(PicMod_UI, "pics/but0.png"),
-				 g_gr->imgcache().load(PicMod_UI, "pics/menu_abort.png"),
+				 g_gr->images().get("pics/but0.png"),
+				 g_gr->images().get("pics/menu_abort.png"),
 				 _("Close"));
 		closebtn->sigclicked.connect(boost::bind(&WatchWindow::close_cur_view, this));
 	}


Follow ups