7#include "public/fpdf_transformpage.h"
12#include "constants/page_object.h"
13#include "core/fpdfapi/edit/cpdf_contentstream_write_utils.h"
14#include "core/fpdfapi/page/cpdf_clippath.h"
15#include "core/fpdfapi/page/cpdf_page.h"
16#include "core/fpdfapi/page/cpdf_pageobject.h"
17#include "core/fpdfapi/page/cpdf_path.h"
18#include "core/fpdfapi/parser/cpdf_array.h"
19#include "core/fpdfapi/parser/cpdf_dictionary.h"
20#include "core/fpdfapi/parser/cpdf_document.h"
21#include "core/fpdfapi/parser/cpdf_number.h"
22#include "core/fpdfapi/parser/cpdf_reference.h"
23#include "core/fpdfapi/parser/cpdf_stream.h"
24#include "core/fxcrt/fx_string_wrappers.h"
25#include "core/fxcrt/stl_util.h"
26#include "core/fxge/cfx_fillrenderoptions.h"
27#include "core/fxge/cfx_path.h"
28#include "fpdfsdk/cpdfsdk_helpers.h"
29#include "third_party/base/containers/span.h"
30#include "third_party/base/numerics/safe_conversions.h"
34void SetBoundingBox(CPDF_Page* page,
35 const ByteString& key,
40 page->GetMutableDict()->SetRectFor(key, rect);
44bool GetBoundingBox(
const CPDF_Page* page,
45 const ByteString& key,
50 if (!page || !left || !bottom || !right || !top)
53 RetainPtr<
const CPDF_Array> pArray = page->GetDict()->GetArrayFor(key);
57 *left = pArray->GetFloatAt(0);
58 *bottom = pArray->GetFloatAt(1);
59 *right = pArray->GetFloatAt(2);
60 *top = pArray->GetFloatAt(3);
68void OutputPath(fxcrt::ostringstream& buf,
CPDF_Path path) {
73 pdfium::span<
const CFX_Path::
Point> points = pPath->GetPoints();
75 CFX_PointF diff = points[2].m_Point - points[0].m_Point;
76 buf << points[0].m_Point.x <<
" " << points[0].m_Point.y <<
" " << diff.x
77 <<
" " << diff.y <<
" re\n";
81 for (size_t i = 0; i < points.size(); ++i) {
82 buf << points[i].m_Point.x <<
" " << points[i].m_Point.y;
87 buf <<
" " << points[i + 1].m_Point.x <<
" " << points[i + 1].m_Point.y
88 <<
" " << points[i + 2].m_Point.x <<
" " << points[i + 2].m_Point.y;
90 if (points[i + 2].m_CloseFigure)
97 if (points[i].m_CloseFigure)
202 const FS_MATRIX* matrix,
203 const FS_RECTF* clipRect) {
204 if (!matrix && !clipRect)
211 RetainPtr<CPDF_Dictionary> pPageDict = pPage->GetMutableDict();
220 fxcrt::ostringstream text_buf;
226 WriteRect(text_buf, rect) <<
" re W* n ";
231 auto pStream = pDoc->NewIndirect<CPDF_Stream>(pDoc->New<CPDF_Dictionary>());
232 pStream->SetDataFromStringstream(&text_buf);
235 pDoc->NewIndirect<CPDF_Stream>(pDoc->New<CPDF_Dictionary>());
236 pEndStream->SetData(ByteStringView(
" Q").raw_span());
238 RetainPtr<CPDF_Array> pContentArray = ToArray(pContentObj);
240 pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
241 pContentArray->AppendNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
242 }
else if (pContentObj->IsStream() && !pContentObj->IsInline()) {
243 pContentArray = pDoc->NewIndirect<CPDF_Array>();
244 pContentArray->AppendNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
245 pContentArray->AppendNew<CPDF_Reference>(pDoc, pContentObj->GetObjNum());
246 pContentArray->AppendNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
248 pContentArray->GetObjNum());
253 pPageDict->GetDictFor(pdfium::page_object::kResources);
257 RetainPtr<
const CPDF_Dictionary> pPatternDict = pRes->GetDictFor(
"Pattern");
262 for (
const auto& it : locker) {
263 RetainPtr<CPDF_Object> pObj = it.second;
264 if (pObj->IsReference())
265 pObj = pObj->GetMutableDirect();
267 RetainPtr<CPDF_Dictionary> pDict;
268 if (pObj->IsDictionary())
269 pDict.Reset(pObj->AsMutableDictionary());
270 else if (CPDF_Stream* pObjStream = pObj->AsMutableStream())
271 pDict = pObjStream->GetMutableDict();
276 CFX_Matrix m = CFXMatrixFromFSMatrix(*matrix);
277 pDict->SetMatrixFor(
"Matrix", pDict->GetMatrixFor(
"Matrix") * m);
319 return pdfium::base::checked_cast<
int>(pClipPath->GetPathCount());
328 if (path_index < 0 ||
329 static_cast<size_t>(path_index) >= pClipPath->GetPathCount()) {
333 return fxcrt::CollectionSize<
int>(pClipPath->GetPath(path_index).GetPoints());
344 if (path_index < 0 ||
345 static_cast<size_t>(path_index) >= pClipPath->GetPathCount()) {
350 pClipPath->GetPath(path_index).GetPoints();
351 if (!
fxcrt::IndexInBounds(points, segment_index))
354 return FPDFPathSegmentFromFXPathPoint(&points[segment_index]);
368 return FPDFClipPathFromCPDFClipPath(pNewClipPath.release());
373 std::unique_ptr<CPDF_ClipPath>(CPDFClipPathFromFPDFClipPath(clipPath));
377 FPDF_CLIPPATH clipPath) {
382 RetainPtr<CPDF_Dictionary> pPageDict = pPage->GetMutableDict();
387 fxcrt::ostringstream strClip;
389 for (size_t i = 0; i < pClipPath->GetPathCount(); ++i) {
391 if (path.GetPoints().empty()) {
393 strClip <<
"0 0 m W n ";
395 OutputPath(strClip, path);
396 if (pClipPath->GetClipType(i) ==
408 auto pStream = pDoc->NewIndirect<CPDF_Stream>(pDoc->New<CPDF_Dictionary>());
409 pStream->SetDataFromStringstream(&strClip);
411 RetainPtr<CPDF_Array> pArray = ToArray(pContentObj);
413 pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
414 }
else if (pContentObj->IsStream() && !pContentObj->IsInline()) {
415 auto pContentArray = pDoc->NewIndirect<CPDF_Array>();
416 pContentArray->AppendNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
417 pContentArray->AppendNew<CPDF_Reference>(pDoc, pContentObj->GetObjNum());
419 pContentArray->GetObjNum());
constexpr CFX_FloatRect(float l, float b, float r, float t)
CFX_Matrix(float a1, float b1, float c1, float d1, float e1, float f1)
RetainPtr< CPDF_Object > GetMutableDirectObjectFor(const ByteString &key)
void TransformClipPath(const CFX_Matrix &matrix)
void TransformGeneralState(const CFX_Matrix &matrix)
CPDF_ClipPath & mutable_clip_path()
virtual bool IsShading() const
CPDF_Document * GetDocument() const override
void AppendRect(float left, float bottom, float right, float top)
const CFX_Path * GetObject() const
CPDF_ClipPath * CPDFClipPathFromFPDFClipPath(FPDF_CLIPPATH path)
CFX_FloatRect CFXFloatRectFromFSRectF(const FS_RECTF &rect)
FPDF_CLIPPATH FPDFClipPathFromCPDFClipPath(CPDF_ClipPath *path)
CPDF_Page * CPDFPageFromFPDFPage(FPDF_PAGE page)
CPDF_PageObject * CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object)
CFX_Matrix CFXMatrixFromFSMatrix(const FS_MATRIX &matrix)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GetArtBox(FPDF_PAGE page, float *left, float *bottom, float *right, float *top)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GetTrimBox(FPDF_PAGE page, float *left, float *bottom, float *right, float *top)
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetBleedBox(FPDF_PAGE page, float left, float bottom, float right, float top)
FPDF_EXPORT int FPDF_CALLCONV FPDFClipPath_CountPaths(FPDF_CLIPPATH clip_path)
FPDF_EXPORT FPDF_CLIPPATH FPDF_CALLCONV FPDFPageObj_GetClipPath(FPDF_PAGEOBJECT page_object)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GetMediaBox(FPDF_PAGE page, float *left, float *bottom, float *right, float *top)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GetCropBox(FPDF_PAGE page, float *left, float *bottom, float *right, float *top)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_TransFormWithClip(FPDF_PAGE page, const FS_MATRIX *matrix, const FS_RECTF *clipRect)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GetBleedBox(FPDF_PAGE page, float *left, float *bottom, float *right, float *top)
FPDF_EXPORT void FPDF_CALLCONV FPDFPageObj_TransformClipPath(FPDF_PAGEOBJECT page_object, double a, double b, double c, double d, double e, double f)
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetMediaBox(FPDF_PAGE page, float left, float bottom, float right, float top)
FPDF_EXPORT FPDF_PATHSEGMENT FPDF_CALLCONV FPDFClipPath_GetPathSegment(FPDF_CLIPPATH clip_path, int path_index, int segment_index)
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetCropBox(FPDF_PAGE page, float left, float bottom, float right, float top)
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetTrimBox(FPDF_PAGE page, float left, float bottom, float right, float top)
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_SetArtBox(FPDF_PAGE page, float left, float bottom, float right, float top)
FPDF_EXPORT FPDF_CLIPPATH FPDF_CALLCONV FPDF_CreateClipPath(float left, float bottom, float right, float top)
FPDF_EXPORT int FPDF_CALLCONV FPDFClipPath_CountPathSegments(FPDF_CLIPPATH clip_path, int path_index)
FPDF_EXPORT void FPDF_CALLCONV FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath)
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_InsertClipPath(FPDF_PAGE page, FPDF_CLIPPATH clipPath)