Index: source/gui/CButton.cpp
===================================================================
--- source/gui/CButton.cpp	(revision 8836)
+++ source/gui/CButton.cpp	(working copy)
@@ -76,7 +76,7 @@
 	GUI<float>::GetSetting(this, "buffer_zone", buffer_zone);
 	*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, m_CachedActualSize.GetWidth(), buffer_zone, this);
 
-	CalculateTextPosition(m_CachedActualSize, m_TextPos, *m_GeneratedTexts[0]);
+	CalculateTextPosition(m_CachedActualSize, m_TextPositions, m_SpritePositions, *m_GeneratedTexts[0], buffer_zone);
 }
 
 void CButton::HandleMessage(const SGUIMessage &Message)
@@ -127,5 +127,5 @@
 			   cell_id);
 
 	CColor color = ChooseColor();
-	IGUITextOwner::Draw(0, color, m_TextPos, bz+0.1f);
+	IGUITextOwner::Draw(0, color, m_TextPositions, m_SpritePositions, 0, bz+0.1f);
 }
Index: source/gui/CButton.h
===================================================================
--- source/gui/CButton.h	(revision 8836)
+++ source/gui/CButton.h	(working copy)
@@ -84,9 +84,14 @@
 	void SetupText();
 
 	/**
-	 * Placement of text.
+	 * Placements of text.
 	 */
-	CPos m_TextPos;
+	std::vector<CPos> m_TextPositions;
+
+	/**
+	 * Placements of sprites.
+	 */
+	std::vector<CPos> m_SpritePositions;
 };
 
 #endif
Index: source/gui/CCheckBox.cpp
===================================================================
--- source/gui/CCheckBox.cpp	(revision 8836)
+++ source/gui/CCheckBox.cpp	(working copy)
@@ -175,5 +175,7 @@
 	if (square_side > line_height)
 		text_pos.y += square_side/2.f - line_height/2.f;
 
-	IGUITextOwner::Draw(0, color, text_pos, bz+0.1f, m_CachedActualSize);
+	std::vector<CPos> TextPositions, SpritePositions;
+	TextPositions.push_back(text_pos);
+	IGUITextOwner::Draw(0, color, TextPositions, SpritePositions, 0, bz+0.1f, m_CachedActualSize);
 }
Index: source/gui/CDropDown.cpp
===================================================================
--- source/gui/CDropDown.cpp	(revision 8836)
+++ source/gui/CDropDown.cpp	(working copy)
@@ -337,7 +337,9 @@
 					   m_CachedActualSize.right-button_width, m_CachedActualSize.bottom);
 
 		CPos pos(m_CachedActualSize.left, m_CachedActualSize.top);
-		IGUITextOwner::Draw(selected, color, pos, bz+0.1f, cliparea);
+		std::vector<CPos> TextPositions, SpritePositions;
+		TextPositions.push_back(pos);
+		IGUITextOwner::Draw(selected, color, TextPositions, SpritePositions, 0, bz+0.1f, cliparea);
 	}
 
 	bool *scrollbar=NULL, old;
Index: source/gui/CGUI.cpp
===================================================================
--- source/gui/CGUI.cpp	(revision 8836)
+++ source/gui/CGUI.cpp	(working copy)
@@ -932,8 +932,10 @@
 	return Text;
 }
 
