1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- all fonts handling is now in new file, UIFramework/Fonts.cpp/h

- common base class for H3 bmp and ttf fonts
- replaced fonts.txt with fonts.json
This commit is contained in:
Ivan Savenko 2012-12-19 17:24:53 +00:00
parent 0e06ac15ad
commit b5ebf443fc
30 changed files with 1726 additions and 1917 deletions

View File

@ -2271,14 +2271,9 @@ void CBattleInterface::showAliveStack(const CStack *stack, SDL_Surface * to)
SDL_Rect temp_rect = genRect(amountNormal->h, amountNormal->w, creAnims[ID]->pos.x + xAdd, creAnims[ID]->pos.y + yAdd);
SDL_BlitSurface(amountBG, NULL, to, &temp_rect);
//blitting amount
CSDL_Ext::printAtMiddle(
makeNumberShort(stack->count),
creAnims[ID]->pos.x + xAdd + 15,
creAnims[ID]->pos.y + yAdd + 5,
FONT_TINY,
Colors::WHITE,
to
);
Point textPos(creAnims[ID]->pos.x + xAdd + 15, creAnims[ID]->pos.y + yAdd + 5);
graphics->fonts[FONT_TINY]->renderTextCenter(to, makeNumberShort(stack->count), Colors::WHITE, textPos);
}
}

View File

@ -23,6 +23,7 @@
#include "../../lib/CTownHandler.h"
#include "../CBitmapHandler.h"
#include "../CCreatureWindow.h"
#include "../CMessage.h"
CBattleConsole::~CBattleConsole()
{
@ -31,24 +32,27 @@ CBattleConsole::~CBattleConsole()
void CBattleConsole::showAll(SDL_Surface * to)
{
Point textPos(pos.x + pos.w/2, pos.y + 11);
if(ingcAlter.size())
{
CSDL_Ext::printAtMiddleWB(ingcAlter, pos.x + pos.w/2, pos.y + 11, FONT_SMALL, 80, Colors::WHITE, to);
graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(ingcAlter, pos.w, FONT_SMALL), Colors::WHITE, textPos);
}
else if(alterTxt.size())
{
CSDL_Ext::printAtMiddleWB(alterTxt, pos.x + pos.w/2, pos.y + 11, FONT_SMALL, 80, Colors::WHITE, to);
graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(alterTxt, pos.w, FONT_SMALL), Colors::WHITE, textPos);
}
else if(texts.size())
{
if(texts.size()==1)
{
CSDL_Ext::printAtMiddleWB(texts[0], pos.x + pos.w/2, pos.y + 11, FONT_SMALL, 80, Colors::WHITE, to);
graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[0], pos.w, FONT_SMALL), Colors::WHITE, textPos);
}
else
{
CSDL_Ext::printAtMiddleWB(texts[lastShown-1], pos.x + pos.w/2, pos.y + 11, FONT_SMALL, 80, Colors::WHITE, to);
CSDL_Ext::printAtMiddleWB(texts[lastShown], pos.x + pos.w/2, pos.y + 27, FONT_SMALL, 80, Colors::WHITE, to);
graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[lastShown - 1], pos.w, FONT_SMALL), Colors::WHITE, textPos);
textPos.y += 16;
graphics->fonts[FONT_SMALL]->renderTextLinesCenter(to, CMessage::breakText(texts[lastShown], pos.w, FONT_SMALL), Colors::WHITE, textPos);
}
}
}

View File

@ -335,20 +335,19 @@ CResDataBar::~CResDataBar()
void CResDataBar::draw(SDL_Surface * to)
{
blitAt(bg,pos.x,pos.y,to);
char * buf = new char[15];
for (int i=0;i<7;i++)
{
SDL_itoa(LOCPLINT->cb->getResourceAmount(i),buf,10);
printAt(buf,txtpos[i].first,txtpos[i].second,FONT_SMALL,Colors::WHITE,to);
std::string text = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i));
graphics->fonts[FONT_SMALL]->renderTextLeft(to, text, Colors::WHITE, Point(txtpos[i].first,txtpos[i].second));
}
std::vector<std::string> temp;
SDL_itoa(LOCPLINT->cb->getDate(3),buf,10); temp+=std::string(buf);
SDL_itoa(LOCPLINT->cb->getDate(2),buf,10); temp+=std::string(buf);
SDL_itoa(LOCPLINT->cb->getDate(1),buf,10); temp+=std::string(buf);
printAt(processStr(datetext,temp),txtpos[7].first,txtpos[7].second,FONT_SMALL,Colors::WHITE,to);
temp.clear();
//updateRect(&pos,screen);
delete[] buf;
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(3)));
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(2)));
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(1)));
graphics->fonts[FONT_SMALL]->renderTextLeft(to, processStr(datetext,temp), Colors::WHITE, Point(txtpos[7].first,txtpos[7].second));
}
void CResDataBar::show(SDL_Surface * to)

View File

