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