-void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, 
-					const CPos &pos, const float &z, const CRect &clipping)
+void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor,
+					const std::vector<CPos> &TextCallPositions, 
+					const std::vector<CPos> &SpritePositions, 
+					const float &scroll, const float &z, const CRect &clipping)
 {
 	// TODO Gee: All these really necessary? Some
 	//  are defaults and if you changed them
@@ -968,31 +970,33 @@
 	CFont* font = NULL;
 	CStrW LastFontName;
 
-	for (std::vector<SGUIText::STextCall>::const_iterator it = Text.m_TextCalls.begin(); 
-		 it != Text.m_TextCalls.end(); 
-		 ++it)
+	int textPosIndex;
+	for (unsigned int i = 0; i < Text.m_TextCalls.size(); ++i)
 	{
+		SGUIText::STextCall *TextCall = &(Text.m_TextCalls[i]);
+		textPosIndex = std::min(i, TextCallPositions.size() - 1);
+		const CPos *TextPos = &(TextCallPositions[textPosIndex]);
 		// If this is just a placeholder for a sprite call, continue
-		if (it->m_pSpriteCall)
+		if (TextCall->m_pSpriteCall)
 			continue;
 
 		// Switch fonts when necessary, but remember the last one used
-		if (it->m_Font != LastFontName)
+		if (TextCall->m_Font != LastFontName)
 		{
 			delete font;
-			font = new CFont(it->m_Font);
+			font = new CFont(TextCall->m_Font);
 			font->Bind();
-			LastFontName = it->m_Font;
+			LastFontName = TextCall->m_Font;
 		}
 
-		CColor color = it->m_UseCustomColor ? it->m_Color : DefaultColor;
+		CColor color = TextCall->m_UseCustomColor ? TextCall->m_Color : DefaultColor;
 
 		glPushMatrix();
 
 		// TODO Gee: (2004-09-04) Why are font corrupted if inputted float value?
-		glTranslatef((GLfloat)int(pos.x+it->m_Pos.x), (GLfloat)int(pos.y+it->m_Pos.y), z);
+		glTranslatef((GLfloat)int(TextPos->x + TextCall->m_Pos.x), (GLfloat)int(TextPos->y + TextCall->m_Pos.y - scroll), z);
 		glColor4fv(color.FloatArray());
-		glwprintf(L"%ls", it->m_String.c_str()); // "%ls" is necessary in case m_String contains % symbols
+		glwprintf(L"%ls", TextCall->m_String.c_str()); // "%ls" is necessary in case m_String contains % symbols
 
 		glPopMatrix();
 
@@ -1001,11 +1005,15 @@
 	if (font)
 		delete font;
 
-	for (std::list<SGUIText::SSpriteCall>::iterator it=Text.m_SpriteCalls.begin(); 
-		 it!=Text.m_SpriteCalls.end(); 
+	std::list<SGUIText::SSpriteCall>::const_iterator it;
+	unsigned int spriteIndex = 0;
+	for (it = Text.m_SpriteCalls.begin(); 
+		 it != Text.m_SpriteCalls.end(); 
 		 ++it)
 	{
-		DrawSprite(it->m_Sprite, it->m_CellID, z, it->m_Area + pos);
+		DrawSprite(it->m_Sprite, it->m_CellID, z, 
+			it->m_Area + SpritePositions[spriteIndex] - CPos(0, scroll));
+		if (spriteIndex < SpritePositions.size() - 1) spriteIndex++;
 	}
 
 	// TODO To whom it may concern: Thing were not reset, so
Index: source/gui/CGUI.h
===================================================================
--- source/gui/CGUI.h	(revision 8836)
+++ source/gui/CGUI.h	(working copy)
@@ -158,7 +158,8 @@
 	 * @param clipping
 	 */
 	void DrawText(SGUIText &Text, const CColor &DefaultColor, 
-				  const CPos &pos, const float &z, const CRect &clipping);
+		          const std::vector<CPos> &TextPositions, const std::vector<CPos> &SpritePositions,
+				  const float &scroll, const float &z, const CRect &clipping);
 
 	/**
 	 * Clean up, call this to clean up all memory allocated
Index: source/gui/CList.cpp
===================================================================
--- source/gui/CList.cpp	(revision 8836)
+++ source/gui/CList.cpp	(working copy)
@@ -380,6 +380,8 @@
 		CColor color;
 		GUI<CColor>::GetSetting(this, _textcolor, color);
 
+		std::vector<CPos> TextPositions;
+	
 		for (int i=0; i<(int)pList->m_Items.size(); ++i)
 		{
 			if (m_ItemsYPositions[i+1] - scroll < 0 ||
@@ -400,8 +402,10 @@
 					cliparea.left = GetScrollBar(0).GetOuterRect().right;
 			}
 
-			IGUITextOwner::Draw(i, color, rect.TopLeft() - CPos(0.f, scroll - m_ItemsYPositions[i]), 
-								bz+0.1f, cliparea);
+			CPos text_pos(rect.TopLeft() + CPos(0.f, m_ItemsYPositions[i]));
+			std::vector<CPos> TextPositions, SpritePositions;
+			TextPositions.push_back(text_pos);
+			IGUITextOwner::Draw(i, color, TextPositions, SpritePositions, scroll, bz+0.1f, cliparea);
 		}
 	}
 }
Index: source/gui/CText.cpp
===================================================================
--- source/gui/CText.cpp	(revision 8836)
+++ source/gui/CText.cpp	(working copy)
@@ -97,8 +97,7 @@
 	GUI<float>::GetSetting(this, "buffer_zone", buffer_zone);
 	*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, width, buffer_zone, this);
 
-	if (! scrollbar)
-		CalculateTextPosition(m_CachedActualSize, m_TextPos, *m_GeneratedTexts[0]);
+	CalculateTextPosition(m_CachedActualSize, m_TextPositions, m_SpritePositions, *m_GeneratedTexts[0], buffer_zone);
 
 	// Setup scrollbar
 	if (scrollbar)
@@ -240,11 +239,7 @@
 		CColor color;
 		GUI<CColor>::GetSetting(this, "textcolor", color);
 
-		// Draw text
-		if (scrollbar)
-			IGUITextOwner::Draw(0, color, m_CachedActualSize.TopLeft() - CPos(0.f, scroll), bz+0.1f, cliparea);
-		else
-			IGUITextOwner::Draw(0, color, m_TextPos, bz+0.1f, cliparea);
+		IGUITextOwner::Draw(0, color, m_TextPositions, m_SpritePositions, scroll, bz+0.1f, cliparea);
 	}
 }
 
Index: source/gui/CText.h
===================================================================
--- source/gui/CText.h	(revision 8836)
+++ source/gui/CText.h	(working copy)
@@ -91,9 +91,14 @@
 	virtual void Draw();
 
 	/**
-	 * Placement of text. Ignored when scrollbars are active.
+	 * Placements of text.
 	 */
-	CPos m_TextPos;
+	std::vector<CPos> m_TextPositions;
+
+	/**
+	 * Placements of sprites.
+	 */
+	std::vector<CPos> m_SpritePositions;
 };
 
 #endif
Index: source/gui/CTooltip.cpp
===================================================================
--- source/gui/CTooltip.cpp	(revision 8836)
+++ source/gui/CTooltip.cpp	(working copy)
@@ -160,6 +160,8 @@
 		GUI<CColor>::GetSetting(this, "textcolor", color);
 
 		// Draw text
-		IGUITextOwner::Draw(0, color, m_CachedActualSize.TopLeft(), z+0.1f);
+		std::vector<CPos> TextPositions, SpritePositions;
+		TextPositions.push_back(m_CachedActualSize.TopLeft());
+		IGUITextOwner::Draw(0, color, TextPositions, SpritePositions, 0, z+0.1f);
 	}
 }
