blob: 9cf5a0b729eb25981e31960a7efc5139dc93b4c8 [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>
Dan Sinclaire4602322017-02-15 11:07:32 -050010#include <vector>
11
dsinclair41872fa2016-10-04 11:29:35 -070012#include "core/fpdfapi/page/cpdf_clippath.h"
13#include "core/fpdfapi/page/cpdf_page.h"
14#include "core/fpdfapi/page/cpdf_pageobject.h"
15#include "core/fpdfapi/page/cpdf_path.h"
dsinclair488b7ad2016-10-04 11:55:50 -070016#include "core/fpdfapi/parser/cpdf_array.h"
17#include "core/fpdfapi/parser/cpdf_document.h"
18#include "core/fpdfapi/parser/cpdf_number.h"
19#include "core/fpdfapi/parser/cpdf_reference.h"
20#include "core/fpdfapi/parser/cpdf_stream.h"
dsinclair74a34fc2016-09-29 16:41:42 -070021#include "core/fxge/cfx_pathdata.h"
dsinclair114e46a2016-09-29 17:18:21 -070022#include "fpdfsdk/fsdk_define.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070023
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070024namespace {
25
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070026void SetBoundingBox(CPDF_Page* page,
tsepez71a452f2016-05-13 17:51:27 -070027 const CFX_ByteString& key,
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070028 float left,
29 float bottom,
30 float right,
31 float top) {
tsepez0e606b52016-11-18 16:22:41 -080032 CPDF_Array* pBoundingBoxArray = page->m_pFormDict->SetNewFor<CPDF_Array>(key);
tsepez8a3aa452016-11-16 12:26:06 -080033 pBoundingBoxArray->AddNew<CPDF_Number>(left);
34 pBoundingBoxArray->AddNew<CPDF_Number>(bottom);
35 pBoundingBoxArray->AddNew<CPDF_Number>(right);
36 pBoundingBoxArray->AddNew<CPDF_Number>(top);
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070037}
38
tsepez71a452f2016-05-13 17:51:27 -070039bool GetBoundingBox(CPDF_Page* page,
40 const CFX_ByteString& key,
41 float* left,
42 float* bottom,
43 float* right,
44 float* top) {
dsinclair38fd8442016-09-15 10:15:32 -070045 CPDF_Array* pArray = page->m_pFormDict->GetArrayFor(key);
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070046 if (!pArray)
tsepez71a452f2016-05-13 17:51:27 -070047 return false;
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070048
Wei Li9b761132016-01-29 15:44:20 -080049 *left = pArray->GetFloatAt(0);
50 *bottom = pArray->GetFloatAt(1);
51 *right = pArray->GetFloatAt(2);
52 *top = pArray->GetFloatAt(3);
tsepez71a452f2016-05-13 17:51:27 -070053 return true;
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070054}
55
56} // namespace
57
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page,
59 float left,
60 float bottom,
61 float right,
62 float top) {
Tom Sepezdb0be962015-10-16 14:00:21 -070063 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064 if (!pPage)
65 return;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070066
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070067 SetBoundingBox(pPage, "MediaBox", left, bottom, right, top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070068}
69
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070DLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page,
71 float left,
72 float bottom,
73 float right,
74 float top) {
Tom Sepezdb0be962015-10-16 14:00:21 -070075 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076 if (!pPage)
77 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070078
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070079 SetBoundingBox(pPage, "CropBox", left, bottom, right, top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070080}
81
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page,
83 float* left,
84 float* bottom,
85 float* right,
86 float* top) {
Tom Sepezdb0be962015-10-16 14:00:21 -070087 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070088 return pPage && GetBoundingBox(pPage, "MediaBox", left, bottom, right, top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070089}
90
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page,
92 float* left,
93 float* bottom,
94 float* right,
95 float* top) {
Tom Sepezdb0be962015-10-16 14:00:21 -070096 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Lei Zhang6ac0d2f2015-10-02 10:08:48 -070097 return pPage && GetBoundingBox(pPage, "CropBox", left, bottom, right, top);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098}
99
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page,
101 FS_MATRIX* matrix,
102 FS_RECTF* clipRect) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700103 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104 if (!pPage)
tsepez4cf55152016-11-02 14:37:54 -0700105 return false;
Bo Xufdc00a72014-10-28 23:03:33 -0700106
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107 CFX_ByteTextBuf textBuf;
108 textBuf << "q ";
109 CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right,
110 clipRect->top);
111 rect.Normalize();
112 CFX_ByteString bsClipping;
113 bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom,
114 rect.Width(), rect.Height());
115 textBuf << bsClipping;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700116
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117 CFX_ByteString bsMatix;
118 bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c,
119 matrix->d, matrix->e, matrix->f);
120 textBuf << bsMatix;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700121
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700122 CPDF_Dictionary* pPageDic = pPage->m_pFormDict.Get();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400123 CPDF_Object* pContentObj =
dsinclair38fd8442016-09-15 10:15:32 -0700124 pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125 if (!pContentObj)
dsinclair38fd8442016-09-15 10:15:32 -0700126 pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 if (!pContentObj)
tsepez4cf55152016-11-02 14:37:54 -0700128 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700129
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700130 CPDF_Document* pDoc = pPage->m_pDocument.Get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 if (!pDoc)
tsepez4cf55152016-11-02 14:37:54 -0700132 return false;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700133
tsepez9e05ee12016-11-21 13:19:10 -0800134 CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
135 nullptr, 0,
136 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
tsepez698c5712016-09-28 16:47:07 -0700137 pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize());
tsepez70c4afd2016-11-15 11:33:44 -0800138
tsepez9e05ee12016-11-21 13:19:10 -0800139 CPDF_Stream* pEndStream = pDoc->NewIndirect<CPDF_Stream>(
140 nullptr, 0,
141 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
tsepeze6db16e2016-09-19 10:45:09 -0700142 pEndStream->SetData((const uint8_t*)" Q", 2);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700143
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400144 CPDF_Array* pContentArray = nullptr;
weilidb444d22016-06-02 15:48:15 -0700145 CPDF_Array* pArray = ToArray(pContentObj);
146 if (pArray) {
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400147 pContentArray = pArray;
tsepez8a3aa452016-11-16 12:26:06 -0800148 pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
149 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
Dan Sinclairbf81c142015-10-26 16:54:39 -0400150 } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 CPDF_Object* pDirectObj = pReference->GetDirect();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400152 if (pDirectObj) {
weilidb444d22016-06-02 15:48:15 -0700153 CPDF_Array* pObjArray = pDirectObj->AsArray();
154 if (pObjArray) {
155 pContentArray = pObjArray;
tsepez8a3aa452016-11-16 12:26:06 -0800156 pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc,
157 pStream->GetObjNum());
158 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400159 } else if (pDirectObj->IsStream()) {
tsepez70c4afd2016-11-15 11:33:44 -0800160 pContentArray = pDoc->NewIndirect<CPDF_Array>();
tsepez8a3aa452016-11-16 12:26:06 -0800161 pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
162 pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
163 pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
tsepez0e606b52016-11-18 16:22:41 -0800164 pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
165 pContentArray->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 }
167 }
168 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700169
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 // Need to transform the patterns as well.
dsinclair38fd8442016-09-15 10:15:32 -0700171 CPDF_Dictionary* pRes = pPageDic->GetDictFor("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 if (pRes) {
dsinclair38fd8442016-09-15 10:15:32 -0700173 CPDF_Dictionary* pPattenDict = pRes->GetDictFor("Pattern");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174 if (pPattenDict) {
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800175 for (const auto& it : *pPattenDict) {
tsepez0e606b52016-11-18 16:22:41 -0800176 CPDF_Object* pObj = it.second.get();
Dan Sinclairbf81c142015-10-26 16:54:39 -0400177 if (pObj->IsReference())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 pObj = pObj->GetDirect();
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400179
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800180 CPDF_Dictionary* pDict = nullptr;
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400181 if (pObj->IsDictionary())
Dan Sinclairf1251c12015-10-20 16:24:45 -0400182 pDict = pObj->AsDictionary();
weilidb444d22016-06-02 15:48:15 -0700183 else if (CPDF_Stream* pObjStream = pObj->AsStream())
184 pDict = pObjStream->GetDict();
Dan Sinclairaa435ba2015-10-22 16:45:48 -0400185 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186 continue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700187
dsinclair38fd8442016-09-15 10:15:32 -0700188 CFX_Matrix m = pDict->GetMatrixFor("Matrix");
Tom Sepez60d909e2015-12-10 15:34:55 -0800189 CFX_Matrix t = *(CFX_Matrix*)matrix;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 m.Concat(t);
dsinclair38fd8442016-09-15 10:15:32 -0700191 pDict->SetMatrixFor("Matrix", m);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192 }
193 }
194 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700195
tsepez4cf55152016-11-02 14:37:54 -0700196 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700197}
198
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199DLLEXPORT void STDCALL
200FPDFPageObj_TransformClipPath(FPDF_PAGEOBJECT page_object,
201 double a,
202 double b,
203 double c,
204 double d,
205 double e,
206 double f) {
207 CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
Lei Zhang412e9082015-12-14 18:34:00 -0800208 if (!pPageObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 return;
Dan Sinclair05df0752017-03-14 14:43:42 -0400210 CFX_Matrix matrix((float)a, (float)b, (float)c, (float)d, (float)e, (float)f);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700211
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 // Special treatment to shading object, because the ClipPath for shading
213 // object is already transformed.
Wei Li7cf13c92016-02-19 11:53:03 -0800214 if (!pPageObj->IsShading())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215 pPageObj->TransformClipPath(matrix);
216 pPageObj->TransformGeneralState(matrix);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700217}
218
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219DLLEXPORT FPDF_CLIPPATH STDCALL FPDF_CreateClipPath(float left,
220 float bottom,
221 float right,
222 float top) {
tsepezfc1d16f2016-09-02 15:45:22 -0700223 CPDF_Path Path;
224 Path.AppendRect(left, bottom, right, top);
225
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700226 auto pNewClipPath = pdfium::MakeUnique<CPDF_ClipPath>();
tsepez4cf55152016-11-02 14:37:54 -0700227 pNewClipPath->AppendPath(Path, FXFILL_ALTERNATE, false);
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700228 return pNewClipPath.release(); // Caller takes ownership.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700229}
230
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231DLLEXPORT void STDCALL FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath) {
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700232 // Take ownership back from caller and destroy.
233 std::unique_ptr<CPDF_ClipPath>(static_cast<CPDF_ClipPath*>(clipPath));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700234}
235
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700236void OutputPath(CFX_ByteTextBuf& buf, CPDF_Path path) {
tsepez7d2a8d92016-06-08 11:51:23 -0700237 const CFX_PathData* pPathData = path.GetObject();
Lei Zhang412e9082015-12-14 18:34:00 -0800238 if (!pPathData)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239 return;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700240
Dan Sinclaire4602322017-02-15 11:07:32 -0500241 const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
tsepez59601432016-08-29 14:26:57 -0700242 if (path.IsRect()) {
dan sinclairb147e072017-02-22 19:56:15 -0500243 CFX_PointF diff = pPoints[2].m_Point - pPoints[0].m_Point;
244 buf << pPoints[0].m_Point.x << " " << pPoints[0].m_Point.y << " " << diff.x
245 << " " << diff.y << " re\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 return;
247 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700248
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 CFX_ByteString temp;
Dan Sinclaire4602322017-02-15 11:07:32 -0500250 for (size_t i = 0; i < pPoints.size(); i++) {
dan sinclairb147e072017-02-22 19:56:15 -0500251 buf << pPoints[i].m_Point.x << " " << pPoints[i].m_Point.y;
Nicolas Pena79365f72017-02-07 14:21:36 -0500252 FXPT_TYPE point_type = pPoints[i].m_Type;
253 if (point_type == FXPT_TYPE::MoveTo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 buf << " m\n";
Nicolas Pena79365f72017-02-07 14:21:36 -0500255 } else if (point_type == FXPT_TYPE::BezierTo) {
dan sinclairb147e072017-02-22 19:56:15 -0500256 buf << " " << pPoints[i + 1].m_Point.x << " " << pPoints[i + 1].m_Point.y
257 << " " << pPoints[i + 2].m_Point.x << " " << pPoints[i + 2].m_Point.y;
258 buf << " c";
Nicolas Pena79365f72017-02-07 14:21:36 -0500259 if (pPoints[i + 2].m_CloseFigure)
dan sinclairb147e072017-02-22 19:56:15 -0500260 buf << " h";
261 buf << "\n";
262
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 i += 2;
Nicolas Pena79365f72017-02-07 14:21:36 -0500264 } else if (point_type == FXPT_TYPE::LineTo) {
dan sinclairb147e072017-02-22 19:56:15 -0500265 buf << " l";
Nicolas Pena79365f72017-02-07 14:21:36 -0500266 if (pPoints[i].m_CloseFigure)
dan sinclairb147e072017-02-22 19:56:15 -0500267 buf << " h";
268 buf << "\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 }
270 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700271}
272
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,
274 FPDF_CLIPPATH clipPath) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700275 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 if (!pPage)
277 return;
Lei Zhang6ac0d2f2015-10-02 10:08:48 -0700278
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700279 CPDF_Dictionary* pPageDic = pPage->m_pFormDict.Get();
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400280 CPDF_Object* pContentObj =
dsinclair38fd8442016-09-15 10:15:32 -0700281 pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 if (!pContentObj)
dsinclair38fd8442016-09-15 10:15:32 -0700283 pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 if (!pContentObj)
285 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700286
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 CFX_ByteTextBuf strClip;
288 CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
tsepezc3255f52016-03-25 14:52:27 -0700289 uint32_t i;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290 for (i = 0; i < pClipPath->GetPathCount(); i++) {
291 CPDF_Path path = pClipPath->GetPath(i);
292 int iClipType = pClipPath->GetClipType(i);
Dan Sinclaire4602322017-02-15 11:07:32 -0500293 if (path.GetPoints().empty()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 // Empty clipping (totally clipped out)
295 strClip << "0 0 m W n ";
296 } else {
297 OutputPath(strClip, path);
298 if (iClipType == FXFILL_WINDING)
299 strClip << "W n\n";
300 else
301 strClip << "W* n\n";
302 }
303 }
Tom Sepez4cb82ee2017-05-22 15:15:30 -0700304 CPDF_Document* pDoc = pPage->m_pDocument.Get();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305 if (!pDoc)
306 return;
tsepezbb577af2016-09-21 19:10:19 -0700307
tsepez9e05ee12016-11-21 13:19:10 -0800308 CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
309 nullptr, 0,
310 pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
tsepez698c5712016-09-28 16:47:07 -0700311 pStream->SetData(strClip.GetBuffer(), strClip.GetSize());
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700312
weilidb444d22016-06-02 15:48:15 -0700313 CPDF_Array* pArray = ToArray(pContentObj);
314 if (pArray) {
tsepez8a3aa452016-11-16 12:26:06 -0800315 pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
316 return;
317 }
318 CPDF_Reference* pReference = ToReference(pContentObj);
319 if (!pReference)
320 return;
321
322 CPDF_Object* pDirectObj = pReference->GetDirect();
323 if (!pDirectObj)
324 return;
325
326 CPDF_Array* pObjArray = pDirectObj->AsArray();
327 if (pObjArray) {
328 pObjArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
329 return;
330 }
331 if (pDirectObj->IsStream()) {
332 CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
333 pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
334 pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
tsepez0e606b52016-11-18 16:22:41 -0800335 pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
336 pContentArray->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700337 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700338}