Chromium Code Reviews| Index: fpdfsdk/fpdfeditpage.cpp |
| diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp |
| index 0d0dac4964d2df7b9681fdd366407fa28ec913f7..0daa45903746fc525a07008a8eece9591e1d34f3 100644 |
| --- a/fpdfsdk/fpdfeditpage.cpp |
| +++ b/fpdfsdk/fpdfeditpage.cpp |
| @@ -6,6 +6,10 @@ |
| #include "public/fpdf_edit.h" |
| +#include <algorithm> |
| +#include <memory> |
| +#include <utility> |
| + |
| #include "core/fpdfapi/fpdf_edit/include/cpdf_pagecontentgenerator.h" |
| #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" |
| #include "core/fpdfapi/fpdf_page/include/cpdf_formobject.h" |
| @@ -37,6 +41,29 @@ |
| #include <ctime> |
| #endif |
| +namespace { |
| + |
| +static_assert(FPDF_PAGEOBJ_TEXT == CPDF_PageObject::TEXT, |
| + "FPDF_PAGEOBJ_TEXT/CPDF_PageObject::TEXT mismatch"); |
| +static_assert(FPDF_PAGEOBJ_PATH == CPDF_PageObject::PATH, |
| + "FPDF_PAGEOBJ_PATH/CPDF_PageObject::PATH mismatch"); |
| +static_assert(FPDF_PAGEOBJ_IMAGE == CPDF_PageObject::IMAGE, |
| + "FPDF_PAGEOBJ_IMAGE/CPDF_PageObject::IMAGE mismatch"); |
| +static_assert(FPDF_PAGEOBJ_SHADING == CPDF_PageObject::SHADING, |
| + "FPDF_PAGEOBJ_SHADING/CPDF_PageObject::SHADING mismatch"); |
| +static_assert(FPDF_PAGEOBJ_FORM == CPDF_PageObject::FORM, |
| + "FPDF_PAGEOBJ_FORM/CPDF_PageObject::FORM mismatch"); |
| + |
| +bool IsPageObject(CPDF_Page* pPage) { |
| + if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type")) |
| + return false; |
| + |
| + CPDF_Object* pObject = pPage->m_pFormDict->GetObjectBy("Type")->GetDirect(); |
| + return pObject && !pObject->GetString().Compare("Page"); |
| +} |
| + |
| +} // namespace |
| + |
| DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() { |
| CPDF_Document* pDoc = new CPDF_Document(nullptr); |
| pDoc->CreateNewDoc(); |
| @@ -79,14 +106,11 @@ DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, |
| if (!pDoc) |
| return nullptr; |
| - if (page_index < 0) |
| - page_index = 0; |
| - if (pDoc->GetPageCount() < page_index) |
| - page_index = pDoc->GetPageCount(); |
| - |
| + page_index = std::min(std::max(page_index, 0), pDoc->GetPageCount()); |
| CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index); |
| if (!pPageDict) |
| return nullptr; |
| + |
| CPDF_Array* pMediaBoxArray = new CPDF_Array; |
| pMediaBoxArray->Add(new CPDF_Number(0)); |
| pMediaBoxArray->Add(new CPDF_Number(0)); |
| @@ -111,16 +135,10 @@ DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, |
| DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) { |
| CPDF_Page* pPage = CPDFPageFromFPDFPage(page); |
| - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || |
| - !pPage->m_pFormDict->GetObjectBy("Type")->GetDirect() || |
| - pPage->m_pFormDict->GetObjectBy("Type")->GetDirect()->GetString().Compare( |
| - "Page")) { |
| - return -1; |
| - } |
| - CPDF_Dictionary* pDict = pPage->m_pFormDict; |
| - if (!pDict) |
| + if (!IsPageObject(pPage)) |
| return -1; |
| + CPDF_Dictionary* pDict = pPage->m_pFormDict; |
| while (pDict) { |
| if (pDict->KeyExist("Rotate")) { |
| CPDF_Object* pRotateObj = pDict->GetObjectBy("Rotate")->GetDirect(); |
| @@ -137,68 +155,59 @@ DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) { |
| DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, |
| FPDF_PAGEOBJECT page_obj) { |
| - CPDF_Page* pPage = CPDFPageFromFPDFPage(page); |
| - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || |
| - !pPage->m_pFormDict->GetObjectBy("Type")->GetDirect() || |
| - pPage->m_pFormDict->GetObjectBy("Type")->GetDirect()->GetString().Compare( |
| - "Page")) { |
| - return; |
| - } |
| - CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj; |
| + CPDF_PageObject* pPageObj = reinterpret_cast<CPDF_PageObject*>(page_obj); |
| if (!pPageObj) |
| return; |
| - pPage->GetPageObjectList()->push_back( |
| - std::unique_ptr<CPDF_PageObject>(pPageObj)); |
| + std::unique_ptr<CPDF_PageObject> pPageObjHolder(pPageObj); |
|
dsinclair
2016/07/29 13:22:49
Move this down to 167 where it is first used? No p
Lei Zhang
2016/07/29 14:46:15
FPDFPage_InsertObject() has ownership of |page_obj
|
| + CPDF_Page* pPage = CPDFPageFromFPDFPage(page); |
| + if (!IsPageObject(pPage)) |
| + return; |
| + pPage->GetPageObjectList()->push_back(std::move(pPageObjHolder)); |
| switch (pPageObj->GetType()) { |
| - case FPDF_PAGEOBJ_PATH: { |
| - CPDF_PathObject* pPathObj = pPageObj->AsPath(); |
| - pPathObj->CalcBoundingBox(); |
| + case CPDF_PageObject::TEXT: { |
| break; |
| } |
| - case FPDF_PAGEOBJ_TEXT: { |
| + case CPDF_PageObject::PATH: { |
| + CPDF_PathObject* pPathObj = pPageObj->AsPath(); |
| + pPathObj->CalcBoundingBox(); |
| break; |
| } |
| - case FPDF_PAGEOBJ_IMAGE: { |
| + case CPDF_PageObject::IMAGE: { |
| CPDF_ImageObject* pImageObj = pPageObj->AsImage(); |
| pImageObj->CalcBoundingBox(); |
| break; |
| } |
| - case FPDF_PAGEOBJ_SHADING: { |
| + case CPDF_PageObject::SHADING: { |
| CPDF_ShadingObject* pShadingObj = pPageObj->AsShading(); |
| pShadingObj->CalcBoundingBox(); |
| break; |
| } |
| - case FPDF_PAGEOBJ_FORM: { |
| + case CPDF_PageObject::FORM: { |
| CPDF_FormObject* pFormObj = pPageObj->AsForm(); |
| pFormObj->CalcBoundingBox(); |
| break; |
| } |
| - default: |
| + default: { |
| + ASSERT(false); |
| break; |
| + } |
| } |
| } |
| DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page) { |
| CPDF_Page* pPage = CPDFPageFromFPDFPage(page); |
| - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || |
| - !pPage->m_pFormDict->GetObjectBy("Type")->GetDirect() || |
| - pPage->m_pFormDict->GetObjectBy("Type")->GetDirect()->GetString().Compare( |
| - "Page")) { |
| + if (!IsPageObject(pPage)) |
| return -1; |
| - } |
| return pdfium::CollectionSize<int>(*pPage->GetPageObjectList()); |
| } |
| DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, |
| int index) { |
| CPDF_Page* pPage = CPDFPageFromFPDFPage(page); |
| - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || |
| - pPage->m_pFormDict->GetObjectBy("Type")->GetDirect()->GetString().Compare( |
| - "Page")) { |
| + if (!IsPageObject(pPage)) |
| return nullptr; |
| - } |
| return pPage->GetPageObjectList()->GetPageObjectByIndex(index); |
| } |
| @@ -211,8 +220,8 @@ DLLEXPORT FPDF_BOOL STDCALL |
| FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) { |
| if (!pageObject) |
| return FALSE; |
| - CPDF_PageObject* pPageObj = (CPDF_PageObject*)pageObject; |
| + CPDF_PageObject* pPageObj = reinterpret_cast<CPDF_PageObject*>(pageObject); |
| const CPDF_GeneralStateData* pGeneralState = |
| pPageObj->m_GeneralState.GetObject(); |
| int blend_type = |
| @@ -228,35 +237,30 @@ FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) { |
| if (pGeneralState && pGeneralState->m_FillAlpha != 1.0f) |
| return TRUE; |
| - if (pPageObj->IsPath()) { |
| - if (pGeneralState && pGeneralState->m_StrokeAlpha != 1.0f) |
| - return TRUE; |
| + if (pPageObj->IsPath() && pGeneralState && |
| + pGeneralState->m_StrokeAlpha != 1.0f) { |
| + return TRUE; |
| } |
| if (pPageObj->IsForm()) { |
| - CPDF_FormObject* pFormObj = pPageObj->AsForm(); |
| - 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; |
| + const CPDF_Form* pForm = pPageObj->AsForm()->form(); |
| + if (pForm) { |
| + int trans = pForm->m_Transparency; |
| + if ((trans & PDFTRANS_ISOLATED) || (trans & PDFTRANS_GROUP)) |
| + return TRUE; |
| + } |
| } |
| + |
| return FALSE; |
| } |
| DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page) { |
| CPDF_Page* pPage = CPDFPageFromFPDFPage(page); |
| - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || |
| - !pPage->m_pFormDict->GetObjectBy("Type")->GetDirect() || |
| - pPage->m_pFormDict->GetObjectBy("Type")->GetDirect()->GetString().Compare( |
| - "Page")) { |
| + if (!IsPageObject(pPage)) |
| return FALSE; |
| - } |
| + |
| CPDF_PageContentGenerator CG(pPage); |
| CG.GenerateContent(); |
| - |
| return TRUE; |
| } |
| @@ -267,7 +271,7 @@ DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object, |
| double d, |
| double e, |
| double f) { |
| - CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object; |
| + CPDF_PageObject* pPageObj = reinterpret_cast<CPDF_PageObject*>(page_object); |
| if (!pPageObj) |
| return; |
| @@ -275,6 +279,7 @@ DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object, |
| (FX_FLOAT)e, (FX_FLOAT)f); |
| pPageObj->Transform(matrix); |
| } |
| + |
| DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page, |
| double a, |
| double b, |
| @@ -285,6 +290,7 @@ DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page, |
| CPDF_Page* pPage = CPDFPageFromFPDFPage(page); |
| if (!pPage) |
| return; |
| + |
| CPDF_AnnotList AnnotList(pPage); |
| for (size_t i = 0; i < AnnotList.Count(); ++i) { |
| CPDF_Annot* pAnnot = AnnotList.GetAt(i); |
| @@ -310,14 +316,10 @@ DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page, |
| DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate) { |
| CPDF_Page* pPage = CPDFPageFromFPDFPage(page); |
| - if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || |
| - !pPage->m_pFormDict->GetObjectBy("Type")->GetDirect() || |
| - pPage->m_pFormDict->GetObjectBy("Type")->GetDirect()->GetString().Compare( |
| - "Page")) { |
| + if (!IsPageObject(pPage)) |
| return; |
| - } |
| + |
| CPDF_Dictionary* pDict = pPage->m_pFormDict; |
| rotate %= 4; |
| - |
| pDict->SetAt("Rotate", new CPDF_Number(rotate * 90)); |
| } |