• 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/fxfa/cxfa_ffwidget.h"
8 
9 #include <algorithm>
10 #include <cmath>
11 #include <memory>
12 #include <utility>
13 #include <vector>
14 
15 #include "core/fpdfapi/cpdf_modulemgr.h"
16 #include "core/fxcodec/codec/ccodec_progressivedecoder.h"
17 #include "core/fxcodec/fx_codec.h"
18 #include "core/fxcrt/cfx_memorystream.h"
19 #include "core/fxcrt/maybe_owned.h"
20 #include "core/fxge/cfx_pathdata.h"
21 #include "xfa/fwl/fwl_widgethit.h"
22 #include "xfa/fxfa/cxfa_eventparam.h"
23 #include "xfa/fxfa/cxfa_ffapp.h"
24 #include "xfa/fxfa/cxfa_ffdoc.h"
25 #include "xfa/fxfa/cxfa_ffdocview.h"
26 #include "xfa/fxfa/cxfa_ffpageview.h"
27 #include "xfa/fxfa/cxfa_imagerenderer.h"
28 #include "xfa/fxfa/cxfa_widgetacc.h"
29 #include "xfa/fxfa/parser/cxfa_border.h"
30 #include "xfa/fxfa/parser/cxfa_box.h"
31 #include "xfa/fxfa/parser/cxfa_image.h"
32 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
33 #include "xfa/fxfa/parser/cxfa_margin.h"
34 #include "xfa/fxfa/parser/cxfa_node.h"
35 #include "xfa/fxgraphics/cxfa_graphics.h"
36 
37 namespace {
38 
XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,int32_t iComponents,int32_t iBitsPerComponent)39 FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,
40                               int32_t iComponents,
41                               int32_t iBitsPerComponent) {
42   FXDIB_Format dibFormat = FXDIB_Argb;
43   switch (type) {
44     case FXCODEC_IMAGE_BMP:
45     case FXCODEC_IMAGE_JPG:
46     case FXCODEC_IMAGE_TIF: {
47       dibFormat = FXDIB_Rgb32;
48       int32_t bpp = iComponents * iBitsPerComponent;
49       if (bpp <= 24) {
50         dibFormat = FXDIB_Rgb;
51       }
52     } break;
53     case FXCODEC_IMAGE_PNG:
54     default:
55       break;
56   }
57   return dibFormat;
58 }
59 
IsFXCodecErrorStatus(FXCODEC_STATUS status)60 bool IsFXCodecErrorStatus(FXCODEC_STATUS status) {
61   return (status == FXCODEC_STATUS_ERROR ||
62 #ifdef PDF_ENABLE_XFA
63           status == FXCODEC_STATUS_ERR_MEMORY ||
64 #endif  // PDF_ENABLE_XFA
65           status == FXCODEC_STATUS_ERR_READ ||
66           status == FXCODEC_STATUS_ERR_FLUSH ||
67           status == FXCODEC_STATUS_ERR_FORMAT ||
68           status == FXCODEC_STATUS_ERR_PARAMS);
69 }
70 
71 }  // namespace
72 
XFA_DrawImage(CXFA_Graphics * pGS,const CFX_RectF & rtImage,const CFX_Matrix & matrix,const RetainPtr<CFX_DIBitmap> & pDIBitmap,XFA_AttributeEnum iAspect,int32_t iImageXDpi,int32_t iImageYDpi,XFA_AttributeEnum iHorzAlign,XFA_AttributeEnum iVertAlign)73 void XFA_DrawImage(CXFA_Graphics* pGS,
74                    const CFX_RectF& rtImage,
75                    const CFX_Matrix& matrix,
76                    const RetainPtr<CFX_DIBitmap>& pDIBitmap,
77                    XFA_AttributeEnum iAspect,
78                    int32_t iImageXDpi,
79                    int32_t iImageYDpi,
80                    XFA_AttributeEnum iHorzAlign,
81                    XFA_AttributeEnum iVertAlign) {
82   if (rtImage.IsEmpty())
83     return;
84   if (!pDIBitmap || !pDIBitmap->GetBuffer())
85     return;
86 
87   CFX_RectF rtFit(
88       rtImage.TopLeft(),
89       XFA_UnitPx2Pt((float)pDIBitmap->GetWidth(), (float)iImageXDpi),
90       XFA_UnitPx2Pt((float)pDIBitmap->GetHeight(), (float)iImageYDpi));
91   switch (iAspect) {
92     case XFA_AttributeEnum::Fit: {
93       float f1 = rtImage.height / rtFit.height;
94       float f2 = rtImage.width / rtFit.width;
95       f1 = std::min(f1, f2);
96       rtFit.height = rtFit.height * f1;
97       rtFit.width = rtFit.width * f1;
98       break;
99     }
100     case XFA_AttributeEnum::Height: {
101       float f1 = rtImage.height / rtFit.height;
102       rtFit.height = rtImage.height;
103       rtFit.width = f1 * rtFit.width;
104       break;
105     }
106     case XFA_AttributeEnum::None:
107       rtFit.height = rtImage.height;
108       rtFit.width = rtImage.width;
109       break;
110     case XFA_AttributeEnum::Width: {
111       float f1 = rtImage.width / rtFit.width;
112       rtFit.width = rtImage.width;
113       rtFit.height = rtFit.height * f1;
114       break;
115     }
116     case XFA_AttributeEnum::Actual:
117     default:
118       break;
119   }
120 
121   if (iHorzAlign == XFA_AttributeEnum::Center)
122     rtFit.left += (rtImage.width - rtFit.width) / 2;
123   else if (iHorzAlign == XFA_AttributeEnum::Right)
124     rtFit.left = rtImage.right() - rtFit.width;
125 
126   if (iVertAlign == XFA_AttributeEnum::Middle)
127     rtFit.top += (rtImage.height - rtFit.height) / 2;
128   else if (iVertAlign == XFA_AttributeEnum::Bottom)
129     rtFit.top = rtImage.bottom() - rtImage.height;
130 
131   CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
132   CFX_RenderDevice::StateRestorer restorer(pRenderDevice);
133   CFX_PathData path;
134   path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
135   pRenderDevice->SetClip_PathFill(&path, &matrix, FXFILL_WINDING);
136 
137   CFX_Matrix mtImage(1, 0, 0, -1, 0, 1);
138   mtImage.Concat(
139       CFX_Matrix(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top));
140   mtImage.Concat(matrix);
141 
142   CXFA_ImageRenderer imageRender(pRenderDevice, pDIBitmap, &mtImage);
143   if (!imageRender.Start()) {
144     return;
145   }
146   while (imageRender.Continue())
147     continue;
148 }
149 
XFA_LoadImageFromBuffer(const RetainPtr<IFX_SeekableReadStream> & pImageFileRead,FXCODEC_IMAGE_TYPE type,int32_t & iImageXDpi,int32_t & iImageYDpi)150 RetainPtr<CFX_DIBitmap> XFA_LoadImageFromBuffer(
151     const RetainPtr<IFX_SeekableReadStream>& pImageFileRead,
152     FXCODEC_IMAGE_TYPE type,
153     int32_t& iImageXDpi,
154     int32_t& iImageYDpi) {
155   CCodec_ModuleMgr* pCodecMgr = CPDF_ModuleMgr::Get()->GetCodecModule();
156   std::unique_ptr<CCodec_ProgressiveDecoder> pProgressiveDecoder =
157       pCodecMgr->CreateProgressiveDecoder();
158 
159   CFX_DIBAttribute dibAttr;
160   pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr, false);
161   switch (dibAttr.m_wDPIUnit) {
162     case FXCODEC_RESUNIT_CENTIMETER:
163       dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI * 2.54f);
164       dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI * 2.54f);
165       break;
166     case FXCODEC_RESUNIT_METER:
167       dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI / (float)100 * 2.54f);
168       dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI / (float)100 * 2.54f);
169       break;
170     default:
171       break;
172   }
173   iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
174   iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
175   if (pProgressiveDecoder->GetWidth() <= 0 ||
176       pProgressiveDecoder->GetHeight() <= 0) {
177     return nullptr;
178   }
179 
180   type = pProgressiveDecoder->GetType();
181   int32_t iComponents = pProgressiveDecoder->GetNumComponents();
182   int32_t iBpc = pProgressiveDecoder->GetBPC();
183   FXDIB_Format dibFormat = XFA_GetDIBFormat(type, iComponents, iBpc);
184   RetainPtr<CFX_DIBitmap> pBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
185   pBitmap->Create(pProgressiveDecoder->GetWidth(),
186                   pProgressiveDecoder->GetHeight(), dibFormat);
187   pBitmap->Clear(0xffffffff);
188 
189   size_t nFrames;
190   FXCODEC_STATUS status;
191   std::tie(status, nFrames) = pProgressiveDecoder->GetFrames();
192   if (status != FXCODEC_STATUS_DECODE_READY || nFrames == 0) {
193     pBitmap = nullptr;
194     return pBitmap;
195   }
196 
197   status = pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(),
198                                             pBitmap->GetHeight());
199   if (IsFXCodecErrorStatus(status)) {
200     pBitmap = nullptr;
201     return pBitmap;
202   }
203 
204   while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
205     status = pProgressiveDecoder->ContinueDecode();
206     if (IsFXCodecErrorStatus(status)) {
207       pBitmap = nullptr;
208       return pBitmap;
209     }
210   }
211 
212   return pBitmap;
213 }
214 
XFA_RectWithoutMargin(CFX_RectF & rt,const CXFA_Margin * margin,bool bUI)215 void XFA_RectWithoutMargin(CFX_RectF& rt, const CXFA_Margin* margin, bool bUI) {
216   if (!margin)
217     return;
218 
219   rt.Deflate(margin->GetLeftInset(), margin->GetTopInset(),
220              margin->GetRightInset(), margin->GetBottomInset());
221 }
222 
XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem * pLayoutItem)223 CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
224   if (pLayoutItem->GetFormNode()->HasCreatedUIWidget())
225     return static_cast<CXFA_FFWidget*>(pLayoutItem);
226   return nullptr;
227 }
228 
CXFA_CalcData()229 CXFA_CalcData::CXFA_CalcData() : m_iRefCount(0) {}
230 
~CXFA_CalcData()231 CXFA_CalcData::~CXFA_CalcData() {}
232 
CXFA_FFWidget(CXFA_Node * node)233 CXFA_FFWidget::CXFA_FFWidget(CXFA_Node* node)
234     : CXFA_ContentLayoutItem(node), m_pNode(node) {}
235 
~CXFA_FFWidget()236 CXFA_FFWidget::~CXFA_FFWidget() {}
237 
GetFWLApp()238 const CFWL_App* CXFA_FFWidget::GetFWLApp() {
239   return GetPageView()->GetDocView()->GetDoc()->GetApp()->GetFWLApp();
240 }
241 
GetWidgetRect() const242 const CFX_RectF& CXFA_FFWidget::GetWidgetRect() const {
243   if ((m_dwStatus & XFA_WidgetStatus_RectCached) == 0)
244     RecacheWidgetRect();
245   return m_rtWidget;
246 }
247 
RecacheWidgetRect() const248 const CFX_RectF& CXFA_FFWidget::RecacheWidgetRect() const {
249   m_dwStatus |= XFA_WidgetStatus_RectCached;
250   m_rtWidget = GetRect(false);
251   return m_rtWidget;
252 }
253 
GetRectWithoutRotate()254 CFX_RectF CXFA_FFWidget::GetRectWithoutRotate() {
255   CFX_RectF rtWidget = GetWidgetRect();
256   float fValue = 0;
257   switch (m_pNode->GetRotate()) {
258     case 90:
259       rtWidget.top = rtWidget.bottom();
260       fValue = rtWidget.width;
261       rtWidget.width = rtWidget.height;
262       rtWidget.height = fValue;
263       break;
264     case 180:
265       rtWidget.left = rtWidget.right();
266       rtWidget.top = rtWidget.bottom();
267       break;
268     case 270:
269       rtWidget.left = rtWidget.right();
270       fValue = rtWidget.width;
271       rtWidget.width = rtWidget.height;
272       rtWidget.height = fValue;
273       break;
274   }
275   return rtWidget;
276 }
277 
GetStatus()278 uint32_t CXFA_FFWidget::GetStatus() {
279   return m_dwStatus;
280 }
281 
ModifyStatus(uint32_t dwAdded,uint32_t dwRemoved)282 void CXFA_FFWidget::ModifyStatus(uint32_t dwAdded, uint32_t dwRemoved) {
283   m_dwStatus = (m_dwStatus & ~dwRemoved) | dwAdded;
284 }
285 
GetBBox(uint32_t dwStatus,bool bDrawFocus)286 CFX_RectF CXFA_FFWidget::GetBBox(uint32_t dwStatus, bool bDrawFocus) {
287   if (bDrawFocus || !m_pPageView)
288     return CFX_RectF();
289   return m_pPageView->GetPageViewRect();
290 }
291 
RenderWidget(CXFA_Graphics * pGS,const CFX_Matrix & matrix,uint32_t dwStatus)292 void CXFA_FFWidget::RenderWidget(CXFA_Graphics* pGS,
293                                  const CFX_Matrix& matrix,
294                                  uint32_t dwStatus) {
295   if (!IsMatchVisibleStatus(dwStatus))
296     return;
297 
298   CXFA_Border* border = m_pNode->GetBorderIfExists();
299   if (!border)
300     return;
301 
302   CFX_RectF rtBorder = GetRectWithoutRotate();
303   CXFA_Margin* margin = border->GetMarginIfExists();
304   if (margin)
305     XFA_RectWithoutMargin(rtBorder, margin);
306 
307   rtBorder.Normalize();
308   DrawBorder(pGS, border, rtBorder, matrix);
309 }
310 
IsLoaded()311 bool CXFA_FFWidget::IsLoaded() {
312   return !!m_pPageView;
313 }
314 
LoadWidget()315 bool CXFA_FFWidget::LoadWidget() {
316   PerformLayout();
317   return true;
318 }
319 
UnloadWidget()320 void CXFA_FFWidget::UnloadWidget() {}
321 
PerformLayout()322 bool CXFA_FFWidget::PerformLayout() {
323   RecacheWidgetRect();
324   return true;
325 }
326 
UpdateFWLData()327 bool CXFA_FFWidget::UpdateFWLData() {
328   return false;
329 }
330 
UpdateWidgetProperty()331 void CXFA_FFWidget::UpdateWidgetProperty() {}
332 
DrawBorder(CXFA_Graphics * pGS,CXFA_Box * box,const CFX_RectF & rtBorder,const CFX_Matrix & matrix)333 void CXFA_FFWidget::DrawBorder(CXFA_Graphics* pGS,
334                                CXFA_Box* box,
335                                const CFX_RectF& rtBorder,
336                                const CFX_Matrix& matrix) {
337   if (box)
338     box->Draw(pGS, rtBorder, matrix, false);
339 }
340 
DrawBorderWithFlag(CXFA_Graphics * pGS,CXFA_Box * box,const CFX_RectF & rtBorder,const CFX_Matrix & matrix,bool forceRound)341 void CXFA_FFWidget::DrawBorderWithFlag(CXFA_Graphics* pGS,
342                                        CXFA_Box* box,
343                                        const CFX_RectF& rtBorder,
344                                        const CFX_Matrix& matrix,
345                                        bool forceRound) {
346   if (box)
347     box->Draw(pGS, rtBorder, matrix, forceRound);
348 }
349 
AddInvalidateRect()350 void CXFA_FFWidget::AddInvalidateRect() {
351   CFX_RectF rtWidget = GetBBox(XFA_WidgetStatus_Focused);
352   rtWidget.Inflate(2, 2);
353   m_pDocView->AddInvalidateRect(m_pPageView, rtWidget);
354 }
355 
OnMouseEnter()356 bool CXFA_FFWidget::OnMouseEnter() {
357   return false;
358 }
359 
OnMouseExit()360 bool CXFA_FFWidget::OnMouseExit() {
361   return false;
362 }
363 
OnLButtonDown(uint32_t dwFlags,const CFX_PointF & point)364 bool CXFA_FFWidget::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
365   return false;
366 }
367 
OnLButtonUp(uint32_t dwFlags,const CFX_PointF & point)368 bool CXFA_FFWidget::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
369   return false;
370 }
371 
OnLButtonDblClk(uint32_t dwFlags,const CFX_PointF & point)372 bool CXFA_FFWidget::OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
373   return false;
374 }
375 
OnMouseMove(uint32_t dwFlags,const CFX_PointF & point)376 bool CXFA_FFWidget::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
377   return false;
378 }
379 
OnMouseWheel(uint32_t dwFlags,int16_t zDelta,const CFX_PointF & point)380 bool CXFA_FFWidget::OnMouseWheel(uint32_t dwFlags,
381                                  int16_t zDelta,
382                                  const CFX_PointF& point) {
383   return false;
384 }
385 
OnRButtonDown(uint32_t dwFlags,const CFX_PointF & point)386 bool CXFA_FFWidget::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
387   return false;
388 }
389 
OnRButtonUp(uint32_t dwFlags,const CFX_PointF & point)390 bool CXFA_FFWidget::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
391   return false;
392 }
393 
OnRButtonDblClk(uint32_t dwFlags,const CFX_PointF & point)394 bool CXFA_FFWidget::OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
395   return false;
396 }
397 
OnSetFocus(CXFA_FFWidget * pOldWidget)398 bool CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
399   CXFA_FFWidget* pParent = GetParent();
400   if (pParent && !pParent->IsAncestorOf(pOldWidget)) {
401     pParent->OnSetFocus(pOldWidget);
402   }
403   m_dwStatus |= XFA_WidgetStatus_Focused;
404   CXFA_EventParam eParam;
405   eParam.m_eType = XFA_EVENT_Enter;
406   eParam.m_pTarget = m_pNode->GetWidgetAcc();
407   m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Enter, &eParam);
408   return true;
409 }
410 
OnKillFocus(CXFA_FFWidget * pNewWidget)411 bool CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
412   m_dwStatus &= ~XFA_WidgetStatus_Focused;
413   EventKillFocus();
414   if (pNewWidget) {
415     CXFA_FFWidget* pParent = GetParent();
416     if (pParent && !pParent->IsAncestorOf(pNewWidget)) {
417       pParent->OnKillFocus(pNewWidget);
418     }
419   }
420   return true;
421 }
422 
OnKeyDown(uint32_t dwKeyCode,uint32_t dwFlags)423 bool CXFA_FFWidget::OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) {
424   return false;
425 }
426 
OnKeyUp(uint32_t dwKeyCode,uint32_t dwFlags)427 bool CXFA_FFWidget::OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) {
428   return false;
429 }
430 
OnChar(uint32_t dwChar,uint32_t dwFlags)431 bool CXFA_FFWidget::OnChar(uint32_t dwChar, uint32_t dwFlags) {
432   return false;
433 }
434 
OnHitTest(const CFX_PointF & point)435 FWL_WidgetHit CXFA_FFWidget::OnHitTest(const CFX_PointF& point) {
436   return FWL_WidgetHit::Unknown;
437 }
438 
OnSetCursor(const CFX_PointF & point)439 bool CXFA_FFWidget::OnSetCursor(const CFX_PointF& point) {
440   return false;
441 }
442 
CanUndo()443 bool CXFA_FFWidget::CanUndo() {
444   return false;
445 }
446 
CanRedo()447 bool CXFA_FFWidget::CanRedo() {
448   return false;
449 }
450 
Undo()451 bool CXFA_FFWidget::Undo() {
452   return false;
453 }
454 
Redo()455 bool CXFA_FFWidget::Redo() {
456   return false;
457 }
458 
CanCopy()459 bool CXFA_FFWidget::CanCopy() {
460   return false;
461 }
462 
CanCut()463 bool CXFA_FFWidget::CanCut() {
464   return false;
465 }
466 
CanPaste()467 bool CXFA_FFWidget::CanPaste() {
468   return false;
469 }
470 
CanSelectAll()471 bool CXFA_FFWidget::CanSelectAll() {
472   return false;
473 }
474 
CanDelete()475 bool CXFA_FFWidget::CanDelete() {
476   return CanCut();
477 }
478 
CanDeSelect()479 bool CXFA_FFWidget::CanDeSelect() {
480   return CanCopy();
481 }
482 
Copy()483 Optional<WideString> CXFA_FFWidget::Copy() {
484   return {};
485 }
486 
Cut()487 Optional<WideString> CXFA_FFWidget::Cut() {
488   return {};
489 }
490 
Paste(const WideString & wsPaste)491 bool CXFA_FFWidget::Paste(const WideString& wsPaste) {
492   return false;
493 }
494 
SelectAll()495 void CXFA_FFWidget::SelectAll() {}
496 
Delete()497 void CXFA_FFWidget::Delete() {}
498 
DeSelect()499 void CXFA_FFWidget::DeSelect() {}
500 
GetFormFieldType()501 FormFieldType CXFA_FFWidget::GetFormFieldType() {
502   return FormFieldType::kXFA;
503 }
504 
GetSuggestWords(CFX_PointF pointf,std::vector<ByteString> * pWords)505 void CXFA_FFWidget::GetSuggestWords(CFX_PointF pointf,
506                                     std::vector<ByteString>* pWords) {
507   pWords->clear();
508 }
509 
ReplaceSpellCheckWord(CFX_PointF pointf,const ByteStringView & bsReplace)510 bool CXFA_FFWidget::ReplaceSpellCheckWord(CFX_PointF pointf,
511                                           const ByteStringView& bsReplace) {
512   return false;
513 }
514 
Rotate2Normal(const CFX_PointF & point)515 CFX_PointF CXFA_FFWidget::Rotate2Normal(const CFX_PointF& point) {
516   CFX_Matrix mt = GetRotateMatrix();
517   if (mt.IsIdentity())
518     return point;
519 
520   return mt.GetInverse().Transform(point);
521 }
522 
GetRotateMatrix()523 CFX_Matrix CXFA_FFWidget::GetRotateMatrix() {
524   int32_t iRotate = m_pNode->GetRotate();
525   if (!iRotate)
526     return CFX_Matrix();
527 
528   CFX_RectF rcWidget = GetRectWithoutRotate();
529   CFX_Matrix mt;
530   switch (iRotate) {
531     case 90:
532       mt.a = 0;
533       mt.b = -1;
534       mt.c = 1;
535       mt.d = 0;
536       mt.e = rcWidget.left - rcWidget.top;
537       mt.f = rcWidget.left + rcWidget.top;
538       break;
539     case 180:
540       mt.a = -1;
541       mt.b = 0;
542       mt.c = 0;
543       mt.d = -1;
544       mt.e = rcWidget.left * 2;
545       mt.f = rcWidget.top * 2;
546       break;
547     case 270:
548       mt.a = 0;
549       mt.b = 1;
550       mt.c = -1;
551       mt.d = 0;
552       mt.e = rcWidget.left + rcWidget.top;
553       mt.f = rcWidget.top - rcWidget.left;
554       break;
555   }
556   return mt;
557 }
558 
IsLayoutRectEmpty()559 bool CXFA_FFWidget::IsLayoutRectEmpty() {
560   CFX_RectF rtLayout = GetRectWithoutRotate();
561   return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
562 }
563 
GetParent()564 CXFA_FFWidget* CXFA_FFWidget::GetParent() {
565   CXFA_Node* pParentNode = m_pNode->GetParent();
566   if (pParentNode) {
567     CXFA_WidgetAcc* pParentWidgetAcc =
568         static_cast<CXFA_WidgetAcc*>(pParentNode->GetWidgetAcc());
569     if (pParentWidgetAcc) {
570       CXFA_LayoutProcessor* layout = GetDocView()->GetXFALayout();
571       return static_cast<CXFA_FFWidget*>(
572           layout->GetLayoutItem(pParentWidgetAcc->GetNode()));
573     }
574   }
575   return nullptr;
576 }
577 
IsAncestorOf(CXFA_FFWidget * pWidget)578 bool CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
579   if (!pWidget)
580     return false;
581 
582   CXFA_Node* pChildNode = pWidget->GetNode();
583   while (pChildNode) {
584     if (pChildNode == m_pNode)
585       return true;
586 
587     pChildNode = pChildNode->GetParent();
588   }
589   return false;
590 }
591 
PtInActiveRect(const CFX_PointF & point)592 bool CXFA_FFWidget::PtInActiveRect(const CFX_PointF& point) {
593   return GetWidgetRect().Contains(point);
594 }
595 
GetDocView()596 CXFA_FFDocView* CXFA_FFWidget::GetDocView() {
597   return m_pDocView;
598 }
599 
SetDocView(CXFA_FFDocView * pDocView)600 void CXFA_FFWidget::SetDocView(CXFA_FFDocView* pDocView) {
601   m_pDocView = pDocView;
602 }
603 
GetDoc()604 CXFA_FFDoc* CXFA_FFWidget::GetDoc() {
605   return m_pDocView->GetDoc();
606 }
607 
GetApp()608 CXFA_FFApp* CXFA_FFWidget::GetApp() {
609   return GetDoc()->GetApp();
610 }
611 
GetAppProvider()612 IXFA_AppProvider* CXFA_FFWidget::GetAppProvider() {
613   return GetApp()->GetAppProvider();
614 }
615 
IsMatchVisibleStatus(uint32_t dwStatus)616 bool CXFA_FFWidget::IsMatchVisibleStatus(uint32_t dwStatus) {
617   return !!(m_dwStatus & XFA_WidgetStatus_Visible);
618 }
619 
EventKillFocus()620 void CXFA_FFWidget::EventKillFocus() {
621   if (m_dwStatus & XFA_WidgetStatus_Access) {
622     m_dwStatus &= ~XFA_WidgetStatus_Access;
623     return;
624   }
625   CXFA_EventParam eParam;
626   eParam.m_eType = XFA_EVENT_Exit;
627   eParam.m_pTarget = m_pNode->GetWidgetAcc();
628   m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Exit, &eParam);
629 }
630 
IsButtonDown()631 bool CXFA_FFWidget::IsButtonDown() {
632   return (m_dwStatus & XFA_WidgetStatus_ButtonDown) != 0;
633 }
634 
SetButtonDown(bool bSet)635 void CXFA_FFWidget::SetButtonDown(bool bSet) {
636   bSet ? m_dwStatus |= XFA_WidgetStatus_ButtonDown
637        : m_dwStatus &= ~XFA_WidgetStatus_ButtonDown;
638 }
639