@ -1390,7 +1390,7 @@ void CShowableAnim::rotate(bool on, bool vertical)
}
CCreatureAnim::CCreatureAnim(int x, int y, std::string name, Rect picPos, ui8 flags, EAnimType type):
CShowableAnim(x,y,name,flags,3,type)
CShowableAnim(x,y,name,flags,4,type)
{
xOffset = picPos.x;
yOffset = picPos.y;

View File

@ -562,8 +562,9 @@ void CCreatureWindow::showAll(SDL_Surface * to)
void CCreatureWindow::show(SDL_Surface * to)
{
if (count.size()) //army stack
printTo(count, pos.x + 114, pos.y + 174,FONT_TIMES, Colors::WHITE, to);
CIntObject::show(to);
if (!count.empty()) //army stack
graphics->fonts[FONT_TIMES]->renderTextRight(to, count, Colors::WHITE, Point(pos.x + 114, pos.y + 174));
}
@ -710,8 +711,8 @@ void CBonusItem::showAll (SDL_Surface * to)
{
if (visible)
{
printAt(name, pos.x + 72, pos.y + 6, FONT_SMALL, Colors::YELLOW, to);
printAt(description, pos.x + 72, pos.y + 30, FONT_SMALL, Colors::WHITE, to);
graphics->fonts[FONT_SMALL]->renderTextLeft(to, name, Colors::YELLOW, Point(pos.x + 72, pos.y + 6));
graphics->fonts[FONT_SMALL]->renderTextLeft(to, name, Colors::WHITE, Point(pos.x + 72, pos.y + 30));
if (bonusGraphics && bonusGraphics->bg)
blitAtLoc(bonusGraphics->bg, 12, 2, to);
}

View File

@ -339,28 +339,9 @@ void CHeroWindow::showAll(SDL_Surface * to)
printAtMiddleLoc(CGI->generaltexth->jktexts[4], 262, 99, FONT_SMALL, Colors::YELLOW, to);
//dismiss / quest log
std::vector<std::string> toPrin = CMessage::breakText(CGI->generaltexth->jktexts[8]);
if(toPrin.size()==1)
{
printAtLoc(toPrin[0], 372, 439, FONT_SMALL, Colors::WHITE, to);
}
else
{
printAtLoc(toPrin[0], 372, 430, FONT_SMALL, Colors::WHITE, to);
printAtLoc(toPrin[1], 372, 446, FONT_SMALL, Colors::WHITE, to);
}
toPrin = CMessage::breakText(CGI->generaltexth->jktexts[9]);
if(toPrin.size()==1)
{
printAtLoc(toPrin[0], 512, 439, FONT_SMALL, Colors::WHITE, to);
}
else
{
printAtLoc(toPrin[0], 512, 430, FONT_SMALL, Colors::WHITE, to);
printAtLoc(toPrin[1], 512, 446, FONT_SMALL, Colors::WHITE, to);
}
printAtMiddleWBLoc(CGI->generaltexth->jktexts[8], 388, 455, FONT_SMALL, 50, Colors::WHITE, to);
printAtMiddleWBLoc(CGI->generaltexth->jktexts[9], 534, 455, FONT_SMALL, 50, Colors::WHITE, to);
//printing primary skills' amounts
for(int m=0; m<4; ++m)
{

View File

@ -14,6 +14,7 @@ set(client_SRCS
UIFramework/CGuiHandler.cpp
UIFramework/CIntObject.cpp
UIFramework/CIntObjectClasses.cpp
UIFramework/Fonts.cpp
UIFramework/Geometries.cpp
UIFramework/CCursorHandler.cpp
UIFramework/SDL_Extensions.cpp

View File

@ -58,8 +58,8 @@ struct ComponentsToBlit
std::vector< std::vector<ComponentResolved*> > comps;
int w, h;
void blitCompsOnSur(SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret);
ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, SDL_Surface* _or); //c-tor
void blitCompsOnSur(bool blitOr, int inter, int &curh, SDL_Surface *ret);
ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, bool blitOr); //c-tor
~ComponentsToBlit(); //d-tor
};
@ -131,9 +131,7 @@ SDL_Surface * CMessage::drawDialogBox(int w, int h, int playerColor)
return ret;
}
/* The map file contains long texts, with or without line breaks. This
* method takes such a text and breaks it into into several lines. */
std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSize/*=30*/, const boost::function<int(char)> &charMetric /*= 0*/, bool allowLeadingWhitespace /*= false*/ )
std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSize, EFonts font )
{
std::vector<std::string> ret;
@ -153,11 +151,8 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSi
opened=true;
else if (text[z]=='}')
opened=false;
else if(charMetric)
lineLength += charMetric(text[z]);
else
lineLength++;
lineLength += graphics->fonts[font]->getSymbolWidth(text[z]);
z++;
}
@ -176,8 +171,8 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSi
if (pos > 0)
z = pos+1;
}
if(z) //non-blank line
if(z) //non-blank line
{
ret.push_back(text.substr(0, z));
@ -187,7 +182,7 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSi
text.erase(0, z);
}
else if(text[z] == 0x0a) //blank line
else if(text[z] == 0x0a) //blank line
{
ret.push_back(""); //add empty string, no extra actions needed
}
@ -204,8 +199,9 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSi
lineManuallyBroken = true;
}
if(!allowLeadingWhitespace || !lineManuallyBroken)
boost::algorithm::trim_left_if(text,boost::algorithm::is_any_of(std::string(" ")));
//if(!allowLeadingWhitespace || !lineManuallyBroken)
if(!lineManuallyBroken)
boost::algorithm::trim_left_if(text,boost::algorithm::is_any_of(std::string(" ")));
if (opened)
{
@ -216,164 +212,18 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineSi
}
/* Trim whitespaces of every line. */
if(!allowLeadingWhitespace)
//if(!allowLeadingWhitespace)
for (size_t i=0; i<ret.size(); i++)
boost::algorithm::trim(ret[i]);
return ret;
}
std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineWidth, EFonts font )
{
return breakText(text, maxLineWidth, boost::bind(&Font::getCharWidth, graphics->fonts[font], _1), true);
}
std::pair<int,int> CMessage::getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight)
{
std::pair<int,int> ret;
ret.first = -1;
ret.second=0;
for (size_t i=0; i<txtg->size();i++) //we are searching widest line and total height
{
int lw=0;
for (size_t j=0;j<(*txtg)[i].size();j++)
{
lw+=(*txtg)[i][j]->w;
ret.second+=(*txtg)[i][j]->h;
}
if(!(*txtg)[i].size())
ret.second+=fontHeight;
if (ret.first<lw)
ret.first=lw;
}
return ret;
}
// Blit the text in txtg onto one surface. txtg contains lines of
// text. Each line can be split into pieces. Currently only lines with
// the same height are supported (ie. fontHeight).
SDL_Surface * CMessage::blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight, int & curh, SDL_Surface * ret, int xCenterPos)
{
for (size_t i=0; i<txtg->size(); i++, curh += fontHeight)
{
int lw=0; //line width
for (size_t j=0;j<(*txtg)[i].size();j++)
lw+=(*txtg)[i][j]->w;
int pw = (xCenterPos < 0) ? ret->w/2 : xCenterPos;
pw -= lw/2; //x coord for the start of the text
int tw = pw;
for (size_t j=0;j<(*txtg)[i].size();j++) //blit text
{
SDL_Surface *surf = (*txtg)[i][j];
blitAt(surf, tw, curh, ret);
tw+=surf->w;
SDL_FreeSurface(surf);
(*txtg)[i][j] = NULL;
}
}
return ret;
}
SDL_Surface * FNT_RenderText (EFonts font, std::string text, SDL_Color kolor= Colors::WHITE)
{
if (graphics->fontsTrueType[font])
return TTF_RenderText_Blended(graphics->fontsTrueType[font], text.c_str(), kolor);
const Font *f = graphics->fonts[font];
int w = f->getWidth(text.c_str()),
h = f->height;
SDL_Surface * ret = CSDL_Ext::newSurface(w, h, screen);
CSDL_Ext::fillRect (ret, NULL, SDL_MapRGB(ret->format,128,128,128));//if use default black - no shadowing
SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,128,128,128));
CSDL_Ext::printAt(text.c_str(), 0, 0, font, kolor, ret);
return ret;
}
std::vector<std::vector<SDL_Surface*> > * CMessage::drawText(std::vector<std::string> * brtext, int &fontHeigh, EFonts font)
{
std::vector<std::vector<SDL_Surface*> > * txtg = new std::vector<std::vector<SDL_Surface*> >();
txtg->resize(brtext->size());
if (graphics->fontsTrueType[font])
fontHeigh = TTF_FontHeight(graphics->fontsTrueType[font]);
else
fontHeigh = graphics->fonts[font]->height;
for (size_t i=0; i<brtext->size();i++) //foreach line
{
while((*brtext)[i].length()) //if something left
{
size_t z;
/* Handle normal text. */
z = 0;
while(z < (*brtext)[i].length() && (*brtext)[i][z] != ('{'))
z++;
if (z)
(*txtg)[i].push_back(FNT_RenderText(font, (*brtext)[i].substr(0,z), Colors::WHITE));
(*brtext)[i].erase(0,z);
if ((*brtext)[i].length() && (*brtext)[i][0] == '{')
/* Remove '{' */
(*brtext)[i].erase(0,1);
if ((*brtext)[i].length()==0)
/* End of line */
continue;
/* This text will be highlighted. */
z = 0;
while(z < (*brtext)[i].length() && (*brtext)[i][z] != ('}'))
z++;
if (z)
(*txtg)[i].push_back(FNT_RenderText(font, (*brtext)[i].substr(0,z), Colors::YELLOW));
(*brtext)[i].erase(0,z);
if ((*brtext)[i].length() && (*brtext)[i][0] == '}')
/* Remove '}' */
(*brtext)[i].erase(0,1);
} //ends while((*brtext)[i].length())
} //ends for(int i=0; i<brtext->size();i++)
return txtg;
}
SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline/*=30*/, int imgToBmp/*=55*/ )
{
int curh;
int fontHeight;
std::vector<std::string> tekst = breakText(text,charperline);
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(&tekst, fontHeight);
std::pair<int,int> txts = getMaxSizes(txtg, fontHeight), boxs;
boxs.first = std::max(txts.first,bitmap->w) // text/bitmap max width
+ 50; //side margins
boxs.second =
(curh=45) //top margin
+ txts.second //text total height
+ imgToBmp //text <=> img
+ bitmap->h
+ 5 // to sibtitle
+ (*txtg)[0][0]->h
+ 30;
SDL_Surface *ret = drawDialogBox(boxs.first,boxs.second,player);
blitTextOnSur(txtg,fontHeight,curh,ret);
curh += imgToBmp;
blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret);
curh += bitmap->h + 5;
CSDL_Ext::printAtMiddle(sub,ret->w/2,curh+10,FONT_SMALL,Colors::WHITE,ret);
delete txtg;
return ret;
}
void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
{
SDL_Surface * _or = NULL;
bool blitOr = false;
if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components
_or = FNT_RenderText(FONT_MEDIUM,CGI->generaltexth->allTexts[4],Colors::WHITE);
blitOr = true;
const int sizes[][2] = {{400, 125}, {500, 150}, {600, 200}, {480, 400}};
@ -392,7 +242,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
std::pair<int,int> winSize(ret->text->pos.w, ret->text->pos.h); //start with text size
ComponentsToBlit comps(ret->components,500,_or);
ComponentsToBlit comps(ret->components,500, blitOr);
if (ret->components.size())
winSize.second += 10 + comps.h; //space to first component
@ -436,7 +286,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
if (ret->components.size())
{
curh += BEFORE_COMPONENTS;
comps.blitCompsOnSur (_or, BETWEEN_COMPS, curh, ret->bitmap);
comps.blitCompsOnSur (blitOr, BETWEEN_COMPS, curh, ret->bitmap);
}
if(ret->buttons.size())
{
@ -452,9 +302,6 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
}
for(size_t i=0; i<ret->components.size(); i++)
ret->components[i]->moveBy(Point(ret->pos.x, ret->pos.y));
if(_or)
SDL_FreeSurface(_or);
}
void CMessage::drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int x, int y)
@ -562,8 +409,10 @@ ComponentsToBlit::~ComponentsToBlit()
}
ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, SDL_Surface* _or)
ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, bool blitOr)
{
int orWidth = graphics->fonts[FONT_MEDIUM]->getStringWidth(CGI->generaltexth->allTexts[4]);
w = h = 0;
if(SComps.empty())
return;
@ -576,7 +425,7 @@ ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw,
{
ComponentResolved *cur = new ComponentResolved(SComps[i]);
int toadd = (cur->pos.w + BETWEEN_COMPS + (_or ? _or->w : 0));
int toadd = (cur->pos.w + BETWEEN_COMPS + (blitOr ? orWidth : 0));
if (curw + toadd > maxw)
{
curr++;
@ -603,8 +452,10 @@ ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw,
}
}
void ComponentsToBlit::blitCompsOnSur( SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret )
void ComponentsToBlit::blitCompsOnSur( bool blitOr, int inter, int &curh, SDL_Surface *ret )
{
int orWidth = graphics->fonts[FONT_MEDIUM]->getStringWidth(CGI->generaltexth->allTexts[4]);
for (size_t i=0;i<comps.size();i++)//for each row
{
int totalw=0, maxHeight=0;
@ -616,8 +467,8 @@ void ComponentsToBlit::blitCompsOnSur( SDL_Surface * _or, int inter, int &curh,
}
//add space between comps in this row
if(_or)
totalw += (inter*2+_or->w) * ((comps)[i].size() - 1);
if(blitOr)
totalw += (inter*2+orWidth) * ((comps)[i].size() - 1);
else
totalw += (inter) * ((comps)[i].size() - 1);
@ -636,11 +487,14 @@ void ComponentsToBlit::blitCompsOnSur( SDL_Surface * _or, int inter, int &curh,
//if there is subsequent component blit "or"
if(j<((comps)[i].size()-1))
{
if(_or)
if(blitOr)
{
curw+=inter;
blitAt(_or,curw,middleh-(_or->h/2),ret);
curw+=_or->w;
graphics->fonts[FONT_MEDIUM]->renderTextLeft(ret, CGI->generaltexth->allTexts[4], Colors::WHITE,
Point(curw,middleh-(graphics->fonts[FONT_MEDIUM]->getLineHeight()/2)));
curw+=orWidth;
}
curw+=inter;
}

View File

@ -1,6 +1,6 @@
#pragma once
#include "FontBase.h"
#include "Graphics.h"
#include "UIFramework/Geometries.h"
@ -28,7 +28,6 @@ class CMessage
public:
//Function usd only in CMessage.cpp
static std::pair<int,int> getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight);
static std::vector<std::vector<SDL_Surface*> > * drawText(std::vector<std::string> * brtext, int &fontHeigh, EFonts font = FONT_MEDIUM);
static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight, int & curh, SDL_Surface * ret, int xCenterPos=-1); //xPos==-1 works as if ret->w/2
/// Draw border on exiting surface
@ -37,14 +36,9 @@ public:
/// Draw simple dialog box (borders and background only)
static SDL_Surface * drawDialogBox(int w, int h, int playerColor=1);
/// Draw simple dialog box and blit bitmap with text on it
static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charPerline=30, int imgToBmp=55);
static void drawIWindow(CInfoWindow * ret, std::string text, int player);
/// split text in lines
static std::vector<std::string> breakText(std::string text, size_t maxLineSize=30, const boost::function<int(char)> &charMetric = boost::function<int(char)>(), bool allowLeadingWhitespace = false);
static std::vector<std::string> breakText(std::string text, size_t maxLineWidth, EFonts font);
/// constructor

View File

@ -1369,7 +1369,6 @@ void SelectionTab::printMaps(SDL_Surface *to)
SDL_Color itemColor;
#define POS(xx, yy) pos.x + xx, pos.y + yy + line*25
for (int line = 0; line < positions && elemIdx < curItems.size(); elemIdx++, line++)
{
CMapInfo *currentItem = curItems[elemIdx];
@ -1384,7 +1383,7 @@ void SelectionTab::printMaps(SDL_Surface *to)
//amount of players
std::ostringstream ostr(std::ostringstream::out);
ostr << currentItem->playerAmnt << "/" << currentItem->humanPlayers;
CSDL_Ext::printAt(ostr.str(), POS(29, 120), FONT_SMALL, itemColor, to);
printAtLoc(ostr.str(), 29, 120 + line * 25, FONT_SMALL, itemColor, to);
//map size
std::string temp2 = "C";
@ -1403,7 +1402,7 @@ void SelectionTab::printMaps(SDL_Surface *to)
temp2="XL";
break;
}
CSDL_Ext::printAtMiddle(temp2, POS(70, 128), FONT_SMALL, itemColor, to);
printAtMiddleLoc(temp2, 70, 128 + line * 25, FONT_SMALL, itemColor, to);
int temp=-1;
switch (currentItem->mapHeader->version)
@ -1425,28 +1424,28 @@ void SelectionTab::printMaps(SDL_Surface *to)
tlog2 << "Warning: " << currentItem->fileURI << " has wrong version!\n";
continue;
}
blitAt(format->ourImages[temp].bitmap, POS(88, 117), to);
blitAtLoc(format->ourImages[temp].bitmap, 88, 117 + line * 25, to);
//victory conditions
if (currentItem->mapHeader->victoryCondition.condition == EVictoryConditionType::WINSTANDARD)
temp = 11;
else
temp = currentItem->mapHeader->victoryCondition.condition;
blitAt(CGP->victory->ourImages[temp].bitmap, POS(306, 117), to);
blitAtLoc(CGP->victory->ourImages[temp].bitmap, 306, 117 + line * 25, to);
//loss conditions
if (currentItem->mapHeader->lossCondition.typeOfLossCon == ELossConditionType::LOSSSTANDARD)
temp=3;
else
temp=currentItem->mapHeader->lossCondition.typeOfLossCon;
blitAt(CGP->loss->ourImages[temp].bitmap, POS(339, 117), to);
blitAtLoc(CGP->loss->ourImages[temp].bitmap, 339, 117 + line * 25, to);
}
else //if campaign
{
//number of maps in campaign
std::ostringstream ostr(std::ostringstream::out);
ostr << CGI->generaltexth->campaignRegionNames[ currentItem->campaignHeader->mapVersion ].size();
CSDL_Ext::printAt(ostr.str(), POS(29, 120), FONT_SMALL, itemColor, to);
printAtLoc(ostr.str(), 29, 120 + line * 25, FONT_SMALL, itemColor, to);
}
std::string name;
@ -1467,10 +1466,8 @@ void SelectionTab::printMaps(SDL_Surface *to)
}
//print name
CSDL_Ext::printAtMiddle(CSDL_Ext::trimToFit(name, 185, FONT_SMALL), POS(213, 128), FONT_SMALL, itemColor, to);
printAtMiddleLoc(name, 213, 128 + line * 25, FONT_SMALL, itemColor, to);
}
#undef POS
}
void SelectionTab::showAll(SDL_Surface * to)
@ -1490,14 +1487,14 @@ void SelectionTab::showAll(SDL_Surface * to)
title = CGI->generaltexth->arraytxt[231];
break;
case CMenuScreen::campaignList:
title = "Select a Campaign"; //TODO: find where is the title
title = CGI->generaltexth->arraytxt[726];
break;
}
CSDL_Ext::printAtMiddle(title, pos.x+205, pos.y+28, FONT_MEDIUM, Colors::YELLOW, to); //Select a Scenario to Play
printAtMiddleLoc(title, 205, 28, FONT_MEDIUM, Colors::YELLOW, to); //Select a Scenario to Play
if(tabType != CMenuScreen::campaignList)
{
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[510], pos.x+87, pos.y+62, FONT_SMALL, Colors::YELLOW, to); //Map sizes
printAtMiddleLoc(CGI->generaltexth->allTexts[510], 87, 62, FONT_SMALL, Colors::YELLOW, to); //Map sizes
}
}
@ -1871,13 +1868,12 @@ CChatBox::CChatBox(const Rect &rect)
addUsedEvents(KEYBOARD);
captureAllKeys = true;
const int height = graphics->fonts[FONT_SMALL]->height;
const int height = graphics->fonts[FONT_SMALL]->getLineHeight();
inputBox = new CTextInput(Rect(0, rect.h - height, rect.w, height));
inputBox->removeUsedEvents(KEYBOARD);
chatHistory = new CTextBox("", Rect(0, 0, rect.w, rect.h - height), 1);
SDL_Color green = {0,252,0, SDL_ALPHA_OPAQUE};
chatHistory->color = green;
chatHistory->color = Colors::GREEN;
}
void CChatBox::keyPressed(const SDL_KeyboardEvent & key)
@ -1989,7 +1985,7 @@ void InfoCard::showAll(SDL_Surface * to)
{
if(i->second.playerID != PlayerSettings::PLAYER_AI)
{
printAtLoc(i->second.name, 24, 285 + playerSoFar++ * graphics->fonts[FONT_SMALL]->height, FONT_SMALL, Colors::WHITE, to);
printAtLoc(i->second.name, 24, 285 + playerSoFar++ * graphics->fonts[FONT_SMALL]->getLineHeight(), FONT_SMALL, Colors::WHITE, to);
playerNames.erase(i->second.playerID);
}
}
@ -1997,7 +1993,7 @@ void InfoCard::showAll(SDL_Surface * to)
playerSoFar = 0;
for (auto i = playerNames.cbegin(); i != playerNames.cend(); i++)
{
printAtLoc(i->second, 193, 285 + playerSoFar++ * graphics->fonts[FONT_SMALL]->height, FONT_SMALL, Colors::WHITE, to);
printAtLoc(i->second, 193, 285 + playerSoFar++ * graphics->fonts[FONT_SMALL]->getLineHeight(), FONT_SMALL, Colors::WHITE, to);
}
}
@ -2064,8 +2060,8 @@ void InfoCard::showAll(SDL_Surface * to)
printToLoc((static_cast<const CMapInfo*>(SEL->current))->date,308,34, FONT_SMALL, Colors::WHITE, to);
//print flags
int fx = 34 + graphics->fonts[FONT_SMALL]->getWidth(CGI->generaltexth->allTexts[390].c_str());
int ex = 200 + graphics->fonts[FONT_SMALL]->getWidth(CGI->generaltexth->allTexts[391].c_str());
int fx = 34 + graphics->fonts[FONT_SMALL]->getStringWidth(CGI->generaltexth->allTexts[390]);
int ex = 200 + graphics->fonts[FONT_SMALL]->getStringWidth(CGI->generaltexth->allTexts[391]);
int myT;
@ -2117,7 +2113,7 @@ void InfoCard::showAll(SDL_Surface * to)
//name
if (name.length())
printAtLoc(CSDL_Ext::trimToFit(name, 300, FONT_BIG), 26, 39, FONT_BIG, Colors::YELLOW, to);
printAtLoc(name, 26, 39, FONT_BIG, Colors::YELLOW, to);
else
printAtLoc("Unnamed", 26, 39, FONT_BIG, Colors::YELLOW, to);
}
@ -2150,14 +2146,16 @@ void InfoCard::clickRight( tribool down, bool previousState )
void InfoCard::showTeamsPopup()
{
SDL_Surface *bmp = CMessage::drawDialogBox(256, 90 + 50 * SEL->current->mapHeader->howManyTeams);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[657], 128, 30, FONT_MEDIUM, Colors::YELLOW, bmp); //{Team Alignments}
graphics->fonts[FONT_MEDIUM]->renderTextCenter(bmp, CGI->generaltexth->allTexts[657], Colors::YELLOW, Point(128, 30));
for(int i = 0; i < SEL->current->mapHeader->howManyTeams; i++)
{
std::vector<ui8> flags;
std::string hlp = CGI->generaltexth->allTexts[656]; //Team %d
hlp.replace(hlp.find("%d"), 2, boost::lexical_cast<std::string>(i+1));
CSDL_Ext::printAtMiddle(hlp, 128, 65 + 50*i, FONT_SMALL, Colors::WHITE, bmp);
graphics->fonts[FONT_SMALL]->renderTextCenter(bmp, hlp, Colors::WHITE, Point(128, 65 + 50 * i));
for(int j = 0; j < GameConstants::PLAYER_LIMIT; j++)
if((SEL->current->mapHeader->players[j].canHumanPlay || SEL->current->mapHeader->players[j].canComputerPlay)
@ -2224,11 +2222,11 @@ void OptionsTab::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
printAtMiddleLoc(CGI->generaltexth->allTexts[515], 222, 30, FONT_BIG, Colors::YELLOW, to);
printAtMiddleWBLoc(CGI->generaltexth->allTexts[516], 222, 58, FONT_SMALL, 55, Colors::WHITE, to); //Select starting options, handicap, and name for each player in the game.
printAtMiddleWBLoc(CGI->generaltexth->allTexts[517], 107, 102, FONT_SMALL, 14, Colors::YELLOW, to); //Player Name Handicap Type
printAtMiddleWBLoc(CGI->generaltexth->allTexts[518], 197, 102, FONT_SMALL, 10, Colors::YELLOW, to); //Starting Town
printAtMiddleWBLoc(CGI->generaltexth->allTexts[519], 273, 102, FONT_SMALL, 10, Colors::YELLOW, to); //Starting Hero
printAtMiddleWBLoc(CGI->generaltexth->allTexts[520], 349, 102, FONT_SMALL, 10, Colors::YELLOW, to); //Starting Bonus
printAtMiddleWBLoc(CGI->generaltexth->allTexts[516], 222, 68, FONT_SMALL, 300, Colors::WHITE, to); //Select starting options, handicap, and name for each player in the game.
printAtMiddleWBLoc(CGI->generaltexth->allTexts[517], 107, 110, FONT_SMALL, 100, Colors::YELLOW, to); //Player Name Handicap Type
printAtMiddleWBLoc(CGI->generaltexth->allTexts[518], 197, 110, FONT_SMALL, 70, Colors::YELLOW, to); //Starting Town
printAtMiddleWBLoc(CGI->generaltexth->allTexts[519], 273, 110, FONT_SMALL, 70, Colors::YELLOW, to); //Starting Hero
printAtMiddleWBLoc(CGI->generaltexth->allTexts[520], 349, 110, FONT_SMALL, 70, Colors::YELLOW, to); //Starting Bonus
printAtMiddleLoc(CGI->generaltexth->allTexts[521], 222, 538, FONT_SMALL, Colors::YELLOW, to); // Player Turn Duration
if (turnDuration)
printAtMiddleLoc(CGI->generaltexth->turnDurations[turnDuration->value], 319,559, FONT_SMALL, Colors::WHITE, to);//Turn duration value
@ -2558,7 +2556,7 @@ void OptionsTab::PlayerOptionsEntry::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
printAtMiddleLoc(s.name, 55, 10, FONT_SMALL, Colors::WHITE, to);
printAtMiddleWBLoc(CGI->generaltexth->arraytxt[206+whoCanPlay], 28, 34, FONT_TINY, 8, Colors::WHITE, to);
printAtMiddleWBLoc(CGI->generaltexth->arraytxt[206+whoCanPlay], 28, 39, FONT_TINY, 50, Colors::WHITE, to);
}
void OptionsTab::PlayerOptionsEntry::update()
@ -3130,16 +3128,15 @@ void CBonusSelection::init()
//campaign name
if (ourCampaign->camp->header.name.length())
CSDL_Ext::printAt(ourCampaign->camp->header.name, 481, 28, FONT_BIG, Colors::YELLOW, background);
graphics->fonts[FONT_BIG]->renderTextLeft(background, ourCampaign->camp->header.name, Colors::YELLOW, Point(481, 28));
else
CSDL_Ext::printAt("Unnamed", 481, 28, FONT_BIG, Colors::YELLOW, background);
graphics->fonts[FONT_BIG]->renderTextLeft(background, CGI->generaltexth->allTexts[508], Colors::YELLOW, Point(481, 28));
//map size icon
sizes = CDefHandler::giveDef("SCNRMPSZ.DEF");
//campaign description
CSDL_Ext::printAt(CGI->generaltexth->allTexts[38], 481, 63, FONT_SMALL, Colors::YELLOW, background);
graphics->fonts[FONT_SMALL]->renderTextLeft(background, CGI->generaltexth->allTexts[38], Colors::YELLOW, Point(481, 63));
cmpgDesc = new CTextBox(ourCampaign->camp->header.description, Rect(480, 86, 286, 117), 1);
//cmpgDesc->showAll(background);
@ -3148,7 +3145,7 @@ void CBonusSelection::init()
mapDesc = new CTextBox("", Rect(480, 280, 286, 117), 1);
//bonus choosing
CSDL_Ext::printAt(CGI->generaltexth->allTexts[71], 511, 432, FONT_MEDIUM, Colors::WHITE, background); //Choose a bonus:
graphics->fonts[FONT_MEDIUM]->renderTextLeft(background, CGI->generaltexth->allTexts[71], Colors::WHITE, Point(511, 432));
bonuses = new CHighlightableButtonsGroup(bind(&CBonusSelection::selectBonus, this, _1));
//set left part of window
@ -3181,15 +3178,15 @@ void CBonusSelection::init()
// }
//allies / enemies
CSDL_Ext::printAt(CGI->generaltexth->allTexts[390] + ":", 486, 407, FONT_SMALL, Colors::WHITE, background); //Allies
CSDL_Ext::printAt(CGI->generaltexth->allTexts[391] + ":", 619, 407, FONT_SMALL, Colors::WHITE, background); //Enemies
graphics->fonts[FONT_SMALL]->renderTextLeft(background, CGI->generaltexth->allTexts[390] + ":", Colors::WHITE, Point(486, 407));
graphics->fonts[FONT_SMALL]->renderTextLeft(background, CGI->generaltexth->allTexts[391] + ":", Colors::WHITE, Point(619, 407));
SDL_FreeSurface(panel);
//difficulty
std::vector<std::string> difficulty;
boost::split(difficulty, CGI->generaltexth->allTexts[492], boost::is_any_of(" "));
CSDL_Ext::printAt(difficulty.back(), 689, 432, FONT_MEDIUM, Colors::WHITE, background); //Difficulty
graphics->fonts[FONT_MEDIUM]->renderTextLeft(background, difficulty.back(), Colors::WHITE, Point(689, 432));
//difficulty pics
for (int b=0; b<ARRAY_COUNT(diffPics); ++b)
@ -3350,8 +3347,8 @@ void CBonusSelection::show(SDL_Surface * to)
blitAtLoc(sizes->ourImages[temp].bitmap, 735, 26, to);
//flags
int fx = 496 + graphics->fonts[FONT_SMALL]->getWidth(CGI->generaltexth->allTexts[390].c_str());
int ex = 629 + graphics->fonts[FONT_SMALL]->getWidth(CGI->generaltexth->allTexts[391].c_str());
int fx = 496 + graphics->fonts[FONT_SMALL]->getStringWidth(CGI->generaltexth->allTexts[390]);
int ex = 629 + graphics->fonts[FONT_SMALL]->getStringWidth(CGI->generaltexth->allTexts[391]);
int myT;
myT = ourHeader->players[playerColor].team;
for (auto i = sInfo.playerInfos.cbegin(); i != sInfo.playerInfos.cend(); i++)
@ -4045,7 +4042,9 @@ std::string CLoadingScreen::getBackground()
CLoadingScreen::CLoadingScreen(boost::function<void ()> loader):
CWindowObject(BORDERED, getBackground()),
loadingThread(loader)
{}
{
CCS->musich->stopMusic(5000);
}
CLoadingScreen::~CLoadingScreen()
{

View File

@ -321,7 +321,7 @@ void CSpellWindow::showAll(SDL_Surface * to)
std::ostringstream mana;
mana<<myHero->mana;
CSDL_Ext::printAtMiddle(mana.str(), pos.x+435, pos.y +426, FONT_SMALL, Colors::YELLOW, to);
printAtMiddleLoc(mana.str(), 435, 426, FONT_SMALL, Colors::YELLOW, to);
statusBar->showAll(to);
@ -800,12 +800,8 @@ void CSpellWindow::SpellArea::clickRight(tribool down, bool previousState)
boost::algorithm::replace_first(dmgInfo, "%d", boost::lexical_cast<std::string>(causedDmg));
}
SDL_Surface *spellBox = CMessage::drawBoxTextBitmapSub(
owner->myInt->playerID,
CGI->spellh->spells[mySpell]->descriptions[schoolLevel] + dmgInfo, this->owner->spells->ourImages[mySpell].bitmap,
CGI->spellh->spells[mySpell]->name,30,30);
CInfoPopup *vinya = new CInfoPopup(spellBox, true);
GH.pushInt(vinya);
CRClickPopup::createAndPush(CGI->spellh->spells[mySpell]->descriptions[schoolLevel] + dmgInfo,
new CComponent(CComponent::spell, mySpell));
}
}
@ -850,13 +846,13 @@ void CSpellWindow::SpellArea::showAll(SDL_Surface * to)
secondLineColor = Colors::WHITE;
}
//printing spell's name
CSDL_Ext::printAtMiddle(spell->name, pos.x + 39, pos.y + 70, FONT_TINY, firstLineColor, to);
printAtMiddleLoc(spell->name, 39, 70, FONT_TINY, firstLineColor, to);
//printing lvl
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[171 + spell->level], pos.x + 39, pos.y + 82, FONT_TINY, secondLineColor, to);
printAtMiddleLoc(CGI->generaltexth->allTexts[171 + spell->level], 39, 82, FONT_TINY, secondLineColor, to);
//printing cost
std::ostringstream ss;
ss << CGI->generaltexth->allTexts[387] << ": " << spellCost;
CSDL_Ext::printAtMiddle(ss.str(), pos.x + 39, pos.y + 94, FONT_TINY, secondLineColor, to);
printAtMiddleLoc(ss.str(), 39, 94, FONT_TINY, secondLineColor, to);
}
void CSpellWindow::SpellArea::setSpell(int spellID)

