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