00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "precomp.h"
00028
00029 #include "debug.h"
00030 #include "TextPart.h"
00031
00039 TextWord::TextWord(const std::wstring& s, const PGLYPHPOS& arGlyphPos, const POINTQF* pWidths, std::tstring::size_type nStart, std::tstring::size_type nEnd )
00040 {
00041
00042 if (nEnd == -1)
00043 nEnd = s.size();
00044
00045 for (; nStart < nEnd; nStart++)
00046 {
00047
00048 ASSERT(s[nStart] != ' ');
00049 push_back(TextLetter(s[nStart], arGlyphPos[nStart].ptl.x, pWidths[nStart].x.HighPart >> 4));
00050 }
00051 }
00052
00059 TextWord::TextWord(const std::wstring& s, int nCharWidth, std::tstring::size_type nStart, std::tstring::size_type nEnd )
00060 {
00061
00062 if (nEnd == -1)
00063 nEnd = s.size();
00064
00065 for (; nStart < nEnd; nStart++)
00066 {
00067
00068 ASSERT(s[nStart] != ' ');
00069 push_back(TextLetter(s[nStart], (long) (nStart * nCharWidth), nCharWidth));
00070 }
00071 }
00072
00073
00074
00081 TextLine::TextLine(const std::wstring& s, const RECTL& rc, const PGLYPHPOS& arGlyphPos, const POINTQF* pWidths) : rcArea(rc)
00082 {
00083
00084 size_t nPos = 0, nEndPos = s.find_first_of(_T(" \r\n\t"));
00085 while (nEndPos != std::wstring::npos)
00086 {
00087
00088 if (nEndPos > nPos)
00089
00090 push_back(TextWord(s, arGlyphPos, pWidths, nPos, nEndPos));
00091
00092
00093 nPos = nEndPos + 1;
00094 if (nPos < s.size())
00095
00096 nEndPos = s.find_first_of(_T(" \r\n\t"), nPos);
00097 else
00098
00099 nEndPos = std::wstring::npos;
00100 }
00101 if (nPos < s.size())
00102
00103 push_back(TextWord(s, arGlyphPos, pWidths, nPos));
00104
00105
00106 SetSides();
00107 }
00108
00114 TextLine::TextLine(const std::wstring& s, const RECTL& rc, int nCharWidth) : rcArea(rc)
00115 {
00116
00117 std::tstring::size_type nPos = 0, nEndPos = s.find_first_of(_T(" \r\n\t"));
00118 while (nEndPos != std::wstring::npos)
00119 {
00120
00121 if (nEndPos > nPos)
00122
00123 push_back(TextWord(s, nCharWidth, nPos, nEndPos));
00124
00125
00126 nPos = nEndPos + 1;
00127 if (nPos < s.size())
00128
00129 nEndPos = s.find_first_of(_T(" \r\n\t"), nPos);
00130 else
00131
00132 nEndPos = std::wstring::npos;
00133 }
00134 if (nPos < s.size())
00135
00136 push_back(TextWord(s, nCharWidth, nPos));
00137
00138
00139 SetSides();
00140 }
00141
00148 bool OnSameLine(const RECTL& rect1, const RECTL& rect2)
00149 {
00150 int nMiddle1 = (rect1.top + rect1.bottom) / 2, nMiddle2 = (rect2.top + rect2.bottom) / 2;
00151 return ((nMiddle1 >= rect2.top) && (nMiddle1 <= rect2.bottom)) || ((nMiddle2 >= rect1.top) && (nMiddle2 <= rect1.bottom));
00152 }
00153
00158 bool TextLine::AddTextSameLine(const TextLine& other)
00159 {
00160
00161 if (!OnSameLine(rcArea, other.rcArea))
00162
00163 return false;
00164
00165
00166 int nOffset;
00167 if (rcArea.left > other.rcArea.left)
00168 {
00169 nOffset = rcArea.left - other.rcArea.left;
00170 if (rcArea.left > other.rcArea.right + 2)
00171 {
00172
00173 insert(begin(), other.begin(), other.end());
00174 }
00175 else
00176 {
00177
00178 ASSERT(!other.empty());
00179 ASSERT(!empty());
00180 TextWord part(other.back());
00181 part += front();
00182 erase(begin());
00183 push_front(part);
00184 if (other.size() > 1)
00185 {
00186 const_iterator ci = other.end();
00187 ci--;
00188 insert(begin(), other.begin(), ci);
00189 }
00190 }
00191 rcArea.left = other.rcArea.left;
00192 }
00193 else
00194 {
00195 nOffset = other.rcArea.left - rcArea.left;
00196 std::tstring::size_type nSize = size();
00197 if (rcArea.right < other.rcArea.left - 2)
00198 {
00199
00200 insert(end(), other.begin(), other.end());
00201 }
00202 else
00203 {
00204
00205 ASSERT(!other.empty());
00206 ASSERT(!empty());
00207 const_iterator i = other.begin();
00208 back() += (*i);
00209 i++;
00210 if (i != other.end())
00211 insert(end(), i, other.end());
00212 }
00213 rcArea.right = other.rcArea.right;
00214 }
00215
00216
00217 rcArea.top = min(rcArea.top, other.rcArea.top);
00218 rcArea.bottom = max(rcArea.bottom, other.rcArea.bottom);
00219 return true;
00220 }
00221
00225 void TextLine::SetSides()
00226 {
00227
00228 if (empty())
00229
00230 rcArea.right = rcArea.left;
00231 else
00232 {
00233
00234 const TextWord& word = back();
00235 rcArea.right = word.GetEnd(word.size() - 1);
00236 rcArea.left = front().GetStart(0);
00237 }
00238 }
00239
00240
00241
00242
00243
00247 void TextArea::AddLine(const TextLine& line)
00248 {
00249
00250 if (line.empty())
00251 return;
00252
00253 if (empty())
00254
00255 push_back(line);
00256 else
00257 {
00258
00259 TextLine& last = back();
00260 if (!last.AddTextSameLine(line))
00261
00262 push_back(line);
00263 }
00264 }
00265
00269 void TextArea::InitSearch()
00270 {
00271
00272 m_iLine = begin();
00273 if (m_iLine != end())
00274
00275 m_iWord = (*m_iLine).begin();
00276 }
00277
00283 bool TextArea::SearchFor(const STRLIST& words, RECTL& rectArea)
00284 {
00285
00286 if (words.empty())
00287
00288 return false;
00289
00290
00291 const_iterator iPrev = m_iLine;
00292 std::wstring sWord;
00293 std::wstring::size_type pos;
00294
00295 for (; m_iLine != end(); m_iLine++)
00296 {
00297
00298 if (iPrev != m_iLine)
00299 {
00300
00301 if ((*m_iLine).size() < words.size())
00302
00303 continue;
00304
00305 m_iWord = (*m_iLine).begin();
00306 }
00307
00308
00309 for (; m_iWord != (*m_iLine).end(); m_iWord++)
00310 {
00311
00312 sWord = (*m_iWord).GetText();
00313 if ((pos = sWord.find(words.front().c_str())) != (sWord.size() - words.front().size()))
00314
00315
00316
00317 continue;
00318
00319
00320 TextLine::const_iterator iTestThis = m_iWord;
00321 STRLIST::const_iterator iTestWords = words.begin(), iTestWordsNext;
00322 iTestWords++;
00323 while (iTestWords != words.end())
00324 {
00325
00326 iTestThis++;
00327 if (iTestThis == (*m_iLine).end())
00328
00329 break;
00330 sWord = (*iTestThis).GetText();
00331
00332 iTestWordsNext = iTestWords;
00333 iTestWordsNext++;
00334 if (iTestWordsNext == words.end())
00335 {
00336
00337 if (sWord.find((*iTestWords).c_str()) != 0)
00338 break;
00339
00340 iTestWords = words.end();
00341 }
00342 else
00343 {
00344 if (sWord != (*iTestWords))
00345
00346 break;
00347 }
00348
00349 iTestWords = iTestWordsNext;
00350 }
00351
00352 if (iTestWords == words.end())
00353 {
00354
00355 rectArea = (*m_iLine).rcArea;
00356 rectArea.left = (*m_iWord).GetStart(pos);
00357 rectArea.right = (*iTestThis).GetEnd((*iTestThis).size() - 1);
00358 m_iWord = iTestThis;
00359 m_iWord++;
00360 return true;
00361 }
00362 }
00363 iPrev = m_iLine;
00364 }
00365 return false;
00366 }
00367
00373 bool TextArea::SearchForURL(RECTL& rectArea, std::wstring& sURL)
00374 {
00375
00376 const_iterator iPrev = m_iLine;
00377 std::wstring sWord;
00378 std::tstring::size_type nStart, nEnd;
00379 for (; m_iLine != end(); m_iLine++)
00380 {
00381
00382
00383 if (iPrev != m_iLine)
00384
00385 m_iWord = (*m_iLine).begin();
00386
00387
00388 for (; m_iWord != (*m_iLine).end(); m_iWord++)
00389 {
00390
00391 sWord = (*m_iWord).GetText();
00392 if (sWord.size() < 8)
00393
00394 continue;
00395 if (_wcsnicmp(sWord.c_str(), _T("http"), 4) != 0)
00396
00397 continue;
00398
00399 nStart = 4;
00400 if ((sWord[nStart] == 's') || (sWord[nStart] == 'S'))
00401
00402 nStart++;
00403
00404 if (wcsncmp(sWord.c_str() + nStart, _T("://"), 3) != 0)
00405
00406 continue;
00407 nStart += 3;
00408
00409
00410 nEnd = sWord.find_first_not_of(_T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.+$-_@&+-!*\"'(),%/?"), nStart);
00411 if (nEnd == std::wstring::npos)
00412 nEnd = sWord.size();
00413
00414 while ((nEnd > nStart) && wcschr(_T(").'\"?"), sWord[nEnd-1]) != NULL)
00415 nEnd--;
00416
00417
00418 rectArea = (*m_iLine).rcArea;
00419 rectArea.right = (*m_iWord).GetEnd(nEnd);
00420 rectArea.left = (*m_iWord).GetStart(0);
00421 sURL = sWord.substr(0, nEnd);
00422
00423
00424 m_iWord++;
00425 return true;
00426 }
00427 iPrev = m_iLine;
00428 }
00429 return false;
00430 }
00431