Преглед изворни кода

Changes to Canvas class according to review:

- renamed CCanvas -> Canvas.cpp
- replaced shared_ptr<Canvas> with Canvas&
- removed getSurface method
Ivan Savenko пре 3 година
родитељ
комит
7f5e5259c8

+ 2 - 2
client/CMakeLists.txt

@@ -17,7 +17,7 @@ set(client_SRCS
 		battle/CreatureAnimation.cpp
 
 		gui/CAnimation.cpp
-		gui/CCanvas.cpp
+		gui/Canvas.cpp
 		gui/CCursorHandler.cpp
 		gui/CGuiHandler.cpp
 		gui/CIntObject.cpp
@@ -100,7 +100,7 @@ set(client_HEADERS
 		battle/CreatureAnimation.h
 
 		gui/CAnimation.h
-		gui/CCanvas.h
+		gui/Canvas.h
 		gui/CCursorHandler.h
 		gui/CGuiHandler.h
 		gui/CIntObject.h

+ 2 - 2
client/battle/BattleEffectsController.cpp

@@ -22,7 +22,7 @@
 #include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CAnimation.h"
-#include "../gui/CCanvas.h"
+#include "../gui/Canvas.h"
 
 #include "../../CCallback.h"
 #include "../../lib/battle/BattleAction.h"
@@ -134,7 +134,7 @@ void BattleEffectsController::collectRenderableObjects(BattleRenderer & renderer
 
 			auto img = elem.animation->getImage(currentFrame);
 
-			canvas->draw(img, Point(elem.x, elem.y));
+			canvas.draw(img, Point(elem.x, elem.y));
 		});
 	}
 }

+ 1 - 1
client/battle/BattleEffectsController.h

@@ -21,7 +21,7 @@ VCMI_LIB_NAMESPACE_END
 
 struct SDL_Surface;
 class CAnimation;
-class CCanvas;
+class Canvas;
 class BattleInterface;
 class BattleRenderer;
 class CPointEffectAnimation;

+ 17 - 17
client/battle/BattleFieldController.cpp

@@ -23,7 +23,7 @@
 #include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CAnimation.h"
-#include "../gui/CCanvas.h"
+#include "../gui/Canvas.h"
 #include "../gui/CGuiHandler.h"
 #include "../gui/CCursorHandler.h"
 
@@ -61,7 +61,7 @@ BattleFieldController::BattleFieldController(BattleInterface * owner):
 	}
 
 	//preparing graphic with cell borders
-	cellBorders = std::make_shared<CCanvas>(Point(background->width(), background->height()));
+	cellBorders = std::make_unique<Canvas>(Point(background->width(), background->height()));
 
 	for (int i=0; i<GameConstants::BFIELD_SIZE; ++i)
 	{
@@ -73,7 +73,7 @@ BattleFieldController::BattleFieldController(BattleInterface * owner):
 		cellBorders->draw(cellBorder, hexPositionLocal(i).topLeft());
 	}
 
-	backgroundWithHexes = std::make_shared<CCanvas>(Point(background->width(), background->height()));
+	backgroundWithHexes = std::make_unique<Canvas>(Point(background->width(), background->height()));
 
 	for (int h = 0; h < GameConstants::BFIELD_SIZE; ++h)
 	{
@@ -89,7 +89,7 @@ BattleFieldController::BattleFieldController(BattleInterface * owner):
 		stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE);
 }
 
-void BattleFieldController::renderBattlefield(std::shared_ptr<CCanvas> canvas)
+void BattleFieldController::renderBattlefield(Canvas & canvas)
 {
 	showBackground(canvas);
 
@@ -100,7 +100,7 @@ void BattleFieldController::renderBattlefield(std::shared_ptr<CCanvas> canvas)
 	owner->projectilesController->showProjectiles(canvas);
 }
 
-void BattleFieldController::showBackground(std::shared_ptr<CCanvas> canvas)
+void BattleFieldController::showBackground(Canvas & canvas)
 {
 	if (owner->stacksController->getActiveStack() != nullptr ) //&& creAnims[stacksController->getActiveStack()->ID]->isIdle() //show everything with range
 		showBackgroundImageWithHexes(canvas);
@@ -111,21 +111,21 @@ void BattleFieldController::showBackground(std::shared_ptr<CCanvas> canvas)
 
 }
 
-void BattleFieldController::showBackgroundImage(std::shared_ptr<CCanvas> canvas)
+void BattleFieldController::showBackgroundImage(Canvas & canvas)
 {
-	canvas->draw(background, owner->pos.topLeft());
+	canvas.draw(background, owner->pos.topLeft());
 
 	owner->obstacleController->showAbsoluteObstacles(canvas, pos.topLeft());
 	if ( owner->siegeController )
 		owner->siegeController->showAbsoluteObstacles(canvas, pos.topLeft());
 
 	if (settings["battle"]["cellBorders"].Bool())
-		canvas->draw(cellBorders, owner->pos.topLeft());
+		canvas.draw(*cellBorders, owner->pos.topLeft());
 }
 
-void BattleFieldController::showBackgroundImageWithHexes(std::shared_ptr<CCanvas> canvas)
+void BattleFieldController::showBackgroundImageWithHexes(Canvas & canvas)
 {
-	canvas->draw(backgroundWithHexes, owner->pos.topLeft());
+	canvas.draw(*backgroundWithHexes.get(), owner->pos.topLeft());
 }
 
 void BattleFieldController::redrawBackgroundWithHexes()
