Add namespace and-re-arrange PDFium's local copy of chromium /base.
[pdfium.git] / fpdfsdk / src / javascript / Document.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4  
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../include/javascript/JavaScript.h"
8 #include "../../include/javascript/IJavaScript.h"
9 #include "../../include/javascript/JS_Define.h"
10 #include "../../include/javascript/JS_Object.h"
11 #include "../../include/javascript/JS_Value.h"
12 #include "../../include/javascript/Document.h"
13 #include "../../include/javascript/JS_EventHandler.h"
14 #include "../../include/javascript/JS_Context.h"
15 #include "../../include/javascript/JS_Runtime.h"
16 #include "../../include/javascript/app.h"
17 #include "../../include/javascript/Field.h"
18 #include "../../include/javascript/Icon.h"
19 #include "../../include/javascript/Field.h"
20
21 #include "../../../third_party/base/numerics/safe_math.h"
22
23 static v8::Isolate* GetIsolate(IFXJS_Context* cc)
24 {
25         CJS_Context* pContext = (CJS_Context *)cc;
26         ASSERT(pContext != NULL);
27
28         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
29         ASSERT(pRuntime != NULL);
30
31         return pRuntime->GetIsolate();
32 }
33
34 BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj)
35 END_JS_STATIC_CONST()
36
37 BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj)
38 END_JS_STATIC_PROP()
39
40 BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj)
41 END_JS_STATIC_METHOD()
42
43 IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj)
44
45 PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject)
46 : CJS_EmbedObj(pJSObject)
47 {
48         bUI = TRUE;
49         nStart = 0;
50         nEnd = 0;
51         bSilent = FALSE;
52         bShrinkToFit = FALSE;
53         bPrintAsImage = FALSE;
54         bReverse = FALSE;
55         bAnnotations = TRUE;
56 }
57
58 /* ---------------------- Document ---------------------- */
59
60 #define MINWIDTH  5.0f
61 #define MINHEIGHT 5.0f
62
63 BEGIN_JS_STATIC_CONST(CJS_Document)
64 END_JS_STATIC_CONST()
65
66 BEGIN_JS_STATIC_PROP(CJS_Document)
67         JS_STATIC_PROP_ENTRY(ADBE)
68         JS_STATIC_PROP_ENTRY(author)
69         JS_STATIC_PROP_ENTRY(baseURL)
70         JS_STATIC_PROP_ENTRY(bookmarkRoot)
71         JS_STATIC_PROP_ENTRY(calculate)
72         JS_STATIC_PROP_ENTRY(Collab)
73         JS_STATIC_PROP_ENTRY(creationDate)
74         JS_STATIC_PROP_ENTRY(creator)
75         JS_STATIC_PROP_ENTRY(delay)
76         JS_STATIC_PROP_ENTRY(dirty)
77         JS_STATIC_PROP_ENTRY(documentFileName)
78         JS_STATIC_PROP_ENTRY(external)
79         JS_STATIC_PROP_ENTRY(filesize)
80         JS_STATIC_PROP_ENTRY(icons)
81         JS_STATIC_PROP_ENTRY(info)   
82         JS_STATIC_PROP_ENTRY(keywords)
83         JS_STATIC_PROP_ENTRY(layout)
84         JS_STATIC_PROP_ENTRY(media)
85         JS_STATIC_PROP_ENTRY(modDate)
86         JS_STATIC_PROP_ENTRY(mouseX)
87         JS_STATIC_PROP_ENTRY(mouseY)
88         JS_STATIC_PROP_ENTRY(numFields)
89         JS_STATIC_PROP_ENTRY(numPages)
90         JS_STATIC_PROP_ENTRY(pageNum)   
91         JS_STATIC_PROP_ENTRY(pageWindowRect)
92         JS_STATIC_PROP_ENTRY(path)
93         JS_STATIC_PROP_ENTRY(producer)
94         JS_STATIC_PROP_ENTRY(subject)
95         JS_STATIC_PROP_ENTRY(title)
96         JS_STATIC_PROP_ENTRY(zoom)
97         JS_STATIC_PROP_ENTRY(zoomType)
98 END_JS_STATIC_PROP()
99
100 BEGIN_JS_STATIC_METHOD(CJS_Document)
101         JS_STATIC_METHOD_ENTRY(addAnnot,0)
102         JS_STATIC_METHOD_ENTRY(addField, 4)
103         JS_STATIC_METHOD_ENTRY(addLink, 0)
104         JS_STATIC_METHOD_ENTRY(addIcon, 0)
105         JS_STATIC_METHOD_ENTRY(calculateNow, 0)
106         JS_STATIC_METHOD_ENTRY(closeDoc, 0)
107         JS_STATIC_METHOD_ENTRY(createDataObject, 0)
108         JS_STATIC_METHOD_ENTRY(deletePages, 2)
109         JS_STATIC_METHOD_ENTRY(exportAsText, 3)
110         JS_STATIC_METHOD_ENTRY(exportAsFDF, 6)
111         JS_STATIC_METHOD_ENTRY(exportAsXFDF, 5)
112         JS_STATIC_METHOD_ENTRY(extractPages, 3)
113         JS_STATIC_METHOD_ENTRY(getAnnot, 0)
114         JS_STATIC_METHOD_ENTRY(getAnnots, 2)
115         JS_STATIC_METHOD_ENTRY(getAnnot3D, 2)
116         JS_STATIC_METHOD_ENTRY(getAnnots3D, 1)
117         JS_STATIC_METHOD_ENTRY(getField, 1)
118         JS_STATIC_METHOD_ENTRY(getIcon, 0)
119         JS_STATIC_METHOD_ENTRY(getLinks, 0)
120         JS_STATIC_METHOD_ENTRY(getNthFieldName, 1)
121         JS_STATIC_METHOD_ENTRY(getOCGs, 0)
122         JS_STATIC_METHOD_ENTRY(getPageBox, 0)
123         JS_STATIC_METHOD_ENTRY(getPageNthWord, 3)
124         JS_STATIC_METHOD_ENTRY(getPageNthWordQuads, 2)
125         JS_STATIC_METHOD_ENTRY(getPageNumWords, 1)
126         JS_STATIC_METHOD_ENTRY(getPrintParams, 0)
127         JS_STATIC_METHOD_ENTRY(getURL, 2)
128         JS_STATIC_METHOD_ENTRY(importAnFDF, 1)
129         JS_STATIC_METHOD_ENTRY(importAnXFDF, 1)
130         JS_STATIC_METHOD_ENTRY(importTextData, 2)
131         JS_STATIC_METHOD_ENTRY(insertPages, 4)
132         JS_STATIC_METHOD_ENTRY(mailForm, 6)
133         JS_STATIC_METHOD_ENTRY(print, 9)
134         JS_STATIC_METHOD_ENTRY(removeField, 1)
135         JS_STATIC_METHOD_ENTRY(replacePages, 4)
136         JS_STATIC_METHOD_ENTRY(resetForm, 1)
137         JS_STATIC_METHOD_ENTRY(removeIcon, 0)
138         JS_STATIC_METHOD_ENTRY(saveAs, 5)
139         JS_STATIC_METHOD_ENTRY(submitForm, 23)
140         JS_STATIC_METHOD_ENTRY(mailDoc, 0)              
141 END_JS_STATIC_METHOD()
142
143 IMPLEMENT_JS_CLASS(CJS_Document, Document)
144
145 FX_BOOL CJS_Document::InitInstance(IFXJS_Context* cc)
146 {
147         CJS_Context* pContext = (CJS_Context*)cc;
148         ASSERT(pContext != NULL);
149
150         Document* pDoc = (Document*)GetEmbedObject();
151         ASSERT(pDoc != NULL);
152         
153         pDoc->AttachDoc(pContext->GetReaderDocument());
154         pDoc->SetIsolate(pContext->GetJSRuntime()->GetIsolate());
155         return TRUE;
156 };
157
158 /* --------------------------------- Document --------------------------------- */
159
160 Document::Document(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject),
161         m_isolate(NULL),
162         m_pIconTree(NULL),
163         m_pDocument(NULL),
164         m_cwBaseURL(L""),
165         m_bDelay(FALSE)
166 {
167 }
168
169 Document::~Document()
170 {
171         if (m_pIconTree)
172         {
173                 m_pIconTree->DeleteIconTree();
174                 delete m_pIconTree;
175                 m_pIconTree = NULL;
176         }
177         for (int i=0; i<m_DelayData.GetSize(); i++)
178         {
179                 if (CJS_DelayData* pData = m_DelayData.GetAt(i))
180                 {
181                         delete pData;
182                         pData = NULL;
183                         m_DelayData.SetAt(i, NULL);
184                         
185                 }
186         }
187
188         m_DelayData.RemoveAll();
189         m_DelayAnnotData.RemoveAll();
190 }
191
192 //the total number of fileds in document.
193 FX_BOOL Document::numFields(OBJ_PROP_PARAMS)
194 {
195         if (!vp.IsGetting()) return FALSE;
196
197         ASSERT(m_pDocument != NULL);
198
199         CPDFSDK_InterForm *pInterForm = m_pDocument->GetInterForm();
200         ASSERT(pInterForm != NULL);
201
202         CPDF_InterForm *pPDFForm = pInterForm->GetInterForm();
203         ASSERT(pPDFForm != NULL);
204
205         vp << (int)pPDFForm->CountFields();
206
207         return TRUE;
208 }
209
210 FX_BOOL Document::dirty(OBJ_PROP_PARAMS)
211 {
212         ASSERT(m_pDocument != NULL);
213
214         if (vp.IsGetting())
215         {
216                 if (m_pDocument->GetChangeMark())
217                         vp << true;
218                 else
219                         vp << false;
220         }
221         else
222         {
223                 bool bChanged = false;
224
225                 vp >> bChanged;
226
227                 if (bChanged)
228                         m_pDocument->SetChangeMark();
229                 else
230                         m_pDocument->ClearChangeMark();
231         }
232
233         return TRUE;
234 }
235
236 FX_BOOL Document::ADBE(OBJ_PROP_PARAMS)
237 {
238         ASSERT(m_pDocument != NULL);
239
240         if (vp.IsGetting())
241         {
242                 vp.SetNull();
243         }
244         else
245         {
246         }
247
248         return TRUE;
249 }
250
251 FX_BOOL Document::pageNum(OBJ_PROP_PARAMS)
252 {
253         ASSERT(m_pDocument != NULL);
254
255         if (vp.IsGetting())
256         {                       
257                 if (CPDFSDK_PageView* pPageView = m_pDocument->GetCurrentView())
258                 {
259                         vp << pPageView->GetPageIndex();
260                 }
261         }
262         else
263         {               
264                 int iPageCount = m_pDocument->GetPageCount();
265
266                 int iPageNum = 0;
267                 vp >> iPageNum;
268
269                 CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
270                 if(!pEnv)
271                         return FALSE;
272
273                 if (iPageNum >= 0 && iPageNum < iPageCount)
274                 {
275                          pEnv->JS_docgotoPage(iPageNum);
276                 }
277                 else if (iPageNum >= iPageCount)
278                 {
279                          pEnv->JS_docgotoPage(iPageCount-1);
280                 }
281                 else if (iPageNum < 0)
282                 {
283                          pEnv->JS_docgotoPage(0);
284                 }
285         }
286
287         return TRUE;
288 }
289
290 FX_BOOL Document::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj)
291 {
292         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         pdfium::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         pdfium::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         return TRUE;
1767 }
1768
1769 FX_BOOL Document::createDataObject(OBJ_METHOD_PARAMS)
1770 {
1771         if (IsSafeMode(cc)) return TRUE;
1772         ASSERT(m_pDocument != NULL);
1773
1774         CFX_WideString swName = L"";
1775         CFX_ByteString sbName = "";
1776         CFX_WideString swValue = L"";
1777         CFX_WideString swMIMEType = L"";
1778         CFX_WideString swCryptFilter = L"";
1779         CFX_ByteString sbFileValue = "";
1780         
1781         int iParamSize = params.size();
1782         for (int i = 0; i < iParamSize; i++)
1783         {
1784                 if (i == 0)
1785                         swName = params[0];
1786                 if (i == 1)
1787                         swValue = params[1];
1788                 if (i == 2)
1789                         swMIMEType = params[2];
1790                 if (i == 3)
1791                         swCryptFilter = params[4];
1792         }
1793
1794         FILE* pFile = NULL;
1795
1796         //CFileStatus fileStatus;
1797         const int BUFSIZE = 17;
1798         FX_BYTE buf[BUFSIZE];
1799         FX_BYTE *pBuffer = NULL;
1800         char* pBuf = NULL;
1801         int nFileSize = 0;
1802         sbFileValue = CFX_ByteString::FromUnicode(swValue);
1803         sbName = CFX_ByteString::FromUnicode(swName);
1804         int iBufLength = sbFileValue.GetLength();
1805         pBuf = (char*)malloc(sizeof(char) * iBufLength);
1806         pBuf = sbFileValue.GetBuffer(iBufLength);
1807
1808         if ( NULL == (pFile = FXSYS_fopen( sbName.GetBuffer(sbName.GetLength()), "wb+" )) )
1809         {
1810                 return FALSE;
1811         }
1812
1813         fwrite( pBuf, sizeof(char), iBufLength, pFile );
1814         fclose( pFile );
1815         pFile = NULL;
1816
1817         pFile = FXSYS_fopen( sbName.GetBuffer(sbName.GetLength()), "rb+" );
1818         fseek( pFile, 0, SEEK_END );
1819         nFileSize = ftell( pFile );
1820
1821         pBuffer = new FX_BYTE[nFileSize];
1822         fseek( pFile, 0, SEEK_SET );
1823         size_t s = fread( pBuffer, sizeof(char), nFileSize, pFile );
1824         if(s == 0)
1825         {
1826                 delete[] pBuffer;
1827                 return FALSE;
1828         }
1829
1830         CRYPT_MD5Generate(pBuffer, nFileSize, buf);
1831         buf[BUFSIZE - 1] = 0;
1832         CFX_WideString csCheckSum((FX_LPCWSTR)buf, 16);
1833         delete[] pBuffer;
1834
1835         return TRUE;
1836 }
1837
1838 FX_BOOL Document::media(OBJ_PROP_PARAMS)
1839 {
1840         return TRUE;
1841 }
1842
1843 FX_BOOL Document::calculateNow(OBJ_METHOD_PARAMS)
1844 {
1845         ASSERT(m_pDocument != NULL);
1846
1847         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
1848                 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
1849                 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
1850
1851         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
1852         ASSERT(pInterForm != NULL);
1853         pInterForm->OnCalculate();
1854         return TRUE;
1855 }
1856
1857 FX_BOOL Document::Collab(OBJ_PROP_PARAMS)
1858 {
1859         return TRUE;
1860 }
1861
1862 FX_BOOL Document::getPageNthWord(OBJ_METHOD_PARAMS)
1863 {
1864         //if (IsSafeMode(cc)) return TRUE;
1865
1866         ASSERT(m_pDocument != NULL);
1867
1868         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1869
1870         int nPageNo = params.GetSize() > 0 ? (int)params[0] : 0;
1871         int nWordNo = params.GetSize() > 1 ? (int)params[1] : 0;
1872         bool bStrip = params.GetSize() > 2 ? (bool)params[2] : true;
1873
1874         CPDF_Document* pDocument = m_pDocument->GetDocument();
1875         if (!pDocument) return FALSE;
1876
1877         if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
1878         {
1879                 //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
1880                 return FALSE;
1881         }
1882
1883         CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
1884         if (!pPageDict) return FALSE;
1885
1886         CPDF_Page page;
1887         page.Load(pDocument, pPageDict);
1888         page.StartParse();
1889         page.ParseContent();
1890
1891         FX_POSITION pos = page.GetFirstObjectPosition();
1892
1893         int nWords = 0;
1894
1895         CFX_WideString swRet;
1896
1897         while (pos)
1898         {
1899                 if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
1900                 {
1901                         if (pPageObj->m_Type == PDFPAGE_TEXT)
1902                         {
1903                                 int nObjWords = CountWords((CPDF_TextObject*)pPageObj);
1904
1905                                 if (nWords + nObjWords >= nWordNo)
1906                                 {
1907                                         swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords);
1908                                         break;
1909                                 }
1910
1911                                 nWords += nObjWords;
1912                         }
1913                 }
1914         }
1915
1916         if (bStrip)
1917         {
1918                 swRet.TrimLeft();
1919                 swRet.TrimRight();
1920         }
1921
1922         vRet = swRet;
1923         return TRUE;
1924 }
1925
1926 FX_BOOL Document::getPageNthWordQuads(OBJ_METHOD_PARAMS)
1927 {
1928         //if (IsSafeMode(cc)) return TRUE;
1929
1930         ASSERT(m_pDocument != NULL);
1931
1932         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1933
1934         return FALSE;
1935 }
1936
1937 FX_BOOL Document::getPageNumWords(OBJ_METHOD_PARAMS)
1938 {
1939         ASSERT(m_pDocument != NULL);
1940
1941         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1942
1943         int nPageNo = params.GetSize() > 0 ? (int)params[0] : 0;
1944
1945         CPDF_Document* pDocument = m_pDocument->GetDocument();
1946         ASSERT(pDocument != NULL);
1947
1948         if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
1949         {
1950                 //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
1951                 return FALSE;
1952         }
1953
1954         CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
1955         if (!pPageDict) return FALSE;
1956
1957         CPDF_Page page;
1958         page.Load(pDocument, pPageDict);
1959         page.StartParse();
1960         page.ParseContent();
1961
1962         FX_POSITION pos = page.GetFirstObjectPosition();
1963
1964         int nWords = 0;
1965
1966         while (pos)
1967         {
1968                 if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
1969                 {
1970                         if (pPageObj->m_Type == PDFPAGE_TEXT)
1971                         {
1972                                 CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj;
1973                                 nWords += CountWords(pTextObj);
1974                         }
1975                 }
1976         }
1977
1978         vRet = nWords;
1979
1980         return TRUE;
1981 }
1982
1983 FX_BOOL Document::getPrintParams(OBJ_METHOD_PARAMS)
1984 {
1985         CJS_Context* pContext = (CJS_Context*)cc;
1986         ASSERT(pContext != NULL);
1987         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1988         ASSERT(pRuntime != NULL);
1989         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"PrintParamsObj"));
1990         //not implemented yet.
1991         vRet = pRetObj;
1992
1993         return TRUE;
1994 }
1995
1996 #define ISLATINWORD(u)  (u != 0x20 && u <= 0x28FF)
1997
1998 int     Document::CountWords(CPDF_TextObject* pTextObj)
1999 {
2000         if (!pTextObj) return 0;
2001
2002         int nWords = 0;
2003
2004         CPDF_Font* pFont = pTextObj->GetFont();
2005         if (!pFont) return 0;
2006
2007         FX_BOOL bIsLatin = FALSE;
2008
2009         for (int i=0, sz=pTextObj->CountChars(); i<sz; i++)
2010         {
2011                 FX_DWORD charcode = -1;
2012                 FX_FLOAT kerning;
2013
2014                 pTextObj->GetCharInfo(i, charcode, kerning);
2015                 CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
2016
2017                 FX_WORD unicode = 0;
2018                 if (swUnicode.GetLength() > 0)
2019                         unicode = swUnicode[0];
2020
2021                 if (ISLATINWORD(unicode) && bIsLatin)
2022                         continue;
2023                 
2024                 bIsLatin = ISLATINWORD(unicode);
2025                 if (unicode != 0x20)
2026                         nWords++;
2027         }
2028
2029         return nWords;
2030 }
2031
2032 CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex)
2033 {
2034         ASSERT(pTextObj != NULL);
2035
2036         CFX_WideString swRet;
2037
2038         CPDF_Font* pFont = pTextObj->GetFont();
2039         if (!pFont) return L"";
2040
2041         int nWords = 0;
2042         FX_BOOL bIsLatin = FALSE;
2043
2044         for (int i=0, sz=pTextObj->CountChars(); i<sz; i++)
2045         {
2046                 FX_DWORD charcode = -1;
2047                 FX_FLOAT kerning;
2048
2049                 pTextObj->GetCharInfo(i, charcode, kerning);
2050                 CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
2051
2052                 FX_WORD unicode = 0;
2053                 if (swUnicode.GetLength() > 0)
2054                         unicode = swUnicode[0];
2055
2056                 if (ISLATINWORD(unicode) && bIsLatin)
2057                 {
2058                 }
2059                 else
2060                 {               
2061                         bIsLatin = ISLATINWORD(unicode);
2062                         if (unicode != 0x20)
2063                                 nWords++;       
2064                 }
2065
2066                 if (nWords-1 == nWordIndex)
2067                         swRet += unicode;
2068         }
2069
2070         return swRet;
2071 }
2072
2073 FX_BOOL Document::zoom(OBJ_PROP_PARAMS)
2074 {
2075
2076         return TRUE;
2077 }
2078
2079 /**
2080 (none,  NoVary)
2081 (fitP,  FitPage)
2082 (fitW,  FitWidth)
2083 (fitH,  FitHeight)
2084 (fitV,  FitVisibleWidth)
2085 (pref,  Preferred)
2086 (refW,  ReflowWidth)
2087 */
2088
2089 FX_BOOL Document::zoomType(OBJ_PROP_PARAMS)
2090 {
2091         return TRUE;
2092 }
2093
2094 FX_BOOL Document::deletePages(OBJ_METHOD_PARAMS)
2095 {
2096         
2097
2098         
2099         
2100
2101
2102         v8::Isolate* isolate = GetIsolate(cc);
2103 //      if (pEnv->GetAppName().Compare(PHANTOM) != 0)
2104 //              return TRUE;
2105
2106         //if (IsSafeMode(cc)) return TRUE;
2107
2108         ASSERT(m_pDocument != NULL);
2109
2110         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || 
2111                 m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE;
2112
2113         int iSize = params.size();
2114         
2115         int nStart = 0;
2116         int nEnd = 0;
2117         
2118         if (iSize < 1)
2119         {
2120         }
2121         else if (iSize == 1)
2122         {
2123                 if (params[0].GetType() == VT_object)
2124                 {
2125                         JSObject  pObj = (JSObject )params[0];
2126                         v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nStart");
2127                                 nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2128
2129                         pValue = JS_GetObjectElement(isolate,pObj, L"nEnd");
2130                                 nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue));
2131                 }
2132                 else
2133                 {
2134                         nStart = (int)params[0];
2135                 }
2136         }
2137         else
2138         {
2139                 nStart = (int)params[0];
2140                 nEnd = (int)params[1];
2141         }
2142
2143         int nTotal = m_pDocument->GetPageCount();
2144
2145         if (nStart < 0) nStart = 0;
2146         if (nStart >= nTotal) nStart = nTotal - 1;
2147
2148         if (nEnd < 0) nEnd = 0;
2149         if (nEnd >= nTotal) nEnd = nTotal - 1;
2150
2151         if (nEnd < nStart) nEnd = nStart;
2152
2153         
2154
2155         return TRUE;
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 }