View File

@ -1,35 +0,0 @@
#pragma once
/*
* FontBase.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
enum EFonts
{
FONT_BIG, FONT_CALLI, FONT_CREDITS, FONT_HIGH_SCORE, FONT_MEDIUM, FONT_SMALL, FONT_TIMES, FONT_TINY, FONT_VERD
};
struct Font
{
struct Char
{
si32 leftOffset, width, rightOffset;
ui8 *pixels;
};
Char chars[256];
ui8 height;
ui8 *data;
Font(ui8 *Data);
~Font();
int getWidth(const char *text) const;
int getCharWidth(char c) const;
};

View File

@ -880,7 +880,7 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize)
std::vector<std::string> textLines = CMessage::breakText(getSubtitle(), std::max<int>(80, pos.w), font);
BOOST_FOREACH(auto & line, textLines)
{
int height = graphics->fonts[font]->height;
int height = graphics->fonts[font]->getLineHeight();
CLabel * label = new CLabel(pos.w/2, pos.h + height/2, font, CENTER, Colors::WHITE, line);
pos.h += height;
@ -1748,24 +1748,22 @@ void CMinorResDataBar::show(SDL_Surface * to)
void CMinorResDataBar::showAll(SDL_Surface * to)
{
blitAt(bg,pos.x,pos.y,to);
char buf[30];
for (int i=0;i<7;i++)
{
SDL_itoa(LOCPLINT->cb->getResourceAmount(i),buf,10);
CSDL_Ext::printAtMiddle(buf,pos.x + 50 + 76*i,pos.y+pos.h/2,FONT_SMALL,Colors::WHITE,to);
std::string text = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i));
graphics->fonts[FONT_SMALL]->renderTextCenter(to, text, Colors::WHITE, Point(pos.x + 50 + 76 * i, pos.y + pos.h/2));
}
std::vector<std::string> temp;
SDL_itoa(LOCPLINT->cb->getDate(3),buf,10); temp.push_back(std::string(buf));
SDL_itoa(LOCPLINT->cb->getDate(2),buf,10); temp.push_back(buf);
SDL_itoa(LOCPLINT->cb->getDate(1),buf,10); temp.push_back(buf);
CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(
CGI->generaltexth->allTexts[62]
+": %s, "
+ CGI->generaltexth->allTexts[63]
+ ": %s, "
+ CGI->generaltexth->allTexts[64]
+ ": %s",temp)
,pos.x+545+(pos.w-545)/2,pos.y+pos.h/2,FONT_SMALL,Colors::WHITE,to);
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(3)));
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(2)));
temp.push_back(boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(1)));
std::string datetext = CGI->generaltexth->allTexts[62]+": %s, " + CGI->generaltexth->allTexts[63]
+ ": %s, " + CGI->generaltexth->allTexts[64] + ": %s";
graphics->fonts[FONT_SMALL]->renderTextCenter(to, processStr(datetext,temp), Colors::WHITE, Point(pos.x+545+(pos.w-545)/2,pos.y+pos.h/2));
}
CMinorResDataBar::CMinorResDataBar()
@ -3663,7 +3661,7 @@ void CTavernWindow::show(SDL_Surface * to)
boost::algorithm::replace_first(recruit->hoverTexts[0],"%s",sel->h->type->heroClass->name);
}
printAtMiddleWB(sel->descr,pos.x+146,pos.y+389,FONT_SMALL,40,Colors::WHITE,to);
printAtMiddleWBLoc(sel->descr, 146, 389, FONT_SMALL, 200, Colors::WHITE, to);
CSDL_Ext::drawBorder(to,sel->pos.x-2,sel->pos.y-2,sel->pos.w+4,sel->pos.h+4,int3(247,223,123));
}
}
@ -3728,13 +3726,14 @@ void CInGameConsole::show(SDL_Surface * to)
boost::unique_lock<boost::mutex> lock(texts_mx);
for(std::list< std::pair< std::string, int > >::iterator it = texts.begin(); it != texts.end(); ++it, ++number)
{
SDL_Color green = {0,0xff,0,0};
Point leftBottomCorner(0, screen->h);
if(LOCPLINT->battleInt)
{
leftBottomCorner = LOCPLINT->battleInt->pos.bottomLeft();
}
CSDL_Ext::printAt(it->first, leftBottomCorner.x + 50, leftBottomCorner.y - texts.size() * 20 - 80 + number*20, FONT_MEDIUM, green);
graphics->fonts[FONT_MEDIUM]->renderTextLeft(to, it->first, Colors::GREEN,
Point(leftBottomCorner.x + 50, leftBottomCorner.y - texts.size() * 20 - 80 + number*20));
if(SDL_GetTicks() - it->second > defaultTimeout)
{
toDel.push_back(it);

View File

@ -124,7 +124,6 @@ Graphics::Graphics()
std::vector<Task> tasks; //preparing list of graphics to load
tasks += boost::bind(&Graphics::loadFonts,this);
tasks += boost::bind(&Graphics::loadTrueType,this);
tasks += boost::bind(&Graphics::loadPaletteAndColors,this);
tasks += boost::bind(&Graphics::loadHeroFlags,this);
tasks += boost::bind(&Graphics::initializeBattleGraphics,this);
@ -386,38 +385,24 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, int player)
}
}
void Graphics::loadTrueType()
{
for(int i = 0; i < FONTS_NUMBER; i++)
fontsTrueType[i] = NULL;
}
Font * Graphics::loadFont( const char * name )
{
ui8 * hlp = CResourceHandler::get()->loadData(
ResourceID(std::string("DATA/") + name, EResType::FONT)).first.release();
if(!hlp)
{
tlog1 << "Error: cannot load font: " << name << std::endl;
return NULL;
}
int magic = SDL_SwapLE32(*(const Uint32*)hlp);
if(magic != 589598 && magic != 589599)
tlog1 << "Suspicious font file, fname " << name << "n";
Font *ret = new Font(hlp);
return ret;
}
void Graphics::loadFonts()
{
static const char *fontnames [] = {"BIGFONT.FNT", "CALLI10R.FNT", "CREDITS.FNT", "HISCORE.FNT", "MEDFONT.FNT",
"SMALFONT.FNT", "TIMES08R.FNT", "TINY.FNT", "VERD10B.FNT"} ;
const JsonNode config(ResourceID("config/fonts.json"));
assert(ARRAY_COUNT(fontnames) == FONTS_NUMBER);
for(int i = 0; i < FONTS_NUMBER; i++)
fonts[i] = loadFont(fontnames[i]);
const JsonVector & bmpConf = config["bitmap"].Vector();
const JsonNode & ttfConf = config["trueType"];
assert(bmpConf.size() == FONTS_NUMBER);
for (size_t i=0; i<FONTS_NUMBER; i++)
{
std::string filename = bmpConf[i].String();
if (ttfConf[filename].isNull()) // no ttf override
fonts[i] = new CBitmapFont(filename);
else
fonts[i] = new CTrueTypeFont(ttfConf[filename]);
}
}
CDefEssential * Graphics::getDef( const CGObjectInstance * obj )
@ -447,60 +432,3 @@ void Graphics::loadErmuToPicture()
}
assert (etp_idx == 44);
}
Font::Font(ui8 *Data)
{
data = Data;
int i = 0;
height = data[5];
i = 32;
for(int ci = 0; ci < 256; ci++)
{
chars[ci].leftOffset = read_le_u32(data + i); i+=4;
chars[ci].width = read_le_u32(data + i); i+=4;
chars[ci].rightOffset = read_le_u32(data + i); i+=4;
//if(ci>=30)
// tlog0 << ci << ". (" << (char)ci << "). Width: " << chars[ci].width << " U1/U2:" << chars[ci].unknown1 << "/" << chars[ci].unknown2 << std::endl;
}
for(int ci = 0; ci < 256; ci++)
{
int offset = read_le_u32(data + i); i+=4;
chars[ci].pixels = data + 4128 + offset;
}
}
Font::~Font()
{
delete [] data;
}
int Font::getWidth(const char *text ) const
{
int length = std::strlen(text);
int ret = 0;
for(int i = 0; i < length; i++)
{
ui8 c = text[i];
ret += chars[c].width + chars[c].leftOffset + chars[c].rightOffset;
}
return ret;
}
int Font::getCharWidth( char c ) const
{
const Char &C = chars[(ui8)c];
return C.width + C.leftOffset + C.rightOffset;;
}
/*
void Font::WriteAt(const char *text, SDL_Surface *sur, int x, int y )
{
SDL_Surface *SDL_CreateRGBSurfaceFrom(pixels, w, h, 8, int pitch,
224, 28, 3, 0);
}
*/