@@ -142,9 +142,9 @@ void BattleFieldController::redrawBackgroundWithHexes()
 
 	//prepare background graphic with hexes and shaded hexes
 	backgroundWithHexes->draw(background, Point(0,0));
-	owner->obstacleController->showAbsoluteObstacles(backgroundWithHexes, Point(0,0));
+	owner->obstacleController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0));
 	if ( owner->siegeController )
-		owner->siegeController->showAbsoluteObstacles(backgroundWithHexes, Point(0,0));
+		owner->siegeController->showAbsoluteObstacles(*backgroundWithHexes, Point(0,0));
 
 	if (settings["battle"]["stackRange"].Bool())
 	{
@@ -157,16 +157,16 @@ void BattleFieldController::redrawBackgroundWithHexes()
 	}
 
 	if(settings["battle"]["cellBorders"].Bool())
-		backgroundWithHexes->draw(cellBorders, Point(0, 0));
+		backgroundWithHexes->draw(*cellBorders, Point(0, 0));
 }
 
-void BattleFieldController::showHighlightedHex(std::shared_ptr<CCanvas> to, BattleHex hex, bool darkBorder)
+void BattleFieldController::showHighlightedHex(Canvas & canvas, BattleHex hex, bool darkBorder)
 {
 	Point hexPos = hexPosition(hex).topLeft();
 
-	to->draw(cellShade, hexPos);
+	canvas.draw(cellShade, hexPos);
 	if(!darkBorder && settings["battle"]["cellBorders"].Bool())
-		to->draw(cellBorder, hexPos);
+		canvas.draw(cellBorder, hexPos);
 }
 
 std::set<BattleHex> BattleFieldController::getHighlightedHexesStackRange()
@@ -242,7 +242,7 @@ std::set<BattleHex> BattleFieldController::getHighlightedHexesSpellRange()
 	return result;
 }
 
-void BattleFieldController::showHighlightedHexes(std::shared_ptr<CCanvas> canvas)
+void BattleFieldController::showHighlightedHexes(Canvas & canvas)
 {
 	std::set<BattleHex> hoveredStack = getHighlightedHexesStackRange();
 	std::set<BattleHex> hoveredMouse = getHighlightedHexesSpellRange();

+ 9 - 9
client/battle/BattleFieldController.h

@@ -23,7 +23,7 @@ struct Rect;
 struct Point;
 
 class ClickableHex;
-class CCanvas;
+class Canvas;
 class IImage;
 class BattleInterface;
 
@@ -35,10 +35,10 @@ class BattleFieldController : public CIntObject
 	std::shared_ptr<IImage> cellBorder;
 	std::shared_ptr<IImage> cellShade;
 
-	std::shared_ptr<CCanvas> cellBorders;
+	std::unique_ptr<Canvas> cellBorders;
 
 	/// Canvas that contains background, hex grid (if enabled), absolute obstacles and movement range of active stack
-	std::shared_ptr<CCanvas> backgroundWithHexes;
+	std::unique_ptr<Canvas> backgroundWithHexes;
 
 	//BattleHex previouslyHoveredHex; //number of hex that was hovered by the cursor a while ago
 	//BattleHex currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon)
@@ -49,21 +49,21 @@ class BattleFieldController : public CIntObject
 
 	std::vector<std::shared_ptr<ClickableHex>> bfield; //11 lines, 17 hexes on each
 
-	void showHighlightedHex(std::shared_ptr<CCanvas> to, BattleHex hex, bool darkBorder);
+	void showHighlightedHex(Canvas & to, BattleHex hex, bool darkBorder);
 
 	std::set<BattleHex> getHighlightedHexesStackRange();
 	std::set<BattleHex> getHighlightedHexesSpellRange();
 
-	void showBackground(std::shared_ptr<CCanvas> canvas);
-	void showBackgroundImage(std::shared_ptr<CCanvas> canvas);
-	void showBackgroundImageWithHexes(std::shared_ptr<CCanvas> canvas);
-	void showHighlightedHexes(std::shared_ptr<CCanvas> canvas);
+	void showBackground(Canvas & canvas);
+	void showBackgroundImage(Canvas & canvas);
+	void showBackgroundImageWithHexes(Canvas & canvas);
+	void showHighlightedHexes(Canvas & canvas);
 
 public:
 	BattleFieldController(BattleInterface * owner);
 
 	void redrawBackgroundWithHexes();
-	void renderBattlefield(std::shared_ptr<CCanvas> canvas);
+	void renderBattlefield(Canvas & canvas);
 
 	Rect hexPositionLocal(BattleHex hex) const;
 	Rect hexPosition(BattleHex hex) const;

+ 10 - 10
client/battle/BattleInterface.cpp

@@ -27,7 +27,7 @@
 #include "../CMessage.h"
 #include "../CMusicHandler.h"
 #include "../CPlayerInterface.h"
-#include "../gui/CCanvas.h"
+#include "../gui/Canvas.h"
 #include "../gui/CCursorHandler.h"
 #include "../gui/CGuiHandler.h"
 #include "../windows/CAdvmapInterface.h"
@@ -891,7 +891,7 @@ void BattleInterface::showAll(SDL_Surface *to)
 
 void BattleInterface::show(SDL_Surface *to)
 {
-	auto canvas = std::make_shared<CCanvas>(to);
+	Canvas canvas(to);
 	assert(to);
 
 	SDL_Rect buf;
@@ -907,7 +907,7 @@ void BattleInterface::show(SDL_Surface *to)
 
 	SDL_SetClipRect(to, &buf); //restoring previous clip_rect
 
-	showInterface(canvas);
+	showInterface(to);
 
 	//activation of next stack, if any
 	//TODO: should be moved to the very start of this method?
@@ -920,23 +920,23 @@ void BattleInterface::collectRenderableObjects(BattleRenderer & renderer)
 	{
 		renderer.insert(EBattleFieldLayer::HEROES, BattleHex(0),[this](BattleRenderer::RendererPtr canvas)
 		{
-			attackingHero->show(canvas->getSurface());
+			attackingHero->render(canvas);
 		});
 	}
 	if (defendingHero)
 	{
 		renderer.insert(EBattleFieldLayer::HEROES, BattleHex(GameConstants::BFIELD_WIDTH-1),[this](BattleRenderer::RendererPtr canvas)
 		{
-			defendingHero->show(canvas->getSurface());
+			defendingHero->render(canvas);
 		});
 	}
 }
 
-void BattleInterface::showInterface(std::shared_ptr<CCanvas> canvas)
+void BattleInterface::showInterface(SDL_Surface * to)
 {
 	//showing in-game console
-	LOCPLINT->cingconsole->show(canvas->getSurface());
-	controlPanel->showAll(canvas->getSurface());
+	LOCPLINT->cingconsole->show(to);
+	controlPanel->showAll(to);
 
 	Rect posWithQueue = Rect(pos.x, pos.y, 800, 600);
 
@@ -948,13 +948,13 @@ void BattleInterface::showInterface(std::shared_ptr<CCanvas> canvas)
 			posWithQueue.h += queue->pos.h;
 		}
 
-		queue->showAll(canvas->getSurface());
+		queue->showAll(to);
 	}
 
 	//printing border around interface
 	if (screen->w != 800 || screen->h !=600)
 	{
-		CMessage::drawBorder(curInt->playerID,canvas->getSurface(),posWithQueue.w + 28, posWithQueue.h + 28, posWithQueue.x-14, posWithQueue.y-15);
+		CMessage::drawBorder(curInt->playerID,to,posWithQueue.w + 28, posWithQueue.h + 28, posWithQueue.x-14, posWithQueue.y-15);
 	}
 }
 

