blob: b419ad1fb292138f205f31153dd83344ad0b7d8d [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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070059DLLEXPORT void STDCALL 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071DLLEXPORT void STDCALL 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083DLLEXPORT FPDF_BOOL STDCALL 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092DLLEXPORT FPDF_BOOL STDCALL 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page,
102 FS_MATRIX* matrix,
103 FS_RECTF* clipRect) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700104 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105 if (!pPage)
tsepez4cf55152016-11-02 14:37:54 -0700106 return false;
Bo Xufdc00a72014-10-28 23:03:33 -0700107
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400108 std::ostringstream textBuf;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700109 textBuf << "q ";
110 CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right,
111 clipRect->top);
112 rect.Normalize();
113 CFX_ByteString bsClipping;
114 bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom,
115 rect.Width(), rect.Height());
116 textBuf << bsClipping;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700117
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700118 CFX_ByteString bsMatix;
119 bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c,
120 matrix->d, matrix->e, matrix->f);
121 textBuf << bsMatix;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700122
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700123 CPDF_Dictionary* pPageDic = pPage->m_pFormDict.Get();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400124 CPDF_Object* pContentObj =
dsinclair38fd8442016-09-15 10:15:32 -0700125 pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 if (!pContentObj)
dsinclair38fd8442016-09-15 10:15:32 -0700127 pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 if (!pContentObj)
tsepez4cf55152016-11-02 14:37:54 -0700129 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700130
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700131 CPDF_Document* pDoc = pPage->m_pDocument.Get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 if (!pDoc)
tsepez4cf55152016-11-02 14:37:54 -0700133 return false;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700134
tsepez9e05ee12016-11-21 13:19:10 -0800135 CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
136 nullptr, 0,
137 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400138 pStream->SetData(&textBuf);
tsepez70c4afd2016-11-15 11:33:44 -0800139
tsepez9e05ee12016-11-21 13:19:10 -0800140 CPDF_Stream* pEndStream = pDoc->NewIndirect<CPDF_Stream>(
141 nullptr, 0,
142 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
tsepeze6db16e2016-09-19 10:45:09 -0700143 pEndStream->SetData((const uint8_t*)" Q", 2);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700144
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400145 CPDF_Array* pContentArray = nullptr;
weilidb444d22016-06-02 15:48:15 -0700146 CPDF_Array* pArray = ToArray(pContentObj);
147 if (pArray) {
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400148 pContentArray = pArray;
tsepez8a3aa452016-11-16 12:26:06 -0800149 pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
150 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
Dan Sinclairbf81c142015-10-26 16:54:39 -0400151 } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 CPDF_Object* pDirectObj = pReference->GetDirect();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400153 if (pDirectObj) {
weilidb444d22016-06-02 15:48:15 -0700154 CPDF_Array* pObjArray = pDirectObj->AsArray();
155 if (pObjArray) {
156 pContentArray = pObjArray;
tsepez8a3aa452016-11-16 12:26:06 -0800157 pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc,
158 pStream->GetObjNum());
159 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400160 } else if (pDirectObj->IsStream()) {
tsepez70c4afd2016-11-15 11:33:44 -0800161 pContentArray = pDoc->NewIndirect<CPDF_Array>();
tsepez8a3aa452016-11-16 12:26:06 -0800162 pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
163 pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
164 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
tsepez0e606b52016-11-18 16:22:41 -0800165 pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
166 pContentArray->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 }
168 }
169 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700170
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 // Need to transform the patterns as well.
dsinclair38fd8442016-09-15 10:15:32 -0700172 CPDF_Dictionary* pRes = pPageDic->GetDictFor("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 if (pRes) {
dsinclair38fd8442016-09-15 10:15:32 -0700174 CPDF_Dictionary* pPattenDict = pRes->GetDictFor("Pattern");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 if (pPattenDict) {
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800176 for (const auto& it : *pPattenDict) {
tsepez0e606b52016-11-18 16:22:41 -0800177 CPDF_Object* pObj = it.second.get();
Dan Sinclairbf81c142015-10-26 16:54:39 -0400178 if (pObj->IsReference())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179 pObj = pObj->GetDirect();
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400180
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800181 CPDF_Dictionary* pDict = nullptr;
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400182 if (pObj->IsDictionary())
Dan Sinclairf1251c12015-10-20 16:24:45 -0400183 pDict = pObj->AsDictionary();
weilidb444d22016-06-02 15:48:15 -0700184 else if (CPDF_Stream* pObjStream = pObj->AsStream())
185 pDict = pObjStream->GetDict();
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400186 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187 continue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700188
dsinclair38fd8442016-09-15 10:15:32 -0700189 CFX_Matrix m = pDict->GetMatrixFor("Matrix");
Tom Sepez60d909e2015-12-10 15:34:55 -0800190 CFX_Matrix t = *(CFX_Matrix*)matrix;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 m.Concat(t);
dsinclair38fd8442016-09-15 10:15:32 -0700192 pDict->SetMatrixFor("Matrix", m);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 }
194 }
195 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700196
tsepez4cf55152016-11-02 14:37:54 -0700197 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700198}
199
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200DLLEXPORT void STDCALL
201FPDFPageObj_TransformClipPath(FPDF_PAGEOBJECT page_object,
202 double a,
203 double b,
204 double c,
205 double d,
206 double e,
207 double f) {
208 CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
Lei Zhang412e9082015-12-14 18:34:00 -0800209 if (!pPageObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 return;
Dan Sinclair05df0752017-03-14 14:43:42 -0400211 CFX_Matrix matrix((float)a, (float)b, (float)c, (float)d, (float)e, (float)f);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700212
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 // Special treatment to shading object, because the ClipPath for shading
214 // object is already transformed.
Wei Li7cf13c92016-02-19 11:53:03 -0800215 if (!pPageObj->IsShading())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 pPageObj->TransformClipPath(matrix);
217 pPageObj->TransformGeneralState(matrix);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700218}
219
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220DLLEXPORT FPDF_CLIPPATH STDCALL FPDF_CreateClipPath(float left,
221 float bottom,
222 float right,
223 float top) {
tsepezfc1d16f2016-09-02 15:45:22 -0700224 CPDF_Path Path;
225 Path.AppendRect(left, bottom, right, top);
226
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700227 auto pNewClipPath = pdfium::MakeUnique<CPDF_ClipPath>();
tsepez4cf55152016-11-02 14:37:54 -0700228 pNewClipPath->AppendPath(Path, FXFILL_ALTERNATE, false);
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700229 return pNewClipPath.release(); // Caller takes ownership.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700230}
231
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232DLLEXPORT void STDCALL FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath) {
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700233 // Take ownership back from caller and destroy.
234 std::unique_ptr<CPDF_ClipPath>(static_cast<CPDF_ClipPath*>(clipPath));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235}
236
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400237void OutputPath(std::ostringstream& buf, CPDF_Path path) {
tsepez7d2a8d92016-06-08 11:51:23 -0700238 const CFX_PathData* pPathData = path.GetObject();
Lei Zhang412e9082015-12-14 18:34:00 -0800239 if (!pPathData)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240 return;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700241
Dan Sinclaire4602322017-02-15 11:07:32 -0500242 const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
tsepez59601432016-08-29 14:26:57 -0700243 if (path.IsRect()) {
dan sinclairb147e072017-02-22 19:56:15 -0500244 CFX_PointF diff = pPoints[2].m_Point - pPoints[0].m_Point;
245 buf << pPoints[0].m_Point.x << " " << pPoints[0].m_Point.y << " " << diff.x
246 << " " << diff.y << " re\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 return;
248 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700249
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 CFX_ByteString temp;
Dan Sinclaire4602322017-02-15 11:07:32 -0500251 for (size_t i = 0; i < pPoints.size(); i++) {
dan sinclairb147e072017-02-22 19:56:15 -0500252 buf << pPoints[i].m_Point.x << " " << pPoints[i].m_Point.y;
Nicolas Pena79365f72017-02-07 14:21:36 -0500253 FXPT_TYPE point_type = pPoints[i].m_Type;
254 if (point_type == FXPT_TYPE::MoveTo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255 buf << " m\n";
Nicolas Pena79365f72017-02-07 14:21:36 -0500256 } else if (point_type == FXPT_TYPE::BezierTo) {
dan sinclairb147e072017-02-22 19:56:15 -0500257 buf << " " << pPoints[i + 1].m_Point.x << " " << pPoints[i + 1].m_Point.y
258 << " " << pPoints[i + 2].m_Point.x << " " << pPoints[i + 2].m_Point.y;
259 buf << " c";
Nicolas Pena79365f72017-02-07 14:21:36 -0500260 if (pPoints[i + 2].m_CloseFigure)
dan sinclairb147e072017-02-22 19:56:15 -0500261 buf << " h";
262 buf << "\n";
263
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700264 i += 2;
Nicolas Pena79365f72017-02-07 14:21:36 -0500265 } else if (point_type == FXPT_TYPE::LineTo) {
dan sinclairb147e072017-02-22 19:56:15 -0500266 buf << " l";
Nicolas Pena79365f72017-02-07 14:21:36 -0500267 if (pPoints[i].m_CloseFigure)
dan sinclairb147e072017-02-22 19:56:15 -0500268 buf << " h";
269 buf << "\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 }
271 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700272}
273
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,
275 FPDF_CLIPPATH clipPath) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700276 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 if (!pPage)
278 return;
Lei Zhang6ac0d2f2015-10-02 10:08:48 -0700279
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700280 CPDF_Dictionary* pPageDic = pPage->m_pFormDict.Get();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400281 CPDF_Object* pContentObj =
dsinclair38fd8442016-09-15 10:15:32 -0700282 pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700283 if (!pContentObj)
dsinclair38fd8442016-09-15 10:15:32 -0700284 pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 if (!pContentObj)
286 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700287
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400288 std::ostringstream strClip;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700289 CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
tsepezc3255f52016-03-25 14:52:27 -0700290 uint32_t i;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700291 for (i = 0; i < pClipPath->GetPathCount(); i++) {
292 CPDF_Path path = pClipPath->GetPath(i);
293 int iClipType = pClipPath->GetClipType(i);
Dan Sinclaire4602322017-02-15 11:07:32 -0500294 if (path.GetPoints().empty()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295 // Empty clipping (totally clipped out)
296 strClip << "0 0 m W n ";
297 } else {
298 OutputPath(strClip, path);
299 if (iClipType == FXFILL_WINDING)
300 strClip << "W n\n";
301 else
302 strClip << "W* n\n";
303 }
304 }
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700305 CPDF_Document* pDoc = pPage->m_pDocument.Get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306 if (!pDoc)
307 return;
tsepezbb577af2016-09-21 19:10:19 -0700308
tsepez9e05ee12016-11-21 13:19:10 -0800309 CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
310 nullptr, 0,
311 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
Henrique Nakashima8e052a62017-06-27 17:14:31 -0400312 pStream->SetData(&strClip);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700313
weilidb444d22016-06-02 15:48:15 -0700314 CPDF_Array* pArray = ToArray(pContentObj);
315 if (pArray) {
tsepez8a3aa452016-11-16 12:26:06 -0800316 pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
317 return;
318 }
319 CPDF_Reference* pReference = ToReference(pContentObj);
320 if (!pReference)
321 return;
322
323 CPDF_Object* pDirectObj = pReference->GetDirect();
324 if (!pDirectObj)
325 return;
326
327 CPDF_Array* pObjArray = pDirectObj->AsArray();
328 if (pObjArray) {
329 pObjArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
330 return;
331 }
332 if (pDirectObj->IsStream()) {
333 CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
334 pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
335 pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
tsepez0e606b52016-11-18 16:22:41 -0800336 pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
337 pContentArray->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700338 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700339}