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