View File

@ -1,7 +1,7 @@
#pragma once
#include "FontBase.h"
#include "UIFramework/Fonts.h"
#include "../lib/GameConstants.h"
#include "UIFramework/Geometries.h"
@ -27,7 +27,10 @@ struct InfoAboutTown;
class CGObjectInstance;
class CGDefInfo;
typedef struct _TTF_Font TTF_Font; //from SDL_ttf.h
enum EFonts
{
FONT_BIG, FONT_CALLI, FONT_CREDITS, FONT_HIGH_SCORE, FONT_MEDIUM, FONT_SMALL, FONT_TIMES, FONT_TINY, FONT_VERD
};
/// Handles fonts, hero images, town images, various graphics
class Graphics
@ -35,9 +38,8 @@ class Graphics
public:
//Fonts
static const int FONTS_NUMBER = 9;
Font *fonts[FONTS_NUMBER];
TTF_Font * fontsTrueType[FONTS_NUMBER];//true type fonts, if some of the fonts not loaded - NULL
IFont * fonts[FONTS_NUMBER];
\
//various graphics
SDL_Color * playerColors; //array [8]
SDL_Color * neutralColor;
@ -77,9 +79,7 @@ public:
CDefEssential * loadHeroAnim(const std::string &name, const std::vector<std::pair<int,int> > &rotations);
void loadErmuToPicture();
void blueToPlayersAdv(SDL_Surface * sur, int player); //replaces blue interface colour with a color of player
void loadTrueType();
void loadFonts();
Font *loadFont(const char * name);
};
extern Graphics * graphics;

