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