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_ffimageedit.h"
8
9 #include <utility>
10
11 #include "core/fxge/dib/cfx_dibitmap.h"
12 #include "third_party/base/check.h"
13 #include "v8/include/cppgc/visitor.h"
14 #include "xfa/fwl/cfwl_app.h"
15 #include "xfa/fwl/cfwl_messagemouse.h"
16 #include "xfa/fwl/cfwl_notedriver.h"
17 #include "xfa/fwl/cfwl_picturebox.h"
18 #include "xfa/fxfa/cxfa_ffdoc.h"
19 #include "xfa/fxfa/cxfa_ffdocview.h"
20 #include "xfa/fxfa/cxfa_fffield.h"
21 #include "xfa/fxfa/cxfa_ffpageview.h"
22 #include "xfa/fxfa/cxfa_ffwidget.h"
23 #include "xfa/fxfa/parser/cxfa_border.h"
24 #include "xfa/fxfa/parser/cxfa_image.h"
25 #include "xfa/fxfa/parser/cxfa_para.h"
26 #include "xfa/fxfa/parser/cxfa_value.h"
27
CXFA_FFImageEdit(CXFA_Node * pNode)28 CXFA_FFImageEdit::CXFA_FFImageEdit(CXFA_Node* pNode) : CXFA_FFField(pNode) {}
29
30 CXFA_FFImageEdit::~CXFA_FFImageEdit() = default;
31
PreFinalize()32 void CXFA_FFImageEdit::PreFinalize() {
33 m_pNode->SetEditImage(nullptr);
34 }
35
Trace(cppgc::Visitor * visitor) const36 void CXFA_FFImageEdit::Trace(cppgc::Visitor* visitor) const {
37 CXFA_FFField::Trace(visitor);
38 visitor->Trace(m_pOldDelegate);
39 }
40
LoadWidget()41 bool CXFA_FFImageEdit::LoadWidget() {
42 DCHECK(!IsLoaded());
43
44 CFWL_PictureBox* pPictureBox = cppgc::MakeGarbageCollected<CFWL_PictureBox>(
45 GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
46 SetNormalWidget(pPictureBox);
47 pPictureBox->SetAdapterIface(this);
48
49 CFWL_NoteDriver* pNoteDriver = pPictureBox->GetFWLApp()->GetNoteDriver();
50 pNoteDriver->RegisterEventTarget(pPictureBox, pPictureBox);
51 m_pOldDelegate = pPictureBox->GetDelegate();
52 pPictureBox->SetDelegate(this);
53
54 CXFA_FFField::LoadWidget();
55 if (!m_pNode->GetEditImage())
56 UpdateFWLData();
57
58 return true;
59 }
60
RenderWidget(CFGAS_GEGraphics * pGS,const CFX_Matrix & matrix,HighlightOption highlight)61 void CXFA_FFImageEdit::RenderWidget(CFGAS_GEGraphics* pGS,
62 const CFX_Matrix& matrix,
63 HighlightOption highlight) {
64 if (!HasVisibleStatus())
65 return;
66
67 CFX_Matrix mtRotate = GetRotateMatrix();
68 mtRotate.Concat(matrix);
69
70 CXFA_FFWidget::RenderWidget(pGS, mtRotate, highlight);
71 DrawBorder(pGS, m_pNode->GetUIBorder(), m_UIRect, mtRotate);
72 RenderCaption(pGS, mtRotate);
73 RetainPtr<CFX_DIBitmap> pDIBitmap = m_pNode->GetEditImage();
74 if (!pDIBitmap)
75 return;
76
77 CFX_RectF rtImage = GetNormalWidget()->GetWidgetRect();
78 XFA_AttributeValue iHorzAlign = XFA_AttributeValue::Left;
79 XFA_AttributeValue iVertAlign = XFA_AttributeValue::Top;
80 CXFA_Para* para = m_pNode->GetParaIfExists();
81 if (para) {
82 iHorzAlign = para->GetHorizontalAlign();
83 iVertAlign = para->GetVerticalAlign();
84 }
85
86 XFA_AttributeValue iAspect = XFA_AttributeValue::Fit;
87 CXFA_Value* value = m_pNode->GetFormValueIfExists();
88 if (value) {
89 CXFA_Image* image = value->GetImageIfExists();
90 if (image)
91 iAspect = image->GetAspect();
92 }
93
94 XFA_DrawImage(pGS, rtImage, mtRotate, std::move(pDIBitmap), iAspect,
95 m_pNode->GetEditImageDpi(), iHorzAlign, iVertAlign);
96 }
97
AcceptsFocusOnButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point,CFWL_MessageMouse::MouseCommand command)98 bool CXFA_FFImageEdit::AcceptsFocusOnButtonDown(
99 Mask<XFA_FWL_KeyFlag> dwFlags,
100 const CFX_PointF& point,
101 CFWL_MessageMouse::MouseCommand command) {
102 if (command != CFWL_MessageMouse::MouseCommand::kLeftButtonDown)
103 return CXFA_FFField::AcceptsFocusOnButtonDown(dwFlags, point, command);
104
105 if (!m_pNode->IsOpenAccess())
106 return false;
107 if (!PtInActiveRect(point))
108 return false;
109
110 return true;
111 }
112
OnLButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,const CFX_PointF & point)113 bool CXFA_FFImageEdit::OnLButtonDown(Mask<XFA_FWL_KeyFlag> dwFlags,
114 const CFX_PointF& point) {
115 SetButtonDown(true);
116 CFWL_MessageMouse msg(GetNormalWidget(),
117 CFWL_MessageMouse::MouseCommand::kLeftButtonDown,
118 dwFlags, FWLToClient(point));
119 SendMessageToFWLWidget(&msg);
120 return true;
121 }
122
SetFWLRect()123 void CXFA_FFImageEdit::SetFWLRect() {
124 if (!GetNormalWidget())
125 return;
126
127 CFX_RectF rtUIMargin = m_pNode->GetUIMargin();
128 CFX_RectF rtImage(m_UIRect);
129 rtImage.Deflate(rtUIMargin.left, rtUIMargin.top, rtUIMargin.width,
130 rtUIMargin.height);
131 GetNormalWidget()->SetWidgetRect(rtImage);
132 }
133
CommitData()134 bool CXFA_FFImageEdit::CommitData() {
135 return true;
136 }
137
UpdateFWLData()138 bool CXFA_FFImageEdit::UpdateFWLData() {
139 m_pNode->SetEditImage(nullptr);
140 m_pNode->LoadEditImage(GetDoc());
141 return true;
142 }
143
OnProcessMessage(CFWL_Message * pMessage)144 void CXFA_FFImageEdit::OnProcessMessage(CFWL_Message* pMessage) {
145 m_pOldDelegate->OnProcessMessage(pMessage);
146 }
147
OnProcessEvent(CFWL_Event * pEvent)148 void CXFA_FFImageEdit::OnProcessEvent(CFWL_Event* pEvent) {
149 CXFA_FFField::OnProcessEvent(pEvent);
150 m_pOldDelegate->OnProcessEvent(pEvent);
151 }
152
OnDrawWidget(CFGAS_GEGraphics * pGraphics,const CFX_Matrix & matrix)153 void CXFA_FFImageEdit::OnDrawWidget(CFGAS_GEGraphics* pGraphics,
154 const CFX_Matrix& matrix) {
155 m_pOldDelegate->OnDrawWidget(pGraphics, matrix);
156 }
157
GetFormFieldType()158 FormFieldType CXFA_FFImageEdit::GetFormFieldType() {
159 return FormFieldType::kXFA_ImageField;
160 }
161