View File

@ -424,7 +424,7 @@ void CGuiHandler::drawFPSCounter()
Uint32 black = SDL_MapRGB(screen->format, 10, 10, 10);
SDL_FillRect(screen, &overlay, black);
std::string fps = boost::lexical_cast<std::string>(mainFPSmng->fps);
CSDL_Ext::printAt(fps, 10, 10, FONT_BIG, yellow, screen);
graphics->fonts[FONT_BIG]->renderTextLeft(screen, fps, yellow, Point(10, 10));
}
SDLKey CGuiHandler::arrowToNum( SDLKey key )

View File

@ -2,6 +2,7 @@
#include "CIntObject.h"
#include "CGuiHandler.h"
#include "SDL_Extensions.h"
#include "CMessage.h"
CIntObject::CIntObject(int used_, Point pos_):
parent_m(nullptr),
@ -129,17 +130,17 @@ CIntObject::~CIntObject()
void CIntObject::printAtLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::WHITE*/, SDL_Surface * dst/*=screen*/ )
{
CSDL_Ext::printAt(text, pos.x + x, pos.y + y, font, kolor, dst);
graphics->fonts[font]->renderTextLeft(dst, text, kolor, Point(pos.x + x, pos.y + y));
}
void CIntObject::printAtMiddleLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::WHITE*/, SDL_Surface * dst/*=screen*/ )
{
CSDL_Ext::printAtMiddle(text, pos.x + x, pos.y + y, font, kolor, dst);
printAtMiddleLoc(text, Point(x,y), font, kolor, dst);
}
void CIntObject::printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, SDL_Color kolor, SDL_Surface * dst)
{
printAtMiddleLoc(text, p.x, p.y, font, kolor, dst);
graphics->fonts[font]->renderTextCenter(dst, text, kolor, pos.topLeft() + p);
}
void CIntObject::blitAtLoc( SDL_Surface * src, int x, int y, SDL_Surface * dst )
@ -154,12 +155,12 @@ void CIntObject::blitAtLoc(SDL_Surface * src, const Point &p, SDL_Surface * dst)
void CIntObject::printAtMiddleWBLoc( const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst)
{
CSDL_Ext::printAtMiddleWB(text, pos.x + x, pos.y + y, font, charpr, kolor, dst);
graphics->fonts[font]->renderTextLinesCenter(dst, CMessage::breakText(text, charpr, font), kolor, Point(pos.x + x, pos.y + y));
}
void CIntObject::printToLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst )
{
CSDL_Ext::printTo(text, pos.x + x, pos.y + y, font, kolor, dst);
graphics->fonts[font]->renderTextRight(dst, text, kolor, Point(pos.x + x, pos.y + y));
}
void CIntObject::addUsedEvents(ui16 newActions)

View File

@ -2,7 +2,7 @@
#include <SDL_events.h>
#include "Geometries.h"
#include "../FontBase.h"
#include "../Graphics.h"
struct SDL_Surface;
class CPicture;

View File