+ 2 - 2
client/battle/BattleInterface.h

@@ -33,7 +33,7 @@ struct CustomEffectInfo;
 VCMI_LIB_NAMESPACE_END
 
 class BattleHero;
-class CCanvas;
+class Canvas;
 class BattleResultWindow;
 class StackQueue;
 class CPlayerInterface;
@@ -98,7 +98,7 @@ private:
 
 	const CGHeroInstance *getActiveHero(); //returns hero that can currently cast a spell
 
-	void showInterface(std::shared_ptr<CCanvas> canvas);
+	void showInterface(SDL_Surface * to);
 
 	void setHeroAnimation(ui8 side, int phase);
 public:

+ 8 - 24
client/battle/BattleInterfaceClasses.cpp

@@ -24,6 +24,7 @@
 #include "../CVideoHandler.h"
 #include "../Graphics.h"
 #include "../gui/CAnimation.h"
+#include "../gui/Canvas.h"
 #include "../gui/CCursorHandler.h"
 #include "../gui/CGuiHandler.h"
 #include "../widgets/Buttons.h"
@@ -126,7 +127,7 @@ void BattleConsole::lock(bool shouldLock)
 	// no-op?
 }
 
-void BattleHero::show(SDL_Surface * to)
+void BattleHero::render(Canvas & canvas)
 {
 	auto flagFrame = flagAnimation->getImage(flagAnim, 0, true);
 
@@ -134,35 +135,18 @@ void BattleHero::show(SDL_Surface * to)
 		return;
 
 	//animation of flag
-	SDL_Rect temp_rect;
-	if(flip)
-	{
-		temp_rect = genRect(
-			flagFrame->height(),
-			flagFrame->width(),
-			pos.x + 61,
-			pos.y + 39);
+	Point flagPosition = pos.topLeft();
 
-	}
+	if(flip)
+		flagPosition += Point(61, 39);
 	else
-	{
-		temp_rect = genRect(
-			flagFrame->height(),
-			flagFrame->width(),
-			pos.x + 72,
-			pos.y + 39);
-	}
+		flagPosition += Point(72, 39);
 
-	flagFrame->draw(screen, &temp_rect, nullptr); //FIXME: why screen?
-
-	//animation of hero
-	SDL_Rect rect = pos;
 
 	auto heroFrame = animation->getImage(currentFrame, phase, true);
-	if(!heroFrame)
-		return;
 
-	heroFrame->draw(to, &rect, nullptr);
+	canvas.draw(flagFrame, flagPosition);
+	canvas.draw(heroFrame, pos.topLeft());
 
 	if(++animCount >= 4)
 	{

+ 2 - 1
client/battle/BattleInterfaceClasses.h

@@ -18,6 +18,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 class CGHeroInstance;
 struct BattleResult;
 class CStack;
+class Canvas;
 
 namespace battle
 {
@@ -79,7 +80,7 @@ public:
 
 	size_t flagAnim;
 	ui8 animCount; //for flag animation
-	void show(SDL_Surface * to) override; //prints next frame of animation to to
+	void render(Canvas & canvas); //prints next frame of animation to to
 	void setPhase(int newPhase); //sets phase of hero animation
 	void hover(bool on) override;
 	void clickLeft(tribool down, bool previousState) override; //call-in

+ 4 - 4
client/battle/BattleObstacleController.cpp

@@ -18,7 +18,7 @@
 
 #include "../CPlayerInterface.h"
 #include "../gui/CAnimation.h"
-#include "../gui/CCanvas.h"
+#include "../gui/Canvas.h"
 
 #include "../../CCallback.h"
 #include "../../lib/battle/CObstacleInstance.h"
@@ -113,7 +113,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
 	}
 }
 
-void BattleObstacleController::showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset)
+void BattleObstacleController::showAbsoluteObstacles(Canvas & canvas, const Point & offset)
 {
 	//Blit absolute obstacles
 	for(auto & oi : owner->curInt->cb->battleGetAllObstacles())
@@ -122,7 +122,7 @@ void BattleObstacleController::showAbsoluteObstacles(std::shared_ptr<CCanvas> ca
 		{
 			auto img = getObstacleImage(*oi);
 			if(img)
-				canvas->draw(img, Point(offset.x + oi->getInfo().width, offset.y + oi->getInfo().height));
+				canvas.draw(img, Point(offset.x + oi->getInfo().width, offset.y + oi->getInfo().height));
 		}
 	}
 }
