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 "../../../third_party/base/nonstd_unique_ptr.h" | 7 #include "../../../third_party/base/nonstd_unique_ptr.h" |
8 #include "../../include/fpdfdoc/fpdf_doc.h" | 8 #include "../../include/fpdfdoc/fpdf_doc.h" |
9 #include "../../include/fpdfapi/fpdf_pageobj.h" | 9 #include "../../include/fpdfapi/fpdf_pageobj.h" |
10 | 10 |
11 CPDF_AnnotList::CPDF_AnnotList(CPDF_Page* pPage) { | 11 CPDF_AnnotList::CPDF_AnnotList(CPDF_Page* pPage) |
12 ASSERT(pPage != NULL); | 12 : m_pDocument(pPage->m_pDocument) { |
13 m_pPageDict = pPage->m_pFormDict; | 13 if (!pPage->m_pFormDict) |
14 if (m_pPageDict == NULL) { | |
15 return; | 14 return; |
16 } | 15 |
17 m_pDocument = pPage->m_pDocument; | 16 CPDF_Array* pAnnots = pPage->m_pFormDict->GetArray("Annots"); |
18 CPDF_Array* pAnnots = m_pPageDict->GetArray("Annots"); | 17 if (!pAnnots) |
19 if (pAnnots == NULL) { | |
20 return; | 18 return; |
21 } | 19 |
22 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); | 20 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); |
23 CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm"); | 21 CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm"); |
24 FX_BOOL bRegenerateAP = pAcroForm && pAcroForm->GetBoolean("NeedAppearances"); | 22 FX_BOOL bRegenerateAP = pAcroForm && pAcroForm->GetBoolean("NeedAppearances"); |
25 for (FX_DWORD i = 0; i < pAnnots->GetCount(); ++i) { | 23 for (FX_DWORD i = 0; i < pAnnots->GetCount(); ++i) { |
26 CPDF_Dictionary* pDict = ToDictionary(pAnnots->GetElementValue(i)); | 24 CPDF_Dictionary* pDict = ToDictionary(pAnnots->GetElementValue(i)); |
27 if (!pDict) { | 25 if (!pDict) |
28 continue; | 26 continue; |
29 } | 27 |
30 FX_DWORD dwObjNum = pDict->GetObjNum(); | 28 FX_DWORD dwObjNum = pDict->GetObjNum(); |
31 if (dwObjNum == 0) { | 29 if (dwObjNum == 0) { |
32 dwObjNum = m_pDocument->AddIndirectObject(pDict); | 30 dwObjNum = m_pDocument->AddIndirectObject(pDict); |
33 CPDF_Reference* pAction = new CPDF_Reference(m_pDocument, dwObjNum); | 31 CPDF_Reference* pAction = new CPDF_Reference(m_pDocument, dwObjNum); |
34 pAnnots->InsertAt(i, pAction); | 32 pAnnots->InsertAt(i, pAction); |
35 pAnnots->RemoveAt(i + 1); | 33 pAnnots->RemoveAt(i + 1); |
36 pDict = pAnnots->GetDict(i); | 34 pDict = pAnnots->GetDict(i); |
37 } | 35 } |
38 CPDF_Annot* pAnnot = new CPDF_Annot(pDict, this); | 36 m_AnnotList.push_back(new CPDF_Annot(pDict, this)); |
39 m_AnnotList.Add(pAnnot); | |
40 if (bRegenerateAP && | 37 if (bRegenerateAP && |
41 pDict->GetConstString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget")) | 38 pDict->GetConstString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget") && |
42 if (CPDF_InterForm::UpdatingAPEnabled()) { | 39 CPDF_InterForm::UpdatingAPEnabled()) { |
43 FPDF_GenerateAP(m_pDocument, pDict); | 40 FPDF_GenerateAP(m_pDocument, pDict); |
44 } | 41 } |
45 } | 42 } |
46 } | 43 } |
| 44 |
47 CPDF_AnnotList::~CPDF_AnnotList() { | 45 CPDF_AnnotList::~CPDF_AnnotList() { |
48 int i = 0; | 46 for (CPDF_Annot* annot : m_AnnotList) |
49 for (i = 0; i < m_AnnotList.GetSize(); ++i) { | 47 delete annot; |
50 delete (CPDF_Annot*)m_AnnotList[i]; | |
51 } | |
52 for (i = 0; i < m_Borders.GetSize(); ++i) { | |
53 delete (CPDF_PageObjects*)m_Borders[i]; | |
54 } | |
55 } | 48 } |
| 49 |
56 void CPDF_AnnotList::DisplayPass(const CPDF_Page* pPage, | 50 void CPDF_AnnotList::DisplayPass(const CPDF_Page* pPage, |
57 CFX_RenderDevice* pDevice, | 51 CFX_RenderDevice* pDevice, |
58 CPDF_RenderContext* pContext, | 52 CPDF_RenderContext* pContext, |
59 FX_BOOL bPrinting, | 53 FX_BOOL bPrinting, |
60 CFX_AffineMatrix* pMatrix, | 54 CFX_AffineMatrix* pMatrix, |
61 FX_BOOL bWidgetPass, | 55 FX_BOOL bWidgetPass, |
62 CPDF_RenderOptions* pOptions, | 56 CPDF_RenderOptions* pOptions, |
63 FX_RECT* clip_rect) { | 57 FX_RECT* clip_rect) { |
64 for (int i = 0; i < m_AnnotList.GetSize(); ++i) { | 58 for (CPDF_Annot* pAnnot : m_AnnotList) { |
65 CPDF_Annot* pAnnot = (CPDF_Annot*)m_AnnotList[i]; | |
66 FX_BOOL bWidget = pAnnot->GetSubType() == "Widget"; | 59 FX_BOOL bWidget = pAnnot->GetSubType() == "Widget"; |
67 if ((bWidgetPass && !bWidget) || (!bWidgetPass && bWidget)) { | 60 if ((bWidgetPass && !bWidget) || (!bWidgetPass && bWidget)) |
68 continue; | 61 continue; |
69 } | 62 |
70 FX_DWORD annot_flags = pAnnot->GetFlags(); | 63 FX_DWORD annot_flags = pAnnot->GetFlags(); |
71 if (annot_flags & ANNOTFLAG_HIDDEN) { | 64 if (annot_flags & ANNOTFLAG_HIDDEN) |
72 continue; | 65 continue; |
73 } | 66 |
74 if (bPrinting && (annot_flags & ANNOTFLAG_PRINT) == 0) { | 67 if (bPrinting && (annot_flags & ANNOTFLAG_PRINT) == 0) |
75 continue; | 68 continue; |
76 } | 69 |
77 if (!bPrinting && (annot_flags & ANNOTFLAG_NOVIEW)) { | 70 if (!bPrinting && (annot_flags & ANNOTFLAG_NOVIEW)) |
78 continue; | 71 continue; |
79 } | 72 |
80 if (pOptions != NULL) { | 73 if (pOptions) { |
81 IPDF_OCContext* pOCContext = pOptions->m_pOCContext; | 74 IPDF_OCContext* pOCContext = pOptions->m_pOCContext; |
82 CPDF_Dictionary* pAnnotDict = pAnnot->GetAnnotDict(); | 75 CPDF_Dictionary* pAnnotDict = pAnnot->GetAnnotDict(); |
83 if (pOCContext != NULL && pAnnotDict != NULL && | 76 if (pOCContext && pAnnotDict && |
84 !pOCContext->CheckOCGVisible(pAnnotDict->GetDict(FX_BSTRC("OC")))) { | 77 !pOCContext->CheckOCGVisible(pAnnotDict->GetDict(FX_BSTRC("OC")))) { |
85 continue; | 78 continue; |
86 } | 79 } |
87 } | 80 } |
88 CPDF_Rect annot_rect_f; | 81 CPDF_Rect annot_rect_f; |
89 pAnnot->GetRect(annot_rect_f); | 82 pAnnot->GetRect(annot_rect_f); |
90 CFX_Matrix matrix; | 83 CFX_Matrix matrix = *pMatrix; |
91 matrix = *pMatrix; | |
92 if (clip_rect) { | 84 if (clip_rect) { |
93 annot_rect_f.Transform(&matrix); | 85 annot_rect_f.Transform(&matrix); |
94 FX_RECT annot_rect = annot_rect_f.GetOutterRect(); | 86 FX_RECT annot_rect = annot_rect_f.GetOutterRect(); |
95 annot_rect.Intersect(*clip_rect); | 87 annot_rect.Intersect(*clip_rect); |
96 if (annot_rect.IsEmpty()) { | 88 if (annot_rect.IsEmpty()) { |
97 continue; | 89 continue; |
98 } | 90 } |
99 } | 91 } |
100 if (pContext) { | 92 if (pContext) { |
101 pAnnot->DrawInContext(pPage, pContext, &matrix, CPDF_Annot::Normal); | 93 pAnnot->DrawInContext(pPage, pContext, &matrix, CPDF_Annot::Normal); |
102 } else if (!pAnnot->DrawAppearance(pPage, pDevice, &matrix, | 94 } else if (!pAnnot->DrawAppearance(pPage, pDevice, &matrix, |
103 CPDF_Annot::Normal, pOptions)) { | 95 CPDF_Annot::Normal, pOptions)) { |
104 pAnnot->DrawBorder(pDevice, &matrix, pOptions); | 96 pAnnot->DrawBorder(pDevice, &matrix, pOptions); |
105 } | 97 } |
106 } | 98 } |
107 } | 99 } |
108 void CPDF_AnnotList::DisplayAnnots(const CPDF_Page* pPage, | 100 |
109 CFX_RenderDevice* pDevice, | |
110 CFX_AffineMatrix* pUser2Device, | |
111 FX_BOOL bShowWidget, | |
112 CPDF_RenderOptions* pOptions) { | |
113 FX_RECT clip_rect; | |
114 if (pDevice) { | |
115 clip_rect = pDevice->GetClipBox(); | |
116 } | |
117 FX_BOOL bPrinting = pDevice->GetDeviceClass() == FXDC_PRINTER || | |
118 (pOptions && (pOptions->m_Flags & RENDER_PRINTPREVIEW)); | |
119 DisplayAnnots(pPage, pDevice, NULL, bPrinting, pUser2Device, | |
120 bShowWidget ? 3 : 1, pOptions, &clip_rect); | |
121 } | |
122 void CPDF_AnnotList::DisplayAnnots(const CPDF_Page* pPage, | 101 void CPDF_AnnotList::DisplayAnnots(const CPDF_Page* pPage, |
123 CFX_RenderDevice* pDevice, | 102 CFX_RenderDevice* pDevice, |
124 CPDF_RenderContext* pContext, | 103 CPDF_RenderContext* pContext, |
125 FX_BOOL bPrinting, | 104 FX_BOOL bPrinting, |
126 CFX_AffineMatrix* pUser2Device, | 105 CFX_AffineMatrix* pUser2Device, |
127 FX_DWORD dwAnnotFlags, | 106 FX_DWORD dwAnnotFlags, |
128 CPDF_RenderOptions* pOptions, | 107 CPDF_RenderOptions* pOptions, |
129 FX_RECT* pClipRect) { | 108 FX_RECT* pClipRect) { |
130 if (dwAnnotFlags & 0x01) { | 109 if (dwAnnotFlags & 0x01) { |
131 DisplayPass(pPage, pDevice, pContext, bPrinting, pUser2Device, FALSE, | 110 DisplayPass(pPage, pDevice, pContext, bPrinting, pUser2Device, FALSE, |
132 pOptions, pClipRect); | 111 pOptions, pClipRect); |
133 } | 112 } |
134 if (dwAnnotFlags & 0x02) { | 113 if (dwAnnotFlags & 0x02) { |
135 DisplayPass(pPage, pDevice, pContext, bPrinting, pUser2Device, TRUE, | 114 DisplayPass(pPage, pDevice, pContext, bPrinting, pUser2Device, TRUE, |
136 pOptions, pClipRect); | 115 pOptions, pClipRect); |
137 } | 116 } |
138 } | 117 } |
139 int CPDF_AnnotList::GetIndex(CPDF_Annot* pAnnot) { | 118 |
140 for (int i = 0; i < m_AnnotList.GetSize(); ++i) | |
141 if (m_AnnotList[i] == (void*)pAnnot) { | |
142 return i; | |
143 } | |
144 return -1; | |
145 } | |
146 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, CPDF_AnnotList* pList) | 119 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, CPDF_AnnotList* pList) |
147 : m_pAnnotDict(pDict), | 120 : m_pAnnotDict(pDict), |
148 m_pList(pList), | 121 m_pList(pList), |
149 m_sSubtype(m_pAnnotDict->GetConstString(FX_BSTRC("Subtype"))) {} | 122 m_sSubtype(m_pAnnotDict->GetConstString(FX_BSTRC("Subtype"))) {} |
150 CPDF_Annot::~CPDF_Annot() { | 123 CPDF_Annot::~CPDF_Annot() { |
151 ClearCachedAP(); | 124 ClearCachedAP(); |
152 } | 125 } |
153 void CPDF_Annot::ClearCachedAP() { | 126 void CPDF_Annot::ClearCachedAP() { |
154 FX_POSITION pos = m_APMap.GetStartPosition(); | 127 FX_POSITION pos = m_APMap.GetStartPosition(); |
155 while (pos) { | 128 while (pos) { |
(...skipping 13 matching lines...) Expand all Loading... |
169 return; | 142 return; |
170 } | 143 } |
171 rect = m_pAnnotDict->GetRect("Rect"); | 144 rect = m_pAnnotDict->GetRect("Rect"); |
172 rect.Normalize(); | 145 rect.Normalize(); |
173 } | 146 } |
174 | 147 |
175 FX_DWORD CPDF_Annot::GetFlags() const { | 148 FX_DWORD CPDF_Annot::GetFlags() const { |
176 return m_pAnnotDict->GetInteger("F"); | 149 return m_pAnnotDict->GetInteger("F"); |
177 } | 150 } |
178 | 151 |
179 CPDF_Dictionary* CPDF_Annot::GetAnnotDict() { | |
180 return m_pAnnotDict; | |
181 } | |
182 | |
183 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict, | 152 CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict, |
184 CPDF_Annot::AppearanceMode mode) { | 153 CPDF_Annot::AppearanceMode mode) { |
185 CPDF_Dictionary* pAP = pAnnotDict->GetDict("AP"); | 154 CPDF_Dictionary* pAP = pAnnotDict->GetDict("AP"); |
186 if (pAP == NULL) { | 155 if (pAP == NULL) { |
187 return NULL; | 156 return NULL; |
188 } | 157 } |
189 const FX_CHAR* ap_entry = "N"; | 158 const FX_CHAR* ap_entry = "N"; |
190 if (mode == CPDF_Annot::Down) | 159 if (mode == CPDF_Annot::Down) |
191 ap_entry = "D"; | 160 ap_entry = "D"; |
192 else if (mode == CPDF_Annot::Rollover) | 161 else if (mode == CPDF_Annot::Rollover) |
(...skipping 17 matching lines...) Expand all Loading... |
210 } | 179 } |
211 if (value.IsEmpty() || !pDict->KeyExist(value)) | 180 if (value.IsEmpty() || !pDict->KeyExist(value)) |
212 as = FX_BSTRC("Off"); | 181 as = FX_BSTRC("Off"); |
213 else | 182 else |
214 as = value; | 183 as = value; |
215 } | 184 } |
216 return pDict->GetStream(as); | 185 return pDict->GetStream(as); |
217 } | 186 } |
218 return nullptr; | 187 return nullptr; |
219 } | 188 } |
| 189 |
220 CPDF_Form* CPDF_Annot::GetAPForm(const CPDF_Page* pPage, AppearanceMode mode) { | 190 CPDF_Form* CPDF_Annot::GetAPForm(const CPDF_Page* pPage, AppearanceMode mode) { |
221 CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(m_pAnnotDict, mode); | 191 CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(m_pAnnotDict, mode); |
222 if (pStream == NULL) { | 192 if (!pStream) |
223 return NULL; | 193 return nullptr; |
224 } | 194 |
225 CPDF_Form* pForm; | 195 void* pForm; |
226 if (m_APMap.Lookup(pStream, (void*&)pForm)) { | 196 if (m_APMap.Lookup(pStream, pForm)) |
227 return pForm; | 197 return static_cast<CPDF_Form*>(pForm); |
228 } | 198 |
229 pForm = new CPDF_Form(m_pList->m_pDocument, pPage->m_pResources, pStream); | 199 CPDF_Form* pNewForm = |
230 pForm->ParseContent(NULL, NULL, NULL, NULL); | 200 new CPDF_Form(m_pList->GetDocument(), pPage->m_pResources, pStream); |
231 m_APMap.SetAt(pStream, pForm); | 201 pNewForm->ParseContent(nullptr, nullptr, nullptr, nullptr); |
232 return pForm; | 202 m_APMap.SetAt(pStream, pNewForm); |
| 203 return pNewForm; |
233 } | 204 } |
| 205 |
234 static CPDF_Form* FPDFDOC_Annot_GetMatrix(const CPDF_Page* pPage, | 206 static CPDF_Form* FPDFDOC_Annot_GetMatrix(const CPDF_Page* pPage, |
235 CPDF_Annot* pAnnot, | 207 CPDF_Annot* pAnnot, |
236 CPDF_Annot::AppearanceMode mode, | 208 CPDF_Annot::AppearanceMode mode, |
237 const CFX_AffineMatrix* pUser2Device, | 209 const CFX_AffineMatrix* pUser2Device, |
238 CFX_Matrix& matrix) { | 210 CFX_Matrix& matrix) { |
239 CPDF_Form* pForm = pAnnot->GetAPForm(pPage, mode); | 211 CPDF_Form* pForm = pAnnot->GetAPForm(pPage, mode); |
240 if (!pForm) { | 212 if (!pForm) { |
241 return NULL; | 213 return NULL; |
242 } | 214 } |
243 CFX_FloatRect form_bbox = pForm->m_pFormDict->GetRect(FX_BSTRC("BBox")); | 215 CFX_FloatRect form_bbox = pForm->m_pFormDict->GetRect(FX_BSTRC("BBox")); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 CPDF_PathData path; | 343 CPDF_PathData path; |
372 width /= 2; | 344 width /= 2; |
373 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, | 345 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, |
374 rect.top - width); | 346 rect.top - width); |
375 int fill_type = 0; | 347 int fill_type = 0; |
376 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { | 348 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { |
377 fill_type |= FXFILL_NOPATHSMOOTH; | 349 fill_type |= FXFILL_NOPATHSMOOTH; |
378 } | 350 } |
379 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); | 351 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); |
380 } | 352 } |
OLD | NEW |