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/fxcodec/fx_codec.h"
16 #include "core/fxcodec/progressivedecoder.h"
17 #include "core/fxcrt/maybe_owned.h"
18 #include "core/fxge/cfx_pathdata.h"
19 #include "core/fxge/cfx_renderdevice.h"
20 #include "core/fxge/dib/cfx_dibitmap.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_ffwidgethandler.h"
28 #include "xfa/fxfa/cxfa_imagerenderer.h"
29 #include "xfa/fxfa/layout/cxfa_layoutprocessor.h"
30 #include "xfa/fxfa/parser/cxfa_border.h"
31 #include "xfa/fxfa/parser/cxfa_box.h"
32 #include "xfa/fxfa/parser/cxfa_edge.h"
33 #include "xfa/fxfa/parser/cxfa_image.h"
34 #include "xfa/fxfa/parser/cxfa_margin.h"
35 #include "xfa/fxfa/parser/cxfa_node.h"
36 #include "xfa/fxgraphics/cxfa_graphics.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_Argb;
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_Rgb32;
54 int32_t bpp = iComponents * iBitsPerComponent;
55 if (bpp <= 24) {
56 dibFormat = FXDIB_Rgb;
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
IsFXCodecErrorStatus(FXCODEC_STATUS status)68 bool IsFXCodecErrorStatus(FXCODEC_STATUS status) {
69 return (status == FXCODEC_STATUS_ERROR ||
70 status == FXCODEC_STATUS_ERR_MEMORY ||
71 status == FXCODEC_STATUS_ERR_READ ||
72 status == FXCODEC_STATUS_ERR_FLUSH ||
73 status == FXCODEC_STATUS_ERR_FORMAT ||
74 status == FXCODEC_STATUS_ERR_PARAMS);
75 }
76
77 } // namespace
78
XFA_DrawImage(CXFA_Graphics * pGS,const CFX_RectF & rtImage,const CFX_Matrix & matrix,const RetainPtr<CFX_DIBitmap> & pDIBitmap,XFA_AttributeValue iAspect,const CFX_Size & dpi,XFA_AttributeValue iHorzAlign,XFA_AttributeValue iVertAlign)79 void XFA_DrawImage(CXFA_Graphics* pGS,
80 const CFX_RectF& rtImage,
81 const CFX_Matrix& matrix,
82 const RetainPtr<CFX_DIBitmap>& pDIBitmap,
83 XFA_AttributeValue iAspect,
84 const CFX_Size& dpi,
85 XFA_AttributeValue iHorzAlign,
86 XFA_AttributeValue iVertAlign) {
87 if (rtImage.IsEmpty())
88 return;
89 if (!pDIBitmap || !pDIBitmap->GetBuffer())
90 return;
91
92 CFX_RectF rtFit(rtImage.TopLeft(),
93 XFA_UnitPx2Pt(pDIBitmap->GetWidth(), dpi.width),
94 XFA_UnitPx2Pt(pDIBitmap->GetHeight(), dpi.height));
95 switch (iAspect) {
96 case XFA_AttributeValue::Fit: {
97 float f1 = rtImage.height / rtFit.height;
98 float f2 = rtImage.width / rtFit.width;
99 f1 = std::min(f1, f2);
100 rtFit.height = rtFit.height * f1;
101 rtFit.width = rtFit.width * f1;
102 break;
103 }
104 case XFA_AttributeValue::Height: {
105 float f1 = rtImage.height / rtFit.height;
106 rtFit.height = rtImage.height;
107 rtFit.width = f1 * rtFit.width;
108 break;
109 }
110 case XFA_AttributeValue::None:
111 rtFit.height = rtImage.height;
112 rtFit.width = rtImage.width;
113 break;
114 case XFA_AttributeValue::Width: {
115 float f1 = rtImage.width / rtFit.width;
116 rtFit.width = rtImage.width;
117 rtFit.height = rtFit.height * f1;
118 break;
119 }
120 case XFA_AttributeValue::Actual:
121 default:
122 break;
123 }
124
125 if (iHorzAlign == XFA_AttributeValue::Center)
126 rtFit.left += (rtImage.width - rtFit.width) / 2;
127 else if (iHorzAlign == XFA_AttributeValue::Right)
128 rtFit.left = rtImage.right() - rtFit.width;
129
130 if (iVertAlign == XFA_AttributeValue::Middle)
131 rtFit.top += (rtImage.height - rtFit.height) / 2;
132 else if (iVertAlign == XFA_AttributeValue::Bottom)
133 rtFit.top = rtImage.bottom() - rtImage.height;
134
135 CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
136 CFX_RenderDevice::StateRestorer restorer(pRenderDevice);
137 CFX_PathData path;
138 path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
139 pRenderDevice->SetClip_PathFill(&path, &matrix, FXFILL_WINDING);
140
141 CFX_Matrix mtImage(1, 0, 0, -1, 0, 1);
142 mtImage.Concat(
143 CFX_Matrix(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top));
144 mtImage.Concat(matrix);
145
146 CXFA_ImageRenderer imageRender(pRenderDevice, pDIBitmap, &mtImage);
147 if (!imageRender.Start()) {
148 return;
149 }
150 while (imageRender.Continue())
151 continue;
152 }
153
XFA_LoadImageFromBuffer(const RetainPtr<IFX_SeekableReadStream> & pImageFileRead,FXCODEC_IMAGE_TYPE type,int32_t & iImageXDpi,int32_t & iImageYDpi)154 RetainPtr<CFX_DIBitmap> XFA_LoadImageFromBuffer(
155 const RetainPtr<IFX_SeekableReadStream>& pImageFileRead,
156 FXCODEC_IMAGE_TYPE type,
157 int32_t& iImageXDpi,
158 int32_t& iImageYDpi) {
159 auto* pCodecMgr = fxcodec::ModuleMgr::GetInstance();
160 std::unique_ptr<ProgressiveDecoder> pProgressiveDecoder =
161 pCodecMgr->CreateProgressiveDecoder();
162
163 CFX_DIBAttribute dibAttr;
164 pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr, false);
165 switch (dibAttr.m_wDPIUnit) {
166 case FXCODEC_RESUNIT_CENTIMETER:
167 dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI * 2.54f);
168 dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI * 2.54f);
169 break;
170 case FXCODEC_RESUNIT_METER:
171 dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI / (float)100 * 2.54f);
172 dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI / (float)100 * 2.54f);
173 break;
174 default:
175 break;
176 }
177 iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
178 iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
179 if (pProgressiveDecoder->GetWidth() <= 0 ||
180 pProgressiveDecoder->GetHeight() <= 0) {
181 return nullptr;
182 }
183
184 type = pProgressiveDecoder->GetType();
185 int32_t iComponents = pProgressiveDecoder->GetNumComponents();
186 int32_t iBpc = pProgressiveDecoder->GetBPC();
187 FXDIB_Format dibFormat = XFA_GetDIBFormat(type, iComponents, iBpc);
188 RetainPtr<CFX_DIBitmap> pBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
189 pBitmap->Create(pProgressiveDecoder->GetWidth(),
190 pProgressiveDecoder->GetHeight(), dibFormat);
191 pBitmap->Clear(0xffffffff);
192
193 size_t nFrames;
194 FXCODEC_STATUS status;
195 std::tie(status, nFrames) = pProgressiveDecoder->GetFrames();
196 if (status != FXCODEC_STATUS_DECODE_READY || nFrames == 0) {
197 pBitmap = nullptr;
198 return pBitmap;
199 }
200
201 status = pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(),
202 pBitmap->GetHeight());
203 if (IsFXCodecErrorStatus(status)) {
204 pBitmap = nullptr;
205 return pBitmap;
206 }
207
208 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
209 status = pProgressiveDecoder->ContinueDecode();
210 if (IsFXCodecErrorStatus(status)) {
211 pBitmap = nullptr;
212 return pBitmap;
213 }
214 }
215
216 return pBitmap;
217 }
218
XFA_RectWithoutMargin(CFX_RectF * rt,const CXFA_Margin * margin)219 void XFA_RectWithoutMargin(CFX_RectF* rt, const CXFA_Margin* margin) {
220 if (!margin)
221 return;
222
223 rt->Deflate(margin->GetLeftInset(), margin->GetTopInset(),
224 margin->GetRightInset(), margin->GetBottomInset());
225 }
226
XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem * pLayoutItem)227 CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
228 if (!pLayoutItem->GetFormNode()->HasCreatedUIWidget())
229 return nullptr;
230
231 return GetFFWidget(ToContentLayoutItem(pLayoutItem));
232 }
233
234 CXFA_CalcData::CXFA_CalcData() = default;
235
236 CXFA_CalcData::~CXFA_CalcData() = default;
237
CXFA_FFWidget(CXFA_Node * node)238 CXFA_FFWidget::CXFA_FFWidget(CXFA_Node* node) : m_pNode(node) {}
239
240 CXFA_FFWidget::~CXFA_FFWidget() = default;
241
GetFWLApp()242 const CFWL_App* CXFA_FFWidget::GetFWLApp() {
243 return GetPageView()->GetDocView()->GetDoc()->GetApp()->GetFWLApp();
244 }
245
GetNextFFWidget() const246 CXFA_FFWidget* CXFA_FFWidget::GetNextFFWidget() const {
247 return GetFFWidget(GetLayoutItem()->GetNext());
248 }
249
GetWidgetRect() const250 const CFX_RectF& CXFA_FFWidget::GetWidgetRect() const {
251 if (!GetLayoutItem()->TestStatusBits(XFA_WidgetStatus_RectCached))
252 RecacheWidgetRect();
253 return m_rtWidget;
254 }
255
RecacheWidgetRect() const256 const CFX_RectF& CXFA_FFWidget::RecacheWidgetRect() const {
257 GetLayoutItem()->SetStatusBits(XFA_WidgetStatus_RectCached);
258 m_rtWidget = GetLayoutItem()->GetRect(false);
259 return m_rtWidget;
260 }
261
GetRectWithoutRotate()262 CFX_RectF CXFA_FFWidget::GetRectWithoutRotate() {
263 CFX_RectF rtWidget = GetWidgetRect();
264 float fValue = 0;
265 switch (m_pNode->GetRotate()) {
266 case 90:
267 rtWidget.top = rtWidget.bottom();
268 fValue = rtWidget.width;
269 rtWidget.width = rtWidget.height;
270 rtWidget.height = fValue;
271 break;
272 case 180:
273 rtWidget.left = rtWidget.right();
274 rtWidget.top = rtWidget.bottom();
275 break;
276 case 270:
277 rtWidget.left = rtWidget.right();
278 fValue = rtWidget.width;
279 rtWidget.width = rtWidget.height;
280 rtWidget.height = fValue;
281 break;
282 }
283 return rtWidget;
284 }
285
ModifyStatus(uint32_t dwAdded,uint32_t dwRemoved)286 void CXFA_FFWidget::ModifyStatus(uint32_t dwAdded, uint32_t dwRemoved) {
287 GetLayoutItem()->ClearStatusBits(dwRemoved);
288 GetLayoutItem()->SetStatusBits(dwAdded);
289 }
290
AsField()291 CXFA_FFField* CXFA_FFWidget::AsField() {
292 return nullptr;
293 }
294
GetBBox(FocusOption focus)295 CFX_RectF CXFA_FFWidget::GetBBox(FocusOption focus) {
296 if (focus == kDrawFocus || !m_pPageView)
297 return CFX_RectF();
298 return m_pPageView->GetPageViewRect();
299 }
300
RenderWidget(CXFA_Graphics * pGS,const CFX_Matrix & matrix,HighlightOption highlight)301 void CXFA_FFWidget::RenderWidget(CXFA_Graphics* pGS,
302 const CFX_Matrix& matrix,
303 HighlightOption highlight) {
304 if (!HasVisibleStatus())
305 return;
306
307 CXFA_Border* border = m_pNode->GetBorderIfExists();
308 if (!border)
309 return;
310
311 CFX_RectF rtBorder = GetRectWithoutRotate();
312 CXFA_Margin* margin = border->GetMarginIfExists();
313 XFA_RectWithoutMargin(&rtBorder, margin);
314 rtBorder.Normalize();
315 DrawBorder(pGS, border, rtBorder, matrix);
316 }
317
IsLoaded()318 bool CXFA_FFWidget::IsLoaded() {
319 return !!m_pPageView;
320 }
321
LoadWidget()322 bool CXFA_FFWidget::LoadWidget() {
323 PerformLayout();
324 return true;
325 }
326
PerformLayout()327 bool CXFA_FFWidget::PerformLayout() {
328 RecacheWidgetRect();
329 return true;
330 }
331
UpdateFWLData()332 bool CXFA_FFWidget::UpdateFWLData() {
333 return false;
334 }
335
UpdateWidgetProperty()336 void CXFA_FFWidget::UpdateWidgetProperty() {}
337
HasEventUnderHandler(XFA_EVENTTYPE eEventType,CXFA_FFWidgetHandler * pHandler)338 bool CXFA_FFWidget::HasEventUnderHandler(XFA_EVENTTYPE eEventType,
339 CXFA_FFWidgetHandler* pHandler) {
340 CXFA_Node* pNode = GetNode();
341 return pNode->IsWidgetReady() && pHandler->HasEvent(pNode, eEventType);
342 }
343
ProcessEventUnderHandler(CXFA_EventParam * params,CXFA_FFWidgetHandler * pHandler)344 bool CXFA_FFWidget::ProcessEventUnderHandler(CXFA_EventParam* params,
345 CXFA_FFWidgetHandler* pHandler) {
346 CXFA_Node* pNode = GetNode();
347 if (!pNode->IsWidgetReady())
348 return false;
349
350 params->m_pTarget = pNode;
351 return pHandler->ProcessEvent(pNode, params) == XFA_EventError::kSuccess;
352 }
353
DrawBorder(CXFA_Graphics * pGS,CXFA_Box * box,const CFX_RectF & rtBorder,const CFX_Matrix & matrix)354 void CXFA_FFWidget::DrawBorder(CXFA_Graphics* pGS,
355 CXFA_Box* box,
356 const CFX_RectF& rtBorder,
357 const CFX_Matrix& matrix) {
358 if (box)
359 box->Draw(pGS, rtBorder, matrix, false);
360 }
361
DrawBorderWithFlag(CXFA_Graphics * pGS,CXFA_Box * box,const CFX_RectF & rtBorder,const CFX_Matrix & matrix,bool forceRound)362 void CXFA_FFWidget::DrawBorderWithFlag(CXFA_Graphics* pGS,
363 CXFA_Box* box,
364 const CFX_RectF& rtBorder,
365 const CFX_Matrix& matrix,
366 bool forceRound) {
367 if (box)
368 box->Draw(pGS, rtBorder, matrix, forceRound);
369 }
370
InvalidateRect()371 void CXFA_FFWidget::InvalidateRect() {
372 CFX_RectF rtWidget = GetBBox(kDoNotDrawFocus);
373 rtWidget.Inflate(2, 2);
374 m_pDocView->InvalidateRect(m_pPageView.Get(), rtWidget);
375 }
376
OnMouseEnter()377 bool CXFA_FFWidget::OnMouseEnter() {
378 return false;
379 }
380
OnMouseExit()381 bool CXFA_FFWidget::OnMouseExit() {
382 return false;
383 }
384
AcceptsFocusOnButtonDown(uint32_t dwFlags,const CFX_PointF & point,FWL_MouseCommand command)385 bool CXFA_FFWidget::AcceptsFocusOnButtonDown(uint32_t dwFlags,
386 const CFX_PointF& point,
387 FWL_MouseCommand command) {
388 return false;
389 }
390
OnLButtonDown(uint32_t dwFlags,const CFX_PointF & point)391 bool CXFA_FFWidget::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
392 return false;
393 }
394
OnLButtonUp(uint32_t dwFlags,const CFX_PointF & point)395 bool CXFA_FFWidget::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
396 return false;
397 }
398
OnLButtonDblClk(uint32_t dwFlags,const CFX_PointF & point)399 bool CXFA_FFWidget::OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
400 return false;
401 }
402
OnMouseMove(uint32_t dwFlags,const CFX_PointF & point)403 bool CXFA_FFWidget::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
404 return false;
405 }
406
OnMouseWheel(uint32_t dwFlags,int16_t zDelta,const CFX_PointF & point)407 bool CXFA_FFWidget::OnMouseWheel(uint32_t dwFlags,
408 int16_t zDelta,
409 const CFX_PointF& point) {
410 return false;
411 }
412
OnRButtonDown(uint32_t dwFlags,const CFX_PointF & point)413 bool CXFA_FFWidget::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
414 return false;
415 }
416
OnRButtonUp(uint32_t dwFlags,const CFX_PointF & point)417 bool CXFA_FFWidget::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
418 return false;
419 }
420
OnRButtonDblClk(uint32_t dwFlags,const CFX_PointF & point)421 bool CXFA_FFWidget::OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) {
422 return false;
423 }
424
OnSetFocus(CXFA_FFWidget * pOldWidget)425 bool CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
426 // OnSetFocus event may remove this widget.
427 ObservedPtr<CXFA_FFWidget> pWatched(this);
428 CXFA_FFWidget* pParent = GetFFWidget(ToContentLayoutItem(GetParent()));
429 if (pParent && !pParent->IsAncestorOf(pOldWidget)) {
430 if (!pParent->OnSetFocus(pOldWidget))
431 return false;
432 }
433 if (!pWatched)
434 return false;
435
436 GetLayoutItem()->SetStatusBits(XFA_WidgetStatus_Focused);
437
438 CXFA_EventParam eParam;
439 eParam.m_eType = XFA_EVENT_Enter;
440 eParam.m_pTarget = m_pNode.Get();
441 m_pNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Enter, &eParam);
442
443 return !!pWatched;
444 }
445
OnKillFocus(CXFA_FFWidget * pNewWidget)446 bool CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
447 // OnKillFocus event may remove these widgets.
448 ObservedPtr<CXFA_FFWidget> pWatched(this);
449 ObservedPtr<CXFA_FFWidget> pNewWatched(pNewWidget);
450 GetLayoutItem()->ClearStatusBits(XFA_WidgetStatus_Focused);
451 EventKillFocus();
452 if (!pWatched)
453 return false;
454
455 if (!pNewWidget)
456 return true;
457
458 if (!pNewWatched)
459 return false;
460
461 // OnKillFocus event may remove |pNewWidget|.
462 CXFA_FFWidget* pParent = GetFFWidget(ToContentLayoutItem(GetParent()));
463 if (pParent && !pParent->IsAncestorOf(pNewWidget)) {
464 if (!pParent->OnKillFocus(pNewWidget))
465 return false;
466 }
467 return pWatched && pNewWatched;
468 }
469
OnKeyDown(uint32_t dwKeyCode,uint32_t dwFlags)470 bool CXFA_FFWidget::OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) {
471 return false;
472 }
473
OnKeyUp(uint32_t dwKeyCode,uint32_t dwFlags)474 bool CXFA_FFWidget::OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) {
475 return false;
476 }
477
OnChar(uint32_t dwChar,uint32_t dwFlags)478 bool CXFA_FFWidget::OnChar(uint32_t dwChar, uint32_t dwFlags) {
479 return false;
480 }
481
HitTest(const CFX_PointF & point)482 FWL_WidgetHit CXFA_FFWidget::HitTest(const CFX_PointF& point) {
483 return FWL_WidgetHit::Unknown;
484 }
485
OnSetCursor(const CFX_PointF & point)486 bool CXFA_FFWidget::OnSetCursor(const CFX_PointF& point) {
487 return false;
488 }
489
CanUndo()490 bool CXFA_FFWidget::CanUndo() {
491 return false;
492 }
493
CanRedo()494 bool CXFA_FFWidget::CanRedo() {
495 return false;
496 }
497
Undo()498 bool CXFA_FFWidget::Undo() {
499 return false;
500 }
501
Redo()502 bool CXFA_FFWidget::Redo() {
503 return false;
504 }
505
CanCopy()506 bool CXFA_FFWidget::CanCopy() {
507 return false;
508 }
509
CanCut()510 bool CXFA_FFWidget::CanCut() {
511 return false;
512 }
513
CanPaste()514 bool CXFA_FFWidget::CanPaste() {
515 return false;
516 }
517
CanSelectAll()518 bool CXFA_FFWidget::CanSelectAll() {
519 return false;
520 }
521
CanDelete()522 bool CXFA_FFWidget::CanDelete() {
523 return CanCut();
524 }
525
CanDeSelect()526 bool CXFA_FFWidget::CanDeSelect() {
527 return CanCopy();
528 }
529
Copy()530 Optional<WideString> CXFA_FFWidget::Copy() {
531 return {};
532 }
533
Cut()534 Optional<WideString> CXFA_FFWidget::Cut() {
535 return {};
536 }
537
Paste(const WideString & wsPaste)538 bool CXFA_FFWidget::Paste(const WideString& wsPaste) {
539 return false;
540 }
541
SelectAll()542 void CXFA_FFWidget::SelectAll() {}
543
Delete()544 void CXFA_FFWidget::Delete() {}
545
DeSelect()546 void CXFA_FFWidget::DeSelect() {}
547
GetText()548 WideString CXFA_FFWidget::GetText() {
549 return WideString();
550 }
551
GetFormFieldType()552 FormFieldType CXFA_FFWidget::GetFormFieldType() {
553 return FormFieldType::kXFA;
554 }
555
Rotate2Normal(const CFX_PointF & point)556 CFX_PointF CXFA_FFWidget::Rotate2Normal(const CFX_PointF& point) {
557 CFX_Matrix mt = GetRotateMatrix();
558 if (mt.IsIdentity())
559 return point;
560
561 return mt.GetInverse().Transform(point);
562 }
563
GetRotateMatrix()564 CFX_Matrix CXFA_FFWidget::GetRotateMatrix() {
565 int32_t iRotate = m_pNode->GetRotate();
566 if (!iRotate)
567 return CFX_Matrix();
568
569 CFX_RectF rcWidget = GetRectWithoutRotate();
570 CFX_Matrix mt;
571 switch (iRotate) {
572 case 90:
573 mt.a = 0;
574 mt.b = -1;
575 mt.c = 1;
576 mt.d = 0;
577 mt.e = rcWidget.left - rcWidget.top;
578 mt.f = rcWidget.left + rcWidget.top;
579 break;
580 case 180:
581 mt.a = -1;
582 mt.b = 0;
583 mt.c = 0;
584 mt.d = -1;
585 mt.e = rcWidget.left * 2;
586 mt.f = rcWidget.top * 2;
587 break;
588 case 270:
589 mt.a = 0;
590 mt.b = 1;
591 mt.c = -1;
592 mt.d = 0;
593 mt.e = rcWidget.left + rcWidget.top;
594 mt.f = rcWidget.top - rcWidget.left;
595 break;
596 }
597 return mt;
598 }
599
DisplayCaret(bool bVisible,const CFX_RectF * pRtAnchor)600 void CXFA_FFWidget::DisplayCaret(bool bVisible, const CFX_RectF* pRtAnchor) {
601 IXFA_DocEnvironment* pDocEnvironment = GetDoc()->GetDocEnvironment();
602 if (!pDocEnvironment)
603 return;
604
605 pDocEnvironment->DisplayCaret(this, bVisible, pRtAnchor);
606 }
607
GetBorderColorAndThickness(FX_ARGB * cr,float * fWidth)608 void CXFA_FFWidget::GetBorderColorAndThickness(FX_ARGB* cr, float* fWidth) {
609 ASSERT(GetNode()->IsWidgetReady());
610 CXFA_Border* borderUI = GetNode()->GetUIBorder();
611 if (!borderUI)
612 return;
613
614 CXFA_Edge* edge = borderUI->GetEdgeIfExists(0);
615 if (!edge)
616 return;
617
618 *cr = edge->GetColor();
619 *fWidth = edge->GetThickness();
620 }
621
IsLayoutRectEmpty()622 bool CXFA_FFWidget::IsLayoutRectEmpty() {
623 CFX_RectF rtLayout = GetRectWithoutRotate();
624 return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
625 }
626
GetParent()627 CXFA_LayoutItem* CXFA_FFWidget::GetParent() {
628 CXFA_Node* pParentNode = m_pNode->GetParent();
629 if (!pParentNode)
630 return nullptr;
631
632 CXFA_LayoutProcessor* layout = GetDocView()->GetXFALayout();
633 return layout->GetLayoutItem(pParentNode);
634 }
635
IsAncestorOf(CXFA_FFWidget * pWidget)636 bool CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
637 if (!pWidget)
638 return false;
639
640 CXFA_Node* pChildNode = pWidget->GetNode();
641 while (pChildNode) {
642 if (pChildNode == m_pNode)
643 return true;
644
645 pChildNode = pChildNode->GetParent();
646 }
647 return false;
648 }
649
PtInActiveRect(const CFX_PointF & point)650 bool CXFA_FFWidget::PtInActiveRect(const CFX_PointF& point) {
651 return GetWidgetRect().Contains(point);
652 }
653
GetDoc()654 CXFA_FFDoc* CXFA_FFWidget::GetDoc() {
655 return m_pDocView->GetDoc();
656 }
657
GetApp()658 CXFA_FFApp* CXFA_FFWidget::GetApp() {
659 return GetDoc()->GetApp();
660 }
661
GetAppProvider()662 IXFA_AppProvider* CXFA_FFWidget::GetAppProvider() {
663 return GetApp()->GetAppProvider();
664 }
665
HasVisibleStatus() const666 bool CXFA_FFWidget::HasVisibleStatus() const {
667 return GetLayoutItem()->TestStatusBits(XFA_WidgetStatus_Visible);
668 }
669
EventKillFocus()670 void CXFA_FFWidget::EventKillFocus() {
671 CXFA_ContentLayoutItem* pItem = GetLayoutItem();
672 if (pItem->TestStatusBits(XFA_WidgetStatus_Access)) {
673 pItem->ClearStatusBits(XFA_WidgetStatus_Access);
674 return;
675 }
676 CXFA_EventParam eParam;
677 eParam.m_eType = XFA_EVENT_Exit;
678 eParam.m_pTarget = m_pNode.Get();
679 m_pNode->ProcessEvent(GetDocView(), XFA_AttributeValue::Exit, &eParam);
680 }
681
IsButtonDown()682 bool CXFA_FFWidget::IsButtonDown() {
683 return GetLayoutItem()->TestStatusBits(XFA_WidgetStatus_ButtonDown);
684 }
685
SetButtonDown(bool bSet)686 void CXFA_FFWidget::SetButtonDown(bool bSet) {
687 CXFA_ContentLayoutItem* pItem = GetLayoutItem();
688 if (bSet)
689 pItem->SetStatusBits(XFA_WidgetStatus_ButtonDown);
690 else
691 pItem->ClearStatusBits(XFA_WidgetStatus_ButtonDown);
692 }
693