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

Side by Side Diff: core/fpdfapi/fpdf_page/fpdf_page_doc.cpp

Issue 2386423004: Move core/fpdfapi/fpdf_page to core/fpdfapi/page (Closed)
Patch Set: Rebase to master Created 4 years, 2 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/fpdfapi/fpdf_page/fpdf_page_colors.cpp ('k') | core/fpdfapi/fpdf_page/fpdf_page_func.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/fpdfapi/fpdf_page/pageint.h"
8
9 #include <algorithm>
10 #include <set>
11
12 #include "core/fdrm/crypto/fx_crypt.h"
13 #include "core/fpdfapi/cpdf_modulemgr.h"
14 #include "core/fpdfapi/font/cpdf_type1font.h"
15 #include "core/fpdfapi/font/font_int.h"
16 #include "core/fpdfapi/fpdf_page/cpdf_image.h"
17 #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h"
18 #include "core/fpdfapi/fpdf_page/cpdf_pattern.h"
19 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
20 #include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h"
21 #include "core/fpdfapi/fpdf_parser/cpdf_array.h"
22 #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
23 #include "core/fpdfapi/fpdf_parser/cpdf_document.h"
24 #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h"
25 #include "third_party/base/stl_util.h"
26
27 void CPDF_ModuleMgr::InitPageModule() {
28 m_pPageModule.reset(new CPDF_PageModule);
29 }
30
31 CPDF_DocPageData::CPDF_DocPageData(CPDF_Document* pPDFDoc)
32 : m_pPDFDoc(pPDFDoc), m_bForceClear(FALSE) {}
33
34 CPDF_DocPageData::~CPDF_DocPageData() {
35 Clear(FALSE);
36 Clear(TRUE);
37
38 for (auto& it : m_PatternMap)
39 delete it.second;
40 m_PatternMap.clear();
41
42 for (auto& it : m_FontMap)
43 delete it.second;
44 m_FontMap.clear();
45
46 for (auto& it : m_ColorSpaceMap)
47 delete it.second;
48 m_ColorSpaceMap.clear();
49 }
50
51 void CPDF_DocPageData::Clear(FX_BOOL bForceRelease) {
52 m_bForceClear = bForceRelease;
53
54 for (auto& it : m_PatternMap) {
55 CPDF_CountedPattern* ptData = it.second;
56 if (!ptData->get())
57 continue;
58
59 if (bForceRelease || ptData->use_count() < 2)
60 ptData->clear();
61 }
62
63 for (auto& it : m_FontMap) {
64 CPDF_CountedFont* fontData = it.second;
65 if (!fontData->get())
66 continue;
67
68 if (bForceRelease || fontData->use_count() < 2) {
69 fontData->clear();
70 }
71 }
72
73 for (auto& it : m_ColorSpaceMap) {
74 CPDF_CountedColorSpace* csData = it.second;
75 if (!csData->get())
76 continue;
77
78 if (bForceRelease || csData->use_count() < 2) {
79 csData->get()->Release();
80 csData->reset(nullptr);
81 }
82 }
83
84 for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end();) {
85 auto curr_it = it++;
86 CPDF_CountedIccProfile* ipData = curr_it->second;
87 if (!ipData->get())
88 continue;
89
90 if (bForceRelease || ipData->use_count() < 2) {
91 for (auto hash_it = m_HashProfileMap.begin();
92 hash_it != m_HashProfileMap.end(); ++hash_it) {
93 if (curr_it->first == hash_it->second) {
94 m_HashProfileMap.erase(hash_it);
95 break;
96 }
97 }
98 delete ipData->get();
99 delete ipData;
100 m_IccProfileMap.erase(curr_it);
101 }
102 }
103
104 for (auto it = m_FontFileMap.begin(); it != m_FontFileMap.end();) {
105 auto curr_it = it++;
106 CPDF_CountedStreamAcc* pCountedFont = curr_it->second;
107 if (!pCountedFont->get())
108 continue;
109
110 if (bForceRelease || pCountedFont->use_count() < 2) {
111 delete pCountedFont->get();
112 delete pCountedFont;
113 m_FontFileMap.erase(curr_it);
114 }
115 }
116
117 for (auto it = m_ImageMap.begin(); it != m_ImageMap.end();) {
118 auto curr_it = it++;
119 CPDF_CountedImage* pCountedImage = curr_it->second;
120 if (!pCountedImage->get())
121 continue;
122
123 if (bForceRelease || pCountedImage->use_count() < 2) {
124 delete pCountedImage->get();
125 delete pCountedImage;
126 m_ImageMap.erase(curr_it);
127 }
128 }
129 }
130
131 CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict,
132 FX_BOOL findOnly) {
133 if (!pFontDict)
134 return nullptr;
135
136 CPDF_CountedFont* pFontData = nullptr;
137 auto it = m_FontMap.find(pFontDict);
138 if (it != m_FontMap.end()) {
139 pFontData = it->second;
140 if (pFontData->get()) {
141 return pFontData->AddRef();
142 }
143 }
144
145 if (findOnly)
146 return nullptr;
147
148 std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(m_pPDFDoc, pFontDict);
149 if (!pFont)
150 return nullptr;
151
152 if (pFontData) {
153 pFontData->reset(pFont.release());
154 } else {
155 pFontData = new CPDF_CountedFont(pFont.release());
156 m_FontMap[pFontDict] = pFontData;
157 }
158 return pFontData->AddRef();
159 }
160
161 CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName,
162 CPDF_FontEncoding* pEncoding) {
163 if (fontName.IsEmpty())
164 return nullptr;
165
166 for (auto& it : m_FontMap) {
167 CPDF_CountedFont* fontData = it.second;
168 CPDF_Font* pFont = fontData->get();
169 if (!pFont)
170 continue;
171 if (pFont->GetBaseFont() != fontName)
172 continue;
173 if (pFont->IsEmbedded())
174 continue;
175 if (!pFont->IsType1Font())
176 continue;
177 if (pFont->GetFontDict()->KeyExist("Widths"))
178 continue;
179
180 CPDF_Type1Font* pT1Font = pFont->AsType1Font();
181 if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding))
182 continue;
183
184 return fontData->AddRef();
185 }
186
187 CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPDFDoc->GetByteStringPool());
188 pDict->SetNameFor("Type", "Font");
189 pDict->SetNameFor("Subtype", "Type1");
190 pDict->SetNameFor("BaseFont", fontName);
191 if (pEncoding) {
192 pDict->SetFor("Encoding",
193 pEncoding->Realize(m_pPDFDoc->GetByteStringPool()));
194 }
195 m_pPDFDoc->AddIndirectObject(pDict);
196 std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(m_pPDFDoc, pDict);
197 if (!pFont)
198 return nullptr;
199
200 CPDF_CountedFont* fontData = new CPDF_CountedFont(pFont.release());
201 m_FontMap[pDict] = fontData;
202 return fontData->AddRef();
203 }
204
205 void CPDF_DocPageData::ReleaseFont(const CPDF_Dictionary* pFontDict) {
206 if (!pFontDict)
207 return;
208
209 auto it = m_FontMap.find(pFontDict);
210 if (it == m_FontMap.end())
211 return;
212
213 CPDF_CountedFont* pFontData = it->second;
214 if (!pFontData->get())
215 return;
216
217 pFontData->RemoveRef();
218 if (pFontData->use_count() > 1)
219 return;
220
221 // We have font data only in m_FontMap cache. Clean it.
222 pFontData->clear();
223 }
224
225 CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace(
226 CPDF_Object* pCSObj,
227 const CPDF_Dictionary* pResources) {
228 std::set<CPDF_Object*> visited;
229 return GetColorSpaceImpl(pCSObj, pResources, &visited);
230 }
231
232 CPDF_ColorSpace* CPDF_DocPageData::GetColorSpaceImpl(
233 CPDF_Object* pCSObj,
234 const CPDF_Dictionary* pResources,
235 std::set<CPDF_Object*>* pVisited) {
236 if (!pCSObj)
237 return nullptr;
238
239 if (pdfium::ContainsKey(*pVisited, pCSObj))
240 return nullptr;
241
242 if (pCSObj->IsName()) {
243 CFX_ByteString name = pCSObj->GetString();
244 CPDF_ColorSpace* pCS = CPDF_ColorSpace::ColorspaceFromName(name);
245 if (!pCS && pResources) {
246 CPDF_Dictionary* pList = pResources->GetDictFor("ColorSpace");
247 if (pList) {
248 pdfium::ScopedSetInsertion<CPDF_Object*> insertion(pVisited, pCSObj);
249 return GetColorSpaceImpl(pList->GetDirectObjectFor(name), nullptr,
250 pVisited);
251 }
252 }
253 if (!pCS || !pResources)
254 return pCS;
255
256 CPDF_Dictionary* pColorSpaces = pResources->GetDictFor("ColorSpace");
257 if (!pColorSpaces)
258 return pCS;
259
260 CPDF_Object* pDefaultCS = nullptr;
261 switch (pCS->GetFamily()) {
262 case PDFCS_DEVICERGB:
263 pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultRGB");
264 break;
265 case PDFCS_DEVICEGRAY:
266 pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultGray");
267 break;
268 case PDFCS_DEVICECMYK:
269 pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultCMYK");
270 break;
271 }
272 if (!pDefaultCS)
273 return pCS;
274
275 pdfium::ScopedSetInsertion<CPDF_Object*> insertion(pVisited, pCSObj);
276 return GetColorSpaceImpl(pDefaultCS, nullptr, pVisited);
277 }
278
279 CPDF_Array* pArray = pCSObj->AsArray();
280 if (!pArray || pArray->IsEmpty())
281 return nullptr;
282
283 if (pArray->GetCount() == 1) {
284 pdfium::ScopedSetInsertion<CPDF_Object*> insertion(pVisited, pCSObj);
285 return GetColorSpaceImpl(pArray->GetDirectObjectAt(0), pResources,
286 pVisited);
287 }
288
289 CPDF_CountedColorSpace* csData = nullptr;
290 auto it = m_ColorSpaceMap.find(pCSObj);
291 if (it != m_ColorSpaceMap.end()) {
292 csData = it->second;
293 if (csData->get()) {
294 return csData->AddRef();
295 }
296 }
297
298 std::unique_ptr<CPDF_ColorSpace> pCS =
299 CPDF_ColorSpace::Load(m_pPDFDoc, pArray);
300 if (!pCS)
301 return nullptr;
302
303 if (!csData) {
304 csData = new CPDF_CountedColorSpace(pCS.release());
305 m_ColorSpaceMap[pCSObj] = csData;
306 } else {
307 csData->reset(pCS.release());
308 }
309 return csData->AddRef();
310 }
311
312 CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj) {
313 if (!pCSObj)
314 return nullptr;
315
316 auto it = m_ColorSpaceMap.find(pCSObj);
317 if (it != m_ColorSpaceMap.end())
318 return it->second->AddRef();
319
320 return nullptr;
321 }
322
323 void CPDF_DocPageData::ReleaseColorSpace(const CPDF_Object* pColorSpace) {
324 if (!pColorSpace)
325 return;
326
327 auto it = m_ColorSpaceMap.find(pColorSpace);
328 if (it == m_ColorSpaceMap.end())
329 return;
330
331 CPDF_CountedColorSpace* pCountedColorSpace = it->second;
332 if (!pCountedColorSpace->get())
333 return;
334
335 pCountedColorSpace->RemoveRef();
336 if (pCountedColorSpace->use_count() > 1)
337 return;
338
339 // We have item only in m_ColorSpaceMap cache. Clean it.
340 pCountedColorSpace->get()->Release();
341 pCountedColorSpace->reset(nullptr);
342 }
343
344 CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj,
345 FX_BOOL bShading,
346 const CFX_Matrix& matrix) {
347 if (!pPatternObj)
348 return nullptr;
349
350 CPDF_CountedPattern* ptData = nullptr;
351 auto it = m_PatternMap.find(pPatternObj);
352 if (it != m_PatternMap.end()) {
353 ptData = it->second;
354 if (ptData->get()) {
355 return ptData->AddRef();
356 }
357 }
358 CPDF_Pattern* pPattern = nullptr;
359 if (bShading) {
360 pPattern = new CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, TRUE, matrix);
361 } else {
362 CPDF_Dictionary* pDict = pPatternObj ? pPatternObj->GetDict() : nullptr;
363 if (pDict) {
364 int type = pDict->GetIntegerFor("PatternType");
365 if (type == CPDF_Pattern::TILING) {
366 pPattern = new CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix);
367 } else if (type == CPDF_Pattern::SHADING) {
368 pPattern =
369 new CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix);
370 }
371 }
372 }
373 if (!pPattern)
374 return nullptr;
375
376 if (!ptData) {
377 ptData = new CPDF_CountedPattern(pPattern);
378 m_PatternMap[pPatternObj] = ptData;
379 } else {
380 ptData->reset(pPattern);
381 }
382 return ptData->AddRef();
383 }
384
385 void CPDF_DocPageData::ReleasePattern(const CPDF_Object* pPatternObj) {
386 if (!pPatternObj)
387 return;
388
389 auto it = m_PatternMap.find(pPatternObj);
390 if (it == m_PatternMap.end())
391 return;
392
393 CPDF_CountedPattern* pPattern = it->second;
394 if (!pPattern->get())
395 return;
396
397 pPattern->RemoveRef();
398 if (pPattern->use_count() > 1)
399 return;
400
401 // We have item only in m_PatternMap cache. Clean it.
402 pPattern->clear();
403 }
404
405 CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream) {
406 if (!pImageStream)
407 return nullptr;
408
409 const uint32_t dwImageObjNum = pImageStream->GetObjNum();
410 auto it = m_ImageMap.find(dwImageObjNum);
411 if (it != m_ImageMap.end())
412 return it->second->AddRef();
413
414 CPDF_CountedImage* pCountedImage = new CPDF_CountedImage(
415 new CPDF_Image(m_pPDFDoc, pImageStream->AsStream(), false));
416 m_ImageMap[dwImageObjNum] = pCountedImage;
417 return pCountedImage->AddRef();
418 }
419
420 void CPDF_DocPageData::ReleaseImage(const CPDF_Object* pImageStream) {
421 if (!pImageStream)
422 return;
423
424 uint32_t dwObjNum = pImageStream->GetObjNum();
425 if (!dwObjNum)
426 return;
427
428 auto it = m_ImageMap.find(dwObjNum);
429 if (it == m_ImageMap.end())
430 return;
431
432 CPDF_CountedImage* pCountedImage = it->second;
433 if (!pCountedImage)
434 return;
435
436 pCountedImage->RemoveRef();
437 if (pCountedImage->use_count() > 1)
438 return;
439
440 // We have item only in m_ImageMap cache. Clean it.
441 delete pCountedImage->get();
442 delete pCountedImage;
443 m_ImageMap.erase(it);
444 }
445
446 CPDF_IccProfile* CPDF_DocPageData::GetIccProfile(
447 CPDF_Stream* pIccProfileStream) {
448 if (!pIccProfileStream)
449 return nullptr;
450
451 auto it = m_IccProfileMap.find(pIccProfileStream);
452 if (it != m_IccProfileMap.end())
453 return it->second->AddRef();
454
455 CPDF_StreamAcc stream;
456 stream.LoadAllData(pIccProfileStream, FALSE);
457 uint8_t digest[20];
458 CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest);
459 CFX_ByteString bsDigest(digest, 20);
460 auto hash_it = m_HashProfileMap.find(bsDigest);
461 if (hash_it != m_HashProfileMap.end()) {
462 auto it_copied_stream = m_IccProfileMap.find(hash_it->second);
463 if (it_copied_stream != m_IccProfileMap.end())
464 return it_copied_stream->second->AddRef();
465 }
466 CPDF_IccProfile* pProfile =
467 new CPDF_IccProfile(stream.GetData(), stream.GetSize());
468 CPDF_CountedIccProfile* ipData = new CPDF_CountedIccProfile(pProfile);
469 m_IccProfileMap[pIccProfileStream] = ipData;
470 m_HashProfileMap[bsDigest] = pIccProfileStream;
471 return ipData->AddRef();
472 }
473
474 void CPDF_DocPageData::ReleaseIccProfile(const CPDF_IccProfile* pIccProfile) {
475 ASSERT(pIccProfile);
476
477 for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end(); ++it) {
478 CPDF_CountedIccProfile* profile = it->second;
479 if (profile->get() != pIccProfile)
480 continue;
481
482 profile->RemoveRef();
483 if (profile->use_count() > 1)
484 continue;
485 // We have item only in m_IccProfileMap cache. Clean it.
486 delete profile->get();
487 delete profile;
488 m_IccProfileMap.erase(it);
489 return;
490 }
491 }
492
493 CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc(
494 CPDF_Stream* pFontStream) {
495 ASSERT(pFontStream);
496
497 auto it = m_FontFileMap.find(pFontStream);
498 if (it != m_FontFileMap.end())
499 return it->second->AddRef();
500
501 CPDF_Dictionary* pFontDict = pFontStream->GetDict();
502 int32_t org_size = pFontDict->GetIntegerFor("Length1") +
503 pFontDict->GetIntegerFor("Length2") +
504 pFontDict->GetIntegerFor("Length3");
505 org_size = std::max(org_size, 0);
506
507 CPDF_StreamAcc* pFontFile = new CPDF_StreamAcc;
508 pFontFile->LoadAllData(pFontStream, FALSE, org_size);
509
510 CPDF_CountedStreamAcc* pCountedFont = new CPDF_CountedStreamAcc(pFontFile);
511 m_FontFileMap[pFontStream] = pCountedFont;
512 return pCountedFont->AddRef();
513 }
514
515 void CPDF_DocPageData::ReleaseFontFileStreamAcc(
516 const CPDF_Stream* pFontStream) {
517 if (!pFontStream)
518 return;
519
520 auto it = m_FontFileMap.find(pFontStream);
521 if (it == m_FontFileMap.end())
522 return;
523
524 CPDF_CountedStreamAcc* pCountedStream = it->second;
525 if (!pCountedStream)
526 return;
527
528 pCountedStream->RemoveRef();
529 if (pCountedStream->use_count() > 1)
530 return;
531
532 // We have item only in m_FontFileMap cache. Clean it.
533 delete pCountedStream->get();
534 delete pCountedStream;
535 m_FontFileMap.erase(it);
536 }
537
538 CPDF_CountedColorSpace* CPDF_DocPageData::FindColorSpacePtr(
539 CPDF_Object* pCSObj) const {
540 if (!pCSObj)
541 return nullptr;
542
543 auto it = m_ColorSpaceMap.find(pCSObj);
544 return it != m_ColorSpaceMap.end() ? it->second : nullptr;
545 }
546
547 CPDF_CountedPattern* CPDF_DocPageData::FindPatternPtr(
548 CPDF_Object* pPatternObj) const {
549 if (!pPatternObj)
550 return nullptr;
551
552 auto it = m_PatternMap.find(pPatternObj);
553 return it != m_PatternMap.end() ? it->second : nullptr;
554 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_page/fpdf_page_colors.cpp ('k') | core/fpdfapi/fpdf_page/fpdf_page_func.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698