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

Side by Side Diff: fpdfsdk/fpdf_flatten.cpp

Issue 2510223002: Make CPDF_Dictionary use unique pointers. (Closed)
Patch Set: rebase Created 4 years, 1 month 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 | « fpdfsdk/formfiller/cba_fontmap.cpp ('k') | fpdfsdk/fpdf_transformpage.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "public/fpdf_flatten.h" 7 #include "public/fpdf_flatten.h"
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory>
11 #include <utility>
12 #include <vector>
10 13
11 #include "core/fpdfapi/page/cpdf_page.h" 14 #include "core/fpdfapi/page/cpdf_page.h"
12 #include "core/fpdfapi/page/cpdf_pageobject.h" 15 #include "core/fpdfapi/page/cpdf_pageobject.h"
13 #include "core/fpdfapi/parser/cpdf_array.h" 16 #include "core/fpdfapi/parser/cpdf_array.h"
14 #include "core/fpdfapi/parser/cpdf_document.h" 17 #include "core/fpdfapi/parser/cpdf_document.h"
18 #include "core/fpdfapi/parser/cpdf_name.h"
15 #include "core/fpdfapi/parser/cpdf_number.h" 19 #include "core/fpdfapi/parser/cpdf_number.h"
16 #include "core/fpdfapi/parser/cpdf_reference.h" 20 #include "core/fpdfapi/parser/cpdf_reference.h"
17 #include "core/fpdfapi/parser/cpdf_stream.h" 21 #include "core/fpdfapi/parser/cpdf_stream.h"
18 #include "core/fpdfapi/parser/cpdf_stream_acc.h" 22 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
19 #include "core/fpdfdoc/cpdf_annot.h" 23 #include "core/fpdfdoc/cpdf_annot.h"
20 #include "fpdfsdk/fsdk_define.h" 24 #include "fpdfsdk/fsdk_define.h"
21 #include "third_party/base/stl_util.h" 25 #include "third_party/base/stl_util.h"
22 26
23 enum FPDF_TYPE { MAX, MIN }; 27 enum FPDF_TYPE { MAX, MIN };
24 enum FPDF_VALUE { TOP, LEFT, RIGHT, BOTTOM }; 28 enum FPDF_VALUE { TOP, LEFT, RIGHT, BOTTOM };
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 187
184 void SetPageContents(const CFX_ByteString& key, 188 void SetPageContents(const CFX_ByteString& key,
185 CPDF_Dictionary* pPage, 189 CPDF_Dictionary* pPage,
186 CPDF_Document* pDocument) { 190 CPDF_Document* pDocument) {
187 CPDF_Array* pContentsArray = nullptr; 191 CPDF_Array* pContentsArray = nullptr;
188 CPDF_Stream* pContentsStream = pPage->GetStreamFor("Contents"); 192 CPDF_Stream* pContentsStream = pPage->GetStreamFor("Contents");
189 if (!pContentsStream) { 193 if (!pContentsStream) {
190 pContentsArray = pPage->GetArrayFor("Contents"); 194 pContentsArray = pPage->GetArrayFor("Contents");
191 if (!pContentsArray) { 195 if (!pContentsArray) {
192 if (!key.IsEmpty()) { 196 if (!key.IsEmpty()) {
193 pPage->SetReferenceFor("Contents", pDocument, 197 pPage->SetNewFor<CPDF_Reference>(
194 NewIndirectContentsStream(key, pDocument)); 198 "Contents", pDocument, NewIndirectContentsStream(key, pDocument));
195 } 199 }
196 return; 200 return;
197 } 201 }
198 } 202 }
199 pPage->ConvertToIndirectObjectFor("Contents", pDocument); 203 pPage->ConvertToIndirectObjectFor("Contents", pDocument);
200 if (!pContentsArray) { 204 if (!pContentsArray) {
201 pContentsArray = pDocument->NewIndirect<CPDF_Array>(); 205 pContentsArray = pDocument->NewIndirect<CPDF_Array>();
202 CPDF_StreamAcc acc; 206 CPDF_StreamAcc acc;
203 acc.LoadAllData(pContentsStream); 207 acc.LoadAllData(pContentsStream);
204 CFX_ByteString sStream = "q\n"; 208 CFX_ByteString sStream = "q\n";
205 CFX_ByteString sBody = 209 CFX_ByteString sBody =
206 CFX_ByteString((const FX_CHAR*)acc.GetData(), acc.GetSize()); 210 CFX_ByteString((const FX_CHAR*)acc.GetData(), acc.GetSize());
207 sStream = sStream + sBody + "\nQ"; 211 sStream = sStream + sBody + "\nQ";
208 pContentsStream->SetData(sStream.raw_str(), sStream.GetLength()); 212 pContentsStream->SetData(sStream.raw_str(), sStream.GetLength());
209 pContentsArray->AddNew<CPDF_Reference>(pDocument, 213 pContentsArray->AddNew<CPDF_Reference>(pDocument,
210 pContentsStream->GetObjNum()); 214 pContentsStream->GetObjNum());
211 pPage->SetReferenceFor("Contents", pDocument, pContentsArray); 215 pPage->SetNewFor<CPDF_Reference>("Contents", pDocument,
216 pContentsArray->GetObjNum());
212 } 217 }
213 if (!key.IsEmpty()) { 218 if (!key.IsEmpty()) {
214 pContentsArray->AddNew<CPDF_Reference>( 219 pContentsArray->AddNew<CPDF_Reference>(
215 pDocument, NewIndirectContentsStream(key, pDocument)); 220 pDocument, NewIndirectContentsStream(key, pDocument));
216 } 221 }
217 } 222 }
218 223
219 CFX_Matrix GetMatrix(CFX_FloatRect rcAnnot, 224 CFX_Matrix GetMatrix(CFX_FloatRect rcAnnot,
220 CFX_FloatRect rcStream, 225 CFX_FloatRect rcStream,
221 const CFX_Matrix& matrix) { 226 const CFX_Matrix& matrix) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 rcMerger.left = std::max(rcMerger.left, rcOriginalMB.left); 269 rcMerger.left = std::max(rcMerger.left, rcOriginalMB.left);
265 rcMerger.right = std::min(rcMerger.right, rcOriginalMB.right); 270 rcMerger.right = std::min(rcMerger.right, rcOriginalMB.right);
266 rcMerger.bottom = std::max(rcMerger.bottom, rcOriginalMB.bottom); 271 rcMerger.bottom = std::max(rcMerger.bottom, rcOriginalMB.bottom);
267 rcMerger.top = std::min(rcMerger.top, rcOriginalMB.top); 272 rcMerger.top = std::min(rcMerger.top, rcOriginalMB.top);
268 if (pPageDict->KeyExist("ArtBox")) 273 if (pPageDict->KeyExist("ArtBox"))
269 rcOriginalCB = pPageDict->GetRectFor("ArtBox"); 274 rcOriginalCB = pPageDict->GetRectFor("ArtBox");
270 else 275 else
271 rcOriginalCB = rcOriginalMB; 276 rcOriginalCB = rcOriginalMB;
272 277
273 if (!rcOriginalMB.IsEmpty()) { 278 if (!rcOriginalMB.IsEmpty()) {
274 CPDF_Array* pMediaBox = new CPDF_Array(); 279 CPDF_Array* pMediaBox = pPageDict->SetNewFor<CPDF_Array>("MediaBox");
275 pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.left); 280 pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.left);
276 pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.bottom); 281 pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.bottom);
277 pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.right); 282 pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.right);
278 pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.top); 283 pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.top);
279 pPageDict->SetFor("MediaBox", pMediaBox);
280 } 284 }
281 285
282 if (!rcOriginalCB.IsEmpty()) { 286 if (!rcOriginalCB.IsEmpty()) {
283 CPDF_Array* pCropBox = new CPDF_Array(); 287 CPDF_Array* pCropBox = pPageDict->SetNewFor<CPDF_Array>("ArtBox");
284 pCropBox->AddNew<CPDF_Number>(rcOriginalCB.left); 288 pCropBox->AddNew<CPDF_Number>(rcOriginalCB.left);
285 pCropBox->AddNew<CPDF_Number>(rcOriginalCB.bottom); 289 pCropBox->AddNew<CPDF_Number>(rcOriginalCB.bottom);
286 pCropBox->AddNew<CPDF_Number>(rcOriginalCB.right); 290 pCropBox->AddNew<CPDF_Number>(rcOriginalCB.right);
287 pCropBox->AddNew<CPDF_Number>(rcOriginalCB.top); 291 pCropBox->AddNew<CPDF_Number>(rcOriginalCB.top);
288 pPageDict->SetFor("ArtBox", pCropBox);
289 } 292 }
290 293
291 CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources"); 294 CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources");
292 if (!pRes) { 295 if (!pRes)
293 pRes = new CPDF_Dictionary(pDocument->GetByteStringPool()); 296 pRes = pPageDict->SetNewFor<CPDF_Dictionary>("Resources");
294 pPageDict->SetFor("Resources", pRes);
295 }
296 297
297 CPDF_Stream* pNewXObject = pDocument->NewIndirect<CPDF_Stream>( 298 CPDF_Stream* pNewXObject = pDocument->NewIndirect<CPDF_Stream>(
298 nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); 299 nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool()));
299 300
300 uint32_t dwObjNum = pNewXObject->GetObjNum(); 301 uint32_t dwObjNum = pNewXObject->GetObjNum();
301 CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject"); 302 CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject");
302 if (!pPageXObject) { 303 if (!pPageXObject)
303 pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); 304 pPageXObject = pRes->SetNewFor<CPDF_Dictionary>("XObject");
304 pRes->SetFor("XObject", pPageXObject);
305 }
306 305
307 CFX_ByteString key = ""; 306 CFX_ByteString key = "";
308 int nStreams = pdfium::CollectionSize<int>(ObjectArray); 307 int nStreams = pdfium::CollectionSize<int>(ObjectArray);
309 if (nStreams > 0) { 308 if (nStreams > 0) {
310 for (int iKey = 0; /*iKey < 100*/; iKey++) { 309 for (int iKey = 0; /*iKey < 100*/; iKey++) {
311 char sExtend[5] = {}; 310 char sExtend[5] = {};
312 FXSYS_itoa(iKey, sExtend, 10); 311 FXSYS_itoa(iKey, sExtend, 10);
313 key = CFX_ByteString("FFT") + CFX_ByteString(sExtend); 312 key = CFX_ByteString("FFT") + CFX_ByteString(sExtend);
314 if (!pPageXObject->KeyExist(key)) 313 if (!pPageXObject->KeyExist(key))
315 break; 314 break;
316 } 315 }
317 } 316 }
318 317
319 SetPageContents(key, pPageDict, pDocument); 318 SetPageContents(key, pPageDict, pDocument);
320 319
321 CPDF_Dictionary* pNewXORes = nullptr; 320 CPDF_Dictionary* pNewXORes = nullptr;
322 if (!key.IsEmpty()) { 321 if (!key.IsEmpty()) {
323 pPageXObject->SetReferenceFor(key, pDocument, dwObjNum); 322 pPageXObject->SetNewFor<CPDF_Reference>(key, pDocument, dwObjNum);
324 CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict(); 323 CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict();
325 pNewXORes = new CPDF_Dictionary(pDocument->GetByteStringPool()); 324 pNewXORes = pNewOXbjectDic->SetNewFor<CPDF_Dictionary>("Resources");
326 pNewOXbjectDic->SetFor("Resources", pNewXORes); 325 pNewOXbjectDic->SetNewFor<CPDF_Name>("Type", "XObject");
327 pNewOXbjectDic->SetNameFor("Type", "XObject"); 326 pNewOXbjectDic->SetNewFor<CPDF_Name>("Subtype", "Form");
328 pNewOXbjectDic->SetNameFor("Subtype", "Form"); 327 pNewOXbjectDic->SetNewFor<CPDF_Number>("FormType", 1);
329 pNewOXbjectDic->SetIntegerFor("FormType", 1); 328 pNewOXbjectDic->SetNewFor<CPDF_Name>("Name", "FRM");
330 pNewOXbjectDic->SetNameFor("Name", "FRM");
331 CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox"); 329 CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox");
332 pNewOXbjectDic->SetRectFor("BBox", rcBBox); 330 pNewOXbjectDic->SetRectFor("BBox", rcBBox);
333 } 331 }
334 332
335 for (int i = 0; i < nStreams; i++) { 333 for (int i = 0; i < nStreams; i++) {
336 CPDF_Dictionary* pAnnotDic = ObjectArray[i]; 334 CPDF_Dictionary* pAnnotDic = ObjectArray[i];
337 if (!pAnnotDic) 335 if (!pAnnotDic)
338 continue; 336 continue;
339 337
340 CFX_FloatRect rcAnnot = pAnnotDic->GetRectFor("Rect"); 338 CFX_FloatRect rcAnnot = pAnnotDic->GetRectFor("Rect");
341 rcAnnot.Normalize(); 339 rcAnnot.Normalize();
342 340
343 CFX_ByteString sAnnotState = pAnnotDic->GetStringFor("AS"); 341 CFX_ByteString sAnnotState = pAnnotDic->GetStringFor("AS");
344 CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDictFor("AP"); 342 CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDictFor("AP");
345 if (!pAnnotAP) 343 if (!pAnnotAP)
346 continue; 344 continue;
347 345
348 CPDF_Stream* pAPStream = pAnnotAP->GetStreamFor("N"); 346 CPDF_Stream* pAPStream = pAnnotAP->GetStreamFor("N");
349 if (!pAPStream) { 347 if (!pAPStream) {
350 CPDF_Dictionary* pAPDic = pAnnotAP->GetDictFor("N"); 348 CPDF_Dictionary* pAPDic = pAnnotAP->GetDictFor("N");
351 if (!pAPDic) 349 if (!pAPDic)
352 continue; 350 continue;
353 351
354 if (!sAnnotState.IsEmpty()) { 352 if (!sAnnotState.IsEmpty()) {
355 pAPStream = pAPDic->GetStreamFor(sAnnotState); 353 pAPStream = pAPDic->GetStreamFor(sAnnotState);
356 } else { 354 } else {
357 auto it = pAPDic->begin(); 355 auto it = pAPDic->begin();
358 if (it != pAPDic->end()) { 356 if (it != pAPDic->end()) {
359 CPDF_Object* pFirstObj = it->second; 357 CPDF_Object* pFirstObj = it->second.get();
360 if (pFirstObj) { 358 if (pFirstObj) {
361 if (pFirstObj->IsReference()) 359 if (pFirstObj->IsReference())
362 pFirstObj = pFirstObj->GetDirect(); 360 pFirstObj = pFirstObj->GetDirect();
363 if (!pFirstObj->IsStream()) 361 if (!pFirstObj->IsStream())
364 continue; 362 continue;
365 pAPStream = pFirstObj->AsStream(); 363 pAPStream = pFirstObj->AsStream();
366 } 364 }
367 } 365 }
368 } 366 }
369 } 367 }
(...skipping 12 matching lines...) Expand all
382 380
383 CPDF_Object* pObj = pAPStream; 381 CPDF_Object* pObj = pAPStream;
384 if (pObj->IsInline()) { 382 if (pObj->IsInline()) {
385 std::unique_ptr<CPDF_Object> pNew = pObj->Clone(); 383 std::unique_ptr<CPDF_Object> pNew = pObj->Clone();
386 pObj = pNew.get(); 384 pObj = pNew.get();
387 pDocument->AddIndirectObject(std::move(pNew)); 385 pDocument->AddIndirectObject(std::move(pNew));
388 } 386 }
389 387
390 CPDF_Dictionary* pObjDic = pObj->GetDict(); 388 CPDF_Dictionary* pObjDic = pObj->GetDict();
391 if (pObjDic) { 389 if (pObjDic) {
392 pObjDic->SetNameFor("Type", "XObject"); 390 pObjDic->SetNewFor<CPDF_Name>("Type", "XObject");
393 pObjDic->SetNameFor("Subtype", "Form"); 391 pObjDic->SetNewFor<CPDF_Name>("Subtype", "Form");
394 } 392 }
395 393
396 CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject"); 394 CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject");
397 if (!pXObject) { 395 if (!pXObject)
398 pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); 396 pXObject = pNewXORes->SetNewFor<CPDF_Dictionary>("XObject");
399 pNewXORes->SetFor("XObject", pXObject);
400 }
401 397
402 CFX_ByteString sFormName; 398 CFX_ByteString sFormName;
403 sFormName.Format("F%d", i); 399 sFormName.Format("F%d", i);
404 pXObject->SetReferenceFor(sFormName, pDocument, pObj->GetObjNum()); 400 pXObject->SetNewFor<CPDF_Reference>(sFormName, pDocument,
401 pObj->GetObjNum());
405 402
406 CPDF_StreamAcc acc; 403 CPDF_StreamAcc acc;
407 acc.LoadAllData(pNewXObject); 404 acc.LoadAllData(pNewXObject);
408 405
409 const uint8_t* pData = acc.GetData(); 406 const uint8_t* pData = acc.GetData();
410 CFX_ByteString sStream(pData, acc.GetSize()); 407 CFX_ByteString sStream(pData, acc.GetSize());
411 CFX_Matrix matrix = pAPDic->GetMatrixFor("Matrix"); 408 CFX_Matrix matrix = pAPDic->GetMatrixFor("Matrix");
412 if (matrix.IsIdentity()) { 409 if (matrix.IsIdentity()) {
413 matrix.a = 1.0f; 410 matrix.a = 1.0f;
414 matrix.b = 0.0f; 411 matrix.b = 0.0f;
415 matrix.c = 0.0f; 412 matrix.c = 0.0f;
416 matrix.d = 1.0f; 413 matrix.d = 1.0f;
417 matrix.e = 0.0f; 414 matrix.e = 0.0f;
418 matrix.f = 0.0f; 415 matrix.f = 0.0f;
419 } 416 }
420 417
421 CFX_ByteString sTemp; 418 CFX_ByteString sTemp;
422 CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix); 419 CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix);
423 sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, 420 sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f,
424 sFormName.c_str()); 421 sFormName.c_str());
425 sStream += sTemp; 422 sStream += sTemp;
426 pNewXObject->SetData(sStream.raw_str(), sStream.GetLength()); 423 pNewXObject->SetData(sStream.raw_str(), sStream.GetLength());
427 } 424 }
428 pPageDict->RemoveFor("Annots"); 425 pPageDict->RemoveFor("Annots");
429 return FLATTEN_SUCCESS; 426 return FLATTEN_SUCCESS;
430 } 427 }
OLDNEW
« no previous file with comments | « fpdfsdk/formfiller/cba_fontmap.cpp ('k') | fpdfsdk/fpdf_transformpage.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698