• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
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 <memory>
11 #include <utility>
12 
13 #include "core/fxcodec/fx_codec.h"
14 #include "core/fxcodec/progressive_decoder.h"
15 #include "core/fxcrt/check.h"
16 #include "core/fxcrt/maybe_owned.h"
17 #include "core/fxge/cfx_fillrenderoptions.h"
18 #include "core/fxge/cfx_path.h"
19 #include "core/fxge/cfx_renderdevice.h"
20 #include "core/fxge/dib/cfx_dibitmap.h"
21 #include "xfa/fgas/graphics/cfgas_gegraphics.h"
22 #include "xfa/fwl/fwl_widgethit.h"
23 #include "xfa/fxfa/cxfa_eventparam.h"
24 #include "xfa/fxfa/cxfa_ffapp.h"
25 #include "xfa/fxfa/cxfa_ffdoc.h"
26 #include "xfa/fxfa/cxfa_ffdocview.h"
27 #include "xfa/fxfa/cxfa_ffpageview.h"
28 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
29 #include "xfa/fxfa/cxfa_imagerenderer.h"
30 #include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
31 #include "xfa/fxfa/parser/cxfa_border.h"
32 #include "xfa/fxfa/parser/cxfa_box.h"
33 #include "xfa/fxfa/parser/cxfa_edge.h"
34 #include "xfa/fxfa/parser/cxfa_image.h"
35 #include "xfa/fxfa/parser/cxfa_margin.h"
36 #include "xfa/fxfa/parser/cxfa_node.h"
37 
XFA_DrawImage(CFGAS_GEGraphics * pGS,const CFX_RectF & rtImage,const CFX_Matrix & matrix,RetainPtr<CFX_DIBitmap> bitmap,XFA_AttributeValue iAspect,const CFX_Size & dpi,XFA_AttributeValue iHorzAlign,XFA_AttributeValue iVertAlign)38 void XFA_DrawImage(CFGAS_GEGraphics* pGS,
39                    const CFX_RectF& rtImage,
40                    const CFX_Matrix& matrix,
41                    RetainPtr<CFX_DIBitmap> bitmap,
42                    XFA_AttributeValue iAspect,
43                    const CFX_Size& dpi,
44                    XFA_AttributeValue iHorzAlign,
45                    XFA_AttributeValue iVertAlign) {
46   if (rtImage.IsEmpty())
47     return;
48 
49   CHECK(bitmap);
50   if (bitmap->GetBuffer().empty()) {
51     return;
52   }
53 
54   CFX_RectF rtFit(rtImage.TopLeft(),
55                   XFA_UnitPx2Pt(bitmap->GetWidth(), dpi.width),
56                   XFA_UnitPx2Pt(bitmap->GetHeight(), dpi.height));
57   switch (iAspect) {
58     case XFA_AttributeValue::Fit: {
59       float f1 = rtImage.height / rtFit.height;
60       float f2 = rtImage.width / rtFit.width;
61       f1 = std::min(f1, f2);
62       rtFit.height = rtFit.height * f1;
63       rtFit.width = rtFit.width * f1;
64       break;
65     }
66     case XFA_AttributeValue::Height: {
67       float f1 = rtImage.height / rtFit.height;
68       rtFit.height = rtImage.height;
69       rtFit.width = f1 * rtFit.width;
70       break;
71     }
72     case XFA_AttributeValue::None:
73       rtFit.height = rtImage.height;
74       rtFit.width = rtImage.width;
75       break;
76     case XFA_AttributeValue::Width: {
77       float f1 = rtImage.width / rtFit.width;
78       rtFit.width = rtImage.width;
79       rtFit.height = rtFit.height * f1;
80       break;
81     }
82     case XFA_AttributeValue::Actual:
83     default:
84       break;
85   }
86 
87   if (iHorzAlign == XFA_AttributeValue::Center)
88     rtFit.left += (rtImage.width - rtFit.width) / 2;
89   else if (iHorzAlign == XFA_AttributeValue::Right)
90     rtFit.left = rtImage.right() - rtFit.width;
91 
92   if (iVertAlign == XFA_AttributeValue::Middle)
93     rtFit.top += (rtImage.height - rtFit.height) / 2;
94   else if (iVertAlign == XFA_AttributeValue::Bottom)
95     rtFit.top = rtImage.bottom() - rtImage.height;
96 
97   CFX_RenderDevice* device = pGS->GetRenderDevice();
98   CFX_RenderDevice::StateRestorer restorer(device);
99   CFX_Path path;
100   path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
101   device->SetClip_PathFill(path, &matrix,
102                            CFX_FillRenderOptions::WindingOptions());
103 
104   CFX_Matrix image_to_device(1, 0, 0, -1, 0, 1);
105   image_to_device.Concat(
106       CFX_Matrix(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top));
107   image_to_device.Concat(matrix);
108 
109   CXFA_ImageRenderer image_renderer(device, std::move(bitmap), image_to_device);
110   if (!image_renderer.Start()) {
111     return;
112   }
113 
114   while (image_renderer.Continue()) {
115     continue;
116   }
117 }
118 
XFA_LoadImageFromBuffer(RetainPtr<IFX_SeekableReadStream> pImageFileRead,FXCODEC_IMAGE_TYPE type,int32_t & iImageXDpi,int32_t & iImageYDpi)119 RetainPtr<CFX_DIBitmap> XFA_LoadImageFromBuffer(
120     RetainPtr<IFX_SeekableReadStream> pImageFileRead,
121     FXCODEC_IMAGE_TYPE type,
122     int32_t& iImageXDpi,
123     int32_t& iImageYDpi) {
124   auto pProgressiveDecoder = std::make_unique<ProgressiveDecoder>();
125 
126   CFX_DIBAttribute dibAttr;
127   pProgressiveDecoder->LoadImageInfo(std::move(pImageFileRead), type, &dibAttr,
128                                      false);
129   switch (dibAttr.m_wDPIUnit) {
130     case CFX_DIBAttribute::kResUnitCentimeter:
131       dibAttr.m_nXDPI = static_cast<int32_t>(dibAttr.m_nXDPI * 2.54f);
132       dibAttr.m_nYDPI = static_cast<int32_t>(dibAttr.m_nYDPI * 2.54f);
133       break;
134     case CFX_DIBAttribute::kResUnitMeter:
135       dibAttr.m_nXDPI =
136           static_cast<int32_t>(dibAttr.m_nXDPI / (float)100 * 2.54f);
137       dibAttr.m_nYDPI =
138           static_cast<int32_t>(dibAttr.m_nYDPI / (float)100 * 2.54f);
139       break;
140     default:
141       break;
142   }
143   iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
144   iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
145   if (pProgressiveDecoder->GetWidth() <= 0 ||
146       pProgressiveDecoder->GetHeight() <= 0) {
147     return nullptr;
148   }
149 
150   RetainPtr<CFX_DIBitmap> pBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
151   if (!pBitmap->Create(pProgressiveDecoder->GetWidth(),
152                        pProgressiveDecoder->GetHeight(),
153                        pProgressiveDecoder->GetBitmapFormat())) {
154     return nullptr;
155   }
156 
157   pBitmap->Clear(0xffffffff);
158 
159   auto [status, nFrames] = pProgressiveDecoder->GetFrames();
160   if (status != FXCODEC_STATUS::kDecodeReady || nFrames == 0) {
161     return nullptr;
162   }
163 
164   status = pProgressiveDecoder->StartDecode(pBitmap);
165   if (status == FXCODEC_STATUS::kError) {
166     return nullptr;
167   }
168 
169   while (status == FXCODEC_STATUS::kDecodeToBeContinued) {
170     status = pProgressiveDecoder->ContinueDecode();
171     if (status == FXCODEC_STATUS::kError) {
172       return nullptr;
173     }
174   }
175 
176   return pBitmap;
177 }
178 
XFA_RectWithoutMargin(CFX_RectF * rt,const CXFA_Margin * margin)179 void XFA_RectWithoutMargin(CFX_RectF* rt, const CXFA_Margin* margin) {
180   if (!margin)
181     return;
182 
183   rt->Deflate(margin->GetLeftInset(), margin->GetTopInset(),
184               margin->GetRightInset(), margin->GetBottomInset());
185 }
186 
187 // static
FromLayoutItem(CXFA_LayoutItem * pLayoutItem)188 CXFA_FFWidget* CXFA_FFWidget::FromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
189   if (!pLayoutItem->GetFormNode()->HasCreatedUIWidget())
190     return nullptr;
191 
192   return GetFFWidget(ToContentLayoutItem(pLayoutItem));
193 }
194 
CXFA_FFWidget(CXFA_Node * node)195 CXFA_FFWidget::CXFA_FFWidget(CXFA_Node* node) : m_pNode(node) {}
196 
197 CXFA_FFWidget::~CXFA_FFWidget() = default;
198 
Trace(cppgc::Visitor * visitor) const199 void CXFA_FFWidget::Trace(cppgc::Visitor* visitor) const {
200   visitor->Trace(m_pLayoutItem);
201   visitor->Trace(m_pDocView);
202   visitor->Trace(m_pPageView);
203   visitor->Trace(m_pNode);
204 }
205 
GetFWLApp() const206 CFWL_App* CXFA_FFWidget::GetFWLApp() const {
207   return GetPageView()->GetDocView()->GetDoc()->GetApp()->GetFWLApp();
208 }
209 
GetNextFFWidget() const210 CXFA_FFWidget* CXFA_FFWidget::GetNextFFWidget() const {
211   return GetFFWidget(GetLayoutItem()->GetNext());
212 }
213 
GetWidgetRect() const214 const CFX_RectF& CXFA_FFWidget::GetWidgetRect() const {
215   if (!GetLayoutItem()->TestStatusBits(XFA_WidgetStatus::kRectCached))
216     RecacheWidgetRect();
217   return m_WidgetRect;
218 }
219 
RecacheWidgetRect() const220 const CFX_RectF& CXFA_FFWidget::RecacheWidgetRect() const {
221   GetLayoutItem()->SetStatusBits(XFA_WidgetStatus::kRectCached);
222   m_WidgetRect = GetLayoutItem()->GetAbsoluteRect();
223   return m_WidgetRect;
224 }
225 
GetRectWithoutRotate()226 CFX_RectF CXFA_FFWidget::GetRectWithoutRotate() {
227   CFX_RectF rtWidget = GetWidgetRect();
228   float fValue = 0;
229   switch (m_pNode->GetRotate()) {
230     case 90:
231       rtWidget.top = rtWidget.bottom();
232       fValue = rtWidget.width;
233       rtWidget.width = rtWidget.height;
234       rtWidget.height = fValue;
235       break;
236     case 180:
237       rtWidget.left = rtWidget.right();
238       rtWidget.top = rtWidget.bottom();
239       break;
240     case 270:
241       rtWidget.left = rtWidget.right();
242       fValue = rtWidget.width;
243       rtWidget.width = rtWidget.height;
244       rtWidget.height = fValue;
245       break;
246   }
247   return rtWidget;
248 }
249 
ModifyStatus(Mask<XFA_WidgetStatus> dwAdded,Mask<XFA_WidgetStatus> dwRemoved)250 void CXFA_FFWidget::ModifyStatus(Mask<XFA_WidgetStatus> dwAdded,
251                                  Mask<XFA_WidgetStatus> dwRemoved) {
252   GetLayoutItem()->ClearStatusBits(dwRemoved);
253   GetLayoutItem()->SetStatusBits(dwAdded);
254 }
255 
AsField()256 CXFA_FFField* CXFA_FFWidget::AsField() {
257   return nullptr;
258 }
259 
GetBBox(FocusOption focus)260 CFX_RectF CXFA_FFWidget::GetBBox(FocusOption focus) {
261   if (focus == kDrawFocus || !m_pPageView)
262     return CFX_RectF();
263   return m_pPageView->GetPageViewRect();
264 }
265 
RenderWidget(CFGAS_GEGraphics * pGS,const CFX_Matrix & matrix,HighlightOption highlight)266 void CXFA_FFWidget::RenderWidget(CFGAS_GEGraphics* pGS,
267                                  const CFX_Matrix& matrix,
268                                  HighlightOption highlight) {
269   if (!HasVisibleStatus())
270     return;
271 
272   CXFA_Border* border = m_pNode->GetBorderIfExists();
273   if (!border)
274     return;
275 
276   CFX_RectF rtBorder = GetRectWithoutRotate();
277   CXFA_Margin* margin = border->GetMarginIfExists();
278   XFA_RectWithoutMargin(&rtBorder, margin);
279   rtBorder.Normalize();
280   DrawBorder(pGS, border, rtBorder, matrix);
281 }
282 
IsLoaded()283 bool CXFA_FFWidget::IsLoaded() {
284   return !!m_pPageView;
285 }
286 
LoadWidget()287 bool CXFA_FFWidget::LoadWidget() {
288   PerformLayout();
289   return true;
290 }
291 
PerformLayout()292 bool CXFA_FFWidget::PerformLayout() {
293   RecacheWidgetRect();
294   return true;
295 }
296 
UpdateFWLData()297 bool CXFA_FFWidget::UpdateFWLData() {
298   return false;
299 }
300 
UpdateWidgetProperty()301 void CXFA_FFWidget::UpdateWidgetProperty() {}
302 
HasEventUnderHandler(XFA_EVENTTYPE eEventType,CXFA_FFWidgetHandler * pHandler)303 bool CXFA_FFWidget::HasEventUnderHandler(XFA_EVENTTYPE eEventType,
304                                          CXFA_FFWidgetHandler* pHandler) {
305   CXFA_Node* pNode = GetNode();
306   return pNode->IsWidgetReady() && pHandler->HasEvent(pNode, eEventType);
307 }
308 
ProcessEventUnderHandler(CXFA_EventParam * params,CXFA_FFWidgetHandler * pHandler)309 bool CXFA_FFWidget::ProcessEventUnderHandler(CXFA_EventParam* params,
310                                              CXFA_FFWidgetHandler* pHandler) {
311   CXFA_Node* pNode = GetNode();
312   if (!pNode->IsWidgetReady())
313     return false;
314 
315   return pHandler->ProcessEvent(pNode, params) == XFA_EventError::kSuccess;
316 }
317 
DrawBorder(CFGAS_GEGraphics * pGS,CXFA_Box * box,const CFX_RectF & rtBorder,const CFX_Matrix & matrix)318 void CXFA_FFWidget::DrawBorder(CFGAS_GEGraphics* pGS,
319                                CXFA_Box* box,
320                                const CFX_RectF& rtBorder,
321                                const CFX_Matrix& matrix) {
322   if (box)
323     box->Draw(pGS, rtBorder, matrix, false);
324 }
325 
DrawBorderWithFlag(CFGAS_GEGraphics * pGS,CXFA_Box * box,const CFX_RectF & rtBorder,const CFX_Matrix & matrix,bool forceRound)326 void CXFA_FFWidget::DrawBorderWithFlag(CFGAS_GEGraphics* pGS,
327                                        CXFA_Box* box,
328                                        const CFX_RectF& rtBorder,
329                                        const CFX_Matrix& matrix,
330                                        bool forceRound) {
331   if (box)
332     box->Draw(pGS, rtBorder, matrix, forceRound);
333 }
334 
InvalidateRect()335 void CXFA_FFWidget::InvalidateRect() {
336   CFX_RectF rtWidget = GetBBox(kDoNotDrawFocus);
337   rtWidget.Inflate(2, 2);
338   m_pDocView->InvalidateRect(m_pPageView.Get(), rtWidget);
339 }
340 
OnMouseEnter()341 bool CXFA_FFWidget::OnMouseEnter() {
342   return false;
343 }
344 
OnMouseExit()345 bool CXFA_FFWidget::OnMouseExit() {
346   return false;
347 }
348 
AcceptsFocusOnButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point,CFWL_MessageMouse::MouseCommand command)349 bool CXFA_FFWidget::AcceptsFocusOnButtonDown(
350     Mask<XFA_FWL_KeyFlag> dwFlags,
351     const CFX_PointF& point,
352     CFWL_MessageMouse::MouseCommand command) {
353   return false;
354 }
355 
OnLButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)356 bool CXFA_FFWidget::OnLButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,
357                                   const CFX_PointF& point) {
358   return false;
359 }
360 
OnLButtonUp(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)361 bool CXFA_FFWidget::OnLButtonUp(Mask<XFA_FWL_KeyFlag> dwFlags,
362                                 const CFX_PointF& point) {
363   return false;
364 }
365 
OnLButtonDblClk(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)366 bool CXFA_FFWidget::OnLButtonDblClk(Mask<XFA_FWL_KeyFlag> dwFlags,
367                                     const CFX_PointF& point) {
368   return false;
369 }
370 
OnMouseMove(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)371 bool CXFA_FFWidget::OnMouseMove(Mask<XFA_FWL_KeyFlag> dwFlags,
372                                 const CFX_PointF& point) {
373   return false;
374 }
375 
OnMouseWheel(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point,const CFX_Vector & delta)376 bool CXFA_FFWidget::OnMouseWheel(Mask<XFA_FWL_KeyFlag> dwFlags,
377                                  const CFX_PointF& point,
378                                  const CFX_Vector& delta) {
379   return false;
380 }
381 
OnRButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)382 bool CXFA_FFWidget::OnRButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,
383                                   const CFX_PointF& point) {
384   return false;
385 }
386 
OnRButtonUp(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)387 bool CXFA_FFWidget::OnRButtonUp(Mask<XFA_FWL_KeyFlag> dwFlags,
388                                 const CFX_PointF& point) {
389   return false;
390 }
391 
OnRButtonDblClk(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)392 bool CXFA_FFWidget::OnRButtonDblClk(Mask<XFA_FWL_KeyFlag> dwFlags,
393                                     const CFX_PointF& point) {
394   return false;
395 }
396 
OnSetFocus(CXFA_FFWidget * pOldWidget)397 bool CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
398   CXFA_FFWidget* pParent = GetFFWidget(ToContentLayoutItem(GetParent()));
399   if (pParent && !pParent->IsAncestorOf(pOldWidget)) {
400     if (!pParent->OnSetFocus(pOldWidget))
401       return false;
402   }
403   GetLayoutItem()->SetStatusBits(XFA_WidgetStatus::kFocused);
404 
405   CXFA_EventParam eParam(XFA_EVENT_Enter);
406   m_pNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Enter, &eParam);
407   return true;
408 }
409 
OnKillFocus(CXFA_FFWidget * pNewWidget)410 bool CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
411   GetLayoutItem()->ClearStatusBits(XFA_WidgetStatus::kFocused);
412   EventKillFocus();
413   if (!pNewWidget)
414     return true;
415 
416   CXFA_FFWidget* pParent = GetFFWidget(ToContentLayoutItem(GetParent()));
417   if (pParent && !pParent->IsAncestorOf(pNewWidget)) {
418     if (!pParent->OnKillFocus(pNewWidget))
419       return false;
420   }
421   return true;
422 }
423 
OnKeyDown(XFA_FWL_VKEYCODE dwKeyCode,Mask<XFA_FWL_KeyFlag> dwFlags)424 bool CXFA_FFWidget::OnKeyDown(XFA_FWL_VKEYCODE dwKeyCode,
425                               Mask<XFA_FWL_KeyFlag> dwFlags) {
426   return false;
427 }
428 
OnChar(uint32_t dwChar,Mask<XFA_FWL_KeyFlag> dwFlags)429 bool CXFA_FFWidget::OnChar(uint32_t dwChar, Mask<XFA_FWL_KeyFlag> dwFlags) {
430   return false;
431 }
432 
HitTest(const CFX_PointF & point)433 FWL_WidgetHit CXFA_FFWidget::HitTest(const CFX_PointF& point) {
434   return FWL_WidgetHit::Unknown;
435 }
436 
CanUndo()437 bool CXFA_FFWidget::CanUndo() {
438   return false;
439 }
440 
CanRedo()441 bool CXFA_FFWidget::CanRedo() {
442   return false;
443 }
444 
CanCopy()445 bool CXFA_FFWidget::CanCopy() {
446   return false;
447 }
448 
CanCut()449 bool CXFA_FFWidget::CanCut() {
450   return false;
451 }
452 
CanPaste()453 bool CXFA_FFWidget::CanPaste() {
454   return false;
455 }
456 
CanSelectAll()457 bool CXFA_FFWidget::CanSelectAll() {
458   return false;
459 }
460 
CanDelete()461 bool CXFA_FFWidget::CanDelete() {
462   return CanCut();
463 }
464 
CanDeSelect()465 bool CXFA_FFWidget::CanDeSelect() {
466   return CanCopy();
467 }
468 
Undo()469 bool CXFA_FFWidget::Undo() {
470   return false;
471 }
472 
Redo()473 bool CXFA_FFWidget::Redo() {
474   return false;
475 }
476 
Copy()477 std::optional<WideString> CXFA_FFWidget::Copy() {
478   return std::nullopt;
479 }
480 
Cut()481 std::optional<WideString> CXFA_FFWidget::Cut() {
482   return std::nullopt;
483 }
484 
Paste(const WideString & wsPaste)485 bool CXFA_FFWidget::Paste(const WideString& wsPaste) {
486   return false;
487 }
488 
SelectAll()489 void CXFA_FFWidget::SelectAll() {}
490 
Delete()491 void CXFA_FFWidget::Delete() {}
492 
DeSelect()493 void CXFA_FFWidget::DeSelect() {}
494 
GetText()495 WideString CXFA_FFWidget::GetText() {
496   return WideString();
497 }
498 
GetFormFieldType()499 FormFieldType CXFA_FFWidget::GetFormFieldType() {
500   return FormFieldType::kXFA;
501 }
502 
Rotate2Normal(const CFX_PointF & point)503 CFX_PointF CXFA_FFWidget::Rotate2Normal(const CFX_PointF& point) {
504   CFX_Matrix mt = GetRotateMatrix();
505   if (mt.IsIdentity())
506     return point;
507 
508   return mt.GetInverse().Transform(point);
509 }
510 
GetRotateMatrix()511 CFX_Matrix CXFA_FFWidget::GetRotateMatrix() {
512   int32_t iRotate = m_pNode->GetRotate();
513   if (!iRotate)
514     return CFX_Matrix();
515 
516   CFX_RectF rcWidget = GetRectWithoutRotate();
517   CFX_Matrix mt;
518   switch (iRotate) {
519     case 90:
520       mt.a = 0;
521       mt.b = -1;
522       mt.c = 1;
523       mt.d = 0;
524       mt.e = rcWidget.left - rcWidget.top;
525       mt.f = rcWidget.left + rcWidget.top;
526       break;
527     case 180:
528       mt.a = -1;
529       mt.b = 0;
530       mt.c = 0;
531       mt.d = -1;
532       mt.e = rcWidget.left * 2;
533       mt.f = rcWidget.top * 2;
534       break;
535     case 270:
536       mt.a = 0;
537       mt.b = 1;
538       mt.c = -1;
539       mt.d = 0;
540       mt.e = rcWidget.left + rcWidget.top;
541       mt.f = rcWidget.top - rcWidget.left;
542       break;
543   }
544   return mt;
545 }
546 
DisplayCaret(bool bVisible,const CFX_RectF * pRtAnchor)547 void CXFA_FFWidget::DisplayCaret(bool bVisible, const CFX_RectF* pRtAnchor) {
548   GetDoc()->DisplayCaret(this, bVisible, pRtAnchor);
549 }
550 
GetBorderColorAndThickness(FX_ARGB * cr,float * fWidth)551 void CXFA_FFWidget::GetBorderColorAndThickness(FX_ARGB* cr, float* fWidth) {
552   DCHECK(GetNode()->IsWidgetReady());
553   CXFA_Border* borderUI = GetNode()->GetUIBorder();
554   if (!borderUI)
555     return;
556 
557   CXFA_Edge* edge = borderUI->GetEdgeIfExists(0);
558   if (!edge)
559     return;
560 
561   *cr = edge->GetColor();
562   *fWidth = edge->GetThickness();
563 }
564 
IsLayoutRectEmpty()565 bool CXFA_FFWidget::IsLayoutRectEmpty() {
566   CFX_RectF rtLayout = GetRectWithoutRotate();
567   return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
568 }
569 
GetParent()570 CXFA_LayoutItem* CXFA_FFWidget::GetParent() {
571   CXFA_Node* pParentNode = m_pNode->GetParent();
572   if (!pParentNode)
573     return nullptr;
574 
575   CXFA_LayoutProcessor* layout = GetDocView()->GetLayoutProcessor();
576   return layout->GetLayoutItem(pParentNode);
577 }
578 
IsAncestorOf(CXFA_FFWidget * pWidget)579 bool CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
580   if (!pWidget)
581     return false;
582 
583   CXFA_Node* pChildNode = pWidget->GetNode();
584   while (pChildNode) {
585     if (pChildNode == m_pNode)
586       return true;
587 
588     pChildNode = pChildNode->GetParent();
589   }
590   return false;
591 }
592 
PtInActiveRect(const CFX_PointF & point)593 bool CXFA_FFWidget::PtInActiveRect(const CFX_PointF& point) {
594   return GetWidgetRect().Contains(point);
595 }
596 
GetDoc()597 CXFA_FFDoc* CXFA_FFWidget::GetDoc() {
598   return m_pDocView->GetDoc();
599 }
600 
GetApp()601 CXFA_FFApp* CXFA_FFWidget::GetApp() {
602   return GetDoc()->GetApp();
603 }
604 
GetAppProvider()605 CXFA_FFApp::CallbackIface* CXFA_FFWidget::GetAppProvider() {
606   return GetApp()->GetAppProvider();
607 }
608 
HasVisibleStatus() const609 bool CXFA_FFWidget::HasVisibleStatus() const {
610   return GetLayoutItem()->TestStatusBits(XFA_WidgetStatus::kVisible);
611 }
612 
EventKillFocus()613 void CXFA_FFWidget::EventKillFocus() {
614   CXFA_ContentLayoutItem* pItem = GetLayoutItem();
615   if (pItem->TestStatusBits(XFA_WidgetStatus::kAccess)) {
616     pItem->ClearStatusBits(XFA_WidgetStatus::kAccess);
617     return;
618   }
619   CXFA_EventParam eParam(XFA_EVENT_Exit);
620   m_pNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Exit, &eParam);
621 }
622 
IsButtonDown()623 bool CXFA_FFWidget::IsButtonDown() {
624   return GetLayoutItem()->TestStatusBits(XFA_WidgetStatus::kButtonDown);
625 }
626 
SetButtonDown(bool bSet)627 void CXFA_FFWidget::SetButtonDown(bool bSet) {
628   CXFA_ContentLayoutItem* pItem = GetLayoutItem();
629   if (bSet)
630     pItem->SetStatusBits(XFA_WidgetStatus::kButtonDown);
631   else
632     pItem->ClearStatusBits(XFA_WidgetStatus::kButtonDown);
633 }
634