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