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 "Document.h" 8 9 #include "Field.h" 10 #include "Icon.h" 11 #include "JS_Context.h" 12 #include "JS_Define.h" 13 #include "JS_EventHandler.h" 14 #include "JS_Object.h" 15 #include "JS_Runtime.h" 16 #include "JS_Value.h" 17 #include "app.h" 18 #include "fpdfsdk/include/fsdk_mgr.h" // For CPDFDoc_Environment. 19 #include "fpdfsdk/include/javascript/IJavaScript.h" 20 #include "resource.h" 21 #include "third_party/base/numerics/safe_math.h" 22 23 static v8::Isolate* GetIsolate(IJS_Context* cc) { 24 CJS_Context* pContext = (CJS_Context*)cc; 25 CJS_Runtime* pRuntime = pContext->GetJSRuntime(); 26 return pRuntime->GetIsolate(); 27 } 28 29 BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj) 30 END_JS_STATIC_CONST() 31 32 BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj) 33 END_JS_STATIC_PROP() 34 35 BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj) 36 END_JS_STATIC_METHOD() 37 38 IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj) 39 40 PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject) 41 : CJS_EmbedObj(pJSObject) { 42 bUI = TRUE; 43 nStart = 0; 44 nEnd = 0; 45 bSilent = FALSE; 46 bShrinkToFit = FALSE; 47 bPrintAsImage = FALSE; 48 bReverse = FALSE; 49 bAnnotations = TRUE; 50 } 51 52 /* ---------------------- Document ---------------------- */ 53 54 #define MINWIDTH 5.0f 55 #define MINHEIGHT 5.0f 56 57 BEGIN_JS_STATIC_CONST(CJS_Document) 58 END_JS_STATIC_CONST() 59 60 BEGIN_JS_STATIC_PROP(CJS_Document) 61 JS_STATIC_PROP_ENTRY(ADBE) 62 JS_STATIC_PROP_ENTRY(author) 63 JS_STATIC_PROP_ENTRY(baseURL) 64 JS_STATIC_PROP_ENTRY(bookmarkRoot) 65 JS_STATIC_PROP_ENTRY(calculate) 66 JS_STATIC_PROP_ENTRY(Collab) 67 JS_STATIC_PROP_ENTRY(creationDate) 68 JS_STATIC_PROP_ENTRY(creator) 69 JS_STATIC_PROP_ENTRY(delay) 70 JS_STATIC_PROP_ENTRY(dirty) 71 JS_STATIC_PROP_ENTRY(documentFileName) 72 JS_STATIC_PROP_ENTRY(external) 73 JS_STATIC_PROP_ENTRY(filesize) 74 JS_STATIC_PROP_ENTRY(icons) 75 JS_STATIC_PROP_ENTRY(info) 76 JS_STATIC_PROP_ENTRY(keywords) 77 JS_STATIC_PROP_ENTRY(layout) 78 JS_STATIC_PROP_ENTRY(media) 79 JS_STATIC_PROP_ENTRY(modDate) 80 JS_STATIC_PROP_ENTRY(mouseX) 81 JS_STATIC_PROP_ENTRY(mouseY) 82 JS_STATIC_PROP_ENTRY(numFields) 83 JS_STATIC_PROP_ENTRY(numPages) 84 JS_STATIC_PROP_ENTRY(pageNum) 85 JS_STATIC_PROP_ENTRY(pageWindowRect) 86 JS_STATIC_PROP_ENTRY(path) 87 JS_STATIC_PROP_ENTRY(producer) 88 JS_STATIC_PROP_ENTRY(subject) 89 JS_STATIC_PROP_ENTRY(title) 90 JS_STATIC_PROP_ENTRY(zoom) 91 JS_STATIC_PROP_ENTRY(zoomType) 92 END_JS_STATIC_PROP() 93 94 BEGIN_JS_STATIC_METHOD(CJS_Document) 95 JS_STATIC_METHOD_ENTRY(addAnnot) 96 JS_STATIC_METHOD_ENTRY(addField) 97 JS_STATIC_METHOD_ENTRY(addLink) 98 JS_STATIC_METHOD_ENTRY(addIcon) 99 JS_STATIC_METHOD_ENTRY(calculateNow) 100 JS_STATIC_METHOD_ENTRY(closeDoc) 101 JS_STATIC_METHOD_ENTRY(createDataObject) 102 JS_STATIC_METHOD_ENTRY(deletePages) 103 JS_STATIC_METHOD_ENTRY(exportAsText) 104 JS_STATIC_METHOD_ENTRY(exportAsFDF) 105 JS_STATIC_METHOD_ENTRY(exportAsXFDF) 106 JS_STATIC_METHOD_ENTRY(extractPages) 107 JS_STATIC_METHOD_ENTRY(getAnnot) 108 JS_STATIC_METHOD_ENTRY(getAnnots) 109 JS_STATIC_METHOD_ENTRY(getAnnot3D) 110 JS_STATIC_METHOD_ENTRY(getAnnots3D) 111 JS_STATIC_METHOD_ENTRY(getField) 112 JS_STATIC_METHOD_ENTRY(getIcon) 113 JS_STATIC_METHOD_ENTRY(getLinks) 114 JS_STATIC_METHOD_ENTRY(getNthFieldName) 115 JS_STATIC_METHOD_ENTRY(getOCGs) 116 JS_STATIC_METHOD_ENTRY(getPageBox) 117 JS_STATIC_METHOD_ENTRY(getPageNthWord) 118 JS_STATIC_METHOD_ENTRY(getPageNthWordQuads) 119 JS_STATIC_METHOD_ENTRY(getPageNumWords) 120 JS_STATIC_METHOD_ENTRY(getPrintParams) 121 JS_STATIC_METHOD_ENTRY(getURL) 122 JS_STATIC_METHOD_ENTRY(importAnFDF) 123 JS_STATIC_METHOD_ENTRY(importAnXFDF) 124 JS_STATIC_METHOD_ENTRY(importTextData) 125 JS_STATIC_METHOD_ENTRY(insertPages) 126 JS_STATIC_METHOD_ENTRY(mailForm) 127 JS_STATIC_METHOD_ENTRY(print) 128 JS_STATIC_METHOD_ENTRY(removeField) 129 JS_STATIC_METHOD_ENTRY(replacePages) 130 JS_STATIC_METHOD_ENTRY(resetForm) 131 JS_STATIC_METHOD_ENTRY(removeIcon) 132 JS_STATIC_METHOD_ENTRY(saveAs) 133 JS_STATIC_METHOD_ENTRY(submitForm) 134 JS_STATIC_METHOD_ENTRY(mailDoc) 135 END_JS_STATIC_METHOD() 136 137 IMPLEMENT_JS_CLASS(CJS_Document, Document) 138 139 void CJS_Document::InitInstance(IJS_Runtime* pIRuntime) { 140 CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime); 141 Document* pDoc = static_cast<Document*>(GetEmbedObject()); 142 pDoc->AttachDoc(pRuntime->GetReaderDocument()); 143 pDoc->SetIsolate(pRuntime->GetIsolate()); 144 } 145 146 /* --------------------------------- Document --------------------------------- 147 */ 148 149 Document::Document(CJS_Object* pJSObject) 150 : CJS_EmbedObj(pJSObject), 151 m_isolate(NULL), 152 m_pDocument(NULL), 153 m_cwBaseURL(L""), 154 m_bDelay(FALSE) {} 155 156 Document::~Document() { 157 for (int i = 0; i < m_DelayData.GetSize(); i++) { 158 delete m_DelayData.GetAt(i); 159 } 160 161 m_DelayData.RemoveAll(); 162 } 163 164 // the total number of fileds in document. 165 FX_BOOL Document::numFields(IJS_Context* cc, 166 CJS_PropValue& vp, 167 CFX_WideString& sError) { 168 if (vp.IsSetting()) { 169 CJS_Context* pContext = static_cast<CJS_Context*>(cc); 170 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY); 171 return FALSE; 172 } 173 CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm(); 174 CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); 175 vp << (int)pPDFForm->CountFields(); 176 return TRUE; 177 } 178 179 FX_BOOL Document::dirty(IJS_Context* cc, 180 CJS_PropValue& vp, 181 CFX_WideString& sError) { 182 if (vp.IsGetting()) { 183 if (m_pDocument->GetChangeMark()) 184 vp << true; 185 else 186 vp << false; 187 } else { 188 bool bChanged = false; 189 190 vp >> bChanged; 191 192 if (bChanged) 193 m_pDocument->SetChangeMark(); 194 else 195 m_pDocument->ClearChangeMark(); 196 } 197 198 return TRUE; 199 } 200 201 FX_BOOL Document::ADBE(IJS_Context* cc, 202 CJS_PropValue& vp, 203 CFX_WideString& sError) { 204 if (vp.IsGetting()) { 205 vp.SetNull(); 206 } else { 207 } 208 209 return TRUE; 210 } 211 212 FX_BOOL Document::pageNum(IJS_Context* cc, 213 CJS_PropValue& vp, 214 CFX_WideString& sError) { 215 if (vp.IsGetting()) { 216 if (CPDFSDK_PageView* pPageView = m_pDocument->GetCurrentView()) { 217 vp << pPageView->GetPageIndex(); 218 } 219 } else { 220 int iPageCount = m_pDocument->GetPageCount(); 221 int iPageNum = 0; 222 vp >> iPageNum; 223 224 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); 225 if (iPageNum >= 0 && iPageNum < iPageCount) { 226 pEnv->JS_docgotoPage(iPageNum); 227 } else if (iPageNum >= iPageCount) { 228 pEnv->JS_docgotoPage(iPageCount - 1); 229 } else if (iPageNum < 0) { 230 pEnv->JS_docgotoPage(0); 231 } 232 } 233 234 return TRUE; 235 } 236 237 FX_BOOL Document::addAnnot(IJS_Context* cc, 238 const std::vector<CJS_Value>& params, 239 CJS_Value& vRet, 240 CFX_WideString& sError) { 241 // Not supported. 242 return TRUE; 243 } 244 245 FX_BOOL Document::addField(IJS_Context* cc, 246 const std::vector<CJS_Value>& params, 247 CJS_Value& vRet, 248 CFX_WideString& sError) { 249 // Not supported. 250 return TRUE; 251 } 252 253 FX_BOOL Document::exportAsText(IJS_Context* cc, 254 const std::vector<CJS_Value>& params, 255 CJS_Value& vRet, 256 CFX_WideString& sError) { 257 // Unsafe, not supported. 258 return TRUE; 259 } 260 261 FX_BOOL Document::exportAsFDF(IJS_Context* cc, 262 const std::vector<CJS_Value>& params, 263 CJS_Value& vRet, 264 CFX_WideString& sError) { 265 // Unsafe, not supported. 266 return TRUE; 267 } 268 269 FX_BOOL Document::exportAsXFDF(IJS_Context* cc, 270 const std::vector<CJS_Value>& params, 271 CJS_Value& vRet, 272 CFX_WideString& sError) { 273 // Unsafe, not supported. 274 return TRUE; 275 } 276 277 // Maps a field object in PDF document to a JavaScript variable 278 // comment: 279 // note: the paremter cName, this is clue how to treat if the cName is not a 280 // valiable filed name in this document 281 282 FX_BOOL Document::getField(IJS_Context* cc, 283 const std::vector<CJS_Value>& params, 284 CJS_Value& vRet, 285 CFX_WideString& sError) { 286 CJS_Context* pContext = (CJS_Context*)cc; 287 if (params.size() < 1) { 288 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR); 289 return FALSE; 290 } 291 292 CFX_WideString wideName = params[0].ToCFXWideString(); 293 294 CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm(); 295 CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); 296 if (pPDFForm->CountFields(wideName) <= 0) { 297 vRet.SetNull(); 298 return TRUE; 299 } 300 301 CJS_Runtime* pRuntime = pContext->GetJSRuntime(); 302 v8::Local<v8::Object> pFieldObj = FXJS_NewFxDynamicObj( 303 pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID); 304 305 v8::Isolate* isolate = GetIsolate(cc); 306 CJS_Field* pJSField = (CJS_Field*)FXJS_GetPrivate(isolate, pFieldObj); 307 Field* pField = (Field*)pJSField->GetEmbedObject(); 308 pField->AttachField(this, wideName); 309 310 vRet = pJSField; 311 return TRUE; 312 } 313 314 // Gets the name of the nth field in the document 315 FX_BOOL Document::getNthFieldName(IJS_Context* cc, 316 const std::vector<CJS_Value>& params, 317 CJS_Value& vRet, 318 CFX_WideString& sError) { 319 CJS_Context* pContext = (CJS_Context*)cc; 320 if (params.size() != 1) { 321 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR); 322 return FALSE; 323 } 324 325 int nIndex = params[0].ToInt(); 326 if (nIndex < 0) { 327 sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR); 328 return FALSE; 329 } 330 331 CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm(); 332 CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); 333 CPDF_FormField* pField = pPDFForm->GetField(nIndex); 334 if (!pField) 335 return FALSE; 336 337 vRet = pField->GetFullName().c_str(); 338 return TRUE; 339 } 340 341 FX_BOOL Document::importAnFDF(IJS_Context* cc, 342 const std::vector<CJS_Value>& params, 343 CJS_Value& vRet, 344 CFX_WideString& sError) { 345 // Unsafe, not supported. 346 return TRUE; 347 } 348 349 FX_BOOL Document::importAnXFDF(IJS_Context* cc, 350 const std::vector<CJS_Value>& params, 351 CJS_Value& vRet, 352 CFX_WideString& sError) { 353 // Unsafe, not supported. 354 return TRUE; 355 } 356 357 FX_BOOL Document::importTextData(IJS_Context* cc, 358 const std::vector<CJS_Value>& params, 359 CJS_Value& vRet, 360 CFX_WideString& sError) { 361 // Unsafe, not supported. 362 return TRUE; 363 } 364 365 // exports the form data and mails the resulting fdf file as an attachment to 366 // all recipients. 367 // comment: need reader supports 368 // note: 369 // int CPDFSDK_Document::mailForm(FX_BOOL bUI,String cto,string ccc,string 370 // cbcc,string cSubject,string cms); 371 372 FX_BOOL Document::mailForm(IJS_Context* cc, 373 const std::vector<CJS_Value>& params, 374 CJS_Value& vRet, 375 CFX_WideString& sError) { 376 if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) 377 return FALSE; 378 379 int iLength = params.size(); 380 381 FX_BOOL bUI = iLength > 0 ? params[0].ToBool() : TRUE; 382 CFX_WideString cTo = iLength > 1 ? params[1].ToCFXWideString() : L""; 383 CFX_WideString cCc = iLength > 2 ? params[2].ToCFXWideString() : L""; 384 CFX_WideString cBcc = iLength > 3 ? params[3].ToCFXWideString() : L""; 385 CFX_WideString cSubject = iLength > 4 ? params[4].ToCFXWideString() : L""; 386 CFX_WideString cMsg = iLength > 5 ? params[5].ToCFXWideString() : L""; 387 388 CPDFSDK_InterForm* pInterForm = 389 (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); 390 CFX_ByteTextBuf textBuf; 391 if (!pInterForm->ExportFormToFDFTextBuf(textBuf)) 392 return FALSE; 393 394 CJS_Context* pContext = (CJS_Context*)cc; 395 CPDFDoc_Environment* pEnv = pContext->GetReaderApp(); 396 CJS_Runtime* pRuntime = pContext->GetJSRuntime(); 397 398 pRuntime->BeginBlock(); 399 pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, 400 cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), 401 cMsg.c_str()); 402 pRuntime->EndBlock(); 403 return TRUE; 404 } 405 406 FX_BOOL Document::print(IJS_Context* cc, 407 const std::vector<CJS_Value>& params, 408 CJS_Value& vRet, 409 CFX_WideString& sError) { 410 FX_BOOL bUI = TRUE; 411 int nStart = 0; 412 int nEnd = 0; 413 FX_BOOL bSilent = FALSE; 414 FX_BOOL bShrinkToFit = FALSE; 415 FX_BOOL bPrintAsImage = FALSE; 416 FX_BOOL bReverse = FALSE; 417 FX_BOOL bAnnotations = FALSE; 418 419 int nlength = params.size(); 420 if (nlength == 9) { 421 if (params[8].GetType() == CJS_Value::VT_fxobject) { 422 v8::Local<v8::Object> pObj = params[8].ToV8Object(); 423 { 424 if (FXJS_GetObjDefnID(pObj) == CJS_PrintParamsObj::g_nObjDefnID) { 425 if (CJS_Object* pJSObj = params[8].ToCJSObject()) { 426 if (PrintParamsObj* pprintparamsObj = 427 (PrintParamsObj*)pJSObj->GetEmbedObject()) { 428 bUI = pprintparamsObj->bUI; 429 nStart = pprintparamsObj->nStart; 430 nEnd = pprintparamsObj->nEnd; 431 bSilent = pprintparamsObj->bSilent; 432 bShrinkToFit = pprintparamsObj->bShrinkToFit; 433 bPrintAsImage = pprintparamsObj->bPrintAsImage; 434 bReverse = pprintparamsObj->bReverse; 435 bAnnotations = pprintparamsObj->bAnnotations; 436 } 437 } 438 } 439 } 440 } 441 } else { 442 if (nlength >= 1) 443 bUI = params[0].ToBool(); 444 if (nlength >= 2) 445 nStart = params[1].ToInt(); 446 if (nlength >= 3) 447 nEnd = params[2].ToInt(); 448 if (nlength >= 4) 449 bSilent = params[3].ToBool(); 450 if (nlength >= 5) 451 bShrinkToFit = params[4].ToBool(); 452 if (nlength >= 6) 453 bPrintAsImage = params[5].ToBool(); 454 if (nlength >= 7) 455 bReverse = params[6].ToBool(); 456 if (nlength >= 8) 457 bAnnotations = params[7].ToBool(); 458 } 459 460 if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv()) { 461 pEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage, 462 bReverse, bAnnotations); 463 return TRUE; 464 } 465 return FALSE; 466 } 467 468 // removes the specified field from the document. 469 // comment: 470 // note: if the filed name is not retional, adobe is dumb for it. 471 472 FX_BOOL Document::removeField(IJS_Context* cc, 473 const std::vector<CJS_Value>& params, 474 CJS_Value& vRet, 475 CFX_WideString& sError) { 476 if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 477 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM))) 478 return FALSE; 479 480 CJS_Context* pContext = (CJS_Context*)cc; 481 if (params.size() != 1) { 482 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR); 483 return FALSE; 484 } 485 486 CFX_WideString sFieldName = params[0].ToCFXWideString(); 487 CPDFSDK_InterForm* pInterForm = 488 (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); 489 490 std::vector<CPDFSDK_Widget*> widgets; 491 pInterForm->GetWidgets(sFieldName, &widgets); 492 493 if (widgets.empty()) 494 return TRUE; 495 496 for (CPDFSDK_Widget* pWidget : widgets) { 497 CPDF_Rect rcAnnot = pWidget->GetRect(); 498 --rcAnnot.left; 499 --rcAnnot.bottom; 500 ++rcAnnot.right; 501 ++rcAnnot.top; 502 503 CFX_RectArray aRefresh; 504 aRefresh.Add(rcAnnot); 505 506 UnderlyingPageType* pPage = pWidget->GetUnderlyingPage(); 507 ASSERT(pPage); 508 509 CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage); 510 pPageView->DeleteAnnot(pWidget); 511 pPageView->UpdateRects(aRefresh); 512 } 513 m_pDocument->SetChangeMark(); 514 515 return TRUE; 516 } 517 518 // reset filed values within a document. 519 // comment: 520 // note: if the fields names r not rational, aodbe is dumb for it. 521 522 FX_BOOL Document::resetForm(IJS_Context* cc, 523 const std::vector<CJS_Value>& params, 524 CJS_Value& vRet, 525 CFX_WideString& sError) { 526 if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 527 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) || 528 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) 529 return FALSE; 530 531 CPDFSDK_InterForm* pInterForm = 532 (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); 533 CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); 534 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); 535 CJS_Array aName(pRuntime); 536 537 if (params.empty()) { 538 pPDFForm->ResetForm(TRUE); 539 m_pDocument->SetChangeMark(); 540 return TRUE; 541 } 542 543 switch (params[0].GetType()) { 544 default: 545 aName.Attach(params[0].ToV8Array()); 546 break; 547 case CJS_Value::VT_string: 548 aName.SetElement(0, params[0]); 549 break; 550 } 551 552 std::vector<CPDF_FormField*> aFields; 553 for (int i = 0, isz = aName.GetLength(); i < isz; ++i) { 554 CJS_Value valElement(pRuntime); 555 aName.GetElement(i, valElement); 556 CFX_WideString swVal = valElement.ToCFXWideString(); 557 for (int j = 0, jsz = pPDFForm->CountFields(swVal); j < jsz; ++j) 558 aFields.push_back(pPDFForm->GetField(j, swVal)); 559 } 560 561 if (!aFields.empty()) { 562 pPDFForm->ResetForm(aFields, TRUE, TRUE); 563 m_pDocument->SetChangeMark(); 564 } 565 566 return TRUE; 567 } 568 569 FX_BOOL Document::saveAs(IJS_Context* cc, 570 const std::vector<CJS_Value>& params, 571 CJS_Value& vRet, 572 CFX_WideString& sError) { 573 // Unsafe, not supported. 574 return TRUE; 575 } 576 577 FX_BOOL Document::submitForm(IJS_Context* cc, 578 const std::vector<CJS_Value>& params, 579 CJS_Value& vRet, 580 CFX_WideString& sError) { 581 CJS_Context* pContext = (CJS_Context*)cc; 582 int nSize = params.size(); 583 if (nSize < 1) { 584 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR); 585 return FALSE; 586 } 587 588 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); 589 v8::Isolate* isolate = pRuntime->GetIsolate(); 590 CJS_Array aFields(pRuntime); 591 CFX_WideString strURL; 592 FX_BOOL bFDF = TRUE; 593 FX_BOOL bEmpty = FALSE; 594 595 CJS_Value v = params[0]; 596 if (v.GetType() == CJS_Value::VT_string) { 597 strURL = params[0].ToCFXWideString(); 598 if (nSize > 1) 599 bFDF = params[1].ToBool(); 600 if (nSize > 2) 601 bEmpty = params[2].ToBool(); 602 if (nSize > 3) 603 aFields.Attach(params[3].ToV8Array()); 604 } else if (v.GetType() == CJS_Value::VT_object) { 605 v8::Local<v8::Object> pObj = params[0].ToV8Object(); 606 v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"cURL"); 607 if (!pValue.IsEmpty()) 608 strURL = 609 CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString(); 610 611 pValue = FXJS_GetObjectElement(isolate, pObj, L"bFDF"); 612 bFDF = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool(); 613 614 pValue = FXJS_GetObjectElement(isolate, pObj, L"bEmpty"); 615 bEmpty = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool(); 616 617 pValue = FXJS_GetObjectElement(isolate, pObj, L"aFields"); 618 aFields.Attach( 619 CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToV8Array()); 620 } 621 622 CPDFSDK_InterForm* pInterForm = 623 (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); 624 CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm(); 625 FX_BOOL bAll = (aFields.GetLength() == 0); 626 if (bAll && bEmpty) { 627 if (pPDFInterForm->CheckRequiredFields(nullptr, true)) { 628 pRuntime->BeginBlock(); 629 pInterForm->SubmitForm(strURL, FALSE); 630 pRuntime->EndBlock(); 631 } 632 return TRUE; 633 } 634 635 std::vector<CPDF_FormField*> fieldObjects; 636 for (int i = 0, sz = aFields.GetLength(); i < sz; ++i) { 637 CJS_Value valName(pRuntime); 638 aFields.GetElement(i, valName); 639 640 CFX_WideString sName = valName.ToCFXWideString(); 641 CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); 642 for (int j = 0, jsz = pPDFForm->CountFields(sName); j < jsz; ++j) { 643 CPDF_FormField* pField = pPDFForm->GetField(j, sName); 644 if (!bEmpty && pField->GetValue().IsEmpty()) 645 continue; 646 647 fieldObjects.push_back(pField); 648 } 649 } 650 651 if (pPDFInterForm->CheckRequiredFields(&fieldObjects, true)) { 652 pRuntime->BeginBlock(); 653 pInterForm->SubmitFields(strURL, fieldObjects, TRUE, !bFDF); 654 pRuntime->EndBlock(); 655 } 656 return TRUE; 657 } 658 659 ////////////////////////////////////////////////////////////////////////////////////////////// 660 661 void Document::AttachDoc(CPDFSDK_Document* pDoc) { 662 m_pDocument = pDoc; 663 } 664 665 CPDFSDK_Document* Document::GetReaderDoc() { 666 return m_pDocument; 667 } 668 669 FX_BOOL Document::bookmarkRoot(IJS_Context* cc, 670 CJS_PropValue& vp, 671 CFX_WideString& sError) { 672 return TRUE; 673 } 674 675 FX_BOOL Document::mailDoc(IJS_Context* cc, 676 const std::vector<CJS_Value>& params, 677 CJS_Value& vRet, 678 CFX_WideString& sError) { 679 FX_BOOL bUI = TRUE; 680 CFX_WideString cTo = L""; 681 CFX_WideString cCc = L""; 682 CFX_WideString cBcc = L""; 683 CFX_WideString cSubject = L""; 684 CFX_WideString cMsg = L""; 685 686 if (params.size() >= 1) 687 bUI = params[0].ToBool(); 688 if (params.size() >= 2) 689 cTo = params[1].ToCFXWideString(); 690 if (params.size() >= 3) 691 cCc = params[2].ToCFXWideString(); 692 if (params.size() >= 4) 693 cBcc = params[3].ToCFXWideString(); 694 if (params.size() >= 5) 695 cSubject = params[4].ToCFXWideString(); 696 if (params.size() >= 6) 697 cMsg = params[5].ToCFXWideString(); 698 699 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); 700 v8::Isolate* isolate = pRuntime->GetIsolate(); 701 702 if (params.size() >= 1 && params[0].GetType() == CJS_Value::VT_object) { 703 v8::Local<v8::Object> pObj = params[0].ToV8Object(); 704 705 v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"bUI"); 706 bUI = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToInt(); 707 708 pValue = FXJS_GetObjectElement(isolate, pObj, L"cTo"); 709 cTo = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString(); 710 711 pValue = FXJS_GetObjectElement(isolate, pObj, L"cCc"); 712 cCc = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString(); 713 714 pValue = FXJS_GetObjectElement(isolate, pObj, L"cBcc"); 715 cBcc = 716 CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString(); 717 718 pValue = FXJS_GetObjectElement(isolate, pObj, L"cSubject"); 719 cSubject = 720 CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString(); 721 722 pValue = FXJS_GetObjectElement(isolate, pObj, L"cMsg"); 723 cMsg = 724 CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString(); 725 } 726 727 pRuntime->BeginBlock(); 728 CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp(); 729 pEnv->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), 730 cBcc.c_str(), cMsg.c_str()); 731 pRuntime->EndBlock(); 732 733 return TRUE; 734 } 735 736 FX_BOOL Document::author(IJS_Context* cc, 737 CJS_PropValue& vp, 738 CFX_WideString& sError) { 739 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 740 if (!pDictionary) 741 return FALSE; 742 743 if (vp.IsGetting()) { 744 vp << pDictionary->GetUnicodeText("Author"); 745 return TRUE; 746 } else { 747 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 748 return FALSE; 749 750 CFX_WideString csAuthor; 751 vp >> csAuthor; 752 pDictionary->SetAtString("Author", PDF_EncodeText(csAuthor)); 753 m_pDocument->SetChangeMark(); 754 return TRUE; 755 } 756 } 757 758 FX_BOOL Document::info(IJS_Context* cc, 759 CJS_PropValue& vp, 760 CFX_WideString& sError) { 761 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 762 if (!pDictionary) 763 return FALSE; 764 765 CFX_WideString cwAuthor = pDictionary->GetUnicodeText("Author"); 766 CFX_WideString cwTitle = pDictionary->GetUnicodeText("Title"); 767 CFX_WideString cwSubject = pDictionary->GetUnicodeText("Subject"); 768 CFX_WideString cwKeywords = pDictionary->GetUnicodeText("Keywords"); 769 CFX_WideString cwCreator = pDictionary->GetUnicodeText("Creator"); 770 CFX_WideString cwProducer = pDictionary->GetUnicodeText("Producer"); 771 CFX_WideString cwCreationDate = pDictionary->GetUnicodeText("CreationDate"); 772 CFX_WideString cwModDate = pDictionary->GetUnicodeText("ModDate"); 773 CFX_WideString cwTrapped = pDictionary->GetUnicodeText("Trapped"); 774 775 v8::Isolate* isolate = GetIsolate(cc); 776 if (vp.IsGetting()) { 777 CJS_Context* pContext = (CJS_Context*)cc; 778 CJS_Runtime* pRuntime = pContext->GetJSRuntime(); 779 v8::Local<v8::Object> pObj = 780 FXJS_NewFxDynamicObj(pRuntime->GetIsolate(), pRuntime, -1); 781 FXJS_PutObjectString(isolate, pObj, L"Author", cwAuthor.c_str()); 782 FXJS_PutObjectString(isolate, pObj, L"Title", cwTitle.c_str()); 783 FXJS_PutObjectString(isolate, pObj, L"Subject", cwSubject.c_str()); 784 FXJS_PutObjectString(isolate, pObj, L"Keywords", cwKeywords.c_str()); 785 FXJS_PutObjectString(isolate, pObj, L"Creator", cwCreator.c_str()); 786 FXJS_PutObjectString(isolate, pObj, L"Producer", cwProducer.c_str()); 787 FXJS_PutObjectString(isolate, pObj, L"CreationDate", 788 cwCreationDate.c_str()); 789 FXJS_PutObjectString(isolate, pObj, L"ModDate", cwModDate.c_str()); 790 FXJS_PutObjectString(isolate, pObj, L"Trapped", cwTrapped.c_str()); 791 792 // It's to be compatible to non-standard info dictionary. 793 for (const auto& it : *pDictionary) { 794 const CFX_ByteString& bsKey = it.first; 795 CPDF_Object* pValueObj = it.second; 796 CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey, bsKey.GetLength()); 797 798 if (pValueObj->IsString() || pValueObj->IsName()) { 799 FXJS_PutObjectString(isolate, pObj, wsKey.c_str(), 800 pValueObj->GetUnicodeText().c_str()); 801 } else if (pValueObj->IsNumber()) { 802 FXJS_PutObjectNumber(isolate, pObj, wsKey.c_str(), 803 (float)pValueObj->GetNumber()); 804 } else if (pValueObj->IsBoolean()) { 805 FXJS_PutObjectBoolean(isolate, pObj, wsKey.c_str(), 806 (bool)pValueObj->GetInteger()); 807 } 808 } 809 vp << pObj; 810 } 811 return TRUE; 812 } 813 814 FX_BOOL Document::creationDate(IJS_Context* cc, 815 CJS_PropValue& vp, 816 CFX_WideString& sError) { 817 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 818 if (!pDictionary) 819 return FALSE; 820 821 if (vp.IsGetting()) { 822 vp << pDictionary->GetUnicodeText("CreationDate"); 823 } else { 824 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 825 return FALSE; 826 827 CFX_WideString csCreationDate; 828 vp >> csCreationDate; 829 pDictionary->SetAtString("CreationDate", PDF_EncodeText(csCreationDate)); 830 m_pDocument->SetChangeMark(); 831 } 832 return TRUE; 833 } 834 835 FX_BOOL Document::creator(IJS_Context* cc, 836 CJS_PropValue& vp, 837 CFX_WideString& sError) { 838 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 839 if (!pDictionary) 840 return FALSE; 841 842 if (vp.IsGetting()) { 843 vp << pDictionary->GetUnicodeText("Creator"); 844 } else { 845 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 846 return FALSE; 847 848 CFX_WideString csCreator; 849 vp >> csCreator; 850 pDictionary->SetAtString("Creator", PDF_EncodeText(csCreator)); 851 m_pDocument->SetChangeMark(); 852 } 853 return TRUE; 854 } 855 856 FX_BOOL Document::delay(IJS_Context* cc, 857 CJS_PropValue& vp, 858 CFX_WideString& sError) { 859 if (vp.IsGetting()) { 860 vp << m_bDelay; 861 } else { 862 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 863 return FALSE; 864 865 vp >> m_bDelay; 866 if (m_bDelay) { 867 for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++) 868 delete m_DelayData.GetAt(i); 869 870 m_DelayData.RemoveAll(); 871 } else { 872 CFX_ArrayTemplate<CJS_DelayData*> DelayDataToProcess; 873 for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++) { 874 if (CJS_DelayData* pData = m_DelayData.GetAt(i)) { 875 DelayDataToProcess.Add(pData); 876 m_DelayData.SetAt(i, NULL); 877 } 878 } 879 m_DelayData.RemoveAll(); 880 for (int i = 0, sz = DelayDataToProcess.GetSize(); i < sz; i++) { 881 CJS_DelayData* pData = DelayDataToProcess.GetAt(i); 882 Field::DoDelay(m_pDocument, pData); 883 DelayDataToProcess.SetAt(i, NULL); 884 delete pData; 885 } 886 } 887 } 888 return TRUE; 889 } 890 891 FX_BOOL Document::keywords(IJS_Context* cc, 892 CJS_PropValue& vp, 893 CFX_WideString& sError) { 894 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 895 if (!pDictionary) 896 return FALSE; 897 898 if (vp.IsGetting()) { 899 vp << pDictionary->GetUnicodeText("Keywords"); 900 } else { 901 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 902 return FALSE; 903 904 CFX_WideString csKeywords; 905 vp >> csKeywords; 906 pDictionary->SetAtString("Keywords", PDF_EncodeText(csKeywords)); 907 m_pDocument->SetChangeMark(); 908 } 909 return TRUE; 910 } 911 912 FX_BOOL Document::modDate(IJS_Context* cc, 913 CJS_PropValue& vp, 914 CFX_WideString& sError) { 915 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 916 if (!pDictionary) 917 return FALSE; 918 919 if (vp.IsGetting()) { 920 vp << pDictionary->GetUnicodeText("ModDate"); 921 } else { 922 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 923 return FALSE; 924 925 CFX_WideString csmodDate; 926 vp >> csmodDate; 927 pDictionary->SetAtString("ModDate", PDF_EncodeText(csmodDate)); 928 m_pDocument->SetChangeMark(); 929 } 930 return TRUE; 931 } 932 933 FX_BOOL Document::producer(IJS_Context* cc, 934 CJS_PropValue& vp, 935 CFX_WideString& sError) { 936 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 937 if (!pDictionary) 938 return FALSE; 939 940 if (vp.IsGetting()) { 941 vp << pDictionary->GetUnicodeText("Producer"); 942 } else { 943 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 944 return FALSE; 945 946 CFX_WideString csproducer; 947 vp >> csproducer; 948 pDictionary->SetAtString("Producer", PDF_EncodeText(csproducer)); 949 m_pDocument->SetChangeMark(); 950 } 951 return TRUE; 952 } 953 954 FX_BOOL Document::subject(IJS_Context* cc, 955 CJS_PropValue& vp, 956 CFX_WideString& sError) { 957 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 958 if (!pDictionary) 959 return FALSE; 960 961 if (vp.IsGetting()) { 962 vp << pDictionary->GetUnicodeText("Subject"); 963 } else { 964 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 965 return FALSE; 966 967 CFX_WideString cssubject; 968 vp >> cssubject; 969 pDictionary->SetAtString("Subject", PDF_EncodeText(cssubject)); 970 m_pDocument->SetChangeMark(); 971 } 972 return TRUE; 973 } 974 975 FX_BOOL Document::title(IJS_Context* cc, 976 CJS_PropValue& vp, 977 CFX_WideString& sError) { 978 if (!m_pDocument || !m_pDocument->GetUnderlyingDocument()) 979 return FALSE; 980 981 CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo(); 982 if (!pDictionary) 983 return FALSE; 984 985 if (vp.IsGetting()) { 986 vp << pDictionary->GetUnicodeText("Title"); 987 } else { 988 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) 989 return FALSE; 990 991 CFX_WideString cstitle; 992 vp >> cstitle; 993 pDictionary->SetAtString("Title", PDF_EncodeText(cstitle)); 994 m_pDocument->SetChangeMark(); 995 } 996 return TRUE; 997 } 998 999 FX_BOOL Document::numPages(IJS_Context* cc, 1000 CJS_PropValue& vp, 1001 CFX_WideString& sError) { 1002 if (vp.IsSetting()) { 1003 CJS_Context* pContext = static_cast<CJS_Context*>(cc); 1004 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY); 1005 return FALSE; 1006 } 1007 vp << m_pDocument->GetPageCount(); 1008 return TRUE; 1009 } 1010 1011 FX_BOOL Document::external(IJS_Context* cc, 1012 CJS_PropValue& vp, 1013 CFX_WideString& sError) { 1014 // In Chrome case,should always return true. 1015 if (vp.IsGetting()) { 1016 vp << true; 1017 } 1018 return TRUE; 1019 } 1020 1021 FX_BOOL Document::filesize(IJS_Context* cc, 1022 CJS_PropValue& vp, 1023 CFX_WideString& sError) { 1024 if (vp.IsSetting()) { 1025 CJS_Context* pContext = static_cast<CJS_Context*>(cc); 1026 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY); 1027 return FALSE; 1028 } 1029 vp << 0; 1030 return TRUE; 1031 } 1032 1033 FX_BOOL Document::mouseX(IJS_Context* cc, 1034 CJS_PropValue& vp, 1035 CFX_WideString& sError) { 1036 return TRUE; 1037 } 1038 1039 FX_BOOL Document::mouseY(IJS_Context* cc, 1040 CJS_PropValue& vp, 1041 CFX_WideString& sError) { 1042 return TRUE; 1043 } 1044 1045 FX_BOOL Document::baseURL(IJS_Context* cc, 1046 CJS_PropValue& vp, 1047 CFX_WideString& sError) { 1048 if (vp.IsGetting()) { 1049 vp << m_cwBaseURL; 1050 } else { 1051 vp >> m_cwBaseURL; 1052 } 1053 return TRUE; 1054 } 1055 1056 FX_BOOL Document::calculate(IJS_Context* cc, 1057 CJS_PropValue& vp, 1058 CFX_WideString& sError) { 1059 CPDFSDK_InterForm* pInterForm = 1060 (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); 1061 1062 if (vp.IsGetting()) { 1063 if (pInterForm->IsCalculateEnabled()) 1064 vp << true; 1065 else 1066 vp << false; 1067 } else { 1068 bool bCalculate; 1069 vp >> bCalculate; 1070 1071 pInterForm->EnableCalculate(bCalculate); 1072 } 1073 1074 return TRUE; 1075 } 1076 1077 FX_BOOL Document::documentFileName(IJS_Context* cc, 1078 CJS_PropValue& vp, 1079 CFX_WideString& sError) { 1080 if (vp.IsSetting()) { 1081 CJS_Context* pContext = static_cast<CJS_Context*>(cc); 1082 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY); 1083 return FALSE; 1084 } 1085 CFX_WideString wsFilePath = m_pDocument->GetPath(); 1086 int32_t i = wsFilePath.GetLength() - 1; 1087 for (; i >= 0; i--) { 1088 if (wsFilePath.GetAt(i) == L'\\' || wsFilePath.GetAt(i) == L'/') 1089 break; 1090 } 1091 if (i >= 0 && i < wsFilePath.GetLength() - 1) { 1092 vp << (wsFilePath.GetBuffer(wsFilePath.GetLength()) + i + 1); 1093 } else { 1094 vp << L""; 1095 } 1096 return TRUE; 1097 } 1098 1099 FX_BOOL Document::path(IJS_Context* cc, 1100 CJS_PropValue& vp, 1101 CFX_WideString& sError) { 1102 if (vp.IsSetting()) { 1103 CJS_Context* pContext = static_cast<CJS_Context*>(cc); 1104 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY); 1105 return FALSE; 1106 } 1107 vp << app::SysPathToPDFPath(m_pDocument->GetPath()); 1108 return TRUE; 1109 } 1110 1111 FX_BOOL Document::pageWindowRect(IJS_Context* cc, 1112 CJS_PropValue& vp, 1113 CFX_WideString& sError) { 1114 return TRUE; 1115 } 1116 1117 FX_BOOL Document::layout(IJS_Context* cc, 1118 CJS_PropValue& vp, 1119 CFX_WideString& sError) { 1120 return TRUE; 1121 } 1122 1123 FX_BOOL Document::addLink(IJS_Context* cc, 1124 const std::vector<CJS_Value>& params, 1125 CJS_Value& vRet, 1126 CFX_WideString& sError) { 1127 return TRUE; 1128 } 1129 1130 FX_BOOL Document::closeDoc(IJS_Context* cc, 1131 const std::vector<CJS_Value>& params, 1132 CJS_Value& vRet, 1133 CFX_WideString& sError) { 1134 return TRUE; 1135 } 1136 1137 FX_BOOL Document::getPageBox(IJS_Context* cc, 1138 const std::vector<CJS_Value>& params, 1139 CJS_Value& vRet, 1140 CFX_WideString& sError) { 1141 return TRUE; 1142 } 1143 1144 FX_BOOL Document::getAnnot(IJS_Context* cc, 1145 const std::vector<CJS_Value>& params, 1146 CJS_Value& vRet, 1147 CFX_WideString& sError) { 1148 return TRUE; 1149 } 1150 1151 FX_BOOL Document::getAnnots(IJS_Context* cc, 1152 const std::vector<CJS_Value>& params, 1153 CJS_Value& vRet, 1154 CFX_WideString& sError) { 1155 vRet.SetNull(); 1156 return TRUE; 1157 } 1158 1159 FX_BOOL Document::getAnnot3D(IJS_Context* cc, 1160 const std::vector<CJS_Value>& params, 1161 CJS_Value& vRet, 1162 CFX_WideString& sError) { 1163 vRet.SetNull(); 1164 return TRUE; 1165 } 1166 1167 FX_BOOL Document::getAnnots3D(IJS_Context* cc, 1168 const std::vector<CJS_Value>& params, 1169 CJS_Value& vRet, 1170 CFX_WideString& sError) { 1171 vRet = CJS_Value::VT_undefined; 1172 return TRUE; 1173 } 1174 1175 FX_BOOL Document::getOCGs(IJS_Context* cc, 1176 const std::vector<CJS_Value>& params, 1177 CJS_Value& vRet, 1178 CFX_WideString& sError) { 1179 return TRUE; 1180 } 1181 1182 FX_BOOL Document::getLinks(IJS_Context* cc, 1183 const std::vector<CJS_Value>& params, 1184 CJS_Value& vRet, 1185 CFX_WideString& sError) { 1186 return TRUE; 1187 } 1188 1189 bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect) { 1190 return (rect.left <= LinkRect.left && rect.top <= LinkRect.top && 1191 rect.right >= LinkRect.right && rect.bottom >= LinkRect.bottom); 1192 } 1193 1194 FX_BOOL Document::addIcon(IJS_Context* cc, 1195 const std::vector<CJS_Value>& params, 1196 CJS_Value& vRet, 1197 CFX_WideString& sError) { 1198 CJS_Context* pContext = (CJS_Context*)cc; 1199 if (params.size() != 2) { 1200 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR); 1201 return FALSE; 1202 } 1203 CFX_WideString swIconName = params[0].ToCFXWideString(); 1204 1205 if (params[1].GetType() != CJS_Value::VT_object) { 1206 sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR); 1207 return FALSE; 1208 } 1209 1210 v8::Local<v8::Object> pJSIcon = params[1].ToV8Object(); 1211 if (FXJS_GetObjDefnID(pJSIcon) != CJS_Icon::g_nObjDefnID) { 1212 sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR); 1213 return FALSE; 1214 } 1215 1216 CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject()->GetEmbedObject(); 1217 if (!pEmbedObj) { 1218 sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR); 1219 return FALSE; 1220 } 1221 1222 m_IconList.push_back(std::unique_ptr<IconElement>( 1223 new IconElement(swIconName, (Icon*)pEmbedObj))); 1224 return TRUE; 1225 } 1226 1227 FX_BOOL Document::icons(IJS_Context* cc, 1228 CJS_PropValue& vp, 1229 CFX_WideString& sError) { 1230 if (vp.IsSetting()) { 1231 CJS_Context* pContext = static_cast<CJS_Context*>(cc); 1232 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY); 1233 return FALSE; 1234 } 1235 1236 if (m_IconList.empty()) { 1237 vp.SetNull(); 1238 return TRUE; 1239 } 1240 1241 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); 1242 CJS_Array Icons(pRuntime); 1243 1244 int i = 0; 1245 for (const auto& pIconElement : m_IconList) { 1246 v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj( 1247 pRuntime->GetIsolate(), pRuntime, CJS_Icon::g_nObjDefnID); 1248 if (pObj.IsEmpty()) 1249 return FALSE; 1250 1251 CJS_Icon* pJS_Icon = (CJS_Icon*)FXJS_GetPrivate(m_isolate, pObj); 1252 if (!pJS_Icon) 1253 return FALSE; 1254 1255 Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject(); 1256 if (!pIcon) 1257 return FALSE; 1258 1259 pIcon->SetStream(pIconElement->IconStream->GetStream()); 1260 pIcon->SetIconName(pIconElement->IconName); 1261 Icons.SetElement(i++, CJS_Value(pRuntime, pJS_Icon)); 1262 } 1263 1264 vp << Icons; 1265 return TRUE; 1266 } 1267 1268 FX_BOOL Document::getIcon(IJS_Context* cc, 1269 const std::vector<CJS_Value>& params, 1270 CJS_Value& vRet, 1271 CFX_WideString& sError) { 1272 CJS_Context* pContext = (CJS_Context*)cc; 1273 if (params.size() != 1) { 1274 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR); 1275 return FALSE; 1276 } 1277 1278 if (m_IconList.empty()) 1279 return FALSE; 1280 1281 CFX_WideString swIconName = params[0].ToCFXWideString(); 1282 CJS_Runtime* pRuntime = pContext->GetJSRuntime(); 1283 1284 for (const auto& pIconElement : m_IconList) { 1285 if (pIconElement->IconName == swIconName) { 1286 Icon* pRetIcon = pIconElement->IconStream; 1287 1288 v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj( 1289 pRuntime->GetIsolate(), pRuntime, CJS_Icon::g_nObjDefnID); 1290 if (pObj.IsEmpty()) 1291 return FALSE; 1292 1293 CJS_Icon* pJS_Icon = (CJS_Icon*)FXJS_GetPrivate(m_isolate, pObj); 1294 if (!pJS_Icon) 1295 return FALSE; 1296 1297 Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject(); 1298 if (!pIcon) 1299 return FALSE; 1300 1301 pIcon->SetIconName(swIconName); 1302 pIcon->SetStream(pRetIcon->GetStream()); 1303 vRet = pJS_Icon; 1304 return TRUE; 1305 } 1306 } 1307 1308 return FALSE; 1309 } 1310 1311 FX_BOOL Document::removeIcon(IJS_Context* cc, 1312 const std::vector<CJS_Value>& params, 1313 CJS_Value& vRet, 1314 CFX_WideString& sError) { 1315 // Unsafe, no supported. 1316 return TRUE; 1317 } 1318 1319 FX_BOOL Document::createDataObject(IJS_Context* cc, 1320 const std::vector<CJS_Value>& params, 1321 CJS_Value& vRet, 1322 CFX_WideString& sError) { 1323 // Unsafe, not implemented. 1324 return TRUE; 1325 } 1326 1327 FX_BOOL Document::media(IJS_Context* cc, 1328 CJS_PropValue& vp, 1329 CFX_WideString& sError) { 1330 return TRUE; 1331 } 1332 1333 FX_BOOL Document::calculateNow(IJS_Context* cc, 1334 const std::vector<CJS_Value>& params, 1335 CJS_Value& vRet, 1336 CFX_WideString& sError) { 1337 if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 1338 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) || 1339 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) 1340 return FALSE; 1341 1342 CPDFSDK_InterForm* pInterForm = 1343 (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); 1344 pInterForm->OnCalculate(); 1345 return TRUE; 1346 } 1347 1348 FX_BOOL Document::Collab(IJS_Context* cc, 1349 CJS_PropValue& vp, 1350 CFX_WideString& sError) { 1351 return TRUE; 1352 } 1353 1354 FX_BOOL Document::getPageNthWord(IJS_Context* cc, 1355 const std::vector<CJS_Value>& params, 1356 CJS_Value& vRet, 1357 CFX_WideString& sError) { 1358 if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) 1359 return FALSE; 1360 1361 int nPageNo = params.size() > 0 ? params[0].ToInt() : 0; 1362 int nWordNo = params.size() > 1 ? params[1].ToInt() : 0; 1363 bool bStrip = params.size() > 2 ? params[2].ToBool() : true; 1364 1365 CPDF_Document* pDocument = m_pDocument->GetPDFDocument(); 1366 if (!pDocument) 1367 return FALSE; 1368 1369 CJS_Context* pContext = static_cast<CJS_Context*>(cc); 1370 if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) { 1371 sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR); 1372 return FALSE; 1373 } 1374 1375 CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo); 1376 if (!pPageDict) 1377 return FALSE; 1378 1379 CPDF_Page page; 1380 page.Load(pDocument, pPageDict); 1381 page.StartParse(); 1382 page.ParseContent(); 1383 1384 FX_POSITION pos = page.GetFirstObjectPosition(); 1385 1386 int nWords = 0; 1387 1388 CFX_WideString swRet; 1389 1390 while (pos) { 1391 if (CPDF_PageObject* pPageObj = page.GetNextObject(pos)) { 1392 if (pPageObj->m_Type == PDFPAGE_TEXT) { 1393 int nObjWords = CountWords((CPDF_TextObject*)pPageObj); 1394 1395 if (nWords + nObjWords >= nWordNo) { 1396 swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords); 1397 break; 1398 } 1399 1400 nWords += nObjWords; 1401 } 1402 } 1403 } 1404 1405 if (bStrip) { 1406 swRet.TrimLeft(); 1407 swRet.TrimRight(); 1408 } 1409 1410 vRet = swRet.c_str(); 1411 return TRUE; 1412 } 1413 1414 FX_BOOL Document::getPageNthWordQuads(IJS_Context* cc, 1415 const std::vector<CJS_Value>& params, 1416 CJS_Value& vRet, 1417 CFX_WideString& sError) { 1418 if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) 1419 return FALSE; 1420 1421 return FALSE; 1422 } 1423 1424 FX_BOOL Document::getPageNumWords(IJS_Context* cc, 1425 const std::vector<CJS_Value>& params, 1426 CJS_Value& vRet, 1427 CFX_WideString& sError) { 1428 if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) 1429 return FALSE; 1430 1431 int nPageNo = params.size() > 0 ? params[0].ToInt() : 0; 1432 1433 CPDF_Document* pDocument = m_pDocument->GetPDFDocument(); 1434 CJS_Context* pContext = static_cast<CJS_Context*>(cc); 1435 if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) { 1436 sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR); 1437 return FALSE; 1438 } 1439 1440 CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo); 1441 if (!pPageDict) 1442 return FALSE; 1443 1444 CPDF_Page page; 1445 page.Load(pDocument, pPageDict); 1446 page.StartParse(); 1447 page.ParseContent(); 1448 1449 FX_POSITION pos = page.GetFirstObjectPosition(); 1450 1451 int nWords = 0; 1452 1453 while (pos) { 1454 if (CPDF_PageObject* pPageObj = page.GetNextObject(pos)) { 1455 if (pPageObj->m_Type == PDFPAGE_TEXT) { 1456 CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj; 1457 nWords += CountWords(pTextObj); 1458 } 1459 } 1460 } 1461 1462 vRet = nWords; 1463 1464 return TRUE; 1465 } 1466 1467 FX_BOOL Document::getPrintParams(IJS_Context* cc, 1468 const std::vector<CJS_Value>& params, 1469 CJS_Value& vRet, 1470 CFX_WideString& sError) { 1471 CJS_Context* pContext = (CJS_Context*)cc; 1472 CJS_Runtime* pRuntime = pContext->GetJSRuntime(); 1473 v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj( 1474 pRuntime->GetIsolate(), pRuntime, CJS_PrintParamsObj::g_nObjDefnID); 1475 1476 // Not implemented yet. 1477 1478 vRet = pRetObj; 1479 return TRUE; 1480 } 1481 1482 #define ISLATINWORD(u) (u != 0x20 && u <= 0x28FF) 1483 1484 int Document::CountWords(CPDF_TextObject* pTextObj) { 1485 if (!pTextObj) 1486 return 0; 1487 1488 int nWords = 0; 1489 1490 CPDF_Font* pFont = pTextObj->GetFont(); 1491 if (!pFont) 1492 return 0; 1493 1494 FX_BOOL bIsLatin = FALSE; 1495 1496 for (int i = 0, sz = pTextObj->CountChars(); i < sz; i++) { 1497 FX_DWORD charcode = -1; 1498 FX_FLOAT kerning; 1499 1500 pTextObj->GetCharInfo(i, charcode, kerning); 1501 CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode); 1502 1503 FX_WORD unicode = 0; 1504 if (swUnicode.GetLength() > 0) 1505 unicode = swUnicode[0]; 1506 1507 if (ISLATINWORD(unicode) && bIsLatin) 1508 continue; 1509 1510 bIsLatin = ISLATINWORD(unicode); 1511 if (unicode != 0x20) 1512 nWords++; 1513 } 1514 1515 return nWords; 1516 } 1517 1518 CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj, 1519 int nWordIndex) { 1520 CFX_WideString swRet; 1521 1522 CPDF_Font* pFont = pTextObj->GetFont(); 1523 if (!pFont) 1524 return L""; 1525 1526 int nWords = 0; 1527 FX_BOOL bIsLatin = FALSE; 1528 1529 for (int i = 0, sz = pTextObj->CountChars(); i < sz; i++) { 1530 FX_DWORD charcode = -1; 1531 FX_FLOAT kerning; 1532 1533 pTextObj->GetCharInfo(i, charcode, kerning); 1534 CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode); 1535 1536 FX_WORD unicode = 0; 1537 if (swUnicode.GetLength() > 0) 1538 unicode = swUnicode[0]; 1539 1540 if (ISLATINWORD(unicode) && bIsLatin) { 1541 } else { 1542 bIsLatin = ISLATINWORD(unicode); 1543 if (unicode != 0x20) 1544 nWords++; 1545 } 1546 1547 if (nWords - 1 == nWordIndex) 1548 swRet += unicode; 1549 } 1550 1551 return swRet; 1552 } 1553 1554 FX_BOOL Document::zoom(IJS_Context* cc, 1555 CJS_PropValue& vp, 1556 CFX_WideString& sError) { 1557 return TRUE; 1558 } 1559 1560 /** 1561 (none, NoVary) 1562 (fitP, FitPage) 1563 (fitW, FitWidth) 1564 (fitH, FitHeight) 1565 (fitV, FitVisibleWidth) 1566 (pref, Preferred) 1567 (refW, ReflowWidth) 1568 */ 1569 1570 FX_BOOL Document::zoomType(IJS_Context* cc, 1571 CJS_PropValue& vp, 1572 CFX_WideString& sError) { 1573 return TRUE; 1574 } 1575 1576 FX_BOOL Document::deletePages(IJS_Context* cc, 1577 const std::vector<CJS_Value>& params, 1578 CJS_Value& vRet, 1579 CFX_WideString& sError) { 1580 // Unsafe, no supported. 1581 return TRUE; 1582 } 1583 1584 FX_BOOL Document::extractPages(IJS_Context* cc, 1585 const std::vector<CJS_Value>& params, 1586 CJS_Value& vRet, 1587 CFX_WideString& sError) { 1588 // Unsafe, not supported. 1589 return TRUE; 1590 } 1591 1592 FX_BOOL Document::insertPages(IJS_Context* cc, 1593 const std::vector<CJS_Value>& params, 1594 CJS_Value& vRet, 1595 CFX_WideString& sError) { 1596 // Unsafe, not supported. 1597 return TRUE; 1598 } 1599 1600 FX_BOOL Document::replacePages(IJS_Context* cc, 1601 const std::vector<CJS_Value>& params, 1602 CJS_Value& vRet, 1603 CFX_WideString& sError) { 1604 // Unsafe, not supported. 1605 return TRUE; 1606 } 1607 1608 FX_BOOL Document::getURL(IJS_Context* cc, 1609 const std::vector<CJS_Value>& params, 1610 CJS_Value& vRet, 1611 CFX_WideString& sError) { 1612 // Unsafe, not supported. 1613 return TRUE; 1614 } 1615 1616 void Document::AddDelayData(CJS_DelayData* pData) { 1617 m_DelayData.Add(pData); 1618 } 1619 1620 void Document::DoFieldDelay(const CFX_WideString& sFieldName, 1621 int nControlIndex) { 1622 CFX_DWordArray DelArray; 1623 CFX_ArrayTemplate<CJS_DelayData*> DelayDataForFieldAndControlIndex; 1624 1625 for (int i = 0, sz = m_DelayData.GetSize(); i < sz; i++) { 1626 if (CJS_DelayData* pData = m_DelayData.GetAt(i)) { 1627 if (pData->sFieldName == sFieldName && 1628 pData->nControlIndex == nControlIndex) { 1629 DelayDataForFieldAndControlIndex.Add(pData); 1630 m_DelayData.SetAt(i, NULL); 1631 DelArray.Add(i); 1632 } 1633 } 1634 } 1635 1636 for (int j = DelArray.GetSize() - 1; j >= 0; j--) { 1637 m_DelayData.RemoveAt(DelArray[j]); 1638 } 1639 1640 for (int i = 0, sz = DelayDataForFieldAndControlIndex.GetSize(); i < sz; 1641 i++) { 1642 CJS_DelayData* pData = DelayDataForFieldAndControlIndex.GetAt(i); 1643 Field::DoDelay(m_pDocument, pData); 1644 DelayDataForFieldAndControlIndex.SetAt(i, NULL); 1645 delete pData; 1646 } 1647 } 1648 1649 CJS_Document* Document::GetCJSDoc() const { 1650 return static_cast<CJS_Document*>(m_pJSObject); 1651 } 1652