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 #ifndef XFA_FXFA_CXFA_FFWIDGET_H_
8 #define XFA_FXFA_CXFA_FFWIDGET_H_
9
10 #include <stdint.h>
11
12 #include "core/fpdfdoc/cpdf_formfield.h"
13 #include "core/fxcodec/fx_codec_def.h"
14 #include "core/fxcrt/mask.h"
15 #include "core/fxcrt/retain_ptr.h"
16 #include "core/fxge/cfx_graphstatedata.h"
17 #include "fxjs/gc/heap.h"
18 #include "v8/include/cppgc/garbage-collected.h"
19 #include "v8/include/cppgc/visitor.h"
20 #include "xfa/fwl/cfwl_app.h"
21 #include "xfa/fwl/cfwl_messagemouse.h"
22 #include "xfa/fwl/cfwl_widget.h"
23 #include "xfa/fwl/fwl_widgetdef.h"
24 #include "xfa/fxfa/cxfa_eventparam.h"
25 #include "xfa/fxfa/cxfa_ffapp.h"
26 #include "xfa/fxfa/fxfa.h"
27 #include "xfa/fxfa/layout/cxfa_contentlayoutitem.h"
28
29 class CFGAS_GEGraphics;
30 class CFX_DIBitmap;
31 class CXFA_Box;
32 class CXFA_FFApp;
33 class CXFA_FFDoc;
34 class CXFA_FFDocView;
35 class CXFA_FFField;
36 class CXFA_FFPageView;
37 class CXFA_FFWidgetHandler;
38 class CXFA_Margin;
39 class IFX_SeekableReadStream;
40 enum class FWL_WidgetHit;
41
XFA_UnitPx2Pt(float fPx,float fDpi)42 inline float XFA_UnitPx2Pt(float fPx, float fDpi) {
43 return fPx * 72.0f / fDpi;
44 }
45
46 constexpr float kXFAWidgetPrecision = 0.001f;
47
48 void XFA_DrawImage(CFGAS_GEGraphics* pGS,
49 const CFX_RectF& rtImage,
50 const CFX_Matrix& matrix,
51 RetainPtr<CFX_DIBitmap> pDIBitmap,
52 XFA_AttributeValue iAspect,
53 const CFX_Size& dpi,
54 XFA_AttributeValue iHorzAlign = XFA_AttributeValue::Left,
55 XFA_AttributeValue iVertAlign = XFA_AttributeValue::Top);
56
57 RetainPtr<CFX_DIBitmap> XFA_LoadImageFromBuffer(
58 RetainPtr<IFX_SeekableReadStream> pImageFileRead,
59 FXCODEC_IMAGE_TYPE type,
60 int32_t& iImageXDpi,
61 int32_t& iImageYDpi);
62
63 void XFA_RectWithoutMargin(CFX_RectF* rt, const CXFA_Margin* margin);
64
65 class CXFA_FFWidget : public cppgc::GarbageCollected<CXFA_FFWidget>,
66 public CFWL_Widget::AdapterIface {
67 public:
68 enum FocusOption { kDoNotDrawFocus = 0, kDrawFocus };
69 enum HighlightOption { kNoHighlight = 0, kHighlight };
70
71 class IteratorIface {
72 public:
73 virtual ~IteratorIface() = default;
74
75 virtual CXFA_FFWidget* MoveToFirst() = 0;
76 virtual CXFA_FFWidget* MoveToLast() = 0;
77 virtual CXFA_FFWidget* MoveToNext() = 0;
78 virtual CXFA_FFWidget* MoveToPrevious() = 0;
79 virtual CXFA_FFWidget* GetCurrentWidget() = 0;
80 virtual bool SetCurrentWidget(CXFA_FFWidget* hWidget) = 0;
81 };
82
83 static CXFA_FFWidget* FromLayoutItem(CXFA_LayoutItem* pLayoutItem);
84
85 CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
86 ~CXFA_FFWidget() override;
87
88 void Trace(cppgc::Visitor* visitor) const override;
89
90 // CFWL_Widget::AdapterIface:
91 CFX_Matrix GetRotateMatrix() override;
92 void DisplayCaret(bool bVisible, const CFX_RectF* pRtAnchor) override;
93 void GetBorderColorAndThickness(FX_ARGB* cr, float* fWidth) override;
94
95 virtual CXFA_FFField* AsField();
96 virtual CFX_RectF GetBBox(FocusOption focus);
97 virtual void RenderWidget(CFGAS_GEGraphics* pGS,
98 const CFX_Matrix& matrix,
99 HighlightOption highlight);
100 virtual bool IsLoaded();
101 virtual bool LoadWidget();
102 virtual bool PerformLayout();
103 virtual bool UpdateFWLData();
104 virtual void UpdateWidgetProperty();
105 // |command| must be LeftButtonDown or RightButtonDown.
106 virtual bool AcceptsFocusOnButtonDown(
107 Mask<XFA_FWL_KeyFlag> dwFlags,
108 const CFX_PointF& point,
109 CFWL_MessageMouse::MouseCommand command);
110
111 // Caution: Returning false from an On* method may mean |this| is destroyed.
112 [[nodiscard]] virtual bool OnMouseEnter();
113 [[nodiscard]] virtual bool OnMouseExit();
114 [[nodiscard]] virtual bool OnLButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,
115 const CFX_PointF& point);
116 [[nodiscard]] virtual bool OnLButtonUp(Mask<XFA_FWL_KeyFlag> dwFlags,
117 const CFX_PointF& point);
118 [[nodiscard]] virtual bool OnLButtonDblClk(Mask<XFA_FWL_KeyFlag> dwFlags,
119 const CFX_PointF& point);
120 [[nodiscard]] virtual bool OnMouseMove(Mask<XFA_FWL_KeyFlag> dwFlags,
121 const CFX_PointF& point);
122 [[nodiscard]] virtual bool OnMouseWheel(Mask<XFA_FWL_KeyFlag> dwFlags,
123 const CFX_PointF& point,
124 const CFX_Vector& delta);
125 [[nodiscard]] virtual bool OnRButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,
126 const CFX_PointF& point);
127 [[nodiscard]] virtual bool OnRButtonUp(Mask<XFA_FWL_KeyFlag> dwFlags,
128 const CFX_PointF& point);
129 [[nodiscard]] virtual bool OnRButtonDblClk(Mask<XFA_FWL_KeyFlag> dwFlags,
130 const CFX_PointF& point);
131 [[nodiscard]] virtual bool OnSetFocus(CXFA_FFWidget* pOldWidget);
132 [[nodiscard]] virtual bool OnKillFocus(CXFA_FFWidget* pNewWidget);
133 [[nodiscard]] virtual bool OnKeyDown(XFA_FWL_VKEYCODE dwKeyCode,
134 Mask<XFA_FWL_KeyFlag> dwFlags);
135 [[nodiscard]] virtual bool OnChar(uint32_t dwChar,
136 Mask<XFA_FWL_KeyFlag> dwFlags);
137
138 virtual FWL_WidgetHit HitTest(const CFX_PointF& point);
139 virtual bool CanUndo();
140 virtual bool CanRedo();
141 virtual bool CanCopy();
142 virtual bool CanCut();
143 virtual bool CanPaste();
144 virtual bool CanSelectAll();
145 virtual bool CanDelete();
146 virtual bool CanDeSelect();
147 virtual bool Undo();
148 virtual bool Redo();
149 virtual absl::optional<WideString> Copy();
150 virtual absl::optional<WideString> Cut();
151 virtual bool Paste(const WideString& wsPaste);
152 virtual void SelectAll();
153 virtual void Delete();
154 virtual void DeSelect();
155 virtual WideString GetText();
156 virtual FormFieldType GetFormFieldType();
157
GetNode()158 CXFA_Node* GetNode() const { return m_pNode; }
GetLayoutItem()159 CXFA_ContentLayoutItem* GetLayoutItem() const { return m_pLayoutItem; }
SetLayoutItem(CXFA_ContentLayoutItem * pItem)160 void SetLayoutItem(CXFA_ContentLayoutItem* pItem) { m_pLayoutItem = pItem; }
GetPageView()161 CXFA_FFPageView* GetPageView() const { return m_pPageView; }
SetPageView(CXFA_FFPageView * pPageView)162 void SetPageView(CXFA_FFPageView* pPageView) { m_pPageView = pPageView; }
GetDocView()163 CXFA_FFDocView* GetDocView() const { return m_pDocView; }
SetDocView(CXFA_FFDocView * pDocView)164 void SetDocView(CXFA_FFDocView* pDocView) { m_pDocView = pDocView; }
165
166 CXFA_FFWidget* GetNextFFWidget() const;
167 const CFX_RectF& GetWidgetRect() const;
168 const CFX_RectF& RecacheWidgetRect() const;
169 void ModifyStatus(Mask<XFA_WidgetStatus> dwAdded,
170 Mask<XFA_WidgetStatus> dwRemoved);
171
172 CXFA_FFDoc* GetDoc();
173 CXFA_FFApp* GetApp();
174 CXFA_FFApp::CallbackIface* GetAppProvider();
175 CFWL_App* GetFWLApp() const;
176 void InvalidateRect();
IsFocused()177 bool IsFocused() const {
178 return GetLayoutItem()->TestStatusBits(XFA_WidgetStatus::kFocused);
179 }
180 CFX_PointF Rotate2Normal(const CFX_PointF& point);
181 bool IsLayoutRectEmpty();
182 CXFA_LayoutItem* GetParent();
183 bool IsAncestorOf(CXFA_FFWidget* pWidget);
184 bool HasEventUnderHandler(XFA_EVENTTYPE eEventType,
185 CXFA_FFWidgetHandler* pHandler);
186 bool ProcessEventUnderHandler(CXFA_EventParam* params,
187 CXFA_FFWidgetHandler* pHandler);
188
189 protected:
190 explicit CXFA_FFWidget(CXFA_Node* pNode);
191 virtual bool PtInActiveRect(const CFX_PointF& point);
192
193 void DrawBorder(CFGAS_GEGraphics* pGS,
194 CXFA_Box* box,
195 const CFX_RectF& rtBorder,
196 const CFX_Matrix& matrix);
197 void DrawBorderWithFlag(CFGAS_GEGraphics* pGS,
198 CXFA_Box* box,
199 const CFX_RectF& rtBorder,
200 const CFX_Matrix& matrix,
201 bool forceRound);
202
203 CFX_RectF GetRectWithoutRotate();
204 bool HasVisibleStatus() const;
205 void EventKillFocus();
206 bool IsButtonDown();
207 void SetButtonDown(bool bSet);
208
209 cppgc::Member<CXFA_ContentLayoutItem> m_pLayoutItem;
210 cppgc::Member<CXFA_FFDocView> m_pDocView;
211 cppgc::Member<CXFA_FFPageView> m_pPageView;
212 cppgc::Member<CXFA_Node> const m_pNode;
213 mutable CFX_RectF m_WidgetRect;
214 };
215
ToField(CXFA_FFWidget * widget)216 inline CXFA_FFField* ToField(CXFA_FFWidget* widget) {
217 return widget ? widget->AsField() : nullptr;
218 }
219
220 #endif // XFA_FXFA_CXFA_FFWIDGET_H_
221