| 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 "public/fpdf_flatten.h" | 7 #include "public/fpdf_flatten.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 rcRet.left = GetMinMaxValue(*pRectArray, MIN, LEFT); | 179 rcRet.left = GetMinMaxValue(*pRectArray, MIN, LEFT); |
| 180 rcRet.top = GetMinMaxValue(*pRectArray, MAX, TOP); | 180 rcRet.top = GetMinMaxValue(*pRectArray, MAX, TOP); |
| 181 rcRet.right = GetMinMaxValue(*pRectArray, MAX, RIGHT); | 181 rcRet.right = GetMinMaxValue(*pRectArray, MAX, RIGHT); |
| 182 rcRet.bottom = GetMinMaxValue(*pRectArray, MIN, BOTTOM); | 182 rcRet.bottom = GetMinMaxValue(*pRectArray, MIN, BOTTOM); |
| 183 | 183 |
| 184 return rcRet; | 184 return rcRet; |
| 185 } | 185 } |
| 186 | 186 |
| 187 uint32_t NewIndirectContentsStream(const CFX_ByteString& key, | 187 uint32_t NewIndirectContentsStream(const CFX_ByteString& key, |
| 188 CPDF_Document* pDocument) { | 188 CPDF_Document* pDocument) { |
| 189 CPDF_Stream* pNewContents = new CPDF_Stream( | 189 CPDF_Stream* pNewContents = pDocument->AddIndirectStream( |
| 190 nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); | 190 nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); |
| 191 CFX_ByteString sStream; | 191 CFX_ByteString sStream; |
| 192 sStream.Format("q 1 0 0 1 0 0 cm /%s Do Q", key.c_str()); | 192 sStream.Format("q 1 0 0 1 0 0 cm /%s Do Q", key.c_str()); |
| 193 pNewContents->SetData(sStream.raw_str(), sStream.GetLength()); | 193 pNewContents->SetData(sStream.raw_str(), sStream.GetLength()); |
| 194 return pDocument->AddIndirectObject(pNewContents); | 194 return pNewContents->GetObjNum(); |
| 195 } | 195 } |
| 196 | 196 |
| 197 void SetPageContents(const CFX_ByteString& key, | 197 void SetPageContents(const CFX_ByteString& key, |
| 198 CPDF_Dictionary* pPage, | 198 CPDF_Dictionary* pPage, |
| 199 CPDF_Document* pDocument) { | 199 CPDF_Document* pDocument) { |
| 200 CPDF_Array* pContentsArray = nullptr; | 200 CPDF_Array* pContentsArray = nullptr; |
| 201 CPDF_Stream* pContentsStream = pPage->GetStreamFor("Contents"); | 201 CPDF_Stream* pContentsStream = pPage->GetStreamFor("Contents"); |
| 202 if (!pContentsStream) { | 202 if (!pContentsStream) { |
| 203 pContentsArray = pPage->GetArrayFor("Contents"); | 203 pContentsArray = pPage->GetArrayFor("Contents"); |
| 204 if (!pContentsArray) { | 204 if (!pContentsArray) { |
| 205 if (!key.IsEmpty()) { | 205 if (!key.IsEmpty()) { |
| 206 pPage->SetReferenceFor("Contents", pDocument, | 206 pPage->SetReferenceFor("Contents", pDocument, |
| 207 NewIndirectContentsStream(key, pDocument)); | 207 NewIndirectContentsStream(key, pDocument)); |
| 208 } | 208 } |
| 209 return; | 209 return; |
| 210 } | 210 } |
| 211 } | 211 } |
| 212 pPage->ConvertToIndirectObjectFor("Contents", pDocument); | 212 pPage->ConvertToIndirectObjectFor("Contents", pDocument); |
| 213 if (!pContentsArray) { | 213 if (!pContentsArray) { |
| 214 pContentsArray = new CPDF_Array; | 214 pContentsArray = pDocument->AddIndirectArray(); |
| 215 CPDF_StreamAcc acc; | 215 CPDF_StreamAcc acc; |
| 216 acc.LoadAllData(pContentsStream); | 216 acc.LoadAllData(pContentsStream); |
| 217 CFX_ByteString sStream = "q\n"; | 217 CFX_ByteString sStream = "q\n"; |
| 218 CFX_ByteString sBody = | 218 CFX_ByteString sBody = CFX_ByteString(acc.GetData(), acc.GetSize()); |
| 219 CFX_ByteString((const FX_CHAR*)acc.GetData(), acc.GetSize()); | |
| 220 sStream = sStream + sBody + "\nQ"; | 219 sStream = sStream + sBody + "\nQ"; |
| 221 pContentsStream->SetData(sStream.raw_str(), sStream.GetLength()); | 220 pContentsStream->SetData(sStream.raw_str(), sStream.GetLength()); |
| 222 pContentsArray->AddReference(pDocument, pContentsStream->GetObjNum()); | 221 pContentsArray->AddReference(pDocument, pContentsStream->GetObjNum()); |
| 223 pPage->SetReferenceFor("Contents", pDocument, | 222 pPage->SetReferenceFor("Contents", pDocument, pContentsArray); |
| 224 pDocument->AddIndirectObject(pContentsArray)); | |
| 225 } | 223 } |
| 226 if (!key.IsEmpty()) { | 224 if (!key.IsEmpty()) { |
| 227 pContentsArray->AddReference(pDocument, | 225 pContentsArray->AddReference(pDocument, |
| 228 NewIndirectContentsStream(key, pDocument)); | 226 NewIndirectContentsStream(key, pDocument)); |
| 229 } | 227 } |
| 230 } | 228 } |
| 231 | 229 |
| 232 CFX_Matrix GetMatrix(CFX_FloatRect rcAnnot, | 230 CFX_Matrix GetMatrix(CFX_FloatRect rcAnnot, |
| 233 CFX_FloatRect rcStream, | 231 CFX_FloatRect rcStream, |
| 234 const CFX_Matrix& matrix) { | 232 const CFX_Matrix& matrix) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 pCropBox->Add(new CPDF_Number(rcOriginalCB.top)); | 309 pCropBox->Add(new CPDF_Number(rcOriginalCB.top)); |
| 312 pPageDict->SetFor("ArtBox", pCropBox); | 310 pPageDict->SetFor("ArtBox", pCropBox); |
| 313 } | 311 } |
| 314 | 312 |
| 315 CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources"); | 313 CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources"); |
| 316 if (!pRes) { | 314 if (!pRes) { |
| 317 pRes = new CPDF_Dictionary(pDocument->GetByteStringPool()); | 315 pRes = new CPDF_Dictionary(pDocument->GetByteStringPool()); |
| 318 pPageDict->SetFor("Resources", pRes); | 316 pPageDict->SetFor("Resources", pRes); |
| 319 } | 317 } |
| 320 | 318 |
| 321 CPDF_Stream* pNewXObject = new CPDF_Stream( | 319 CPDF_Stream* pNewXObject = pDocument->AddIndirectStream( |
| 322 nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); | 320 nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); |
| 323 | 321 |
| 324 uint32_t dwObjNum = pDocument->AddIndirectObject(pNewXObject); | 322 uint32_t dwObjNum = pNewXObject->GetObjNum(); |
| 325 CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject"); | 323 CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject"); |
| 326 if (!pPageXObject) { | 324 if (!pPageXObject) { |
| 327 pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); | 325 pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); |
| 328 pRes->SetFor("XObject", pPageXObject); | 326 pRes->SetFor("XObject", pPageXObject); |
| 329 } | 327 } |
| 330 | 328 |
| 331 CFX_ByteString key = ""; | 329 CFX_ByteString key = ""; |
| 332 int nStreams = pdfium::CollectionSize<int>(ObjectArray); | 330 int nStreams = pdfium::CollectionSize<int>(ObjectArray); |
| 333 | 331 |
| 334 if (nStreams > 0) { | 332 if (nStreams > 0) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 } | 417 } |
| 420 | 418 |
| 421 CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject"); | 419 CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject"); |
| 422 if (!pXObject) { | 420 if (!pXObject) { |
| 423 pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); | 421 pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); |
| 424 pNewXORes->SetFor("XObject", pXObject); | 422 pNewXORes->SetFor("XObject", pXObject); |
| 425 } | 423 } |
| 426 | 424 |
| 427 CFX_ByteString sFormName; | 425 CFX_ByteString sFormName; |
| 428 sFormName.Format("F%d", i); | 426 sFormName.Format("F%d", i); |
| 427 |
| 428 // TODO(tsepez): check |pObj| ownership. |
| 429 pXObject->SetReferenceFor(sFormName, pDocument, | 429 pXObject->SetReferenceFor(sFormName, pDocument, |
| 430 pDocument->AddIndirectObject(pObj)); | 430 pDocument->AddIndirectObject(UniqueObject(pObj))); |
| 431 | 431 |
| 432 CPDF_StreamAcc acc; | 432 CPDF_StreamAcc acc; |
| 433 acc.LoadAllData(pNewXObject); | 433 acc.LoadAllData(pNewXObject); |
| 434 | 434 |
| 435 const uint8_t* pData = acc.GetData(); | 435 const uint8_t* pData = acc.GetData(); |
| 436 CFX_ByteString sStream(pData, acc.GetSize()); | 436 CFX_ByteString sStream(pData, acc.GetSize()); |
| 437 | 437 |
| 438 if (matrix.IsIdentity()) { | 438 if (matrix.IsIdentity()) { |
| 439 matrix.a = 1.0f; | 439 matrix.a = 1.0f; |
| 440 matrix.b = 0.0f; | 440 matrix.b = 0.0f; |
| 441 matrix.c = 0.0f; | 441 matrix.c = 0.0f; |
| 442 matrix.d = 1.0f; | 442 matrix.d = 1.0f; |
| 443 matrix.e = 0.0f; | 443 matrix.e = 0.0f; |
| 444 matrix.f = 0.0f; | 444 matrix.f = 0.0f; |
| 445 } | 445 } |
| 446 | 446 |
| 447 CFX_ByteString sTemp; | 447 CFX_ByteString sTemp; |
| 448 CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix); | 448 CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix); |
| 449 sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, | 449 sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, |
| 450 sFormName.c_str()); | 450 sFormName.c_str()); |
| 451 sStream += sTemp; | 451 sStream += sTemp; |
| 452 pNewXObject->SetData(sStream.raw_str(), sStream.GetLength()); | 452 pNewXObject->SetData(sStream.raw_str(), sStream.GetLength()); |
| 453 } | 453 } |
| 454 pPageDict->RemoveFor("Annots"); | 454 pPageDict->RemoveFor("Annots"); |
| 455 | 455 |
| 456 RectArray.RemoveAll(); | 456 RectArray.RemoveAll(); |
| 457 return FLATTEN_SUCCESS; | 457 return FLATTEN_SUCCESS; |
| 458 } | 458 } |
| OLD | NEW |