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_bookmark.h"
8 
9 #include <memory>
10 #include <vector>
11 
12 #include "core/fpdfapi/parser/cpdf_array.h"
13 #include "core/fpdfapi/parser/cpdf_string.h"
14 #include "core/fpdfdoc/cpdf_nametree.h"
15 #include "core/fxge/fx_dib.h"
16 
CPDF_Bookmark()17 CPDF_Bookmark::CPDF_Bookmark() {}
18 
19 CPDF_Bookmark::CPDF_Bookmark(const CPDF_Bookmark& that) = default;
20 
CPDF_Bookmark(CPDF_Dictionary * pDict)21 CPDF_Bookmark::CPDF_Bookmark(CPDF_Dictionary* pDict) : m_pDict(pDict) {}
22 
~CPDF_Bookmark()23 CPDF_Bookmark::~CPDF_Bookmark() {}
24 
GetColorRef() const25 uint32_t CPDF_Bookmark::GetColorRef() const {
26   if (!m_pDict)
27     return FXSYS_RGB(0, 0, 0);
28 
29   CPDF_Array* pColor = m_pDict->GetArrayFor("C");
30   if (!pColor)
31     return FXSYS_RGB(0, 0, 0);
32 
33   int r = FXSYS_round(pColor->GetNumberAt(0) * 255);
34   int g = FXSYS_round(pColor->GetNumberAt(1) * 255);
35   int b = FXSYS_round(pColor->GetNumberAt(2) * 255);
36   return FXSYS_RGB(r, g, b);
37 }
38 
GetFontStyle() const39 uint32_t CPDF_Bookmark::GetFontStyle() const {
40   return m_pDict ? m_pDict->GetIntegerFor("F") : 0;
41 }
42 
GetTitle() const43 WideString CPDF_Bookmark::GetTitle() const {
44   if (!m_pDict)
45     return WideString();
46 
47   CPDF_String* pString = ToString(m_pDict->GetDirectObjectFor("Title"));
48   if (!pString)
49     return WideString();
50 
51   WideString title = pString->GetUnicodeText();
52   int len = title.GetLength();
53   if (!len)
54     return WideString();
55 
56   std::vector<wchar_t> buf(len);
57   for (int i = 0; i < len; i++) {
58     wchar_t w = title[i];
59     buf[i] = w > 0x20 ? w : 0x20;
60   }
61   return WideString(buf.data(), len);
62 }
63 
GetDest(CPDF_Document * pDocument) const64 CPDF_Dest CPDF_Bookmark::GetDest(CPDF_Document* pDocument) const {
65   if (!m_pDict)
66     return CPDF_Dest();
67 
68   CPDF_Object* pDest = m_pDict->GetDirectObjectFor("Dest");
69   if (!pDest)
70     return CPDF_Dest();
71   if (pDest->IsString() || pDest->IsName()) {
72     CPDF_NameTree name_tree(pDocument, "Dests");
73     return CPDF_Dest(
74         name_tree.LookupNamedDest(pDocument, pDest->GetUnicodeText()));
75   }
76   if (CPDF_Array* pArray = pDest->AsArray())
77     return CPDF_Dest(pArray);
78   return CPDF_Dest();
79 }
80 
GetAction() const81 CPDF_Action CPDF_Bookmark::GetAction() const {
82   return CPDF_Action(m_pDict ? m_pDict->GetDictFor("A") : nullptr);
83 }
84