@@ -142,7 +142,7 @@ void BattleObstacleController::collectRenderableObjects(BattleRenderer & rendere
 			if(img)
 			{
 				Point p = getObstaclePosition(img, *obstacle);
-				canvas->draw(img, p);
+				canvas.draw(img, p);
 			}
 		});
 	}

+ 2 - 2
client/battle/BattleObstacleController.h

@@ -18,7 +18,7 @@ VCMI_LIB_NAMESPACE_END
 
 struct SDL_Surface;
 class IImage;
-class CCanvas;
+class Canvas;
 class CAnimation;
 class BattleInterface;
 class BattleRenderer;
@@ -46,7 +46,7 @@ public:
 
 	void obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> & oi);
 	void showObstacles(SDL_Surface *to, std::vector<std::shared_ptr<const CObstacleInstance>> &obstacles);
-	void showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset);
+	void showAbsoluteObstacles(Canvas & canvas, const Point & offset);
 
 	void collectRenderableObjects(BattleRenderer & renderer);
 };

+ 10 - 10
client/battle/BattleProjectileController.cpp

@@ -17,7 +17,7 @@
 
 #include "../gui/Geometries.h"
 #include "../gui/CAnimation.h"
-#include "../gui/CCanvas.h"
+#include "../gui/Canvas.h"
 #include "../gui/CGuiHandler.h"
 #include "../CGameInfo.h"
 
@@ -46,7 +46,7 @@ static double calculateCatapultParabolaY(const Point & from, const Point & dest,
 	return facA *pow(x, 2.0) + facB *x + facC;
 }
 
-void ProjectileMissile::show(std::shared_ptr<CCanvas> canvas)
+void ProjectileMissile::show(Canvas & canvas)
 {
 	logAnim->info("Projectile rendering, %d / %d", step, steps);
 	size_t group = reverse ? 1 : 0;
@@ -61,12 +61,12 @@ void ProjectileMissile::show(std::shared_ptr<CCanvas> canvas)
 			CSDL_Ext::lerp(from.y, dest.y, progress) - image->height() / 2,
 		};
 
-		canvas->draw(image, pos);
+		canvas.draw(image, pos);
 	}
 	++step;
 }
 
-void ProjectileAnimatedMissile::show(std::shared_ptr<CCanvas> canvas)
+void ProjectileAnimatedMissile::show(Canvas & canvas)
 {
 	ProjectileMissile::show(canvas);
 	frameProgress += AnimationControls::getSpellEffectSpeed() * GH.mainFPSmng->getElapsedMilliseconds() / 1000;
@@ -77,7 +77,7 @@ void ProjectileAnimatedMissile::show(std::shared_ptr<CCanvas> canvas)
 	frameNum = std::floor(frameProgress);
 }
 
-void ProjectileCatapult::show(std::shared_ptr<CCanvas> canvas)
+void ProjectileCatapult::show(Canvas & canvas)
 {
 	auto image = animation->getImage(frameNum, 0, true);
 
@@ -89,14 +89,14 @@ void ProjectileCatapult::show(std::shared_ptr<CCanvas> canvas)
 		int posY = calculateCatapultParabolaY(from, dest, posX);
 		Point pos(posX, posY);
 
-		canvas->draw(image, pos);
+		canvas.draw(image, pos);
 
 		frameNum = (frameNum + 1) % animation->size(0);
 	}
 	++step;
 }
 
