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