diff options
Diffstat (limited to 'fpdfsdk/src/fpdfeditpage.cpp')
-rw-r--r-- | fpdfsdk/src/fpdfeditpage.cpp | 562 |
1 files changed, 284 insertions, 278 deletions
diff --git a/fpdfsdk/src/fpdfeditpage.cpp b/fpdfsdk/src/fpdfeditpage.cpp index 12c2cce1e2..0219c9ca7e 100644 --- a/fpdfsdk/src/fpdfeditpage.cpp +++ b/fpdfsdk/src/fpdfeditpage.cpp @@ -7,315 +7,321 @@ #include "../../public/fpdf_edit.h" #include "../include/fsdk_define.h" - #if _FX_OS_ == _FX_ANDROID_ #include "time.h" #else #include <ctime> #endif -DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() -{ - CPDF_Document* pDoc = new CPDF_Document; - pDoc->CreateNewDoc(); - time_t currentTime; - - CFX_ByteString DateStr; - - if(FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) - { - if ( -1 != time( ¤tTime ) ) - { - tm * pTM = localtime( ¤tTime ); - if ( pTM ) - { - DateStr.Format( "D:%04d%02d%02d%02d%02d%02d", pTM->tm_year+1900, pTM->tm_mon+1, - pTM->tm_mday, pTM->tm_hour, pTM->tm_min, pTM->tm_sec ); - } - } - } - - CPDF_Dictionary* pInfoDict = NULL; - pInfoDict = pDoc->GetInfo(); - if (pInfoDict) - { - if(FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) - pInfoDict->SetAt("CreationDate", new CPDF_String(DateStr)); - pInfoDict->SetAt("Creator", new CPDF_String(L"PDFium")); - } - - return pDoc; +DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() { + CPDF_Document* pDoc = new CPDF_Document; + pDoc->CreateNewDoc(); + time_t currentTime; + + CFX_ByteString DateStr; + + if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) { + if (-1 != time(¤tTime)) { + tm* pTM = localtime(¤tTime); + if (pTM) { + DateStr.Format("D:%04d%02d%02d%02d%02d%02d", pTM->tm_year + 1900, + pTM->tm_mon + 1, pTM->tm_mday, pTM->tm_hour, pTM->tm_min, + pTM->tm_sec); + } + } + } + + CPDF_Dictionary* pInfoDict = NULL; + pInfoDict = pDoc->GetInfo(); + if (pInfoDict) { + if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) + pInfoDict->SetAt("CreationDate", new CPDF_String(DateStr)); + pInfoDict->SetAt("Creator", new CPDF_String(L"PDFium")); + } + + return pDoc; } -DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index) -{ - CPDF_Document* pDoc = (CPDF_Document*)document; - if (pDoc == NULL) - return; - if (page_index < 0 || page_index >= pDoc->GetPageCount()) - return; +DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index) { + CPDF_Document* pDoc = (CPDF_Document*)document; + if (pDoc == NULL) + return; + if (page_index < 0 || page_index >= pDoc->GetPageCount()) + return; - pDoc->DeletePage(page_index); + pDoc->DeletePage(page_index); } -DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height) -{ - if (!document) - return NULL; - -// CPDF_Parser* pParser = (CPDF_Parser*)document; - CPDF_Document* pDoc = (CPDF_Document*)document; - if(page_index < 0) - page_index = 0; - if(pDoc->GetPageCount()<page_index) - page_index = pDoc->GetPageCount(); -// if (page_index < 0 || page_index >= pDoc->GetPageCount()) -// return NULL; - - CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index); - if(!pPageDict) - return NULL; - CPDF_Array* pMediaBoxArray = new CPDF_Array; - pMediaBoxArray->Add(new CPDF_Number(0)); - pMediaBoxArray->Add(new CPDF_Number(0)); - pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width))); - pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height))); - - pPageDict->SetAt("MediaBox", pMediaBoxArray); - pPageDict->SetAt("Rotate", new CPDF_Number(0)); - pPageDict->SetAt("Resources", new CPDF_Dictionary); - - CPDF_Page* pPage = new CPDF_Page; - pPage->Load(pDoc,pPageDict); - pPage->ParseContent(); - - return pPage; +DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, + int page_index, + double width, + double height) { + if (!document) + return NULL; + + // CPDF_Parser* pParser = (CPDF_Parser*)document; + CPDF_Document* pDoc = (CPDF_Document*)document; + if (page_index < 0) + page_index = 0; + if (pDoc->GetPageCount() < page_index) + page_index = pDoc->GetPageCount(); + // if (page_index < 0 || page_index >= pDoc->GetPageCount()) + // return NULL; + + CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index); + if (!pPageDict) + return NULL; + CPDF_Array* pMediaBoxArray = new CPDF_Array; + pMediaBoxArray->Add(new CPDF_Number(0)); + pMediaBoxArray->Add(new CPDF_Number(0)); + pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width))); + pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height))); + + pPageDict->SetAt("MediaBox", pMediaBoxArray); + pPageDict->SetAt("Rotate", new CPDF_Number(0)); + pPageDict->SetAt("Resources", new CPDF_Dictionary); + + CPDF_Page* pPage = new CPDF_Page; + pPage->Load(pDoc, pPageDict); + pPage->ParseContent(); + + return pPage; } -DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) -{ - CPDF_Page* pPage = (CPDF_Page*)page; - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect() - || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page")) - { - return -1; - } - CPDF_Dictionary* pDict = pPage->m_pFormDict; - - int rotate = 0; - if(pDict != NULL) - { - if (pDict->KeyExist("Rotate")) - rotate = pDict->GetElement("Rotate")->GetDirect()? pDict->GetElement("Rotate")->GetDirect()->GetInteger() / 90 : 0; - else - { - if(pDict->KeyExist("Parent")) - { - CPDF_Dictionary* pPages = (CPDF_Dictionary*)pDict->GetElement("Parent")->GetDirect(); - while(pPages) - { - if(pPages->KeyExist("Rotate")) - { - rotate = pPages->GetElement("Rotate")->GetDirect()? pPages->GetElement("Rotate")->GetDirect()->GetInteger() / 90 : 0; - break; - } - else if(pPages->KeyExist("Parent")) - pPages = (CPDF_Dictionary*)pPages->GetElement("Parent")->GetDirect(); - else break; - } - } - } - } - else - { - return -1; - } - - return rotate; +DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) { + CPDF_Page* pPage = (CPDF_Page*)page; + if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || + !pPage->m_pFormDict->GetElement("Type")->GetDirect() || + pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare( + "Page")) { + return -1; + } + CPDF_Dictionary* pDict = pPage->m_pFormDict; + + int rotate = 0; + if (pDict != NULL) { + if (pDict->KeyExist("Rotate")) + rotate = pDict->GetElement("Rotate")->GetDirect() + ? pDict->GetElement("Rotate")->GetDirect()->GetInteger() / 90 + : 0; + else { + if (pDict->KeyExist("Parent")) { + CPDF_Dictionary* pPages = + (CPDF_Dictionary*)pDict->GetElement("Parent")->GetDirect(); + while (pPages) { + if (pPages->KeyExist("Rotate")) { + rotate = + pPages->GetElement("Rotate")->GetDirect() + ? pPages->GetElement("Rotate")->GetDirect()->GetInteger() / + 90 + : 0; + break; + } else if (pPages->KeyExist("Parent")) + pPages = + (CPDF_Dictionary*)pPages->GetElement("Parent")->GetDirect(); + else + break; + } + } + } + } else { + return -1; + } + + return rotate; } -DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_obj) -{ - CPDF_Page* pPage = (CPDF_Page*)page; - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect() - || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page")) - { - return; - } - CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj; - if(pPageObj == NULL) - return; - FX_POSITION LastPersition = pPage->GetLastObjectPosition(); - - pPage->InsertObject(LastPersition, pPageObj); - switch(pPageObj->m_Type) - { - case FPDF_PAGEOBJ_PATH: - { - CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj; - pPathObj->CalcBoundingBox(); - break; - } - case FPDF_PAGEOBJ_TEXT: - { - // CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj; - // pPathObj->CalcBoundingBox(); - break; - } - case FPDF_PAGEOBJ_IMAGE: - { - CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pPageObj; - pImageObj->CalcBoundingBox(); - break; - } - case FPDF_PAGEOBJ_SHADING: - { - CPDF_ShadingObject* pShadingObj = (CPDF_ShadingObject*)pPageObj; - pShadingObj->CalcBoundingBox(); - break; - } - case FPDF_PAGEOBJ_FORM: - { - CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj; - pFormObj->CalcBoundingBox(); - break; - } - default: - break; - } - - // pPage->ParseContent(); - //pPage->GenerateContent(); - +DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, + FPDF_PAGEOBJECT page_obj) { + CPDF_Page* pPage = (CPDF_Page*)page; + if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || + !pPage->m_pFormDict->GetElement("Type")->GetDirect() || + pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare( + "Page")) { + return; + } + CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj; + if (pPageObj == NULL) + return; + FX_POSITION LastPersition = pPage->GetLastObjectPosition(); + + pPage->InsertObject(LastPersition, pPageObj); + switch (pPageObj->m_Type) { + case FPDF_PAGEOBJ_PATH: { + CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj; + pPathObj->CalcBoundingBox(); + break; + } + case FPDF_PAGEOBJ_TEXT: { + // CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj; + // pPathObj->CalcBoundingBox(); + break; + } + case FPDF_PAGEOBJ_IMAGE: { + CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pPageObj; + pImageObj->CalcBoundingBox(); + break; + } + case FPDF_PAGEOBJ_SHADING: { + CPDF_ShadingObject* pShadingObj = (CPDF_ShadingObject*)pPageObj; + pShadingObj->CalcBoundingBox(); + break; + } + case FPDF_PAGEOBJ_FORM: { + CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj; + pFormObj->CalcBoundingBox(); + break; + } + default: + break; + } + + // pPage->ParseContent(); + // pPage->GenerateContent(); } -DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page) -{ - CPDF_Page* pPage = (CPDF_Page*)page; - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect() - || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page")) - { - return -1; - } - return pPage->CountObjects(); -// return 0; +DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page) { + CPDF_Page* pPage = (CPDF_Page*)page; + if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || + !pPage->m_pFormDict->GetElement("Type")->GetDirect() || + pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare( + "Page")) { + return -1; + } + return pPage->CountObjects(); + // return 0; } -DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, int index) -{ - CPDF_Page* pPage = (CPDF_Page*)page; - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") - || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page")) - { - return NULL; - } - return pPage->GetObjectByIndex(index); -// return NULL; +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, + int index) { + CPDF_Page* pPage = (CPDF_Page*)page; + if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || + pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare( + "Page")) { + return NULL; + } + return pPage->GetObjectByIndex(index); + // return NULL; } -DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page) -{ - if(!page) return FALSE; - CPDF_Page* pPage = (CPDF_Page*)page; +DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page) { + if (!page) + return FALSE; + CPDF_Page* pPage = (CPDF_Page*)page; - return pPage->BackgroundAlphaNeeded(); + return pPage->BackgroundAlphaNeeded(); } -DLLEXPORT FPDF_BOOL STDCALL FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) -{ - if(!pageObject) return FALSE; - CPDF_PageObject* pPageObj = (CPDF_PageObject*)pageObject; - - const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState; - int blend_type = pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL; - if (blend_type != FXDIB_BLEND_NORMAL) return TRUE; - - CPDF_Dictionary* pSMaskDict = pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL; - if(pSMaskDict) return TRUE; - - if(pGeneralState && pGeneralState->m_FillAlpha != 1.0f) - return TRUE; - - if(pPageObj->m_Type == PDFPAGE_PATH) - { - if(pGeneralState && pGeneralState->m_StrokeAlpha != 1.0f) - return TRUE; - } - - if(pPageObj->m_Type == PDFPAGE_FORM) - { - CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj; - if(pFormObj->m_pForm && (pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED)) - return TRUE; - if(pFormObj->m_pForm && (!(pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED) && (pFormObj->m_pForm->m_Transparency & PDFTRANS_GROUP))) - return TRUE; - } - return FALSE; +DLLEXPORT FPDF_BOOL STDCALL +FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) { + if (!pageObject) + return FALSE; + CPDF_PageObject* pPageObj = (CPDF_PageObject*)pageObject; + + const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState; + int blend_type = + pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL; + if (blend_type != FXDIB_BLEND_NORMAL) + return TRUE; + + CPDF_Dictionary* pSMaskDict = + pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL; + if (pSMaskDict) + return TRUE; + + if (pGeneralState && pGeneralState->m_FillAlpha != 1.0f) + return TRUE; + + if (pPageObj->m_Type == PDFPAGE_PATH) { + if (pGeneralState && pGeneralState->m_StrokeAlpha != 1.0f) + return TRUE; + } + + if (pPageObj->m_Type == PDFPAGE_FORM) { + CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj; + if (pFormObj->m_pForm && + (pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED)) + return TRUE; + if (pFormObj->m_pForm && + (!(pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED) && + (pFormObj->m_pForm->m_Transparency & PDFTRANS_GROUP))) + return TRUE; + } + return FALSE; } -DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page) -{ - CPDF_Page* pPage = (CPDF_Page*)page; - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect() - || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page")) - { - return FALSE; - } - CPDF_PageContentGenerate CG(pPage); - CG.GenerateContent(); - - return TRUE; +DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page) { + CPDF_Page* pPage = (CPDF_Page*)page; + if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || + !pPage->m_pFormDict->GetElement("Type")->GetDirect() || + pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare( + "Page")) { + return FALSE; + } + CPDF_PageContentGenerate CG(pPage); + CG.GenerateContent(); + + return TRUE; } DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object, - double a, double b, double c, double d, double e, double f) -{ - CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object; - if(pPageObj == NULL) - return; - CFX_AffineMatrix matrix((FX_FLOAT)a,(FX_FLOAT)b,(FX_FLOAT)c,(FX_FLOAT)d,(FX_FLOAT)e,(FX_FLOAT)f); - pPageObj->Transform(matrix); + double a, + double b, + double c, + double d, + double e, + double f) { + CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object; + if (pPageObj == NULL) + return; + CFX_AffineMatrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d, + (FX_FLOAT)e, (FX_FLOAT)f); + pPageObj->Transform(matrix); } DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page, - double a, double b, double c, double d, double e, double f) -{ - if(page == NULL) - return; - CPDF_Page* pPage = (CPDF_Page*)page; - CPDF_AnnotList AnnotList(pPage); - for (int i=0; i<AnnotList.Count();i++) - { - CPDF_Annot* pAnnot = AnnotList.GetAt(i); - // transformAnnots Rectangle - CPDF_Rect rect; - pAnnot->GetRect(rect); - CFX_AffineMatrix matrix((FX_FLOAT)a,(FX_FLOAT)b,(FX_FLOAT)c,(FX_FLOAT)d,(FX_FLOAT)e,(FX_FLOAT)f); - rect.Transform(&matrix); - CPDF_Array *pRectArray = NULL; - pRectArray = pAnnot->GetAnnotDict()->GetArray("Rect"); - if (!pRectArray) pRectArray=CPDF_Array::Create(); - pRectArray->SetAt(0, new CPDF_Number(rect.left)); - pRectArray->SetAt(1, new CPDF_Number(rect.bottom)); - pRectArray->SetAt(2, new CPDF_Number(rect.right)); - pRectArray->SetAt(3, new CPDF_Number(rect.top)); - pAnnot->GetAnnotDict()->SetAt("Rect",pRectArray); - - //Transform AP's rectangle - //To Do - } - + double a, + double b, + double c, + double d, + double e, + double f) { + if (page == NULL) + return; + CPDF_Page* pPage = (CPDF_Page*)page; + CPDF_AnnotList AnnotList(pPage); + for (int i = 0; i < AnnotList.Count(); i++) { + CPDF_Annot* pAnnot = AnnotList.GetAt(i); + // transformAnnots Rectangle + CPDF_Rect rect; + pAnnot->GetRect(rect); + CFX_AffineMatrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d, + (FX_FLOAT)e, (FX_FLOAT)f); + rect.Transform(&matrix); + CPDF_Array* pRectArray = NULL; + pRectArray = pAnnot->GetAnnotDict()->GetArray("Rect"); + if (!pRectArray) + pRectArray = CPDF_Array::Create(); + pRectArray->SetAt(0, new CPDF_Number(rect.left)); + pRectArray->SetAt(1, new CPDF_Number(rect.bottom)); + pRectArray->SetAt(2, new CPDF_Number(rect.right)); + pRectArray->SetAt(3, new CPDF_Number(rect.top)); + pAnnot->GetAnnotDict()->SetAt("Rect", pRectArray); + + // Transform AP's rectangle + // To Do + } } -DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate) -{ - CPDF_Page* pPage = (CPDF_Page*)page; - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect() - || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page")) - { - return; - } - CPDF_Dictionary* pDict = pPage->m_pFormDict; - rotate %=4; - - pDict->SetAt("Rotate", new CPDF_Number(rotate * 90)); +DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate) { + CPDF_Page* pPage = (CPDF_Page*)page; + if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || + !pPage->m_pFormDict->GetElement("Type")->GetDirect() || + pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare( + "Page")) { + return; + } + CPDF_Dictionary* pDict = pPage->m_pFormDict; + rotate %= 4; + + pDict->SetAt("Rotate", new CPDF_Number(rotate * 90)); } |