-void ProjectileRay::show(std::shared_ptr<CCanvas> canvas)
+void ProjectileRay::show(Canvas & canvas)
 {
 	float progress = float(step) / steps;
 
@@ -123,7 +123,7 @@ void ProjectileRay::show(std::shared_ptr<CCanvas> canvas)
 			SDL_Color beginColor{ ray.r1, ray.g1, ray.b1, ray.a1};
 			SDL_Color endColor  { ray.r2, ray.g2, ray.b2, ray.a2};
 
-			canvas->drawLine(Point(x1, y1 + i), Point(x2, y2+i), beginColor, endColor);
+			canvas.drawLine(Point(x1, y1 + i), Point(x2, y2+i), beginColor, endColor);
 		}
 	}
 	else // draw in vertical axis
@@ -140,7 +140,7 @@ void ProjectileRay::show(std::shared_ptr<CCanvas> canvas)
 			SDL_Color beginColor{ ray.r1, ray.g1, ray.b1, ray.a1};
 			SDL_Color endColor  { ray.r2, ray.g2, ray.b2, ray.a2};
 
-			canvas->drawLine(Point(x1 + i, y1), Point(x2 + i, y2), beginColor, endColor);
+			canvas.drawLine(Point(x1 + i, y1), Point(x2 + i, y2), beginColor, endColor);
 		}
 	}
 	++step;
@@ -223,7 +223,7 @@ void BattleProjectileController::emitStackProjectile(const CStack * stack)
 	}
 }
 