@ -1147,7 +1147,8 @@ void CStatusBar::show(SDL_Surface * to)
SDL_Rect srcRect = genRect(pos.h,pos.w,0,0);
SDL_Rect dstRect = genRect(pos.h,pos.w,pos.x,pos.y);
CSDL_Ext::blitSurface(bg,&srcRect,to,&dstRect);
CSDL_Ext::printAtMiddle(current,middlex,middley,FONT_SMALL,Colors::WHITE,to);
graphics->fonts[FONT_SMALL]->renderTextCenter(to, current, Colors::WHITE, Point(middlex, middley));
}
std::string CStatusBar::getCurrent()
@ -1214,8 +1215,18 @@ void CLabel::showAll(SDL_Surface * to)
if(!toPrint.length())
return;
static void (*printer[3])(const std::string &, int, int, EFonts, SDL_Color, SDL_Surface *) = {&CSDL_Ext::printAt, &CSDL_Ext::printAtMiddle, &CSDL_Ext::printTo}; //array of printing functions
printer[alignment](toPrint, pos.x + textOffset.x, pos.y + textOffset.y, font, color, to);
switch (alignment)
{
break; case TOPLEFT :
CIntObject::printAtLoc(toPrint, textOffset.x, textOffset.y, font, color, to);
break; case CENTER :
CIntObject::printAtMiddleLoc(toPrint, textOffset.x, textOffset.y, font, color, to);
break; case BOTTOMRIGHT :
CIntObject::printToLoc(toPrint, textOffset.x, textOffset.y, font, color, to);
break; default :
assert(0);
}
}
CLabel::CLabel(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, const SDL_Color &Color /*= Colors::WHITE*/, const std::string &Text /*= ""*/)
@ -1228,8 +1239,8 @@ CLabel::CLabel(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, con
bg = NULL;
ignoreLeadingWhitespace = false;
pos.w = graphics->fonts[font]->getWidth(text.c_str());
pos.h = graphics->fonts[font]->height;
pos.w = graphics->fonts[font]->getStringWidth(text.c_str());
pos.h = graphics->fonts[font]->getLineHeight();
}
std::string CLabel::visibleText()
@ -1267,7 +1278,7 @@ void CBoundedLabel::setTxt(const std::string &Txt)
void CBoundedLabel::blitLine(SDL_Surface *to, Point where, std::string what)
{
const Font &f = *graphics->fonts[font];
const IFont * f = graphics->fonts[font];
size_t begin = 0;
size_t end;
@ -1277,14 +1288,16 @@ void CBoundedLabel::blitLine(SDL_Surface *to, Point where, std::string what)
do
{
end = what.find_first_of(delimeters[currDelimeter % 2], begin);
std::string toPrint = what.substr(begin, end);
if (currDelimeter % 2)
CSDL_Ext::printAt(toPrint, where.x, where.y, font, Colors::YELLOW, to);
else
CSDL_Ext::printAt(toPrint, where.x, where.y, font, color, to);
begin = end;
where.x += f.getWidth(toPrint.c_str());
if (begin != end)
{
std::string toPrint = what.substr(begin, end-1);
if (currDelimeter % 2) // Enclosed in {} text - set to yellow
graphics->fonts[font]->renderTextLeft(to, toPrint, Colors::YELLOW, where);
else // Non-enclosed text
graphics->fonts[font]->renderTextLeft(to, toPrint, color, where);
begin = end;
where.x += f->getStringWidth(toPrint.c_str());
}
currDelimeter++;
}
while (begin++ != std::string::npos);
@ -1294,11 +1307,11 @@ void CBoundedLabel::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
const Font &f = *graphics->fonts[font];
int lineHeight = f.height;
const IFont * f = graphics->fonts[font];
int lineHeight = f->getLineHeight();
int lineCapacity = pos.h / lineHeight;
int dy = f.height; //line height
int dy = f->getLineHeight(); //line height
int base_y = pos.y;
if(alignment == CENTER)
base_y += std::max((pos.h - maxH)/2,0);
@ -1312,7 +1325,7 @@ void CBoundedLabel::showAll(SDL_Surface * to)
int x = pos.x;
if(alignment == CENTER)
{
x += (pos.w - f.getWidth(line.c_str())) / 2;
x += pos.w - f->getStringWidth(line.c_str()) / 2;
}
blitLine(to, Point(x, base_y + i * dy), line);
@ -1323,15 +1336,15 @@ void CBoundedLabel::recalculateLines(const std::string &Txt)
{
lines.clear();
const Font &f = *graphics->fonts[font];
int lineHeight = f.height;
const IFont * f = graphics->fonts[font];
int lineHeight = f->getLineHeight();
lines = CMessage::breakText(Txt, pos.w, font);
maxH = lineHeight * lines.size();
maxW = 0;
BOOST_FOREACH(const std::string &line, lines)
vstd::amax(maxW, f.getWidth(line.c_str()));
vstd::amax(maxW, f->getStringWidth(line.c_str()));
}
CLabelGroup::CLabelGroup(EFonts Font, EAlignment Align, const SDL_Color &Color):
@ -1362,8 +1375,8 @@ void CTextBox::recalculateLines(const std::string &Txt)
vstd::clear_pointer(slider);
lines.clear();
const Font &f = *graphics->fonts[font];
int lineHeight = f.height;
const IFont * f = graphics->fonts[font];
int lineHeight = f->getLineHeight();
int lineCapacity = pos.h / lineHeight;
lines = CMessage::breakText(Txt, pos.w, font);
@ -1379,15 +1392,15 @@ void CTextBox::recalculateLines(const std::string &Txt)
maxH = lineHeight * lines.size();
maxW = 0;
BOOST_FOREACH(const std::string &line, lines)
vstd::amax(maxW, f.getWidth(line.c_str()));
vstd::amax(maxW, f->getStringWidth(line));
}
void CTextBox::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
const Font &f = *graphics->fonts[font];
int dy = f.height; //line height
const IFont * f = graphics->fonts[font];
int dy = f->getLineHeight(); //line height
int base_y = pos.y;
if(alignment == CENTER)
base_y += std::max((pos.h - maxH)/2,0);
@ -1403,7 +1416,7 @@ void CTextBox::showAll(SDL_Surface * to)
int x = pos.x;
if(alignment == CENTER)
{
x += (pos.w - f.getWidth(line.c_str())) / 2;
x += (pos.w - f->getStringWidth(line.c_str())) / 2;
if(slider)
x -= slider->pos.w / 2 + 5;
}

View File

