Getting rid of more (FX_LPCWSTR) casts and fixing two bugs revealed by this.
[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/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         return TRUE;
293 }
294
295 FX_BOOL Document::addAnnot(OBJ_METHOD_PARAMS)
296 {
297         return TRUE;
298 }
299
300 FX_BOOL Document::addField(OBJ_METHOD_PARAMS)
301 {
302         //Doesn't support.
303         return TRUE;
304 }
305
306 //exports form fields as a tab-delimited text file to a local hard disk.
307 //comment: need reader support
308 //note : watch the third parameter:cPath, for what case it can be safely saved?
309 //int CPDFSDK_InterForm::ExportAsText(FX_BOOL bNoPassword,StringArray aFields,String cPath);
310 //return value, int the index of the parameters illegal, the index is based on 1.
311
312 FX_BOOL Document::exportAsText(OBJ_METHOD_PARAMS)
313 {
314         if (IsSafeMode(cc)) return TRUE;
315         return TRUE;
316 }
317
318 //exports form fields as a fdf file to the local hard drive
319 //comment: need reader supports
320 //note:the last parameter hasn't been confirmed.because the previous one blocks the way.
321 //int CPDFSDK_Document::ExportAsFDF(FX_BOOL bAllFields,BOOL bNoPassword,StringArray aFields,FX_BOOL bFlags,String cPath,FX_BOOL bAnnotations);
322
323 FX_BOOL Document::exportAsFDF(OBJ_METHOD_PARAMS)
324 {
325         v8::Isolate* isolate = GetIsolate(cc);
326         if (IsSafeMode(cc)) return TRUE;
327
328         ASSERT(m_pDocument != NULL);
329
330         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
331
332         FX_BOOL bAllFields = params.size() > 0 ? (FX_BOOL)params[0] : FALSE;
333         FX_BOOL bNoPassWord = params.size() > 1 ? (FX_BOOL)params[1] : TRUE;
334         FX_BOOL bWhole = params.size() > 2 ? (params[2].GetType() == VT_null) : TRUE;
335         CJS_Array arrayFileds(isolate);
336         if (!bWhole)
337                 arrayFileds.Attach(params[2]);
338         //FX_BOOL bFlags = params.size() > 3 ? (FX_BOOL)params[3] : FALSE;
339         CFX_WideString swFilePath = params.size() > 4 ? (FX_LPCWSTR)params[4].operator CFX_WideString() : L"";
340
341         if (swFilePath.IsEmpty())
342         {
343                 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
344                 swFilePath = pEnv->JS_fieldBrowse();
345                 if(swFilePath.IsEmpty())
346                         return TRUE;
347         }
348         else
349         {
350                 swFilePath = app::PDFPathToSysPath(swFilePath);
351         }
352         
353         m_pDocument->SetFocusAnnot(NULL);
354    
355         CPDFSDK_InterForm* pInterForm= (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
356         ASSERT(pInterForm != NULL);
357
358         CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
359         ASSERT(pPDFForm != NULL);
360
361         CFX_PtrArray aFields;
362
363         if (bWhole)
364         {
365                 for (int j=0,jsz=pPDFForm->CountFields(); j<jsz; j++)
366                 {
367                         aFields.Add(pPDFForm->GetField(j));
368                 }
369         }
370         else
371         {
372                 for (int i=0,isz=arrayFileds.GetLength(); i<isz; i++)
373                 {
374                         CJS_Value valName(isolate);
375                         arrayFileds.GetElement(i,valName);
376                         CFX_WideString swName = valName.operator CFX_WideString();
377
378                         for (int j=0, jsz=pPDFForm->CountFields(swName); j<jsz; j++)
379                         {
380                                 aFields.Add(pPDFForm->GetField(j, swName));
381                         }
382                 }
383         }
384
385         CFX_PtrArray fields;
386
387         for (int i=0,sz=aFields.GetSize(); i<sz; i++)
388         {
389                 CPDF_FormField* pField = (CPDF_FormField*)aFields[i];
390                 
391                 if (!bAllFields)
392                         if (pField->GetValue() == L"")
393                                 continue;
394
395                 if (bNoPassWord)
396                         if (pField->GetFieldFlags() & 0x2000)
397                                 continue;
398
399                 fields.Add((void*)pField);
400         }    
401
402         return pInterForm->ExportFieldsToFDFFile(swFilePath, fields, TRUE);
403 }
404
405 //exports form fields an XFDF file to the local hard drive
406 //comment: need reder supports
407 //note:the last parameter can't be test
408 //int CPDFSDK_Document::ExportAsXFDF(FX_BOOL bAllFields,FX_BOOL  bNoPassWord,StringArray aFields,String cPath,FX_BOOL bAnnoatations);
409
410 FX_BOOL Document::exportAsXFDF(OBJ_METHOD_PARAMS)
411 {
412         if (IsSafeMode(cc)) return TRUE;
413         ASSERT(m_pDocument != NULL);
414
415         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
416
417         return TRUE;
418 }
419
420 //Maps a field object in PDF document to a JavaScript variable
421 //comment:
422 //note: the paremter cName, this is clue how to treat if the cName is not a valiable filed name in this document
423
424 FX_BOOL Document::getField(OBJ_METHOD_PARAMS)
425 {
426         v8::Isolate* isolate = GetIsolate(cc);
427         ASSERT(m_pDocument != NULL);
428
429         if (params.size() < 1) return FALSE;
430
431         CFX_WideString wideName = params[0].operator CFX_WideString();
432
433         CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
434         ASSERT(pInterForm != NULL);
435
436         CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
437         ASSERT(pPDFForm != NULL);
438
439         if (pPDFForm->CountFields(wideName) <= 0) 
440         {
441                 vRet.SetNull();
442                 return TRUE;
443         }
444
445         CJS_Context* pContext = (CJS_Context*)cc;
446         ASSERT(pContext != NULL);
447         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
448         ASSERT(pRuntime != NULL);
449
450         JSFXObject  pFieldObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Field"));
451
452         CJS_Field * pJSField = (CJS_Field*)JS_GetPrivate(isolate,pFieldObj);
453         ASSERT(pJSField != NULL);
454
455         Field * pField = (Field *)pJSField->GetEmbedObject(); 
456         ASSERT(pField != NULL);
457
458         pField->AttachField(this, wideName);
459         vRet = pJSField;
460
461         return TRUE;
462 }
463
464 //Gets the name of the nth field in the document 
465 //comment:
466 //note: the parameter nIndex, if it is not available
467
468 FX_BOOL Document::getNthFieldName(OBJ_METHOD_PARAMS)
469 {
470         ASSERT(m_pDocument != NULL);
471
472         int nIndex = params.size() > 0 ? (int)params[0] : -1;
473         if (nIndex == -1) return FALSE;
474
475         CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
476         ASSERT(pInterForm != NULL);
477
478         CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
479         ASSERT(pPDFForm != NULL);
480
481         CPDF_FormField* pField = pPDFForm->GetField(nIndex);
482         if (!pField)
483                 return FALSE;
484
485         vRet = pField->GetFullName();
486         return TRUE;    
487 }
488
489 //imports the specified fdf file.
490 //comments: need reader suppport
491 //note:once the cpath is illigl  then a file dialog box pops up in order to ask user to chooose the file
492 //int CPDFSDK_Document::importAnFDF(String cPath);
493
494 FX_BOOL Document::importAnFDF(OBJ_METHOD_PARAMS)
495 {
496         if (IsSafeMode(cc)) return TRUE;
497         ASSERT(m_pDocument != NULL);
498
499         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
500                 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
501                 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
502
503
504         CFX_WideString swPath;
505         
506         if (params.size() > 0)
507                 swPath = params[0];
508         
509         if (swPath.IsEmpty())
510         {
511                 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
512                 swPath = pEnv->JS_fieldBrowse();
513                 if(swPath.IsEmpty())
514                         return TRUE;
515         }
516         else
517         {
518                 swPath = app::PDFPathToSysPath(swPath);
519         }
520
521         m_pDocument->SetFocusAnnot(NULL);
522
523         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
524         ASSERT(pInterForm != NULL);
525
526         if (!pInterForm->ImportFormFromFDFFile(swPath, TRUE))
527                 return FALSE;
528
529         m_pDocument->SetChangeMark();
530 //      CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
531 //      ASSERT(pEnv != NULL);
532 //      IUndo* pUndo = IUndo::GetUndo(pEnv);
533 //      ASSERT(pUndo != NULL);
534 //      pUndo->Reset(m_pDocument);
535
536         return TRUE;
537 }
538
539 //imports and specified XFDF file containing XML form data
540 //comment: need reader supports
541 //note: same as up
542 //int CPDFSDK_Document::importAnFDF(String cPath)
543
544 FX_BOOL Document::importAnXFDF(OBJ_METHOD_PARAMS)
545 {
546         if (IsSafeMode(cc)) return TRUE;
547         ASSERT(m_pDocument != NULL);
548
549         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
550                 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
551                 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
552
553         return TRUE;
554 }
555
556 //imports and specified text file 
557 //commnet: need reader supports
558 //note: same as up,when nRow is not rational,adobe is dumb for it.
559 //int CPDFSDK_Document::importTextData(String cPath,int nRow);
560
561 FX_BOOL Document::importTextData(OBJ_METHOD_PARAMS)
562 {
563         if (IsSafeMode(cc)) return TRUE;
564         ASSERT(m_pDocument != NULL);
565
566         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
567                 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
568                 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
569
570         return TRUE;
571 }
572
573 //exports the form data and mails the resulting fdf file as an attachment to all recipients.
574 //comment: need reader supports
575 //note:
576 //int CPDFSDK_Document::mailForm(FX_BOOL bUI,String cto,string ccc,string cbcc,string cSubject,string cms);
577
578 FX_BOOL Document::mailForm(OBJ_METHOD_PARAMS)
579 {
580         ASSERT(m_pDocument != NULL);
581
582         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
583
584         int iLength = params.size();
585
586         FX_BOOL bUI = iLength > 0 ? (FX_BOOL)params[0] : TRUE;
587         CFX_WideString cTo = iLength > 1 ? (FX_LPCWSTR)params[1].operator CFX_WideString() : L"";
588         CFX_WideString cCc = iLength > 2 ? (FX_LPCWSTR)params[2].operator CFX_WideString() : L"";
589         CFX_WideString cBcc = iLength > 3 ? (FX_LPCWSTR)params[3].operator CFX_WideString() : L"";
590         CFX_WideString cSubject = iLength > 4 ? (FX_LPCWSTR)params[4].operator CFX_WideString() : L"";
591         CFX_WideString cMsg = iLength > 5 ? (FX_LPCWSTR)params[5].operator CFX_WideString() : L"";
592
593         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
594         ASSERT(pInterForm != NULL);
595
596         CFX_ByteTextBuf textBuf;
597         if (!pInterForm->ExportFormToFDFTextBuf(textBuf))
598                 return FALSE;
599
600         CJS_Context* pContext = (CJS_Context*)cc;
601         ASSERT(pContext != NULL);
602         CPDFDoc_Environment* pEnv = pContext->GetReaderApp();
603         ASSERT(pEnv != NULL);
604         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
605         ASSERT(pRuntime != NULL);
606
607         pRuntime->BeginBlock();
608         pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
609         pRuntime->EndBlock();
610         return TRUE;
611 }
612
613 FX_BOOL Document::print(OBJ_METHOD_PARAMS)
614 {
615         CJS_Context* pContext = (CJS_Context*)cc;
616         ASSERT(pContext != NULL);
617         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
618         ASSERT(pRuntime != NULL);
619
620         FX_BOOL bUI = TRUE;
621         int nStart = 0;
622         int nEnd = 0;
623         FX_BOOL bSilent = FALSE;
624         FX_BOOL bShrinkToFit = FALSE;
625         FX_BOOL bPrintAsImage = FALSE;
626         FX_BOOL bReverse = FALSE;
627         FX_BOOL bAnnotations = FALSE;
628
629         int nlength = params.size();
630         if(nlength ==9)
631         {
632                 if (params[8].GetType() == VT_fxobject)
633                 {
634                         JSFXObject pObj = (JSFXObject)params[8];
635                         {
636                                 if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"PrintParamsObj"))
637                                 {
638                                         if (CJS_Object* pJSObj = (CJS_Object*)params[8])
639                                         {
640                                                         if (PrintParamsObj* pprintparamsObj = (PrintParamsObj*)pJSObj->GetEmbedObject())
641                                                         {
642                                                                 bUI = pprintparamsObj->bUI;
643                                                                 nStart = pprintparamsObj->nStart;
644                                                                 nEnd = pprintparamsObj->nEnd;
645                                                                 bSilent = pprintparamsObj->bSilent;
646                                                                 bShrinkToFit = pprintparamsObj->bShrinkToFit;
647                                                                 bPrintAsImage = pprintparamsObj->bPrintAsImage;
648                                                                 bReverse = pprintparamsObj->bReverse;
649                                                                 bAnnotations = pprintparamsObj->bAnnotations;
650                                                         }
651                                         }
652                                 }
653                         }       
654                 }
655         }
656         else
657         {
658                 if(nlength >= 1)
659                          bUI = params[0];
660                 if(nlength >= 2)
661                          nStart = (int)params[1];
662                 if(nlength >= 3)
663                         nEnd = (int)params[2];
664                 if(nlength >= 4)
665                         bSilent = params[3];
666                 if(nlength >= 5)
667                         bShrinkToFit = params[4];
668                 if(nlength >= 6)
669                         bPrintAsImage = params[5];
670                 if(nlength >= 7)
671                         bReverse = params[6];
672                 if(nlength >= 8)
673                         bAnnotations = params[7];
674         }
675
676         ASSERT(m_pDocument != NULL);
677  
678         if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv())
679         {
680                 pEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage, bReverse, bAnnotations);
681                 return TRUE;
682         }
683         return FALSE;
684 }
685
686 //removes the specified field from the document.
687 //comment:
688 //note: if the filed name is not retional, adobe is dumb for it.
689
690 FX_BOOL Document::removeField(OBJ_METHOD_PARAMS)
691 {
692         ASSERT(m_pDocument != NULL);
693
694         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
695                 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM))) return FALSE;
696
697         if (params.size() < 1)
698                 return TRUE;
699
700         CFX_WideString sFieldName = params[0].operator CFX_WideString();
701
702         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
703         ASSERT(pInterForm != NULL);
704
705         CFX_PtrArray widgets;
706         pInterForm->GetWidgets(sFieldName, widgets);
707
708         int nSize = widgets.GetSize();
709
710         if (nSize > 0)
711         {
712                 for (int i=0; i<nSize; i++)
713                 {
714                         CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)widgets[i];
715                         ASSERT(pWidget != NULL);
716
717                         CPDF_Rect rcAnnot = pWidget->GetRect();
718                         rcAnnot.left -= 1;
719                         rcAnnot.bottom -= 1;
720                         rcAnnot.right += 1;
721                         rcAnnot.top += 1;
722
723                         CFX_RectArray aRefresh;
724                         aRefresh.Add(rcAnnot);
725
726                         CPDF_Page* pPage = pWidget->GetPDFPage();
727                         ASSERT(pPage != NULL);
728                         
729                         CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage);
730                         pPageView->DeleteAnnot(pWidget);
731
732                         pPageView->UpdateRects(aRefresh);
733                 }
734                 m_pDocument->SetChangeMark();
735         }
736
737         return TRUE;
738 }
739
740 //reset filed values within a document.
741 //comment:
742 //note: if the fields names r not rational, aodbe is dumb for it.
743
744 FX_BOOL Document::resetForm(OBJ_METHOD_PARAMS)
745 {
746         ASSERT(m_pDocument != NULL);
747
748         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
749                 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
750                 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
751
752         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
753         ASSERT(pInterForm != NULL);
754
755         CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
756         ASSERT(pPDFForm != NULL);
757
758         v8::Isolate* isolate = GetIsolate(cc);
759         CJS_Array aName(isolate);
760
761         if (params.size() > 0)
762         {
763                 switch (params[0].GetType())
764                 {
765                 default:
766                         aName.Attach(params[0]);
767                         break;
768                 case VT_string:
769                         aName.SetElement(0,params[0]);
770                         break;
771                 }
772
773                 CFX_PtrArray aFields;
774
775                 for (int i=0,isz=aName.GetLength(); i<isz; i++)
776                 {
777                         CJS_Value valElement(isolate);
778                         aName.GetElement(i,valElement);
779                         CFX_WideString swVal = valElement.operator CFX_WideString();    
780                         
781                         for (int j=0,jsz=pPDFForm->CountFields(swVal); j<jsz; j++)
782                         {
783                                 aFields.Add((void*)pPDFForm->GetField(j,swVal));
784                         }               
785                 }
786
787                 if (aFields.GetSize() > 0)
788                 {
789                         pPDFForm->ResetForm(aFields, TRUE, TRUE);
790                         m_pDocument->SetChangeMark();
791
792                 }
793         }
794         else
795         {
796                 pPDFForm->ResetForm(TRUE);
797                 m_pDocument->SetChangeMark();
798
799         }
800
801         return TRUE;
802 }
803
804
805 FX_BOOL Document::saveAs(OBJ_METHOD_PARAMS)
806 {
807
808         if (IsSafeMode(cc)) return TRUE;
809
810         ASSERT(m_pDocument != NULL);
811
812 //      m_pDocument->DoSaveAs();
813
814         return TRUE;
815 }
816
817
818 FX_BOOL Document::submitForm(OBJ_METHOD_PARAMS)
819 {
820         ASSERT(m_pDocument != NULL);
821
822 //      if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
823
824         int nSize = params.size();
825         if (nSize < 1) return FALSE;
826
827         CFX_WideString strURL;
828         FX_BOOL bFDF = TRUE;
829         FX_BOOL bEmpty = FALSE;
830         v8::Isolate* isolate = GetIsolate(cc);
831         CJS_Array aFields(isolate);
832
833         CJS_Value v = params[0];
834         if (v.GetType() == VT_string)
835         {
836                 strURL = params[0].operator CFX_WideString();
837                 if (nSize > 1)
838                         bFDF = params[1];
839                 if (nSize > 2)
840                         bEmpty = params[2];
841                 if (nSize > 3)
842                         aFields.Attach(params[3]);
843         }
844         else if (v.GetType() == VT_object)
845         {
846                 JSObject pObj = (JSObject)params[0];
847                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"cURL");
848                 if (!pValue.IsEmpty())
849                         strURL = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
850                 pValue = JS_GetObjectElement(isolate,pObj, L"bFDF");
851                         bFDF = CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue));
852                 pValue = JS_GetObjectElement(isolate,pObj, L"bEmpty");
853                         bEmpty = CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue));
854                 pValue = JS_GetObjectElement(isolate,pObj,L"aFields");
855                         aFields.Attach(CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue)));
856         }               
857
858         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
859         ASSERT(pInterForm != NULL);
860         CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
861         ASSERT(pPDFInterForm != NULL);
862
863         FX_BOOL bAll = (aFields.GetLength() == 0);
864
865         if (bAll && bEmpty)
866         {
867                 CJS_Context* pContext = (CJS_Context*)cc;
868                 ASSERT(pContext != NULL);
869                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
870                 ASSERT(pRuntime != NULL);
871
872                 
873                 if (pPDFInterForm->CheckRequiredFields())
874                 {
875                         pRuntime->BeginBlock();
876                         pInterForm->SubmitForm(strURL, FALSE);
877                         pRuntime->EndBlock();
878                 }
879
880                 return TRUE;
881         }
882         else
883         {       
884                 CFX_PtrArray fieldObjects;
885
886                 for (int i=0,sz=aFields.GetLength(); i<sz; i++)
887                 {
888                         CJS_Value valName(isolate);
889                         aFields.GetElement(i, valName);
890                         CFX_WideString sName = valName.operator CFX_WideString();
891
892                         CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
893                         ASSERT(pPDFForm != NULL);
894
895                         for (int j=0, jsz=pPDFForm->CountFields(sName); j<jsz; j++)
896                         {
897                                 CPDF_FormField* pField = pPDFForm->GetField(j, sName);
898                                 if (!bEmpty && pField->GetValue().IsEmpty())
899                                         continue;
900
901                                 fieldObjects.Add(pField);
902                         }
903                 }
904
905                 CJS_Context* pContext = (CJS_Context*)cc;
906                 ASSERT(pContext != NULL);
907                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
908                 ASSERT(pRuntime != NULL);
909
910                 
911                 if (pPDFInterForm->CheckRequiredFields(&fieldObjects, TRUE))
912                 {
913                         pRuntime->BeginBlock();
914                         pInterForm->SubmitFields(strURL, fieldObjects, TRUE, !bFDF);
915                         pRuntime->EndBlock();
916                 }
917
918                 return TRUE;
919         }
920
921 }
922
923 //////////////////////////////////////////////////////////////////////////////////////////////
924
925 void Document::AttachDoc(CPDFSDK_Document *pDoc)
926 {
927         m_pDocument = pDoc;
928 }
929
930 CPDFSDK_Document * Document::GetReaderDoc()
931 {
932         return m_pDocument;
933 }
934
935 FX_BOOL Document::ExtractFileName(CPDFSDK_Document *pDoc,CFX_ByteString &strFileName)
936 {
937         return FALSE;
938 }
939
940 FX_BOOL Document::ExtractFolderName(CPDFSDK_Document *pDoc,CFX_ByteString &strFolderName)
941 {
942         return FALSE;
943 }
944
945 FX_BOOL Document::bookmarkRoot(OBJ_PROP_PARAMS)
946 {       
947         return TRUE;
948 }
949
950 FX_BOOL Document::mailDoc(OBJ_METHOD_PARAMS)
951 {
952         ASSERT(m_pDocument != NULL);
953
954         FX_BOOL bUI = TRUE;
955         CFX_WideString cTo = L"";
956         CFX_WideString cCc = L"";
957         CFX_WideString cBcc = L"";
958         CFX_WideString cSubject = L"";
959         CFX_WideString cMsg = L"";
960         
961
962         bUI = params.size()>=1?static_cast<FX_BOOL>(params[0]):TRUE;
963         cTo = params.size()>=2?(const wchar_t*)params[1].operator CFX_WideString():L"";
964         cCc = params.size()>=3?(const wchar_t*)params[2].operator CFX_WideString():L"";
965         cBcc = params.size()>=4?(const wchar_t*)params[3].operator CFX_WideString():L"";
966         cSubject = params.size()>=5?(const wchar_t*)params[4].operator CFX_WideString():L"";
967         cMsg = params.size()>=6?(const wchar_t*)params[5].operator CFX_WideString():L"";
968         
969         v8::Isolate* isolate = GetIsolate(cc);
970
971         if(params.size()>=1 && params[0].GetType() == VT_object)
972         {
973                 JSObject  pObj = (JSObject )params[0];
974
975                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI");
976                         bUI = (int)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
977
978                 pValue = JS_GetObjectElement(isolate,pObj, L"cTo");
979                         cTo = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
980
981                 pValue = JS_GetObjectElement(isolate,pObj, L"cCc");
982                         cCc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
983
984                 pValue = JS_GetObjectElement(isolate,pObj, L"cBcc");
985                         cBcc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
986
987                 pValue = JS_GetObjectElement(isolate,pObj, L"cSubject");
988                         cSubject = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
989
990                 pValue = JS_GetObjectElement(isolate,pObj, L"cMsg");
991                         cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
992         
993         }
994
995         CJS_Context* pContext = (CJS_Context*)cc;
996         ASSERT(pContext != NULL);
997         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
998         ASSERT(pRuntime != NULL);
999
1000         pRuntime->BeginBlock();
1001         CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp();
1002         pEnv->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
1003         pRuntime->EndBlock();
1004
1005         return TRUE;
1006 }
1007
1008 FX_BOOL Document::author(OBJ_PROP_PARAMS)
1009 {
1010         ASSERT(m_pDocument != NULL);
1011
1012         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1013         if (!pDictionary)return FALSE;
1014
1015         if (vp.IsGetting())
1016         {
1017                 vp << pDictionary->GetUnicodeText("Author");
1018                 return TRUE;
1019         }
1020         else
1021         {
1022                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1023
1024                 CFX_WideString csAuthor;
1025                 vp >> csAuthor;
1026                 pDictionary->SetAtString("Author", PDF_EncodeText(csAuthor));
1027                 m_pDocument->SetChangeMark();
1028                 return TRUE;
1029         }
1030 }
1031
1032 FX_BOOL Document::info(OBJ_PROP_PARAMS)
1033 {
1034         ASSERT(m_pDocument != NULL);
1035
1036         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1037         if (!pDictionary)return FALSE;
1038
1039         CFX_WideString cwAuthor                 = pDictionary->GetUnicodeText("Author");
1040         CFX_WideString cwTitle                  = pDictionary->GetUnicodeText("Title");
1041         CFX_WideString cwSubject                = pDictionary->GetUnicodeText("Subject");
1042         CFX_WideString cwKeywords               = pDictionary->GetUnicodeText("Keywords");
1043         CFX_WideString cwCreator                = pDictionary->GetUnicodeText("Creator");
1044         CFX_WideString cwProducer               = pDictionary->GetUnicodeText("Producer");
1045         CFX_WideString cwCreationDate   = pDictionary->GetUnicodeText("CreationDate");
1046         CFX_WideString cwModDate                = pDictionary->GetUnicodeText("ModDate");
1047         CFX_WideString cwTrapped                = pDictionary->GetUnicodeText("Trapped");
1048
1049         v8::Isolate* isolate = GetIsolate(cc);
1050         if (!vp.IsSetting())
1051         {
1052                 CJS_Context* pContext = (CJS_Context *)cc;
1053                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1054
1055                 JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, -1);
1056
1057                 JS_PutObjectString(isolate,pObj, L"Author", cwAuthor);
1058                 JS_PutObjectString(isolate,pObj, L"Title", cwTitle);
1059                 JS_PutObjectString(isolate,pObj, L"Subject", cwSubject);
1060                 JS_PutObjectString(isolate,pObj, L"Keywords", cwKeywords);
1061                 JS_PutObjectString(isolate,pObj, L"Creator", cwCreator);
1062                 JS_PutObjectString(isolate,pObj, L"Producer", cwProducer);
1063                 JS_PutObjectString(isolate,pObj, L"CreationDate", cwCreationDate);
1064                 JS_PutObjectString(isolate,pObj, L"ModDate", cwModDate);
1065                 JS_PutObjectString(isolate,pObj, L"Trapped", cwTrapped);
1066
1067 // It's to be compatible to non-standard info dictionary.       
1068                 FX_POSITION pos = pDictionary->GetStartPos();
1069                 while(pos)
1070                 {
1071                         CFX_ByteString bsKey;
1072                         CPDF_Object* pValueObj = pDictionary->GetNextElement(pos, bsKey);
1073                         CFX_WideString wsKey  = CFX_WideString::FromUTF8(bsKey, bsKey.GetLength());
1074                         if((pValueObj->GetType()==PDFOBJ_STRING) || (pValueObj->GetType()==PDFOBJ_NAME) )
1075                                         JS_PutObjectString(isolate,pObj, wsKey, pValueObj->GetUnicodeText());
1076                         if(pValueObj->GetType()==PDFOBJ_NUMBER)
1077                                 JS_PutObjectNumber(isolate,pObj, wsKey, (float)pValueObj->GetNumber());
1078                         if(pValueObj->GetType()==PDFOBJ_BOOLEAN)
1079                                 JS_PutObjectBoolean(isolate,pObj, wsKey, (bool)pValueObj->GetInteger());
1080                 }
1081
1082                 vp << pObj;
1083                 return TRUE;
1084         }
1085         else
1086         {
1087                 return TRUE;
1088         }
1089 }
1090
1091 FX_BOOL Document::creationDate(OBJ_PROP_PARAMS)
1092 {
1093         ASSERT(m_pDocument != NULL);
1094
1095         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1096         if (!pDictionary)return FALSE;
1097
1098         if (vp.IsGetting())
1099         {
1100                 vp << pDictionary->GetUnicodeText("CreationDate");
1101                 return TRUE;
1102         }
1103         else
1104         {
1105                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1106
1107                 CFX_WideString csCreationDate;
1108                 vp >> csCreationDate;
1109                 pDictionary->SetAtString("CreationDate", PDF_EncodeText(csCreationDate));
1110                 m_pDocument->SetChangeMark();
1111
1112                 return TRUE;
1113         }
1114 }
1115
1116 FX_BOOL Document::creator(OBJ_PROP_PARAMS)
1117 {
1118         ASSERT(m_pDocument != NULL);
1119
1120         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1121         if (!pDictionary)return FALSE;
1122
1123         if (vp.IsGetting())
1124         {
1125                 vp << pDictionary->GetUnicodeText("Creator");
1126                 return TRUE;
1127         }
1128         else
1129         {
1130                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1131
1132                 CFX_WideString csCreator;
1133                 vp >> csCreator;
1134                 pDictionary->SetAtString("Creator", PDF_EncodeText(csCreator));
1135                 m_pDocument->SetChangeMark();
1136                 return TRUE;
1137         }
1138 }
1139
1140 FX_BOOL Document::delay(OBJ_PROP_PARAMS)
1141 {
1142         if (vp.IsGetting())
1143         {
1144                 vp << m_bDelay;
1145                 return TRUE;
1146         }
1147         else
1148         {
1149                 ASSERT(m_pDocument != NULL);
1150
1151                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1152
1153                 bool b;
1154                 vp >> b;
1155
1156                 m_bDelay = b;
1157
1158                 if (m_bDelay) 
1159                 {
1160                         for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++)
1161                                 delete m_DelayData.GetAt(i);
1162
1163                         m_DelayData.RemoveAll();
1164                 }
1165                 else
1166                 {
1167                         for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++)
1168                         {
1169                                 if (CJS_DelayData* pData = m_DelayData.GetAt(i))
1170                                 {
1171                                         Field::DoDelay(m_pDocument, pData);
1172                                         delete m_DelayData.GetAt(i);
1173                                 }
1174                         }
1175                         m_DelayData.RemoveAll();
1176                 }
1177
1178                 return TRUE;
1179         }
1180 }
1181
1182 FX_BOOL Document::keywords(OBJ_PROP_PARAMS)
1183 {
1184         ASSERT(m_pDocument != NULL);
1185
1186         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1187         if (!pDictionary)return FALSE;
1188
1189         if (vp.IsGetting())
1190         {
1191                 vp << pDictionary->GetUnicodeText("Keywords");
1192                 return TRUE;
1193         }
1194         else
1195         {
1196                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1197
1198                 CFX_WideString csKeywords;
1199                 vp >> csKeywords;
1200                 pDictionary->SetAtString("Keywords", PDF_EncodeText(csKeywords));
1201                 m_pDocument->SetChangeMark();
1202                 return TRUE;
1203         }
1204 }
1205
1206 FX_BOOL Document::modDate(OBJ_PROP_PARAMS)
1207 {
1208         ASSERT(m_pDocument != NULL);
1209
1210         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1211         if (!pDictionary)return FALSE;
1212
1213         if (vp.IsGetting())
1214         {
1215                 vp << pDictionary->GetUnicodeText("ModDate");
1216                 return TRUE;
1217         }
1218         else
1219         {
1220                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1221
1222                 CFX_WideString csmodDate;
1223                 vp >> csmodDate;
1224                 pDictionary->SetAtString("ModDate", PDF_EncodeText(csmodDate));
1225                 m_pDocument->SetChangeMark();
1226                 return TRUE;
1227         }
1228 }
1229
1230 FX_BOOL Document::producer(OBJ_PROP_PARAMS)
1231 {
1232         ASSERT(m_pDocument != NULL);
1233
1234         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1235         if (!pDictionary)return FALSE;
1236
1237         if (vp.IsGetting())
1238         {
1239                 vp << pDictionary->GetUnicodeText("Producer");
1240                 return TRUE;
1241         }
1242         else
1243         {
1244                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1245
1246                 CFX_WideString csproducer;
1247                 vp >> csproducer;
1248                 pDictionary->SetAtString("Producer", PDF_EncodeText(csproducer));
1249                 m_pDocument->SetChangeMark();
1250                 return TRUE;
1251         }
1252 }
1253
1254 FX_BOOL Document::subject(OBJ_PROP_PARAMS)
1255 {
1256         ASSERT(m_pDocument != NULL);
1257
1258         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1259         if (!pDictionary)return FALSE;
1260
1261         if (vp.IsGetting())
1262         {
1263                 vp << pDictionary->GetUnicodeText("Subject");
1264                 return TRUE;
1265         }
1266         else
1267         {
1268                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1269
1270                 CFX_WideString cssubject;
1271                 vp >> cssubject;
1272                 pDictionary->SetAtString("Subject", PDF_EncodeText(cssubject));
1273                 m_pDocument->SetChangeMark();
1274                 return TRUE;
1275         }
1276 }
1277
1278 FX_BOOL Document::title(OBJ_PROP_PARAMS)
1279 {
1280         ASSERT(m_pDocument != NULL);
1281
1282         if (m_pDocument == NULL || m_pDocument->GetDocument() == NULL)
1283                 return FALSE;
1284
1285         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1286         if (!pDictionary)return FALSE;
1287
1288         if (vp.IsGetting())
1289         {
1290                 vp << pDictionary->GetUnicodeText("Title");
1291                 return TRUE;
1292         }
1293         else
1294         {
1295                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1296
1297                 CFX_WideString cstitle;
1298                 vp >> cstitle;
1299                 pDictionary->SetAtString("Title", PDF_EncodeText(cstitle));
1300                 m_pDocument->SetChangeMark();
1301                 return TRUE;
1302         }
1303 }
1304
1305 FX_BOOL Document::numPages(OBJ_PROP_PARAMS)
1306 {
1307         if (vp.IsGetting())
1308         {
1309                 ASSERT(m_pDocument != NULL);
1310                 vp << m_pDocument->GetPageCount();
1311                 return TRUE;
1312         }
1313         else
1314         {
1315                 return FALSE;
1316         }
1317 }
1318
1319 FX_BOOL Document::external(OBJ_PROP_PARAMS)
1320 {
1321         //In Chrome case,should always return true.
1322         vp << TRUE;
1323         return TRUE;
1324 }
1325
1326 FX_BOOL Document::filesize(OBJ_PROP_PARAMS)
1327 {
1328         if (!vp.IsGetting())return FALSE;
1329
1330         ASSERT(m_pDocument != NULL);
1331
1332 //      CFile file(m_pDocument->GetPath(), CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone);
1333 //      vp << (double)file.GetLength();
1334 //      file.Close();
1335
1336         if ( m_pDocument->GetPath().IsEmpty() == FALSE)
1337         {
1338                 CFX_ByteString bsStr = CFX_ByteString::FromUnicode( m_pDocument->GetPath() );
1339                 FILE * pFile = NULL;
1340                 pFile = fopen( bsStr.GetBuffer( bsStr.GetLength() ), "rb" );
1341                 if ( pFile )
1342                 {
1343                         fseek( pFile, 0, SEEK_END );
1344                         long lSize = ftell( pFile );
1345                         fclose( pFile );
1346                         pFile = NULL;
1347
1348                         vp << (FX_INT32)(lSize);
1349                         return TRUE;
1350                 }
1351         }
1352
1353         vp << 0;
1354         return TRUE;
1355 }
1356
1357 FX_BOOL Document::mouseX(OBJ_PROP_PARAMS)
1358 {
1359         return TRUE;    
1360 }
1361
1362 FX_BOOL Document::mouseY(OBJ_PROP_PARAMS)
1363 {
1364         return TRUE;
1365 }
1366
1367 FX_BOOL Document::baseURL(OBJ_PROP_PARAMS)
1368 {
1369         if (vp.IsGetting())
1370         {
1371                 vp << m_cwBaseURL;
1372                 return TRUE;
1373         }
1374         else
1375         {
1376                 vp >> m_cwBaseURL;
1377                 return TRUE;
1378         }
1379 }
1380
1381 FX_BOOL Document::calculate(OBJ_PROP_PARAMS)
1382 {
1383         ASSERT(m_pDocument != NULL);
1384
1385         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
1386         ASSERT(pInterForm != NULL);
1387
1388         if (vp.IsGetting())
1389         {
1390                 if (pInterForm->IsCalculateEnabled())
1391                         vp << true;
1392                 else
1393                         vp << false;
1394         }
1395         else
1396         {
1397                 bool bCalculate;
1398                 vp >> bCalculate;
1399
1400                 pInterForm->EnableCalculate(bCalculate);
1401         }
1402
1403         return TRUE;
1404 }
1405
1406 FX_BOOL Document::documentFileName(OBJ_PROP_PARAMS)
1407 {
1408         if (!vp.IsGetting())
1409                 return FALSE;
1410
1411         CFX_WideString wsFilePath = m_pDocument->GetPath();
1412
1413         FX_INT32 i = wsFilePath.GetLength() - 1;
1414         for ( ; i >= 0; i-- )
1415         {
1416                 if ( wsFilePath.GetAt( i ) == L'\\' || wsFilePath.GetAt( i ) == L'/' )
1417                         break;
1418         }
1419         if ( i >= 0 && i < wsFilePath.GetLength() - 1 )
1420         {
1421                 vp << ( wsFilePath.GetBuffer( wsFilePath.GetLength() ) + i + 1 );
1422         }else{
1423                 vp << L"";
1424         }
1425         return TRUE;
1426 }
1427
1428 CFX_WideString Document::ReversalStr(CFX_WideString cbFrom)
1429 {
1430         size_t iLength = cbFrom.GetLength();
1431         base::CheckedNumeric<size_t> iSize = sizeof(wchar_t);
1432         iSize *= (iLength + 1);
1433         wchar_t* pResult = (wchar_t*)malloc(iSize.ValueOrDie());
1434         wchar_t* pFrom = (wchar_t*)cbFrom.GetBuffer(iLength);
1435
1436         for (size_t i = 0; i < iLength; i++)
1437         {
1438                 pResult[i] = *(pFrom + iLength - i - 1);
1439         }
1440         pResult[iLength] = L'\0';
1441
1442         cbFrom.ReleaseBuffer();
1443         CFX_WideString cbRet = CFX_WideString(pResult);
1444         free(pResult);
1445         pResult = NULL;
1446         return cbRet;
1447 }
1448
1449 CFX_WideString Document::CutString(CFX_WideString cbFrom)
1450 {
1451         size_t iLength = cbFrom.GetLength();
1452         base::CheckedNumeric<size_t> iSize = sizeof(wchar_t);
1453         iSize *= (iLength + 1);
1454         wchar_t* pResult = (wchar_t*)malloc(iSize.ValueOrDie());
1455         wchar_t* pFrom = (wchar_t*)cbFrom.GetBuffer(iLength);
1456
1457         for (int i = 0; i < iLength; i++)
1458         {
1459                 if (pFrom[i] == L'\\' || pFrom[i] == L'/')
1460                 {
1461                         pResult[i] = L'\0';
1462                         break;
1463                 }
1464                 pResult[i] = pFrom[i];
1465         }
1466         pResult[iLength] = L'\0';
1467
1468         cbFrom.ReleaseBuffer();
1469         CFX_WideString cbRet = CFX_WideString(pResult);
1470         free(pResult);
1471         pResult = NULL;
1472         return cbRet;
1473 }
1474
1475 FX_BOOL Document::path(OBJ_PROP_PARAMS)
1476 {
1477         if (!vp.IsGetting()) return FALSE;
1478
1479         vp << app::SysPathToPDFPath(m_pDocument->GetPath());
1480
1481         return TRUE;
1482 }
1483
1484 FX_BOOL Document::pageWindowRect(OBJ_PROP_PARAMS)
1485 {
1486         return TRUE;
1487 }
1488
1489 FX_BOOL Document::layout(OBJ_PROP_PARAMS)
1490 {       
1491         return TRUE;
1492 }
1493
1494 FX_BOOL Document::addLink(OBJ_METHOD_PARAMS)
1495 {
1496         return TRUE;
1497 }
1498
1499 FX_BOOL Document::closeDoc(OBJ_METHOD_PARAMS)
1500 {
1501         ASSERT(m_pDocument != NULL);
1502
1503
1504         
1505         
1506
1507         return TRUE;
1508 }
1509
1510 FX_BOOL Document::getPageBox(OBJ_METHOD_PARAMS)
1511 {
1512         return TRUE;
1513 }
1514
1515
1516 FX_BOOL Document::getAnnot(OBJ_METHOD_PARAMS)
1517 {
1518         return TRUE;
1519 }
1520
1521 FX_BOOL Document::getAnnots(OBJ_METHOD_PARAMS)
1522 {
1523         vRet.SetNull();
1524         return TRUE;
1525 }
1526
1527 FX_BOOL Document::getAnnot3D(OBJ_METHOD_PARAMS)
1528 {
1529         vRet.SetNull();
1530         return TRUE;
1531 }
1532
1533 FX_BOOL Document::getAnnots3D(OBJ_METHOD_PARAMS)
1534 {
1535         vRet = VT_undefined;
1536         return TRUE;
1537 }
1538
1539 FX_BOOL Document::getOCGs(OBJ_METHOD_PARAMS)
1540 {       
1541         return TRUE;
1542 }
1543
1544 FX_BOOL Document::getLinks(OBJ_METHOD_PARAMS)
1545 {
1546         return TRUE;
1547 }
1548
1549 bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect)
1550 {
1551         if (rect.left <= LinkRect.left
1552           && rect.top <= LinkRect.top
1553           && rect.right >= LinkRect.right
1554           && rect.bottom >= LinkRect.bottom)
1555                 return true;
1556         else
1557                 return false;
1558 }
1559
1560 void IconTree::InsertIconElement(IconElement* pNewIcon)
1561 {
1562         if (!pNewIcon)return;
1563
1564         if (m_pHead == NULL && m_pEnd == NULL)
1565         {
1566                 m_pHead = m_pEnd = pNewIcon;
1567                 m_iLength++;
1568         }
1569         else
1570         {
1571                 m_pEnd->NextIcon = pNewIcon;
1572                 m_pEnd = pNewIcon;
1573                 m_iLength++;
1574         }
1575 }
1576
1577 void IconTree::DeleteIconTree()
1578 {
1579         if (!m_pHead || !m_pEnd)return;
1580         
1581         IconElement* pTemp = NULL;
1582         while(m_pEnd != m_pHead)
1583         {
1584                 pTemp = m_pHead;
1585                 m_pHead = m_pHead->NextIcon;
1586                 delete pTemp;
1587         }
1588
1589         delete m_pEnd;
1590         m_pHead = NULL;
1591         m_pEnd = NULL;
1592 }
1593
1594 int IconTree::GetLength()
1595 {
1596         return m_iLength;
1597 }
1598
1599 IconElement* IconTree::operator [](int iIndex)
1600 {
1601         if (iIndex >= 0 && iIndex <= m_iLength)
1602         {
1603                 IconElement* pTemp = m_pHead;
1604                 for (int i = 0; i < iIndex; i++)
1605                 {
1606                         pTemp = pTemp->NextIcon;
1607                 }
1608                 return pTemp;
1609         }
1610         else
1611                 return NULL;
1612 }
1613
1614 void IconTree::DeleteIconElement(CFX_WideString swIconName)
1615 {
1616         IconElement* pTemp = m_pHead;
1617         int iLoopCount = m_iLength; 
1618         for (int i = 0; i < iLoopCount - 1; i++)
1619         {
1620                 if (pTemp == m_pEnd)
1621                         break;
1622         
1623                 if (m_pHead->IconName == swIconName)
1624                 {
1625                         m_pHead = m_pHead->NextIcon;
1626                         delete pTemp;
1627                         m_iLength--;
1628                         pTemp = m_pHead;
1629                 }
1630                 if (pTemp->NextIcon->IconName == swIconName)
1631                 {
1632                         if (pTemp->NextIcon == m_pEnd)
1633                         {
1634                                 m_pEnd = pTemp;
1635                                 delete pTemp->NextIcon;
1636                                 m_iLength--;
1637                                 pTemp->NextIcon = NULL;
1638                         }
1639                         else
1640                         {
1641                                 IconElement* pElement = pTemp->NextIcon;
1642                                 pTemp->NextIcon = pTemp->NextIcon->NextIcon;
1643                                 delete pElement;
1644                                 m_iLength--;
1645                                 pElement = NULL;
1646                         }
1647
1648                         continue;
1649                 }
1650
1651                 pTemp = pTemp->NextIcon;
1652         }
1653 }
1654
1655 FX_BOOL Document::addIcon(OBJ_METHOD_PARAMS)
1656 {
1657         if (params.size() != 2)return FALSE;
1658
1659         CJS_Context* pContext = (CJS_Context*)cc;
1660         ASSERT(pContext != NULL);
1661         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1662         ASSERT(pRuntime != NULL);
1663
1664         CFX_WideString swIconName = params[0].operator CFX_WideString();
1665         
1666         JSFXObject pJSIcon = (JSFXObject)params[1];
1667         if (JS_GetObjDefnID(pJSIcon) != JS_GetObjDefnID(*pRuntime, L"Icon")) return FALSE;
1668
1669         CJS_EmbedObj* pEmbedObj = ((CJS_Object*)params[1])->GetEmbedObject();
1670         if (!pEmbedObj)return FALSE;
1671         Icon* pIcon = (Icon*)pEmbedObj;
1672
1673         if (!m_pIconTree)
1674                 m_pIconTree = new IconTree();
1675
1676         IconElement* pNewIcon = new IconElement();
1677         pNewIcon->IconName = swIconName;
1678         pNewIcon->NextIcon = NULL;
1679         pNewIcon->IconStream = pIcon;
1680         m_pIconTree->InsertIconElement(pNewIcon);
1681         return TRUE;
1682 }
1683
1684 FX_BOOL Document::icons(OBJ_PROP_PARAMS)
1685 {
1686         if (vp.IsSetting())
1687                 return FALSE;
1688
1689         if (!m_pIconTree)
1690         {
1691                 vp.SetNull();
1692                 return TRUE;
1693         }
1694
1695         CJS_Array Icons(m_isolate);
1696         IconElement* pIconElement = NULL;
1697         int iIconTreeLength = m_pIconTree->GetLength();
1698
1699         CJS_Context* pContext = (CJS_Context *)cc;
1700         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1701
1702         for (int i = 0; i < iIconTreeLength; i++)
1703         {
1704                 pIconElement = (*m_pIconTree)[i];
1705                 
1706                 JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon"));
1707                 if (pObj.IsEmpty()) return FALSE;
1708                                 
1709                 CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(pObj);
1710                 if (!pJS_Icon) return FALSE;
1711
1712                 Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
1713                 if (!pIcon)return FALSE;
1714
1715                 pIcon->SetStream(pIconElement->IconStream->GetStream());
1716                 pIcon->SetIconName(pIconElement->IconName);
1717                 Icons.SetElement(i, CJS_Value(m_isolate,pJS_Icon));
1718         }
1719
1720         vp << Icons;
1721         return TRUE;
1722 }
1723
1724 FX_BOOL Document::getIcon(OBJ_METHOD_PARAMS)
1725 {
1726         if (params.size() != 1)return FALSE;
1727         if(!m_pIconTree)
1728                 return FALSE;
1729         CFX_WideString swIconName = params[0].operator CFX_WideString();
1730         int iIconCounts = m_pIconTree->GetLength();
1731
1732         CJS_Context* pContext = (CJS_Context *)cc;
1733         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1734
1735         for (int i = 0; i < iIconCounts; i++)
1736         {
1737                 if ((*m_pIconTree)[i]->IconName == swIconName)
1738                 {
1739                         Icon* pRetIcon = (*m_pIconTree)[i]->IconStream;
1740                                 
1741                         JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon"));
1742                         if (pObj.IsEmpty()) return FALSE;
1743                                         
1744                         CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(pObj);
1745                         if (!pJS_Icon) return FALSE;
1746
1747                         Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
1748                         if (!pIcon)return FALSE;
1749
1750                         pIcon->SetIconName(swIconName);
1751                         pIcon->SetStream(pRetIcon->GetStream());
1752                         vRet = pJS_Icon;
1753                         return TRUE;
1754                 }
1755         }
1756
1757         return FALSE;
1758 }
1759
1760 FX_BOOL Document::removeIcon(OBJ_METHOD_PARAMS)
1761 {
1762         if (params.size() != 1)return FALSE;
1763         if(!m_pIconTree)
1764                 return FALSE;
1765         CFX_WideString swIconName = params[0].operator CFX_WideString();
1766 #ifndef FOXIT_CHROME_BUILD
1767         m_pIconTree->DeleteIconElement(swIconName);
1768 #endif
1769         return TRUE;
1770 }
1771
1772 FX_BOOL Document::createDataObject(OBJ_METHOD_PARAMS)
1773 {
1774         if (IsSafeMode(cc)) return TRUE;
1775         ASSERT(m_pDocument != NULL);
1776
1777         CFX_WideString swName = L"";
1778         CFX_ByteString sbName = "";
1779         CFX_WideString swValue = L"";
1780         CFX_WideString swMIMEType = L"";
1781         CFX_WideString swCryptFilter = L"";
1782         CFX_ByteString sbFileValue = "";
1783         
1784         int iParamSize = params.size();
1785         for (int i = 0; i < iParamSize; i++)
1786         {
1787                 if (i == 0)
1788                         swName = params[0];
1789                 if (i == 1)
1790                         swValue = params[1];
1791                 if (i == 2)
1792                         swMIMEType = params[2];
1793                 if (i == 3)
1794                         swCryptFilter = params[4];
1795         }
1796
1797         FILE* pFile = NULL;
1798
1799         //CFileStatus fileStatus;
1800         const int BUFSIZE = 17;
1801         FX_BYTE buf[BUFSIZE];
1802         FX_BYTE *pBuffer = NULL;
1803         char* pBuf = NULL;
1804         int nFileSize = 0;
1805         sbFileValue = CFX_ByteString::FromUnicode(swValue);
1806         sbName = CFX_ByteString::FromUnicode(swName);
1807         int iBufLength = sbFileValue.GetLength();
1808         pBuf = (char*)malloc(sizeof(char) * iBufLength);
1809         pBuf = sbFileValue.GetBuffer(iBufLength);
1810
1811         if ( NULL == (pFile = FXSYS_fopen( sbName.GetBuffer(sbName.GetLength()), "wb+" )) )
1812         {
1813                 return FALSE;
1814         }
1815
1816         fwrite( pBuf, sizeof(char), iBufLength, pFile );
1817         fclose( pFile );
1818         pFile = NULL;
1819
1820         pFile = FXSYS_fopen( sbName.GetBuffer(sbName.GetLength()), "rb+" );
1821         fseek( pFile, 0, SEEK_END );
1822         nFileSize = ftell( pFile );
1823
1824         pBuffer = new FX_BYTE[nFileSize];
1825         fseek( pFile, 0, SEEK_SET );
1826         size_t s = fread( pBuffer, sizeof(char), nFileSize, pFile );
1827         if(s == 0)
1828         {
1829                 delete[] pBuffer;
1830                 return FALSE;
1831         }
1832
1833         CRYPT_MD5Generate(pBuffer, nFileSize, buf);
1834         buf[BUFSIZE - 1] = 0;
1835         CFX_WideString csCheckSum((FX_LPCWSTR)buf, 16);
1836         delete[] pBuffer;
1837
1838         return TRUE;
1839 }
1840
1841 FX_BOOL Document::media(OBJ_PROP_PARAMS)
1842 {
1843         return TRUE;
1844 }
1845
1846 FX_BOOL Document::calculateNow(OBJ_METHOD_PARAMS)
1847 {
1848         ASSERT(m_pDocument != NULL);
1849
1850         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
1851                 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
1852                 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
1853
1854         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
1855         ASSERT(pInterForm != NULL);
1856         pInterForm->OnCalculate();
1857         return TRUE;
1858 }
1859
1860 FX_BOOL Document::Collab(OBJ_PROP_PARAMS)
1861 {
1862         return TRUE;
1863 }
1864
1865 FX_BOOL Document::getPageNthWord(OBJ_METHOD_PARAMS)
1866 {
1867         //if (IsSafeMode(cc)) return TRUE;
1868
1869         ASSERT(m_pDocument != NULL);
1870
1871         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1872
1873         int nPageNo = params.GetSize() > 0 ? (int)params[0] : 0;
1874         int nWordNo = params.GetSize() > 1 ? (int)params[1] : 0;
1875         bool bStrip = params.GetSize() > 2 ? (bool)params[2] : true;
1876
1877         CPDF_Document* pDocument = m_pDocument->GetDocument();
1878         if (!pDocument) return FALSE;
1879
1880         if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
1881         {
1882                 //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
1883                 return FALSE;
1884         }
1885
1886         CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
1887         if (!pPageDict) return FALSE;
1888
1889         CPDF_Page page;
1890         page.Load(pDocument, pPageDict);
1891         page.StartParse();
1892         page.ParseContent();
1893
1894         FX_POSITION pos = page.GetFirstObjectPosition();
1895
1896         int nWords = 0;
1897
1898         CFX_WideString swRet;
1899
1900         while (pos)
1901         {
1902                 if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
1903                 {
1904                         if (pPageObj->m_Type == PDFPAGE_TEXT)
1905                         {
1906                                 int nObjWords = CountWords((CPDF_TextObject*)pPageObj);
1907
1908                                 if (nWords + nObjWords >= nWordNo)
1909                                 {
1910                                         swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords);
1911                                         break;
1912                                 }
1913
1914                                 nWords += nObjWords;
1915                         }
1916                 }
1917         }
1918
1919         if (bStrip)
1920         {
1921                 swRet.TrimLeft();
1922                 swRet.TrimRight();
1923         }
1924
1925         vRet = swRet;
1926         return TRUE;
1927 }
1928
1929 FX_BOOL Document::getPageNthWordQuads(OBJ_METHOD_PARAMS)
1930 {
1931         //if (IsSafeMode(cc)) return TRUE;
1932
1933         ASSERT(m_pDocument != NULL);
1934
1935         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1936
1937         return FALSE;
1938 }
1939
1940 FX_BOOL Document::getPageNumWords(OBJ_METHOD_PARAMS)
1941 {
1942         ASSERT(m_pDocument != NULL);
1943
1944         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1945
1946         int nPageNo = params.GetSize() > 0 ? (int)params[0] : 0;
1947
1948         CPDF_Document* pDocument = m_pDocument->GetDocument();
1949         ASSERT(pDocument != NULL);
1950
1951         if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
1952         {
1953                 //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
1954                 return FALSE;
1955         }
1956
1957         CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
1958         if (!pPageDict) return FALSE;
1959
1960         CPDF_Page page;
1961         page.Load(pDocument, pPageDict);
1962         page.StartParse();
1963         page.ParseContent();
1964
1965         FX_POSITION pos = page.GetFirstObjectPosition();
1966
1967         int nWords = 0;
1968
1969         while (pos)
1970         {
1971                 if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
1972                 {
1973                         if (pPageObj->m_Type == PDFPAGE_TEXT)
1974                         {
1975                                 CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj;
1976                                 nWords += CountWords(pTextObj);
1977                         }
1978                 }
1979         }
1980
1981         vRet = nWords;
1982
1983         return TRUE;
1984 }
1985
1986 FX_BOOL Document::getPrintParams(OBJ_METHOD_PARAMS)
1987 {
1988         CJS_Context* pContext = (CJS_Context*)cc;
1989         ASSERT(pContext != NULL);
1990         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1991         ASSERT(pRuntime != NULL);
1992         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"PrintParamsObj"));
1993         //not implemented yet.
1994         vRet = pRetObj;
1995
1996         return TRUE;
1997 }
1998
1999 #define ISLATINWORD(u)  (u != 0x20 && u <= 0x28FF)
2000
2001 int     Document::CountWords(CPDF_TextObject* pTextObj)
2002 {
2003         if (!pTextObj) return 0;
2004
2005         int nWords = 0;
2006
2007         CPDF_Font* pFont = pTextObj->GetFont();
2008         if (!pFont) return 0;
2009
2010         FX_BOOL bIsLatin = FALSE;
2011
2012         for (int i=0, sz=pTextObj->CountChars(); i<sz; i++)
2013         {
2014                 FX_DWORD charcode = -1;
2015                 FX_FLOAT kerning;
2016
2017                 pTextObj->GetCharInfo(i, charcode, kerning);
2018                 CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
2019
2020                 FX_WORD unicode = 0;
2021                 if (swUnicode.GetLength() > 0)
2022                         unicode = swUnicode[0];
2023
2024                 if (ISLATINWORD(unicode) && bIsLatin)
2025                         continue;
2026                 
2027                 bIsLatin = ISLATINWORD(unicode);
2028                 if (unicode != 0x20)
2029                         nWords++;
2030         }
2031
2032         return nWords;
2033 }
2034
2035 CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex)
2036 {
2037         ASSERT(pTextObj != NULL);
2038
2039         CFX_WideString swRet;
2040
2041         CPDF_Font* pFont = pTextObj->GetFont();
2042         if (!pFont) return L"";
2043
2044         int nWords = 0;
2045         FX_BOOL bIsLatin = FALSE;
2046
2047         for (int i=0, sz=pTextObj->CountChars(); i<sz; i++)
2048         {
2049                 FX_DWORD charcode = -1;
2050                 FX_FLOAT kerning;
2051
2052                 pTextObj->GetCharInfo(i, charcode, kerning);
2053                 CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
2054
2055                 FX_WORD unicode = 0;
2056                 if (swUnicode.GetLength() > 0)
2057                         unicode = swUnicode[0];
2058
2059                 if (ISLATINWORD(unicode) && bIsLatin)
2060                 {
2061                 }
2062                 else
2063                 {               
2064                         bIsLatin = ISLATINWORD(unicode);
2065                         if (unicode != 0x20)
2066                                 nWords++;       
2067                 }
2068
2069                 if (nWords-1 == nWordIndex)
2070                         swRet += unicode;
2071         }
2072
2073         return swRet;
2074 }
2075
2076 FX_BOOL Document::zoom(OBJ_PROP_PARAMS)
2077 {
2078
2079         return TRUE;
2080 }
2081
2082 /**
2083 (none,  NoVary)
2084 (fitP,  FitPage)
2085 (fitW,  FitWidth)
2086 (fitH,  FitHeight)
2087 (fitV,  FitVisibleWidth)
2088 (pref,  Preferred)
2089 (refW,  ReflowWidth)
2090 */
2091
2092 FX_BOOL Document::zoomType(OBJ_PROP_PARAMS)
2093 {
2094         return TRUE;
2095 }
2096
2097 FX_BOOL Document::deletePages(OBJ_METHOD_PARAMS)
2098 {
2099         
2100
2101         
2102         
2103
2104
2105         v8::Isolate* isolate = GetIsolate(cc);
2106 //      if (pEnv->GetAppName().Compare(PHANTOM) != 0)
2107 //              return TRUE;
2108
2109         //if (IsSafeMode(cc)) return TRUE;
2110
2111         ASSERT(m_pDocument != NULL);
2112
2113         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
2114                 m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE;
2115
2116         int iSize = params.size();
2117         
2118         int nStart = 0;
2119         int nEnd = 0;
2120         
2121         if (iSize < 1)
2122         {
2123         }
2124         else if (iSize == 1)
2125         {
2126                 if (params[0].GetType() == VT_object)
2127                 {
2128                         JSObject  pObj = (JSObject )params[0];
2129                         v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
2130                                 nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2131
2132                         pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
2133                                 nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2134                 }
2135                 else
2136                 {
2137                         nStart = (int)params[0];
2138                 }
2139         }
2140         else
2141         {
2142                 nStart = (int)params[0];
2143                 nEnd = (int)params[1];
2144         }
2145
2146         int nTotal = m_pDocument->GetPageCount();
2147
2148         if (nStart < 0) nStart = 0;
2149         if (nStart >= nTotal) nStart = nTotal - 1;
2150
2151         if (nEnd < 0) nEnd = 0;
2152         if (nEnd >= nTotal) nEnd = nTotal - 1;
2153
2154         if (nEnd < nStart) nEnd = nStart;
2155
2156         
2157
2158 #ifndef FOXIT_CHROME_BUILD
2159         return m_pDocument->DeletePages(nStart, nEnd - nStart + 1);
2160 #else
2161         return TRUE;
2162 #endif
2163 }
2164
2165 FX_BOOL Document::extractPages(OBJ_METHOD_PARAMS)
2166 {
2167         
2168
2169         
2170         
2171         
2172
2173         v8::Isolate* isolate = GetIsolate(cc);
2174
2175         if (IsSafeMode(cc)) return TRUE;
2176
2177         ASSERT(m_pDocument != NULL);
2178
2179         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT)) return FALSE;
2180
2181         int iSize = params.size();
2182         
2183         int nTotal = m_pDocument->GetPageCount();
2184         int nStart = 0;
2185         int nEnd = nTotal - 1;
2186
2187         CFX_WideString swFilePath;
2188         
2189         if (iSize < 1)
2190         {
2191         }
2192         else if (iSize == 1)
2193         {
2194                 if (params[0].GetType() == VT_object)
2195                 {
2196                         JSObject  pObj = (JSObject )params[0];
2197                         v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
2198                                 nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2199
2200                         pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
2201                                 nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2202
2203                         pValue = JS_GetObjectElement(isolate,pObj, L"cPath");
2204                                 swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
2205                 }
2206                 else
2207                 {
2208                         nStart = (int)params[0];
2209                 }
2210         }
2211         else if (iSize == 2)
2212         {
2213                 nStart = (int)params[0];
2214                 nEnd = (int)params[1];
2215         }
2216         else
2217         {
2218                 nStart = (int)params[0];
2219                 nEnd = (int)params[1];
2220                 swFilePath = params[2].operator CFX_WideString();
2221         }
2222
2223         if (nEnd < nStart)
2224                 nEnd = nStart;
2225
2226         CPDF_Document *pNewDoc = new CPDF_Document;
2227         pNewDoc->CreateNewDoc();        
2228
2229         CFX_WordArray array;
2230         for (int i=nStart; i<=nEnd; i++)
2231                 array.Add(i);
2232
2233 //      m_pDocument->ExtractPages(array, pNewDoc);
2234
2235         if (swFilePath.IsEmpty())
2236         {
2237
2238         }
2239         else
2240         {
2241                 swFilePath = app::PDFPathToSysPath(swFilePath);
2242                 CPDF_Creator PDFCreater(pNewDoc);
2243                 PDFCreater.Create(swFilePath);
2244                 delete pNewDoc;
2245 //              pEnv->OpenDocument(swFilePath);
2246                 vRet.SetNull();
2247         }
2248
2249         return TRUE;
2250 }
2251
2252 FX_BOOL Document::insertPages(OBJ_METHOD_PARAMS)
2253 {
2254
2255
2256         
2257
2258
2259
2260         v8::Isolate* isolate = GetIsolate(cc);
2261
2262         if (IsSafeMode(cc)) return TRUE;
2263
2264         ASSERT(m_pDocument != NULL);
2265
2266         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
2267                 m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE;
2268
2269         int iSize = params.size();
2270         
2271         int nStart = 0;
2272         int nEnd = 0;
2273         int nPage = 0;
2274
2275         CFX_WideString swFilePath;
2276         
2277         if (iSize < 1)
2278         {
2279         }
2280         else if (iSize == 1)
2281         {
2282                 if (params[0].GetType() == VT_object)
2283                 {
2284                         JSObject  pObj = (JSObject )params[0];
2285
2286                         v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nPage");
2287                                 nPage = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2288
2289                         pValue = JS_GetObjectElement(isolate,pObj, L"cPath");
2290                                 swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
2291
2292                         pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
2293                                 nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2294
2295                         pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
2296                                 nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2297                 }
2298                 else
2299                 {
2300                         nPage = (int)params[0];
2301                 }
2302         }
2303         else 
2304         {
2305                 nPage = (int)params[0];
2306
2307                 if (iSize >= 2)
2308                         swFilePath = params[1].operator CFX_WideString();
2309
2310                 if (iSize >= 3)
2311                         nStart = (int)params[2];
2312
2313                 if (iSize >= 4)
2314                         nEnd = (int)params[3];
2315         }
2316
2317         nPage++;
2318
2319         if (nPage < 0)
2320                 nPage = 0;
2321
2322         if (nPage > m_pDocument->GetPageCount())
2323                 nPage = m_pDocument->GetPageCount();
2324
2325         if (swFilePath.IsEmpty()) return FALSE;
2326
2327         swFilePath = app::PDFPathToSysPath(swFilePath);
2328
2329         CPDF_Parser pdfParser;
2330         pdfParser.StartParse(swFilePath, FALSE);
2331         CPDF_Document* pSrcDoc = pdfParser.GetDocument();
2332
2333         if (!pSrcDoc) 
2334         {
2335                 pdfParser.CloseParser();
2336                 return FALSE;
2337         }
2338
2339         int nTotal = pSrcDoc->GetPageCount();
2340
2341         if (nStart < 0) nStart = 0;
2342         if (nStart >= nTotal) nStart = nTotal - 1;
2343
2344         if (nEnd < 0) nEnd = 0;
2345         if (nEnd >= nTotal) nEnd = nTotal - 1;
2346
2347         if (nEnd < nStart) nEnd = nStart;
2348
2349         CFX_WordArray array;
2350         for (int i=nStart; i<=nEnd; i++)
2351                 array.Add(i);
2352
2353 //      m_pDocument->InsertPages(nPage, pSrcDoc, array);
2354
2355         pdfParser.CloseParser();
2356
2357         return TRUE;
2358 }
2359
2360 FX_BOOL Document::replacePages(OBJ_METHOD_PARAMS)
2361 {
2362
2363
2364         
2365
2366
2367
2368         v8::Isolate* isolate = GetIsolate(cc);
2369
2370         if (IsSafeMode(cc)) return TRUE;
2371
2372         ASSERT(m_pDocument != NULL);
2373
2374         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
2375                 m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE;
2376
2377         int iSize = params.size();
2378         
2379         int nStart = -1;
2380         int nEnd = -1;
2381         int nPage = 0;
2382
2383         CFX_WideString swFilePath;
2384         
2385         if (iSize < 1)
2386         {
2387         }
2388         else if (iSize == 1)
2389         {
2390                 if (params[0].GetType() == VT_object)
2391                 {
2392                         JSObject  pObj = (JSObject )params[0];
2393
2394                         v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nPage");
2395                                 nPage = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2396
2397                         pValue = JS_GetObjectElement(isolate,pObj, L"cPath");
2398                                 swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
2399
2400                         pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
2401                                 nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2402
2403                         pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
2404                                 nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2405                 }
2406                 else
2407                 {
2408                         nPage = (int)params[0];
2409                 }
2410         }
2411         else 
2412         {
2413                 nPage = (int)params[0];
2414
2415                 if (iSize >= 2)
2416                         swFilePath = params[1].operator CFX_WideString();
2417
2418                 if (iSize >= 3)
2419                         nStart = (int)params[2];
2420
2421                 if (iSize >= 4)
2422                         nEnd = (int)params[3];
2423         }
2424
2425         if (nPage < 0)
2426                 nPage = 0;
2427
2428         if (nPage >= m_pDocument->GetPageCount())
2429                 nPage = m_pDocument->GetPageCount() - 1;
2430
2431         if (swFilePath.IsEmpty()) return FALSE;
2432
2433         swFilePath = app::PDFPathToSysPath(swFilePath);
2434
2435         CPDF_Parser pdfParser;
2436         pdfParser.StartParse(swFilePath, FALSE);
2437         CPDF_Document* pSrcDoc = pdfParser.GetDocument();
2438
2439         if (!pSrcDoc) 
2440         {
2441                 pdfParser.CloseParser();
2442                 return FALSE;
2443         }
2444
2445         int nTotal = pSrcDoc->GetPageCount();
2446
2447         if (nStart < 0)
2448         {
2449                 if (nEnd < 0)
2450                 {
2451                         nStart = 0;
2452                         nEnd = nTotal - 1;
2453                 }
2454                 else
2455                 {
2456                         nStart = 0;
2457                 }
2458         }
2459         else
2460         {
2461                 if (nEnd < 0)
2462                 {
2463                         nEnd = nStart;
2464                 }
2465                 else
2466                 {
2467                         if (nStart >= nTotal) nStart = nTotal - 1;
2468                         if (nEnd >= nTotal) nEnd = nTotal - 1;
2469
2470                         if (nEnd < nStart) nEnd = nStart;
2471                 }
2472         }
2473
2474         CFX_WordArray array;
2475         for (int i=nStart; i<=nEnd; i++)
2476                 array.Add(i);
2477
2478 //      m_pDocument->ReplacePages(nPage, pSrcDoc, array);
2479
2480         pdfParser.CloseParser();
2481
2482         return TRUE;
2483 }
2484
2485 FX_BOOL Document::getURL(OBJ_METHOD_PARAMS)
2486 {
2487         if (IsSafeMode(cc)) return TRUE;
2488
2489         return TRUE;
2490 }
2491
2492 void Document::AddDelayData(CJS_DelayData* pData)
2493 {
2494         m_DelayData.Add(pData);
2495 }
2496
2497 void Document::DoFieldDelay(const CFX_WideString& sFieldName, int nControlIndex)
2498 {
2499         CFX_DWordArray DelArray;
2500
2501         for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++)
2502         {
2503                 if (CJS_DelayData* pData = m_DelayData.GetAt(i))
2504                 {
2505                         if (pData->sFieldName == sFieldName && pData->nControlIndex == nControlIndex)
2506                         {
2507                                 Field::DoDelay(m_pDocument, pData);
2508                                 delete pData;
2509                                 m_DelayData.SetAt(i, NULL);
2510                                 DelArray.Add(i);
2511                         }
2512                 }
2513         }
2514
2515         for (int j=DelArray.GetSize()-1; j>=0; j--)
2516         {
2517                 m_DelayData.RemoveAt(DelArray[j]);
2518         }
2519 }
2520
2521 void Document::AddDelayAnnotData(CJS_AnnotObj *pData)
2522 {
2523         m_DelayAnnotData.Add(pData);
2524 }
2525
2526 void Document::DoAnnotDelay()
2527 {
2528         CFX_DWordArray DelArray;
2529         
2530         for (int j=DelArray.GetSize()-1; j>=0; j--)
2531         {
2532                 m_DelayData.RemoveAt(DelArray[j]);
2533         }
2534 }