OLD | NEW |
1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 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 "core/fpdfdoc/include/cpdf_annot.h" | 7 #include "core/fpdfdoc/include/cpdf_annot.h" |
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_page/include/cpdf_page.h" | 10 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" |
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
13 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h" | 13 #include "core/fpdfapi/fpdf_render/include/cpdf_rendercontext.h" |
14 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" | 14 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" |
15 #include "core/fpdfdoc/cpvt_generateap.h" | 15 #include "core/fpdfdoc/cpvt_generateap.h" |
16 #include "core/fxcrt/include/fx_memory.h" | 16 #include "core/fxcrt/include/fx_memory.h" |
17 #include "core/fxge/include/cfx_graphstatedata.h" | 17 #include "core/fxge/include/cfx_graphstatedata.h" |
18 #include "core/fxge/include/cfx_pathdata.h" | 18 #include "core/fxge/include/cfx_pathdata.h" |
19 #include "core/fxge/include/cfx_renderdevice.h" | 19 #include "core/fxge/include/cfx_renderdevice.h" |
20 | 20 |
21 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, CPDF_Document* pDocument) | 21 CPDF_Annot::CPDF_Annot(CPDF_Dictionary* pDict, CPDF_Document* pDocument) |
22 : m_pAnnotDict(pDict), | 22 : m_pAnnotDict(pDict), |
23 m_pDocument(pDocument), | 23 m_pDocument(pDocument), |
24 m_sSubtype(m_pAnnotDict->GetStringBy("Subtype")), | |
25 m_bOpenState(false), | 24 m_bOpenState(false), |
26 m_pPopupAnnot(nullptr) { | 25 m_pPopupAnnot(nullptr) { |
| 26 m_nSubtype = StringToAnnotSubtype(m_pAnnotDict->GetStringBy("Subtype")); |
27 GenerateAPIfNeeded(); | 27 GenerateAPIfNeeded(); |
28 } | 28 } |
29 | 29 |
30 CPDF_Annot::~CPDF_Annot() { | 30 CPDF_Annot::~CPDF_Annot() { |
31 ClearCachedAP(); | 31 ClearCachedAP(); |
32 } | 32 } |
33 | 33 |
34 void CPDF_Annot::GenerateAPIfNeeded() { | 34 void CPDF_Annot::GenerateAPIfNeeded() { |
35 if (m_sSubtype == "Circle") | 35 if (m_nSubtype == CPDF_Annot::Subtype::CIRCLE) |
36 CPVT_GenerateAP::GenerateCircleAP(m_pDocument, m_pAnnotDict); | 36 CPVT_GenerateAP::GenerateCircleAP(m_pDocument, m_pAnnotDict); |
37 else if (m_sSubtype == "Highlight") | 37 else if (m_nSubtype == CPDF_Annot::Subtype::HIGHLIGHT) |
38 CPVT_GenerateAP::GenerateHighlightAP(m_pDocument, m_pAnnotDict); | 38 CPVT_GenerateAP::GenerateHighlightAP(m_pDocument, m_pAnnotDict); |
39 else if (m_sSubtype == "Ink") | 39 else if (m_nSubtype == CPDF_Annot::Subtype::INK) |
40 CPVT_GenerateAP::GenerateInkAP(m_pDocument, m_pAnnotDict); | 40 CPVT_GenerateAP::GenerateInkAP(m_pDocument, m_pAnnotDict); |
41 else if (m_sSubtype == "Popup") | 41 else if (m_nSubtype == CPDF_Annot::Subtype::POPUP) |
42 CPVT_GenerateAP::GeneratePopupAP(m_pDocument, m_pAnnotDict); | 42 CPVT_GenerateAP::GeneratePopupAP(m_pDocument, m_pAnnotDict); |
43 else if (m_sSubtype == "Square") | 43 else if (m_nSubtype == CPDF_Annot::Subtype::SQUARE) |
44 CPVT_GenerateAP::GenerateSquareAP(m_pDocument, m_pAnnotDict); | 44 CPVT_GenerateAP::GenerateSquareAP(m_pDocument, m_pAnnotDict); |
45 else if (m_sSubtype == "Squiggly") | 45 else if (m_nSubtype == CPDF_Annot::Subtype::SQUIGGLY) |
46 CPVT_GenerateAP::GenerateSquigglyAP(m_pDocument, m_pAnnotDict); | 46 CPVT_GenerateAP::GenerateSquigglyAP(m_pDocument, m_pAnnotDict); |
47 else if (m_sSubtype == "StrikeOut") | 47 else if (m_nSubtype == CPDF_Annot::Subtype::STRIKEOUT) |
48 CPVT_GenerateAP::GenerateStrikeOutAP(m_pDocument, m_pAnnotDict); | 48 CPVT_GenerateAP::GenerateStrikeOutAP(m_pDocument, m_pAnnotDict); |
49 else if (m_sSubtype == "Text") | 49 else if (m_nSubtype == CPDF_Annot::Subtype::TEXT) |
50 CPVT_GenerateAP::GenerateTextAP(m_pDocument, m_pAnnotDict); | 50 CPVT_GenerateAP::GenerateTextAP(m_pDocument, m_pAnnotDict); |
51 else if (m_sSubtype == "Underline") | 51 else if (m_nSubtype == CPDF_Annot::Subtype::UNDERLINE) |
52 CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict); | 52 CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict); |
53 } | 53 } |
54 | 54 |
55 void CPDF_Annot::ClearCachedAP() { | 55 void CPDF_Annot::ClearCachedAP() { |
56 m_APMap.clear(); | 56 m_APMap.clear(); |
57 } | 57 } |
58 CFX_ByteString CPDF_Annot::GetSubtype() const { | 58 |
59 return m_sSubtype; | 59 CPDF_Annot::Subtype CPDF_Annot::GetSubtype() const { |
| 60 return m_nSubtype; |
60 } | 61 } |
61 | 62 |
62 CFX_FloatRect CPDF_Annot::GetRect() const { | 63 CFX_FloatRect CPDF_Annot::GetRect() const { |
63 if (!m_pAnnotDict) | 64 if (!m_pAnnotDict) |
64 return CFX_FloatRect(); | 65 return CFX_FloatRect(); |
65 | 66 |
66 CFX_FloatRect rect = m_pAnnotDict->GetRectBy("Rect"); | 67 CFX_FloatRect rect = m_pAnnotDict->GetRectBy("Rect"); |
67 rect.Normalize(); | 68 rect.Normalize(); |
68 return rect; | 69 return rect; |
69 } | 70 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 matrix.MatchRect(pAnnot->GetRect(), form_bbox); | 142 matrix.MatchRect(pAnnot->GetRect(), form_bbox); |
142 matrix.Concat(*pUser2Device); | 143 matrix.Concat(*pUser2Device); |
143 return pForm; | 144 return pForm; |
144 } | 145 } |
145 | 146 |
146 // static | 147 // static |
147 bool CPDF_Annot::IsAnnotationHidden(CPDF_Dictionary* pAnnotDict) { | 148 bool CPDF_Annot::IsAnnotationHidden(CPDF_Dictionary* pAnnotDict) { |
148 return !!(pAnnotDict->GetIntegerBy("F") & ANNOTFLAG_HIDDEN); | 149 return !!(pAnnotDict->GetIntegerBy("F") & ANNOTFLAG_HIDDEN); |
149 } | 150 } |
150 | 151 |
| 152 // Static. |
| 153 CPDF_Annot::Subtype CPDF_Annot::StringToAnnotSubtype( |
| 154 const CFX_ByteString& sSubtype) { |
| 155 if (sSubtype == "Text") |
| 156 return CPDF_Annot::Subtype::TEXT; |
| 157 if (sSubtype == "Link") |
| 158 return CPDF_Annot::Subtype::LINK; |
| 159 if (sSubtype == "FreeText") |
| 160 return CPDF_Annot::Subtype::FREETEXT; |
| 161 if (sSubtype == "Line") |
| 162 return CPDF_Annot::Subtype::LINE; |
| 163 if (sSubtype == "Square") |
| 164 return CPDF_Annot::Subtype::SQUARE; |
| 165 if (sSubtype == "Circle") |
| 166 return CPDF_Annot::Subtype::CIRCLE; |
| 167 if (sSubtype == "Polygon") |
| 168 return CPDF_Annot::Subtype::POLYGON; |
| 169 if (sSubtype == "PolyLine") |
| 170 return CPDF_Annot::Subtype::POLYLINE; |
| 171 if (sSubtype == "Highlight") |
| 172 return CPDF_Annot::Subtype::HIGHLIGHT; |
| 173 if (sSubtype == "Underline") |
| 174 return CPDF_Annot::Subtype::UNDERLINE; |
| 175 if (sSubtype == "Squiggly") |
| 176 return CPDF_Annot::Subtype::SQUIGGLY; |
| 177 if (sSubtype == "StrikeOut") |
| 178 return CPDF_Annot::Subtype::STRIKEOUT; |
| 179 if (sSubtype == "Stamp") |
| 180 return CPDF_Annot::Subtype::STAMP; |
| 181 if (sSubtype == "Caret") |
| 182 return CPDF_Annot::Subtype::CARET; |
| 183 if (sSubtype == "Ink") |
| 184 return CPDF_Annot::Subtype::INK; |
| 185 if (sSubtype == "Popup") |
| 186 return CPDF_Annot::Subtype::POPUP; |
| 187 if (sSubtype == "FileAttachment") |
| 188 return CPDF_Annot::Subtype::FILEATTACHMENT; |
| 189 if (sSubtype == "Sound") |
| 190 return CPDF_Annot::Subtype::SOUND; |
| 191 if (sSubtype == "Movie") |
| 192 return CPDF_Annot::Subtype::MOVIE; |
| 193 if (sSubtype == "Widget") |
| 194 return CPDF_Annot::Subtype::WIDGET; |
| 195 if (sSubtype == "Screen") |
| 196 return CPDF_Annot::Subtype::SCREEN; |
| 197 if (sSubtype == "PrinterMark") |
| 198 return CPDF_Annot::Subtype::PRINTERMARK; |
| 199 if (sSubtype == "TrapNet") |
| 200 return CPDF_Annot::Subtype::TRAPNET; |
| 201 if (sSubtype == "Watermark") |
| 202 return CPDF_Annot::Subtype::WATERMARK; |
| 203 if (sSubtype == "3D") |
| 204 return CPDF_Annot::Subtype::THREED; |
| 205 if (sSubtype == "RichMedia") |
| 206 return CPDF_Annot::Subtype::RICHMEDIA; |
| 207 if (sSubtype == "XFAWidget") |
| 208 return CPDF_Annot::Subtype::XFAWIDGET; |
| 209 return CPDF_Annot::Subtype::UNKNOWN; |
| 210 } |
| 211 |
| 212 // Static. |
| 213 CFX_ByteString CPDF_Annot::AnnotSubtypeToString(CPDF_Annot::Subtype nSubtype) { |
| 214 if (nSubtype == CPDF_Annot::Subtype::TEXT) |
| 215 return "Text"; |
| 216 if (nSubtype == CPDF_Annot::Subtype::LINK) |
| 217 return "Link"; |
| 218 if (nSubtype == CPDF_Annot::Subtype::FREETEXT) |
| 219 return "FreeText"; |
| 220 if (nSubtype == CPDF_Annot::Subtype::LINE) |
| 221 return "Line"; |
| 222 if (nSubtype == CPDF_Annot::Subtype::SQUARE) |
| 223 return "Square"; |
| 224 if (nSubtype == CPDF_Annot::Subtype::CIRCLE) |
| 225 return "Circle"; |
| 226 if (nSubtype == CPDF_Annot::Subtype::POLYGON) |
| 227 return "Polygon"; |
| 228 if (nSubtype == CPDF_Annot::Subtype::POLYLINE) |
| 229 return "PolyLine"; |
| 230 if (nSubtype == CPDF_Annot::Subtype::HIGHLIGHT) |
| 231 return "Highlight"; |
| 232 if (nSubtype == CPDF_Annot::Subtype::UNDERLINE) |
| 233 return "Underline"; |
| 234 if (nSubtype == CPDF_Annot::Subtype::SQUIGGLY) |
| 235 return "Squiggly"; |
| 236 if (nSubtype == CPDF_Annot::Subtype::STRIKEOUT) |
| 237 return "StrikeOut"; |
| 238 if (nSubtype == CPDF_Annot::Subtype::STAMP) |
| 239 return "Stamp"; |
| 240 if (nSubtype == CPDF_Annot::Subtype::CARET) |
| 241 return "Caret"; |
| 242 if (nSubtype == CPDF_Annot::Subtype::INK) |
| 243 return "Ink"; |
| 244 if (nSubtype == CPDF_Annot::Subtype::POPUP) |
| 245 return "Popup"; |
| 246 if (nSubtype == CPDF_Annot::Subtype::FILEATTACHMENT) |
| 247 return "FileAttachment"; |
| 248 if (nSubtype == CPDF_Annot::Subtype::SOUND) |
| 249 return "Sound"; |
| 250 if (nSubtype == CPDF_Annot::Subtype::MOVIE) |
| 251 return "Movie"; |
| 252 if (nSubtype == CPDF_Annot::Subtype::WIDGET) |
| 253 return "Widget"; |
| 254 if (nSubtype == CPDF_Annot::Subtype::SCREEN) |
| 255 return "Screen"; |
| 256 if (nSubtype == CPDF_Annot::Subtype::PRINTERMARK) |
| 257 return "PrinterMark"; |
| 258 if (nSubtype == CPDF_Annot::Subtype::TRAPNET) |
| 259 return "TrapNet"; |
| 260 if (nSubtype == CPDF_Annot::Subtype::WATERMARK) |
| 261 return "Watermark"; |
| 262 if (nSubtype == CPDF_Annot::Subtype::THREED) |
| 263 return "3D"; |
| 264 if (nSubtype == CPDF_Annot::Subtype::RICHMEDIA) |
| 265 return "RichMedia"; |
| 266 if (nSubtype == CPDF_Annot::Subtype::XFAWIDGET) |
| 267 return "XFAWidget"; |
| 268 return ""; |
| 269 } |
| 270 |
151 FX_BOOL CPDF_Annot::DrawAppearance(CPDF_Page* pPage, | 271 FX_BOOL CPDF_Annot::DrawAppearance(CPDF_Page* pPage, |
152 CFX_RenderDevice* pDevice, | 272 CFX_RenderDevice* pDevice, |
153 const CFX_Matrix* pUser2Device, | 273 const CFX_Matrix* pUser2Device, |
154 AppearanceMode mode, | 274 AppearanceMode mode, |
155 const CPDF_RenderOptions* pOptions) { | 275 const CPDF_RenderOptions* pOptions) { |
156 if (IsAnnotationHidden(m_pAnnotDict)) | 276 if (IsAnnotationHidden(m_pAnnotDict)) |
157 return FALSE; | 277 return FALSE; |
158 | 278 |
159 if (m_sSubtype == "Popup" && !m_bOpenState) | 279 if (m_nSubtype == CPDF_Annot::Subtype::POPUP && !m_bOpenState) |
160 return FALSE; | 280 return FALSE; |
161 | 281 |
162 // It might happen that by the time this annotation instance was created, | 282 // It might happen that by the time this annotation instance was created, |
163 // it was flagged as "hidden" (e.g. /F 2), and hence CPVT_GenerateAP decided | 283 // it was flagged as "hidden" (e.g. /F 2), and hence CPVT_GenerateAP decided |
164 // to not "generate" its AP. | 284 // to not "generate" its AP. |
165 // If for a reason the object is no longer hidden, but still does not have | 285 // If for a reason the object is no longer hidden, but still does not have |
166 // its "AP" generated, generate it now. | 286 // its "AP" generated, generate it now. |
167 GenerateAPIfNeeded(); | 287 GenerateAPIfNeeded(); |
168 | 288 |
169 CFX_Matrix matrix; | 289 CFX_Matrix matrix; |
(...skipping 16 matching lines...) Expand all Loading... |
186 FPDFDOC_Annot_GetMatrix(pPage, this, mode, pUser2Device, matrix); | 306 FPDFDOC_Annot_GetMatrix(pPage, this, mode, pUser2Device, matrix); |
187 if (!pForm) { | 307 if (!pForm) { |
188 return FALSE; | 308 return FALSE; |
189 } | 309 } |
190 pContext->AppendLayer(pForm, &matrix); | 310 pContext->AppendLayer(pForm, &matrix); |
191 return TRUE; | 311 return TRUE; |
192 } | 312 } |
193 void CPDF_Annot::DrawBorder(CFX_RenderDevice* pDevice, | 313 void CPDF_Annot::DrawBorder(CFX_RenderDevice* pDevice, |
194 const CFX_Matrix* pUser2Device, | 314 const CFX_Matrix* pUser2Device, |
195 const CPDF_RenderOptions* pOptions) { | 315 const CPDF_RenderOptions* pOptions) { |
196 if (GetSubtype() == "Popup") | 316 if (GetSubtype() == CPDF_Annot::Subtype::POPUP) |
197 return; | 317 return; |
198 | 318 |
199 uint32_t annot_flags = GetFlags(); | 319 uint32_t annot_flags = GetFlags(); |
200 if (annot_flags & ANNOTFLAG_HIDDEN) { | 320 if (annot_flags & ANNOTFLAG_HIDDEN) { |
201 return; | 321 return; |
202 } | 322 } |
203 bool bPrinting = pDevice->GetDeviceClass() == FXDC_PRINTER || | 323 bool bPrinting = pDevice->GetDeviceClass() == FXDC_PRINTER || |
204 (pOptions && (pOptions->m_Flags & RENDER_PRINTPREVIEW)); | 324 (pOptions && (pOptions->m_Flags & RENDER_PRINTPREVIEW)); |
205 if (bPrinting && (annot_flags & ANNOTFLAG_PRINT) == 0) { | 325 if (bPrinting && (annot_flags & ANNOTFLAG_PRINT) == 0) { |
206 return; | 326 return; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 CFX_PathData path; | 402 CFX_PathData path; |
283 width /= 2; | 403 width /= 2; |
284 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, | 404 path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, |
285 rect.top - width); | 405 rect.top - width); |
286 int fill_type = 0; | 406 int fill_type = 0; |
287 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { | 407 if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { |
288 fill_type |= FXFILL_NOPATHSMOOTH; | 408 fill_type |= FXFILL_NOPATHSMOOTH; |
289 } | 409 } |
290 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); | 410 pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); |
291 } | 411 } |
OLD | NEW |