-void BattleProjectileController::showProjectiles(std::shared_ptr<CCanvas> canvas)
+void BattleProjectileController::showProjectiles(Canvas & canvas)
 {
 	for ( auto it = projectiles.begin(); it != projectiles.end();)
 	{

+ 8 - 8
client/battle/BattleProjectileController.h

@@ -22,14 +22,14 @@ VCMI_LIB_NAMESPACE_END
 struct Point;
 struct SDL_Surface;
 class CAnimation;
-class CCanvas;
+class Canvas;
 class BattleInterface;
 
 /// Small struct which contains information about the position and the velocity of a projectile
 struct ProjectileBase
 {
 	virtual ~ProjectileBase() = default;
-	virtual void show(std::shared_ptr<CCanvas> canvas) =  0;
+	virtual void show(Canvas & canvas) =  0;
 
 	Point from; // initial position on the screen
 	Point dest; // target position on the screen
@@ -42,7 +42,7 @@ struct ProjectileBase
 
 struct ProjectileMissile : ProjectileBase
 {
-	void show(std::shared_ptr<CCanvas> canvas) override;
+	void show(Canvas & canvas) override;
 
 	std::shared_ptr<CAnimation> animation;
 	int frameNum;  // frame to display from projectile animation
@@ -51,13 +51,13 @@ struct ProjectileMissile : ProjectileBase
 
 struct ProjectileAnimatedMissile : ProjectileMissile
 {
-	void show(std::shared_ptr<CCanvas> canvas) override;
+	void show(Canvas & canvas) override;
 	float frameProgress;
 };
 
 struct ProjectileCatapult : ProjectileBase
 {
-	void show(std::shared_ptr<CCanvas> canvas) override;
+	void show(Canvas & canvas) override;
 
 	std::shared_ptr<CAnimation> animation;
 	int frameNum;  // frame to display from projectile animation
@@ -65,7 +65,7 @@ struct ProjectileCatapult : ProjectileBase
 
 struct ProjectileRay : ProjectileBase
 {
-	void show(std::shared_ptr<CCanvas> canvas) override;
+	void show(Canvas & canvas) override;
 
 	std::vector<CCreature::CreatureAnimation::RayColor> rayConfig;
 };
@@ -90,7 +90,7 @@ class BattleProjectileController
 	bool stackUsesRayProjectile(const CStack * stack);
 	bool stackUsesMissileProjectile(const CStack * stack);
 
-	void showProjectile(std::shared_ptr<CCanvas> canvas, std::shared_ptr<ProjectileBase> projectile);
+	void showProjectile(Canvas & canvas, std::shared_ptr<ProjectileBase> projectile);
 
 	const CCreature * getShooter(const CStack * stack);
 
@@ -99,7 +99,7 @@ class BattleProjectileController
 public:
 	BattleProjectileController(BattleInterface * owner);
 
-	void showProjectiles(std::shared_ptr<CCanvas> canvas);
+	void showProjectiles(Canvas & canvas);
 
 	bool hasActiveProjectile(const CStack * stack);
 	void emitStackProjectile(const CStack * stack);

+ 2 - 2
client/battle/BattleRenderer.h

@@ -22,7 +22,7 @@ VCMI_LIB_NAMESPACE_END
 //struct Point;
 //
 //class CClickableHex;
-class CCanvas;
+class Canvas;
 //class IImage;
 class BattleInterface;
 
@@ -41,7 +41,7 @@ enum class EBattleFieldLayer {
 class BattleRenderer
 {
 public:
-	using RendererPtr = std::shared_ptr<CCanvas>;
+	using RendererPtr = Canvas &;
 	using RenderFunctor = std::function<void(RendererPtr)>;
 
 private:

+ 4 - 4
client/battle/BattleSiegeController.cpp

@@ -21,7 +21,7 @@
 #include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CAnimation.h"
-#include "../gui/CCanvas.h"
+#include "../gui/Canvas.h"
 
 #include "../../CCallback.h"
 #include "../../lib/NetPacks.h"
@@ -106,13 +106,13 @@ std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisua
 	}
 }
 
-void BattleSiegeController::showWallPiece(std::shared_ptr<CCanvas> canvas, EWallVisual::EWallVisual what, const Point & offset)
+void BattleSiegeController::showWallPiece(Canvas & canvas, EWallVisual::EWallVisual what, const Point & offset)
 {
 	auto & ci = town->town->clientInfo;
 	auto const & pos = ci.siegePositions[what];
 
 	if ( wallPieceImages[what])
-		canvas->draw(wallPieceImages[what], offset + Point(pos.x, pos.y));
+		canvas.draw(wallPieceImages[what], offset + Point(pos.x, pos.y));
 }
 
 std::string BattleSiegeController::getBattleBackgroundName() const
@@ -249,7 +249,7 @@ void BattleSiegeController::gateStateChanged(const EGateState state)
 		CCS->soundh->playSound(soundBase::DRAWBRG);
 }
 
-void BattleSiegeController::showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset)
+void BattleSiegeController::showAbsoluteObstacles(Canvas & canvas, const Point & offset)
 {
 	if (getWallPieceExistance(EWallVisual::MOAT))
 		showWallPiece(canvas, EWallVisual::MOAT, offset);

+ 3 - 3
client/battle/BattleSiegeController.h

@@ -23,7 +23,7 @@ VCMI_LIB_NAMESPACE_END
 
 struct Point;
 struct SDL_Surface;
-class CCanvas;
+class Canvas;
 class BattleInterface;
 class BattleRenderer;
 class IImage;
@@ -85,7 +85,7 @@ class BattleSiegeController
 	/// returns true if chosen wall piece should be present in current battle
 	bool getWallPieceExistance(EWallVisual::EWallVisual what) const;
 
-	void showWallPiece(std::shared_ptr<CCanvas> canvas, EWallVisual::EWallVisual what, const Point & offset);
+	void showWallPiece(Canvas & canvas, EWallVisual::EWallVisual what, const Point & offset);
 
 	BattleHex getTurretBattleHex(EWallVisual::EWallVisual wallPiece) const;
 	const CStack * getTurretStack(EWallVisual::EWallVisual wallPiece) const;
@@ -98,7 +98,7 @@ public:
 	void stackIsCatapulting(const CatapultAttack & ca);
 
 	/// call-ins from other battle controllers
-	void showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset);
+	void showAbsoluteObstacles(Canvas & canvas, const Point & offset);
 	void collectRenderableObjects(BattleRenderer & renderer);
 
 	/// queries from other battle controllers

+ 5 - 5
client/battle/BattleStacksController.cpp

@@ -26,7 +26,7 @@
 #include "../CGameInfo.h"
 #include "../gui/CAnimation.h"
 #include "../gui/CGuiHandler.h"
-#include "../gui/CCanvas.h"
+#include "../gui/Canvas.h"
 
 #include "../../CCallback.h"
 #include "../../lib/battle/BattleHex.h"
@@ -302,7 +302,7 @@ std::shared_ptr<IImage> BattleStacksController::getStackAmountBox(const CStack *
 	return amountEffNeutral;
 }
 
-void BattleStacksController::showStackAmountBox(std::shared_ptr<CCanvas> canvas, const CStack * stack)
+void BattleStacksController::showStackAmountBox(Canvas & canvas, const CStack * stack)
 {
 	//blitting amount background box
 	auto amountBG = getStackAmountBox(stack);
@@ -318,15 +318,15 @@ void BattleStacksController::showStackAmountBox(std::shared_ptr<CCanvas> canvas,
 			(moveInside ? amountBG->width() + 10 : 0) * reverseSideShift;
 	int yAdd = 260 + ((stack->side == BattleSide::ATTACKER || moveInside) ? 0 : -15);
 
-	canvas->draw(amountBG, stackAnimation[stack->ID]->pos.topLeft() + Point(xAdd, yAdd));
+	canvas.draw(amountBG, stackAnimation[stack->ID]->pos.topLeft() + Point(xAdd, yAdd));
 
 	//blitting amount
 	Point textPos = stackAnimation[stack->ID]->pos.topLeft() + amountBG->dimensions()/2 + Point(xAdd, yAdd);
 
-	canvas->drawText(textPos, EFonts::FONT_TINY, Colors::WHITE, ETextAlignment::CENTER, makeNumberShort(stack->getCount()));
+	canvas.drawText(textPos, EFonts::FONT_TINY, Colors::WHITE, ETextAlignment::CENTER, makeNumberShort(stack->getCount()));
 }
 
-void BattleStacksController::showStack(std::shared_ptr<CCanvas> canvas, const CStack * stack)
+void BattleStacksController::showStack(Canvas & canvas, const CStack * stack)
 {
 	stackAnimation[stack->ID]->nextFrame(canvas, facingRight(stack)); // do actual blit
 	stackAnimation[stack->ID]->incrementFrame(float(GH.mainFPSmng->getElapsedMilliseconds()) / 1000);

+ 4 - 4
client/battle/BattleStacksController.h

@@ -23,7 +23,7 @@ VCMI_LIB_NAMESPACE_END
 struct SDL_Surface;
 struct StackAttackedInfo;
 
-class CCanvas;
+class Canvas;
 class BattleInterface;
 class CBattleAnimation;
 class CreatureAnimation;
@@ -55,7 +55,7 @@ class BattleStacksController
 	ui32 animIDhelper; //for giving IDs for animations
 
 	bool stackNeedsAmountBox(const CStack * stack);
-	void showStackAmountBox(std::shared_ptr<CCanvas> canvas, const CStack * stack);
+	void showStackAmountBox(Canvas & canvas, const CStack * stack);
 	BattleHex getStackCurrentPosition(const CStack * stack);
 
 	std::shared_ptr<IImage> getStackAmountBox(const CStack * stack);
@@ -86,8 +86,8 @@ public:
 	void setHoveredStack(const CStack *stack);
 	void setSelectedStack(const CStack *stack);
 
-	void showAliveStack(std::shared_ptr<CCanvas> canvas, const CStack * stack);
-	void showStack(std::shared_ptr<CCanvas> canvas, const CStack * stack);
+	void showAliveStack(Canvas & canvas, const CStack * stack);
+	void showStack(Canvas & canvas, const CStack * stack);
 
 	void collectRenderableObjects(BattleRenderer & renderer);
 

+ 3 - 3
client/battle/CreatureAnimation.cpp

@@ -13,7 +13,7 @@
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/CCreatureHandler.h"
 
-#include "../gui/CCanvas.h"
+#include "../gui/Canvas.h"
 
 static const SDL_Color creatureBlueBorder = { 0, 255, 255, 255 };
 static const SDL_Color creatureGoldBorder = { 255, 255, 0, 255 };
@@ -301,7 +301,7 @@ void CreatureAnimation::genBorderPalette(IImage::BorderPallete & target)
 	target[2] = addColors(genShadow(64),  genBorderColor(getBorderStrength(elapsedTime), border));
 }
 
-void CreatureAnimation::nextFrame(std::shared_ptr<CCanvas> canvas, bool facingRight)
+void CreatureAnimation::nextFrame(Canvas & canvas, bool facingRight)
 {
 	size_t frame = static_cast<size_t>(floor(currentFrame));
 
@@ -319,7 +319,7 @@ void CreatureAnimation::nextFrame(std::shared_ptr<CCanvas> canvas, bool facingRi
 
 		image->setBorderPallete(borderPallete);
 
-		canvas->draw(image, pos.topLeft(), Rect(0, 0, pos.w, pos.h));
+		canvas.draw(image, pos.topLeft(), Rect(0, 0, pos.w, pos.h));
 	}
 }
 

+ 2 - 2
client/battle/CreatureAnimation.h

@@ -15,7 +15,7 @@
 
 class CIntObject;
 class CreatureAnimation;
-class CCanvas;
+class Canvas;
 
 /// Namespace for some common controls of animations
 namespace AnimationControls
@@ -102,7 +102,7 @@ public:
 	void setType(CCreatureAnim::EAnimType type); //sets type of animation and cleares framecount
 	CCreatureAnim::EAnimType getType() const; //returns type of animation
 
-	void nextFrame(std::shared_ptr<CCanvas> canvas, bool facingRight);
+	void nextFrame(Canvas & canvas, bool facingRight);
 
 	// should be called every frame, return true when animation was reset to beginning
 	bool incrementFrame(float timePassed);

+ 9 - 12
client/gui/CAnimation.cpp

@@ -100,8 +100,6 @@ public:
 	void setFlagColor(PlayerColor player) override;
 	bool isTransparent(const Point & coords) const override;
 	Point dimensions() const override;
-	int width() const override;
-	int height() const override;
 
 	void horizontalFlip() override;
 	void verticalFlip() override;
@@ -561,6 +559,15 @@ SDLImageLoader::~SDLImageLoader()
 IImage::IImage() = default;
 IImage::~IImage() = default;
 
+int IImage::width() const
+{
+	return dimensions().x;
+}
+
+int IImage::height() const
+{
+	return dimensions().y;
+}
 
 SDLImage::SDLImage(CDefFile * data, size_t frame, size_t group)
 	: surf(nullptr),
@@ -737,16 +744,6 @@ void SDLImage::setFlagColor(PlayerColor player)
 		CSDL_Ext::setPlayerColor(surf, player);
 }
 
-int SDLImage::width() const
-{
-	return fullSize.x;
-}
-
-int SDLImage::height() const
-{
-	return fullSize.y;
-}
-
 bool SDLImage::isTransparent(const Point & coords) const
 {
 	return CSDL_Ext::isTransparent(surf, coords.x, coords.y);

+ 2 - 2
client/gui/CAnimation.h

@@ -57,8 +57,8 @@ public:
 	virtual bool isTransparent(const Point & coords) const = 0;
 
 	virtual Point dimensions() const = 0;
-	virtual int width() const=0;
-	virtual int height() const=0;
+	int width() const;
+	int height() const;
 
 	//only indexed bitmaps, 16 colors maximum
 	virtual void shiftPalette(int from, int howMany) = 0;

+ 24 - 18
client/gui/CCanvas.cpp → client/gui/Canvas.cpp

@@ -1,5 +1,5 @@
 /*
- * CCanvas.cpp, part of VCMI engine
+ * Canvas.cpp, part of VCMI engine
  *
  * Authors: listed in file AUTHORS in main folder
  *
@@ -8,7 +8,7 @@
  *
  */
 #include "StdInc.h"
-#include "CCanvas.h"
+#include "Canvas.h"
 
 #include "SDL_Extensions.h"
 #include "Geometries.h"
@@ -16,43 +16,53 @@
 
 #include "../Graphics.h"
 
-CCanvas::CCanvas(SDL_Surface * surface):
+Canvas::Canvas(SDL_Surface * surface):
 	surface(surface)
 {
 	surface->refcount++;
 }
 
-CCanvas::CCanvas(const Point & size)
+Canvas::Canvas(Canvas & other):
+	surface(other.surface)
+{
+	surface->refcount++;
+}
+
+Canvas::Canvas(const Point & size)
 {
 	surface = CSDL_Ext::newSurface(size.x, size.y);
 }
 
-CCanvas::~CCanvas()
+Canvas::~Canvas()
 {
 	SDL_FreeSurface(surface);
 }
 
-void CCanvas::draw(std::shared_ptr<IImage> image, const Point & pos)
+void Canvas::draw(std::shared_ptr<IImage> image, const Point & pos)
 {
-	image->draw(surface, pos.x, pos.y);
+	assert(image);
+	if (image)
+		image->draw(surface, pos.x, pos.y);
 }
 
-void CCanvas::draw(std::shared_ptr<IImage> image, const Point & pos, const Rect & sourceRect)
+void Canvas::draw(std::shared_ptr<IImage> image, const Point & pos, const Rect & sourceRect)
 {
-	image->draw(surface, pos.x, pos.y, &sourceRect);
+	assert(image);
+	if (image)
+		image->draw(surface, pos.x, pos.y, &sourceRect);
 }
 
-void CCanvas::draw(std::shared_ptr<CCanvas> image, const Point & pos)
+void Canvas::draw(Canvas & image, const Point & pos)
 {
-	blitAt(image->surface, pos.x, pos.y, surface);
+	blitAt(image.surface, pos.x, pos.y, surface);
 }
 
-void CCanvas::drawLine(const Point & from, const Point & dest, const SDL_Color & colorFrom, const SDL_Color & colorDest)
+void Canvas::drawLine(const Point & from, const Point & dest, const SDL_Color & colorFrom, const SDL_Color & colorDest)
 {
 	CSDL_Ext::drawLine(surface, from.x, from.y, dest.x, dest.y, colorFrom, colorDest);
 }
 
-void CCanvas::drawText(const Point & position, const EFonts & font, const SDL_Color & colorDest, ETextAlignment alignment, const std::string & text )
+void Canvas::drawText(const Point & position, const EFonts & font, const SDL_Color & colorDest, ETextAlignment alignment, const std::string & text )
 {
 	switch (alignment)
 	{
@@ -62,7 +72,7 @@ void CCanvas::drawText(const Point & position, const EFonts & font, const SDL_Co
 	}
 }
 
-void CCanvas::drawText(const Point & position, const EFonts & font, const SDL_Color & colorDest, ETextAlignment alignment, const std::vector<std::string> & text )
+void Canvas::drawText(const Point & position, const EFonts & font, const SDL_Color & colorDest, ETextAlignment alignment, const std::vector<std::string> & text )
 {
 	switch (alignment)
 	{
@@ -72,7 +82,3 @@ void CCanvas::drawText(const Point & position, const EFonts & font, const SDL_Co
 	}
 }
 
-SDL_Surface * CCanvas::getSurface()
-{
-	return surface;
-}

+ 11 - 9
client/gui/CCanvas.h → client/gui/Canvas.h

@@ -1,5 +1,5 @@
 /*
- * CCanvas.h, part of VCMI engine
+ * Canvas.h, part of VCMI engine
  *
  * Authors: listed in file AUTHORS in main folder
  *
@@ -17,18 +17,23 @@ class IImage;
 enum EFonts : int;
 
 /// Class that represents surface for drawing on
-class CCanvas
+class Canvas
 {
 	SDL_Surface * surface;
+
+	Canvas & operator = (Canvas & other) = delete;
 public:
 
 	/// constructs canvas using existing surface. Caller maintains ownership on the surface
-	CCanvas(SDL_Surface * surface);
+	Canvas(SDL_Surface * surface);
+
+	/// copy contructor
+	Canvas(Canvas & other);
 
 	/// constructs canvas of specified size
-	CCanvas(const Point & size);
+	Canvas(const Point & size);
 
-	~CCanvas();
+	~Canvas();
 
 	/// renders image onto this canvas at specified position
 	void draw(std::shared_ptr<IImage> image, const Point & pos);
@@ -37,7 +42,7 @@ public:
 	void draw(std::shared_ptr<IImage> image, const Point & pos, const Rect & sourceRect);
 
 	/// renders another canvas onto this canvas
-	void draw(std::shared_ptr<CCanvas> image, const Point & pos);
+	void draw(Canvas & image, const Point & pos);
 
 	/// renders continuous, 1-pixel wide line with color gradient
 	void drawLine(const Point & from, const Point & dest, const SDL_Color & colorFrom, const SDL_Color & colorDest);
@@ -47,7 +52,4 @@ public:
 
 	/// renders multiple lines of text with specified parameters
 	void drawText(const Point & position, const EFonts & font, const SDL_Color & colorDest, ETextAlignment alignment, const std::vector<std::string> & text );
-
-	/// for compatibility, returns pointer to internal SDL surface
-	SDL_Surface * getSurface();
 };