1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "xfa/fwl/cfwl_widgetmgr.h" 8 9 #include <utility> 10 11 #include "third_party/base/ptr_util.h" 12 #include "xfa/fwl/cfwl_app.h" 13 #include "xfa/fwl/cfwl_form.h" 14 #include "xfa/fwl/cfwl_notedriver.h" 15 #include "xfa/fxfa/app/xfa_fwladapter.h" 16 #include "xfa/fxfa/xfa_ffapp.h" 17 18 namespace { 19 20 const int kNeedRepaintHitPoints = 12; 21 const int kNeedRepaintHitPiece = 3; 22 23 struct FWL_NEEDREPAINTHITDATA { 24 CFX_PointF hitPoint; 25 bool bNotNeedRepaint; 26 bool bNotContainByDirty; 27 }; 28 29 } // namespace 30 31 CFWL_WidgetMgr::CFWL_WidgetMgr(CXFA_FFApp* pAdapterNative) 32 : m_dwCapability(0), m_pAdapter(pAdapterNative->GetWidgetMgr(this)) { 33 ASSERT(m_pAdapter); 34 m_mapWidgetItem[nullptr] = pdfium::MakeUnique<Item>(); 35 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) 36 m_rtScreen.Reset(); 37 #endif 38 } 39 40 CFWL_WidgetMgr::~CFWL_WidgetMgr() {} 41 42 CFWL_Widget* CFWL_WidgetMgr::GetParentWidget(CFWL_Widget* pWidget) const { 43 Item* pItem = GetWidgetMgrItem(pWidget); 44 return pItem && pItem->pParent ? pItem->pParent->pWidget : nullptr; 45 } 46 47 CFWL_Widget* CFWL_WidgetMgr::GetOwnerWidget(CFWL_Widget* pWidget) const { 48 Item* pItem = GetWidgetMgrItem(pWidget); 49 return pItem && pItem->pOwner ? pItem->pOwner->pWidget : nullptr; 50 } 51 52 CFWL_Widget* CFWL_WidgetMgr::GetFirstSiblingWidget(CFWL_Widget* pWidget) const { 53 Item* pItem = GetWidgetMgrItem(pWidget); 54 if (!pItem) 55 return nullptr; 56 57 pItem = pItem->pPrevious; 58 while (pItem && pItem->pPrevious) 59 pItem = pItem->pPrevious; 60 return pItem ? pItem->pWidget : nullptr; 61 } 62 63 CFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(CFWL_Widget* pWidget) const { 64 Item* pItem = GetWidgetMgrItem(pWidget); 65 return pItem && pItem->pPrevious ? pItem->pPrevious->pWidget : nullptr; 66 } 67 68 CFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(CFWL_Widget* pWidget) const { 69 Item* pItem = GetWidgetMgrItem(pWidget); 70 return pItem && pItem->pNext ? pItem->pNext->pWidget : nullptr; 71 } 72 73 CFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(CFWL_Widget* pWidget) const { 74 Item* pItem = GetWidgetMgrItem(pWidget); 75 return pItem && pItem->pChild ? pItem->pChild->pWidget : nullptr; 76 } 77 78 CFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(CFWL_Widget* pWidget) const { 79 Item* pItem = GetWidgetMgrItem(pWidget); 80 if (!pItem) 81 return nullptr; 82 83 pItem = pItem->pChild; 84 while (pItem && pItem->pNext) 85 pItem = pItem->pNext; 86 return pItem ? pItem->pWidget : nullptr; 87 } 88 89 CFWL_Widget* CFWL_WidgetMgr::GetSystemFormWidget(CFWL_Widget* pWidget) const { 90 Item* pItem = GetWidgetMgrItem(pWidget); 91 while (pItem) { 92 if (IsAbleNative(pItem->pWidget)) 93 return pItem->pWidget; 94 pItem = pItem->pParent; 95 } 96 return nullptr; 97 } 98 99 void CFWL_WidgetMgr::AppendWidget(CFWL_Widget* pWidget) { 100 Item* pItem = GetWidgetMgrItem(pWidget); 101 if (!pItem) 102 return; 103 if (!pItem->pParent) 104 return; 105 106 Item* pChild = pItem->pParent->pChild; 107 int32_t i = 0; 108 while (pChild) { 109 if (pChild == pItem) { 110 if (pChild->pPrevious) 111 pChild->pPrevious->pNext = pChild->pNext; 112 if (pChild->pNext) 113 pChild->pNext->pPrevious = pChild->pPrevious; 114 if (pItem->pParent->pChild == pItem) 115 pItem->pParent->pChild = pItem->pNext; 116 117 pItem->pNext = nullptr; 118 pItem->pPrevious = nullptr; 119 break; 120 } 121 if (!pChild->pNext) 122 break; 123 124 pChild = pChild->pNext; 125 ++i; 126 } 127 128 pChild = pItem->pParent->pChild; 129 if (pChild) { 130 while (pChild->pNext) 131 pChild = pChild->pNext; 132 133 pChild->pNext = pItem; 134 pItem->pPrevious = pChild; 135 } else { 136 pItem->pParent->pChild = pItem; 137 pItem->pPrevious = nullptr; 138 } 139 pItem->pNext = nullptr; 140 } 141 142 void CFWL_WidgetMgr::RepaintWidget(CFWL_Widget* pWidget, 143 const CFX_RectF& rect) { 144 if (!m_pAdapter) 145 return; 146 147 CFWL_Widget* pNative = pWidget; 148 CFX_RectF transformedRect = rect; 149 if (IsFormDisabled()) { 150 CFWL_Widget* pOuter = pWidget->GetOuter(); 151 while (pOuter) { 152 CFX_RectF rtTemp = pNative->GetWidgetRect(); 153 transformedRect.left += rtTemp.left; 154 transformedRect.top += rtTemp.top; 155 pNative = pOuter; 156 pOuter = pOuter->GetOuter(); 157 } 158 } else if (!IsAbleNative(pWidget)) { 159 pNative = GetSystemFormWidget(pWidget); 160 if (!pNative) 161 return; 162 163 CFX_PointF pos = pWidget->TransformTo( 164 pNative, CFX_PointF(transformedRect.left, transformedRect.top)); 165 transformedRect.left = pos.x; 166 transformedRect.top = pos.y; 167 } 168 AddRedrawCounts(pNative); 169 m_pAdapter->RepaintWidget(pNative); 170 } 171 172 void CFWL_WidgetMgr::InsertWidget(CFWL_Widget* pParent, CFWL_Widget* pChild) { 173 Item* pParentItem = GetWidgetMgrItem(pParent); 174 if (!pParentItem) { 175 auto item = pdfium::MakeUnique<Item>(pParent); 176 pParentItem = item.get(); 177 m_mapWidgetItem[pParent] = std::move(item); 178 179 pParentItem->pParent = GetWidgetMgrItem(nullptr); 180 AppendWidget(pParent); 181 } 182 183 Item* pItem = GetWidgetMgrItem(pChild); 184 if (!pItem) { 185 auto item = pdfium::MakeUnique<Item>(pChild); 186 pItem = item.get(); 187 m_mapWidgetItem[pChild] = std::move(item); 188 } 189 if (pItem->pParent && pItem->pParent != pParentItem) { 190 if (pItem->pPrevious) 191 pItem->pPrevious->pNext = pItem->pNext; 192 if (pItem->pNext) 193 pItem->pNext->pPrevious = pItem->pPrevious; 194 if (pItem->pParent->pChild == pItem) 195 pItem->pParent->pChild = pItem->pNext; 196 } 197 pItem->pParent = pParentItem; 198 AppendWidget(pChild); 199 } 200 201 void CFWL_WidgetMgr::RemoveWidget(CFWL_Widget* pWidget) { 202 Item* pItem = GetWidgetMgrItem(pWidget); 203 if (!pItem) 204 return; 205 if (pItem->pPrevious) 206 pItem->pPrevious->pNext = pItem->pNext; 207 if (pItem->pNext) 208 pItem->pNext->pPrevious = pItem->pPrevious; 209 if (pItem->pParent && pItem->pParent->pChild == pItem) 210 pItem->pParent->pChild = pItem->pNext; 211 212 Item* pChild = pItem->pChild; 213 while (pChild) { 214 Item* pNext = pChild->pNext; 215 RemoveWidget(pChild->pWidget); 216 pChild = pNext; 217 } 218 m_mapWidgetItem.erase(pWidget); 219 } 220 221 void CFWL_WidgetMgr::SetOwner(CFWL_Widget* pOwner, CFWL_Widget* pOwned) { 222 Item* pParentItem = GetWidgetMgrItem(pOwner); 223 if (!pParentItem) { 224 auto item = pdfium::MakeUnique<Item>(pOwner); 225 pParentItem = item.get(); 226 m_mapWidgetItem[pOwner] = std::move(item); 227 228 pParentItem->pParent = GetWidgetMgrItem(nullptr); 229 AppendWidget(pOwner); 230 } 231 232 Item* pItem = GetWidgetMgrItem(pOwned); 233 if (!pItem) { 234 auto item = pdfium::MakeUnique<Item>(pOwned); 235 pItem = item.get(); 236 m_mapWidgetItem[pOwned] = std::move(item); 237 } 238 pItem->pOwner = pParentItem; 239 } 240 void CFWL_WidgetMgr::SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild) { 241 Item* pParentItem = GetWidgetMgrItem(pParent); 242 Item* pItem = GetWidgetMgrItem(pChild); 243 if (!pItem) 244 return; 245 if (pItem->pParent && pItem->pParent != pParentItem) { 246 if (pItem->pPrevious) 247 pItem->pPrevious->pNext = pItem->pNext; 248 if (pItem->pNext) 249 pItem->pNext->pPrevious = pItem->pPrevious; 250 if (pItem->pParent->pChild == pItem) 251 pItem->pParent->pChild = pItem->pNext; 252 253 pItem->pNext = nullptr; 254 pItem->pPrevious = nullptr; 255 } 256 pItem->pParent = pParentItem; 257 AppendWidget(pChild); 258 } 259 260 CFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(CFWL_Widget* parent, 261 const CFX_PointF& point) const { 262 if (!parent) 263 return nullptr; 264 265 CFX_PointF pos; 266 CFWL_Widget* child = GetLastChildWidget(parent); 267 while (child) { 268 if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) { 269 CFX_Matrix m; 270 m.SetIdentity(); 271 272 CFX_Matrix matrixOnParent; 273 m.SetReverse(matrixOnParent); 274 pos = m.Transform(point); 275 276 CFX_RectF bounds = child->GetWidgetRect(); 277 if (bounds.Contains(pos)) { 278 pos -= bounds.TopLeft(); 279 return GetWidgetAtPoint(child, pos); 280 } 281 } 282 child = GetPriorSiblingWidget(child); 283 } 284 return parent; 285 } 286 287 CFWL_Widget* CFWL_WidgetMgr::NextTab(CFWL_Widget* parent, 288 CFWL_Widget* focus, 289 bool& bFind) { 290 CFWL_WidgetMgr* pMgr = parent->GetOwnerApp()->GetWidgetMgr(); 291 CFWL_Widget* child = pMgr->GetFirstChildWidget(parent); 292 while (child) { 293 if (focus == child) 294 bFind = true; 295 296 CFWL_Widget* bRet = NextTab(child, focus, bFind); 297 if (bRet) 298 return bRet; 299 300 child = pMgr->GetNextSiblingWidget(child); 301 } 302 return nullptr; 303 } 304 305 int32_t CFWL_WidgetMgr::CountRadioButtonGroup(CFWL_Widget* pFirst) const { 306 int32_t iRet = 0; 307 CFWL_Widget* pChild = pFirst; 308 while (pChild) { 309 pChild = GetNextSiblingWidget(pChild); 310 ++iRet; 311 } 312 return iRet; 313 } 314 315 CFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader( 316 CFWL_Widget* pRadioButton) const { 317 CFWL_Widget* pNext = pRadioButton; 318 if (pNext && (pNext->GetStyles() & FWL_WGTSTYLE_Group)) 319 return pNext; 320 return nullptr; 321 } 322 323 std::vector<CFWL_Widget*> CFWL_WidgetMgr::GetSameGroupRadioButton( 324 CFWL_Widget* pRadioButton) const { 325 CFWL_Widget* pFirst = GetFirstSiblingWidget(pRadioButton); 326 if (!pFirst) 327 pFirst = pRadioButton; 328 329 if (CountRadioButtonGroup(pFirst) < 2) 330 return std::vector<CFWL_Widget*>(); 331 332 std::vector<CFWL_Widget*> group; 333 group.push_back(GetRadioButtonGroupHeader(pRadioButton)); 334 return group; 335 } 336 337 CFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(CFWL_Widget* pParent) const { 338 if ((pParent->GetClassID() == FWL_Type::PushButton) && 339 (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) { 340 return pParent; 341 } 342 343 CFWL_Widget* child = 344 pParent->GetOwnerApp()->GetWidgetMgr()->GetFirstChildWidget(pParent); 345 while (child) { 346 if ((child->GetClassID() == FWL_Type::PushButton) && 347 (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) { 348 return child; 349 } 350 if (CFWL_Widget* find = GetDefaultButton(child)) 351 return find; 352 353 child = child->GetOwnerApp()->GetWidgetMgr()->GetNextSiblingWidget(child); 354 } 355 return nullptr; 356 } 357 358 void CFWL_WidgetMgr::AddRedrawCounts(CFWL_Widget* pWidget) { 359 GetWidgetMgrItem(pWidget)->iRedrawCounter++; 360 } 361 362 void CFWL_WidgetMgr::ResetRedrawCounts(CFWL_Widget* pWidget) { 363 GetWidgetMgrItem(pWidget)->iRedrawCounter = 0; 364 } 365 366 CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem( 367 CFWL_Widget* pWidget) const { 368 auto it = m_mapWidgetItem.find(pWidget); 369 return it != m_mapWidgetItem.end() ? static_cast<Item*>(it->second.get()) 370 : nullptr; 371 } 372 373 bool CFWL_WidgetMgr::IsAbleNative(CFWL_Widget* pWidget) const { 374 if (!pWidget) 375 return false; 376 if (!pWidget->IsInstance(FWL_CLASS_Form)) 377 return false; 378 379 uint32_t dwStyles = pWidget->GetStyles(); 380 return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) == 381 FWL_WGTSTYLE_OverLapper) || 382 (dwStyles & FWL_WGTSTYLE_Popup); 383 } 384 385 void CFWL_WidgetMgr::GetAdapterPopupPos(CFWL_Widget* pWidget, 386 FX_FLOAT fMinHeight, 387 FX_FLOAT fMaxHeight, 388 const CFX_RectF& rtAnchor, 389 CFX_RectF& rtPopup) const { 390 m_pAdapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor, rtPopup); 391 } 392 393 void CFWL_WidgetMgr::OnSetCapability(uint32_t dwCapability) { 394 m_dwCapability = dwCapability; 395 } 396 397 void CFWL_WidgetMgr::OnProcessMessageToForm(CFWL_Message* pMessage) { 398 if (!pMessage) 399 return; 400 if (!pMessage->m_pDstTarget) 401 return; 402 403 CFWL_Widget* pDstWidget = pMessage->m_pDstTarget; 404 const CFWL_App* pApp = pDstWidget->GetOwnerApp(); 405 if (!pApp) 406 return; 407 408 CFWL_NoteDriver* pNoteDriver = 409 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); 410 if (!pNoteDriver) 411 return; 412 413 if (IsFormDisabled()) 414 pNoteDriver->ProcessMessage(pMessage->Clone()); 415 else 416 pNoteDriver->QueueMessage(pMessage->Clone()); 417 418 #if (_FX_OS_ == _FX_MACOSX_) 419 CFWL_NoteLoop* pTopLoop = pNoteDriver->GetTopLoop(); 420 if (pTopLoop) 421 pNoteDriver->UnqueueMessageAndProcess(pTopLoop); 422 #endif 423 } 424 425 void CFWL_WidgetMgr::OnDrawWidget(CFWL_Widget* pWidget, 426 CFX_Graphics* pGraphics, 427 const CFX_Matrix* pMatrix) { 428 if (!pWidget || !pGraphics) 429 return; 430 431 CFX_RectF clipCopy(0, 0, pWidget->GetWidgetRect().Size()); 432 CFX_RectF clipBounds; 433 434 #if _FX_OS_ == _FX_MACOSX_ 435 if (IsFormDisabled()) { 436 #endif // _FX_OS_ == _FX_MACOSX_ 437 438 pWidget->GetDelegate()->OnDrawWidget(pGraphics, pMatrix); 439 clipBounds = pGraphics->GetClipRect(); 440 clipCopy = clipBounds; 441 442 #if _FX_OS_ == _FX_MACOSX_ 443 } else { 444 clipBounds = CFX_RectF(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d); 445 const_cast<CFX_Matrix*>(pMatrix)->SetIdentity(); // FIXME: const cast. 446 pWidget->GetDelegate()->OnDrawWidget(pGraphics, pMatrix); 447 } 448 #endif // _FX_OS_ == _FX_MACOSX_ 449 450 if (!IsFormDisabled()) 451 clipBounds.Intersect(pWidget->GetClientRect()); 452 if (!clipBounds.IsEmpty()) 453 DrawChild(pWidget, clipBounds, pGraphics, pMatrix); 454 455 GetWidgetMgrItem(pWidget)->iRedrawCounter = 0; 456 ResetRedrawCounts(pWidget); 457 } 458 459 void CFWL_WidgetMgr::DrawChild(CFWL_Widget* parent, 460 const CFX_RectF& rtClip, 461 CFX_Graphics* pGraphics, 462 const CFX_Matrix* pMatrix) { 463 if (!parent) 464 return; 465 466 bool bFormDisable = IsFormDisabled(); 467 CFWL_Widget* pNextChild = GetFirstChildWidget(parent); 468 while (pNextChild) { 469 CFWL_Widget* child = pNextChild; 470 pNextChild = GetNextSiblingWidget(child); 471 if (child->GetStates() & FWL_WGTSTATE_Invisible) 472 continue; 473 474 CFX_RectF rtWidget = child->GetWidgetRect(); 475 if (rtWidget.IsEmpty()) 476 continue; 477 478 CFX_Matrix widgetMatrix; 479 CFX_RectF clipBounds(rtWidget); 480 if (!bFormDisable) 481 widgetMatrix = child->GetMatrix(); 482 if (pMatrix) 483 widgetMatrix.Concat(*pMatrix); 484 485 if (!bFormDisable) { 486 CFX_PointF pos = widgetMatrix.Transform(clipBounds.TopLeft()); 487 clipBounds.left = pos.x; 488 clipBounds.top = pos.y; 489 clipBounds.Intersect(rtClip); 490 if (clipBounds.IsEmpty()) 491 continue; 492 493 pGraphics->SaveGraphState(); 494 pGraphics->SetClipRect(clipBounds); 495 } 496 widgetMatrix.Translate(rtWidget.left, rtWidget.top, true); 497 498 if (IFWL_WidgetDelegate* pDelegate = child->GetDelegate()) { 499 if (IsFormDisabled() || IsNeedRepaint(child, &widgetMatrix, rtClip)) 500 pDelegate->OnDrawWidget(pGraphics, &widgetMatrix); 501 } 502 if (!bFormDisable) 503 pGraphics->RestoreGraphState(); 504 505 DrawChild(child, clipBounds, pGraphics, 506 bFormDisable ? &widgetMatrix : pMatrix); 507 child = GetNextSiblingWidget(child); 508 } 509 } 510 511 bool CFWL_WidgetMgr::IsNeedRepaint(CFWL_Widget* pWidget, 512 CFX_Matrix* pMatrix, 513 const CFX_RectF& rtDirty) { 514 Item* pItem = GetWidgetMgrItem(pWidget); 515 if (pItem && pItem->iRedrawCounter > 0) { 516 pItem->iRedrawCounter = 0; 517 return true; 518 } 519 520 CFX_RectF rtWidget(0, 0, pWidget->GetWidgetRect().Size()); 521 pMatrix->TransformRect(rtWidget); 522 if (!rtWidget.IntersectWith(rtDirty)) 523 return false; 524 525 CFWL_Widget* pChild = 526 pWidget->GetOwnerApp()->GetWidgetMgr()->GetFirstChildWidget(pWidget); 527 if (!pChild) 528 return true; 529 530 CFX_RectF rtChilds; 531 bool bChildIntersectWithDirty = false; 532 bool bOrginPtIntersectWidthChild = false; 533 bool bOrginPtIntersectWidthDirty = rtDirty.Contains(rtWidget.TopLeft()); 534 static FWL_NEEDREPAINTHITDATA hitPoint[kNeedRepaintHitPoints]; 535 FXSYS_memset(hitPoint, 0, sizeof(hitPoint)); 536 FX_FLOAT fxPiece = rtWidget.width / kNeedRepaintHitPiece; 537 FX_FLOAT fyPiece = rtWidget.height / kNeedRepaintHitPiece; 538 hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left; 539 hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x = 540 hitPoint[10].hitPoint.x = fxPiece + rtWidget.left; 541 hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x = 542 hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left; 543 hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x = 544 rtWidget.width + rtWidget.left; 545 hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top; 546 hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y = 547 hitPoint[5].hitPoint.y = fyPiece + rtWidget.top; 548 hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y = 549 hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top; 550 hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y = 551 rtWidget.height + rtWidget.top; 552 do { 553 CFX_RectF rect = pChild->GetWidgetRect(); 554 CFX_RectF r(rect.left + rtWidget.left, rect.top + rtWidget.top, rect.width, 555 rect.height); 556 if (r.IsEmpty()) 557 continue; 558 if (r.Contains(rtDirty)) 559 return false; 560 if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty)) 561 bChildIntersectWithDirty = true; 562 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) 563 bOrginPtIntersectWidthChild = rect.Contains(CFX_PointF(0, 0)); 564 565 if (rtChilds.IsEmpty()) 566 rtChilds = rect; 567 else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible)) 568 rtChilds.Union(rect); 569 570 for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) { 571 if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint) 572 continue; 573 if (!rtDirty.Contains(hitPoint[i].hitPoint)) { 574 hitPoint[i].bNotContainByDirty = true; 575 continue; 576 } 577 if (r.Contains(hitPoint[i].hitPoint)) 578 hitPoint[i].bNotNeedRepaint = true; 579 } 580 pChild = 581 pChild->GetOwnerApp()->GetWidgetMgr()->GetNextSiblingWidget(pChild); 582 } while (pChild); 583 584 if (!bChildIntersectWithDirty) 585 return true; 586 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) 587 return true; 588 if (rtChilds.IsEmpty()) 589 return true; 590 591 int32_t repaintPoint = kNeedRepaintHitPoints; 592 for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) { 593 if (hitPoint[i].bNotNeedRepaint) 594 repaintPoint--; 595 } 596 if (repaintPoint > 0) 597 return true; 598 599 pMatrix->TransformRect(rtChilds); 600 if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget)) 601 return false; 602 return true; 603 } 604 605 CFWL_WidgetMgr::Item::Item() : CFWL_WidgetMgr::Item(nullptr) {} 606 607 CFWL_WidgetMgr::Item::Item(CFWL_Widget* widget) 608 : pParent(nullptr), 609 pOwner(nullptr), 610 pChild(nullptr), 611 pPrevious(nullptr), 612 pNext(nullptr), 613 pWidget(widget), 614 iRedrawCounter(0) 615 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) 616 , 617 bOutsideChanged(false) 618 #endif 619 { 620 } 621 622 CFWL_WidgetMgr::Item::~Item() {} 623