@ -0,0 +1,274 @@
#include "StdInc.h"
#include "Fonts.h"
#include <SDL_ttf.h>
#include "SDL_Pixels.h"
#include "../../lib/JsonNode.h"
#include "../../lib/vcmi_endian.h"
#include "../../lib/Filesystem/CResourceLoader.h"
/*
* Fonts.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
void IFont::renderTextLeft(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const
{
renderText(surface, data, color, pos);
}
void IFont::renderTextRight(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const
{
Point size(getStringWidth(data), getLineHeight());
renderText(surface, data, color, pos - size);
}
void IFont::renderTextCenter(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const
{
Point size(getStringWidth(data), getLineHeight());
renderText(surface, data, color, pos - size / 2);
}
void IFont::renderTextLinesLeft(SDL_Surface * surface, const std::vector<std::string> & data, const SDL_Color & color, const Point & pos) const
{
Point currPos = pos;
BOOST_FOREACH(const std::string & line, data)
{
renderTextLeft(surface, line, color, currPos);
currPos.y += getLineHeight();
}
}
void IFont::renderTextLinesRight(SDL_Surface * surface, const std::vector<std::string> & data, const SDL_Color & color, const Point & pos) const
{
Point currPos = pos;
currPos.y -= data.size() * getLineHeight();
BOOST_FOREACH(const std::string & line, data)
{
renderTextRight(surface, line, color, currPos);
currPos.y += getLineHeight();
}
}
void IFont::renderTextLinesCenter(SDL_Surface * surface, const std::vector<std::string> & data, const SDL_Color & color, const Point & pos) const
{
Point currPos = pos;
currPos.y -= data.size() * getLineHeight()/2;
BOOST_FOREACH(const std::string & line, data)
{
renderTextCenter(surface, line, color, currPos);
currPos.y += getLineHeight();
}
}
std::array<CBitmapFont::Char, CBitmapFont::totalChars> CBitmapFont::loadChars() const
{
std::array<Char, totalChars> ret;
size_t offset = 32;
for (size_t i=0; i< ret.size(); i++)
{
ret[i].leftOffset = read_le_u32(data.first.get() + offset); offset+=4;
ret[i].width = read_le_u32(data.first.get() + offset); offset+=4;
ret[i].rightOffset = read_le_u32(data.first.get() + offset); offset+=4;
}
for (size_t i=0; i< ret.size(); i++)
{
int pixelOffset = read_le_u32(data.first.get() + offset); offset+=4;
ret[i].pixels = data.first.get() + 4128 + pixelOffset;
assert(pixelOffset + 4128 < data.second);
}
return ret;
}
CBitmapFont::CBitmapFont(const std::string & filename):
data(CResourceHandler::get()->loadData(ResourceID("data/" + filename, EResType::BMP_FONT))),
chars(loadChars()),
height(data.first.get()[5])
{}
size_t CBitmapFont::getLineHeight() const
{
return height;
}
size_t CBitmapFont::getSymbolWidth(char data) const
{
const Char & ch = chars[ui8(data)];
return ch.leftOffset + ch.width + ch.rightOffset;
}
size_t CBitmapFont::getStringWidth(const std::string & data) const
{
size_t width = 0;
BOOST_FOREACH(auto & ch, data)
{
width += getSymbolWidth(ch);
}
return width;
}
void CBitmapFont::renderCharacter(SDL_Surface * surface, const Char & character, const SDL_Color & color, int &posX, int &posY) const
{
Rect clipRect;
SDL_GetClipRect(surface, &clipRect);
posX += character.leftOffset;
TColorPutter colorPutter = CSDL_Ext::getPutterFor(surface, 0);
Uint8 bpp = surface->format->BytesPerPixel;
// start of line, may differ from 0 due to end of surface or clipped surface
int lineBegin = std::max<int>(0, clipRect.y - posY);
int lineEnd = std::min<int>(height, clipRect.y + clipRect.h - posY - 1);
// start end end of each row, may differ from 0
int rowBegin = std::max<int>(0, clipRect.x - posX);
int rowEnd = std::min<int>(character.width, clipRect.x + clipRect.w - posX - 1);
//for each line in symbol
for(int dy = lineBegin; dy <lineEnd; dy++)
{
Uint8 *dstLine = (Uint8*)surface->pixels;
Uint8 *srcLine = character.pixels;
// shift source\destination pixels to current position
dstLine += (posY+dy) * surface->pitch + posX * bpp;
srcLine += dy * character.width;
//for each column in line
for(int dx = rowBegin; dx < rowEnd; dx++)
{
Uint8* dstPixel = dstLine + dx*bpp;
switch(srcLine[dx])
{
case 1: //black "shadow"
std::fill(dstPixel, dstPixel + bpp, 0);
break;
case 255: //text colour
colorPutter(dstPixel, color.r, color.g, color.b);
break;
default :
break; //transparency
}
}
}
posX += character.width;
posX += character.rightOffset;
}
void CBitmapFont::renderText(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const
{
if (data.empty())
return;
assert(surface);
int posX = pos.x;
int posY = pos.y;
// Safe to remove but I would like to trace all cases of this. Please report on Mantis or send note to me
// Ivan
assert(data[0] != '{');
assert(data[data.size()-1] != '}');
SDL_LockSurface(surface);
// for each symbol
for(size_t index = 0; index < data.size(); index++)
{
renderCharacter(surface, chars[ui8(data[index])], color, posX, posY);
}
SDL_UnlockSurface(surface);
}
std::pair<std::unique_ptr<ui8[]>, ui64> CTrueTypeFont::loadData(const JsonNode & config)
{
std::string filename = "Data/" + config["file"].String();
return CResourceHandler::get()->loadData(ResourceID(filename, EResType::TTF_FONT));
}
TTF_Font * CTrueTypeFont::loadFont(const JsonNode &config)
{
int pointSize = config["size"].Float();
if(!TTF_WasInit() && TTF_Init()==-1)
throw std::runtime_error(std::string("Failed to initialize true type support: ") + TTF_GetError() + "\n");
return TTF_OpenFontRW(SDL_RWFromConstMem(data.first.get(), data.second), 1, pointSize);
}
int CTrueTypeFont::getFontStyle(const JsonNode &config)
{
const JsonVector & names = config["style"].Vector();
int ret = 0;
BOOST_FOREACH(const JsonNode & node, names)
{
if (node.String() == "bold")
ret |= TTF_STYLE_BOLD;
else if (node.String() == "italic")
ret |= TTF_STYLE_ITALIC;
}
return ret;
}
CTrueTypeFont::CTrueTypeFont(const JsonNode & fontConfig):
data(loadData(fontConfig)),
font(loadFont(fontConfig), TTF_CloseFont),
blended(fontConfig["blend"].Bool())
{
assert(font);
TTF_SetFontStyle(font.get(), getFontStyle(fontConfig));
}
size_t CTrueTypeFont::getLineHeight() const
{
return TTF_FontHeight(font.get());
}
size_t CTrueTypeFont::getSymbolWidth(char data) const
{
int advance;
TTF_GlyphMetrics(font.get(), data, NULL, NULL, NULL, NULL, &advance);
return advance;
}
size_t CTrueTypeFont::getStringWidth(const std::string & data) const
{
int width;
TTF_SizeText(font.get(), data.c_str(), &width, NULL);
return width;
}
void CTrueTypeFont::renderText(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const
{
if (!data.empty())
{
SDL_Surface * rendered;
if (blended)
rendered = TTF_RenderText_Solid(font.get(), data.c_str(), color);
else
rendered = TTF_RenderText_Blended(font.get(), data.c_str(), color);
assert(rendered);
Rect rect(pos.x, pos.y, rendered->w, rendered->h);
SDL_BlitSurface(rendered, NULL, surface, &rect);
SDL_FreeSurface(rendered);
}
}

110
client/UIFramework/Fonts.h Normal file
View File

@ -0,0 +1,110 @@
#pragma once
/*
* Fonts.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
class JsonNode;
struct Point;
struct SDL_Surface;
struct SDL_Color;
typedef struct _TTF_Font TTF_Font;
class IFont
{
protected:
/// Internal function to render font, see renderTextLeft
virtual void renderText(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const = 0;
public:
virtual ~IFont()
{}
/// Returns height of font
virtual size_t getLineHeight() const = 0;
/// Returns width of a single symbol
virtual size_t getSymbolWidth(char data) const = 0;
/// Return width of the string
virtual size_t getStringWidth(const std::string & data) const = 0;
/**
* @param surface - destination to print text on
* @param data - string to print
* @param color - font color
* @param pos - position of rendered font
*/
/// pos = topleft corner of the text
void renderTextLeft(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const;
/// pos = center of the text
void renderTextRight(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const;
/// pos = bottomright corner of the text
void renderTextCenter(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const;
/**
* @param maxWidth - max width in pixels of one line
*/
/// pos = topleft corner of the text
void renderTextLinesLeft(SDL_Surface * surface, const std::vector<std::string> & data, const SDL_Color & color, const Point & pos) const;
/// pos = center of the text
void renderTextLinesRight(SDL_Surface * surface, const std::vector<std::string> & data, const SDL_Color & color, const Point & pos) const;
/// pos = bottomright corner of the text
void renderTextLinesCenter(SDL_Surface * surface, const std::vector<std::string> & data, const SDL_Color & color, const Point & pos) const;
};
class CBitmapFont : public IFont
{
static const size_t totalChars = 256;
struct Char
{
si32 leftOffset;
ui32 width;
si32 rightOffset;
ui8 *pixels; // pixels of this character, part of BitmapFont::data
};
const std::pair<std::unique_ptr<ui8[]>, ui64> data;
const std::array<Char, totalChars> chars;
const ui8 height;
std::array<Char, totalChars> loadChars() const;
void renderCharacter(SDL_Surface * surface, const Char & character, const SDL_Color & color, int &posX, int &posY) const;
void renderText(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const;
public:
CBitmapFont(const std::string & filename);
size_t getLineHeight() const;
size_t getSymbolWidth(char data) const;
size_t getStringWidth(const std::string & data) const;
};
class CTrueTypeFont : public IFont
{
const std::pair<std::unique_ptr<ui8[]>, ui64> data;
const std::unique_ptr<TTF_Font, void (*)(TTF_Font*)> font;
const bool blended;
std::pair<std::unique_ptr<ui8[]>, ui64> loadData(const JsonNode & config);
TTF_Font * loadFont(const JsonNode & config);
int getFontStyle(const JsonNode & config);
void renderText(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const;
public:
CTrueTypeFont(const JsonNode & fontConfig);
size_t getLineHeight() const;
size_t getSymbolWidth(char data) const;
size_t getStringWidth(const std::string & data) const;
};

View File

@ -48,6 +48,12 @@ struct Point
return Point(x+b.x,y+b.y);
}
template<typename T>
Point operator/(const T &div) const
{
return Point(x/div, y/div);
}
template<typename T>
Point operator*(const T &mul) const
{

View File

@ -11,6 +11,7 @@
const SDL_Color Colors::YELLOW = { 229, 215, 123, 0 };
const SDL_Color Colors::WHITE = { 255, 243, 222, 0 };
const SDL_Color Colors::METALLIC_GOLD = { 173, 142, 66, 0 };
const SDL_Color Colors::GREEN = { 0, 255, 0, 0 };
SDL_Surface * CSDL_Ext::newSurface(int w, int h, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given
{
@ -76,311 +77,6 @@ void updateRect (SDL_Rect * rect, SDL_Surface * scr)
SDL_UpdateRect(scr,rect->x,rect->y,rect->w,rect->h);
}
void printAtMiddleWB(const std::string & text, int x, int y, TTF_Font * font, int charpr, SDL_Color kolor, SDL_Surface * dst)
{
std::vector<std::string> ws = CMessage::breakText(text,charpr);
std::vector<SDL_Surface*> wesu;
wesu.resize(ws.size());
for (size_t i=0; i < wesu.size(); ++i)
{
wesu[i]=TTF_RenderText_Blended(font,ws[i].c_str(),kolor);
}
int tox=0, toy=0;
for (size_t i=0; i < wesu.size(); ++i)
{
toy+=wesu[i]->h;
if (tox < wesu[i]->w)
tox=wesu[i]->w;
}
int evx, evy = y - (toy/2);
for (size_t i=0; i < wesu.size(); ++i)
{
evx = (x - (tox/2)) + ((tox-wesu[i]->w)/2);
blitAt(wesu[i],evx,evy,dst);
evy+=wesu[i]->h;
}
for (size_t i=0; i < wesu.size(); ++i)
SDL_FreeSurface(wesu[i]);
}
void printAtWB(const std::string & text, int x, int y, TTF_Font * font, int charpr, SDL_Color kolor, SDL_Surface * dst)
{
std::vector<std::string> ws = CMessage::breakText(text,charpr);
std::vector<SDL_Surface*> wesu;
wesu.resize(ws.size());
for (size_t i=0; i < wesu.size(); ++i)
wesu[i]=TTF_RenderText_Blended(font,ws[i].c_str(),kolor);
int evy = y;
for (size_t i=0; i < wesu.size(); ++i)
{
blitAt(wesu[i],x,evy,dst);
evy+=wesu[i]->h;
}
for (size_t i=0; i < wesu.size(); ++i)
SDL_FreeSurface(wesu[i]);
}
void CSDL_Ext::printAtWB(const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst)
{
if (graphics->fontsTrueType[font])
{
printAtWB(text,x, y, graphics->fontsTrueType[font], charpr, kolor, dst);
return;
}
const Font *f = graphics->fonts[font];
std::vector<std::string> ws = CMessage::breakText(text,charpr);
int cury = y;
for (size_t i=0; i < ws.size(); ++i)
{
printAt(ws[i], x, cury, font, kolor, dst);
cury += f->height;
}
}
void CSDL_Ext::printAtMiddleWB( const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor/*=Colors::YELLOW*/, SDL_Surface * dst/*=screen*/ )
{
if (graphics->fontsTrueType[font])
{
printAtMiddleWB(text,x, y, graphics->fontsTrueType[font], charpr, kolor, dst);
return;
}
const Font *f = graphics->fonts[font];
std::vector<std::string> ws = CMessage::breakText(text,charpr);
int totalHeight = ws.size() * f->height;
int cury = y - totalHeight/2;
for (size_t i=0; i < ws.size(); ++i)
{
printAt(ws[i], x - f->getWidth(ws[i].c_str())/2, cury, font, kolor, dst);
cury += f->height;
}
}
void printAtMiddle(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, ui8 quality=2)
{
if(text.length()==0) return;
SDL_Surface * temp;
switch (quality)
{
case 0:
temp = TTF_RenderText_Solid(font,text.c_str(),kolor);
break;
case 1:
SDL_Color tem;
tem.b = 0xff-kolor.b;
tem.g = 0xff-kolor.g;
tem.r = 0xff-kolor.r;
tem.unused = 0xff-kolor.unused;
temp = TTF_RenderText_Shaded(font,text.c_str(),kolor,tem);
break;
case 2:
temp = TTF_RenderText_Blended(font,text.c_str(),kolor);
break;
default:
temp = TTF_RenderText_Blended(font,text.c_str(),kolor);
break;
}
SDL_Rect dstRect = genRect(temp->h, temp->w, x-(temp->w/2), y-(temp->h/2));
CSDL_Ext::blitSurface(temp, NULL, dst, &dstRect);
SDL_FreeSurface(temp);
}
void CSDL_Ext::printAtMiddle( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::WHITE*/, SDL_Surface * dst/*=screen*/ )
{
if (graphics->fontsTrueType[font])
{
printAtMiddle(text,x, y, graphics->fontsTrueType[font], kolor, dst);
return;
}
const Font *f = graphics->fonts[font];
int nx = x - f->getWidth(text.c_str())/2,
ny = y - f->height/2;
printAt(text, nx, ny, font, kolor, dst);
}
void printAt(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, ui8 quality=2, bool refresh=false)
{
if (text.length()==0)
return;
SDL_Surface * temp;
switch (quality)
{
case 0:
temp = TTF_RenderText_Solid(font,text.c_str(),kolor);
break;
case 1:
SDL_Color tem;
tem.b = 0xff-kolor.b;
tem.g = 0xff-kolor.g;
tem.r = 0xff-kolor.r;
tem.unused = 0xff-kolor.unused;
temp = TTF_RenderText_Shaded(font,text.c_str(),kolor,tem);
break;
case 2:
temp = TTF_RenderText_Blended(font,text.c_str(),kolor);
break;
default:
temp = TTF_RenderText_Blended(font,text.c_str(),kolor);
break;
}
SDL_Rect dstRect = genRect(temp->h,temp->w,x,y);
CSDL_Ext::blitSurface(temp,NULL,dst,&dstRect);
if(refresh)
SDL_UpdateRect(dst,x,y,temp->w,temp->h);
SDL_FreeSurface(temp);
}
void CSDL_Ext::printAt( const std::string & text, int dstX, int dstY, EFonts font, SDL_Color color, SDL_Surface * dst)
{
if(!text.size())
return;
if (graphics->fontsTrueType[font])
{
printAt(text,dstX, dstY, graphics->fontsTrueType[font], color, dst);
return;
}
assert(dst);
assert(font < Graphics::FONTS_NUMBER);
Rect clipRect;
SDL_GetClipRect(dst, &clipRect);
const Font *f = graphics->fonts[font];
const Uint8 bpp = dst->format->BytesPerPixel;
TColorPutter colorPutter = getPutterFor(dst, 0);
//if text is in {} braces, we'll ommit them
const int textBegin = (text[0] == '{' ? 1 : 0);
const int textEnd = (text[text.size()-1] == '}' ? text.size()-1 : text.size());
SDL_LockSurface(dst);
// for each symbol
for(int index = textBegin; index < textEnd; index++)
{
const ui8 symbol = text[index];
dstX += f->chars[symbol].leftOffset;
int lineBegin = std::max<int>(0, clipRect.y - dstY);
int lineEnd = std::min<int>(f->height, clipRect.y + clipRect.h - dstY - 1);
int rowBegin = std::max(0, clipRect.x - dstX);
int rowEnd = std::min(f->chars[symbol].width, clipRect.x + clipRect.w - dstX - 1);
//for each line in symbol
for(int dy = lineBegin; dy <lineEnd; dy++)
{
Uint8 *dstLine = (Uint8*)dst->pixels;
Uint8 *srcLine = f->chars[symbol].pixels;
dstLine += (dstY+dy) * dst->pitch + dstX * bpp;
srcLine += dy * f->chars[symbol].width;
//for each column in line
for(int dx = rowBegin; dx < rowEnd; dx++)
{
Uint8* dstPixel = dstLine + dx*bpp;
switch(*(srcLine + dx))
{
case 1: //black "shadow"
memset(dstPixel, 0, bpp);
break;
case 255: //text colour
colorPutter(dstPixel, color.r, color.g, color.b);
break;
}
}
}
dstX += f->chars[symbol].width;
dstX += f->chars[symbol].rightOffset;
}
SDL_UnlockSurface(dst);
}
void printTo(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, ui8 quality=2)
{
if (text.length()==0)
return;
SDL_Surface * temp;
switch (quality)
{
case 0:
temp = TTF_RenderText_Solid(font,text.c_str(),kolor);
break;
case 1:
SDL_Color tem;
tem.b = 0xff-kolor.b;
tem.g = 0xff-kolor.g;
tem.r = 0xff-kolor.r;
tem.unused = 0xff-kolor.unused;
temp = TTF_RenderText_Shaded(font,text.c_str(),kolor,tem);
break;
case 2:
temp = TTF_RenderText_Blended(font,text.c_str(),kolor);
break;
default:
temp = TTF_RenderText_Blended(font,text.c_str(),kolor);
break;
}
SDL_Rect dstRect = genRect(temp->h,temp->w,x-temp->w,y-temp->h);
CSDL_Ext::blitSurface(temp,NULL,dst,&dstRect);
SDL_UpdateRect(dst,x-temp->w,y-temp->h,temp->w,temp->h);
SDL_FreeSurface(temp);
}
void CSDL_Ext::printTo( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=Colors::WHITE*/, SDL_Surface * dst/*=screen*/ )
{
if (graphics->fontsTrueType[font])
{
printTo(text,x, y, graphics->fontsTrueType[font], kolor, dst);
return;
}
const Font *f = graphics->fonts[font];
printAt(text, x - f->getWidth(text.c_str()), y - f->height, font, kolor, dst);
}
void printToWR(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, ui8 quality=2)
{
if (text.length()==0)
return;
SDL_Surface * temp;
switch (quality)
{
case 0:
temp = TTF_RenderText_Solid(font,text.c_str(),kolor);
break;
case 1:
SDL_Color tem;
tem.b = 0xff-kolor.b;
tem.g = 0xff-kolor.g;
tem.r = 0xff-kolor.r;
tem.unused = 0xff-kolor.unused;
temp = TTF_RenderText_Shaded(font,text.c_str(),kolor,tem);
break;
case 2:
temp = TTF_RenderText_Blended(font,text.c_str(),kolor);
break;
default:
temp = TTF_RenderText_Blended(font,text.c_str(),kolor);
break;
}
SDL_Rect dstRect = genRect(temp->h,temp->w,x-temp->w,y-temp->h);
CSDL_Ext::blitSurface(temp,NULL,dst,&dstRect);
SDL_FreeSurface(temp);
}
// Vertical flip
SDL_Surface * CSDL_Ext::rotate01(SDL_Surface * toRot)
{
@ -1282,23 +978,6 @@ void CSDL_Ext::fillTexture(SDL_Surface *dst, SDL_Surface * src)
}
}
std::string CSDL_Ext::trimToFit(std::string text, int widthLimit, EFonts font)
{
int widthSoFar = 0;
for(auto i = text.begin(); i != text.end(); i++)
{
widthSoFar += graphics->fonts[font]->getCharWidth(*i);
if(widthSoFar > widthLimit)
{
//remove all characteres past limit
text.erase(i, text.end());
break;
}
}
return text;
}
template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<2>(int, int);
template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<3>(int, int);
template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<4>(int, int);

View File

@ -3,7 +3,7 @@
#include <SDL_video.h>
#include <SDL_ttf.h>
#include "../../lib/int3.h"
#include "../FontBase.h"
#include "../Graphics.h"
#include "Geometries.h"
/*
@ -51,6 +51,9 @@ public:
/** the metallic gold color used mostly as a border around buttons */
static const SDL_Color METALLIC_GOLD;
/** green color used for in-game console */
static const SDL_Color GREEN;
};
//MSVC gives an error when calling abs with ui64 -> we add template that will match calls with unsigned arg and return it
@ -169,12 +172,6 @@ namespace CSDL_Ext
int blit8bppAlphaTo24bpp(const SDL_Surface * src, const SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect); //blits 8 bpp surface with alpha channel to 24 bpp surface
Uint32 colorToUint32(const SDL_Color * color); //little endian only
void printAtWB(const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor=Colors::WHITE, SDL_Surface * dst=screen);
void printAt(const std::string & text, int x, int y, EFonts font, SDL_Color kolor=Colors::WHITE, SDL_Surface * dst=screen);
void printTo(const std::string & text, int x, int y, EFonts font, SDL_Color kolor=Colors::WHITE, SDL_Surface * dst=screen);
void printAtMiddle(const std::string & text, int x, int y, EFonts font, SDL_Color kolor=Colors::WHITE, SDL_Surface * dst=screen);
void printAtMiddleWB(const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor=Colors::YELLOW, SDL_Surface * dst=screen);
void update(SDL_Surface * what = screen); //updates whole surface (default - main screen)
void drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const int3 &color);
void drawBorder(SDL_Surface * sur, const SDL_Rect &r, const int3 &color);
@ -196,6 +193,4 @@ namespace CSDL_Ext
template<int bpp>
void applyEffectBpp( SDL_Surface * surf, const SDL_Rect * rect, int mode );
void applyEffect(SDL_Surface * surf, const SDL_Rect * rect, int mode); //mode: 0 - sepia, 1 - grayscale
std::string trimToFit(std::string text, int widthLimit, EFonts font);
}

37
config/fonts.json Normal file
View File

@ -0,0 +1,37 @@
{
// Original HoMM 3 bitmap fonts
// Stored in H3Bitmap.lod with fnt extension
// Warning: Do not change number of entries in this list
"bitmap" :
[
"BIGFONT", // Mostly used for window titles
"CALLI10R", // Unused in VCMI
"CREDITS", // Used for credits menu
"HISCORE", // Unused in VCMI
"MEDFONT", // Some titles
"SMALFONT", // Most of the messages
"TIMES08R", // Used to display amounts on creature card
"TINY", // Some text
"VERD10B" // Unused in VCMI
],
// True type replacements
// Should be in format:
// <replaced bitmap font name, case-sensetive> : <true type font description>
// "file" - file to load font from, must be in data/ directory
// "size" - point size of font
// "style" - italic and\or bold, indicates font style
// "blend" - if set to true, font will be antialiased
"trueType":
{
//"BIGFONT" : { "file" : "TimesNewRoman.ttf", "size" : 20, "style" : ["bold"], "blend" : true},
//"CALLI10R" : { "file" : "Georgia.ttf", "size" : 10},
//"CREDITS" : { "file" : "TimesNewRoman.ttf", "size" : 13, "blend" : true},
//"HISCORE" : { "file" : "Georgia.ttf", "size" : 13},
//"MEDFONT" : { "file" : "TimesNewRoman.ttf", "size" : 16, "blend" : true},
//"SMALFONT" : { "file" : "Georgia.ttf", "size" : 13},
//"TIMES08R" : { "file" : "TimesNewRoman.ttf", "size" : 8, "blend" : true},
//"TINY" : { "file" : "Georgia.ttf", "size" : 10},
//"VERD10B" : { "file" : "Georgia.ttf", "size" : 13}
}
}

View File

@ -1,29 +0,0 @@
0 0 tnrb.ttf 20
0 1 georgia.ttf 10
0 2 tnrb.ttf 13
0 3 georgia.ttf 13
0 4 tnrb.ttf 16
0 5 georgia.ttf 13
0 6 tnrb.ttf 08
0 7 georgia.ttf 10
0 8 georgia.ttf 13
-1
Format:
1 = enabled, 0=disabled
font numeric ID
TTF font name
font size
ID of fonts:
0 BIGFONT.FNT //windows titles
1 CALLI10R.FNT ?
2 CREDITS.FNT
3 HISCORE.FNT
4 MEDFONT.FNT //most used font
5 SMALFONT.FNT //most used font
6 TIMES08R.FNT ?
7 TINY.FNT //used for small texts
8 VERD10B.FNT ?

View File

@ -363,6 +363,8 @@ void CCreatureHandler::loadCreatures()
}
}
c->nameRef = creature["name"].Vector().at(0).String();
/* A creature can have several names. */
BOOST_FOREACH(const JsonNode &name, creature["name"].Vector())
{

View File

@ -230,7 +230,8 @@ EResType::Type EResTypeHelper::getTypeFromExtension(std::string extension)
(".MSG", EResType::MASK)
(".H3C", EResType::CAMPAIGN)
(".H3M", EResType::MAP)
(".FNT", EResType::FONT)
(".FNT", EResType::BMP_FONT)
(".TTF", EResType::TTF_FONT)
(".BMP", EResType::IMAGE)
(".JPG", EResType::IMAGE)
(".PCX", EResType::IMAGE)
@ -241,7 +242,8 @@ EResType::Type EResTypeHelper::getTypeFromExtension(std::string extension)
(".SMK", EResType::VIDEO)
(".BIK", EResType::VIDEO)
(".MJPG", EResType::VIDEO)
(".MPG", EResType::VIDEO)
(".MPG", EResType::VIDEO)
(".AVI", EResType::VIDEO)
(".MP3", EResType::MUSIC)
(".OGG", EResType::MUSIC)
(".LOD", EResType::ARCHIVE_LOD)
@ -269,7 +271,8 @@ std::string EResTypeHelper::getEResTypeAsString(EResType::Type type)
MAP_ENUM(MASK)
MAP_ENUM(CAMPAIGN)
MAP_ENUM(MAP)
MAP_ENUM(FONT)
MAP_ENUM(BMP_FONT)
MAP_ENUM(TTF_FONT)
MAP_ENUM(IMAGE)
MAP_ENUM(VIDEO)
MAP_ENUM(SOUND)

View File

@ -46,7 +46,8 @@ namespace EResType
MASK,
CAMPAIGN,
MAP,
FONT,
BMP_FONT,
TTF_FONT,
IMAGE,
VIDEO,
SOUND,

File diff suppressed because it is too large Load Diff