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