1 // Copyright 2016 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 "fpdfsdk/cpdfsdk_pageview.h"
8
9 #include <memory>
10 #include <vector>
11
12 #include "core/fpdfapi/parser/cpdf_document.h"
13 #include "core/fpdfapi/render/cpdf_renderoptions.h"
14 #include "core/fpdfdoc/cpdf_annotlist.h"
15 #include "core/fpdfdoc/cpdf_interform.h"
16 #include "core/fxcrt/autorestorer.h"
17 #include "fpdfsdk/cpdfsdk_annot.h"
18 #include "fpdfsdk/cpdfsdk_annotiteration.h"
19 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
20 #include "fpdfsdk/cpdfsdk_interform.h"
21 #include "third_party/base/ptr_util.h"
22
23 #ifdef PDF_ENABLE_XFA
24 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
25 #include "xfa/fxfa/cxfa_ffdocview.h"
26 #include "xfa/fxfa/cxfa_ffpageview.h"
27 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
28 #include "xfa/fxfa/cxfa_rendercontext.h"
29 #include "xfa/fxgraphics/cxfa_graphics.h"
30 #endif // PDF_ENABLE_XFA
31
CPDFSDK_PageView(CPDFSDK_FormFillEnvironment * pFormFillEnv,UnderlyingPageType * page)32 CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_FormFillEnvironment* pFormFillEnv,
33 UnderlyingPageType* page)
34 : m_page(page),
35 m_pFormFillEnv(pFormFillEnv),
36 #ifndef PDF_ENABLE_XFA
37 m_bOwnsPage(false),
38 #endif // PDF_ENABLE_XFA
39 m_bOnWidget(false),
40 m_bValid(false),
41 m_bLocked(false),
42 m_bBeingDestroyed(false) {
43 CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
44 CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
45 #ifdef PDF_ENABLE_XFA
46 if (page->GetPDFPage())
47 pPDFInterForm->FixPageFields(page->GetPDFPage());
48 #else // PDF_ENABLE_XFA
49 pPDFInterForm->FixPageFields(page);
50 m_page->SetView(this);
51 #endif // PDF_ENABLE_XFA
52 }
53
~CPDFSDK_PageView()54 CPDFSDK_PageView::~CPDFSDK_PageView() {
55 #ifndef PDF_ENABLE_XFA
56 // The call to |ReleaseAnnot| can cause the page pointed to by |m_page| to
57 // be freed, which will cause issues if we try to cleanup the pageview pointer
58 // in |m_page|. So, reset the pageview pointer before doing anything else.
59 m_page->SetView(nullptr);
60 #endif // PDF_ENABLE_XFA
61
62 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
63 m_pFormFillEnv->GetAnnotHandlerMgr();
64 for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray)
65 pAnnotHandlerMgr->ReleaseAnnot(pAnnot);
66
67 m_SDKAnnotArray.clear();
68 m_pAnnotList.reset();
69
70 #ifndef PDF_ENABLE_XFA
71 if (m_bOwnsPage)
72 delete m_page;
73 #endif // PDF_ENABLE_XFA
74 }
75
PageView_OnDraw(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device,CPDF_RenderOptions * pOptions,const FX_RECT & pClip)76 void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice,
77 CFX_Matrix* pUser2Device,
78 #ifdef PDF_ENABLE_XFA
79 CPDF_RenderOptions* pOptions,
80 const FX_RECT& pClip) {
81 #else
82 CPDF_RenderOptions* pOptions) {
83 #endif // PDF_ENABLE_XFA
84 m_curMatrix = *pUser2Device;
85
86 #ifdef PDF_ENABLE_XFA
87 CPDFXFA_Page* pPage = GetPDFXFAPage();
88 if (!pPage)
89 return;
90
91 if (pPage->GetContext()->GetFormType() == FormType::kXFAFull) {
92 CFX_RectF rectClip(
93 static_cast<float>(pClip.left), static_cast<float>(pClip.top),
94 static_cast<float>(pClip.Width()), static_cast<float>(pClip.Height()));
95
96 CXFA_Graphics gs(pDevice);
97 gs.SetClipRect(rectClip);
98
99 CXFA_FFPageView* xfaView = pPage->GetXFAPageView();
100 CXFA_RenderContext renderContext(xfaView, rectClip, *pUser2Device);
101 renderContext.DoRender(&gs);
102
103 CXFA_FFDocView* docView = xfaView->GetDocView();
104 if (!docView)
105 return;
106 CPDFSDK_Annot* annot = GetFocusAnnot();
107 if (!annot)
108 return;
109 // Render the focus widget
110 docView->GetWidgetHandler()->RenderWidget(annot->GetXFAWidget(), &gs,
111 *pUser2Device, false);
112 return;
113 }
114 #endif // PDF_ENABLE_XFA
115
116 // for pdf/static xfa.
117 CPDFSDK_AnnotIteration annotIteration(this, true);
118 for (const auto& pSDKAnnot : annotIteration) {
119 m_pFormFillEnv->GetAnnotHandlerMgr()->Annot_OnDraw(
120 this, pSDKAnnot.Get(), pDevice, pUser2Device,
121 pOptions->GetDrawAnnots());
122 }
123 }
124
125 CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(const CFX_PointF& point) {
126 CPDFSDK_AnnotHandlerMgr* pAnnotMgr = m_pFormFillEnv->GetAnnotHandlerMgr();
127 CPDFSDK_AnnotIteration annotIteration(this, false);
128 for (const auto& pSDKAnnot : annotIteration) {
129 CFX_FloatRect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot.Get());
130 if (pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::POPUP)
131 continue;
132 if (rc.Contains(point))
133 return pSDKAnnot.Get();
134 }
135 return nullptr;
136 }
137
138 CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(const CFX_PointF& point) {
139 CPDFSDK_AnnotHandlerMgr* pAnnotMgr = m_pFormFillEnv->GetAnnotHandlerMgr();
140 CPDFSDK_AnnotIteration annotIteration(this, false);
141 for (const auto& pSDKAnnot : annotIteration) {
142 bool bHitTest = pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET;
143 #ifdef PDF_ENABLE_XFA
144 bHitTest = bHitTest ||
145 pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::XFAWIDGET;
146 #endif // PDF_ENABLE_XFA
147 if (bHitTest) {
148 pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot.Get());
149 if (pAnnotMgr->Annot_OnHitTest(this, pSDKAnnot.Get(), point))
150 return pSDKAnnot.Get();
151 }
152 }
153 return nullptr;
154 }
155
156 #ifdef PDF_ENABLE_XFA
157 CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CXFA_FFWidget* pPDFAnnot) {
158 if (!pPDFAnnot)
159 return nullptr;
160
161 CPDFSDK_Annot* pSDKAnnot = GetAnnotByXFAWidget(pPDFAnnot);
162 if (pSDKAnnot)
163 return pSDKAnnot;
164
165 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = m_pFormFillEnv->GetAnnotHandlerMgr();
166 pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this);
167 if (!pSDKAnnot)
168 return nullptr;
169
170 m_SDKAnnotArray.push_back(pSDKAnnot);
171 return pSDKAnnot;
172 }
173
174 bool CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot) {
175 if (!pAnnot)
176 return false;
177
178 CPDFXFA_Page* pPage = pAnnot->GetPDFXFAPage();
179 if (!pPage || !pPage->GetContext()->ContainsXFAForm())
180 return false;
181
182 CPDFSDK_Annot::ObservedPtr pObserved(pAnnot);
183 if (GetFocusAnnot() == pAnnot)
184 m_pFormFillEnv->KillFocusAnnot(0); // May invoke JS, invalidating pAnnot.
185
186 if (pObserved) {
187 CPDFSDK_AnnotHandlerMgr* pAnnotHandler =
188 m_pFormFillEnv->GetAnnotHandlerMgr();
189 if (pAnnotHandler)
190 pAnnotHandler->ReleaseAnnot(pObserved.Get());
191 }
192
193 auto it = std::find(m_SDKAnnotArray.begin(), m_SDKAnnotArray.end(), pAnnot);
194 if (it != m_SDKAnnotArray.end())
195 m_SDKAnnotArray.erase(it);
196 if (m_pCaptureWidget.Get() == pAnnot)
197 m_pCaptureWidget.Reset();
198
199 return true;
200 }
201 #endif // PDF_ENABLE_XFA
202
203 CPDF_Document* CPDFSDK_PageView::GetPDFDocument() {
204 if (m_page) {
205 #ifdef PDF_ENABLE_XFA
206 return m_page->GetContext()->GetPDFDoc();
207 #else // PDF_ENABLE_XFA
208 return m_page->m_pDocument.Get();
209 #endif // PDF_ENABLE_XFA
210 }
211 return nullptr;
212 }
213
214 CPDF_Page* CPDFSDK_PageView::GetPDFPage() const {
215 #ifdef PDF_ENABLE_XFA
216 return m_page ? m_page->GetPDFPage() : nullptr;
217 #else // PDF_ENABLE_XFA
218 return m_page;
219 #endif // PDF_ENABLE_XFA
220 }
221
222 CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(CPDF_Dictionary* pDict) {
223 for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray) {
224 if (pAnnot->GetPDFAnnot()->GetAnnotDict() == pDict)
225 return pAnnot;
226 }
227 return nullptr;
228 }
229
230 #ifdef PDF_ENABLE_XFA
231 CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByXFAWidget(CXFA_FFWidget* hWidget) {
232 if (!hWidget)
233 return nullptr;
234
235 for (CPDFSDK_Annot* pAnnot : m_SDKAnnotArray) {
236 if (pAnnot->GetXFAWidget() == hWidget)
237 return pAnnot;
238 }
239 return nullptr;
240 }
241 #endif // PDF_ENABLE_XFA
242
243 WideString CPDFSDK_PageView::GetSelectedText() {
244 if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
245 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
246 m_pFormFillEnv->GetAnnotHandlerMgr();
247 return pAnnotHandlerMgr->Annot_GetSelectedText(pAnnot);
248 }
249
250 return WideString();
251 }
252
253 void CPDFSDK_PageView::ReplaceSelection(const WideString& text) {
254 if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
255 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
256 m_pFormFillEnv->GetAnnotHandlerMgr();
257 pAnnotHandlerMgr->Annot_ReplaceSelection(pAnnot, text);
258 }
259 }
260
261 bool CPDFSDK_PageView::OnFocus(const CFX_PointF& point, uint32_t nFlag) {
262 CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point));
263 if (!pAnnot) {
264 m_pFormFillEnv->KillFocusAnnot(nFlag);
265 return false;
266 }
267
268 m_pFormFillEnv->SetFocusAnnot(&pAnnot);
269 return true;
270 }
271
272 bool CPDFSDK_PageView::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
273 CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point));
274 if (!pAnnot) {
275 m_pFormFillEnv->KillFocusAnnot(nFlag);
276 return false;
277 }
278
279 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
280 m_pFormFillEnv->GetAnnotHandlerMgr();
281 if (!pAnnotHandlerMgr->Annot_OnLButtonDown(this, &pAnnot, nFlag, point))
282 return false;
283
284 if (!pAnnot)
285 return false;
286
287 m_pFormFillEnv->SetFocusAnnot(&pAnnot);
288 return true;
289 }
290
291 #ifdef PDF_ENABLE_XFA
292 bool CPDFSDK_PageView::OnRButtonDown(const CFX_PointF& point, uint32_t nFlag) {
293 CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point));
294 if (!pAnnot)
295 return false;
296
297 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
298 m_pFormFillEnv->GetAnnotHandlerMgr();
299 bool ok = pAnnotHandlerMgr->Annot_OnRButtonDown(this, &pAnnot, nFlag, point);
300 if (!pAnnot)
301 return false;
302
303 if (ok)
304 m_pFormFillEnv->SetFocusAnnot(&pAnnot);
305
306 return true;
307 }
308
309 bool CPDFSDK_PageView::OnRButtonUp(const CFX_PointF& point, uint32_t nFlag) {
310 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
311 m_pFormFillEnv->GetAnnotHandlerMgr();
312 CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXWidgetAtPoint(point));
313 if (!pFXAnnot)
314 return false;
315
316 if (pAnnotHandlerMgr->Annot_OnRButtonUp(this, &pFXAnnot, nFlag, point))
317 m_pFormFillEnv->SetFocusAnnot(&pFXAnnot);
318
319 return true;
320 }
321 #endif // PDF_ENABLE_XFA
322
323 bool CPDFSDK_PageView::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
324 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
325 m_pFormFillEnv->GetAnnotHandlerMgr();
326 CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXWidgetAtPoint(point));
327 CPDFSDK_Annot::ObservedPtr pFocusAnnot(GetFocusAnnot());
328 if (pFocusAnnot && pFocusAnnot != pFXAnnot) {
329 // Last focus Annot gets a chance to handle the event.
330 if (pAnnotHandlerMgr->Annot_OnLButtonUp(this, &pFocusAnnot, nFlag, point))
331 return true;
332 }
333 return pFXAnnot &&
334 pAnnotHandlerMgr->Annot_OnLButtonUp(this, &pFXAnnot, nFlag, point);
335 }
336
337 bool CPDFSDK_PageView::OnMouseMove(const CFX_PointF& point, int nFlag) {
338 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
339 m_pFormFillEnv->GetAnnotHandlerMgr();
340 CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXAnnotAtPoint(point));
341
342 if (m_bOnWidget && m_pCaptureWidget != pFXAnnot)
343 ExitWidget(pAnnotHandlerMgr, true, nFlag);
344
345 if (pFXAnnot) {
346 if (!m_bOnWidget) {
347 EnterWidget(pAnnotHandlerMgr, &pFXAnnot, nFlag);
348
349 // Annot_OnMouseEnter may have invalidated pFXAnnot.
350 if (!pFXAnnot) {
351 ExitWidget(pAnnotHandlerMgr, false, nFlag);
352 return true;
353 }
354 }
355
356 pAnnotHandlerMgr->Annot_OnMouseMove(this, &pFXAnnot, nFlag, point);
357 return true;
358 }
359
360 return false;
361 }
362
363 void CPDFSDK_PageView::EnterWidget(CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr,
364 CPDFSDK_Annot::ObservedPtr* pAnnot,
365 uint32_t nFlag) {
366 m_bOnWidget = true;
367 m_pCaptureWidget.Reset(pAnnot->Get());
368 pAnnotHandlerMgr->Annot_OnMouseEnter(this, pAnnot, nFlag);
369 }
370
371 void CPDFSDK_PageView::ExitWidget(CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr,
372 bool callExitCallback,
373 uint32_t nFlag) {
374 m_bOnWidget = false;
375 if (m_pCaptureWidget) {
376 if (callExitCallback)
377 pAnnotHandlerMgr->Annot_OnMouseExit(this, &m_pCaptureWidget, nFlag);
378
379 m_pCaptureWidget.Reset();
380 }
381 }
382
383 bool CPDFSDK_PageView::OnMouseWheel(double deltaX,
384 double deltaY,
385 const CFX_PointF& point,
386 int nFlag) {
387 CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point));
388 if (!pAnnot)
389 return false;
390
391 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
392 m_pFormFillEnv->GetAnnotHandlerMgr();
393 return pAnnotHandlerMgr->Annot_OnMouseWheel(this, &pAnnot, nFlag,
394 static_cast<int>(deltaY), point);
395 }
396
397 bool CPDFSDK_PageView::OnChar(int nChar, uint32_t nFlag) {
398 if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
399 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
400 m_pFormFillEnv->GetAnnotHandlerMgr();
401 return pAnnotHandlerMgr->Annot_OnChar(pAnnot, nChar, nFlag);
402 }
403
404 return false;
405 }
406
407 bool CPDFSDK_PageView::OnKeyDown(int nKeyCode, int nFlag) {
408 if (CPDFSDK_Annot* pAnnot = GetFocusAnnot()) {
409 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
410 m_pFormFillEnv->GetAnnotHandlerMgr();
411 return pAnnotHandlerMgr->Annot_OnKeyDown(pAnnot, nKeyCode, nFlag);
412 }
413 return false;
414 }
415
416 bool CPDFSDK_PageView::OnKeyUp(int nKeyCode, int nFlag) {
417 return false;
418 }
419
420 void CPDFSDK_PageView::LoadFXAnnots() {
421 CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr =
422 m_pFormFillEnv->GetAnnotHandlerMgr();
423
424 AutoRestorer<bool> lock(&m_bLocked);
425 m_bLocked = true;
426
427 #ifdef PDF_ENABLE_XFA
428 RetainPtr<CPDFXFA_Page> protector(m_page);
429 if (m_pFormFillEnv->GetXFAContext()->GetFormType() == FormType::kXFAFull) {
430 CXFA_FFPageView* pageView = m_page->GetXFAPageView();
431 std::unique_ptr<IXFA_WidgetIterator> pWidgetHandler(
432 pageView->CreateWidgetIterator(
433 XFA_TRAVERSEWAY_Form,
434 XFA_WidgetStatus_Visible | XFA_WidgetStatus_Viewable));
435 if (!pWidgetHandler) {
436 return;
437 }
438
439 while (CXFA_FFWidget* pXFAAnnot = pWidgetHandler->MoveToNext()) {
440 CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pXFAAnnot, this);
441 if (!pAnnot)
442 continue;
443 m_SDKAnnotArray.push_back(pAnnot);
444 pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
445 }
446
447 return;
448 }
449 #endif // PDF_ENABLE_XFA
450
451 CPDF_Page* pPage = GetPDFPage();
452 ASSERT(pPage);
453 bool bUpdateAP = CPDF_InterForm::IsUpdateAPEnabled();
454 // Disable the default AP construction.
455 CPDF_InterForm::SetUpdateAP(false);
456 m_pAnnotList = pdfium::MakeUnique<CPDF_AnnotList>(pPage);
457 CPDF_InterForm::SetUpdateAP(bUpdateAP);
458
459 const size_t nCount = m_pAnnotList->Count();
460 for (size_t i = 0; i < nCount; ++i) {
461 CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
462 CheckUnSupportAnnot(GetPDFDocument(), pPDFAnnot);
463 CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
464 if (!pAnnot)
465 continue;
466 m_SDKAnnotArray.push_back(pAnnot);
467 pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
468 }
469 }
470
471 void CPDFSDK_PageView::UpdateRects(const std::vector<CFX_FloatRect>& rects) {
472 for (const auto& rc : rects)
473 m_pFormFillEnv->Invalidate(m_page, rc.GetOuterRect());
474 }
475
476 void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot) {
477 CFX_FloatRect rcWindow = pAnnot->GetRect();
478 m_pFormFillEnv->Invalidate(m_page, rcWindow.GetOuterRect());
479 }
480
481 int CPDFSDK_PageView::GetPageIndex() const {
482 if (!m_page)
483 return -1;
484
485 #ifdef PDF_ENABLE_XFA
486 switch (m_page->GetContext()->GetFormType()) {
487 case FormType::kXFAFull: {
488 CXFA_FFPageView* pPageView = m_page->GetXFAPageView();
489 return pPageView ? pPageView->GetPageIndex() : -1;
490 }
491 case FormType::kNone:
492 case FormType::kAcroForm:
493 case FormType::kXFAForeground:
494 break;
495 }
496 #endif // PDF_ENABLE_XFA
497 return GetPageIndexForStaticPDF();
498 }
499
500 bool CPDFSDK_PageView::IsValidAnnot(const CPDF_Annot* p) const {
501 if (!p)
502 return false;
503
504 const auto& annots = m_pAnnotList->All();
505 auto it = std::find_if(annots.begin(), annots.end(),
506 [p](const std::unique_ptr<CPDF_Annot>& annot) {
507 return annot.get() == p;
508 });
509 return it != annots.end();
510 }
511
512 bool CPDFSDK_PageView::IsValidSDKAnnot(const CPDFSDK_Annot* p) const {
513 if (!p)
514 return false;
515 return pdfium::ContainsValue(m_SDKAnnotArray, p);
516 }
517
518 CPDFSDK_Annot* CPDFSDK_PageView::GetFocusAnnot() {
519 CPDFSDK_Annot* pFocusAnnot = m_pFormFillEnv->GetFocusAnnot();
520 return IsValidSDKAnnot(pFocusAnnot) ? pFocusAnnot : nullptr;
521 }
522
523 int CPDFSDK_PageView::GetPageIndexForStaticPDF() const {
524 CPDF_Dictionary* pDict = GetPDFPage()->m_pFormDict.Get();
525 CPDF_Document* pDoc = m_pFormFillEnv->GetPDFDocument();
526 return (pDoc && pDict) ? pDoc->GetPageIndex(pDict->GetObjNum()) : -1;
527 }
528