OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "render_int.h" | 7 #include "render_int.h" |
8 | 8 |
9 #include "core/include/fpdfapi/fpdf_module.h" | 9 #include "core/include/fpdfapi/fpdf_module.h" |
10 #include "core/include/fpdfapi/fpdf_render.h" | 10 #include "core/include/fpdfapi/fpdf_render.h" |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 m_pCurObj = pObj; | 305 m_pCurObj = pObj; |
306 if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull() && | 306 if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull() && |
307 !m_Options.m_pOCContext->CheckObjectVisible(pObj)) { | 307 !m_Options.m_pOCContext->CheckObjectVisible(pObj)) { |
308 return FALSE; | 308 return FALSE; |
309 } | 309 } |
310 | 310 |
311 ProcessClipPath(pObj->m_ClipPath, pObj2Device); | 311 ProcessClipPath(pObj->m_ClipPath, pObj2Device); |
312 if (ProcessTransparency(pObj, pObj2Device)) | 312 if (ProcessTransparency(pObj, pObj2Device)) |
313 return FALSE; | 313 return FALSE; |
314 | 314 |
315 if (pObj->m_Type == PDFPAGE_IMAGE) { | 315 if (pObj->m_Type == CPDF_PageObject::IMAGE) { |
316 m_pObjectRenderer.reset(IPDF_ObjectRenderer::Create(pObj->m_Type)); | 316 m_pObjectRenderer.reset(IPDF_ObjectRenderer::Create(pObj->m_Type)); |
317 if (!m_pObjectRenderer->Start(this, pObj, pObj2Device, FALSE)) { | 317 if (!m_pObjectRenderer->Start(this, pObj, pObj2Device, FALSE)) { |
318 if (!m_pObjectRenderer->m_Result) | 318 if (!m_pObjectRenderer->m_Result) |
319 DrawObjWithBackground(pObj, pObj2Device); | 319 DrawObjWithBackground(pObj, pObj2Device); |
320 m_pObjectRenderer.reset(); | 320 m_pObjectRenderer.reset(); |
321 return FALSE; | 321 return FALSE; |
322 } | 322 } |
323 return ContinueSingleObject(pObj, pObj2Device, pPause); | 323 return ContinueSingleObject(pObj, pObj2Device, pPause); |
324 } | 324 } |
325 | 325 |
326 ProcessObjectNoClip(pObj, pObj2Device); | 326 ProcessObjectNoClip(pObj, pObj2Device); |
327 return FALSE; | 327 return FALSE; |
328 } | 328 } |
329 | 329 |
330 IPDF_ObjectRenderer* IPDF_ObjectRenderer::Create(int type) { | 330 IPDF_ObjectRenderer* IPDF_ObjectRenderer::Create(int type) { |
331 if (type != PDFPAGE_IMAGE) { | 331 if (type != CPDF_PageObject::IMAGE) { |
332 return NULL; | 332 return NULL; |
333 } | 333 } |
334 return new CPDF_ImageRenderer; | 334 return new CPDF_ImageRenderer; |
335 } | 335 } |
336 FX_BOOL CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj, | 336 FX_BOOL CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj, |
337 const CFX_Matrix* pObj2Device, | 337 const CFX_Matrix* pObj2Device, |
338 FX_BOOL bLogical, | 338 FX_BOOL bLogical, |
339 FX_RECT& rect) const { | 339 FX_RECT& rect) const { |
340 rect = pObj->GetBBox(pObj2Device); | 340 rect = pObj->GetBBox(pObj2Device); |
341 FX_RECT rtClip = m_pDevice->GetClipBox(); | 341 FX_RECT rtClip = m_pDevice->GetClipBox(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 } else if (m_DitherBits == 4) { | 374 } else if (m_DitherBits == 4) { |
375 static FX_ARGB pal[16] = {0, 17, 34, 51, 68, 85, 102, 119, | 375 static FX_ARGB pal[16] = {0, 17, 34, 51, 68, 85, 102, 119, |
376 136, 153, 170, 187, 204, 221, 238, 255}; | 376 136, 153, 170, 187, 204, 221, 238, 255}; |
377 pBitmap->DitherFS(pal, 16, &rect); | 377 pBitmap->DitherFS(pal, 16, &rect); |
378 } | 378 } |
379 } | 379 } |
380 void CPDF_RenderStatus::ProcessObjectNoClip(const CPDF_PageObject* pObj, | 380 void CPDF_RenderStatus::ProcessObjectNoClip(const CPDF_PageObject* pObj, |
381 const CFX_Matrix* pObj2Device) { | 381 const CFX_Matrix* pObj2Device) { |
382 FX_BOOL bRet = FALSE; | 382 FX_BOOL bRet = FALSE; |
383 switch (pObj->m_Type) { | 383 switch (pObj->m_Type) { |
384 case PDFPAGE_TEXT: | 384 case CPDF_PageObject::TEXT: |
385 bRet = ProcessText((CPDF_TextObject*)pObj, pObj2Device, NULL); | 385 bRet = ProcessText((CPDF_TextObject*)pObj, pObj2Device, NULL); |
386 break; | 386 break; |
387 case PDFPAGE_PATH: | 387 case CPDF_PageObject::PATH: |
388 bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device); | 388 bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device); |
389 break; | 389 break; |
390 case PDFPAGE_IMAGE: | 390 case CPDF_PageObject::IMAGE: |
391 bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device); | 391 bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device); |
392 break; | 392 break; |
393 case PDFPAGE_SHADING: | 393 case CPDF_PageObject::SHADING: |
394 bRet = ProcessShading((CPDF_ShadingObject*)pObj, pObj2Device); | 394 bRet = ProcessShading((CPDF_ShadingObject*)pObj, pObj2Device); |
395 break; | 395 break; |
396 case PDFPAGE_FORM: | 396 case CPDF_PageObject::FORM: |
397 bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device); | 397 bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device); |
398 break; | 398 break; |
399 } | 399 } |
400 if (!bRet) { | 400 if (!bRet) { |
401 DrawObjWithBackground(pObj, pObj2Device); | 401 DrawObjWithBackground(pObj, pObj2Device); |
402 } | 402 } |
403 } | 403 } |
404 FX_BOOL CPDF_RenderStatus::DrawObjWithBlend(const CPDF_PageObject* pObj, | 404 FX_BOOL CPDF_RenderStatus::DrawObjWithBlend(const CPDF_PageObject* pObj, |
405 const CFX_Matrix* pObj2Device) { | 405 const CFX_Matrix* pObj2Device) { |
406 FX_BOOL bRet = FALSE; | 406 FX_BOOL bRet = FALSE; |
407 switch (pObj->m_Type) { | 407 switch (pObj->m_Type) { |
408 case PDFPAGE_PATH: | 408 case CPDF_PageObject::PATH: |
409 bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device); | 409 bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device); |
410 break; | 410 break; |
411 case PDFPAGE_IMAGE: | 411 case CPDF_PageObject::IMAGE: |
412 bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device); | 412 bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device); |
413 break; | 413 break; |
414 case PDFPAGE_FORM: | 414 case CPDF_PageObject::FORM: |
415 bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device); | 415 bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device); |
416 break; | 416 break; |
| 417 default: |
| 418 break; |
417 } | 419 } |
418 return bRet; | 420 return bRet; |
419 } | 421 } |
420 void CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix& matrix) const { | 422 void CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix& matrix) const { |
421 CFX_Matrix dCTM = m_pDevice->GetCTM(); | 423 CFX_Matrix dCTM = m_pDevice->GetCTM(); |
422 matrix.a *= FXSYS_fabs(dCTM.a); | 424 matrix.a *= FXSYS_fabs(dCTM.a); |
423 matrix.d *= FXSYS_fabs(dCTM.d); | 425 matrix.d *= FXSYS_fabs(dCTM.d); |
424 } | 426 } |
425 void CPDF_RenderStatus::DrawObjWithBackground(const CPDF_PageObject* pObj, | 427 void CPDF_RenderStatus::DrawObjWithBackground(const CPDF_PageObject* pObj, |
426 const CFX_Matrix* pObj2Device) { | 428 const CFX_Matrix* pObj2Device) { |
427 FX_RECT rect; | 429 FX_RECT rect; |
428 if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) { | 430 if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) { |
429 return; | 431 return; |
430 } | 432 } |
431 int res = 300; | 433 int res = 300; |
432 if (pObj->m_Type == PDFPAGE_IMAGE && | 434 if (pObj->m_Type == CPDF_PageObject::IMAGE && |
433 m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) { | 435 m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) { |
434 res = 0; | 436 res = 0; |
435 } | 437 } |
436 CPDF_ScaledRenderBuffer buffer; | 438 CPDF_ScaledRenderBuffer buffer; |
437 if (!buffer.Initialize(m_pContext, m_pDevice, rect, pObj, &m_Options, res)) { | 439 if (!buffer.Initialize(m_pContext, m_pDevice, rect, pObj, &m_Options, res)) { |
438 return; | 440 return; |
439 } | 441 } |
440 CFX_Matrix matrix = *pObj2Device; | 442 CFX_Matrix matrix = *pObj2Device; |
441 matrix.Concat(*buffer.GetMatrix()); | 443 matrix.Concat(*buffer.GetMatrix()); |
442 GetScaledMatrix(matrix); | 444 GetScaledMatrix(matrix); |
443 CPDF_Dictionary* pFormResource = NULL; | 445 CPDF_Dictionary* pFormResource = NULL; |
444 if (pObj->m_Type == PDFPAGE_FORM) { | 446 if (pObj->m_Type == CPDF_PageObject::FORM) { |
445 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj; | 447 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj; |
446 if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) { | 448 if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) { |
447 pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources"); | 449 pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources"); |
448 } | 450 } |
449 } | 451 } |
450 CPDF_RenderStatus status; | 452 CPDF_RenderStatus status; |
451 status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, | 453 status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, |
452 NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, | 454 NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, |
453 pFormResource); | 455 pFormResource); |
454 status.RenderSingleObject(pObj, &matrix); | 456 status.RenderSingleObject(pObj, &matrix); |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 const CFX_Matrix* pObj2Device) { | 720 const CFX_Matrix* pObj2Device) { |
719 const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState; | 721 const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState; |
720 int blend_type = | 722 int blend_type = |
721 pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL; | 723 pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL; |
722 if (blend_type == FXDIB_BLEND_UNSUPPORTED) { | 724 if (blend_type == FXDIB_BLEND_UNSUPPORTED) { |
723 return TRUE; | 725 return TRUE; |
724 } | 726 } |
725 CPDF_Dictionary* pSMaskDict = | 727 CPDF_Dictionary* pSMaskDict = |
726 pGeneralState ? ToDictionary(pGeneralState->m_pSoftMask) : NULL; | 728 pGeneralState ? ToDictionary(pGeneralState->m_pSoftMask) : NULL; |
727 if (pSMaskDict) { | 729 if (pSMaskDict) { |
728 if (pPageObj->m_Type == PDFPAGE_IMAGE && | 730 if (pPageObj->m_Type == CPDF_PageObject::IMAGE && |
729 ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDict()->KeyExist("SMask")) { | 731 ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDict()->KeyExist("SMask")) { |
730 pSMaskDict = NULL; | 732 pSMaskDict = NULL; |
731 } | 733 } |
732 } | 734 } |
733 CPDF_Dictionary* pFormResource = NULL; | 735 CPDF_Dictionary* pFormResource = NULL; |
734 FX_FLOAT group_alpha = 1.0f; | 736 FX_FLOAT group_alpha = 1.0f; |
735 int Transparency = m_Transparency; | 737 int Transparency = m_Transparency; |
736 FX_BOOL bGroupTransparent = FALSE; | 738 FX_BOOL bGroupTransparent = FALSE; |
737 if (pPageObj->m_Type == PDFPAGE_FORM) { | 739 if (pPageObj->m_Type == CPDF_PageObject::FORM) { |
738 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj; | 740 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj; |
739 const CPDF_GeneralStateData* pStateData = | 741 const CPDF_GeneralStateData* pStateData = |
740 pFormObj->m_GeneralState.GetObject(); | 742 pFormObj->m_GeneralState.GetObject(); |
741 if (pStateData) { | 743 if (pStateData) { |
742 group_alpha = pStateData->m_FillAlpha; | 744 group_alpha = pStateData->m_FillAlpha; |
743 } | 745 } |
744 Transparency = pFormObj->m_pForm->m_Transparency; | 746 Transparency = pFormObj->m_pForm->m_Transparency; |
745 bGroupTransparent = !!(Transparency & PDFTRANS_ISOLATED); | 747 bGroupTransparent = !!(Transparency & PDFTRANS_ISOLATED); |
746 if (pFormObj->m_pForm->m_pFormDict) { | 748 if (pFormObj->m_pForm->m_pFormDict) { |
747 pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources"); | 749 pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources"); |
748 } | 750 } |
749 } | 751 } |
750 FX_BOOL bTextClip = FALSE; | 752 FX_BOOL bTextClip = FALSE; |
751 if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() && | 753 if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() && |
752 m_pDevice->GetDeviceClass() == FXDC_DISPLAY && | 754 m_pDevice->GetDeviceClass() == FXDC_DISPLAY && |
753 !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) { | 755 !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) { |
754 bTextClip = TRUE; | 756 bTextClip = TRUE; |
755 } | 757 } |
756 if ((m_Options.m_Flags & RENDER_OVERPRINT) && | 758 if ((m_Options.m_Flags & RENDER_OVERPRINT) && |
757 pPageObj->m_Type == PDFPAGE_IMAGE && pGeneralState && | 759 pPageObj->m_Type == CPDF_PageObject::IMAGE && pGeneralState && |
758 pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) { | 760 pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) { |
759 CPDF_Document* pDocument = NULL; | 761 CPDF_Document* pDocument = NULL; |
760 CPDF_Page* pPage = NULL; | 762 CPDF_Page* pPage = NULL; |
761 if (m_pContext->GetPageCache()) { | 763 if (m_pContext->GetPageCache()) { |
762 pPage = m_pContext->GetPageCache()->GetPage(); | 764 pPage = m_pContext->GetPageCache()->GetPage(); |
763 pDocument = pPage->m_pDocument; | 765 pDocument = pPage->m_pDocument; |
764 } else { | 766 } else { |
765 pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument(); | 767 pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument(); |
766 } | 768 } |
767 CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL; | 769 CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
867 bitmap->MultiplyAlpha(pSMaskSource.get()); | 869 bitmap->MultiplyAlpha(pSMaskSource.get()); |
868 } | 870 } |
869 if (pTextMask) { | 871 if (pTextMask) { |
870 bitmap->MultiplyAlpha(pTextMask.get()); | 872 bitmap->MultiplyAlpha(pTextMask.get()); |
871 pTextMask.reset(); | 873 pTextMask.reset(); |
872 } | 874 } |
873 if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) { | 875 if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) { |
874 bitmap->MultiplyAlpha((int32_t)(group_alpha * 255)); | 876 bitmap->MultiplyAlpha((int32_t)(group_alpha * 255)); |
875 } | 877 } |
876 Transparency = m_Transparency; | 878 Transparency = m_Transparency; |
877 if (pPageObj->m_Type == PDFPAGE_FORM) { | 879 if (pPageObj->m_Type == CPDF_PageObject::FORM) { |
878 Transparency |= PDFTRANS_GROUP; | 880 Transparency |= PDFTRANS_GROUP; |
879 } | 881 } |
880 CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type, | 882 CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type, |
881 Transparency); | 883 Transparency); |
882 return TRUE; | 884 return TRUE; |
883 } | 885 } |
884 | 886 |
885 CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj, | 887 CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj, |
886 const FX_RECT& rect, | 888 const FX_RECT& rect, |
887 int& left, | 889 int& left, |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 CPDF_PageObject* pCurObj = | 1113 CPDF_PageObject* pCurObj = |
1112 pLayer->m_pObjectList->GetObjectAt(m_ObjectPos); | 1114 pLayer->m_pObjectList->GetObjectAt(m_ObjectPos); |
1113 if (pCurObj && pCurObj->m_Left <= m_ClipRect.right && | 1115 if (pCurObj && pCurObj->m_Left <= m_ClipRect.right && |
1114 pCurObj->m_Right >= m_ClipRect.left && | 1116 pCurObj->m_Right >= m_ClipRect.left && |
1115 pCurObj->m_Bottom <= m_ClipRect.top && | 1117 pCurObj->m_Bottom <= m_ClipRect.top && |
1116 pCurObj->m_Top >= m_ClipRect.bottom) { | 1118 pCurObj->m_Top >= m_ClipRect.bottom) { |
1117 if (m_pRenderStatus->ContinueSingleObject(pCurObj, &pLayer->m_Matrix, | 1119 if (m_pRenderStatus->ContinueSingleObject(pCurObj, &pLayer->m_Matrix, |
1118 pPause)) { | 1120 pPause)) { |
1119 return; | 1121 return; |
1120 } | 1122 } |
1121 if (pCurObj->m_Type == PDFPAGE_IMAGE && | 1123 if (pCurObj->m_Type == CPDF_PageObject::IMAGE && |
1122 m_pRenderStatus->m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { | 1124 m_pRenderStatus->m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { |
1123 m_pContext->GetPageCache()->CacheOptimization( | 1125 m_pContext->GetPageCache()->CacheOptimization( |
1124 m_pRenderStatus->m_Options.m_dwLimitCacheSize); | 1126 m_pRenderStatus->m_Options.m_dwLimitCacheSize); |
1125 } | 1127 } |
1126 if (pCurObj->m_Type == PDFPAGE_FORM || | 1128 if (pCurObj->m_Type == CPDF_PageObject::FORM || |
1127 pCurObj->m_Type == PDFPAGE_SHADING) { | 1129 pCurObj->m_Type == CPDF_PageObject::SHADING) { |
1128 objs_to_go = 0; | 1130 objs_to_go = 0; |
1129 } else { | 1131 } else { |
1130 objs_to_go--; | 1132 objs_to_go--; |
1131 } | 1133 } |
1132 } | 1134 } |
1133 m_ObjectIndex++; | 1135 m_ObjectIndex++; |
1134 pLayer->m_pObjectList->GetNextObject(m_ObjectPos); | 1136 pLayer->m_pObjectList->GetNextObject(m_ObjectPos); |
1135 if (objs_to_go == 0) { | 1137 if (objs_to_go == 0) { |
1136 if (pPause && pPause->NeedToPauseNow()) { | 1138 if (pPause && pPause->NeedToPauseNow()) { |
1137 return; | 1139 return; |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict) { | 1398 item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict) { |
1397 CPDF_Dictionary* pOCG = | 1399 CPDF_Dictionary* pOCG = |
1398 ToDictionary(static_cast<CPDF_Object*>(item.GetParam())); | 1400 ToDictionary(static_cast<CPDF_Object*>(item.GetParam())); |
1399 if (!CheckOCGVisible(pOCG)) { | 1401 if (!CheckOCGVisible(pOCG)) { |
1400 return FALSE; | 1402 return FALSE; |
1401 } | 1403 } |
1402 } | 1404 } |
1403 } | 1405 } |
1404 return TRUE; | 1406 return TRUE; |
1405 } | 1407 } |
OLD | NEW |