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