// Copyright 2014 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../include/javascript/JavaScript.h" #include "../../include/javascript/IJavaScript.h" #include "../../include/javascript/JS_Define.h" #include "../../include/javascript/JS_Object.h" #include "../../include/javascript/JS_Value.h" #include "../../include/javascript/Document.h" #include "../../include/javascript/JS_EventHandler.h" #include "../../include/javascript/JS_Context.h" #include "../../include/javascript/JS_Runtime.h" #include "../../include/javascript/app.h" #include "../../include/javascript/Field.h" #include "../../include/javascript/Icon.h" #include "../../include/javascript/Field.h" static v8::Isolate* GetIsolate(IFXJS_Context* cc) { CJS_Context* pContext = (CJS_Context *)cc; ASSERT(pContext != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); return pRuntime->GetIsolate(); } BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj) END_JS_STATIC_CONST() BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj) END_JS_STATIC_PROP() BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj) END_JS_STATIC_METHOD() IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj) PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) { bUI = TRUE; nStart = 0; nEnd = 0; bSilent = FALSE; bShrinkToFit = FALSE; bPrintAsImage = FALSE; bReverse = FALSE; bAnnotations = TRUE; } /* ---------------------- Document ---------------------- */ #define MINWIDTH 5.0f #define MINHEIGHT 5.0f BEGIN_JS_STATIC_CONST(CJS_Document) END_JS_STATIC_CONST() BEGIN_JS_STATIC_PROP(CJS_Document) JS_STATIC_PROP_ENTRY(ADBE) JS_STATIC_PROP_ENTRY(author) JS_STATIC_PROP_ENTRY(baseURL) JS_STATIC_PROP_ENTRY(bookmarkRoot) JS_STATIC_PROP_ENTRY(calculate) JS_STATIC_PROP_ENTRY(Collab) JS_STATIC_PROP_ENTRY(creationDate) JS_STATIC_PROP_ENTRY(creator) JS_STATIC_PROP_ENTRY(delay) JS_STATIC_PROP_ENTRY(dirty) JS_STATIC_PROP_ENTRY(documentFileName) JS_STATIC_PROP_ENTRY(external) JS_STATIC_PROP_ENTRY(filesize) JS_STATIC_PROP_ENTRY(icons) JS_STATIC_PROP_ENTRY(info) JS_STATIC_PROP_ENTRY(keywords) JS_STATIC_PROP_ENTRY(layout) JS_STATIC_PROP_ENTRY(media) JS_STATIC_PROP_ENTRY(modDate) JS_STATIC_PROP_ENTRY(mouseX) JS_STATIC_PROP_ENTRY(mouseY) JS_STATIC_PROP_ENTRY(numFields) JS_STATIC_PROP_ENTRY(numPages) JS_STATIC_PROP_ENTRY(pageNum) JS_STATIC_PROP_ENTRY(pageWindowRect) JS_STATIC_PROP_ENTRY(path) JS_STATIC_PROP_ENTRY(producer) JS_STATIC_PROP_ENTRY(subject) JS_STATIC_PROP_ENTRY(title) JS_STATIC_PROP_ENTRY(zoom) JS_STATIC_PROP_ENTRY(zoomType) END_JS_STATIC_PROP() BEGIN_JS_STATIC_METHOD(CJS_Document) JS_STATIC_METHOD_ENTRY(addAnnot,0) JS_STATIC_METHOD_ENTRY(addField, 4) JS_STATIC_METHOD_ENTRY(addLink, 0) JS_STATIC_METHOD_ENTRY(addIcon, 0) JS_STATIC_METHOD_ENTRY(calculateNow, 0) JS_STATIC_METHOD_ENTRY(closeDoc, 0) JS_STATIC_METHOD_ENTRY(createDataObject, 0) JS_STATIC_METHOD_ENTRY(deletePages, 2) JS_STATIC_METHOD_ENTRY(exportAsText, 3) JS_STATIC_METHOD_ENTRY(exportAsFDF, 6) JS_STATIC_METHOD_ENTRY(exportAsXFDF, 5) JS_STATIC_METHOD_ENTRY(extractPages, 3) JS_STATIC_METHOD_ENTRY(getAnnot, 0) JS_STATIC_METHOD_ENTRY(getAnnots, 2) JS_STATIC_METHOD_ENTRY(getAnnot3D, 2) JS_STATIC_METHOD_ENTRY(getAnnots3D, 1) JS_STATIC_METHOD_ENTRY(getField, 1) JS_STATIC_METHOD_ENTRY(getIcon, 0) JS_STATIC_METHOD_ENTRY(getLinks, 0) JS_STATIC_METHOD_ENTRY(getNthFieldName, 1) JS_STATIC_METHOD_ENTRY(getOCGs, 0) JS_STATIC_METHOD_ENTRY(getPageBox, 0) JS_STATIC_METHOD_ENTRY(getPageNthWord, 3) JS_STATIC_METHOD_ENTRY(getPageNthWordQuads, 2) JS_STATIC_METHOD_ENTRY(getPageNumWords, 1) JS_STATIC_METHOD_ENTRY(getPrintParams, 0) JS_STATIC_METHOD_ENTRY(getURL, 2) JS_STATIC_METHOD_ENTRY(importAnFDF, 1) JS_STATIC_METHOD_ENTRY(importAnXFDF, 1) JS_STATIC_METHOD_ENTRY(importTextData, 2) JS_STATIC_METHOD_ENTRY(insertPages, 4) JS_STATIC_METHOD_ENTRY(mailForm, 6) JS_STATIC_METHOD_ENTRY(print, 9) JS_STATIC_METHOD_ENTRY(removeField, 1) JS_STATIC_METHOD_ENTRY(replacePages, 4) JS_STATIC_METHOD_ENTRY(resetForm, 1) JS_STATIC_METHOD_ENTRY(removeIcon, 0) JS_STATIC_METHOD_ENTRY(saveAs, 5) JS_STATIC_METHOD_ENTRY(submitForm, 23) JS_STATIC_METHOD_ENTRY(mailDoc, 0) END_JS_STATIC_METHOD() IMPLEMENT_JS_CLASS(CJS_Document, Document) FX_BOOL CJS_Document::InitInstance(IFXJS_Context* cc) { CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); Document* pDoc = (Document*)GetEmbedObject(); ASSERT(pDoc != NULL); pDoc->AttachDoc(pContext->GetReaderDocument()); pDoc->SetIsolate(pContext->GetJSRuntime()->GetIsolate()); return TRUE; }; /* --------------------------------- Document --------------------------------- */ Document::Document(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject), m_cwBaseURL(L""), m_pIconTree(NULL), m_pDocument(NULL), m_bDelay(FALSE), m_isolate(NULL) { } Document::~Document() { if (m_pIconTree) { m_pIconTree->DeleteIconTree(); delete m_pIconTree; m_pIconTree = NULL; } for (int i=0; i<m_DelayData.GetSize(); i++) { if (CJS_DelayData* pData = m_DelayData.GetAt(i)) { delete pData; pData = NULL; m_DelayData.SetAt(i, NULL); } } m_DelayData.RemoveAll(); m_DelayAnnotData.RemoveAll(); } //the total number of fileds in document. FX_BOOL Document::numFields(OBJ_PROP_PARAMS) { if (!vp.IsGetting()) return FALSE; ASSERT(m_pDocument != NULL); CPDFSDK_InterForm *pInterForm = m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm *pPDFForm = pInterForm->GetInterForm(); ASSERT(pPDFForm != NULL); vp << (int)pPDFForm->CountFields(); return TRUE; } FX_BOOL Document::dirty(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); if (vp.IsGetting()) { if (m_pDocument->GetChangeMark()) vp << true; else vp << false; } else { bool bChanged = false; vp >> bChanged; if (bChanged) m_pDocument->SetChangeMark(); else m_pDocument->ClearChangeMark(); } return TRUE; } FX_BOOL Document::ADBE(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); if (vp.IsGetting()) { vp.SetNull(); } else { } return TRUE; } FX_BOOL Document::pageNum(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); if (vp.IsGetting()) { if (CPDFSDK_PageView* pPageView = m_pDocument->GetCurrentView()) { vp << pPageView->GetPageIndex(); } } else { int iPageCount = m_pDocument->GetPageCount(); int iPageNum = 0; vp >> iPageNum; CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); if(!pEnv) return FALSE; if (iPageNum >= 0 && iPageNum < iPageCount) { pEnv->JS_docgotoPage(iPageNum); } else if (iPageNum >= iPageCount) { pEnv->JS_docgotoPage(iPageCount-1); } else if (iPageNum < 0) { pEnv->JS_docgotoPage(0); } } return TRUE; } FX_BOOL Document::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj) { return TRUE; } FX_BOOL Document::addAnnot(OBJ_METHOD_PARAMS) { return TRUE; } FX_BOOL Document::addField(OBJ_METHOD_PARAMS) { //Doesn't support. return TRUE; } //exports form fields as a tab-delimited text file to a local hard disk. //comment: need reader support //note : watch the third parameter:cPath, for what case it can be safely saved? //int CPDFSDK_InterForm::ExportAsText(FX_BOOL bNoPassword,StringArray aFields,String cPath); //return value, int the index of the parameters illegal, the index is based on 1. FX_BOOL Document::exportAsText(OBJ_METHOD_PARAMS) { if (IsSafeMode(cc)) return TRUE; return TRUE; } //exports form fields as a fdf file to the local hard drive //comment: need reader supports //note:the last parameter hasn't been confirmed.because the previous one blocks the way. //int CPDFSDK_Document::ExportAsFDF(FX_BOOL bAllFields,BOOL bNoPassword,StringArray aFields,FX_BOOL bFlags,String cPath,FX_BOOL bAnnotations); FX_BOOL Document::exportAsFDF(OBJ_METHOD_PARAMS) { v8::Isolate* isolate = GetIsolate(cc); if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE; FX_BOOL bAllFields = params.size() > 0 ? (FX_BOOL)params[0] : FALSE; FX_BOOL bNoPassWord = params.size() > 1 ? (FX_BOOL)params[1] : TRUE; FX_BOOL bWhole = params.size() > 2 ? (params[2].GetType() == VT_null) : TRUE; CJS_Array arrayFileds(isolate); if (!bWhole) arrayFileds.Attach(params[2]); //FX_BOOL bFlags = params.size() > 3 ? (FX_BOOL)params[3] : FALSE; CFX_WideString swFilePath = params.size() > 4 ? (FX_LPCWSTR)params[4].operator CFX_WideString() : (FX_LPCWSTR)L""; if (swFilePath.IsEmpty()) { CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); swFilePath = pEnv->JS_fieldBrowse(); if(swFilePath.IsEmpty()) return TRUE; } else { swFilePath = app::PDFPathToSysPath(swFilePath); } m_pDocument->SetFocusAnnot(NULL); CPDFSDK_InterForm* pInterForm= (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); ASSERT(pPDFForm != NULL); CFX_PtrArray aFields; if (bWhole) { for (int j=0,jsz=pPDFForm->CountFields(); j<jsz; j++) { aFields.Add(pPDFForm->GetField(j)); } } else { for (int i=0,isz=arrayFileds.GetLength(); i<isz; i++) { CJS_Value valName(isolate); arrayFileds.GetElement(i,valName); CFX_WideString swName = valName.operator CFX_WideString(); for (int j=0, jsz=pPDFForm->CountFields(swName); j<jsz; j++) { aFields.Add(pPDFForm->GetField(j, swName)); } } } CFX_PtrArray fields; for (int i=0,sz=aFields.GetSize(); i<sz; i++) { CPDF_FormField* pField = (CPDF_FormField*)aFields[i]; if (!bAllFields) if (pField->GetValue() == L"") continue; if (bNoPassWord) if (pField->GetFieldFlags() & 0x2000) continue; fields.Add((void*)pField); } return pInterForm->ExportFieldsToFDFFile(swFilePath, fields, TRUE); } //exports form fields an XFDF file to the local hard drive //comment: need reder supports //note:the last parameter can't be test //int CPDFSDK_Document::ExportAsXFDF(FX_BOOL bAllFields,FX_BOOL bNoPassWord,StringArray aFields,String cPath,FX_BOOL bAnnoatations); FX_BOOL Document::exportAsXFDF(OBJ_METHOD_PARAMS) { if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE; return TRUE; } //Maps a field object in PDF document to a JavaScript variable //comment: //note: the paremter cName, this is clue how to treat if the cName is not a valiable filed name in this document FX_BOOL Document::getField(OBJ_METHOD_PARAMS) { v8::Isolate* isolate = GetIsolate(cc); ASSERT(m_pDocument != NULL); if (params.size() < 1) return FALSE; CFX_WideString wideName = params[0].operator CFX_WideString(); CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); ASSERT(pPDFForm != NULL); if (pPDFForm->CountFields(wideName) <= 0) { vRet.SetNull(); return TRUE; } CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); JSFXObject pFieldObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Field")); CJS_Field * pJSField = (CJS_Field*)JS_GetPrivate(isolate,pFieldObj); ASSERT(pJSField != NULL); Field * pField = (Field *)pJSField->GetEmbedObject(); ASSERT(pField != NULL); pField->AttachField(this, wideName); vRet = pJSField; return TRUE; } //Gets the name of the nth field in the document //comment: //note: the parameter nIndex, if it is not available FX_BOOL Document::getNthFieldName(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); int nIndex = params.size() > 0 ? (int)params[0] : -1; if (nIndex == -1) return FALSE; CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); ASSERT(pPDFForm != NULL); CPDF_FormField* pField = pPDFForm->GetField(nIndex); if (!pField) return FALSE; vRet = pField->GetFullName(); return TRUE; } //imports the specified fdf file. //comments: need reader suppport //note:once the cpath is illigl then a file dialog box pops up in order to ask user to chooose the file //int CPDFSDK_Document::importAnFDF(String cPath); FX_BOOL Document::importAnFDF(OBJ_METHOD_PARAMS) { if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) || m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE; CFX_WideString swPath; if (params.size() > 0) swPath = params[0]; if (swPath.IsEmpty()) { CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); swPath = pEnv->JS_fieldBrowse(); if(swPath.IsEmpty()) return TRUE; } else { swPath = app::PDFPathToSysPath(swPath); } m_pDocument->SetFocusAnnot(NULL); CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); if (!pInterForm->ImportFormFromFDFFile(swPath, TRUE)) return FALSE; m_pDocument->SetChangeMark(); // CPDFDoc_Environment* pEnv = m_pDocument->GetEnv(); // ASSERT(pEnv != NULL); // IUndo* pUndo = IUndo::GetUndo(pEnv); // ASSERT(pUndo != NULL); // pUndo->Reset(m_pDocument); return TRUE; } //imports and specified XFDF file containing XML form data //comment: need reader supports //note: same as up //int CPDFSDK_Document::importAnFDF(String cPath) FX_BOOL Document::importAnXFDF(OBJ_METHOD_PARAMS) { if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) || m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE; return TRUE; } //imports and specified text file //commnet: need reader supports //note: same as up,when nRow is not rational,adobe is dumb for it. //int CPDFSDK_Document::importTextData(String cPath,int nRow); FX_BOOL Document::importTextData(OBJ_METHOD_PARAMS) { if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) || m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE; return TRUE; } //exports the form data and mails the resulting fdf file as an attachment to all recipients. //comment: need reader supports //note: //int CPDFSDK_Document::mailForm(FX_BOOL bUI,String cto,string ccc,string cbcc,string cSubject,string cms); FX_BOOL Document::mailForm(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE; int iLength = params.size(); FX_BOOL bUI = iLength > 0 ? (FX_BOOL)params[0] : TRUE; CFX_WideString cTo = iLength > 1 ? (FX_LPCWSTR)params[1].operator CFX_WideString() : (FX_LPCWSTR)L""; CFX_WideString cCc = iLength > 2 ? (FX_LPCWSTR)params[2].operator CFX_WideString() : (FX_LPCWSTR)L""; CFX_WideString cBcc = iLength > 3 ? (FX_LPCWSTR)params[3].operator CFX_WideString() : (FX_LPCWSTR)L""; CFX_WideString cSubject = iLength > 4 ? (FX_LPCWSTR)params[4].operator CFX_WideString() : (FX_LPCWSTR)L""; CFX_WideString cMsg = iLength > 5 ? (FX_LPCWSTR)params[5].operator CFX_WideString() : (FX_LPCWSTR)L""; CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CFX_ByteTextBuf textBuf; if (!pInterForm->ExportFormToFDFTextBuf(textBuf)) return FALSE; CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); CPDFDoc_Environment* pEnv = pContext->GetReaderApp(); ASSERT(pEnv != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); pRuntime->BeginBlock(); pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg); pRuntime->EndBlock(); return TRUE; } FX_BOOL Document::print(OBJ_METHOD_PARAMS) { CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); FX_BOOL bUI = TRUE; int nStart = 0; int nEnd = 0; FX_BOOL bSilent = FALSE; FX_BOOL bShrinkToFit = FALSE; FX_BOOL bPrintAsImage = FALSE; FX_BOOL bReverse = FALSE; FX_BOOL bAnnotations = FALSE; int nlength = params.size(); if(nlength ==9) { if (params[8].GetType() == VT_fxobject) { JSFXObject pObj = (JSFXObject)params[8]; { if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"PrintParamsObj")) { if (CJS_Object* pJSObj = (CJS_Object*)params[8]) { if (PrintParamsObj* pprintparamsObj = (PrintParamsObj*)pJSObj->GetEmbedObject()) { bUI = pprintparamsObj->bUI; nStart = pprintparamsObj->nStart; nEnd = pprintparamsObj->nEnd; bSilent = pprintparamsObj->bSilent; bShrinkToFit = pprintparamsObj->bShrinkToFit; bPrintAsImage = pprintparamsObj->bPrintAsImage; bReverse = pprintparamsObj->bReverse; bAnnotations = pprintparamsObj->bAnnotations; } } } } } } else { if(nlength >= 1) bUI = params[0]; if(nlength >= 2) nStart = (int)params[1]; if(nlength >= 3) nEnd = (int)params[2]; if(nlength >= 4) bSilent = params[3]; if(nlength >= 5) bShrinkToFit = params[4]; if(nlength >= 6) bPrintAsImage = params[5]; if(nlength >= 7) bReverse = params[6]; if(nlength >= 8) bAnnotations = params[7]; } ASSERT(m_pDocument != NULL); if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv()) { pEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage, bReverse, bAnnotations); return TRUE; } return FALSE; } //removes the specified field from the document. //comment: //note: if the filed name is not retional, adobe is dumb for it. FX_BOOL Document::removeField(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM))) return FALSE; if (params.size() < 1) return TRUE; CFX_WideString sFieldName = params[0].operator CFX_WideString(); CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CFX_PtrArray widgets; pInterForm->GetWidgets(sFieldName, widgets); int nSize = widgets.GetSize(); if (nSize > 0) { for (int i=0; i<nSize; i++) { CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)widgets[i]; ASSERT(pWidget != NULL); CPDF_Rect rcAnnot = pWidget->GetRect(); rcAnnot.left -= 1; rcAnnot.bottom -= 1; rcAnnot.right += 1; rcAnnot.top += 1; CFX_RectArray aRefresh; aRefresh.Add(rcAnnot); CPDF_Page* pPage = pWidget->GetPDFPage(); ASSERT(pPage != NULL); CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage); pPageView->DeleteAnnot(pWidget); pPageView->UpdateRects(aRefresh); } m_pDocument->SetChangeMark(); } return TRUE; } //reset filed values within a document. //comment: //note: if the fields names r not rational, aodbe is dumb for it. FX_BOOL Document::resetForm(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) || m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE; CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); ASSERT(pPDFForm != NULL); v8::Isolate* isolate = GetIsolate(cc); CJS_Array aName(isolate); if (params.size() > 0) { switch (params[0].GetType()) { default: aName.Attach(params[0]); break; case VT_string: aName.SetElement(0,params[0]); break; } CFX_PtrArray aFields; for (int i=0,isz=aName.GetLength(); i<isz; i++) { CJS_Value valElement(isolate); aName.GetElement(i,valElement); CFX_WideString swVal = valElement.operator CFX_WideString(); for (int j=0,jsz=pPDFForm->CountFields(swVal); j<jsz; j++) { aFields.Add((void*)pPDFForm->GetField(j,swVal)); } } if (aFields.GetSize() > 0) { pPDFForm->ResetForm(aFields, TRUE, TRUE); m_pDocument->SetChangeMark(); } } else { pPDFForm->ResetForm(TRUE); m_pDocument->SetChangeMark(); } return TRUE; } FX_BOOL Document::saveAs(OBJ_METHOD_PARAMS) { if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); // m_pDocument->DoSaveAs(); return TRUE; } FX_BOOL Document::submitForm(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); // if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE; int nSize = params.size(); if (nSize < 1) return FALSE; CFX_WideString strURL; FX_BOOL bFDF = TRUE; FX_BOOL bEmpty = FALSE; v8::Isolate* isolate = GetIsolate(cc); CJS_Array aFields(isolate); CJS_Value v = params[0]; if (v.GetType() == VT_string) { strURL = params[0].operator CFX_WideString(); if (nSize > 1) bFDF = params[1]; if (nSize > 2) bEmpty = params[2]; if (nSize > 3) aFields.Attach(params[3]); } else if (v.GetType() == VT_object) { JSObject pObj = (JSObject)params[0]; v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"cURL"); if (!pValue.IsEmpty()) strURL = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"bFDF"); bFDF = CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"bEmpty"); bEmpty = CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj,L"aFields"); aFields.Attach(CJS_Value(isolate,pValue, GET_VALUE_TYPE(pValue))); } CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm(); ASSERT(pPDFInterForm != NULL); FX_BOOL bAll = (aFields.GetLength() == 0); if (bAll && bEmpty) { CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); if (pPDFInterForm->CheckRequiredFields()) { pRuntime->BeginBlock(); pInterForm->SubmitForm(strURL, FALSE); pRuntime->EndBlock(); } return TRUE; } else { CFX_PtrArray fieldObjects; for (int i=0,sz=aFields.GetLength(); i<sz; i++) { CJS_Value valName(isolate); aFields.GetElement(i, valName); CFX_WideString sName = valName.operator CFX_WideString(); CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); ASSERT(pPDFForm != NULL); for (int j=0, jsz=pPDFForm->CountFields(sName); j<jsz; j++) { CPDF_FormField* pField = pPDFForm->GetField(j, sName); if (!bEmpty && pField->GetValue().IsEmpty()) continue; fieldObjects.Add(pField); } } CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); if (pPDFInterForm->CheckRequiredFields(&fieldObjects, TRUE)) { pRuntime->BeginBlock(); pInterForm->SubmitFields(strURL, fieldObjects, TRUE, !bFDF); pRuntime->EndBlock(); } return TRUE; } } ////////////////////////////////////////////////////////////////////////////////////////////// void Document::AttachDoc(CPDFSDK_Document *pDoc) { m_pDocument = pDoc; } CPDFSDK_Document * Document::GetReaderDoc() { return m_pDocument; } FX_BOOL Document::ExtractFileName(CPDFSDK_Document *pDoc,CFX_ByteString &strFileName) { return FALSE; } FX_BOOL Document::ExtractFolderName(CPDFSDK_Document *pDoc,CFX_ByteString &strFolderName) { return FALSE; } FX_BOOL Document::bookmarkRoot(OBJ_PROP_PARAMS) { return TRUE; } FX_BOOL Document::mailDoc(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); FX_BOOL bUI = TRUE; CFX_WideString cTo = L""; CFX_WideString cCc = L""; CFX_WideString cBcc = L""; CFX_WideString cSubject = L""; CFX_WideString cMsg = L""; bUI = params.size()>=1?static_cast<FX_BOOL>(params[0]):TRUE; cTo = params.size()>=2?(const wchar_t*)params[1].operator CFX_WideString():L""; cCc = params.size()>=3?(const wchar_t*)params[2].operator CFX_WideString():L""; cBcc = params.size()>=4?(const wchar_t*)params[3].operator CFX_WideString():L""; cSubject = params.size()>=5?(const wchar_t*)params[4].operator CFX_WideString():L""; cMsg = params.size()>=6?(const wchar_t*)params[5].operator CFX_WideString():L""; v8::Isolate* isolate = GetIsolate(cc); if(params.size()>=1 && params[0].GetType() == VT_object) { JSObject pObj = (JSObject )params[0]; v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI"); bUI = (int)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"cTo"); cTo = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString(); pValue = JS_GetObjectElement(isolate,pObj, L"cCc"); cCc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString(); pValue = JS_GetObjectElement(isolate,pObj, L"cBcc"); cBcc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString(); pValue = JS_GetObjectElement(isolate,pObj, L"cSubject"); cSubject = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString(); pValue = JS_GetObjectElement(isolate,pObj, L"cMsg"); cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString(); } CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); pRuntime->BeginBlock(); CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp(); pEnv->JS_docmailForm(NULL, 0, bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg); pRuntime->EndBlock(); return TRUE; } FX_BOOL Document::author(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; if (vp.IsGetting()) { vp << pDictionary->GetUnicodeText("Author"); return TRUE; } else { if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; CFX_WideString csAuthor; vp >> csAuthor; pDictionary->SetAtString("Author", PDF_EncodeText(csAuthor)); m_pDocument->SetChangeMark(); return TRUE; } } FX_BOOL Document::info(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; CFX_WideString cwAuthor = pDictionary->GetUnicodeText("Author"); CFX_WideString cwTitle = pDictionary->GetUnicodeText("Title"); CFX_WideString cwSubject = pDictionary->GetUnicodeText("Subject"); CFX_WideString cwKeywords = pDictionary->GetUnicodeText("Keywords"); CFX_WideString cwCreator = pDictionary->GetUnicodeText("Creator"); CFX_WideString cwProducer = pDictionary->GetUnicodeText("Producer"); CFX_WideString cwCreationDate = pDictionary->GetUnicodeText("CreationDate"); CFX_WideString cwModDate = pDictionary->GetUnicodeText("ModDate"); CFX_WideString cwTrapped = pDictionary->GetUnicodeText("Trapped"); v8::Isolate* isolate = GetIsolate(cc); if (!vp.IsSetting()) { CJS_Context* pContext = (CJS_Context *)cc; CJS_Runtime* pRuntime = pContext->GetJSRuntime(); JSFXObject pObj = JS_NewFxDynamicObj(*pRuntime, pContext, -1); JS_PutObjectString(isolate,pObj, L"Author", cwAuthor); JS_PutObjectString(isolate,pObj, L"Title", cwTitle); JS_PutObjectString(isolate,pObj, L"Subject", cwSubject); JS_PutObjectString(isolate,pObj, L"Keywords", cwKeywords); JS_PutObjectString(isolate,pObj, L"Creator", cwCreator); JS_PutObjectString(isolate,pObj, L"Producer", cwProducer); JS_PutObjectString(isolate,pObj, L"CreationDate", cwCreationDate); JS_PutObjectString(isolate,pObj, L"ModDate", cwModDate); JS_PutObjectString(isolate,pObj, L"Trapped", cwTrapped); // It's to be compatible to non-standard info dictionary. FX_POSITION pos = pDictionary->GetStartPos(); while(pos) { CFX_ByteString bsKey; CPDF_Object* pValueObj = pDictionary->GetNextElement(pos, bsKey); CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey); if((pValueObj->GetType()==PDFOBJ_STRING) || (pValueObj->GetType()==PDFOBJ_NAME) ) JS_PutObjectString(isolate,pObj, wsKey, pValueObj->GetUnicodeText()); if(pValueObj->GetType()==PDFOBJ_NUMBER) JS_PutObjectNumber(isolate,pObj, wsKey, (float)pValueObj->GetNumber()); if(pValueObj->GetType()==PDFOBJ_BOOLEAN) JS_PutObjectBoolean(isolate,pObj, wsKey, (bool)pValueObj->GetInteger()); } vp << pObj; return TRUE; } else { return TRUE; } } FX_BOOL Document::creationDate(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; if (vp.IsGetting()) { vp << pDictionary->GetUnicodeText("CreationDate"); return TRUE; } else { if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; CFX_WideString csCreationDate; vp >> csCreationDate; pDictionary->SetAtString("CreationDate", PDF_EncodeText(csCreationDate)); m_pDocument->SetChangeMark(); return TRUE; } } FX_BOOL Document::creator(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; if (vp.IsGetting()) { vp << pDictionary->GetUnicodeText("Creator"); return TRUE; } else { if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; CFX_WideString csCreator; vp >> csCreator; pDictionary->SetAtString("Creator", PDF_EncodeText(csCreator)); m_pDocument->SetChangeMark(); return TRUE; } } FX_BOOL Document::delay(OBJ_PROP_PARAMS) { if (vp.IsGetting()) { vp << m_bDelay; return TRUE; } else { ASSERT(m_pDocument != NULL); if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; bool b; vp >> b; m_bDelay = b; if (m_bDelay) { for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++) delete m_DelayData.GetAt(i); m_DelayData.RemoveAll(); } else { for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++) { if (CJS_DelayData* pData = m_DelayData.GetAt(i)) { Field::DoDelay(m_pDocument, pData); delete m_DelayData.GetAt(i); } } m_DelayData.RemoveAll(); } return TRUE; } } FX_BOOL Document::keywords(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; if (vp.IsGetting()) { vp << pDictionary->GetUnicodeText("Keywords"); return TRUE; } else { if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; CFX_WideString csKeywords; vp >> csKeywords; pDictionary->SetAtString("Keywords", PDF_EncodeText(csKeywords)); m_pDocument->SetChangeMark(); return TRUE; } } FX_BOOL Document::modDate(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; if (vp.IsGetting()) { vp << pDictionary->GetUnicodeText("ModDate"); return TRUE; } else { if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; CFX_WideString csmodDate; vp >> csmodDate; pDictionary->SetAtString("ModDate", PDF_EncodeText(csmodDate)); m_pDocument->SetChangeMark(); return TRUE; } } FX_BOOL Document::producer(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; if (vp.IsGetting()) { vp << pDictionary->GetUnicodeText("Producer"); return TRUE; } else { if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; CFX_WideString csproducer; vp >> csproducer; pDictionary->SetAtString("Producer", PDF_EncodeText(csproducer)); m_pDocument->SetChangeMark(); return TRUE; } } FX_BOOL Document::subject(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; if (vp.IsGetting()) { vp << pDictionary->GetUnicodeText("Subject"); return TRUE; } else { if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; CFX_WideString cssubject; vp >> cssubject; pDictionary->SetAtString("Subject", PDF_EncodeText(cssubject)); m_pDocument->SetChangeMark(); return TRUE; } } FX_BOOL Document::title(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); if (m_pDocument == NULL || m_pDocument->GetDocument() == NULL) return FALSE; CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo(); if (!pDictionary)return FALSE; if (vp.IsGetting()) { vp << pDictionary->GetUnicodeText("Title"); return TRUE; } else { if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE; CFX_WideString cstitle; vp >> cstitle; pDictionary->SetAtString("Title", PDF_EncodeText(cstitle)); m_pDocument->SetChangeMark(); return TRUE; } } FX_BOOL Document::numPages(OBJ_PROP_PARAMS) { if (vp.IsGetting()) { ASSERT(m_pDocument != NULL); vp << m_pDocument->GetPageCount(); return TRUE; } else { return FALSE; } } FX_BOOL Document::external(OBJ_PROP_PARAMS) { //In Chrome case,should always return true. vp << TRUE; return TRUE; } FX_BOOL Document::filesize(OBJ_PROP_PARAMS) { if (!vp.IsGetting())return FALSE; ASSERT(m_pDocument != NULL); // CFile file(m_pDocument->GetPath(), CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone); // vp << (double)file.GetLength(); // file.Close(); if ( m_pDocument->GetPath().IsEmpty() == FALSE) { CFX_ByteString bsStr = CFX_ByteString::FromUnicode( m_pDocument->GetPath() ); FILE * pFile = NULL; pFile = fopen( bsStr.GetBuffer( bsStr.GetLength() ), "rb" ); if ( pFile ) { fseek( pFile, 0, SEEK_END ); long lSize = ftell( pFile ); fclose( pFile ); pFile = NULL; vp << (FX_INT32)(lSize); return TRUE; } } vp << 0; return TRUE; } FX_BOOL Document::mouseX(OBJ_PROP_PARAMS) { return TRUE; } FX_BOOL Document::mouseY(OBJ_PROP_PARAMS) { return TRUE; } FX_BOOL Document::baseURL(OBJ_PROP_PARAMS) { if (vp.IsGetting()) { vp << m_cwBaseURL; return TRUE; } else { vp >> m_cwBaseURL; return TRUE; } } FX_BOOL Document::calculate(OBJ_PROP_PARAMS) { ASSERT(m_pDocument != NULL); CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); if (vp.IsGetting()) { if (pInterForm->IsCalculateEnabled()) vp << true; else vp << false; } else { bool bCalculate; vp >> bCalculate; pInterForm->EnableCalculate(bCalculate); } return TRUE; } FX_BOOL Document::documentFileName(OBJ_PROP_PARAMS) { if (!vp.IsGetting()) return FALSE; CFX_WideString wsFilePath = m_pDocument->GetPath(); FX_INT32 i = wsFilePath.GetLength() - 1; for ( ; i >= 0; i-- ) { if ( wsFilePath.GetAt( i ) == L'\\' || wsFilePath.GetAt( i ) == L'/' ) break; } if ( i >= 0 && i < wsFilePath.GetLength() - 1 ) { vp << ( wsFilePath.GetBuffer( wsFilePath.GetLength() ) + i + 1 ); }else{ vp << L""; } return TRUE; } CFX_WideString Document::ReversalStr(CFX_WideString cbFrom) { wchar_t* pFrom = NULL; int iLenth = cbFrom.GetLength(); wchar_t* pResult = (wchar_t*)malloc((iLenth+1) * sizeof(wchar_t)); memset(pResult, 0, (iLenth+1)); pFrom = (wchar_t*)cbFrom.GetBuffer(iLenth); for (int i = 0; i < iLenth; i++) { pResult[i] = *(pFrom + iLenth - i - 1); } cbFrom.ReleaseBuffer(); CFX_WideString cbRet = CFX_WideString(pResult); free(pResult); pResult = NULL; return cbRet; } CFX_WideString Document::CutString(CFX_WideString cbFrom) { wchar_t* pFrom = NULL; int iLenth = cbFrom.GetLength(); wchar_t* pResult = (wchar_t*)malloc((iLenth+1) * sizeof(wchar_t)); memset(pResult, 0, (iLenth+1)); pFrom = (wchar_t*)cbFrom.GetBuffer(iLenth); for (int i = 0; i < iLenth; i++) { if (pFrom[i] == L'\\' || pFrom[i] == L'/') break; pResult[i] = pFrom[i]; } cbFrom.ReleaseBuffer(); CFX_WideString cbRet = CFX_WideString(pResult); free(pResult); pResult = NULL; return cbRet; } FX_BOOL Document::path(OBJ_PROP_PARAMS) { if (!vp.IsGetting()) return FALSE; vp << app::SysPathToPDFPath(m_pDocument->GetPath()); return TRUE; } FX_BOOL Document::pageWindowRect(OBJ_PROP_PARAMS) { return TRUE; } FX_BOOL Document::layout(OBJ_PROP_PARAMS) { return TRUE; } FX_BOOL Document::addLink(OBJ_METHOD_PARAMS) { return TRUE; } FX_BOOL Document::closeDoc(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); return TRUE; } FX_BOOL Document::getPageBox(OBJ_METHOD_PARAMS) { return TRUE; } FX_BOOL Document::getAnnot(OBJ_METHOD_PARAMS) { return TRUE; } FX_BOOL Document::getAnnots(OBJ_METHOD_PARAMS) { vRet.SetNull(); return TRUE; } FX_BOOL Document::getAnnot3D(OBJ_METHOD_PARAMS) { vRet.SetNull(); return TRUE; } FX_BOOL Document::getAnnots3D(OBJ_METHOD_PARAMS) { vRet = VT_undefined; return TRUE; } FX_BOOL Document::getOCGs(OBJ_METHOD_PARAMS) { return TRUE; } FX_BOOL Document::getLinks(OBJ_METHOD_PARAMS) { return TRUE; } bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect) { if (rect.left <= LinkRect.left && rect.top <= LinkRect.top && rect.right >= LinkRect.right && rect.bottom >= LinkRect.bottom) return true; else return false; } void IconTree::InsertIconElement(IconElement* pNewIcon) { if (!pNewIcon)return; if (m_pHead == NULL && m_pEnd == NULL) { m_pHead = m_pEnd = pNewIcon; m_iLength++; } else { m_pEnd->NextIcon = pNewIcon; m_pEnd = pNewIcon; m_iLength++; } } void IconTree::DeleteIconTree() { if (!m_pHead || !m_pEnd)return; IconElement* pTemp = NULL; while(m_pEnd != m_pHead) { pTemp = m_pHead; m_pHead = m_pHead->NextIcon; delete pTemp; } delete m_pEnd; m_pHead = NULL; m_pEnd = NULL; } int IconTree::GetLength() { return m_iLength; } IconElement* IconTree::operator [](int iIndex) { if (iIndex >= 0 && iIndex <= m_iLength) { IconElement* pTemp = m_pHead; for (int i = 0; i < iIndex; i++) { pTemp = pTemp->NextIcon; } return pTemp; } else return NULL; } void IconTree::DeleteIconElement(CFX_WideString swIconName) { IconElement* pTemp = m_pHead; int iLoopCount = m_iLength; for (int i = 0; i < iLoopCount - 1; i++) { if (pTemp == m_pEnd) break; if (m_pHead->IconName == swIconName) { m_pHead = m_pHead->NextIcon; delete pTemp; m_iLength--; pTemp = m_pHead; } if (pTemp->NextIcon->IconName == swIconName) { if (pTemp->NextIcon == m_pEnd) { m_pEnd = pTemp; delete pTemp->NextIcon; m_iLength--; pTemp->NextIcon = NULL; } else { IconElement* pElement = pTemp->NextIcon; pTemp->NextIcon = pTemp->NextIcon->NextIcon; delete pElement; m_iLength--; pElement = NULL; } continue; } pTemp = pTemp->NextIcon; } } FX_BOOL Document::addIcon(OBJ_METHOD_PARAMS) { if (params.size() != 2)return FALSE; CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); CFX_WideString swIconName = params[0].operator CFX_WideString(); JSFXObject pJSIcon = (JSFXObject)params[1]; if (JS_GetObjDefnID(pJSIcon) != JS_GetObjDefnID(*pRuntime, L"Icon")) return FALSE; CJS_EmbedObj* pEmbedObj = ((CJS_Object*)params[1])->GetEmbedObject(); if (!pEmbedObj)return FALSE; Icon* pIcon = (Icon*)pEmbedObj; if (!m_pIconTree) m_pIconTree = new IconTree(); IconElement* pNewIcon = new IconElement(); pNewIcon->IconName = swIconName; pNewIcon->NextIcon = NULL; pNewIcon->IconStream = pIcon; m_pIconTree->InsertIconElement(pNewIcon); return TRUE; } FX_BOOL Document::icons(OBJ_PROP_PARAMS) { if (vp.IsSetting()) return FALSE; if (!m_pIconTree) { vp.SetNull(); return TRUE; } CJS_Array Icons(m_isolate); IconElement* pIconElement = NULL; int iIconTreeLength = m_pIconTree->GetLength(); CJS_Context* pContext = (CJS_Context *)cc; CJS_Runtime* pRuntime = pContext->GetJSRuntime(); for (int i = 0; i < iIconTreeLength; i++) { pIconElement = (*m_pIconTree)[i]; JSFXObject pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon")); if (pObj.IsEmpty()) return FALSE; CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(pObj); if (!pJS_Icon) return FALSE; Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject(); if (!pIcon)return FALSE; pIcon->SetStream(pIconElement->IconStream->GetStream()); pIcon->SetIconName(pIconElement->IconName); Icons.SetElement(i, CJS_Value(m_isolate,pJS_Icon)); } vp << Icons; return TRUE; } FX_BOOL Document::getIcon(OBJ_METHOD_PARAMS) { if (params.size() != 1)return FALSE; if(!m_pIconTree) return FALSE; CFX_WideString swIconName = params[0].operator CFX_WideString(); int iIconCounts = m_pIconTree->GetLength(); CJS_Context* pContext = (CJS_Context *)cc; CJS_Runtime* pRuntime = pContext->GetJSRuntime(); for (int i = 0; i < iIconCounts; i++) { if ((*m_pIconTree)[i]->IconName == swIconName) { Icon* pRetIcon = (*m_pIconTree)[i]->IconStream; JSFXObject pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon")); if (pObj.IsEmpty()) return FALSE; CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(pObj); if (!pJS_Icon) return FALSE; Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject(); if (!pIcon)return FALSE; pIcon->SetIconName(swIconName); pIcon->SetStream(pRetIcon->GetStream()); vRet = pJS_Icon; return TRUE; } } return FALSE; } FX_BOOL Document::removeIcon(OBJ_METHOD_PARAMS) { if (params.size() != 1)return FALSE; if(!m_pIconTree) return FALSE; CFX_WideString swIconName = params[0].operator CFX_WideString(); #ifndef FOXIT_CHROME_BUILD m_pIconTree->DeleteIconElement(swIconName); #endif return TRUE; } FX_BOOL Document::createDataObject(OBJ_METHOD_PARAMS) { if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); CFX_WideString swName = L""; CFX_ByteString sbName = ""; CFX_WideString swValue = L""; CFX_WideString swMIMEType = L""; CFX_WideString swCryptFilter = L""; CFX_ByteString sbFileValue = ""; int iParamSize = params.size(); for (int i = 0; i < iParamSize; i++) { if (i == 0) swName = params[0]; if (i == 1) swValue = params[1]; if (i == 2) swMIMEType = params[2]; if (i == 3) swCryptFilter = params[4]; } FILE* pFile = NULL; //CFileStatus fileStatus; const int BUFSIZE = 17; FX_BYTE buf[BUFSIZE]; FX_BYTE *pBuffer = NULL; char* pBuf = NULL; int nFileSize = 0; sbFileValue = CFX_ByteString::FromUnicode(swValue); sbName = CFX_ByteString::FromUnicode(swName); int iBufLength = sbFileValue.GetLength(); pBuf = (char*)malloc(sizeof(char) * iBufLength); pBuf = sbFileValue.GetBuffer(iBufLength); if ( NULL == (pFile = FXSYS_fopen( sbName.GetBuffer(sbName.GetLength()), "wb+" )) ) { return FALSE; } fwrite( pBuf, sizeof(char), iBufLength, pFile ); fclose( pFile ); pFile = NULL; pFile = FXSYS_fopen( sbName.GetBuffer(sbName.GetLength()), "rb+" ); fseek( pFile, 0, SEEK_END ); nFileSize = ftell( pFile ); pBuffer = new FX_BYTE[nFileSize]; fseek( pFile, 0, SEEK_SET ); size_t s = fread( pBuffer, sizeof(char), nFileSize, pFile ); if(s == 0) { delete[] pBuffer; return FALSE; } CRYPT_MD5Generate(pBuffer, nFileSize, buf); buf[BUFSIZE - 1] = 0; CFX_WideString csCheckSum((FX_LPCWSTR)buf, 16); delete[] pBuffer; return TRUE; } FX_BOOL Document::media(OBJ_PROP_PARAMS) { return TRUE; } FX_BOOL Document::calculateNow(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) || m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE; CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm(); ASSERT(pInterForm != NULL); pInterForm->OnCalculate(); return TRUE; } FX_BOOL Document::Collab(OBJ_PROP_PARAMS) { return TRUE; } FX_BOOL Document::getPageNthWord(OBJ_METHOD_PARAMS) { //if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE; int nPageNo = params.GetSize() > 0 ? (int)params[0] : 0; int nWordNo = params.GetSize() > 1 ? (int)params[1] : 0; bool bStrip = params.GetSize() > 2 ? (bool)params[2] : true; CPDF_Document* pDocument = m_pDocument->GetDocument(); if (!pDocument) return FALSE; if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) { //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR); return FALSE; } CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo); if (!pPageDict) return FALSE; CPDF_Page page; page.Load(pDocument, pPageDict); page.StartParse(); page.ParseContent(); FX_POSITION pos = page.GetFirstObjectPosition(); int nWords = 0; CFX_WideString swRet; while (pos) { if (CPDF_PageObject* pPageObj = page.GetNextObject(pos)) { if (pPageObj->m_Type == PDFPAGE_TEXT) { int nObjWords = CountWords((CPDF_TextObject*)pPageObj); if (nWords + nObjWords >= nWordNo) { swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords); break; } nWords += nObjWords; } } } if (bStrip) { swRet.TrimLeft(); swRet.TrimRight(); } vRet = swRet; return TRUE; } FX_BOOL Document::getPageNthWordQuads(OBJ_METHOD_PARAMS) { //if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE; return FALSE; } FX_BOOL Document::getPageNumWords(OBJ_METHOD_PARAMS) { ASSERT(m_pDocument != NULL); if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE; int nPageNo = params.GetSize() > 0 ? (int)params[0] : 0; CPDF_Document* pDocument = m_pDocument->GetDocument(); ASSERT(pDocument != NULL); if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) { //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR); return FALSE; } CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo); if (!pPageDict) return FALSE; CPDF_Page page; page.Load(pDocument, pPageDict); page.StartParse(); page.ParseContent(); FX_POSITION pos = page.GetFirstObjectPosition(); int nWords = 0; while (pos) { if (CPDF_PageObject* pPageObj = page.GetNextObject(pos)) { if (pPageObj->m_Type == PDFPAGE_TEXT) { CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj; nWords += CountWords(pTextObj); } } } vRet = nWords; return TRUE; } FX_BOOL Document::getPrintParams(OBJ_METHOD_PARAMS) { CJS_Context* pContext = (CJS_Context*)cc; ASSERT(pContext != NULL); CJS_Runtime* pRuntime = pContext->GetJSRuntime(); ASSERT(pRuntime != NULL); JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"PrintParamsObj")); //not implemented yet. vRet = pRetObj; return TRUE; } #define ISLATINWORD(u) (u != 0x20 && u <= 0x28FF) int Document::CountWords(CPDF_TextObject* pTextObj) { if (!pTextObj) return 0; int nWords = 0; CPDF_Font* pFont = pTextObj->GetFont(); if (!pFont) return 0; FX_BOOL bIsLatin = FALSE; for (int i=0, sz=pTextObj->CountChars(); i<sz; i++) { FX_DWORD charcode = -1; FX_FLOAT kerning; pTextObj->GetCharInfo(i, charcode, kerning); CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode); FX_WORD unicode = 0; if (swUnicode.GetLength() > 0) unicode = swUnicode[0]; if (ISLATINWORD(unicode) && bIsLatin) continue; bIsLatin = ISLATINWORD(unicode); if (unicode != 0x20) nWords++; } return nWords; } CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex) { ASSERT(pTextObj != NULL); CFX_WideString swRet; CPDF_Font* pFont = pTextObj->GetFont(); if (!pFont) return L""; int nWords = 0; FX_BOOL bIsLatin = FALSE; for (int i=0, sz=pTextObj->CountChars(); i<sz; i++) { FX_DWORD charcode = -1; FX_FLOAT kerning; pTextObj->GetCharInfo(i, charcode, kerning); CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode); FX_WORD unicode = 0; if (swUnicode.GetLength() > 0) unicode = swUnicode[0]; if (ISLATINWORD(unicode) && bIsLatin) { } else { bIsLatin = ISLATINWORD(unicode); if (unicode != 0x20) nWords++; } if (nWords-1 == nWordIndex) swRet += unicode; } return swRet; } FX_BOOL Document::zoom(OBJ_PROP_PARAMS) { return TRUE; } /** (none, NoVary) (fitP, FitPage) (fitW, FitWidth) (fitH, FitHeight) (fitV, FitVisibleWidth) (pref, Preferred) (refW, ReflowWidth) */ FX_BOOL Document::zoomType(OBJ_PROP_PARAMS) { return TRUE; } FX_BOOL Document::deletePages(OBJ_METHOD_PARAMS) { v8::Isolate* isolate = GetIsolate(cc); // if (pEnv->GetAppName().Compare(PHANTOM) != 0) // return TRUE; //if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE; int iSize = params.size(); int nStart = 0; int nEnd = 0; if (iSize < 1) { } else if (iSize == 1) { if (params[0].GetType() == VT_object) { JSObject pObj = (JSObject )params[0]; v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nStart"); nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"nEnd"); nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); } else { nStart = (int)params[0]; } } else { nStart = (int)params[0]; nEnd = (int)params[1]; } int nTotal = m_pDocument->GetPageCount(); if (nStart < 0) nStart = 0; if (nStart >= nTotal) nStart = nTotal - 1; if (nEnd < 0) nEnd = 0; if (nEnd >= nTotal) nEnd = nTotal - 1; if (nEnd < nStart) nEnd = nStart; #ifndef FOXIT_CHROME_BUILD return m_pDocument->DeletePages(nStart, nEnd - nStart + 1); #else return TRUE; #endif } FX_BOOL Document::extractPages(OBJ_METHOD_PARAMS) { v8::Isolate* isolate = GetIsolate(cc); if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT)) return FALSE; int iSize = params.size(); int nTotal = m_pDocument->GetPageCount(); int nStart = 0; int nEnd = nTotal - 1; CFX_WideString swFilePath; if (iSize < 1) { } else if (iSize == 1) { if (params[0].GetType() == VT_object) { JSObject pObj = (JSObject )params[0]; v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nStart"); nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"nEnd"); nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"cPath"); swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString(); } else { nStart = (int)params[0]; } } else if (iSize == 2) { nStart = (int)params[0]; nEnd = (int)params[1]; } else { nStart = (int)params[0]; nEnd = (int)params[1]; swFilePath = params[2].operator CFX_WideString(); } if (nEnd < nStart) nEnd = nStart; CPDF_Document *pNewDoc = new CPDF_Document; pNewDoc->CreateNewDoc(); CFX_WordArray array; for (int i=nStart; i<=nEnd; i++) array.Add(i); // m_pDocument->ExtractPages(array, pNewDoc); if (swFilePath.IsEmpty()) { } else { swFilePath = app::PDFPathToSysPath(swFilePath); CPDF_Creator PDFCreater(pNewDoc); PDFCreater.Create(swFilePath); delete pNewDoc; // pEnv->OpenDocument(swFilePath); vRet.SetNull(); } return TRUE; } FX_BOOL Document::insertPages(OBJ_METHOD_PARAMS) { v8::Isolate* isolate = GetIsolate(cc); if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE; int iSize = params.size(); int nStart = 0; int nEnd = 0; int nPage = 0; CFX_WideString swFilePath; if (iSize < 1) { } else if (iSize == 1) { if (params[0].GetType() == VT_object) { JSObject pObj = (JSObject )params[0]; v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nPage"); nPage = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"cPath"); swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString(); pValue = JS_GetObjectElement(isolate,pObj, L"nStart"); nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"nEnd"); nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); } else { nPage = (int)params[0]; } } else { nPage = (int)params[0]; if (iSize >= 2) swFilePath = params[1].operator CFX_WideString(); if (iSize >= 3) nStart = (int)params[2]; if (iSize >= 4) nEnd = (int)params[3]; } nPage++; if (nPage < 0) nPage = 0; if (nPage > m_pDocument->GetPageCount()) nPage = m_pDocument->GetPageCount(); if (swFilePath.IsEmpty()) return FALSE; swFilePath = app::PDFPathToSysPath(swFilePath); CPDF_Parser pdfParser; pdfParser.StartParse(swFilePath, FALSE); CPDF_Document* pSrcDoc = pdfParser.GetDocument(); if (!pSrcDoc) { pdfParser.CloseParser(); return FALSE; } int nTotal = pSrcDoc->GetPageCount(); if (nStart < 0) nStart = 0; if (nStart >= nTotal) nStart = nTotal - 1; if (nEnd < 0) nEnd = 0; if (nEnd >= nTotal) nEnd = nTotal - 1; if (nEnd < nStart) nEnd = nStart; CFX_WordArray array; for (int i=nStart; i<=nEnd; i++) array.Add(i); // m_pDocument->InsertPages(nPage, pSrcDoc, array); pdfParser.CloseParser(); return TRUE; } FX_BOOL Document::replacePages(OBJ_METHOD_PARAMS) { v8::Isolate* isolate = GetIsolate(cc); if (IsSafeMode(cc)) return TRUE; ASSERT(m_pDocument != NULL); if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) || m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE; int iSize = params.size(); int nStart = -1; int nEnd = -1; int nPage = 0; CFX_WideString swFilePath; if (iSize < 1) { } else if (iSize == 1) { if (params[0].GetType() == VT_object) { JSObject pObj = (JSObject )params[0]; v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"nPage"); nPage = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"cPath"); swFilePath = CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString(); pValue = JS_GetObjectElement(isolate,pObj, L"nStart"); nStart = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); pValue = JS_GetObjectElement(isolate,pObj, L"nEnd"); nEnd = (int)CJS_Value(m_isolate,pValue,GET_VALUE_TYPE(pValue)); } else { nPage = (int)params[0]; } } else { nPage = (int)params[0]; if (iSize >= 2) swFilePath = params[1].operator CFX_WideString(); if (iSize >= 3) nStart = (int)params[2]; if (iSize >= 4) nEnd = (int)params[3]; } if (nPage < 0) nPage = 0; if (nPage >= m_pDocument->GetPageCount()) nPage = m_pDocument->GetPageCount() - 1; if (swFilePath.IsEmpty()) return FALSE; swFilePath = app::PDFPathToSysPath(swFilePath); CPDF_Parser pdfParser; pdfParser.StartParse(swFilePath, FALSE); CPDF_Document* pSrcDoc = pdfParser.GetDocument(); if (!pSrcDoc) { pdfParser.CloseParser(); return FALSE; } int nTotal = pSrcDoc->GetPageCount(); if (nStart < 0) { if (nEnd < 0) { nStart = 0; nEnd = nTotal - 1; } else { nStart = 0; } } else { if (nEnd < 0) { nEnd = nStart; } else { if (nStart >= nTotal) nStart = nTotal - 1; if (nEnd >= nTotal) nEnd = nTotal - 1; if (nEnd < nStart) nEnd = nStart; } } CFX_WordArray array; for (int i=nStart; i<=nEnd; i++) array.Add(i); // m_pDocument->ReplacePages(nPage, pSrcDoc, array); pdfParser.CloseParser(); return TRUE; } FX_BOOL Document::getURL(OBJ_METHOD_PARAMS) { if (IsSafeMode(cc)) return TRUE; return TRUE; } void Document::AddDelayData(CJS_DelayData* pData) { m_DelayData.Add(pData); } void Document::DoFieldDelay(const CFX_WideString& sFieldName, int nControlIndex) { CFX_DWordArray DelArray; for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++) { if (CJS_DelayData* pData = m_DelayData.GetAt(i)) { if (pData->sFieldName == sFieldName && pData->nControlIndex == nControlIndex) { Field::DoDelay(m_pDocument, pData); delete pData; m_DelayData.SetAt(i, NULL); DelArray.Add(i); } } } for (int j=DelArray.GetSize()-1; j>=0; j--) { m_DelayData.RemoveAt(DelArray[j]); } } void Document::AddDelayAnnotData(CJS_AnnotObj *pData) { m_DelayAnnotData.Add(pData); } void Document::DoAnnotDelay() { CFX_DWordArray DelArray; for (int j=DelArray.GetSize()-1; j>=0; j--) { m_DelayData.RemoveAt(DelArray[j]); } }