Merge branch '138-toggle-free-look-with-hotkey' into 'main/atys-live'
[ryzomcore.git] / nel / src / misc / algo.cpp
blob6a3ef62ddbd5995a0f5481fac200711f31b227e2
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program 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 Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "stdmisc.h"
19 #include "nel/misc/algo.h"
22 using namespace std;
24 #ifdef DEBUG_NEW
25 #define new DEBUG_NEW
26 #endif
28 namespace NLMISC
31 bool testWildCard(const std::string &strIn, const std::string &wildCard)
33 return testWildCard(strIn.c_str(), wildCard.c_str());
37 // ***************************************************************************
38 bool testWildCard(const char *strIn, const char *wildCard)
40 // run the 2 string in //el
41 while(*wildCard!=0 && *strIn!=0)
43 // if same char, continue.
44 if(*wildCard==*strIn)
46 wildCard++;
47 strIn++;
49 // if wildCard is ?, continue
50 else if(*wildCard=='?')
52 wildCard++;
53 strIn++;
55 // if wildcard is *, recurs check.
56 else if(*wildCard=='*')
58 wildCard++;
59 // if last *, its OK.
60 if(*wildCard==0)
61 return true;
62 // else must check next strings.
63 else
65 // build the wilcard token. eg from "*pipo?", take "pipo"
66 string token;
67 while(*wildCard!='*' && *wildCard!='?' && *wildCard!=0)
69 token+= *wildCard;
70 wildCard++;
72 // if token size is empty, error
73 if(token.empty())
74 return false;
76 // in strIn, search all the occurence of token. For each solution, recurs test.
77 string sCopy= strIn;
78 string::size_type pos= sCopy.find(token, 0);
79 while(pos!=string::npos)
81 // do a testWildCard test on the remaining string/wildCard
82 if( testWildCard(strIn+pos+token.size(), wildCard) )
83 // if succeed, end
84 return true;
85 // fails=> test with another occurence of token in the string.
86 pos= sCopy.find(token, pos+1);
89 // if all failed, fail
90 return false;
93 // else fail
94 else
95 return false;
98 // If quit here because end Of 2 strs, OK.
99 if(*wildCard==0 && *strIn==0)
100 return true;
101 // if quit here because wildCard=="*" and s="", OK too.
102 if(*strIn==0 && wildCard[0]=='*' && wildCard[1]==0)
103 return true;
106 Else false:
107 It may be wildCard="?aez" and s="" => error
108 It may be wildCard="" and s="aer" => error
110 return false;
114 // ***************************************************************************
115 void splitString(const std::string &str, const std::string &separator, std::vector<std::string> &retList)
117 string::size_type pos=0;
118 string::size_type newPos=0;
119 retList.clear();
120 while( (newPos= str.find(separator,pos)) != string::npos)
122 // if not empty sub str. (skip repetition of separator )
123 if(newPos-pos>0)
124 retList.push_back(str.substr(pos, newPos-pos));
125 // skip token
126 pos= newPos+separator.size();
128 // copy the last substr
129 if( pos<str.size() )
130 retList.push_back(str.substr(pos, str.size()-pos));
134 // ***************************************************************************
135 void splitUCString(const ucstring &ucstr, const ucstring &separator, std::vector<ucstring> &retList)
137 ucstring::size_type pos=0;
138 ucstring::size_type newPos=0;
139 retList.clear();
140 while( (newPos= ucstr.find(separator,pos)) != ucstring::npos)
142 // if not empty sub str. (skip repetition of separator )
143 if(newPos-pos>0)
144 retList.push_back(ucstr.substr(pos, newPos-pos));
145 // skip token
146 pos= newPos+separator.size();
148 // copy the last substr
149 if( pos<ucstr.size() )
150 retList.push_back(ucstr.substr(pos, ucstr.size()-pos));
153 // ***************************************************************************
155 void drawFullLine (float x0, float y0, float x1, float y1, std::vector<std::pair<sint, sint> > &result)
157 result.clear ();
158 // x0 must be < x1
159 float dx = (float) fabs (x0-x1);
160 float dy = (float) fabs (y0-y1);
161 if ((dx == 0) && (dy == 0))
162 result.push_back (pair<sint, sint> ((sint)floor (x0), (sint)floor (y0)));
163 else if (dx > dy)
165 if (x0 > x1)
167 // Xchg 0 and 1
168 float temp = x0;
169 x0 = x1;
170 x1 = temp;
171 temp = y0;
172 y0 = y1;
173 y1 = temp;
176 float deltaX = x1 - x0;
177 const float deltaY = (y1-y0)/deltaX;
179 // Current integer pixel
180 sint currentX = (sint)floor (x0);
181 sint currentY = (sint)floor (y0);
183 while (deltaX >= 0)
185 // Next point
186 sint previousY = currentY;
188 // Next y0
189 if (deltaX > 1)
190 y0 += deltaY;
191 else
192 y0 += deltaX * deltaY;
194 deltaX -= 1;
196 currentY = (sint)y0;
198 // Add point
199 if (currentY<=previousY)
203 result.push_back (pair<sint, sint> (currentX, previousY));
204 previousY--;
206 while (currentY<=previousY);
208 else
212 result.push_back (pair<sint, sint> (currentX, previousY));
213 previousY++;
215 while (currentY>=previousY);
218 // Next X
219 currentX++;
222 else
224 if (y0 > y1)
226 // Xchg 0 and 1
227 float temp = y0;
228 y0 = y1;
229 y1 = temp;
230 temp = x0;
231 x0 = x1;
232 x1 = temp;
235 float deltaY = y1 - y0;
236 const float deltaX = (x1-x0)/deltaY;
238 // Current integer pixel
239 sint currentY = (sint)floor (y0);
240 sint currentX = (sint)floor (x0);
242 while (deltaY >= 0)
244 // Next point
245 sint previousX = currentX;
247 // Next x0
248 if (deltaY > 1)
249 x0 += deltaX;
250 else
251 x0 += deltaY * deltaX;
253 deltaY -= 1;
255 currentX = (sint)x0;
257 // Add point
258 if (currentX<=previousX)
262 result.push_back (pair<sint, sint> (previousX, currentY));
263 previousX--;
265 while (currentX<=previousX);
267 else
271 result.push_back (pair<sint, sint> (previousX, currentY));
272 previousX++;
274 while (currentX>=previousX);
277 // Next Y
278 currentY++;
283 // ***************************************************************************
285 void drawLine (float x0, float y0, float x1, float y1, vector<pair<sint, sint> > &result)
287 float dx = (float)(floor(x1+0.5) - floor(x0+0.5));
288 float dy = (float)(floor(y1+0.5) - floor(y0+0.5));
290 float rdx = x1-x0;
291 float rdy = y1-y0;
293 sint d = (sint)std::max(fabs(dx), fabs(dy));
294 float maxd = (float)(std::max(fabs(rdx), fabs(rdy)));
296 rdx /= maxd;
297 rdy /= maxd;
299 for (; d>=0; --d)
301 result.push_back(make_pair<sint,sint>((sint)floor(x0+0.5), (sint)floor(y0+0.5)));
303 x0 += rdx;
304 y0 += rdy;
308 // ***************************************************************************
310 } // NLMISC