1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../include/fsdk_define.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../include/fpdf_transformpage.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page, float left, float bottom, float right, float top)
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!page)
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return;
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Page* pPage = (CPDF_Page*)page;
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Array* pMediaBoxArray = FX_NEW CPDF_Array;
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pMediaBoxArray->Add(FX_NEW CPDF_Number(left));
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pMediaBoxArray->Add(FX_NEW CPDF_Number(bottom));
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(right)));
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(top)));
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pPageDict->SetAt("MediaBox", pMediaBoxArray);
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page, float left, float bottom, float right, float top)
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!page)
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return;
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Page* pPage = (CPDF_Page*)page;
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Array* pCropBoxArray = FX_NEW CPDF_Array;
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pCropBoxArray->Add(FX_NEW CPDF_Number(left));
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pCropBoxArray->Add(FX_NEW CPDF_Number(bottom));
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pCropBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(right)));
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pCropBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(top)));
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pPageDict->SetAt("CropBox", pCropBoxArray);
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT FX_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page, float* left, float* bottom, float* right, float* top)
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!page)
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return FALSE;
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Page* pPage = (CPDF_Page*)page;
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Array* pArray = pPageDict->GetArray("MediaBox");
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(pArray)
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	{
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		*left = pArray->GetFloat(0);
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		*bottom = pArray->GetFloat(1);
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		*right = pArray->GetFloat(2);
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		*top = pArray->GetFloat(3);
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return TRUE;
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return FALSE;
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page, float* left, float* bottom, float* right, float* top)
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!page)
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return FALSE;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Page* pPage = (CPDF_Page*)page;
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Array* pArray = pPageDict->GetArray("CropBox");
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(pArray)
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	{
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		*left = pArray->GetFloat(0);
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		*bottom = pArray->GetFloat(1);
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		*right = pArray->GetFloat(2);
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		*top = pArray->GetFloat(3);
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return TRUE;
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return FALSE;
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX* matrix, FS_RECTF* clipRect)
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!page)
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return FALSE;
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CFX_ByteTextBuf textBuf;
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	textBuf<<"q ";
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right, clipRect->top);
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	rect.Normalize();
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CFX_ByteString bsClipping;
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom, rect.Width(), rect.Height());
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	textBuf<<bsClipping;
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CFX_ByteString bsMatix;
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b,matrix->c,matrix->d,matrix->e,matrix->f);
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	textBuf<<bsMatix;
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Page* pPage = (CPDF_Page*)page;
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!pContentObj)
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		pContentObj = pPageDic->GetArray("Contents");
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!pContentObj)
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return FALSE;
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Document* pDoc = pPage->m_pDocument;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!pDoc)
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return FALSE;
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pDoc->AddIndirectObject(pStream);
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pDic = FX_NEW CPDF_Dictionary;
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Stream* pEndStream = FX_NEW CPDF_Stream(NULL,0, pDic);
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pEndStream->SetData((FX_LPCBYTE)" Q", 2, FALSE, FALSE);
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pDoc->AddIndirectObject(pEndStream);
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Array* pContentArray = NULL;
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	{
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		pContentArray = (CPDF_Array*)pContentObj;
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		pContentArray->InsertAt(0, pRef);
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		pContentArray->AddReference(pDoc,pEndStream);
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	{
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		CPDF_Object* pDirectObj = pReference->GetDirect();
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		if(pDirectObj != NULL)
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		{
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			{
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray = (CPDF_Array*)pDirectObj;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray->InsertAt(0, pRef);
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray->AddReference(pDoc,pEndStream);
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			}
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			{
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray = FX_NEW CPDF_Array();
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray->AddReference(pDoc,pStream->GetObjNum());
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray->AddReference(pDoc, pEndStream);
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			}
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	//Need to transform the patterns as well.
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pRes = pPageDic->GetDict(FX_BSTRC("Resources"));
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(pRes)
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	{
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		CPDF_Dictionary* pPattenDict = pRes->GetDict(FX_BSTRC("Pattern"));
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		if(pPattenDict)
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		{
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			FX_POSITION pos = pPattenDict->GetStartPos();
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			while(pos)
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			{
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				CPDF_Dictionary* pDict = NULL;
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				CFX_ByteString key;
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				CPDF_Object* pObj = pPattenDict->GetNextElement(pos, key);
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				if(pObj->GetType() == PDFOBJ_REFERENCE)
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					pObj = pObj->GetDirect();
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				if(pObj->GetType() == PDFOBJ_DICTIONARY)
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				{
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					pDict = (CPDF_Dictionary*)pObj;
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				}
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				else if(pObj->GetType() == PDFOBJ_STREAM)
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				{
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					pDict = ((CPDF_Stream*)pObj)->GetDict();
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				}
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				else
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					continue;
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				CFX_AffineMatrix m = pDict->GetMatrix(FX_BSTRC("Matrix"));
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				CFX_AffineMatrix t = *(CFX_AffineMatrix*)matrix;
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				m.Concat(t);
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pDict->SetAtMatrix(FX_BSTRC("Matrix"), m);
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			}
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return TRUE;
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT void STDCALL FPDFPageObj_TransformClipPath(FPDF_PAGEOBJECT page_object,double a, double b, double c, double d, double e, double f)
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(pPageObj == NULL)
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return;
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CFX_AffineMatrix matrix((FX_FLOAT)a,(FX_FLOAT)b,(FX_FLOAT)c,(FX_FLOAT)d,(FX_FLOAT)e,(FX_FLOAT)f);
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	//Special treatment to shading object, because the ClipPath for shading object is already transformed.
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(pPageObj->m_Type != PDFPAGE_SHADING)
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		pPageObj->TransformClipPath(matrix);
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pPageObj->TransformGeneralState(matrix);
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT FPDF_CLIPPATH STDCALL FPDF_CreateClipPath(float left, float bottom, float right, float top)
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_ClipPath* pNewClipPath =  FX_NEW CPDF_ClipPath();
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pNewClipPath->GetModify();
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Path Path;
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	Path.GetModify();
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	Path.AppendRect(left, bottom, right, top);
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pNewClipPath->AppendPath(Path, FXFILL_ALTERNATE, FALSE);
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return pNewClipPath;
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT void STDCALL FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath)
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(clipPath)
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		delete (CPDF_ClipPath*)clipPath;
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid OutputPath(CFX_ByteTextBuf& buf, CPDF_Path path)
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	const CFX_PathData* pPathData = path;
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if (pPathData == NULL) return;
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	FX_PATHPOINT* pPoints = pPathData->GetPoints();
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if (path.IsRect()) {
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		buf << (pPoints[0].m_PointX) << " " << (pPoints[0].m_PointY) << " "
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			<< (pPoints[2].m_PointX - pPoints[0].m_PointX) << " "
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			<< (pPoints[2].m_PointY - pPoints[0].m_PointY) << " re\n";
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return;
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CFX_ByteString temp;
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for (int i = 0; i < pPathData->GetPointCount(); i ++) {
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		buf << (pPoints[i].m_PointX) << " " << (pPoints[i].m_PointY);
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		int point_type = pPoints[i].m_Flag & FXPT_TYPE;
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		if (point_type == FXPT_MOVETO)
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			buf << " m\n";
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		else if (point_type == FXPT_BEZIERTO) {
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			buf << " " << (pPoints[i+1].m_PointX) << " " << (pPoints[i+1].m_PointY) << " " <<
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				(pPoints[i+2].m_PointX) << " " << (pPoints[i+2].m_PointY);
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			if (pPoints[i+2].m_Flag & FXPT_CLOSEFIGURE)
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				buf << " c h\n";
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			else
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				buf << " c\n";
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			i += 2;
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		} else if (point_type == FXPT_LINETO) {
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE)
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				buf << " l h\n";
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			else
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				buf << " l\n";
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,FPDF_CLIPPATH clipPath)
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!page)
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return;
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Page* pPage = (CPDF_Page*)page;
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!pContentObj)
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		pContentObj = pPageDic->GetArray("Contents");
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!pContentObj)
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CFX_ByteTextBuf strClip;
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	FX_DWORD i;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for (i = 0; i < pClipPath->GetPathCount(); i ++) {
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		CPDF_Path path = pClipPath->GetPath(i);
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		int iClipType = pClipPath->GetClipType(i);
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		if (path.GetPointCount() == 0) {
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			// Empty clipping (totally clipped out)
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			strClip << "0 0 m W n ";
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		} else {
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			OutputPath(strClip, path);
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			if (iClipType == FXFILL_WINDING)
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				strClip << "W n\n";
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			else
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				strClip << "W* n\n";
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Document* pDoc = pPage->m_pDocument;
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if(!pDoc)
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return;
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	pDoc->AddIndirectObject(pStream);
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	CPDF_Array* pContentArray = NULL;
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	{
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		pContentArray = (CPDF_Array*)pContentObj;
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		pContentArray->InsertAt(0, pRef);
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	{
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		CPDF_Object* pDirectObj = pReference->GetDirect();
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		if(pDirectObj != NULL)
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		{
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			{
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray = (CPDF_Array*)pDirectObj;
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray->InsertAt(0, pRef);
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			}
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			{
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray = FX_NEW CPDF_Array();
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray->AddReference(pDoc,pStream->GetObjNum());
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			}
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
326