1 /*
2 * Copyright 2011-2013 Arx Libertatis Team (see the AUTHORS file)
3 *
4 * This file is part of Arx Libertatis.
5 *
6 * Arx Libertatis is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Arx Libertatis is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Arx Libertatis. If not, see <http://www.gnu.org/licenses/>.
18 */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code. If not, see
33 <http://www.gnu.org/licenses/>.
34
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43
44 #include "gui/TextManager.h"
45
46 #include "gui/Text.h"
47 #include "graphics/Math.h"
48 #include "graphics/font/Font.h"
49 #include "io/log/Logger.h"
50
51 using std::string;
52 using std::vector;
53
54 struct TextManager::ManagedText {
55 Font* pFont;
56 Rect rRect;
57 Rect rRectClipp;
58 string lpszUText;
59 float fDeltaY;
60 float fSpeedScrollY;
61 Color lCol;
62 long lTimeScroll;
63 long lTimeOut;
64 };
65
TextManager()66 TextManager::TextManager() {
67 }
68
~TextManager()69 TextManager::~TextManager() {
70 Clear();
71 }
72
AddText(Font * _pFont,const string & _lpszUText,const Rect & _rRect,Color _lCol,long _lTimeOut,long _lTimeScroll,float _fSpeedScroll,int iNbLigneClipp)73 bool TextManager::AddText(Font* _pFont, const string & _lpszUText, const Rect & _rRect, Color _lCol, long _lTimeOut, long _lTimeScroll, float _fSpeedScroll, int iNbLigneClipp) {
74
75 if(_lpszUText.empty()) {
76 return false;
77 }
78
79 if(!_pFont) {
80 LogWarning << "Adding text with NULL font.";
81 return false;
82 }
83
84 ManagedText * pArxText = new ManagedText();
85 if(!pArxText) {
86 return false;
87 }
88
89 pArxText->pFont = _pFont;
90 pArxText->lpszUText = _lpszUText;
91 pArxText->rRect = _rRect;
92 pArxText->lCol = _lCol;
93 pArxText->lTimeScroll = _lTimeScroll;
94 pArxText->fDeltaY = 0.f;
95 pArxText->fSpeedScrollY = _fSpeedScroll;
96 pArxText->lTimeOut = _lTimeOut;
97 pArxText->rRectClipp = pArxText->rRect;
98
99 if(iNbLigneClipp)
100 {
101 Vec2i sSize = _pFont->getTextSize(pArxText->lpszUText);
102 sSize.y *= iNbLigneClipp;
103
104 pArxText->rRectClipp.bottom = pArxText->rRect.top + sSize.y;
105 }
106
107 entries.push_back(pArxText);
108
109 return true;
110 }
111
AddText(Font * font,const std::string & str,long x,long y,Color fgcolor)112 bool TextManager::AddText(Font * font, const std::string & str, long x, long y, Color fgcolor) {
113 Rect r;
114 r.left = x;
115 r.top = y;
116 r.right = Rect::Limits::max();
117 r.bottom = Rect::Limits::max();
118 return AddText(font, str, r, fgcolor);
119 }
120
Update(float _fDiffFrame)121 void TextManager::Update(float _fDiffFrame) {
122
123 int _iDiffFrame = checked_range_cast<int>(_fDiffFrame);
124
125 // TODO-slussier: Until we fix the arxtime.get_updated() mess, it's easy to have a FrameDiff of 0...
126 if(_iDiffFrame == 0)
127 _iDiffFrame = 1;
128
129 vector<ManagedText *>::iterator itManage;
130 for(itManage = entries.begin(); itManage != entries.end();) {
131
132 ManagedText * pArxText = *itManage;
133
134 if(pArxText->lTimeOut < 0) {
135 delete pArxText;
136 itManage = entries.erase(itManage);
137 continue;
138 }
139
140 pArxText->lTimeOut -= _iDiffFrame;
141
142 if(pArxText->lTimeScroll < 0 &&
143 pArxText->fDeltaY < (pArxText->rRect.bottom - pArxText->rRectClipp.bottom)) {
144 pArxText->fDeltaY += pArxText->fSpeedScrollY * (float)_iDiffFrame;
145
146 if(pArxText->fDeltaY >= (pArxText->rRect.bottom - pArxText->rRectClipp.bottom)) {
147 pArxText->fDeltaY = static_cast<float>(pArxText->rRect.bottom - pArxText->rRectClipp.bottom);
148 }
149 } else {
150 pArxText->lTimeScroll -= _iDiffFrame;
151 }
152
153 ++itManage;
154 }
155
156 }
157
Render()158 void TextManager::Render() {
159 vector<ManagedText *>::const_iterator itManage = entries.begin();
160 for(; itManage != entries.end(); ++itManage) {
161
162 ManagedText * pArxText = *itManage;
163
164 Rect * pRectClip = NULL;
165 if(pArxText->rRectClipp.right != Rect::Limits::max() || pArxText->rRectClipp.bottom != Rect::Limits::max()) {
166 pRectClip = &pArxText->rRectClipp;
167 }
168
169 float maxx;
170 if(pArxText->rRect.right == Rect::Limits::max()) {
171 maxx = std::numeric_limits<float>::infinity();
172 } else {
173 maxx = static_cast<float>(pArxText->rRect.right);
174 }
175
176 long height = ARX_UNICODE_DrawTextInRect(pArxText->pFont, static_cast<float>(pArxText->rRect.left),
177 pArxText->rRect.top - pArxText->fDeltaY,
178 maxx,
179 pArxText->lpszUText, pArxText->lCol, pRectClip);
180
181 pArxText->rRect.bottom = pArxText->rRect.top + height;
182 }
183 }
184
Clear()185 void TextManager::Clear() {
186
187 vector<ManagedText *>::iterator itManage;
188 for(itManage = entries.begin(); itManage < entries.end(); ++itManage) {
189 delete *itManage;
190 }
191
192 entries.clear();
193 }
194
Empty() const195 bool TextManager::Empty() const
196 {
197 return entries.empty();
198 }
199