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
21static 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
32BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj)
33END_JS_STATIC_CONST()
34
35BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj)
36END_JS_STATIC_PROP()
37
38BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj)
39END_JS_STATIC_METHOD()
40
41IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj)
42
43PrintParamsObj::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
61BEGIN_JS_STATIC_CONST(CJS_Document)
62END_JS_STATIC_CONST()
63
64BEGIN_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)
96END_JS_STATIC_PROP()
97
98BEGIN_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)
139END_JS_STATIC_METHOD()
140
141IMPLEMENT_JS_CLASS(CJS_Document, Document)
142
143FX_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
158Document::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
167Document::~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.
191FX_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
208FX_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
234FX_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
249FX_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
288FX_BOOL Document::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj)
289{
290	return TRUE;
291}
292
293FX_BOOL Document::addAnnot(OBJ_METHOD_PARAMS)
294{
295 	return TRUE;
296}
297
298FX_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
310FX_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
321FX_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
408FX_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
422FX_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
466FX_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
492FX_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
542FX_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
559FX_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
576FX_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
611FX_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
688FX_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
742FX_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
803FX_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
816FX_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
923void Document::AttachDoc(CPDFSDK_Document *pDoc)
924{
925	m_pDocument = pDoc;
926}
927
928CPDFSDK_Document * Document::GetReaderDoc()
929{
930	return m_pDocument;
931}
932
933FX_BOOL Document::ExtractFileName(CPDFSDK_Document *pDoc,CFX_ByteString &strFileName)
934{
935	return FALSE;
936}
937
938FX_BOOL Document::ExtractFolderName(CPDFSDK_Document *pDoc,CFX_ByteString &strFolderName)
939{
940	return FALSE;
941}
942
943FX_BOOL Document::bookmarkRoot(OBJ_PROP_PARAMS)
944{
945	return TRUE;
946}
947
948FX_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
1006FX_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
1030FX_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
1089FX_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
1114FX_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
1138FX_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
1180FX_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
1204FX_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
1228FX_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
1252FX_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
1276FX_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
1303FX_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
1317FX_BOOL Document::external(OBJ_PROP_PARAMS)
1318{
1319	//In Chrome case,should always return true.
1320	vp << TRUE;
1321	return TRUE;
1322}
1323
1324FX_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
1355FX_BOOL Document::mouseX(OBJ_PROP_PARAMS)
1356{
1357 	return TRUE;
1358}
1359
1360FX_BOOL Document::mouseY(OBJ_PROP_PARAMS)
1361{
1362 	return TRUE;
1363}
1364
1365FX_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
1379FX_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
1404FX_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
1426CFX_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
1446CFX_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
1468FX_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
1477FX_BOOL Document::pageWindowRect(OBJ_PROP_PARAMS)
1478{
1479	return TRUE;
1480}
1481
1482FX_BOOL Document::layout(OBJ_PROP_PARAMS)
1483{
1484	return TRUE;
1485}
1486
1487FX_BOOL Document::addLink(OBJ_METHOD_PARAMS)
1488{
1489 	return TRUE;
1490}
1491
1492FX_BOOL Document::closeDoc(OBJ_METHOD_PARAMS)
1493{
1494	ASSERT(m_pDocument != NULL);
1495
1496
1497
1498
1499
1500	return TRUE;
1501}
1502
1503FX_BOOL Document::getPageBox(OBJ_METHOD_PARAMS)
1504{
1505 	return TRUE;
1506}
1507
1508
1509FX_BOOL Document::getAnnot(OBJ_METHOD_PARAMS)
1510{
1511 	return TRUE;
1512}
1513
1514FX_BOOL Document::getAnnots(OBJ_METHOD_PARAMS)
1515{
1516	vRet.SetNull();
1517	return TRUE;
1518}
1519
1520FX_BOOL Document::getAnnot3D(OBJ_METHOD_PARAMS)
1521{
1522	vRet.SetNull();
1523	return TRUE;
1524}
1525
1526FX_BOOL Document::getAnnots3D(OBJ_METHOD_PARAMS)
1527{
1528	vRet = VT_undefined;
1529	return TRUE;
1530}
1531
1532FX_BOOL Document::getOCGs(OBJ_METHOD_PARAMS)
1533{
1534	return TRUE;
1535}
1536
1537FX_BOOL Document::getLinks(OBJ_METHOD_PARAMS)
1538{
1539	return TRUE;
1540}
1541
1542bool 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
1553void 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
1570void 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
1587int IconTree::GetLength()
1588{
1589	return m_iLength;
1590}
1591
1592IconElement* 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
1607void 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
1648FX_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
1677FX_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
1717FX_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
1753FX_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
1765FX_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
1834FX_BOOL Document::media(OBJ_PROP_PARAMS)
1835{
1836	return TRUE;
1837}
1838
1839FX_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
1853FX_BOOL Document::Collab(OBJ_PROP_PARAMS)
1854{
1855	return TRUE;
1856}
1857
1858FX_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
1922FX_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
1933FX_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
1979FX_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
1994int	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
2028CFX_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
2069FX_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
2085FX_BOOL Document::zoomType(OBJ_PROP_PARAMS)
2086{
2087	return TRUE;
2088}
2089
2090FX_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
2158FX_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
2245FX_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
2353FX_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
2478FX_BOOL Document::getURL(OBJ_METHOD_PARAMS)
2479{
2480	if (IsSafeMode(cc)) return TRUE;
2481
2482	return TRUE;
2483}
2484
2485void Document::AddDelayData(CJS_DelayData* pData)
2486{
2487	m_DelayData.Add(pData);
2488}
2489
2490void 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
2514void Document::AddDelayAnnotData(CJS_AnnotObj *pData)
2515{
2516	m_DelayAnnotData.Add(pData);
2517}
2518
2519void 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}
2528