Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxfa / src / app / xfa_ffapp.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../common/xfa_common.h"\r
9 #include "xfa_ffdochandler.h"\r
10 #include "xfa_fwladapter.h"\r
11 #include "xfa_ffdoc.h"\r
12 #include "xfa_ffapp.h"\r
13 #include "xfa_fwltheme.h"\r
14 #include "xfa_fontmgr.h"\r
15 #include "xfa_ffwidgethandler.h"\r
16 CXFA_FileRead::CXFA_FileRead(const CFX_ArrayTemplate<CPDF_Stream*> &streams)\r
17     : m_dwSize(0)\r
18 {\r
19     m_Streams.Copy(streams);\r
20 }\r
21 CXFA_FileRead::~CXFA_FileRead()\r
22 {\r
23     m_Streams.RemoveAll();\r
24     m_StreamSize.RemoveAll();\r
25 }\r
26 FX_FILESIZE CXFA_FileRead::GetSize()\r
27 {\r
28     if (m_StreamSize.GetSize() > 0) {\r
29         return m_dwSize;\r
30     }\r
31     FX_INT32 iCount = m_Streams.GetSize();\r
32     FX_DWORD iBufferSize = 4096;\r
33     FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, iBufferSize);\r
34     for (FX_INT32 i = 0; i < iCount; i++) {\r
35         CPDF_StreamFilter* pStreamFilter = m_Streams[i]->GetStreamFilter(FALSE);\r
36         FX_DWORD dwCurSize = 0;\r
37         while (TRUE) {\r
38             FX_DWORD dwRead = pStreamFilter->ReadBlock(pBuf, iBufferSize);\r
39             dwCurSize += dwRead;\r
40             if (dwRead < iBufferSize) {\r
41                 break;\r
42             }\r
43         }\r
44         m_dwSize += dwCurSize;\r
45         m_StreamSize.Add(dwCurSize);\r
46         delete pStreamFilter;\r
47     }\r
48     FX_Free(pBuf);\r
49     return m_dwSize;\r
50 }\r
51 FX_BOOL CXFA_FileRead::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)\r
52 {\r
53     FX_FILESIZE dwLen = 0;\r
54     FX_INT32 iCount = m_Streams.GetSize();\r
55     FX_INT32 i = 0;\r
56     for (; i < iCount; i++) {\r
57         dwLen += m_StreamSize[i];\r
58         if (dwLen > offset) {\r
59             dwLen -= m_StreamSize[i];\r
60             break;\r
61         }\r
62     }\r
63     if (i >= iCount) {\r
64         return FALSE;\r
65     }\r
66     CPDF_StreamFilter* pStreamFilter = m_Streams[i]->GetStreamFilter(FALSE);\r
67     if ((offset -= dwLen) > 0) {\r
68         FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, offset);\r
69         FX_DWORD dwRead = pStreamFilter->ReadBlock(pBuf, offset);\r
70         FX_Free(pBuf);\r
71     }\r
72     FX_DWORD dwHadRead = pStreamFilter->ReadBlock((FX_LPBYTE)buffer, size);\r
73     delete pStreamFilter;\r
74     size -= dwHadRead;\r
75     if (size <= 0) {\r
76         return TRUE;\r
77     }\r
78     FX_DWORD dwReadSize = dwHadRead;\r
79     for (FX_INT32 iStart = i + 1; iStart < iCount; iStart++) {\r
80         CPDF_StreamFilter* pStreamFilter = m_Streams[iStart]->GetStreamFilter(FALSE);\r
81         FX_DWORD dwHadRead = pStreamFilter->ReadBlock(((FX_LPBYTE)buffer) + dwReadSize, size);\r
82         delete pStreamFilter;\r
83         size -= dwHadRead;\r
84         if (size <= 0) {\r
85             return TRUE;\r
86         }\r
87         dwReadSize += dwHadRead;\r
88     }\r
89     return FALSE;\r
90 }\r
91 CXFA_FileRead2::CXFA_FileRead2(const CFX_ArrayTemplate<CPDF_Stream*> &streams)\r
92 {\r
93     FX_INT32 iCount = streams.GetSize();\r
94     for (FX_INT32 i = 0; i < iCount; i++) {\r
95         CPDF_StreamAcc &acc = m_Data.Add();\r
96         acc.LoadAllData(streams[i]);\r
97     }\r
98 }\r
99 FX_FILESIZE CXFA_FileRead2::GetSize()\r
100 {\r
101     FX_DWORD dwSize = 0;\r
102     FX_INT32 iCount = m_Data.GetSize();\r
103     for (FX_INT32 i = 0; i < iCount; i++) {\r
104         CPDF_StreamAcc &acc = m_Data[i];\r
105         dwSize += acc.GetSize();\r
106     }\r
107     return dwSize;\r
108 }\r
109 FX_BOOL CXFA_FileRead2::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)\r
110 {\r
111     FX_INT32 iCount = m_Data.GetSize();\r
112     FX_INT32 index = 0;\r
113     while (index < iCount) {\r
114         CPDF_StreamAcc &acc = m_Data[index];\r
115         FX_FILESIZE dwSize = acc.GetSize();\r
116         if (offset < dwSize) {\r
117             break;\r
118         }\r
119         offset -= dwSize;\r
120         index++;\r
121     }\r
122     while (index < iCount) {\r
123         CPDF_StreamAcc &acc = m_Data[index];\r
124         FX_DWORD dwSize = acc.GetSize();\r
125         FX_DWORD dwRead = FX_MIN(size, dwSize - offset);\r
126         FXSYS_memcpy(buffer, acc.GetData() + offset, dwRead);\r
127         size -= dwRead;\r
128         if (size == 0) {\r
129             return TRUE;\r
130         }\r
131         buffer = (FX_LPBYTE)buffer + dwRead;\r
132         offset = 0;\r
133         index++;\r
134     }\r
135     return FALSE;\r
136 }\r
137 IXFA_App* IXFA_App::Create(IXFA_AppProvider* pProvider)\r
138 {\r
139     return FX_NEW CXFA_FFApp(pProvider);\r
140 }\r
141 CXFA_FFApp::CXFA_FFApp(IXFA_AppProvider* pProvider)\r
142     : m_pDocHandler(NULL)\r
143     , m_pFWLTheme(NULL)\r
144     , m_pProvider(pProvider)\r
145     , m_pFontMgr(NULL)\r
146     , m_pAdapterWidgetMgr(NULL)\r
147     , m_pFDEFontMgr(NULL)\r
148     , m_pMenuHandler(NULL)\r
149     , m_pAdapterThreadMgr(NULL)\r
150 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_\r
151     , m_pFontSource(NULL)\r
152 #endif\r
153 {\r
154     m_pFWLApp = IFWL_App::Create(this);\r
155     FWL_SetApp(m_pFWLApp);\r
156     m_pFWLApp->Initialize();\r
157     IXFA_TimeZoneProvider::Create();\r
158 }\r
159 CXFA_FFApp::~CXFA_FFApp()\r
160 {\r
161     if (m_pDocHandler) {\r
162         delete m_pDocHandler;\r
163     }\r
164     if (m_pFWLApp) {\r
165         m_pFWLApp->Finalize();\r
166         m_pFWLApp->Release();\r
167     }\r
168     if (m_pFWLTheme) {\r
169         m_pFWLTheme->Release();\r
170     }\r
171     if (m_pAdapterWidgetMgr) {\r
172         delete m_pAdapterWidgetMgr;\r
173     }\r
174     if (m_pAdapterThreadMgr) {\r
175         delete m_pAdapterThreadMgr;\r
176         m_pAdapterThreadMgr = NULL;\r
177     }\r
178     if (m_pMenuHandler) {\r
179         delete m_pMenuHandler;\r
180         m_pMenuHandler = NULL;\r
181     }\r
182     IXFA_TimeZoneProvider::Destroy();\r
183     if (m_pFontMgr != NULL) {\r
184         delete m_pFontMgr;\r
185         m_pFontMgr = NULL;\r
186     }\r
187 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_\r
188     if(m_pFontSource != NULL) {\r
189         m_pFontSource->Release();\r
190     }\r
191 #endif\r
192     if (m_pFDEFontMgr) {\r
193         m_pFDEFontMgr->Release();\r
194     }\r
195 }\r
196 IXFA_MenuHandler* CXFA_FFApp::GetMenuHandler()\r
197 {\r
198     if (!m_pMenuHandler) {\r
199         m_pMenuHandler = FX_NEW CXFA_FFMenuHandler;\r
200     }\r
201     return m_pMenuHandler;\r
202 }\r
203 IXFA_DocHandler* CXFA_FFApp::GetDocHandler()\r
204 {\r
205     if (!m_pDocHandler) {\r
206         m_pDocHandler = FX_NEW CXFA_FFDocHandler;\r
207     }\r
208     return m_pDocHandler;\r
209 }\r
210 XFA_HDOC CXFA_FFApp::CreateDoc(IXFA_DocProvider* pProvider, IFX_FileRead* pStream, FX_BOOL bTakeOverFile)\r
211 {\r
212     CXFA_FFDoc* pDoc = FX_NEW CXFA_FFDoc(this, pProvider);\r
213     if (!pDoc) {\r
214         return NULL;\r
215     }\r
216     FX_BOOL bSuccess = pDoc->OpenDoc(pStream, bTakeOverFile);\r
217     if (!bSuccess) {\r
218         delete pDoc;\r
219         pDoc = NULL;\r
220     }\r
221     return (XFA_HDOC)pDoc;\r
222 }\r
223 XFA_HDOC CXFA_FFApp::CreateDoc(IXFA_DocProvider* pProvider, CPDF_Document *pPDFDoc)\r
224 {\r
225     if (pPDFDoc == NULL) {\r
226         return NULL;\r
227     }\r
228     CXFA_FFDoc* pDoc = FX_NEW CXFA_FFDoc(this, pProvider);\r
229     if (!pDoc) {\r
230         return NULL;\r
231     }\r
232     FX_BOOL bSuccess = pDoc->OpenDoc(pPDFDoc);\r
233     if (!bSuccess) {\r
234         delete pDoc;\r
235         pDoc = NULL;\r
236     }\r
237     return (XFA_HDOC)pDoc;\r
238 }\r
239 \r
240 void CXFA_FFApp::SetDefaultFontMgr(IXFA_FontMgr* pFontMgr)\r
241 {\r
242     if (!m_pFontMgr) {\r
243         m_pFontMgr = FX_NEW CXFA_FontMgr();\r
244     }\r
245     m_pFontMgr->SetDefFontMgr(pFontMgr);\r
246 }\r
247 CXFA_FontMgr* CXFA_FFApp::GetXFAFontMgr()\r
248 {\r
249     return m_pFontMgr;\r
250 }\r
251 IFX_FontMgr* CXFA_FFApp::GetFDEFontMgr()\r
252 {\r
253     if (!m_pFDEFontMgr) {\r
254 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_\r
255         m_pFDEFontMgr = IFX_FontMgr::Create(FX_GetDefFontEnumerator());\r
256 #else\r
257         m_pFontSource = FX_CreateDefaultFontSourceEnum();\r
258         m_pFDEFontMgr = IFX_FontMgr::Create(m_pFontSource);\r
259 #endif\r
260     }\r
261     return m_pFDEFontMgr;\r
262 }\r
263 CXFA_FWLTheme* CXFA_FFApp::GetFWLTheme()\r
264 {\r
265     if (!m_pFWLTheme) {\r
266         m_pFWLTheme = FX_NEW CXFA_FWLTheme(this);\r
267     }\r
268     return m_pFWLTheme;\r
269 }\r
270 IFWL_AdapterWidgetMgr* CXFA_FFApp::GetWidgetMgr(IFWL_WidgetMgrDelegate *pDelegate)\r
271 {\r
272     if (!m_pAdapterWidgetMgr) {\r
273         m_pAdapterWidgetMgr = FX_NEW CXFA_FWLAdapterWidgetMgr;\r
274         pDelegate->OnSetCapability(FWL_WGTMGR_DisableThread | FWL_WGTMGR_DisableForm);\r
275         m_pWidgetMgrDelegate = pDelegate;\r
276     }\r
277     return m_pAdapterWidgetMgr;\r
278 }\r
279 IFWL_AdapterThreadMgr* CXFA_FFApp::GetThreadMgr()\r
280 {\r
281     if (!m_pAdapterThreadMgr) {\r
282         m_pAdapterThreadMgr = FX_NEW CFWL_SDAdapterThreadMgr;\r
283     }\r
284     return m_pAdapterThreadMgr;\r
285 }\r
286 IFWL_AdapterTimerMgr* CXFA_FFApp::GetTimerMgr()\r
287 {\r
288     return m_pProvider->GetTimerMgr();\r
289 }\r
290 IFWL_AdapterCursorMgr*  CXFA_FFApp::GetCursorMgr()\r
291 {\r
292     return NULL;\r
293 }\r
294 IFWL_AdapterMonitorMgr* CXFA_FFApp::GetMonitorMgr()\r
295 {\r
296     return NULL;\r
297 }\r
298 IFWL_AdapterClipboardMgr* CXFA_FFApp::GetClipboardMgr()\r
299 {\r
300     return NULL;\r
301 }\r