• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "core/fpdfdoc/cpdf_dest.h"
8 
9 #include <algorithm>
10 
11 #include "core/fpdfapi/parser/cpdf_array.h"
12 #include "core/fpdfapi/parser/cpdf_document.h"
13 #include "core/fpdfapi/parser/cpdf_name.h"
14 #include "core/fpdfapi/parser/cpdf_number.h"
15 
16 namespace {
17 
18 // These arrays are indexed by the PDFDEST_VIEW_* constants.
19 
20 // Last element is a sentinel.
21 const char* const g_sZoomModes[] = {"Unknown", "XYZ",  "Fit",  "FitH",
22                                     "FitV",    "FitR", "FitB", "FitBH",
23                                     "FitBV",   nullptr};
24 
25 const uint8_t g_sZoomModeMaxParamCount[] = {0, 3, 0, 1, 1, 4, 0, 1, 1, 0};
26 
27 static_assert(FX_ArraySize(g_sZoomModes) ==
28                   FX_ArraySize(g_sZoomModeMaxParamCount),
29               "Zoom mode count Mismatch");
30 
31 }  // namespace
32 
CPDF_Dest()33 CPDF_Dest::CPDF_Dest() {}
34 
CPDF_Dest(const CPDF_Array * pArray)35 CPDF_Dest::CPDF_Dest(const CPDF_Array* pArray) : m_pArray(pArray) {}
36 
37 CPDF_Dest::CPDF_Dest(const CPDF_Dest& that) = default;
38 
~CPDF_Dest()39 CPDF_Dest::~CPDF_Dest() {}
40 
GetDestPageIndex(CPDF_Document * pDoc) const41 int CPDF_Dest::GetDestPageIndex(CPDF_Document* pDoc) const {
42   if (!m_pArray)
43     return -1;
44 
45   const CPDF_Object* pPage = m_pArray->GetDirectObjectAt(0);
46   if (!pPage)
47     return -1;
48 
49   if (pPage->IsNumber())
50     return pPage->GetInteger();
51 
52   if (!pPage->IsDictionary())
53     return -1;
54 
55   return pDoc->GetPageIndex(pPage->GetObjNum());
56 }
57 
GetZoomMode() const58 int CPDF_Dest::GetZoomMode() const {
59   if (!m_pArray)
60     return 0;
61 
62   const CPDF_Object* pArray = m_pArray->GetDirectObjectAt(1);
63   if (!pArray)
64     return 0;
65 
66   ByteString mode = pArray->GetString();
67   for (int i = 1; g_sZoomModes[i]; ++i) {
68     if (mode == g_sZoomModes[i])
69       return i;
70   }
71 
72   return 0;
73 }
74 
GetXYZ(bool * pHasX,bool * pHasY,bool * pHasZoom,float * pX,float * pY,float * pZoom) const75 bool CPDF_Dest::GetXYZ(bool* pHasX,
76                        bool* pHasY,
77                        bool* pHasZoom,
78                        float* pX,
79                        float* pY,
80                        float* pZoom) const {
81   *pHasX = false;
82   *pHasY = false;
83   *pHasZoom = false;
84 
85   if (!m_pArray)
86     return false;
87 
88   if (m_pArray->size() < 5)
89     return false;
90 
91   const CPDF_Name* xyz = ToName(m_pArray->GetDirectObjectAt(1));
92   if (!xyz || xyz->GetString() != "XYZ")
93     return false;
94 
95   const CPDF_Number* numX = ToNumber(m_pArray->GetDirectObjectAt(2));
96   const CPDF_Number* numY = ToNumber(m_pArray->GetDirectObjectAt(3));
97   const CPDF_Number* numZoom = ToNumber(m_pArray->GetDirectObjectAt(4));
98 
99   // If the value is a CPDF_Null then ToNumber will return nullptr.
100   *pHasX = !!numX;
101   *pHasY = !!numY;
102   *pHasZoom = !!numZoom;
103 
104   if (numX)
105     *pX = numX->GetNumber();
106   if (numY)
107     *pY = numY->GetNumber();
108 
109   // A zoom value of 0 is equivalent to a null value, so treat it as a null.
110   if (numZoom) {
111     float num = numZoom->GetNumber();
112     if (num == 0.0)
113       *pHasZoom = false;
114     else
115       *pZoom = num;
116   }
117 
118   return true;
119 }
120 
GetNumParams() const121 unsigned long CPDF_Dest::GetNumParams() const {
122   if (!m_pArray || m_pArray->size() < 2)
123     return 0;
124 
125   unsigned long maxParamsForFitType = g_sZoomModeMaxParamCount[GetZoomMode()];
126   unsigned long numParamsInArray = m_pArray->size() - 2;
127   return std::min(maxParamsForFitType, numParamsInArray);
128 }
129 
GetParam(int index) const130 float CPDF_Dest::GetParam(int index) const {
131   return m_pArray ? m_pArray->GetNumberAt(2 + index) : 0;
132 }
133