Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: core/fpdfdoc/doc_formcontrol.cpp

Issue 2190983002: Splitting fpdfdoc/doc_* part III. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@fpdf_doc_IV
Patch Set: move cb Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfdoc/doc_form.cpp ('k') | core/fpdfdoc/doc_formfield.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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/include/cpdf_formcontrol.h"
8
9 #include <algorithm>
10
11 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
14 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
15 #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
16 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h"
17 #include "core/fpdfdoc/include/cpdf_interform.h"
18
19 namespace {
20
21 const FX_CHAR* const g_sHighlightingMode[] = {
22 // Must match order of HighlightingMode enum.
23 "N", "I", "O", "P", "T"};
24
25 } // namespace
26
27 CPDF_FormControl::CPDF_FormControl(CPDF_FormField* pField,
28 CPDF_Dictionary* pWidgetDict)
29 : m_pField(pField),
30 m_pWidgetDict(pWidgetDict),
31 m_pForm(m_pField->m_pForm) {}
32
33 CFX_ByteString CPDF_FormControl::GetOnStateName() const {
34 ASSERT(GetType() == CPDF_FormField::CheckBox ||
35 GetType() == CPDF_FormField::RadioButton);
36 CFX_ByteString csOn;
37 CPDF_Dictionary* pAP = m_pWidgetDict->GetDictBy("AP");
38 if (!pAP)
39 return csOn;
40
41 CPDF_Dictionary* pN = pAP->GetDictBy("N");
42 if (!pN)
43 return csOn;
44
45 for (const auto& it : *pN) {
46 if (it.first != "Off")
47 return it.first;
48 }
49 return CFX_ByteString();
50 }
51
52 void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) {
53 ASSERT(GetType() == CPDF_FormField::CheckBox ||
54 GetType() == CPDF_FormField::RadioButton);
55 CFX_ByteString csValue = csOn;
56 if (csValue.IsEmpty()) {
57 csValue = "Yes";
58 }
59 if (csValue == "Off") {
60 csValue = "Yes";
61 }
62 CFX_ByteString csAS = m_pWidgetDict->GetStringBy("AS", "Off");
63 if (csAS != "Off") {
64 m_pWidgetDict->SetAtName("AS", csValue);
65 }
66 CPDF_Dictionary* pAP = m_pWidgetDict->GetDictBy("AP");
67 if (!pAP) {
68 return;
69 }
70 for (const auto& it : *pAP) {
71 CPDF_Object* pObj1 = it.second;
72 if (!pObj1) {
73 continue;
74 }
75 CPDF_Object* pObjDirect1 = pObj1->GetDirect();
76 CPDF_Dictionary* pSubDict = pObjDirect1->AsDictionary();
77 if (!pSubDict)
78 continue;
79
80 auto subdict_it = pSubDict->begin();
81 while (subdict_it != pSubDict->end()) {
82 const CFX_ByteString& csKey2 = subdict_it->first;
83 CPDF_Object* pObj2 = subdict_it->second;
84 ++subdict_it;
85 if (!pObj2) {
86 continue;
87 }
88 if (csKey2 != "Off") {
89 pSubDict->ReplaceKey(csKey2, csValue);
90 break;
91 }
92 }
93 }
94 }
95 CFX_ByteString CPDF_FormControl::GetCheckedAPState() {
96 ASSERT(GetType() == CPDF_FormField::CheckBox ||
97 GetType() == CPDF_FormField::RadioButton);
98 CFX_ByteString csOn = GetOnStateName();
99 if (GetType() == CPDF_FormField::RadioButton ||
100 GetType() == CPDF_FormField::CheckBox) {
101 if (ToArray(FPDF_GetFieldAttr(m_pField->m_pDict, "Opt"))) {
102 int iIndex = m_pField->GetControlIndex(this);
103 csOn.Format("%d", iIndex);
104 }
105 }
106 if (csOn.IsEmpty())
107 csOn = "Yes";
108 return csOn;
109 }
110
111 CFX_WideString CPDF_FormControl::GetExportValue() const {
112 ASSERT(GetType() == CPDF_FormField::CheckBox ||
113 GetType() == CPDF_FormField::RadioButton);
114 CFX_ByteString csOn = GetOnStateName();
115 if (GetType() == CPDF_FormField::RadioButton ||
116 GetType() == CPDF_FormField::CheckBox) {
117 if (CPDF_Array* pArray =
118 ToArray(FPDF_GetFieldAttr(m_pField->m_pDict, "Opt"))) {
119 int iIndex = m_pField->GetControlIndex(this);
120 csOn = pArray->GetStringAt(iIndex);
121 }
122 }
123 if (csOn.IsEmpty())
124 csOn = "Yes";
125 return PDF_DecodeText(csOn);
126 }
127
128 bool CPDF_FormControl::IsChecked() const {
129 ASSERT(GetType() == CPDF_FormField::CheckBox ||
130 GetType() == CPDF_FormField::RadioButton);
131 CFX_ByteString csOn = GetOnStateName();
132 CFX_ByteString csAS = m_pWidgetDict->GetStringBy("AS");
133 return csAS == csOn;
134 }
135
136 bool CPDF_FormControl::IsDefaultChecked() const {
137 ASSERT(GetType() == CPDF_FormField::CheckBox ||
138 GetType() == CPDF_FormField::RadioButton);
139 CPDF_Object* pDV = FPDF_GetFieldAttr(m_pField->m_pDict, "DV");
140 if (!pDV) {
141 return FALSE;
142 }
143 CFX_ByteString csDV = pDV->GetString();
144 CFX_ByteString csOn = GetOnStateName();
145 return (csDV == csOn);
146 }
147
148 void CPDF_FormControl::CheckControl(FX_BOOL bChecked) {
149 ASSERT(GetType() == CPDF_FormField::CheckBox ||
150 GetType() == CPDF_FormField::RadioButton);
151 CFX_ByteString csOn = GetOnStateName();
152 CFX_ByteString csOldAS = m_pWidgetDict->GetStringBy("AS", "Off");
153 CFX_ByteString csAS = "Off";
154 if (bChecked)
155 csAS = csOn;
156 if (csOldAS == csAS)
157 return;
158 m_pWidgetDict->SetAtName("AS", csAS);
159 }
160
161 void CPDF_FormControl::DrawControl(CFX_RenderDevice* pDevice,
162 CFX_Matrix* pMatrix,
163 CPDF_Page* pPage,
164 CPDF_Annot::AppearanceMode mode,
165 const CPDF_RenderOptions* pOptions) {
166 if (m_pWidgetDict->GetIntegerBy("F") & ANNOTFLAG_HIDDEN)
167 return;
168
169 CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(m_pWidgetDict, mode);
170 if (!pStream)
171 return;
172
173 CFX_FloatRect form_bbox = pStream->GetDict()->GetRectBy("BBox");
174 CFX_Matrix form_matrix = pStream->GetDict()->GetMatrixBy("Matrix");
175 form_matrix.TransformRect(form_bbox);
176 CFX_FloatRect arect = m_pWidgetDict->GetRectBy("Rect");
177 CFX_Matrix matrix;
178 matrix.MatchRect(arect, form_bbox);
179 matrix.Concat(*pMatrix);
180 CPDF_Form form(m_pField->m_pForm->m_pDocument,
181 m_pField->m_pForm->m_pFormDict->GetDictBy("DR"), pStream);
182 form.ParseContent(nullptr, nullptr, nullptr);
183 CPDF_RenderContext context(pPage);
184 context.AppendLayer(&form, &matrix);
185 context.Render(pDevice, pOptions, nullptr);
186 }
187
188 CPDF_FormControl::HighlightingMode CPDF_FormControl::GetHighlightingMode() {
189 if (!m_pWidgetDict)
190 return Invert;
191
192 CFX_ByteString csH = m_pWidgetDict->GetStringBy("H", "I");
193 for (size_t i = 0; i < FX_ArraySize(g_sHighlightingMode); ++i) {
194 if (csH == g_sHighlightingMode[i])
195 return static_cast<HighlightingMode>(i);
196 }
197 return Invert;
198 }
199
200 CPDF_ApSettings CPDF_FormControl::GetMK() const {
201 return CPDF_ApSettings(m_pWidgetDict ? m_pWidgetDict->GetDictBy("MK")
202 : nullptr);
203 }
204
205 bool CPDF_FormControl::HasMKEntry(const CFX_ByteString& csEntry) const {
206 return GetMK().HasMKEntry(csEntry);
207 }
208
209 int CPDF_FormControl::GetRotation() {
210 return GetMK().GetRotation();
211 }
212
213 FX_ARGB CPDF_FormControl::GetColor(int& iColorType,
214 const CFX_ByteString& csEntry) {
215 return GetMK().GetColor(iColorType, csEntry);
216 }
217
218 FX_FLOAT CPDF_FormControl::GetOriginalColor(int index,
219 const CFX_ByteString& csEntry) {
220 return GetMK().GetOriginalColor(index, csEntry);
221 }
222
223 void CPDF_FormControl::GetOriginalColor(int& iColorType,
224 FX_FLOAT fc[4],
225 const CFX_ByteString& csEntry) {
226 GetMK().GetOriginalColor(iColorType, fc, csEntry);
227 }
228 CFX_WideString CPDF_FormControl::GetCaption(const CFX_ByteString& csEntry) {
229 return GetMK().GetCaption(csEntry);
230 }
231
232 CPDF_Stream* CPDF_FormControl::GetIcon(const CFX_ByteString& csEntry) {
233 return GetMK().GetIcon(csEntry);
234 }
235
236 CPDF_IconFit CPDF_FormControl::GetIconFit() {
237 return GetMK().GetIconFit();
238 }
239
240 int CPDF_FormControl::GetTextPosition() {
241 return GetMK().GetTextPosition();
242 }
243
244 CPDF_Action CPDF_FormControl::GetAction() {
245 if (!m_pWidgetDict)
246 return CPDF_Action();
247
248 if (m_pWidgetDict->KeyExist("A"))
249 return CPDF_Action(m_pWidgetDict->GetDictBy("A"));
250
251 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pField->m_pDict, "A");
252 if (!pObj)
253 return CPDF_Action();
254
255 return CPDF_Action(pObj->GetDict());
256 }
257
258 CPDF_AAction CPDF_FormControl::GetAdditionalAction() {
259 if (!m_pWidgetDict)
260 return CPDF_AAction();
261
262 if (m_pWidgetDict->KeyExist("AA"))
263 return CPDF_AAction(m_pWidgetDict->GetDictBy("AA"));
264 return m_pField->GetAdditionalAction();
265 }
266
267 CPDF_DefaultAppearance CPDF_FormControl::GetDefaultAppearance() {
268 if (!m_pWidgetDict)
269 return CPDF_DefaultAppearance();
270
271 if (m_pWidgetDict->KeyExist("DA"))
272 return CPDF_DefaultAppearance(m_pWidgetDict->GetStringBy("DA"));
273
274 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pField->m_pDict, "DA");
275 if (pObj)
276 return CPDF_DefaultAppearance(pObj->GetString());
277 return m_pField->m_pForm->GetDefaultAppearance();
278 }
279
280 CPDF_Font* CPDF_FormControl::GetDefaultControlFont() {
281 CPDF_DefaultAppearance cDA = GetDefaultAppearance();
282 CFX_ByteString csFontNameTag;
283 FX_FLOAT fFontSize;
284 cDA.GetFont(csFontNameTag, fFontSize);
285 if (csFontNameTag.IsEmpty())
286 return nullptr;
287
288 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pWidgetDict, "DR");
289 if (CPDF_Dictionary* pDict = ToDictionary(pObj)) {
290 CPDF_Dictionary* pFonts = pDict->GetDictBy("Font");
291 if (pFonts) {
292 CPDF_Dictionary* pElement = pFonts->GetDictBy(csFontNameTag);
293 if (pElement) {
294 CPDF_Font* pFont = m_pField->m_pForm->m_pDocument->LoadFont(pElement);
295 if (pFont) {
296 return pFont;
297 }
298 }
299 }
300 }
301 if (CPDF_Font* pFormFont = m_pField->m_pForm->GetFormFont(csFontNameTag))
302 return pFormFont;
303
304 CPDF_Dictionary* pPageDict = m_pWidgetDict->GetDictBy("P");
305 pObj = FPDF_GetFieldAttr(pPageDict, "Resources");
306 if (CPDF_Dictionary* pDict = ToDictionary(pObj)) {
307 CPDF_Dictionary* pFonts = pDict->GetDictBy("Font");
308 if (pFonts) {
309 CPDF_Dictionary* pElement = pFonts->GetDictBy(csFontNameTag);
310 if (pElement) {
311 CPDF_Font* pFont = m_pField->m_pForm->m_pDocument->LoadFont(pElement);
312 if (pFont) {
313 return pFont;
314 }
315 }
316 }
317 }
318 return nullptr;
319 }
320
321 int CPDF_FormControl::GetControlAlignment() {
322 if (!m_pWidgetDict) {
323 return 0;
324 }
325 if (m_pWidgetDict->KeyExist("Q")) {
326 return m_pWidgetDict->GetIntegerBy("Q", 0);
327 }
328 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pField->m_pDict, "Q");
329 if (pObj)
330 return pObj->GetInteger();
331 return m_pField->m_pForm->GetFormAlignment();
332 }
333
334 CPDF_ApSettings::CPDF_ApSettings(CPDF_Dictionary* pDict) : m_pDict(pDict) {}
335
336 bool CPDF_ApSettings::HasMKEntry(const CFX_ByteString& csEntry) const {
337 return m_pDict && m_pDict->KeyExist(csEntry);
338 }
339
340 int CPDF_ApSettings::GetRotation() const {
341 return m_pDict ? m_pDict->GetIntegerBy("R") : 0;
342 }
343
344 FX_ARGB CPDF_ApSettings::GetColor(int& iColorType,
345 const CFX_ByteString& csEntry) const {
346 iColorType = COLORTYPE_TRANSPARENT;
347 if (!m_pDict)
348 return 0;
349
350 CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry);
351 if (!pEntry)
352 return 0;
353
354 FX_ARGB color = 0;
355 size_t dwCount = pEntry->GetCount();
356 if (dwCount == 1) {
357 iColorType = COLORTYPE_GRAY;
358 FX_FLOAT g = pEntry->GetNumberAt(0) * 255;
359 color = ArgbEncode(255, (int)g, (int)g, (int)g);
360 } else if (dwCount == 3) {
361 iColorType = COLORTYPE_RGB;
362 FX_FLOAT r = pEntry->GetNumberAt(0) * 255;
363 FX_FLOAT g = pEntry->GetNumberAt(1) * 255;
364 FX_FLOAT b = pEntry->GetNumberAt(2) * 255;
365 color = ArgbEncode(255, (int)r, (int)g, (int)b);
366 } else if (dwCount == 4) {
367 iColorType = COLORTYPE_CMYK;
368 FX_FLOAT c = pEntry->GetNumberAt(0);
369 FX_FLOAT m = pEntry->GetNumberAt(1);
370 FX_FLOAT y = pEntry->GetNumberAt(2);
371 FX_FLOAT k = pEntry->GetNumberAt(3);
372 FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
373 FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
374 FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
375 color = ArgbEncode(255, (int)(r * 255), (int)(g * 255), (int)(b * 255));
376 }
377 return color;
378 }
379
380 FX_FLOAT CPDF_ApSettings::GetOriginalColor(
381 int index,
382 const CFX_ByteString& csEntry) const {
383 if (!m_pDict)
384 return 0;
385
386 CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry);
387 return pEntry ? pEntry->GetNumberAt(index) : 0;
388 }
389
390 void CPDF_ApSettings::GetOriginalColor(int& iColorType,
391 FX_FLOAT fc[4],
392 const CFX_ByteString& csEntry) const {
393 iColorType = COLORTYPE_TRANSPARENT;
394 for (int i = 0; i < 4; i++) {
395 fc[i] = 0;
396 }
397 if (!m_pDict) {
398 return;
399 }
400 CPDF_Array* pEntry = m_pDict->GetArrayBy(csEntry);
401 if (!pEntry) {
402 return;
403 }
404 size_t dwCount = pEntry->GetCount();
405 if (dwCount == 1) {
406 iColorType = COLORTYPE_GRAY;
407 fc[0] = pEntry->GetNumberAt(0);
408 } else if (dwCount == 3) {
409 iColorType = COLORTYPE_RGB;
410 fc[0] = pEntry->GetNumberAt(0);
411 fc[1] = pEntry->GetNumberAt(1);
412 fc[2] = pEntry->GetNumberAt(2);
413 } else if (dwCount == 4) {
414 iColorType = COLORTYPE_CMYK;
415 fc[0] = pEntry->GetNumberAt(0);
416 fc[1] = pEntry->GetNumberAt(1);
417 fc[2] = pEntry->GetNumberAt(2);
418 fc[3] = pEntry->GetNumberAt(3);
419 }
420 }
421
422 CFX_WideString CPDF_ApSettings::GetCaption(
423 const CFX_ByteString& csEntry) const {
424 return m_pDict ? m_pDict->GetUnicodeTextBy(csEntry) : CFX_WideString();
425 }
426
427 CPDF_Stream* CPDF_ApSettings::GetIcon(const CFX_ByteString& csEntry) const {
428 return m_pDict ? m_pDict->GetStreamBy(csEntry) : nullptr;
429 }
430
431 CPDF_IconFit CPDF_ApSettings::GetIconFit() const {
432 return CPDF_IconFit(m_pDict ? m_pDict->GetDictBy("IF") : nullptr);
433 }
434
435 int CPDF_ApSettings::GetTextPosition() const {
436 return m_pDict ? m_pDict->GetIntegerBy("TP", TEXTPOS_CAPTION)
437 : TEXTPOS_CAPTION;
438 }
OLDNEW
« no previous file with comments | « core/fpdfdoc/doc_form.cpp ('k') | core/fpdfdoc/doc_formfield.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698