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 "../../public/fpdf_formfill.h" 8 #include "../../public/fpdfview.h" 9 #include "../include/fsdk_define.h" 10 #include "../include/fsdk_mgr.h" 11 12 13 #include "../include/javascript/IJavaScript.h" 14 15 16 DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, FPDF_PAGE page,double page_x, double page_y) 17 { 18 if(!page || !hHandle) 19 return -1; 20 CPDF_Page * pPage = (CPDF_Page*) page; 21 22 CPDF_InterForm * pInterForm = NULL; 23 pInterForm = new CPDF_InterForm(pPage->m_pDocument,FALSE); 24 if (!pInterForm) 25 return -1; 26 CPDF_FormControl* pFormCtrl = pInterForm->GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y); 27 if(!pFormCtrl) 28 { 29 delete pInterForm; 30 return -1; 31 } 32 CPDF_FormField* pFormField = pFormCtrl->GetField(); 33 if(!pFormField) 34 { 35 delete pInterForm; 36 return -1; 37 } 38 39 int nType = pFormField->GetFieldType(); 40 delete pInterForm; 41 return nType; 42 } 43 44 DLLEXPORT FPDF_FORMHANDLE STDCALL FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document, FPDF_FORMFILLINFO* formInfo) 45 { 46 if(!document || !formInfo || formInfo->version!=1) 47 return NULL; 48 CPDF_Document * pDocument = (CPDF_Document*) document; 49 CPDFDoc_Environment * pEnv = NULL; 50 pEnv = new CPDFDoc_Environment(pDocument); 51 if (!pEnv) 52 return NULL; 53 pEnv->RegAppHandle(formInfo); 54 55 if(pEnv->GetPDFDocument()) 56 { 57 CPDFSDK_Document* pSDKDoc = new CPDFSDK_Document(pEnv->GetPDFDocument(), pEnv); 58 if(pSDKDoc) 59 pEnv->SetCurrentDoc(pSDKDoc); 60 } 61 return pEnv; 62 } 63 64 DLLEXPORT void STDCALL FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) 65 { 66 if(!hHandle) 67 return; 68 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 69 if(pSDKDoc) 70 { 71 ((CPDFDoc_Environment*)hHandle)->SetCurrentDoc(NULL); 72 delete pSDKDoc; 73 } 74 delete (CPDFDoc_Environment*)hHandle; 75 hHandle = NULL; 76 } 77 78 DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y) 79 { 80 if (!hHandle || !page) 81 return FALSE; 82 // CPDF_Page * pPage = (CPDF_Page*) page; 83 // CPDF_Document * pDoc = pPage->m_pDocument; 84 // CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle; 85 CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 86 if(!pFXDoc) 87 return FALSE; 88 CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page); 89 if(!pPageView) 90 return FALSE; 91 92 // double page_x = 0; 93 // double page_y = 0; 94 // pEnv->FFI_DeviceToPage(page, point_x, point_y, &page_x, &page_y); 95 CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); 96 return pPageView->OnMouseMove(pt, modifier); 97 } 98 99 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y) 100 { 101 if (!hHandle || !page) 102 return FALSE; 103 CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 104 if(!pFXDoc) 105 return FALSE; 106 CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page); 107 if(!pPageView) 108 return FALSE; 109 // double page_x = 0; 110 // double page_y = 0; 111 // pEnv->FFI_DeviceToPage(page, point_x, point_y, &page_x, &page_y); 112 CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); 113 return pPageView->OnLButtonDown(pt, modifier); 114 } 115 116 DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y) 117 { 118 if (!hHandle || !page) 119 return FALSE; 120 CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 121 if(!pFXDoc) 122 return FALSE; 123 CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page); 124 if(!pPageView) 125 return FALSE; 126 // double page_x = 0; 127 // double page_y = 0; 128 // pEnv->FFI_DeviceToPage(page, point_x, point_y, &page_x, &page_y); 129 CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); 130 return pPageView->OnLButtonUp(pt, modifier); 131 } 132 133 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nKeyCode, int modifier) 134 { 135 if (!hHandle || !page) 136 return FALSE; 137 CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 138 if(!pFXDoc) 139 return FALSE; 140 CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page); 141 if(!pPageView) 142 return FALSE; 143 144 145 return pPageView->OnKeyDown(nKeyCode, modifier); 146 } 147 148 DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nKeyCode, int modifier) 149 { 150 if (!hHandle || !page) 151 return FALSE; 152 CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 153 if(!pFXDoc) 154 return FALSE; 155 CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page); 156 if(!pPageView) 157 return FALSE; 158 159 160 return pPageView->OnKeyUp(nKeyCode, modifier); 161 } 162 163 164 DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nChar, int modifier) 165 { 166 if (!hHandle || !page) 167 return FALSE; 168 CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 169 if(!pFXDoc) 170 return FALSE; 171 CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page); 172 if(!pPageView) 173 return FALSE; 174 return pPageView->OnChar(nChar, modifier); 175 176 } 177 178 DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) 179 { 180 if(!hHandle) 181 return FALSE; 182 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 183 if(!pSDKDoc) 184 return FALSE; 185 //Kill the current focus. 186 return pSDKDoc->KillFocusAnnot(0); 187 } 188 189 DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle, FPDF_BITMAP bitmap, FPDF_PAGE page, int start_x, int start_y, 190 int size_x, int size_y, int rotate, int flags) 191 { 192 if (!hHandle || !page) 193 return ; 194 CPDF_Page* pPage = (CPDF_Page*)page; 195 196 CPDF_RenderOptions options; 197 if (flags & FPDF_LCD_TEXT) 198 options.m_Flags |= RENDER_CLEARTYPE; 199 else 200 options.m_Flags &= ~RENDER_CLEARTYPE; 201 202 //Grayscale output 203 if (flags & FPDF_GRAYSCALE) 204 { 205 options.m_ColorMode = RENDER_COLOR_GRAY; 206 options.m_ForeColor = 0; 207 options.m_BackColor = 0xffffff; 208 } 209 210 options.m_AddFlags = flags >> 8; 211 options.m_pOCContext = new CPDF_OCContext(pPage->m_pDocument); 212 213 CFX_AffineMatrix matrix; 214 pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate); 215 216 FX_RECT clip; 217 clip.left = start_x; 218 clip.right = start_x + size_x; 219 clip.top = start_y; 220 clip.bottom = start_y + size_y; 221 222 #ifdef _SKIA_SUPPORT_ 223 CFX_SkiaDevice* pDevice = new CFX_SkiaDevice; 224 #else 225 CFX_FxgeDevice* pDevice = new CFX_FxgeDevice; 226 #endif 227 pDevice->Attach((CFX_DIBitmap*)bitmap); 228 pDevice->SaveState(); 229 pDevice->SetClip_Rect(&clip); 230 231 CPDF_RenderContext* pContext = new CPDF_RenderContext; 232 CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle; 233 CPDFSDK_Document* pFXDoc = pEnv->GetCurrentDoc(); 234 if(!pFXDoc) 235 { 236 delete pContext; 237 delete pDevice; 238 pContext = NULL; 239 pDevice = NULL; 240 return; 241 } 242 if(CPDFSDK_PageView* pPageView = pFXDoc->GetPageView(pPage)) 243 { 244 pPageView->PageView_OnDraw(pDevice, &matrix, &options); 245 } 246 pDevice->RestoreState(); 247 248 if(options.m_pOCContext) 249 { 250 delete options.m_pOCContext; 251 options.m_pOCContext = NULL; 252 } 253 if(pContext) 254 { 255 delete pContext; 256 pContext = NULL; 257 } 258 if(pDevice) 259 { 260 delete pDevice; 261 pDevice = NULL; 262 } 263 264 } 265 266 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle, int fieldType, unsigned long color) 267 { 268 if (!hHandle) 269 return; 270 // CPDFDoc_Environment* pEnv = (CPDFDoc_Environment* )hHandle; 271 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 272 if(pSDKDoc) 273 { 274 if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm()) 275 { 276 pInterForm->SetHighlightColor(color, fieldType); 277 } 278 279 } 280 281 } 282 283 DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha) 284 { 285 if (!hHandle) 286 return; 287 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 288 if(pSDKDoc) 289 { 290 if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm()) 291 pInterForm->SetHighlightAlpha(alpha); 292 } 293 } 294 295 DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) 296 { 297 if (!hHandle) 298 return; 299 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 300 if(pSDKDoc) 301 { 302 if(CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm()) 303 pInterForm->RemoveAllHighLight(); 304 } 305 } 306 307 DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page, FPDF_FORMHANDLE hHandle) 308 { 309 if(!hHandle || !page) 310 return; 311 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 312 if(!pSDKDoc) 313 return; 314 CPDF_Page* pPage = (CPDF_Page*)page; 315 CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, TRUE); 316 if(pPageView) 317 { 318 pPageView->SetValid(TRUE); 319 } 320 } 321 322 DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page, FPDF_FORMHANDLE hHandle) 323 { 324 if(!hHandle || !page) 325 return; 326 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 327 CPDF_Page* pPage = (CPDF_Page*)page; 328 CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE); 329 if(pPageView) 330 { 331 pPageView->SetValid(FALSE); 332 // ReMovePageView() takes care of the delete for us. 333 pSDKDoc->ReMovePageView(pPage); 334 } 335 } 336 DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) 337 { 338 if(!hHandle) 339 return; 340 if( CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc()) 341 { 342 pSDKDoc->InitPageView(); 343 if(((CPDFDoc_Environment*)hHandle)->IsJSInitiated()) 344 pSDKDoc->ProcJavascriptFun(); 345 } 346 } 347 348 DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) 349 { 350 if(!hHandle) 351 return; 352 if( CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc()) 353 { 354 if(((CPDFDoc_Environment*)hHandle)->IsJSInitiated()) 355 pSDKDoc->ProcOpenAction(); 356 } 357 } 358 DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle, int aaType) 359 { 360 if(!hHandle) 361 return; 362 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 363 if(pSDKDoc) 364 { 365 CPDF_Document* pDoc = pSDKDoc->GetDocument(); 366 CPDF_Dictionary* pDic = pDoc->GetRoot(); 367 if (!pDic) 368 return; 369 CPDF_AAction aa = pDic->GetDict(FX_BSTRC("AA")); 370 371 if(aa.ActionExist((CPDF_AAction::AActionType)aaType)) 372 { 373 CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType); 374 CPDFSDK_ActionHandler *pActionHandler = ((CPDFDoc_Environment*)hHandle)->GetActionHander(); 375 ASSERT(pActionHandler != NULL); 376 pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType, pSDKDoc); 377 } 378 } 379 } 380 DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page, FPDF_FORMHANDLE hHandle, int aaType) 381 { 382 if(!hHandle || !page) 383 return; 384 CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc(); 385 CPDF_Page* pPage = (CPDF_Page*)page; 386 CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE); 387 if(pPageView) 388 { 389 CPDFDoc_Environment *pEnv = pSDKDoc->GetEnv(); 390 ASSERT(pEnv != NULL); 391 392 CPDFSDK_ActionHandler *pActionHandler = pEnv->GetActionHander(); 393 ASSERT(pActionHandler != NULL); 394 395 CPDF_Dictionary *pPageDict = pPage->m_pFormDict; 396 ASSERT(pPageDict != NULL); 397 398 CPDF_AAction aa = pPageDict->GetDict(FX_BSTRC("AA")); 399 400 FX_BOOL bExistOAAction = FALSE; 401 FX_BOOL bExistCAAction = FALSE; 402 if (FPDFPAGE_AACTION_OPEN == aaType) 403 { 404 bExistOAAction = aa.ActionExist(CPDF_AAction::OpenPage); 405 if (bExistOAAction) 406 { 407 CPDF_Action action = aa.GetAction(CPDF_AAction::OpenPage); 408 pActionHandler->DoAction_Page(action, CPDF_AAction::OpenPage, pSDKDoc); 409 } 410 } 411 else 412 { 413 bExistCAAction = aa.ActionExist(CPDF_AAction::ClosePage); 414 if (bExistCAAction) 415 { 416 CPDF_Action action = aa.GetAction(CPDF_AAction::ClosePage); 417 pActionHandler->DoAction_Page(action, CPDF_AAction::ClosePage, pSDKDoc); 418 } 419 } 420 } 421 } 422 423 424