OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "reflowedtextpage.h" | 7 #include "reflowedtextpage.h" |
8 IPDF_TextPage*» IPDF_TextPage::CreateReflowTextPage(IPDF_ReflowedPage* pRefPage) | 8 IPDF_TextPage* IPDF_TextPage::CreateReflowTextPage( |
9 { | 9 IPDF_ReflowedPage* pRefPage) { |
10 return FX_NEW CRF_TextPage(pRefPage); | 10 return FX_NEW CRF_TextPage(pRefPage); |
11 } | 11 } |
12 CRF_TextPage::CRF_TextPage(IPDF_ReflowedPage* pRefPage) | 12 CRF_TextPage::CRF_TextPage(IPDF_ReflowedPage* pRefPage) { |
13 { | 13 m_pRefPage = (CPDF_ReflowedPage*)(pRefPage); |
14 m_pRefPage = (CPDF_ReflowedPage*)(pRefPage); | 14 m_pDataList = NULL; |
| 15 m_CountBSArray = NULL; |
| 16 } |
| 17 CRF_TextPage::~CRF_TextPage() { |
| 18 if (m_pDataList) { |
| 19 delete m_pDataList; |
15 m_pDataList = NULL; | 20 m_pDataList = NULL; |
| 21 } |
| 22 if (m_CountBSArray) { |
| 23 delete m_CountBSArray; |
16 m_CountBSArray = NULL; | 24 m_CountBSArray = NULL; |
17 } | 25 } |
18 CRF_TextPage::~CRF_TextPage() | 26 } |
19 { | 27 FX_BOOL CRF_TextPage::ParseTextPage() { |
20 if(m_pDataList) { | 28 if (!m_pRefPage) { |
21 delete m_pDataList; | 29 return FALSE; |
22 m_pDataList = NULL; | 30 } |
23 } | 31 int count = m_pRefPage->m_pReflowed->GetSize(); |
24 if(m_CountBSArray) { | 32 if (count < 500) { |
25 delete m_CountBSArray; | 33 m_pDataList = FX_NEW CRF_CharDataPtrArray(count); |
26 m_CountBSArray = NULL; | 34 } else { |
27 } | 35 m_pDataList = FX_NEW CRF_CharDataPtrArray(500); |
28 } | 36 } |
29 FX_BOOL CRF_TextPage::ParseTextPage() | 37 if (NULL == m_pDataList) { |
30 { | 38 return FALSE; |
31 if(!m_pRefPage) { | 39 } |
32 return FALSE; | 40 for (int i = 0; i < count; i++) { |
33 } | 41 CRF_Data* pData = (*(m_pRefPage->m_pReflowed))[i]; |
34 int count = m_pRefPage->m_pReflowed->GetSize(); | 42 if (pData->GetType() == CRF_Data::Text) { |
35 if(count < 500) { | 43 m_pDataList->Add((CRF_CharData*)pData); |
36 m_pDataList = FX_NEW CRF_CharDataPtrArray(count); | 44 } |
| 45 } |
| 46 m_CountBSArray = FX_NEW CFX_CountBSINT32Array(20); |
| 47 if (NULL == m_CountBSArray) { |
| 48 return FALSE; |
| 49 } |
| 50 return TRUE; |
| 51 } |
| 52 FX_BOOL CRF_TextPage::IsParsered() const { |
| 53 if (m_pDataList) { |
| 54 return TRUE; |
| 55 } |
| 56 return FALSE; |
| 57 } |
| 58 int CRF_TextPage::CharIndexFromTextIndex(int TextIndex) const { |
| 59 return TextIndex; |
| 60 } |
| 61 int CRF_TextPage::TextIndexFromCharIndex(int CharIndex) const { |
| 62 return CharIndex; |
| 63 } |
| 64 |
| 65 int CRF_TextPage::CountChars() const { |
| 66 if (NULL == m_pDataList) { |
| 67 return -1; |
| 68 } |
| 69 return m_pDataList->GetSize(); |
| 70 } |
| 71 void CRF_TextPage::GetCharInfo(int index, FPDF_CHAR_INFO& info) const { |
| 72 if (index >= CountChars() || index < 0 || !m_pDataList) { |
| 73 return; |
| 74 } |
| 75 CRF_CharData* pData = (*m_pDataList)[index]; |
| 76 FX_FLOAT ReltiveCorddDs = pData->m_pCharState->m_fDescent; |
| 77 FX_FLOAT ReltiveCorddAs = pData->m_pCharState->m_fAscent; |
| 78 info.m_Flag = CHAR_NORMAL; |
| 79 info.m_pTextObj = pData->m_pCharState->m_pTextObj; |
| 80 info.m_OriginX = pData->m_PosX; |
| 81 info.m_OriginY = pData->m_PosY - ReltiveCorddDs; |
| 82 info.m_FontSize = pData->m_pCharState->m_fFontSize; |
| 83 CFX_FloatRect FloatRectTmp(pData->m_PosX, |
| 84 pData->m_PosY, |
| 85 pData->m_PosX + pData->m_Width, |
| 86 pData->m_PosY + ReltiveCorddAs - ReltiveCorddDs); |
| 87 info.m_CharBox = FloatRectTmp; |
| 88 CFX_WideString str = |
| 89 pData->m_pCharState->m_pFont->UnicodeFromCharCode(pData->m_CharCode); |
| 90 if (!str.IsEmpty()) { |
| 91 info.m_Unicode = str.GetAt(0); |
| 92 } else { |
| 93 info.m_Unicode = -1; |
| 94 } |
| 95 info.m_Charcode = (FX_WCHAR)pData->m_CharCode; |
| 96 info.m_Matrix = CFX_Matrix(1, 0, 0, 1, 0, 0); |
| 97 } |
| 98 extern FX_BOOL GetIntersection(FX_FLOAT low1, |
| 99 FX_FLOAT high1, |
| 100 FX_FLOAT low2, |
| 101 FX_FLOAT high2, |
| 102 FX_FLOAT& interlow, |
| 103 FX_FLOAT& interhigh); |
| 104 inline FX_BOOL _IsInsameline(const CFX_FloatRect& rectA, |
| 105 const CFX_FloatRect& rectB) { |
| 106 if ((rectA.top >= rectB.bottom && rectB.top >= rectA.bottom)) { |
| 107 return TRUE; |
| 108 } else { |
| 109 return FALSE; |
| 110 } |
| 111 } |
| 112 inline FX_BOOL _IsIntersect(const CFX_FloatRect& rectA, |
| 113 const CFX_FloatRect& rectB) { |
| 114 FX_FLOAT interlow = .0f, interhigh = .0f; |
| 115 if (GetIntersection(rectA.bottom, |
| 116 rectA.top, |
| 117 rectB.bottom, |
| 118 rectB.top, |
| 119 interlow, |
| 120 interhigh)) { |
| 121 if (GetIntersection(rectA.left, |
| 122 rectA.right, |
| 123 rectB.left, |
| 124 rectB.right, |
| 125 interlow, |
| 126 interhigh)) { |
| 127 return TRUE; |
37 } else { | 128 } else { |
38 m_pDataList = FX_NEW CRF_CharDataPtrArray(500); | 129 return FALSE; |
39 } | 130 } |
40 if (NULL == m_pDataList) { | 131 } |
41 return FALSE; | 132 return FALSE; |
42 } | 133 } |
43 for(int i = 0; i < count; i++) { | 134 void CRF_TextPage::GetRectArray(int start, |
44 CRF_Data* pData = (*(m_pRefPage->m_pReflowed))[i]; | 135 int nCount, |
45 if(pData->GetType() == CRF_Data::Text) { | 136 CFX_RectArray& rectArray) const { |
46 m_pDataList->Add((CRF_CharData*)pData); | 137 int indexlen = start + nCount; |
| 138 FPDF_CHAR_INFO info; |
| 139 FX_BOOL bstart = TRUE; |
| 140 CFX_FloatRect recttmp; |
| 141 int i; |
| 142 for (i = start; i < indexlen; i++) { |
| 143 GetCharInfo(i, info); |
| 144 if (bstart) { |
| 145 recttmp = info.m_CharBox; |
| 146 bstart = FALSE; |
| 147 } else if (_IsInsameline(recttmp, info.m_CharBox)) { |
| 148 recttmp.right = info.m_CharBox.right; |
| 149 if (info.m_CharBox.top > recttmp.top) { |
| 150 recttmp.top = info.m_CharBox.top; |
| 151 } |
| 152 if (info.m_CharBox.bottom < recttmp.bottom) { |
| 153 recttmp.bottom = info.m_CharBox.bottom; |
| 154 } |
| 155 } else { |
| 156 rectArray.Add(recttmp); |
| 157 recttmp = info.m_CharBox; |
| 158 } |
| 159 } |
| 160 rectArray.Add(recttmp); |
| 161 } |
| 162 inline FX_FLOAT _GetDistance(CFX_FloatRect floatRect, CPDF_Point point) { |
| 163 if (floatRect.right < point.x && floatRect.bottom > point.y) { |
| 164 return FXSYS_sqrt(FXSYS_pow(point.x - floatRect.right, 2) + |
| 165 FXSYS_pow(floatRect.bottom - point.y, 2)); |
| 166 } |
| 167 if (floatRect.right < point.x && floatRect.top < point.y) { |
| 168 return FXSYS_sqrt(FXSYS_pow(point.x - floatRect.right, 2) + |
| 169 FXSYS_pow(point.y - floatRect.top, 2)); |
| 170 } |
| 171 if (floatRect.left > point.x && floatRect.bottom > point.y) { |
| 172 return FXSYS_sqrt(FXSYS_pow(floatRect.bottom - point.y, 2) + |
| 173 FXSYS_pow(floatRect.left - point.x, 2)); |
| 174 } |
| 175 if ((floatRect.right > point.x || |
| 176 FXSYS_fabs(floatRect.right - point.x) <= 0.0001f) && |
| 177 (floatRect.left < point.x || |
| 178 FXSYS_fabs(floatRect.left - point.x) <= 0.0001f) && |
| 179 floatRect.bottom > point.y) { |
| 180 return FXSYS_fabs(floatRect.bottom - point.y); |
| 181 } |
| 182 if (floatRect.left > point.x && |
| 183 (floatRect.bottom < point.y || |
| 184 FXSYS_fabs(floatRect.bottom - point.y) <= 0.0001f) && |
| 185 (floatRect.top > point.y || |
| 186 FXSYS_fabs(floatRect.top - point.y) <= 0.0001f)) { |
| 187 return FXSYS_fabs(floatRect.left - point.x); |
| 188 } |
| 189 if (floatRect.left > point.x && floatRect.top < point.y) { |
| 190 return FXSYS_sqrt(FXSYS_pow(floatRect.left - point.x, 2) + |
| 191 FXSYS_pow(point.y - floatRect.top, 2)); |
| 192 } |
| 193 if ((floatRect.left < point.x || |
| 194 FXSYS_fabs(floatRect.left - point.x) <= 0.0001f) && |
| 195 (floatRect.right > point.x || |
| 196 FXSYS_fabs(floatRect.right - point.x) <= 0.0001f) && |
| 197 floatRect.top < point.y) { |
| 198 return FXSYS_fabs(point.y - floatRect.top); |
| 199 } |
| 200 if (floatRect.right < point.x && |
| 201 (floatRect.top > point.y || |
| 202 FXSYS_fabs(floatRect.top - point.y) <= 0.0001f) && |
| 203 (floatRect.bottom < point.y || |
| 204 FXSYS_fabs(floatRect.bottom - point.y) <= 0.0001f)) { |
| 205 return point.x - floatRect.right; |
| 206 } |
| 207 return .0f; |
| 208 } |
| 209 int CRF_TextPage::GetIndexAtPos(CPDF_Point point, |
| 210 FX_FLOAT xTorelance, |
| 211 FX_FLOAT yTorelance) const { |
| 212 int index = -1, i = 0, j = 0; |
| 213 FPDF_CHAR_INFO info; |
| 214 CFX_FloatRect rectTmp; |
| 215 FX_FLOAT MinDistance = 1000, DistanceTmp = 0; |
| 216 FX_FLOAT rect_bottom = point.x - xTorelance; |
| 217 CFX_FloatRect TorelanceRect(rect_bottom <= 0 ? 0 : rect_bottom, |
| 218 point.y - yTorelance, |
| 219 point.x + xTorelance, |
| 220 point.y + yTorelance); |
| 221 int count = CountChars(); |
| 222 for (i = 0; i < count; i++) { |
| 223 GetCharInfo(i, info); |
| 224 rectTmp = info.m_CharBox; |
| 225 if (rectTmp.Contains(point.x, point.y)) { |
| 226 index = i; |
| 227 break; |
| 228 } else if (_IsIntersect(rectTmp, TorelanceRect)) { |
| 229 DistanceTmp = _GetDistance(rectTmp, point); |
| 230 if (DistanceTmp < MinDistance) { |
| 231 MinDistance = DistanceTmp; |
| 232 index = i; |
| 233 } |
| 234 } |
| 235 } |
| 236 return index; |
| 237 } |
| 238 int CRF_TextPage::GetIndexAtPos(FX_FLOAT x, |
| 239 FX_FLOAT y, |
| 240 FX_FLOAT xTorelance, |
| 241 FX_FLOAT yTorelance) const { |
| 242 int index = 0; |
| 243 CPDF_Point point(x, y); |
| 244 if ((index = GetIndexAtPos(point, xTorelance, yTorelance)) < 0) { |
| 245 return -1; |
| 246 } else { |
| 247 return index; |
| 248 } |
| 249 } |
| 250 int CRF_TextPage::GetOrderByDirection(int index, int direction) const { |
| 251 return -1; |
| 252 } |
| 253 CFX_WideString CRF_TextPage::GetTextByRect(CFX_FloatRect rect) const { |
| 254 int count; |
| 255 FPDF_CHAR_INFO info; |
| 256 CFX_WideString str; |
| 257 CFX_FloatRect Recttmp; |
| 258 FX_BOOL bstart = TRUE; |
| 259 count = CountChars(); |
| 260 if (rect.IsEmpty()) { |
| 261 return L""; |
| 262 } |
| 263 for (int i = 0; i < count; i++) { |
| 264 GetCharInfo(i, info); |
| 265 if (_IsIntersect(rect, info.m_CharBox)) { |
| 266 if (bstart) { |
| 267 Recttmp = info.m_CharBox; |
| 268 str += info.m_Unicode; |
| 269 bstart = FALSE; |
| 270 } else if (_IsInsameline(Recttmp, info.m_CharBox)) { |
| 271 str += info.m_Unicode; |
| 272 } else { |
| 273 str += L"\r\n"; |
| 274 Recttmp = info.m_CharBox; |
| 275 str += info.m_Unicode; |
| 276 } |
| 277 } |
| 278 } |
| 279 if (str.IsEmpty()) { |
| 280 return L""; |
| 281 } else { |
| 282 return str; |
| 283 } |
| 284 } |
| 285 void CRF_TextPage::GetRectsArrayByRect(CFX_FloatRect rect, |
| 286 CFX_RectArray& resRectArray) const { |
| 287 int count, i; |
| 288 FX_BOOL bstart = TRUE; |
| 289 FPDF_CHAR_INFO info; |
| 290 CFX_FloatRect recttmp; |
| 291 count = CountChars(); |
| 292 for (i = 0; i < count; i++) { |
| 293 GetCharInfo(i, info); |
| 294 if (_IsIntersect(rect, info.m_CharBox)) { |
| 295 if (bstart) { |
| 296 recttmp = info.m_CharBox; |
| 297 bstart = FALSE; |
| 298 } else if (_IsInsameline(recttmp, info.m_CharBox)) { |
| 299 recttmp.right = info.m_CharBox.right; |
| 300 if (info.m_CharBox.top > recttmp.top) { |
| 301 recttmp.top = info.m_CharBox.top; |
47 } | 302 } |
48 } | 303 if (info.m_CharBox.bottom < recttmp.bottom) { |
49 m_CountBSArray = FX_NEW CFX_CountBSINT32Array(20); | 304 recttmp.bottom = info.m_CharBox.bottom; |
50 if(NULL == m_CountBSArray) { | 305 } |
51 return FALSE; | 306 } else { |
52 } | 307 resRectArray.Add(recttmp); |
53 return TRUE; | 308 recttmp = info.m_CharBox; |
54 } | 309 } |
55 FX_BOOL»CRF_TextPage::IsParsered() const | 310 } |
56 { | 311 } |
57 if(m_pDataList) { | 312 resRectArray.Add(recttmp); |
58 return TRUE; | 313 } |
59 } | 314 int CRF_TextPage::CountRects(int start, int nCount) { |
60 return FALSE; | 315 m_rectArray.RemoveAll(); |
61 } | 316 GetRectArray(start, nCount, m_rectArray); |
62 int CRF_TextPage::CharIndexFromTextIndex(int TextIndex) const | 317 return m_rectArray.GetSize(); |
63 { | 318 } |
64 return TextIndex; | 319 void CRF_TextPage::GetRect(int rectIndex, |
65 } | 320 FX_FLOAT& left, |
66 int CRF_TextPage::TextIndexFromCharIndex(int CharIndex) const | 321 FX_FLOAT& top, |
67 { | 322 FX_FLOAT& right, |
68 return CharIndex; | 323 FX_FLOAT& bottom) const { |
| 324 if (m_rectArray.GetSize() <= rectIndex) { |
| 325 return; |
| 326 } |
| 327 left = m_rectArray[rectIndex].left; |
| 328 top = m_rectArray[rectIndex].top; |
| 329 right = m_rectArray[rectIndex].right; |
| 330 bottom = m_rectArray[rectIndex].bottom; |
| 331 } |
| 332 FX_BOOL CRF_TextPage::GetBaselineRotate(int rectIndex, int& Rotate) { |
| 333 Rotate = 0; |
| 334 return TRUE; |
| 335 } |
| 336 FX_BOOL CRF_TextPage::GetBaselineRotate(CFX_FloatRect rect, int& Rotate) { |
| 337 Rotate = 0; |
| 338 return TRUE; |
| 339 } |
| 340 int CRF_TextPage::CountBoundedSegments(FX_FLOAT left, |
| 341 FX_FLOAT top, |
| 342 FX_FLOAT right, |
| 343 FX_FLOAT bottom, |
| 344 FX_BOOL bContains) { |
| 345 if (!m_CountBSArray) { |
| 346 return -1; |
| 347 } |
| 348 m_CountBSArray->RemoveAll(); |
| 349 CFX_FloatRect floatrect(left, bottom, right, top); |
| 350 int totalcount, i, j = 0, counttmp = 0; |
| 351 FX_BOOL bstart = TRUE; |
| 352 FPDF_CHAR_INFO info; |
| 353 CFX_FloatRect recttmp; |
| 354 totalcount = CountChars(); |
| 355 for (i = 0; i < totalcount; i++) { |
| 356 GetCharInfo(i, info); |
| 357 if (_IsIntersect(floatrect, info.m_CharBox)) { |
| 358 if (bstart) { |
| 359 m_CountBSArray->Add(i); |
| 360 counttmp = 1; |
| 361 recttmp = info.m_CharBox; |
| 362 bstart = FALSE; |
| 363 } else if (_IsInsameline(recttmp, info.m_CharBox)) { |
| 364 recttmp.right = info.m_CharBox.right; |
| 365 if (info.m_CharBox.top > recttmp.top) { |
| 366 recttmp.top = info.m_CharBox.top; |
| 367 } |
| 368 if (info.m_CharBox.bottom < recttmp.bottom) { |
| 369 recttmp.bottom = info.m_CharBox.bottom; |
| 370 } |
| 371 counttmp++; |
| 372 } else { |
| 373 m_CountBSArray->Add(counttmp); |
| 374 m_CountBSArray->Add(i); |
| 375 counttmp = 1; |
| 376 j++; |
| 377 recttmp = info.m_CharBox; |
| 378 } |
| 379 } |
| 380 } |
| 381 m_CountBSArray->Add(counttmp); |
| 382 j++; |
| 383 return j; |
| 384 } |
| 385 void CRF_TextPage::GetBoundedSegment(int index, int& start, int& count) const { |
| 386 if (!m_CountBSArray) { |
| 387 return; |
| 388 } |
| 389 if (m_CountBSArray->GetSize() <= index * 2) { |
| 390 start = 0; |
| 391 count = 0; |
| 392 return; |
| 393 } |
| 394 start = *(int*)m_CountBSArray->GetAt(index * 2); |
| 395 count = *(int*)m_CountBSArray->GetAt(index * 2 + 1); |
69 } | 396 } |
70 | 397 |
71 int» CRF_TextPage::CountChars() const | 398 int CRF_TextPage::GetWordBreak(int index, int direction) const { |
72 { | 399 return -1; |
73 if (NULL == m_pDataList) { | 400 } |
74 return -1; | 401 CFX_WideString CRF_TextPage::GetPageText(int start, int nCount) const { |
75 } | 402 if (nCount == -1) { |
76 return m_pDataList->GetSize(); | 403 nCount = CountChars(); |
77 } | 404 start = 0; |
78 void CRF_TextPage::GetCharInfo(int index, FPDF_CHAR_INFO & info) const | 405 } else if (nCount < 1) { |
79 { | 406 return L""; |
80 if(index >= CountChars() || index < 0 || !m_pDataList) { | 407 } else if (start >= CountChars()) { |
81 return; | 408 return L""; |
82 } | 409 } |
83 CRF_CharData* pData = (*m_pDataList)[index]; | 410 int i, index = start + nCount; |
84 FX_FLOAT ReltiveCorddDs = pData->m_pCharState->m_fDescent; | 411 FPDF_CHAR_INFO info; |
85 FX_FLOAT ReltiveCorddAs = pData->m_pCharState->m_fAscent; | 412 CFX_WideString str; |
86 info.m_Flag»» = CHAR_NORMAL; | 413 CFX_FloatRect recttmp; |
87 info.m_pTextObj» = pData->m_pCharState->m_pTextObj; | 414 FX_BOOL bstart = TRUE; |
88 info.m_OriginX» = pData->m_PosX; | 415 for (i = start; i < index; i++) { |
89 info.m_OriginY» = pData->m_PosY - ReltiveCorddDs; | 416 GetCharInfo(i, info); |
90 info.m_FontSize» = pData->m_pCharState->m_fFontSize; | 417 if (bstart) { |
91 CFX_FloatRect FloatRectTmp(pData->m_PosX, pData->m_PosY, pData->m_PosX + pDa
ta->m_Width, pData->m_PosY + ReltiveCorddAs - ReltiveCorddDs); | 418 recttmp = info.m_CharBox; |
92 info.m_CharBox» = FloatRectTmp; | 419 str += info.m_Unicode; |
93 CFX_WideString str = pData->m_pCharState->m_pFont->UnicodeFromCharCode(pData
->m_CharCode); | 420 bstart = FALSE; |
94 if(!str.IsEmpty()) { | 421 } else if (_IsInsameline(recttmp, info.m_CharBox)) { |
95 info.m_Unicode» = str.GetAt(0); | 422 str += info.m_Unicode; |
96 } else { | 423 } else { |
97 info.m_Unicode = -1; | 424 str += L"\r\n"; |
98 } | 425 recttmp = info.m_CharBox; |
99 info.m_Charcode = (FX_WCHAR)pData->m_CharCode; | 426 str += info.m_Unicode; |
100 info.m_Matrix = CFX_Matrix(1, 0, 0, 1, 0, 0); | 427 } |
101 } | 428 } |
102 extern FX_BOOL GetIntersection(FX_FLOAT low1, FX_FLOAT high1, FX_FLOAT low2, FX_
FLOAT high2, FX_FLOAT& interlow, FX_FLOAT& interhigh); | 429 if (str.IsEmpty()) { |
103 inline FX_BOOL _IsInsameline(const CFX_FloatRect& rectA, const CFX_FloatRect& re
ctB) | 430 return L""; |
104 { | 431 } |
105 if((rectA.top >= rectB.bottom && rectB.top >= rectA.bottom)) { | 432 return str; |
106 return TRUE; | 433 } |
107 } else { | |
108 return FALSE; | |
109 } | |
110 } | |
111 inline FX_BOOL _IsIntersect(const CFX_FloatRect& rectA, const CFX_FloatRect& rec
tB) | |
112 { | |
113 FX_FLOAT interlow = .0f, interhigh = .0f; | |
114 if(GetIntersection(rectA.bottom, rectA.top, rectB.bottom, rectB.top, interlo
w, interhigh)) { | |
115 if(GetIntersection(rectA.left, rectA.right, rectB.left, rectB.right, int
erlow, interhigh)) { | |
116 return TRUE; | |
117 } else { | |
118 return FALSE; | |
119 } | |
120 } | |
121 return FALSE; | |
122 } | |
123 void CRF_TextPage::GetRectArray(int start, int nCount, CFX_RectArray& rectArray)
const | |
124 { | |
125 int indexlen = start + nCount; | |
126 FPDF_CHAR_INFO info; | |
127 FX_BOOL bstart = TRUE; | |
128 CFX_FloatRect recttmp; | |
129 int i; | |
130 for(i = start; i < indexlen; i++) { | |
131 GetCharInfo(i, info); | |
132 if(bstart) { | |
133 recttmp = info.m_CharBox; | |
134 bstart = FALSE; | |
135 } else if(_IsInsameline(recttmp, info.m_CharBox)) { | |
136 recttmp.right = info.m_CharBox.right; | |
137 if(info.m_CharBox.top > recttmp.top) { | |
138 recttmp.top = info.m_CharBox.top; | |
139 } | |
140 if(info.m_CharBox.bottom < recttmp.bottom) { | |
141 recttmp.bottom = info.m_CharBox.bottom; | |
142 } | |
143 } else { | |
144 rectArray.Add(recttmp); | |
145 recttmp = info.m_CharBox; | |
146 } | |
147 } | |
148 rectArray.Add(recttmp); | |
149 } | |
150 inline FX_FLOAT _GetDistance(CFX_FloatRect floatRect, CPDF_Point point) | |
151 { | |
152 if(floatRect.right < point.x && floatRect.bottom > point.y) { | |
153 return FXSYS_sqrt(FXSYS_pow(point.x - floatRect.right, 2) + FXSYS_pow(fl
oatRect.bottom - point.y, 2)); | |
154 } | |
155 if (floatRect.right < point.x && floatRect.top < point.y) { | |
156 return FXSYS_sqrt(FXSYS_pow(point.x - floatRect.right, 2) + FXSYS_pow(po
int.y - floatRect.top, 2)); | |
157 } | |
158 if(floatRect.left > point.x && floatRect.bottom > point.y) { | |
159 return FXSYS_sqrt(FXSYS_pow(floatRect.bottom - point.y, 2) + FXSYS_pow(f
loatRect.left - point.x, 2)); | |
160 } | |
161 if((floatRect.right > point.x || FXSYS_fabs(floatRect.right - point.x) <= 0.
0001f) && | |
162 (floatRect.left < point.x || FXSYS_fabs(floatRect.left - point.x) <=
0.0001f) && floatRect.bottom > point.y) { | |
163 return FXSYS_fabs(floatRect.bottom - point.y); | |
164 } | |
165 if(floatRect.left > point.x && (floatRect.bottom < point.y || FXSYS_fabs(flo
atRect.bottom - point.y) <= 0.0001f) && | |
166 (floatRect.top > point.y || FXSYS_fabs(floatRect.top - point.y) <= 0
.0001f)) { | |
167 return FXSYS_fabs(floatRect.left - point.x); | |
168 } | |
169 if(floatRect.left > point.x && floatRect.top < point.y) { | |
170 return FXSYS_sqrt(FXSYS_pow(floatRect.left - point.x, 2) + FXSYS_pow(poi
nt.y - floatRect.top, 2)); | |
171 } | |
172 if ((floatRect.left < point.x || FXSYS_fabs(floatRect.left - point.x) <= 0.0
001f) && | |
173 (floatRect.right > point.x || FXSYS_fabs(floatRect.right - point.x)
<= 0.0001f) && floatRect.top < point.y) { | |
174 return FXSYS_fabs(point.y - floatRect.top); | |
175 } | |
176 if(floatRect.right < point.x && (floatRect.top > point.y || FXSYS_fabs(float
Rect.top - point.y) <= 0.0001f) && | |
177 (floatRect.bottom < point.y || FXSYS_fabs(floatRect.bottom - point.y
) <= 0.0001f)) { | |
178 return point.x - floatRect.right; | |
179 } | |
180 return .0f; | |
181 } | |
182 int CRF_TextPage::GetIndexAtPos(CPDF_Point point, FX_FLOAT xTorelance, FX_FLOAT
yTorelance) const | |
183 { | |
184 int index = -1, i = 0, j = 0; | |
185 FPDF_CHAR_INFO info; | |
186 CFX_FloatRect rectTmp; | |
187 FX_FLOAT MinDistance = 1000, DistanceTmp = 0; | |
188 FX_FLOAT rect_bottom = point.x - xTorelance; | |
189 CFX_FloatRect TorelanceRect(rect_bottom <= 0 ? 0 : rect_bottom, point.y - yT
orelance, point.x + xTorelance, point.y + yTorelance); | |
190 int count = CountChars(); | |
191 for(i = 0; i < count; i++) { | |
192 GetCharInfo(i, info); | |
193 rectTmp = info.m_CharBox; | |
194 if(rectTmp.Contains(point.x, point.y)) { | |
195 index = i; | |
196 break; | |
197 } else if(_IsIntersect(rectTmp, TorelanceRect)) { | |
198 DistanceTmp = _GetDistance(rectTmp, point); | |
199 if(DistanceTmp < MinDistance) { | |
200 MinDistance = DistanceTmp; | |
201 index = i; | |
202 } | |
203 } | |
204 } | |
205 return index; | |
206 } | |
207 int CRF_TextPage::GetIndexAtPos(FX_FLOAT x, FX_FLOAT y, FX_FLOAT xTorelance, FX_
FLOAT yTorelance) const | |
208 { | |
209 int index = 0; | |
210 CPDF_Point point(x, y); | |
211 if((index = GetIndexAtPos(point, xTorelance, yTorelance)) < 0) { | |
212 return -1; | |
213 } else { | |
214 return index; | |
215 } | |
216 } | |
217 int CRF_TextPage::GetOrderByDirection(int index, int direction) const | |
218 { | |
219 return -1; | |
220 } | |
221 CFX_WideString CRF_TextPage::GetTextByRect(CFX_FloatRect rect) const | |
222 { | |
223 int count; | |
224 FPDF_CHAR_INFO info; | |
225 CFX_WideString str; | |
226 CFX_FloatRect Recttmp; | |
227 FX_BOOL bstart = TRUE; | |
228 count = CountChars(); | |
229 if(rect.IsEmpty()) { | |
230 return L""; | |
231 } | |
232 for(int i = 0; i < count; i++) { | |
233 GetCharInfo(i, info); | |
234 if(_IsIntersect(rect, info.m_CharBox)) { | |
235 if(bstart) { | |
236 Recttmp = info.m_CharBox; | |
237 str += info.m_Unicode; | |
238 bstart = FALSE; | |
239 } else if(_IsInsameline(Recttmp, info.m_CharBox)) { | |
240 str += info.m_Unicode; | |
241 } else { | |
242 str += L"\r\n"; | |
243 Recttmp = info.m_CharBox; | |
244 str += info.m_Unicode; | |
245 } | |
246 } | |
247 } | |
248 if(str.IsEmpty()) { | |
249 return L""; | |
250 } else { | |
251 return str; | |
252 } | |
253 } | |
254 void CRF_TextPage::GetRectsArrayByRect(CFX_FloatRect rect, CFX_RectArray& resRec
tArray) const | |
255 { | |
256 int count, i; | |
257 FX_BOOL bstart = TRUE; | |
258 FPDF_CHAR_INFO info; | |
259 CFX_FloatRect recttmp; | |
260 count = CountChars(); | |
261 for(i = 0; i < count; i++) { | |
262 GetCharInfo(i, info); | |
263 if(_IsIntersect(rect, info.m_CharBox)) { | |
264 if(bstart) { | |
265 recttmp = info.m_CharBox; | |
266 bstart = FALSE; | |
267 } else if(_IsInsameline(recttmp, info.m_CharBox)) { | |
268 recttmp.right = info.m_CharBox.right; | |
269 if(info.m_CharBox.top > recttmp.top) { | |
270 recttmp.top = info.m_CharBox.top; | |
271 } | |
272 if(info.m_CharBox.bottom < recttmp.bottom) { | |
273 recttmp.bottom = info.m_CharBox.bottom; | |
274 } | |
275 } else { | |
276 resRectArray.Add(recttmp); | |
277 recttmp = info.m_CharBox; | |
278 } | |
279 } | |
280 } | |
281 resRectArray.Add(recttmp); | |
282 } | |
283 int CRF_TextPage::CountRects(int start, int nCount) | |
284 { | |
285 m_rectArray.RemoveAll(); | |
286 GetRectArray(start, nCount, m_rectArray); | |
287 return m_rectArray.GetSize(); | |
288 } | |
289 void CRF_TextPage::GetRect(int rectIndex, FX_FLOAT& left, FX_FLOAT& top, FX_FLOA
T& right, FX_FLOAT &bottom) const | |
290 { | |
291 if(m_rectArray.GetSize() <= rectIndex) { | |
292 return; | |
293 } | |
294 left = m_rectArray[rectIndex].left; | |
295 top = m_rectArray[rectIndex].top; | |
296 right = m_rectArray[rectIndex].right; | |
297 bottom = m_rectArray[rectIndex].bottom; | |
298 } | |
299 FX_BOOL CRF_TextPage::GetBaselineRotate(int rectIndex, int& Rotate) | |
300 { | |
301 Rotate = 0; | |
302 return TRUE; | |
303 } | |
304 FX_BOOL CRF_TextPage::GetBaselineRotate(CFX_FloatRect rect, int& Rotate) | |
305 { | |
306 Rotate = 0; | |
307 return TRUE; | |
308 } | |
309 int CRF_TextPage::CountBoundedSegments(FX_FLOAT left, FX_FLOAT top, FX_FLOAT rig
ht, FX_FLOAT bottom, FX_BOOL bContains) | |
310 { | |
311 if (!m_CountBSArray) { | |
312 return -1; | |
313 } | |
314 m_CountBSArray->RemoveAll(); | |
315 CFX_FloatRect floatrect(left, bottom, right, top); | |
316 int totalcount, i, j = 0, counttmp = 0; | |
317 FX_BOOL bstart = TRUE; | |
318 FPDF_CHAR_INFO info; | |
319 CFX_FloatRect recttmp; | |
320 totalcount = CountChars(); | |
321 for(i = 0; i < totalcount; i++) { | |
322 GetCharInfo(i, info); | |
323 if(_IsIntersect(floatrect, info.m_CharBox)) { | |
324 if(bstart) { | |
325 m_CountBSArray->Add(i); | |
326 counttmp = 1; | |
327 recttmp = info.m_CharBox; | |
328 bstart = FALSE; | |
329 } else if(_IsInsameline(recttmp, info.m_CharBox)) { | |
330 recttmp.right = info.m_CharBox.right; | |
331 if(info.m_CharBox.top > recttmp.top) { | |
332 recttmp.top = info.m_CharBox.top; | |
333 } | |
334 if(info.m_CharBox.bottom < recttmp.bottom) { | |
335 recttmp.bottom = info.m_CharBox.bottom; | |
336 } | |
337 counttmp ++; | |
338 } else { | |
339 m_CountBSArray->Add(counttmp); | |
340 m_CountBSArray->Add(i); | |
341 counttmp = 1; | |
342 j++; | |
343 recttmp = info.m_CharBox; | |
344 } | |
345 } | |
346 } | |
347 m_CountBSArray->Add(counttmp); | |
348 j++; | |
349 return j; | |
350 } | |
351 void CRF_TextPage::GetBoundedSegment(int index, int& start, int& count) const | |
352 { | |
353 if (!m_CountBSArray) { | |
354 return; | |
355 } | |
356 if(m_CountBSArray->GetSize() <= index * 2) { | |
357 start = 0; | |
358 count = 0; | |
359 return; | |
360 } | |
361 start = *(int *)m_CountBSArray->GetAt(index * 2); | |
362 count = *(int *)m_CountBSArray->GetAt(index * 2 + 1); | |
363 } | |
364 | |
365 int CRF_TextPage::GetWordBreak(int index, int direction) const | |
366 { | |
367 return -1; | |
368 } | |
369 CFX_WideString CRF_TextPage::GetPageText(int start, int nCount ) const | |
370 { | |
371 if(nCount == -1) { | |
372 nCount = CountChars(); | |
373 start = 0; | |
374 } else if(nCount < 1) { | |
375 return L""; | |
376 } else if(start >= CountChars()) { | |
377 return L""; | |
378 } | |
379 int i, index = start + nCount; | |
380 FPDF_CHAR_INFO info; | |
381 CFX_WideString str; | |
382 CFX_FloatRect recttmp; | |
383 FX_BOOL bstart = TRUE; | |
384 for(i = start; i < index; i++) { | |
385 GetCharInfo(i, info); | |
386 if(bstart) { | |
387 recttmp = info.m_CharBox; | |
388 str += info.m_Unicode; | |
389 bstart = FALSE; | |
390 } else if (_IsInsameline(recttmp, info.m_CharBox)) { | |
391 str += info.m_Unicode; | |
392 } else { | |
393 str += L"\r\n"; | |
394 recttmp = info.m_CharBox; | |
395 str += info.m_Unicode; | |
396 } | |
397 } | |
398 if(str.IsEmpty()) { | |
399 return L""; | |
400 } | |
401 return str; | |
402 } | |
OLD | NEW |