Index: source/gui/IGUITextOwner.cpp
===================================================================
--- source/gui/IGUITextOwner.cpp	(revision 8836)
+++ source/gui/IGUITextOwner.cpp	(working copy)
@@ -78,8 +78,9 @@
 	m_GeneratedTextsValid = false;
 }
 
-void IGUITextOwner::Draw(const int &index, const CColor &color, const CPos &pos,
-						 const float &z, const CRect &clipping)
+void IGUITextOwner::Draw(const int &index, const CColor &color, 
+						 const std::vector<CPos> &TextPositions, const std::vector<CPos> &SpritePositions,
+						 const float &scroll, const float &z, const CRect &clipping)
 {
 	if (!m_GeneratedTextsValid)
 	{
@@ -95,50 +96,200 @@
 
 	if (GetGUI())
 	{
-		GetGUI()->DrawText(*m_GeneratedTexts[index], color, pos, z, clipping);
+		GetGUI()->DrawText(*m_GeneratedTexts[index], color, TextPositions, SpritePositions, scroll, z, clipping);
 	}
 }
 
-void IGUITextOwner::CalculateTextPosition(CRect &ObjSize, CPos &TextPos, SGUIText &Text)
+void IGUITextOwner::CalculateTextPosition(CRect &ObjSize, std::vector<CPos> &TextPositions, 
+										  std::vector<CPos> &SpritePositions, SGUIText &Text, float &buffer_zone)
 {
 	EAlign align;
 	EVAlign valign;
 	GUI<EAlign>::GetSetting(this, "text_align", align);
 	GUI<EVAlign>::GetSetting(this, "text_valign", valign);
 
-	switch (align)
+	if (Text.m_TextCalls.size() == 0 && Text.m_SpriteCalls.size() == 0)
 	{
-	case EAlign_Left:
-		TextPos.x = ObjSize.left;
-		break;
-	case EAlign_Center:
-		// Round to integer pixel values, else the fonts look awful
-		TextPos.x = floorf(ObjSize.CenterPoint().x - Text.m_Size.cx/2.f);
-		break;
-	case EAlign_Right:
-		TextPos.x = ObjSize.right - Text.m_Size.cx;
-		break;
-	default:
-		debug_warn(L"Broken EAlign in CButton::SetupText()");
-		break;
+		TextPositions.clear();
+		SpritePositions.clear();
+		return;
 	}
 
-	switch (valign)
+	// In case of align == EAlign_Center or align == EAlign_Center 
+	// we need additional preparations
+	// XBounds - map of bounds of x coordinate for each line of text
+	// key - y value of TextCall position
+	// value - pair of min and max x values for this line 
+	std::map<float, std::pair<float, float>> xBounds;
+	if (align == EAlign_Center || align == EAlign_Right)
 	{
-	case EVAlign_Top:
-		TextPos.y = ObjSize.top;
-		break;
-	case EVAlign_Center:
-		// Round to integer pixel values, else the fonts look awful
-		TextPos.y = floorf(ObjSize.CenterPoint().y - Text.m_Size.cy/2.f);
-		break;
-	case EVAlign_Bottom:
-		TextPos.y = ObjSize.bottom - Text.m_Size.cy;
-		break;
-	default:
-		debug_warn(L"Broken EVAlign in CButton::SetupText()");
-		break;
+		for (std::vector<SGUIText::STextCall>::const_iterator it = Text.m_TextCalls.begin();
+			it != Text.m_TextCalls.end();
+			++it)
+		{
+			float xLeft = it->m_Pos.x;
+			float xRight = it->m_Pos.x + it->m_Size.cx;
+			if (xBounds.find(it->m_Pos.y) != xBounds.end())
+			{
+				float *xMin = &(xBounds[it->m_Pos.y].first);
+				float *xMax = &(xBounds[it->m_Pos.y].second);
+				
+				if (xLeft < *xMin) *xMin = xLeft;
+				if (xRight > *xMax) *xMax = xRight;
+			}
+			else
+			{
+				xBounds[it->m_Pos.y] = std::make_pair<float, float>(xLeft, xRight);
+			}
+		}
+
+		for (std::list<SGUIText::SSpriteCall>::const_iterator it = Text.m_SpriteCalls.begin();
+			it != Text.m_SpriteCalls.end();
+			++it)
+		{
+			float xLeft = it->m_Area.left;
+			float xRight = it->m_Area.right;
+			if (xBounds.find(it->m_Area.top) != xBounds.end())
+			{
+				float *xMin = &(xBounds[it->m_Area.top].first);
+				float *xMax = &(xBounds[it->m_Area.top].second);
+				
+				if (xLeft < *xMin) *xMin = xLeft;
+				if (xRight > *xMax) *xMax = xRight;
+			}
+			else
+			{
+				xBounds[it->m_Area.top] = std::make_pair<float, float>(xLeft, xRight);
+			}
+		}
 	}
+
+	if (Text.m_TextCalls.size() == 0) 
+	{
+		TextPositions.clear();
+	}
+	else
+	{
+		TextPositions.resize(Text.m_TextCalls.size());
+		CPos *TextPos;
+		std::pair<float, float> bounds;
+		float lineWidth;
+		for (unsigned int i = 0; i < Text.m_TextCalls.size(); ++i)
+		{
+			TextPos = &(TextPositions[i]);
+			switch (align)
+			{
+			case EAlign_Left:
+				TextPos->x = ObjSize.left;
+				break;
+			case EAlign_Center:
+				bounds = xBounds[Text.m_TextCalls[i].m_Pos.y];
+				lineWidth = bounds.second - bounds.first;
+				TextPos->x = ObjSize.CenterPoint().x - buffer_zone - lineWidth / 2.f;
+				break;
+			case EAlign_Right:
+				bounds = xBounds[Text.m_TextCalls[i].m_Pos.y];
+				TextPos->x = ObjSize.right - bounds.second - buffer_zone;
+				break;
+			default:
+				debug_warn(L"Broken EAlign in IGUITextOwner::CalculateTextPosition()");
+				break;
+			}
+
+			switch (valign)
+			{
+			case EVAlign_Top:
+				TextPos->y = ObjSize.top;
+				break;
+			case EVAlign_Center:
+				// if text height is less than object height
+				// then center it, else stick text to object's top
+				if (ObjSize.GetHeight() > Text.m_Size.cy)
+				{
+					// Round to integer pixel values, else the fonts look awful
+					TextPos->y = floorf(ObjSize.CenterPoint().y - Text.m_Size.cy/2.f);
+				}
+				else
+				{
+					TextPos->y = ObjSize.top;
+				}
+				break;
+			case EVAlign_Bottom:
+				// if text height is less than object height
+				// then stick text to oblects bottom, else stick it top
+				if (ObjSize.GetHeight() > Text.m_Size.cy)
+				{
+					TextPos->y = ObjSize.bottom - Text.m_Size.cy;
+				}
+				else
+				{
+					TextPos->y = ObjSize.top;
+				}
+				break;
+			default:
+				debug_warn(L"Broken EVAlign in IGUITextOwner::CalculateTextPosition()");
+				break;
+			}
+		}
+	}
+
+	if (Text.m_SpriteCalls.size() == 0) 
+	{
+		SpritePositions.clear();
+	}
+	else
+	{
+		CPos *SpritePos;
+
+		SpritePositions.resize(Text.m_SpriteCalls.size());
+
+		std::list<SGUIText::SSpriteCall>::const_iterator it;
+		unsigned int i = 0;
+		for (it = Text.m_SpriteCalls.begin(); 
+			 it != Text.m_SpriteCalls.end(); 
+			 ++it)
+		{
+			SpritePos = &(SpritePositions[i]);
+			switch (align)
+			{
+			case EAlign_Left:
+				SpritePos->x = ObjSize.left;
+				break;
+			case EAlign_Center:
+				{
+				std::pair<float, float> bounds = xBounds[it->m_Area.top];
+				float lineWidth = bounds.second - bounds.first;
+				float lineLeft = ObjSize.CenterPoint().x - lineWidth / 2.f;
+				SpritePos->x = lineLeft;
+				break;
+				}
+			case EAlign_Right:
+				SpritePos->x = ObjSize.right - Text.m_Size.cx;
+				break;
+			default:
+				debug_warn(L"Broken EAlign in CButton::SetupText()");
+				break;
+			}
+
+			switch (valign)
+			{
+			case EVAlign_Top:
+				SpritePos->y = ObjSize.top;
+				break;
+			case EVAlign_Center:
+				// Round to integer pixel values, else the fonts look awful
+				SpritePos->y = floorf(ObjSize.CenterPoint().y - Text.m_Size.cy/2.f);
+				break;
+			case EVAlign_Bottom:
+				SpritePos->y = ObjSize.bottom - Text.m_Size.cy;
+				break;
+			default:
+				debug_warn(L"Broken EVAlign in CButton::SetupText()");
+				break;
+			}
+			++i;
+		}
+	}
 }
 
 bool IGUITextOwner::MouseOverIcon()
Index: source/gui/IGUITextOwner.h
===================================================================
--- source/gui/IGUITextOwner.h	(revision 8836)
+++ source/gui/IGUITextOwner.h	(working copy)
@@ -88,8 +88,9 @@
 	 * @param clipping Clipping rectangle, don't even add a parameter
 	 *		  to get no clipping.
 	 */
-	virtual void Draw(const int &index, const CColor &color, const CPos &pos, 
-					  const float &z, const CRect &clipping = CRect());
+	virtual void Draw(const int &index, const CColor &color, 
+					  const std::vector<CPos> &TextPositions, const std::vector<CPos> &SpritePositions, 
+					  const float &scroll, const float &z, const CRect &clipping = CRect());
 
 	/**
 	 * Test if mouse position is over an icon
@@ -116,7 +117,7 @@
 	/**
 	 * Calculate the position for the text, based on the alignment.
 	 */
-	void CalculateTextPosition(CRect &ObjSize, CPos &TextPos, SGUIText &Text);
+	void CalculateTextPosition(CRect &ObjSize, std::vector<CPos> &TextPositions, std::vector<CPos> &SpritePositions, SGUIText &Text, float &buffer_zone);
 };
 
 #endif
