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