• 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 "fpdfsdk/cpdfsdk_baannot.h"
8 
9 #include <algorithm>
10 #include <utility>
11 
12 #include "constants/annotation_common.h"
13 #include "constants/annotation_flags.h"
14 #include "core/fpdfapi/parser/cpdf_array.h"
15 #include "core/fpdfapi/parser/cpdf_dictionary.h"
16 #include "core/fpdfapi/parser/cpdf_document.h"
17 #include "core/fpdfapi/parser/cpdf_name.h"
18 #include "core/fpdfapi/parser/cpdf_number.h"
19 #include "core/fpdfapi/parser/cpdf_reference.h"
20 #include "core/fpdfapi/parser/cpdf_stream.h"
21 #include "core/fpdfapi/parser/cpdf_string.h"
22 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
23 #include "fpdfsdk/cpdfsdk_pageview.h"
24 
CPDFSDK_BAAnnot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPageView)25 CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot,
26                                  CPDFSDK_PageView* pPageView)
27     : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {}
28 
~CPDFSDK_BAAnnot()29 CPDFSDK_BAAnnot::~CPDFSDK_BAAnnot() {}
30 
AsBAAnnot()31 CPDFSDK_BAAnnot* CPDFSDK_BAAnnot::AsBAAnnot() {
32   return this;
33 }
34 
GetPDFAnnot() const35 CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
36   return m_pAnnot.Get();
37 }
38 
GetPDFPopupAnnot() const39 CPDF_Annot* CPDFSDK_BAAnnot::GetPDFPopupAnnot() const {
40   return m_pAnnot->GetPopupAnnot();
41 }
42 
GetAnnotDict() const43 CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
44   return m_pAnnot->GetAnnotDict();
45 }
46 
GetAPDict() const47 CPDF_Dictionary* CPDFSDK_BAAnnot::GetAPDict() const {
48   CPDF_Dictionary* pAPDict =
49       GetAnnotDict()->GetDictFor(pdfium::annotation::kAP);
50   if (pAPDict)
51     return pAPDict;
52   return GetAnnotDict()->SetNewFor<CPDF_Dictionary>(pdfium::annotation::kAP);
53 }
54 
SetRect(const CFX_FloatRect & rect)55 void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
56   ASSERT(rect.right - rect.left >= 1.0f);
57   ASSERT(rect.top - rect.bottom >= 1.0f);
58   GetAnnotDict()->SetRectFor(pdfium::annotation::kRect, rect);
59 }
60 
GetRect() const61 CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
62   return m_pAnnot->GetRect();
63 }
64 
GetAnnotSubtype() const65 CPDF_Annot::Subtype CPDFSDK_BAAnnot::GetAnnotSubtype() const {
66   return m_pAnnot->GetSubtype();
67 }
68 
DrawAppearance(CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device,CPDF_Annot::AppearanceMode mode,const CPDF_RenderOptions * pOptions)69 void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
70                                      const CFX_Matrix& mtUser2Device,
71                                      CPDF_Annot::AppearanceMode mode,
72                                      const CPDF_RenderOptions* pOptions) {
73   m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, mtUser2Device,
74                            mode, pOptions);
75 }
76 
IsAppearanceValid()77 bool CPDFSDK_BAAnnot::IsAppearanceValid() {
78   return !!GetAnnotDict()->GetDictFor(pdfium::annotation::kAP);
79 }
80 
SetAnnotName(const WideString & sName)81 void CPDFSDK_BAAnnot::SetAnnotName(const WideString& sName) {
82   CPDF_Dictionary* pDict = GetAnnotDict();
83   if (sName.IsEmpty())
84     pDict->RemoveFor(pdfium::annotation::kNM);
85   else
86     pDict->SetNewFor<CPDF_String>(pdfium::annotation::kNM, sName);
87 }
88 
GetAnnotName() const89 WideString CPDFSDK_BAAnnot::GetAnnotName() const {
90   return GetAnnotDict()->GetUnicodeTextFor(pdfium::annotation::kNM);
91 }
92 
SetFlags(uint32_t nFlags)93 void CPDFSDK_BAAnnot::SetFlags(uint32_t nFlags) {
94   GetAnnotDict()->SetNewFor<CPDF_Number>(pdfium::annotation::kF,
95                                          static_cast<int>(nFlags));
96 }
97 
GetFlags() const98 uint32_t CPDFSDK_BAAnnot::GetFlags() const {
99   return GetAnnotDict()->GetIntegerFor(pdfium::annotation::kF);
100 }
101 
SetAppState(const ByteString & str)102 void CPDFSDK_BAAnnot::SetAppState(const ByteString& str) {
103   CPDF_Dictionary* pDict = GetAnnotDict();
104   if (str.IsEmpty())
105     pDict->RemoveFor(pdfium::annotation::kAS);
106   else
107     pDict->SetNewFor<CPDF_String>(pdfium::annotation::kAS, str, false);
108 }
109 
GetAppState() const110 ByteString CPDFSDK_BAAnnot::GetAppState() const {
111   return GetAnnotDict()->GetStringFor(pdfium::annotation::kAS);
112 }
113 
SetBorderWidth(int nWidth)114 void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
115   CPDF_Array* pBorder =
116       GetAnnotDict()->GetArrayFor(pdfium::annotation::kBorder);
117   if (pBorder) {
118     pBorder->SetNewAt<CPDF_Number>(2, nWidth);
119   } else {
120     CPDF_Dictionary* pBSDict = GetAnnotDict()->GetDictFor("BS");
121     if (!pBSDict)
122       pBSDict = GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
123     pBSDict->SetNewFor<CPDF_Number>("W", nWidth);
124   }
125 }
126 
GetBorderWidth() const127 int CPDFSDK_BAAnnot::GetBorderWidth() const {
128   if (const CPDF_Array* pBorder =
129           GetAnnotDict()->GetArrayFor(pdfium::annotation::kBorder)) {
130     return pBorder->GetIntegerAt(2);
131   }
132 
133   if (CPDF_Dictionary* pBSDict = GetAnnotDict()->GetDictFor("BS"))
134     return pBSDict->GetIntegerFor("W", 1);
135 
136   return 1;
137 }
138 
SetBorderStyle(BorderStyle nStyle)139 void CPDFSDK_BAAnnot::SetBorderStyle(BorderStyle nStyle) {
140   CPDF_Dictionary* pBSDict = GetAnnotDict()->GetDictFor("BS");
141   if (!pBSDict)
142     pBSDict = GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
143 
144   const char* name = nullptr;
145   switch (nStyle) {
146     case BorderStyle::SOLID:
147       name = "S";
148       break;
149     case BorderStyle::DASH:
150       name = "D";
151       break;
152     case BorderStyle::BEVELED:
153       name = "B";
154       break;
155     case BorderStyle::INSET:
156       name = "I";
157       break;
158     case BorderStyle::UNDERLINE:
159       name = "U";
160       break;
161     default:
162       return;
163   }
164   pBSDict->SetNewFor<CPDF_Name>("S", name);
165 }
166 
GetBorderStyle() const167 BorderStyle CPDFSDK_BAAnnot::GetBorderStyle() const {
168   CPDF_Dictionary* pBSDict = GetAnnotDict()->GetDictFor("BS");
169   if (pBSDict) {
170     ByteString sBorderStyle = pBSDict->GetStringFor("S", "S");
171     if (sBorderStyle == "S")
172       return BorderStyle::SOLID;
173     if (sBorderStyle == "D")
174       return BorderStyle::DASH;
175     if (sBorderStyle == "B")
176       return BorderStyle::BEVELED;
177     if (sBorderStyle == "I")
178       return BorderStyle::INSET;
179     if (sBorderStyle == "U")
180       return BorderStyle::UNDERLINE;
181   }
182 
183   const CPDF_Array* pBorder =
184       GetAnnotDict()->GetArrayFor(pdfium::annotation::kBorder);
185   if (pBorder) {
186     if (pBorder->size() >= 4) {
187       const CPDF_Array* pDP = pBorder->GetArrayAt(3);
188       if (pDP && pDP->size() > 0)
189         return BorderStyle::DASH;
190     }
191   }
192 
193   return BorderStyle::SOLID;
194 }
195 
IsVisible() const196 bool CPDFSDK_BAAnnot::IsVisible() const {
197   uint32_t nFlags = GetFlags();
198   return !((nFlags & pdfium::annotation_flags::kInvisible) ||
199            (nFlags & pdfium::annotation_flags::kHidden) ||
200            (nFlags & pdfium::annotation_flags::kNoView));
201 }
202 
GetAction() const203 CPDF_Action CPDFSDK_BAAnnot::GetAction() const {
204   return CPDF_Action(GetAnnotDict()->GetDictFor("A"));
205 }
206 
GetAAction() const207 CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const {
208   return CPDF_AAction(GetAnnotDict()->GetDictFor("AA"));
209 }
210 
GetAAction(CPDF_AAction::AActionType eAAT)211 CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
212   CPDF_AAction AAction = GetAAction();
213   if (AAction.ActionExist(eAAT))
214     return AAction.GetAction(eAAT);
215 
216   if (eAAT == CPDF_AAction::kButtonUp)
217     return GetAction();
218 
219   return CPDF_Action(nullptr);
220 }
221 
SetOpenState(bool bOpenState)222 void CPDFSDK_BAAnnot::SetOpenState(bool bOpenState) {
223   if (CPDF_Annot* pAnnot = m_pAnnot->GetPopupAnnot())
224     pAnnot->SetOpenState(bOpenState);
225 }
226 
GetLayoutOrder() const227 int CPDFSDK_BAAnnot::GetLayoutOrder() const {
228   if (m_pAnnot->GetSubtype() == CPDF_Annot::Subtype::POPUP)
229     return 1;
230 
231   return CPDFSDK_Annot::GetLayoutOrder();
232 }
233