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