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/src/foxitlib.h"
8#include "xfa/src/fxfa/src/common/xfa_common.h"
9#include "xfa_ffwidget.h"
10#include "xfa_fffield.h"
11#include "xfa_ffpageview.h"
12#include "xfa_ffimageedit.h"
13#include "xfa_ffdocview.h"
14#include "xfa_ffdoc.h"
15CXFA_FFImageEdit::CXFA_FFImageEdit(CXFA_FFPageView* pPageView,
16                                   CXFA_WidgetAcc* pDataAcc)
17    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(NULL) {}
18CXFA_FFImageEdit::~CXFA_FFImageEdit() {
19  CXFA_FFImageEdit::UnloadWidget();
20}
21FX_BOOL CXFA_FFImageEdit::LoadWidget() {
22  CFWL_PictureBox* pPictureBox = new CFWL_PictureBox;
23  if (pPictureBox) {
24    pPictureBox->Initialize();
25  }
26  m_pNormalWidget = (CFWL_Widget*)pPictureBox;
27  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
28  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
29  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
30  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
31  m_pOldDelegate = pPictureBox->SetDelegate(this);
32  CXFA_FFField::LoadWidget();
33  if (m_pDataAcc->GetImageEditImage() != NULL) {
34    return TRUE;
35  }
36  UpdateFWLData();
37  return TRUE;
38}
39void CXFA_FFImageEdit::UnloadWidget() {
40  m_pDataAcc->SetImageEditImage(NULL);
41  CXFA_FFField::UnloadWidget();
42}
43void CXFA_FFImageEdit::RenderWidget(CFX_Graphics* pGS,
44                                    CFX_Matrix* pMatrix,
45                                    FX_DWORD dwStatus,
46                                    int32_t iRotate) {
47  if (!IsMatchVisibleStatus(dwStatus)) {
48    return;
49  }
50  CFX_Matrix mtRotate;
51  GetRotateMatrix(mtRotate);
52  if (pMatrix) {
53    mtRotate.Concat(*pMatrix);
54  }
55  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
56  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
57  DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
58  RenderCaption(pGS, &mtRotate);
59  if (CFX_DIBitmap* pDIBitmap = m_pDataAcc->GetImageEditImage()) {
60    CFX_RectF rtImage;
61    m_pNormalWidget->GetWidgetRect(rtImage);
62    int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left;
63    int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top;
64    if (CXFA_Para para = m_pDataAcc->GetPara()) {
65      iHorzAlign = para.GetHorizontalAlign();
66      iVertAlign = para.GetVerticalAlign();
67    }
68    int32_t iAspect = XFA_ATTRIBUTEENUM_Fit;
69    if (CXFA_Value value = m_pDataAcc->GetFormValue()) {
70      if (CXFA_Image imageObj = value.GetImage()) {
71        iAspect = imageObj.GetAspect();
72      }
73    }
74    int32_t iImageXDpi = 0;
75    int32_t iImageYDpi = 0;
76    m_pDataAcc->GetImageEditDpi(iImageXDpi, iImageYDpi);
77    XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi,
78                  iImageYDpi, iHorzAlign, iVertAlign);
79  }
80}
81FX_BOOL CXFA_FFImageEdit::OnLButtonDown(FX_DWORD dwFlags,
82                                        FX_FLOAT fx,
83                                        FX_FLOAT fy) {
84  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
85    return FALSE;
86  }
87  if (!PtInActiveRect(fx, fy)) {
88    return FALSE;
89  }
90  SetButtonDown(TRUE);
91  CFWL_MsgMouse ms;
92  ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDown;
93  ms.m_dwFlags = dwFlags;
94  ms.m_fx = fx;
95  ms.m_fy = fy;
96  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
97  FWLToClient(ms.m_fx, ms.m_fy);
98  TranslateFWLMessage(&ms);
99  IXFA_AppProvider* pAppProvider = GetAppProvider();
100  if (!pAppProvider) {
101    return TRUE;
102  }
103  CFX_WideString wsTitle;
104  CFX_WideString wsFilter;
105  pAppProvider->LoadString(XFA_IDS_ImageFilter, wsFilter);
106  CFX_WideStringArray wsPathArray;
107  pAppProvider->ShowFileDialog(wsTitle, wsFilter, wsPathArray);
108  int32_t iSize = wsPathArray.GetSize();
109  if (iSize < 1) {
110    return TRUE;
111  }
112  CFX_WideString wsFilePath = wsPathArray[0];
113  FX_STRSIZE nLen = wsFilePath.GetLength();
114  FX_STRSIZE nIndex = nLen - 1;
115  while (nIndex > 0 && wsFilePath[nIndex] != '.') {
116    nIndex--;
117  }
118  if (nIndex <= 0) {
119    return TRUE;
120  }
121  CFX_WideString wsContentType(L"image/");
122  wsContentType += wsFilePath.Right(nLen - nIndex - 1);
123  wsContentType.MakeLower();
124  FXCODEC_IMAGE_TYPE eImageType = XFA_GetImageType(wsContentType);
125  if (eImageType == FXCODEC_IMAGE_UNKNOWN) {
126    return TRUE;
127  }
128  CFX_WideString wsImage;
129  IFX_FileRead* pFileRead = FX_CreateFileRead(wsFilePath);
130  if (pFileRead != NULL) {
131    int32_t nDataSize = pFileRead->GetSize();
132    if (nDataSize > 0) {
133      CFX_ByteString bsBuf;
134      FX_CHAR* pImageBuffer = bsBuf.GetBuffer(nDataSize);
135      pFileRead->ReadBlock(pImageBuffer, 0, nDataSize);
136      bsBuf.ReleaseBuffer();
137      if (!bsBuf.IsEmpty()) {
138        FX_CHAR* pData = XFA_Base64Encode(bsBuf, nDataSize);
139        wsImage = CFX_WideString::FromLocal(pData);
140        if (pData != NULL) {
141          FX_Free(pData);
142        }
143      }
144    }
145    m_pDataAcc->SetImageEditImage(NULL);
146    pFileRead->Release();
147  }
148  m_pDataAcc->SetImageEdit(wsContentType, CFX_WideStringC(), wsImage);
149  m_pDataAcc->LoadImageEditImage();
150  AddInvalidateRect();
151  m_pDocView->SetChangeMark();
152  return TRUE;
153}
154void CXFA_FFImageEdit::SetFWLRect() {
155  if (!m_pNormalWidget) {
156    return;
157  }
158  CFX_RectF rtUIMargin;
159  m_pDataAcc->GetUIMargin(rtUIMargin);
160  CFX_RectF rtImage(m_rtUI);
161  rtImage.Deflate(rtUIMargin.left, rtUIMargin.top, rtUIMargin.width,
162                  rtUIMargin.height);
163  m_pNormalWidget->SetWidgetRect(rtImage);
164}
165FX_BOOL CXFA_FFImageEdit::CommitData() {
166  return TRUE;
167}
168FX_BOOL CXFA_FFImageEdit::UpdateFWLData() {
169  m_pDataAcc->SetImageEditImage(NULL);
170  m_pDataAcc->LoadImageEditImage();
171  return TRUE;
172}
173int32_t CXFA_FFImageEdit::OnProcessMessage(CFWL_Message* pMessage) {
174  return m_pOldDelegate->OnProcessMessage(pMessage);
175}
176FWL_ERR CXFA_FFImageEdit::OnProcessEvent(CFWL_Event* pEvent) {
177  CXFA_FFField::OnProcessEvent(pEvent);
178  return m_pOldDelegate->OnProcessEvent(pEvent);
179}
180FWL_ERR CXFA_FFImageEdit::OnDrawWidget(CFX_Graphics* pGraphics,
181                                       const CFX_Matrix* pMatrix) {
182  return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
183}
184