Home | History | Annotate | Download | only in src
      1 // 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.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../public/fpdf_edit.h"
      8 #include "../include/fsdk_define.h"
      9 
     10 
     11 #if _FX_OS_ == _FX_ANDROID_
     12 #include "time.h"
     13 #else
     14 #include <ctime>
     15 #endif
     16 
     17 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument()
     18 {
     19 	CPDF_Document* pDoc = new CPDF_Document;
     20 	pDoc->CreateNewDoc();
     21 	time_t currentTime;
     22 
     23 	CFX_ByteString DateStr;
     24 
     25 	if(FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
     26 	{
     27 		if ( -1 != time( &currentTime ) )
     28 		{
     29 			tm * pTM = localtime( &currentTime );
     30 			if ( pTM )
     31 			{
     32 				DateStr.Format(	"D:%04d%02d%02d%02d%02d%02d", pTM->tm_year+1900, pTM->tm_mon+1,
     33 					pTM->tm_mday, pTM->tm_hour, pTM->tm_min, pTM->tm_sec );
     34 			}
     35 		}
     36 	}
     37 
     38 	CPDF_Dictionary* pInfoDict = NULL;
     39 	pInfoDict = pDoc->GetInfo();
     40 	if (pInfoDict)
     41 	{
     42 		if(FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
     43 			pInfoDict->SetAt("CreationDate", new CPDF_String(DateStr));
     44 		pInfoDict->SetAt("Creator", new CPDF_String(L"PDFium"));
     45 	}
     46 
     47 	return pDoc;
     48 }
     49 
     50 DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index)
     51 {
     52 	CPDF_Document* pDoc = (CPDF_Document*)document;
     53 	if (pDoc == NULL)
     54 		return;
     55 	if (page_index < 0 || page_index >= pDoc->GetPageCount())
     56 		return;
     57 
     58 	pDoc->DeletePage(page_index);
     59 }
     60 
     61 DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height)
     62 {
     63 	if (!document)
     64 		return NULL;
     65 
     66 //	CPDF_Parser* pParser = (CPDF_Parser*)document;
     67 	CPDF_Document* pDoc = (CPDF_Document*)document;
     68 	if(page_index < 0)
     69 		page_index = 0;
     70 	if(pDoc->GetPageCount()<page_index)
     71 		page_index = pDoc->GetPageCount();
     72 //	if (page_index < 0 || page_index >= pDoc->GetPageCount())
     73 //		return NULL;
     74 
     75 	CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index);
     76 	if(!pPageDict)
     77 		return NULL;
     78 	CPDF_Array* pMediaBoxArray = new CPDF_Array;
     79 	pMediaBoxArray->Add(new CPDF_Number(0));
     80 	pMediaBoxArray->Add(new CPDF_Number(0));
     81 	pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width)));
     82 	pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height)));
     83 
     84 	pPageDict->SetAt("MediaBox", pMediaBoxArray);
     85 	pPageDict->SetAt("Rotate", new CPDF_Number(0));
     86 	pPageDict->SetAt("Resources", new CPDF_Dictionary);
     87 
     88 	CPDF_Page* pPage = new CPDF_Page;
     89 	pPage->Load(pDoc,pPageDict);
     90 	pPage->ParseContent();
     91 
     92 	return pPage;
     93 }
     94 
     95 DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page)
     96 {
     97 	CPDF_Page* pPage = (CPDF_Page*)page;
     98 	if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
     99 		|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
    100 	{
    101 		return -1;
    102 	}
    103 	CPDF_Dictionary* pDict = pPage->m_pFormDict;
    104 
    105 	int rotate = 0;
    106 	if(pDict != NULL)
    107 	{
    108 		if (pDict->KeyExist("Rotate"))
    109 			rotate = pDict->GetElement("Rotate")->GetDirect()? pDict->GetElement("Rotate")->GetDirect()->GetInteger() / 90 : 0;
    110 		else
    111 		{
    112 			if(pDict->KeyExist("Parent"))
    113 			{
    114 				CPDF_Dictionary* pPages = (CPDF_Dictionary*)pDict->GetElement("Parent")->GetDirect();
    115 				while(pPages)
    116 				{
    117 					if(pPages->KeyExist("Rotate"))
    118 					{
    119 						rotate = pPages->GetElement("Rotate")->GetDirect()? pPages->GetElement("Rotate")->GetDirect()->GetInteger() / 90 : 0;
    120 						break;
    121 					}
    122 					else if(pPages->KeyExist("Parent"))
    123 						pPages = (CPDF_Dictionary*)pPages->GetElement("Parent")->GetDirect();
    124 					else break;
    125 				}
    126 			}
    127 		}
    128 	}
    129 	else
    130 	{
    131 		return -1;
    132 	}
    133 
    134 	return rotate;
    135 }
    136 
    137 DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_obj)
    138 {
    139 	CPDF_Page* pPage = (CPDF_Page*)page;
    140 	if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
    141 		|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
    142 	{
    143 		return;
    144 	}
    145 	CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj;
    146 	if(pPageObj == NULL)
    147 		return;
    148 	FX_POSITION LastPersition = pPage->GetLastObjectPosition();
    149 
    150 	pPage->InsertObject(LastPersition, pPageObj);
    151 	switch(pPageObj->m_Type)
    152 	{
    153 	case FPDF_PAGEOBJ_PATH:
    154 		{
    155 			CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
    156 			pPathObj->CalcBoundingBox();
    157 			break;
    158 		}
    159 	case FPDF_PAGEOBJ_TEXT:
    160 		{
    161 			//	CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
    162 			//	pPathObj->CalcBoundingBox();
    163 			break;
    164 		}
    165 	case FPDF_PAGEOBJ_IMAGE:
    166 		{
    167 			CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pPageObj;
    168 			pImageObj->CalcBoundingBox();
    169 			break;
    170 		}
    171 	case FPDF_PAGEOBJ_SHADING:
    172 		{
    173 			CPDF_ShadingObject* pShadingObj = (CPDF_ShadingObject*)pPageObj;
    174 			pShadingObj->CalcBoundingBox();
    175 			break;
    176 		}
    177 	case FPDF_PAGEOBJ_FORM:
    178 		{
    179 			CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
    180 			pFormObj->CalcBoundingBox();
    181 			break;
    182 		}
    183 	default:
    184 		break;
    185 	}
    186 
    187 	//	pPage->ParseContent();
    188 	//pPage->GenerateContent();
    189 
    190 }
    191 
    192 DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page)
    193 {
    194 	CPDF_Page* pPage = (CPDF_Page*)page;
    195 	if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
    196 		|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
    197 	{
    198 		return -1;
    199 	}
    200 	return pPage->CountObjects();
    201 //	return 0;
    202 }
    203 
    204 DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, int index)
    205 {
    206 	CPDF_Page* pPage = (CPDF_Page*)page;
    207 	if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type")
    208 		|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
    209 	{
    210 		return NULL;
    211 	}
    212 	return pPage->GetObjectByIndex(index);
    213 //	return NULL;
    214 }
    215 
    216 DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page)
    217 {
    218 	if(!page) return FALSE;
    219 	CPDF_Page* pPage = (CPDF_Page*)page;
    220 
    221 	return pPage->BackgroundAlphaNeeded();
    222 }
    223 
    224 DLLEXPORT FPDF_BOOL STDCALL FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject)
    225 {
    226 	if(!pageObject) return FALSE;
    227 	CPDF_PageObject* pPageObj = (CPDF_PageObject*)pageObject;
    228 
    229 	const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
    230 	int blend_type = pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
    231 	if (blend_type != FXDIB_BLEND_NORMAL) return TRUE;
    232 
    233 	CPDF_Dictionary* pSMaskDict = pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL;
    234 	if(pSMaskDict) return TRUE;
    235 
    236 	if(pGeneralState && pGeneralState->m_FillAlpha != 1.0f)
    237 		return TRUE;
    238 
    239 	if(pPageObj->m_Type == PDFPAGE_PATH)
    240 	{
    241 		if(pGeneralState && pGeneralState->m_StrokeAlpha != 1.0f)
    242 			return TRUE;
    243 	}
    244 
    245 	if(pPageObj->m_Type == PDFPAGE_FORM)
    246 	{
    247 		CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
    248 		if(pFormObj->m_pForm && (pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED))
    249 			return TRUE;
    250 		if(pFormObj->m_pForm && (!(pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED) && (pFormObj->m_pForm->m_Transparency & PDFTRANS_GROUP)))
    251 			return TRUE;
    252 	}
    253 	return FALSE;
    254 }
    255 
    256 DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page)
    257 {
    258 	CPDF_Page* pPage = (CPDF_Page*)page;
    259 	if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
    260 		|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
    261 	{
    262 		return FALSE;
    263 	}
    264 	CPDF_PageContentGenerate CG(pPage);
    265 	CG.GenerateContent();
    266 
    267 	return TRUE;
    268 }
    269 
    270 DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
    271 			 double a, double b, double c, double d, double e, double f)
    272 {
    273 	CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
    274 	if(pPageObj == NULL)
    275 		return;
    276 	CFX_AffineMatrix matrix((FX_FLOAT)a,(FX_FLOAT)b,(FX_FLOAT)c,(FX_FLOAT)d,(FX_FLOAT)e,(FX_FLOAT)f);
    277 	pPageObj->Transform(matrix);
    278 }
    279 DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
    280 											   double a, double b, double c, double d, double e, double f)
    281 {
    282 	if(page == NULL)
    283 		return;
    284 	CPDF_Page* pPage = (CPDF_Page*)page;
    285 	CPDF_AnnotList AnnotList(pPage);
    286 	for (int i=0; i<AnnotList.Count();i++)
    287 	{
    288 		CPDF_Annot* pAnnot = AnnotList.GetAt(i);
    289 		// transformAnnots Rectangle
    290 		CPDF_Rect rect;
    291 		pAnnot->GetRect(rect);
    292 		CFX_AffineMatrix matrix((FX_FLOAT)a,(FX_FLOAT)b,(FX_FLOAT)c,(FX_FLOAT)d,(FX_FLOAT)e,(FX_FLOAT)f);
    293 		rect.Transform(&matrix);
    294 		CPDF_Array *pRectArray = NULL;
    295 		pRectArray = pAnnot->m_pAnnotDict->GetArray("Rect");
    296 		if (!pRectArray) pRectArray=CPDF_Array::Create();
    297 		pRectArray->SetAt(0, new CPDF_Number(rect.left));
    298 		pRectArray->SetAt(1, new CPDF_Number(rect.bottom));
    299 		pRectArray->SetAt(2, new CPDF_Number(rect.right));
    300 		pRectArray->SetAt(3, new CPDF_Number(rect.top));
    301 		pAnnot->m_pAnnotDict->SetAt("Rect",pRectArray);
    302 
    303 		//Transform AP's rectangle
    304 		//To Do
    305 	}
    306 
    307 }
    308 
    309 DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate)
    310 {
    311 	CPDF_Page* pPage = (CPDF_Page*)page;
    312 	if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
    313 		|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
    314 	{
    315 		return;
    316 	}
    317 	CPDF_Dictionary* pDict = pPage->m_pFormDict;
    318 	rotate %=4;
    319 
    320 	pDict->SetAt("Rotate", new CPDF_Number(rotate * 90));
    321 }
    322