blob: a426749fffeb3093190cf24a3cc7a981d62bec19 [file] [log] [blame]
jaepark27362762016-08-11 13:10:39 -07001// 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
dsinclair114e46a2016-09-29 17:18:21 -07007#include "fpdfsdk/cpdfsdk_baannot.h"
jaepark27362762016-08-11 13:10:39 -07008
tsepez0e606b52016-11-18 16:22:41 -08009#include <algorithm>
tsepez9e05ee12016-11-21 13:19:10 -080010#include <utility>
tsepez0e606b52016-11-18 16:22:41 -080011
dsinclair488b7ad2016-10-04 11:55:50 -070012#include "core/fpdfapi/parser/cpdf_array.h"
13#include "core/fpdfapi/parser/cpdf_document.h"
tsepez0e606b52016-11-18 16:22:41 -080014#include "core/fpdfapi/parser/cpdf_name.h"
dsinclair488b7ad2016-10-04 11:55:50 -070015#include "core/fpdfapi/parser/cpdf_number.h"
tsepez0e606b52016-11-18 16:22:41 -080016#include "core/fpdfapi/parser/cpdf_reference.h"
dsinclair488b7ad2016-10-04 11:55:50 -070017#include "core/fpdfapi/parser/cpdf_stream.h"
tsepez0e606b52016-11-18 16:22:41 -080018#include "core/fpdfapi/parser/cpdf_string.h"
dsinclair488b7ad2016-10-04 11:55:50 -070019#include "core/fpdfapi/parser/fpdf_parser_decode.h"
dsinclair114e46a2016-09-29 17:18:21 -070020#include "fpdfsdk/cpdfsdk_datetime.h"
dsinclair114e46a2016-09-29 17:18:21 -070021#include "fpdfsdk/cpdfsdk_pageview.h"
jaepark27362762016-08-11 13:10:39 -070022
23CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot,
24 CPDFSDK_PageView* pPageView)
25 : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {}
26
27CPDFSDK_BAAnnot::~CPDFSDK_BAAnnot() {}
28
29CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
Tom Sepez797ca5c2017-05-25 12:03:18 -070030 return m_pAnnot.Get();
jaepark27362762016-08-11 13:10:39 -070031}
32
jaepark35512aa2016-08-29 17:15:08 -070033CPDF_Annot* CPDFSDK_BAAnnot::GetPDFPopupAnnot() const {
34 return m_pAnnot->GetPopupAnnot();
35}
36
jaepark27362762016-08-11 13:10:39 -070037CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
38 return m_pAnnot->GetAnnotDict();
39}
40
Dan Sinclaircb2ea422017-07-19 15:24:49 -040041CPDF_Dictionary* CPDFSDK_BAAnnot::GetAPDict() const {
42 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
43 if (!pAPDict)
44 pAPDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("AP");
45 return pAPDict;
46}
47
jaepark27362762016-08-11 13:10:39 -070048void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
49 ASSERT(rect.right - rect.left >= GetMinWidth());
50 ASSERT(rect.top - rect.bottom >= GetMinHeight());
51
dsinclair38fd8442016-09-15 10:15:32 -070052 m_pAnnot->GetAnnotDict()->SetRectFor("Rect", rect);
jaepark27362762016-08-11 13:10:39 -070053}
54
55CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
jaeparka1d21112016-08-25 13:33:34 -070056 return m_pAnnot->GetRect();
jaepark27362762016-08-11 13:10:39 -070057}
58
jaepark956553e2016-08-31 06:49:27 -070059CPDF_Annot::Subtype CPDFSDK_BAAnnot::GetAnnotSubtype() const {
jaepark9ed91372016-08-26 16:16:10 -070060 return m_pAnnot->GetSubtype();
jaepark27362762016-08-11 13:10:39 -070061}
62
63void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
64 const CFX_Matrix* pUser2Device,
65 CPDF_Annot::AppearanceMode mode,
66 const CPDF_RenderOptions* pOptions) {
67 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
68 mode, pOptions);
69}
70
tsepez4cf55152016-11-02 14:37:54 -070071bool CPDFSDK_BAAnnot::IsAppearanceValid() {
dsinclair38fd8442016-09-15 10:15:32 -070072 return !!m_pAnnot->GetAnnotDict()->GetDictFor("AP");
jaepark27362762016-08-11 13:10:39 -070073}
74
tsepez4cf55152016-11-02 14:37:54 -070075bool CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) {
dsinclair38fd8442016-09-15 10:15:32 -070076 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
jaepark27362762016-08-11 13:10:39 -070077 if (!pAP)
tsepez4cf55152016-11-02 14:37:54 -070078 return false;
jaepark27362762016-08-11 13:10:39 -070079
80 // Choose the right sub-ap
Dan Sinclair812e96c2017-03-13 16:43:37 -040081 const char* ap_entry = "N";
jaepark27362762016-08-11 13:10:39 -070082 if (mode == CPDF_Annot::Down)
83 ap_entry = "D";
84 else if (mode == CPDF_Annot::Rollover)
85 ap_entry = "R";
86 if (!pAP->KeyExist(ap_entry))
87 ap_entry = "N";
88
89 // Get the AP stream or subdirectory
dsinclair38fd8442016-09-15 10:15:32 -070090 CPDF_Object* psub = pAP->GetDirectObjectFor(ap_entry);
jaepark27362762016-08-11 13:10:39 -070091 return !!psub;
92}
93
94void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice,
95 const CFX_Matrix* pUser2Device,
96 const CPDF_RenderOptions* pOptions) {
97 m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
98}
99
100void CPDFSDK_BAAnnot::ClearCachedAP() {
101 m_pAnnot->ClearCachedAP();
102}
103
104void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
tsepez0e606b52016-11-18 16:22:41 -0800105 if (sContents.IsEmpty()) {
dsinclair38fd8442016-09-15 10:15:32 -0700106 m_pAnnot->GetAnnotDict()->RemoveFor("Contents");
tsepez0e606b52016-11-18 16:22:41 -0800107 } else {
108 m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
109 "Contents", PDF_EncodeText(sContents), false);
110 }
jaepark27362762016-08-11 13:10:39 -0700111}
112
113CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
dsinclair38fd8442016-09-15 10:15:32 -0700114 return m_pAnnot->GetAnnotDict()->GetUnicodeTextFor("Contents");
jaepark27362762016-08-11 13:10:39 -0700115}
116
117void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
tsepez0e606b52016-11-18 16:22:41 -0800118 if (sName.IsEmpty()) {
dsinclair38fd8442016-09-15 10:15:32 -0700119 m_pAnnot->GetAnnotDict()->RemoveFor("NM");
tsepez0e606b52016-11-18 16:22:41 -0800120 } else {
121 m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
122 "NM", PDF_EncodeText(sName), false);
123 }
jaepark27362762016-08-11 13:10:39 -0700124}
125
126CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
dsinclair38fd8442016-09-15 10:15:32 -0700127 return m_pAnnot->GetAnnotDict()->GetUnicodeTextFor("NM");
jaepark27362762016-08-11 13:10:39 -0700128}
129
130void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
131 CPDFSDK_DateTime dt(st);
132 CFX_ByteString str = dt.ToPDFDateTimeString();
jaepark27362762016-08-11 13:10:39 -0700133 if (str.IsEmpty())
dsinclair38fd8442016-09-15 10:15:32 -0700134 m_pAnnot->GetAnnotDict()->RemoveFor("M");
jaepark27362762016-08-11 13:10:39 -0700135 else
tsepez0e606b52016-11-18 16:22:41 -0800136 m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>("M", str, false);
jaepark27362762016-08-11 13:10:39 -0700137}
138
139FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
140 FX_SYSTEMTIME systime;
dsinclair38fd8442016-09-15 10:15:32 -0700141 CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringFor("M");
jaepark27362762016-08-11 13:10:39 -0700142 CPDFSDK_DateTime dt(str);
143 dt.ToSystemTime(systime);
jaepark27362762016-08-11 13:10:39 -0700144 return systime;
145}
146
147void CPDFSDK_BAAnnot::SetFlags(uint32_t nFlags) {
tsepez0e606b52016-11-18 16:22:41 -0800148 m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F",
149 static_cast<int>(nFlags));
jaepark27362762016-08-11 13:10:39 -0700150}
151
152uint32_t CPDFSDK_BAAnnot::GetFlags() const {
dsinclair38fd8442016-09-15 10:15:32 -0700153 return m_pAnnot->GetAnnotDict()->GetIntegerFor("F");
jaepark27362762016-08-11 13:10:39 -0700154}
155
156void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) {
157 if (str.IsEmpty())
dsinclair38fd8442016-09-15 10:15:32 -0700158 m_pAnnot->GetAnnotDict()->RemoveFor("AS");
jaepark27362762016-08-11 13:10:39 -0700159 else
tsepez0e606b52016-11-18 16:22:41 -0800160 m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>("AS", str, false);
jaepark27362762016-08-11 13:10:39 -0700161}
162
163CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
dsinclair38fd8442016-09-15 10:15:32 -0700164 return m_pAnnot->GetAnnotDict()->GetStringFor("AS");
jaepark27362762016-08-11 13:10:39 -0700165}
166
167void CPDFSDK_BAAnnot::SetStructParent(int key) {
tsepez0e606b52016-11-18 16:22:41 -0800168 m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("StructParent", key);
jaepark27362762016-08-11 13:10:39 -0700169}
170
171int CPDFSDK_BAAnnot::GetStructParent() const {
dsinclair38fd8442016-09-15 10:15:32 -0700172 return m_pAnnot->GetAnnotDict()->GetIntegerFor("StructParent");
jaepark27362762016-08-11 13:10:39 -0700173}
174
175// border
176void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
dsinclair38fd8442016-09-15 10:15:32 -0700177 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayFor("Border");
jaepark27362762016-08-11 13:10:39 -0700178 if (pBorder) {
tsepez8a3aa452016-11-16 12:26:06 -0800179 pBorder->SetNewAt<CPDF_Number>(2, nWidth);
jaepark27362762016-08-11 13:10:39 -0700180 } else {
dsinclair38fd8442016-09-15 10:15:32 -0700181 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
tsepez0e606b52016-11-18 16:22:41 -0800182 if (!pBSDict)
183 pBSDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
184
185 pBSDict->SetNewFor<CPDF_Number>("W", nWidth);
jaepark27362762016-08-11 13:10:39 -0700186 }
187}
188
189int CPDFSDK_BAAnnot::GetBorderWidth() const {
tsepez698c5712016-09-28 16:47:07 -0700190 if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayFor("Border"))
jaepark27362762016-08-11 13:10:39 -0700191 return pBorder->GetIntegerAt(2);
tsepez698c5712016-09-28 16:47:07 -0700192
193 if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS"))
dsinclair38fd8442016-09-15 10:15:32 -0700194 return pBSDict->GetIntegerFor("W", 1);
tsepez698c5712016-09-28 16:47:07 -0700195
jaepark27362762016-08-11 13:10:39 -0700196 return 1;
197}
198
199void CPDFSDK_BAAnnot::SetBorderStyle(BorderStyle nStyle) {
dsinclair38fd8442016-09-15 10:15:32 -0700200 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
tsepez0e606b52016-11-18 16:22:41 -0800201 if (!pBSDict)
202 pBSDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
jaepark27362762016-08-11 13:10:39 -0700203
204 switch (nStyle) {
205 case BorderStyle::SOLID:
tsepez0e606b52016-11-18 16:22:41 -0800206 pBSDict->SetNewFor<CPDF_Name>("S", "S");
jaepark27362762016-08-11 13:10:39 -0700207 break;
208 case BorderStyle::DASH:
tsepez0e606b52016-11-18 16:22:41 -0800209 pBSDict->SetNewFor<CPDF_Name>("S", "D");
jaepark27362762016-08-11 13:10:39 -0700210 break;
211 case BorderStyle::BEVELED:
tsepez0e606b52016-11-18 16:22:41 -0800212 pBSDict->SetNewFor<CPDF_Name>("S", "B");
jaepark27362762016-08-11 13:10:39 -0700213 break;
214 case BorderStyle::INSET:
tsepez0e606b52016-11-18 16:22:41 -0800215 pBSDict->SetNewFor<CPDF_Name>("S", "I");
jaepark27362762016-08-11 13:10:39 -0700216 break;
217 case BorderStyle::UNDERLINE:
tsepez0e606b52016-11-18 16:22:41 -0800218 pBSDict->SetNewFor<CPDF_Name>("S", "U");
jaepark27362762016-08-11 13:10:39 -0700219 break;
220 default:
221 break;
222 }
223}
224
225BorderStyle CPDFSDK_BAAnnot::GetBorderStyle() const {
dsinclair38fd8442016-09-15 10:15:32 -0700226 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
jaepark27362762016-08-11 13:10:39 -0700227 if (pBSDict) {
dsinclair38fd8442016-09-15 10:15:32 -0700228 CFX_ByteString sBorderStyle = pBSDict->GetStringFor("S", "S");
jaepark27362762016-08-11 13:10:39 -0700229 if (sBorderStyle == "S")
230 return BorderStyle::SOLID;
231 if (sBorderStyle == "D")
232 return BorderStyle::DASH;
233 if (sBorderStyle == "B")
234 return BorderStyle::BEVELED;
235 if (sBorderStyle == "I")
236 return BorderStyle::INSET;
237 if (sBorderStyle == "U")
238 return BorderStyle::UNDERLINE;
239 }
240
dsinclair38fd8442016-09-15 10:15:32 -0700241 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayFor("Border");
jaepark27362762016-08-11 13:10:39 -0700242 if (pBorder) {
243 if (pBorder->GetCount() >= 4) {
244 CPDF_Array* pDP = pBorder->GetArrayAt(3);
245 if (pDP && pDP->GetCount() > 0)
246 return BorderStyle::DASH;
247 }
248 }
249
250 return BorderStyle::SOLID;
251}
252
253void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
tsepez0e606b52016-11-18 16:22:41 -0800254 CPDF_Array* pArray = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Array>("C");
Dan Sinclair05df0752017-03-14 14:43:42 -0400255 pArray->AddNew<CPDF_Number>(static_cast<float>(FXSYS_GetRValue(color)) /
tsepez8a3aa452016-11-16 12:26:06 -0800256 255.0f);
Dan Sinclair05df0752017-03-14 14:43:42 -0400257 pArray->AddNew<CPDF_Number>(static_cast<float>(FXSYS_GetGValue(color)) /
tsepez8a3aa452016-11-16 12:26:06 -0800258 255.0f);
Dan Sinclair05df0752017-03-14 14:43:42 -0400259 pArray->AddNew<CPDF_Number>(static_cast<float>(FXSYS_GetBValue(color)) /
tsepez8a3aa452016-11-16 12:26:06 -0800260 255.0f);
jaepark27362762016-08-11 13:10:39 -0700261}
262
263void CPDFSDK_BAAnnot::RemoveColor() {
dsinclair38fd8442016-09-15 10:15:32 -0700264 m_pAnnot->GetAnnotDict()->RemoveFor("C");
jaepark27362762016-08-11 13:10:39 -0700265}
266
tsepez4cf55152016-11-02 14:37:54 -0700267bool CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
dsinclair38fd8442016-09-15 10:15:32 -0700268 if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArrayFor("C")) {
jaepark27362762016-08-11 13:10:39 -0700269 size_t nCount = pEntry->GetCount();
270 if (nCount == 1) {
Dan Sinclair05df0752017-03-14 14:43:42 -0400271 float g = pEntry->GetNumberAt(0) * 255;
jaepark27362762016-08-11 13:10:39 -0700272
273 color = FXSYS_RGB((int)g, (int)g, (int)g);
274
tsepez4cf55152016-11-02 14:37:54 -0700275 return true;
jaepark27362762016-08-11 13:10:39 -0700276 } else if (nCount == 3) {
Dan Sinclair05df0752017-03-14 14:43:42 -0400277 float r = pEntry->GetNumberAt(0) * 255;
278 float g = pEntry->GetNumberAt(1) * 255;
279 float b = pEntry->GetNumberAt(2) * 255;
jaepark27362762016-08-11 13:10:39 -0700280
281 color = FXSYS_RGB((int)r, (int)g, (int)b);
282
tsepez4cf55152016-11-02 14:37:54 -0700283 return true;
jaepark27362762016-08-11 13:10:39 -0700284 } else if (nCount == 4) {
Dan Sinclair05df0752017-03-14 14:43:42 -0400285 float c = pEntry->GetNumberAt(0);
286 float m = pEntry->GetNumberAt(1);
287 float y = pEntry->GetNumberAt(2);
288 float k = pEntry->GetNumberAt(3);
jaepark27362762016-08-11 13:10:39 -0700289
Dan Sinclair05df0752017-03-14 14:43:42 -0400290 float r = 1.0f - std::min(1.0f, c + k);
291 float g = 1.0f - std::min(1.0f, m + k);
292 float b = 1.0f - std::min(1.0f, y + k);
jaepark27362762016-08-11 13:10:39 -0700293
294 color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
295
tsepez4cf55152016-11-02 14:37:54 -0700296 return true;
jaepark27362762016-08-11 13:10:39 -0700297 }
298 }
299
tsepez4cf55152016-11-02 14:37:54 -0700300 return false;
jaepark27362762016-08-11 13:10:39 -0700301}
302
tsepez4cf55152016-11-02 14:37:54 -0700303bool CPDFSDK_BAAnnot::IsVisible() const {
jaepark27362762016-08-11 13:10:39 -0700304 uint32_t nFlags = GetFlags();
305 return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
306 (nFlags & ANNOTFLAG_NOVIEW));
307}
308
309CPDF_Action CPDFSDK_BAAnnot::GetAction() const {
dsinclair38fd8442016-09-15 10:15:32 -0700310 return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictFor("A"));
jaepark27362762016-08-11 13:10:39 -0700311}
312
313void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) {
tsepezbb577af2016-09-21 19:10:19 -0700314 CPDF_Dictionary* pDict = action.GetDict();
315 if (pDict != m_pAnnot->GetAnnotDict()->GetDictFor("A")) {
jaepark27362762016-08-11 13:10:39 -0700316 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
tsepez70c4afd2016-11-15 11:33:44 -0800317 if (pDict->IsInline())
318 pDict = pDoc->AddIndirectObject(pDict->Clone())->AsDictionary();
tsepez0e606b52016-11-18 16:22:41 -0800319 m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Reference>("A", pDoc,
320 pDict->GetObjNum());
jaepark27362762016-08-11 13:10:39 -0700321 }
322}
323
324void CPDFSDK_BAAnnot::RemoveAction() {
dsinclair38fd8442016-09-15 10:15:32 -0700325 m_pAnnot->GetAnnotDict()->RemoveFor("A");
jaepark27362762016-08-11 13:10:39 -0700326}
327
328CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const {
dsinclair38fd8442016-09-15 10:15:32 -0700329 return CPDF_AAction(m_pAnnot->GetAnnotDict()->GetDictFor("AA"));
jaepark27362762016-08-11 13:10:39 -0700330}
331
332void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) {
dsinclair38fd8442016-09-15 10:15:32 -0700333 if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictFor("AA"))
tsepez0e606b52016-11-18 16:22:41 -0800334 m_pAnnot->GetAnnotDict()->SetFor("AA", pdfium::WrapUnique(aa.GetDict()));
jaepark27362762016-08-11 13:10:39 -0700335}
336
337void CPDFSDK_BAAnnot::RemoveAAction() {
dsinclair38fd8442016-09-15 10:15:32 -0700338 m_pAnnot->GetAnnotDict()->RemoveFor("AA");
jaepark27362762016-08-11 13:10:39 -0700339}
340
341CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
342 CPDF_AAction AAction = GetAAction();
jaepark27362762016-08-11 13:10:39 -0700343 if (AAction.ActionExist(eAAT))
344 return AAction.GetAction(eAAT);
345
346 if (eAAT == CPDF_AAction::ButtonUp)
347 return GetAction();
348
349 return CPDF_Action();
350}
351
jaepark35512aa2016-08-29 17:15:08 -0700352void CPDFSDK_BAAnnot::SetOpenState(bool bOpenState) {
353 if (CPDF_Annot* pAnnot = m_pAnnot->GetPopupAnnot())
354 pAnnot->SetOpenState(bOpenState);
355}