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 <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" | 9 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" |
10 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 10 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" | 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
13 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h" | 13 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h" |
14 #include "core/fpdfdoc/include/fpdf_doc.h" | 14 #include "core/fpdfdoc/include/fpdf_doc.h" |
15 | 15 |
| 16 namespace { |
| 17 |
| 18 const FX_CHAR* const g_sHighlightingMode[] = { |
| 19 // Must match order of HighlightingMode enum. |
| 20 "N", "I", "O", "P", "T"}; |
| 21 |
| 22 } // namespace |
| 23 |
16 CPDF_FormControl::CPDF_FormControl(CPDF_FormField* pField, | 24 CPDF_FormControl::CPDF_FormControl(CPDF_FormField* pField, |
17 CPDF_Dictionary* pWidgetDict) { | 25 CPDF_Dictionary* pWidgetDict) |
18 m_pField = pField; | 26 : m_pField(pField), |
19 m_pWidgetDict = pWidgetDict; | 27 m_pWidgetDict(pWidgetDict), |
20 m_pForm = m_pField->m_pForm; | 28 m_pForm(m_pField->m_pForm) {} |
21 } | 29 |
22 CFX_FloatRect CPDF_FormControl::GetRect() const { | 30 CFX_FloatRect CPDF_FormControl::GetRect() const { |
23 return m_pWidgetDict->GetRectBy("Rect"); | 31 return m_pWidgetDict->GetRectBy("Rect"); |
24 } | 32 } |
| 33 |
25 CFX_ByteString CPDF_FormControl::GetOnStateName() const { | 34 CFX_ByteString CPDF_FormControl::GetOnStateName() const { |
26 ASSERT(GetType() == CPDF_FormField::CheckBox || | 35 ASSERT(GetType() == CPDF_FormField::CheckBox || |
27 GetType() == CPDF_FormField::RadioButton); | 36 GetType() == CPDF_FormField::RadioButton); |
28 CFX_ByteString csOn; | 37 CFX_ByteString csOn; |
29 CPDF_Dictionary* pAP = m_pWidgetDict->GetDictBy("AP"); | 38 CPDF_Dictionary* pAP = m_pWidgetDict->GetDictBy("AP"); |
30 if (!pAP) { | 39 if (!pAP) |
31 return csOn; | 40 return csOn; |
32 } | 41 |
33 CPDF_Dictionary* pN = pAP->GetDictBy("N"); | 42 CPDF_Dictionary* pN = pAP->GetDictBy("N"); |
34 if (!pN) { | 43 if (!pN) |
35 return csOn; | 44 return csOn; |
36 } | 45 |
37 for (const auto& it : *pN) { | 46 for (const auto& it : *pN) { |
38 if (it.first != "Off") { | 47 if (it.first != "Off") |
39 return it.first; | 48 return it.first; |
40 } | |
41 } | 49 } |
42 return CFX_ByteString(); | 50 return CFX_ByteString(); |
43 } | 51 } |
| 52 |
44 void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { | 53 void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { |
45 ASSERT(GetType() == CPDF_FormField::CheckBox || | 54 ASSERT(GetType() == CPDF_FormField::CheckBox || |
46 GetType() == CPDF_FormField::RadioButton); | 55 GetType() == CPDF_FormField::RadioButton); |
47 CFX_ByteString csValue = csOn; | 56 CFX_ByteString csValue = csOn; |
48 if (csValue.IsEmpty()) { | 57 if (csValue.IsEmpty()) { |
49 csValue = "Yes"; | 58 csValue = "Yes"; |
50 } | 59 } |
51 if (csValue == "Off") { | 60 if (csValue == "Off") { |
52 csValue = "Yes"; | 61 csValue = "Yes"; |
53 } | 62 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 GetType() == CPDF_FormField::CheckBox) { | 101 GetType() == CPDF_FormField::CheckBox) { |
93 if (ToArray(FPDF_GetFieldAttr(m_pField->m_pDict, "Opt"))) { | 102 if (ToArray(FPDF_GetFieldAttr(m_pField->m_pDict, "Opt"))) { |
94 int iIndex = m_pField->GetControlIndex(this); | 103 int iIndex = m_pField->GetControlIndex(this); |
95 csOn.Format("%d", iIndex); | 104 csOn.Format("%d", iIndex); |
96 } | 105 } |
97 } | 106 } |
98 if (csOn.IsEmpty()) | 107 if (csOn.IsEmpty()) |
99 csOn = "Yes"; | 108 csOn = "Yes"; |
100 return csOn; | 109 return csOn; |
101 } | 110 } |
102 CFX_WideString CPDF_FormControl::GetExportValue() { | 111 |
| 112 CFX_WideString CPDF_FormControl::GetExportValue() const { |
103 ASSERT(GetType() == CPDF_FormField::CheckBox || | 113 ASSERT(GetType() == CPDF_FormField::CheckBox || |
104 GetType() == CPDF_FormField::RadioButton); | 114 GetType() == CPDF_FormField::RadioButton); |
105 CFX_ByteString csOn = GetOnStateName(); | 115 CFX_ByteString csOn = GetOnStateName(); |
106 if (GetType() == CPDF_FormField::RadioButton || | 116 if (GetType() == CPDF_FormField::RadioButton || |
107 GetType() == CPDF_FormField::CheckBox) { | 117 GetType() == CPDF_FormField::CheckBox) { |
108 if (CPDF_Array* pArray = | 118 if (CPDF_Array* pArray = |
109 ToArray(FPDF_GetFieldAttr(m_pField->m_pDict, "Opt"))) { | 119 ToArray(FPDF_GetFieldAttr(m_pField->m_pDict, "Opt"))) { |
110 int iIndex = m_pField->GetControlIndex(this); | 120 int iIndex = m_pField->GetControlIndex(this); |
111 csOn = pArray->GetStringAt(iIndex); | 121 csOn = pArray->GetStringAt(iIndex); |
112 } | 122 } |
113 } | 123 } |
114 if (csOn.IsEmpty()) { | 124 if (csOn.IsEmpty()) |
115 csOn = "Yes"; | 125 csOn = "Yes"; |
116 } | 126 return PDF_DecodeText(csOn); |
117 CFX_WideString csWOn = PDF_DecodeText(csOn); | |
118 return csWOn; | |
119 } | 127 } |
120 | 128 |
121 bool CPDF_FormControl::IsChecked() const { | 129 bool CPDF_FormControl::IsChecked() const { |
122 ASSERT(GetType() == CPDF_FormField::CheckBox || | 130 ASSERT(GetType() == CPDF_FormField::CheckBox || |
123 GetType() == CPDF_FormField::RadioButton); | 131 GetType() == CPDF_FormField::RadioButton); |
124 CFX_ByteString csOn = GetOnStateName(); | 132 CFX_ByteString csOn = GetOnStateName(); |
125 CFX_ByteString csAS = m_pWidgetDict->GetStringBy("AS"); | 133 CFX_ByteString csAS = m_pWidgetDict->GetStringBy("AS"); |
126 return csAS == csOn; | 134 return csAS == csOn; |
127 } | 135 } |
128 | 136 |
129 bool CPDF_FormControl::IsDefaultChecked() const { | 137 bool CPDF_FormControl::IsDefaultChecked() const { |
130 ASSERT(GetType() == CPDF_FormField::CheckBox || | 138 ASSERT(GetType() == CPDF_FormField::CheckBox || |
131 GetType() == CPDF_FormField::RadioButton); | 139 GetType() == CPDF_FormField::RadioButton); |
132 CPDF_Object* pDV = FPDF_GetFieldAttr(m_pField->m_pDict, "DV"); | 140 CPDF_Object* pDV = FPDF_GetFieldAttr(m_pField->m_pDict, "DV"); |
133 if (!pDV) { | 141 if (!pDV) { |
134 return FALSE; | 142 return FALSE; |
135 } | 143 } |
136 CFX_ByteString csDV = pDV->GetString(); | 144 CFX_ByteString csDV = pDV->GetString(); |
137 CFX_ByteString csOn = GetOnStateName(); | 145 CFX_ByteString csOn = GetOnStateName(); |
138 return (csDV == csOn); | 146 return (csDV == csOn); |
139 } | 147 } |
140 | 148 |
141 void CPDF_FormControl::CheckControl(FX_BOOL bChecked) { | 149 void CPDF_FormControl::CheckControl(FX_BOOL bChecked) { |
142 ASSERT(GetType() == CPDF_FormField::CheckBox || | 150 ASSERT(GetType() == CPDF_FormField::CheckBox || |
143 GetType() == CPDF_FormField::RadioButton); | 151 GetType() == CPDF_FormField::RadioButton); |
144 CFX_ByteString csOn = GetOnStateName(); | 152 CFX_ByteString csOn = GetOnStateName(); |
145 CFX_ByteString csOldAS = m_pWidgetDict->GetStringBy("AS", "Off"); | 153 CFX_ByteString csOldAS = m_pWidgetDict->GetStringBy("AS", "Off"); |
146 CFX_ByteString csAS = "Off"; | 154 CFX_ByteString csAS = "Off"; |
147 if (bChecked) { | 155 if (bChecked) |
148 csAS = csOn; | 156 csAS = csOn; |
149 } | 157 if (csOldAS == csAS) |
150 if (csOldAS == csAS) { | |
151 return; | 158 return; |
152 } | |
153 m_pWidgetDict->SetAtName("AS", csAS); | 159 m_pWidgetDict->SetAtName("AS", csAS); |
154 m_pForm->m_bUpdated = TRUE; | |
155 } | 160 } |
156 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict, | 161 |
157 CPDF_Annot::AppearanceMode mode); | |
158 void CPDF_FormControl::DrawControl(CFX_RenderDevice* pDevice, | 162 void CPDF_FormControl::DrawControl(CFX_RenderDevice* pDevice, |
159 CFX_Matrix* pMatrix, | 163 CFX_Matrix* pMatrix, |
160 CPDF_Page* pPage, | 164 CPDF_Page* pPage, |
161 CPDF_Annot::AppearanceMode mode, | 165 CPDF_Annot::AppearanceMode mode, |
162 const CPDF_RenderOptions* pOptions) { | 166 const CPDF_RenderOptions* pOptions) { |
163 if (m_pWidgetDict->GetIntegerBy("F") & ANNOTFLAG_HIDDEN) { | 167 if (m_pWidgetDict->GetIntegerBy("F") & ANNOTFLAG_HIDDEN) |
164 return; | 168 return; |
165 } | 169 |
166 CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(m_pWidgetDict, mode); | 170 CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(m_pWidgetDict, mode); |
167 if (!pStream) { | 171 if (!pStream) |
168 return; | 172 return; |
169 } | 173 |
170 CFX_FloatRect form_bbox = pStream->GetDict()->GetRectBy("BBox"); | 174 CFX_FloatRect form_bbox = pStream->GetDict()->GetRectBy("BBox"); |
171 CFX_Matrix form_matrix = pStream->GetDict()->GetMatrixBy("Matrix"); | 175 CFX_Matrix form_matrix = pStream->GetDict()->GetMatrixBy("Matrix"); |
172 form_matrix.TransformRect(form_bbox); | 176 form_matrix.TransformRect(form_bbox); |
173 CFX_FloatRect arect = m_pWidgetDict->GetRectBy("Rect"); | 177 CFX_FloatRect arect = m_pWidgetDict->GetRectBy("Rect"); |
174 CFX_Matrix matrix; | 178 CFX_Matrix matrix; |
175 matrix.MatchRect(arect, form_bbox); | 179 matrix.MatchRect(arect, form_bbox); |
176 matrix.Concat(*pMatrix); | 180 matrix.Concat(*pMatrix); |
177 CPDF_Form form(m_pField->m_pForm->m_pDocument, | 181 CPDF_Form form(m_pField->m_pForm->m_pDocument, |
178 m_pField->m_pForm->m_pFormDict->GetDictBy("DR"), pStream); | 182 m_pField->m_pForm->m_pFormDict->GetDictBy("DR"), pStream); |
179 form.ParseContent(nullptr, nullptr, nullptr); | 183 form.ParseContent(nullptr, nullptr, nullptr); |
180 CPDF_RenderContext context(pPage); | 184 CPDF_RenderContext context(pPage); |
181 context.AppendLayer(&form, &matrix); | 185 context.AppendLayer(&form, &matrix); |
182 context.Render(pDevice, pOptions, nullptr); | 186 context.Render(pDevice, pOptions, nullptr); |
183 } | 187 } |
184 static const FX_CHAR* const g_sHighlightingMode[] = { | 188 |
185 // Must match order of HiglightingMode enum. | |
186 "N", "I", "O", "P", "T", nullptr}; | |
187 CPDF_FormControl::HighlightingMode CPDF_FormControl::GetHighlightingMode() { | 189 CPDF_FormControl::HighlightingMode CPDF_FormControl::GetHighlightingMode() { |
188 if (!m_pWidgetDict) { | 190 if (!m_pWidgetDict) |
189 return Invert; | 191 return Invert; |
190 } | 192 |
191 CFX_ByteString csH = m_pWidgetDict->GetStringBy("H", "I"); | 193 CFX_ByteString csH = m_pWidgetDict->GetStringBy("H", "I"); |
192 for (int i = 0; g_sHighlightingMode[i]; ++i) { | 194 for (size_t i = 0; i < FX_ArraySize(g_sHighlightingMode); ++i) { |
193 if (csH == g_sHighlightingMode[i]) | 195 if (csH == g_sHighlightingMode[i]) |
194 return static_cast<HighlightingMode>(i); | 196 return static_cast<HighlightingMode>(i); |
195 } | 197 } |
196 return Invert; | 198 return Invert; |
197 } | 199 } |
198 | 200 |
199 CPDF_ApSettings CPDF_FormControl::GetMK() const { | 201 CPDF_ApSettings CPDF_FormControl::GetMK() const { |
200 return CPDF_ApSettings(m_pWidgetDict ? m_pWidgetDict->GetDictBy("MK") | 202 return CPDF_ApSettings(m_pWidgetDict ? m_pWidgetDict->GetDictBy("MK") |
201 : nullptr); | 203 : nullptr); |
202 } | 204 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 | 236 |
235 CPDF_IconFit CPDF_FormControl::GetIconFit() { | 237 CPDF_IconFit CPDF_FormControl::GetIconFit() { |
236 return GetMK().GetIconFit(); | 238 return GetMK().GetIconFit(); |
237 } | 239 } |
238 | 240 |
239 int CPDF_FormControl::GetTextPosition() { | 241 int CPDF_FormControl::GetTextPosition() { |
240 return GetMK().GetTextPosition(); | 242 return GetMK().GetTextPosition(); |
241 } | 243 } |
242 | 244 |
243 CPDF_Action CPDF_FormControl::GetAction() { | 245 CPDF_Action CPDF_FormControl::GetAction() { |
244 if (!m_pWidgetDict) { | 246 if (!m_pWidgetDict) |
245 return CPDF_Action(); | 247 return CPDF_Action(); |
246 } | 248 |
247 if (m_pWidgetDict->KeyExist("A")) { | 249 if (m_pWidgetDict->KeyExist("A")) |
248 return CPDF_Action(m_pWidgetDict->GetDictBy("A")); | 250 return CPDF_Action(m_pWidgetDict->GetDictBy("A")); |
249 } | 251 |
250 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pField->m_pDict, "A"); | 252 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pField->m_pDict, "A"); |
251 if (!pObj) { | 253 if (!pObj) |
252 return CPDF_Action(); | 254 return CPDF_Action(); |
253 } | 255 |
254 return CPDF_Action(pObj->GetDict()); | 256 return CPDF_Action(pObj->GetDict()); |
255 } | 257 } |
256 | 258 |
257 CPDF_AAction CPDF_FormControl::GetAdditionalAction() { | 259 CPDF_AAction CPDF_FormControl::GetAdditionalAction() { |
258 if (!m_pWidgetDict) | 260 if (!m_pWidgetDict) |
259 return CPDF_AAction(); | 261 return CPDF_AAction(); |
260 | 262 |
261 if (m_pWidgetDict->KeyExist("AA")) | 263 if (m_pWidgetDict->KeyExist("AA")) |
262 return CPDF_AAction(m_pWidgetDict->GetDictBy("AA")); | 264 return CPDF_AAction(m_pWidgetDict->GetDictBy("AA")); |
263 return m_pField->GetAdditionalAction(); | 265 return m_pField->GetAdditionalAction(); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 } | 430 } |
429 | 431 |
430 CPDF_IconFit CPDF_ApSettings::GetIconFit() const { | 432 CPDF_IconFit CPDF_ApSettings::GetIconFit() const { |
431 return CPDF_IconFit(m_pDict ? m_pDict->GetDictBy("IF") : nullptr); | 433 return CPDF_IconFit(m_pDict ? m_pDict->GetDictBy("IF") : nullptr); |
432 } | 434 } |
433 | 435 |
434 int CPDF_ApSettings::GetTextPosition() const { | 436 int CPDF_ApSettings::GetTextPosition() const { |
435 return m_pDict ? m_pDict->GetIntegerBy("TP", TEXTPOS_CAPTION) | 437 return m_pDict ? m_pDict->GetIntegerBy("TP", TEXTPOS_CAPTION) |
436 : TEXTPOS_CAPTION; | 438 : TEXTPOS_CAPTION; |
437 } | 439 } |
OLD | NEW |