1 /*
2  *  This file is part of Dune Legacy.
3  *
4  *  Dune Legacy is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Dune Legacy is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Dune Legacy.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <FileClasses/FontManager.h>
19 
20 #include <globals.h>
21 
22 #include <misc/draw_util.h>
23 
24 #include <FileClasses/FileManager.h>
25 #include <FileClasses/PictureFont.h>
26 #include <FileClasses/LoadSavePNG.h>
27 
28 #include <list>
29 
FontManager()30 FontManager::FontManager() {
31     fonts[FONT_STD10] = std::shared_ptr<Font>(new PictureFont(LoadPNG_RW(pFileManager->openFile("Font10.png"),true), true));
32     fonts[FONT_STD12] = std::shared_ptr<Font>(new PictureFont(LoadPNG_RW(pFileManager->openFile("Font12.png"),true), true));
33     fonts[FONT_STD24] = std::shared_ptr<Font>(new PictureFont(LoadPNG_RW(pFileManager->openFile("Font24.png"),true), true));
34 }
35 
~FontManager()36 FontManager::~FontManager() {
37 }
38 
drawTextOnSurface(SDL_Surface * pSurface,const std::string & text,Uint32 color,unsigned int fontNum)39 void FontManager::drawTextOnSurface(SDL_Surface* pSurface, const std::string& text, Uint32 color, unsigned int fontNum) {
40     if(fontNum >= NUM_FONTS) {
41         return;
42     }
43 
44     fonts[fontNum]->drawTextOnSurface(pSurface,text,color);
45 }
46 
getTextWidth(const std::string & text,unsigned int fontNum)47 int FontManager::getTextWidth(const std::string& text, unsigned int fontNum) {
48     if(fontNum >= NUM_FONTS) {
49         return 0;
50     }
51 
52     return fonts[fontNum]->getTextWidth(text);
53 }
54 
getTextHeight(unsigned int fontNum)55 int FontManager::getTextHeight(unsigned int fontNum) {
56     if(fontNum >= NUM_FONTS) {
57         return 0;
58     }
59 
60     return fonts[fontNum]->getTextHeight();
61 }
62 
createSurfaceWithText(const std::string & text,Uint32 color,unsigned int fontNum)63 SDL_Surface* FontManager::createSurfaceWithText(const std::string& text, Uint32 color, unsigned int fontNum) {
64     if(fontNum >= NUM_FONTS) {
65         return nullptr;
66     }
67 
68     SDL_Surface* pic;
69 
70     int width = fonts[fontNum]->getTextWidth(text);
71     int height = fonts[fontNum]->getTextHeight();
72 
73     // create new picture surface
74     if((pic = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
75         return nullptr;
76     }
77 
78     SDL_SetSurfaceBlendMode(pic, SDL_BLENDMODE_NONE);
79     SDL_FillRect(pic, nullptr, COLOR_INVALID);
80     SDL_SetColorKey(pic, SDL_TRUE, COLOR_INVALID);
81 
82     fonts[fontNum]->drawTextOnSurface(pic,text,color);
83 
84     return pic;
85 }
86 
createTextureWithText(const std::string & text,Uint32 color,unsigned int fontNum)87 SDL_Texture* FontManager::createTextureWithText(const std::string& text, Uint32 color, unsigned int fontNum) {
88     return convertSurfaceToTexture(createSurfaceWithText(text, color, fontNum), true);
89 }
90 
createSurfaceWithMultilineText(const std::string & text,Uint32 color,unsigned int fontNum,bool bCentered)91 SDL_Surface* FontManager::createSurfaceWithMultilineText(const std::string& text, Uint32 color, unsigned int fontNum, bool bCentered) {
92     if(fontNum >= NUM_FONTS) {
93         return 0;
94     }
95 
96     size_t startpos = 0;
97     size_t nextpos;
98     std::list<std::string> textLines;
99     do {
100         nextpos = text.find("\n",startpos);
101         if(nextpos == std::string::npos) {
102             textLines.push_back(text.substr(startpos,text.length()-startpos));
103         } else {
104             textLines.push_back(text.substr(startpos,nextpos-startpos));
105             startpos = nextpos+1;
106         }
107     } while(nextpos != std::string::npos);
108 
109     SDL_Surface* pic;
110 
111     int lineHeight = fonts[fontNum]->getTextHeight();
112     int width = fonts[fontNum]->getTextWidth(text);
113     int height = lineHeight * textLines.size() + (lineHeight * (textLines.size()-1))/2;
114 
115     // create new picture surface
116     if((pic = SDL_CreateRGBSurface(0, width, height, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK)) == nullptr) {
117         return nullptr;
118     }
119 
120     SDL_SetSurfaceBlendMode(pic, SDL_BLENDMODE_NONE);
121     SDL_FillRect(pic, nullptr, COLOR_INVALID);
122     SDL_SetColorKey(pic, SDL_TRUE, COLOR_INVALID);
123 
124     int currentLineNum = 0;
125     for(const std::string& textLine : textLines) {
126         SDL_Surface* tmpSurface = createSurfaceWithText(textLine, color, fontNum);
127 
128         SDL_Rect dest = calcDrawingRect(tmpSurface, bCentered ? width/2 : 0, currentLineNum*lineHeight, bCentered ? HAlign::Center : HAlign::Left, VAlign::Top);
129         SDL_BlitSurface(tmpSurface,nullptr,pic,&dest);
130 
131         SDL_FreeSurface(tmpSurface);
132 
133         currentLineNum++;
134     }
135 
136     return pic;
137 }
138 
createTextureWithMultilineText(const std::string & text,Uint32 color,unsigned int fontNum,bool bCentered)139 SDL_Texture* FontManager::createTextureWithMultilineText(const std::string& text, Uint32 color, unsigned int fontNum, bool bCentered) {
140     return convertSurfaceToTexture(createSurfaceWithMultilineText(text, color, fontNum, bCentered), true);
141 }
142