blob: 93df594618d560971382198911c04989eb218f4a [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangb4e7f302015-11-06 15:52:32 -08007#include "public/fpdf_transformpage.h"
8
Tom Sepezfe91c6c2017-05-16 15:33:20 -07009#include <memory>
Henrique Nakashima8e052a62017-06-27 17:14:31 -040010#include <sstream>
Dan Sinclaire4602322017-02-15 11:07:32 -050011#include <vector>
12
dsinclair41872fa2016-10-04 11:29:35 -070013#include "core/fpdfapi/page/cpdf_clippath.h"
14#include "core/fpdfapi/page/cpdf_page.h"
15#include "core/fpdfapi/page/cpdf_pageobject.h"
16#include "core/fpdfapi/page/cpdf_path.h"
dsinclair488b7ad2016-10-04 11:55:50 -070017#include "core/fpdfapi/parser/cpdf_array.h"
18#include "core/fpdfapi/parser/cpdf_document.h"
19#include "core/fpdfapi/parser/cpdf_number.h"
20#include "core/fpdfapi/parser/cpdf_reference.h"
21#include "core/fpdfapi/parser/cpdf_stream.h"
dsinclair74a34fc2016-09-29 16:41:42 -070022#include "core/fxge/cfx_pathdata.h"
dsinclair114e46a2016-09-29 17:18:21 -070023#include "fpdfsdk/fsdk_define.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070025namespace {
26
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070027void SetBoundingBox(CPDF_Page* page,
tsepez71a452f2016-05-13 17:51:27 -070028 const CFX_ByteString& key,
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070029 float left,
30 float bottom,
31 float right,
32 float top) {
tsepez0e606b52016-11-18 16:22:41 -080033 CPDF_Array* pBoundingBoxArray = page->m_pFormDict->SetNewFor<CPDF_Array>(key);
tsepez8a3aa452016-11-16 12:26:06 -080034 pBoundingBoxArray->AddNew<CPDF_Number>(left);
35 pBoundingBoxArray->AddNew<CPDF_Number>(bottom);
36 pBoundingBoxArray->AddNew<CPDF_Number>(right);
37 pBoundingBoxArray->AddNew<CPDF_Number>(top);
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070038}
39
tsepez71a452f2016-05-13 17:51:27 -070040bool GetBoundingBox(CPDF_Page* page,
41 const CFX_ByteString& key,
42 float* left,
43 float* bottom,
44 float* right,
45 float* top) {
dsinclair38fd8442016-09-15 10:15:32 -070046 CPDF_Array* pArray = page->m_pFormDict->GetArrayFor(key);
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070047 if (!pArray)
tsepez71a452f2016-05-13 17:51:27 -070048 return false;
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070049
Wei Li9b761132016-01-29 15:44:20 -080050 *left = pArray->GetFloatAt(0);
51 *bottom = pArray->GetFloatAt(1);
52 *right = pArray->GetFloatAt(2);
53 *top = pArray->GetFloatAt(3);
tsepez71a452f2016-05-13 17:51:27 -070054 return true;
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070055}
56
57} // namespace
58
Dan Sinclair00d2ad12017-08-10 14:13:02 -040059FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetMediaBox(FPDF_PAGE page,
60 float left,
61 float bottom,
62 float right,
63 float top) {
Tom Sepezdb0be962015-10-16 14:00:21 -070064 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065 if (!pPage)
66 return;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070067
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070068 SetBoundingBox(pPage, "MediaBox", left, bottom, right, top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069}
70
Dan Sinclair00d2ad12017-08-10 14:13:02 -040071FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetCropBox(FPDF_PAGE page,
72 float left,
73 float bottom,
74 float right,
75 float top) {
Tom Sepezdb0be962015-10-16 14:00:21 -070076 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070077 if (!pPage)
78 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070079
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070080 SetBoundingBox(pPage, "CropBox", left, bottom, right, top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070081}
82
Dan Sinclair00d2ad12017-08-10 14:13:02 -040083FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GetMediaBox(FPDF_PAGE page,
84 float* left,
85 float* bottom,
86 float* right,
87 float* top) {
Tom Sepezdb0be962015-10-16 14:00:21 -070088 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070089 return pPage && GetBoundingBox(pPage, "MediaBox", left, bottom, right, top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070090}
91
Dan Sinclair00d2ad12017-08-10 14:13:02 -040092FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GetCropBox(FPDF_PAGE page,
93 float* left,
94 float* bottom,
95 float* right,
96 float* top) {
Tom Sepezdb0be962015-10-16 14:00:21 -070097 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070098 return pPage && GetBoundingBox(pPage, "CropBox", left, bottom, right, top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070099}
100
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400101FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
102FPDFPage_TransFormWithClip(FPDF_PAGE page,
103 FS_MATRIX* matrix,
104 FS_RECTF* clipRect) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700105 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106 if (!pPage)
tsepez4cf55152016-11-02 14:37:54 -0700107 return false;
Bo Xufdc00a72014-10-28 23:03:33 -0700108
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400109 std::ostringstream textBuf;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110 textBuf << "q ";
111 CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right,
112 clipRect->top);
113 rect.Normalize();
114 CFX_ByteString bsClipping;
115 bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom,
116 rect.Width(), rect.Height());
117 textBuf << bsClipping;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700118
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 CFX_ByteString bsMatix;
120 bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c,
121 matrix->d, matrix->e, matrix->f);
122 textBuf << bsMatix;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700123
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700124 CPDF_Dictionary* pPageDic = pPage->m_pFormDict.Get();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400125 CPDF_Object* pContentObj =
dsinclair38fd8442016-09-15 10:15:32 -0700126 pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 if (!pContentObj)
dsinclair38fd8442016-09-15 10:15:32 -0700128 pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129 if (!pContentObj)
tsepez4cf55152016-11-02 14:37:54 -0700130 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700131
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700132 CPDF_Document* pDoc = pPage->m_pDocument.Get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133 if (!pDoc)
tsepez4cf55152016-11-02 14:37:54 -0700134 return false;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700135
tsepez9e05ee12016-11-21 13:19:10 -0800136 CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
137 nullptr, 0,
138 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400139 pStream->SetData(&textBuf);
tsepez70c4afd2016-11-15 11:33:44 -0800140
tsepez9e05ee12016-11-21 13:19:10 -0800141 CPDF_Stream* pEndStream = pDoc->NewIndirect<CPDF_Stream>(
142 nullptr, 0,
143 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
tsepeze6db16e2016-09-19 10:45:09 -0700144 pEndStream->SetData((const uint8_t*)" Q", 2);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700145
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400146 CPDF_Array* pContentArray = nullptr;
weilidb444d22016-06-02 15:48:15 -0700147 CPDF_Array* pArray = ToArray(pContentObj);
148 if (pArray) {
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400149 pContentArray = pArray;
tsepez8a3aa452016-11-16 12:26:06 -0800150 pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
151 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
Dan Sinclairbf81c142015-10-26 16:54:39 -0400152 } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 CPDF_Object* pDirectObj = pReference->GetDirect();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400154 if (pDirectObj) {
weilidb444d22016-06-02 15:48:15 -0700155 CPDF_Array* pObjArray = pDirectObj->AsArray();
156 if (pObjArray) {
157 pContentArray = pObjArray;
tsepez8a3aa452016-11-16 12:26:06 -0800158 pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc,
159 pStream->GetObjNum());
160 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400161 } else if (pDirectObj->IsStream()) {
tsepez70c4afd2016-11-15 11:33:44 -0800162 pContentArray = pDoc->NewIndirect<CPDF_Array>();
tsepez8a3aa452016-11-16 12:26:06 -0800163 pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
164 pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
165 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
tsepez0e606b52016-11-18 16:22:41 -0800166 pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
167 pContentArray->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 }
169 }
170 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700171
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 // Need to transform the patterns as well.
dsinclair38fd8442016-09-15 10:15:32 -0700173 CPDF_Dictionary* pRes = pPageDic->GetDictFor("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174 if (pRes) {
dsinclair38fd8442016-09-15 10:15:32 -0700175 CPDF_Dictionary* pPattenDict = pRes->GetDictFor("Pattern");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 if (pPattenDict) {
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800177 for (const auto& it : *pPattenDict) {
tsepez0e606b52016-11-18 16:22:41 -0800178 CPDF_Object* pObj = it.second.get();
Dan Sinclairbf81c142015-10-26 16:54:39 -0400179 if (pObj->IsReference())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 pObj = pObj->GetDirect();
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400181
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800182 CPDF_Dictionary* pDict = nullptr;
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400183 if (pObj->IsDictionary())
Dan Sinclairf1251c12015-10-20 16:24:45 -0400184 pDict = pObj->AsDictionary();
weilidb444d22016-06-02 15:48:15 -0700185 else if (CPDF_Stream* pObjStream = pObj->AsStream())
186 pDict = pObjStream->GetDict();
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400187 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 continue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700189
dsinclair38fd8442016-09-15 10:15:32 -0700190 CFX_Matrix m = pDict->GetMatrixFor("Matrix");
Tom Sepez60d909e2015-12-10 15:34:55 -0800191 CFX_Matrix t = *(CFX_Matrix*)matrix;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192 m.Concat(t);
dsinclair38fd8442016-09-15 10:15:32 -0700193 pDict->SetMatrixFor("Matrix", m);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194 }
195 }
196 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700197
tsepez4cf55152016-11-02 14:37:54 -0700198 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700199}
200
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400201FPDF_EXPORT void FPDF_CALLCONV
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202FPDFPageObj_TransformClipPath(FPDF_PAGEOBJECT page_object,
203 double a,
204 double b,
205 double c,
206 double d,
207 double e,
208 double f) {
209 CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
Lei Zhang412e9082015-12-14 18:34:00 -0800210 if (!pPageObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211 return;
Dan Sinclair05df0752017-03-14 14:43:42 -0400212 CFX_Matrix matrix((float)a, (float)b, (float)c, (float)d, (float)e, (float)f);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700213
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214 // Special treatment to shading object, because the ClipPath for shading
215 // object is already transformed.
Wei Li7cf13c92016-02-19 11:53:03 -0800216 if (!pPageObj->IsShading())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217 pPageObj->TransformClipPath(matrix);
218 pPageObj->TransformGeneralState(matrix);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700219}
220
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400221FPDF_EXPORT FPDF_CLIPPATH FPDF_CALLCONV FPDF_CreateClipPath(float left,
222 float bottom,
223 float right,
224 float top) {
tsepezfc1d16f2016-09-02 15:45:22 -0700225 CPDF_Path Path;
226 Path.AppendRect(left, bottom, right, top);
227
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700228 auto pNewClipPath = pdfium::MakeUnique<CPDF_ClipPath>();
tsepez4cf55152016-11-02 14:37:54 -0700229 pNewClipPath->AppendPath(Path, FXFILL_ALTERNATE, false);
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700230 return pNewClipPath.release(); // Caller takes ownership.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700231}
232
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400233FPDF_EXPORT void FPDF_CALLCONV FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath) {
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700234 // Take ownership back from caller and destroy.
235 std::unique_ptr<CPDF_ClipPath>(static_cast<CPDF_ClipPath*>(clipPath));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700236}
237
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400238void OutputPath(std::ostringstream& buf, CPDF_Path path) {
tsepez7d2a8d92016-06-08 11:51:23 -0700239 const CFX_PathData* pPathData = path.GetObject();
Lei Zhang412e9082015-12-14 18:34:00 -0800240 if (!pPathData)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 return;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700242
Dan Sinclaire4602322017-02-15 11:07:32 -0500243 const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
tsepez59601432016-08-29 14:26:57 -0700244 if (path.IsRect()) {
dan sinclairb147e072017-02-22 19:56:15 -0500245 CFX_PointF diff = pPoints[2].m_Point - pPoints[0].m_Point;
246 buf << pPoints[0].m_Point.x << " " << pPoints[0].m_Point.y << " " << diff.x
247 << " " << diff.y << " re\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700248 return;
249 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700250
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 CFX_ByteString temp;
Dan Sinclaire4602322017-02-15 11:07:32 -0500252 for (size_t i = 0; i < pPoints.size(); i++) {
dan sinclairb147e072017-02-22 19:56:15 -0500253 buf << pPoints[i].m_Point.x << " " << pPoints[i].m_Point.y;
Nicolas Pena79365f72017-02-07 14:21:36 -0500254 FXPT_TYPE point_type = pPoints[i].m_Type;
255 if (point_type == FXPT_TYPE::MoveTo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256 buf << " m\n";
Nicolas Pena79365f72017-02-07 14:21:36 -0500257 } else if (point_type == FXPT_TYPE::BezierTo) {
dan sinclairb147e072017-02-22 19:56:15 -0500258 buf << " " << pPoints[i + 1].m_Point.x << " " << pPoints[i + 1].m_Point.y
259 << " " << pPoints[i + 2].m_Point.x << " " << pPoints[i + 2].m_Point.y;
260 buf << " c";
Nicolas Pena79365f72017-02-07 14:21:36 -0500261 if (pPoints[i + 2].m_CloseFigure)
dan sinclairb147e072017-02-22 19:56:15 -0500262 buf << " h";
263 buf << "\n";
264
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700265 i += 2;
Nicolas Pena79365f72017-02-07 14:21:36 -0500266 } else if (point_type == FXPT_TYPE::LineTo) {
dan sinclairb147e072017-02-22 19:56:15 -0500267 buf << " l";
Nicolas Pena79365f72017-02-07 14:21:36 -0500268 if (pPoints[i].m_CloseFigure)
dan sinclairb147e072017-02-22 19:56:15 -0500269 buf << " h";
270 buf << "\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 }
272 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700273}
274
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400275FPDF_EXPORT void FPDF_CALLCONV FPDFPage_InsertClipPath(FPDF_PAGE page,
276 FPDF_CLIPPATH clipPath) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700277 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 if (!pPage)
279 return;
Lei Zhang6ac0d2f2015-10-02 10:08:48 -0700280
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700281 CPDF_Dictionary* pPageDic = pPage->m_pFormDict.Get();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400282 CPDF_Object* pContentObj =
dsinclair38fd8442016-09-15 10:15:32 -0700283 pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 if (!pContentObj)
dsinclair38fd8442016-09-15 10:15:32 -0700285 pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286 if (!pContentObj)
287 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700288
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400289 std::ostringstream strClip;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290 CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
tsepezc3255f52016-03-25 14:52:27 -0700291 uint32_t i;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700292 for (i = 0; i < pClipPath->GetPathCount(); i++) {
293 CPDF_Path path = pClipPath->GetPath(i);
294 int iClipType = pClipPath->GetClipType(i);
Dan Sinclaire4602322017-02-15 11:07:32 -0500295 if (path.GetPoints().empty()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 // Empty clipping (totally clipped out)
297 strClip << "0 0 m W n ";
298 } else {
299 OutputPath(strClip, path);
300 if (iClipType == FXFILL_WINDING)
301 strClip << "W n\n";
302 else
303 strClip << "W* n\n";
304 }
305 }
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700306 CPDF_Document* pDoc = pPage->m_pDocument.Get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700307 if (!pDoc)
308 return;
tsepezbb577af2016-09-21 19:10:19 -0700309
tsepez9e05ee12016-11-21 13:19:10 -0800310 CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
311 nullptr, 0,
312 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400313 pStream->SetData(&strClip);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700314
weilidb444d22016-06-02 15:48:15 -0700315 CPDF_Array* pArray = ToArray(pContentObj);
316 if (pArray) {
tsepez8a3aa452016-11-16 12:26:06 -0800317 pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
318 return;
319 }
320 CPDF_Reference* pReference = ToReference(pContentObj);
321 if (!pReference)
322 return;
323
324 CPDF_Object* pDirectObj = pReference->GetDirect();
325 if (!pDirectObj)
326 return;
327
328 CPDF_Array* pObjArray = pDirectObj->AsArray();
329 if (pObjArray) {
330 pObjArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
331 return;
332 }
333 if (pDirectObj->IsStream()) {
334 CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
335 pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
336 pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
tsepez0e606b52016-11-18 16:22:41 -0800337 pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
338 pContentArray->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700340}