external/pdfium/edit.patch.1 | 382 ++++++++++++++++++++++++++++++++--- sd/source/filter/pdf/sdpdffilter.cxx | 3 svx/source/svdraw/svdpdf.cxx | 260 ++++++++++++++--------- svx/source/svdraw/svdpdf.hxx | 13 - vcl/source/gdi/impgraph.cxx | 4 5 files changed, 524 insertions(+), 138 deletions(-)
New commits: commit a0565df5d7592d47b73cfd44f2caadcb9dd5285b Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun Apr 15 21:56:49 2018 -0400 svx: support importing forms from PDFs Still missing the context matrix transformations. Change-Id: Id9457c6475463127d3bc444f36fa373a6ec8fcb6 diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1 index 02e0b44c3e87..09f609320169 100644 --- a/external/pdfium/edit.patch.1 +++ b/external/pdfium/edit.patch.1 @@ -110,6 +110,31 @@ index 8bb5bf5..9b5e2ce 100644 + fprintf(stderr, "PageObject BB: %f, %f, %f, %f\n", rc.left, rc.right, rc.top, rc.bottom); return rect.GetOuterRect(); } +diff --git a/core/fpdfapi/page/cpdf_pageobjectlist.cpp b/core/fpdfapi/page/cpdf_pageobjectlist.cpp +index afd2c98..2c8e061 100644 +--- a/core/fpdfapi/page/cpdf_pageobjectlist.cpp ++++ b/core/fpdfapi/page/cpdf_pageobjectlist.cpp +@@ -8,6 +8,6 @@ + + #include "third_party/base/stl_util.h" + +-CPDF_PageObject* CPDF_PageObjectList::GetPageObjectByIndex(int index) { ++CPDF_PageObject* CPDF_PageObjectList::GetPageObjectByIndex(int index) const { + return pdfium::IndexInBounds(*this, index) ? (*this)[index].get() : nullptr; + } +diff --git a/core/fpdfapi/page/cpdf_pageobjectlist.h b/core/fpdfapi/page/cpdf_pageobjectlist.h +index b450537..77c7d81 100644 +--- a/core/fpdfapi/page/cpdf_pageobjectlist.h ++++ b/core/fpdfapi/page/cpdf_pageobjectlist.h +@@ -15,7 +15,7 @@ class CPDF_PageObject; + class CPDF_PageObjectList + : public std::deque<std::unique_ptr<CPDF_PageObject>> { + public: +- CPDF_PageObject* GetPageObjectByIndex(int index); ++ CPDF_PageObject* GetPageObjectByIndex(int index) const; + }; + + #endif // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTLIST_H_ diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 0a01ae0..6947e3a 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -174,7 +199,7 @@ index 0d7ba56..37bdf99 100644 FPDFImageObj_GetImageDataDecoded(FPDF_PAGEOBJECT image_object, void* buffer, diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp -index ca2cf3f..f86201d 100644 +index ca2cf3f..8ecab60 100644 --- a/fpdfsdk/fpdfeditpage.cpp +++ b/fpdfsdk/fpdfeditpage.cpp @@ -11,12 +11,14 @@ @@ -192,7 +217,7 @@ index ca2cf3f..f86201d 100644 #include "core/fpdfapi/page/cpdf_shadingobject.h" #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_document.h" -@@ -363,3 +365,157 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject, +@@ -363,3 +365,187 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject, *top = bbox.top; return true; } @@ -350,6 +375,36 @@ index ca2cf3f..f86201d 100644 + + return true; +} ++ ++FPDF_EXPORT int FPDF_CALLCONV ++FPDFFormObj_CountSubObjects(FPDF_PAGEOBJECT form_object) ++{ ++ CPDF_FormObject* pFrmObj = CPDFFormObjectFromFPDFPageObject(form_object); ++ if (pFrmObj) ++ { ++ const CPDF_PageObjectList* pObjectList = pFrmObj->form()->GetPageObjectList(); ++ if (pObjectList) ++ return pObjectList->size(); ++ } ++ ++ return 0; ++} ++ ++FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV ++FPDFFormObj_GetSubObject(FPDF_PAGEOBJECT form_object, int index) ++{ ++ CPDF_FormObject* pFrmObj = CPDFFormObjectFromFPDFPageObject(form_object); ++ if (pFrmObj) ++ { ++ const CFX_Matrix& matrix = pFrmObj->form_matrix(); ++ fprintf(stderr, "Form matrix a: %f, b: %f, c: %f, d: %f, e: %f, f: %f\n", matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f); ++ const CPDF_PageObjectList* pObjectList = pFrmObj->form()->GetPageObjectList(); ++ if (pObjectList) ++ return pObjectList->GetPageObjectByIndex(index); ++ } ++ ++ return nullptr; ++} diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp index a291987..0202284 100644 --- a/fpdfsdk/fpdfeditpath.cpp @@ -462,10 +517,10 @@ index 68bf4f8..e073b20 100644 int index, double* left, diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp -index e890aa0..709bea3 100644 +index e890aa0..b62283f 100644 --- a/fpdfsdk/fpdfview.cpp +++ b/fpdfsdk/fpdfview.cpp -@@ -336,6 +336,11 @@ CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) { +@@ -336,6 +336,16 @@ CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) { #endif // PDF_ENABLE_XFA } @@ -474,32 +529,40 @@ index e890aa0..709bea3 100644 + return obj ? obj->AsText() : nullptr; +} + ++CPDF_FormObject* CPDFFormObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) { ++ auto* obj = CPDFPageObjectFromFPDFPageObject(page_object); ++ return obj ? obj->AsForm() : nullptr; ++} ++ CPDF_PathObject* CPDFPathObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) { auto* obj = CPDFPageObjectFromFPDFPageObject(page_object); return obj ? obj->AsPath() : nullptr; diff --git a/fpdfsdk/fsdk_define.h b/fpdfsdk/fsdk_define.h -index 77c2315..db3e734 100644 +index 77c2315..b61f447 100644 --- a/fpdfsdk/fsdk_define.h +++ b/fpdfsdk/fsdk_define.h -@@ -25,6 +25,7 @@ class CPDF_Annot; +@@ -25,6 +25,8 @@ class CPDF_Annot; class CPDF_Page; class CPDF_PageObject; class CPDF_PageRenderContext; +class CPDF_TextObject; ++class CPDF_FormObject; class CPDF_PathObject; class CPDF_Stream; class IFSDK_PAUSE_Adapter; -@@ -65,6 +66,8 @@ FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc); +@@ -65,6 +67,10 @@ FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc); CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page); +CPDF_TextObject* CPDFTextObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); + ++CPDF_FormObject* CPDFFormObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); ++ CPDF_PathObject* CPDFPathObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h -index 54735a3..c0231c2 100644 +index 54735a3..1b933bb 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path, @@ -555,7 +618,7 @@ index 54735a3..c0231c2 100644 // Create a new text object using one of the standard PDF fonts. // // document - handle to the document. -@@ -761,6 +800,77 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document, +@@ -761,6 +800,94 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document, FPDF_FONT font, float font_size); @@ -630,6 +693,23 @@ index 54735a3..c0231c2 100644 + unsigned int* B, + unsigned int* A); + ++// Get number of page objects inside the form object. ++// ++// form_object - Handle to a form object. Returned by FPDFPage_GetObject. ++// Return value: ++// The number of the page objects. ++FPDF_EXPORT int FPDF_CALLCONV ++FPDFFormObj_CountSubObjects(FPDF_PAGEOBJECT form_object); ++ ++// Get the page object from a form object. ++// ++// form_object - Handle to a form object. Returned by FPDFPage_GetObject. ++// index - The index of a page object. ++// Return value: ++// The handle of the page object. Null for failed. ++FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV ++FPDFFormObj_GetSubObject(FPDF_PAGEOBJECT form_object, int index); ++ #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 58568666bf5a..c1e9734a5d8e 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -229,32 +229,7 @@ void ImpSdrPdfImport::DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pAc for (int nPageObjectIndex = 0; nPageObjectIndex < nPageObjectCount; ++nPageObjectIndex) { FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(pPdfPage, nPageObjectIndex); - if (pPageObject == nullptr) - continue; - - const int nPageObjectType = FPDFPageObj_GetType(pPageObject); - switch (nPageObjectType) - { - case FPDF_PAGEOBJ_TEXT: - ImportText(pPageObject, nPageObjectIndex); - break; - case FPDF_PAGEOBJ_PATH: - ImportPath(pPageObject, nPageObjectIndex); - break; - case FPDF_PAGEOBJ_IMAGE: - ImportImage(pPageObject, nPageObjectIndex); - break; - case FPDF_PAGEOBJ_SHADING: - SAL_WARN("sd.filter", "Got page object SHADING: " << nPageObjectIndex); - break; - case FPDF_PAGEOBJ_FORM: - SAL_WARN("sd.filter", "Got page object FORM: " << nPageObjectIndex); - break; - default: - SAL_WARN("sd.filter", "Unknown PDF page object type: " - << nPageObjectType << ": " << nPageObjectIndex); - break; - } + ImportPdfObject(pPageObject, nPageObjectIndex); } #if 0 @@ -1015,6 +990,49 @@ void ImpSdrPdfImport::checkClip() } bool ImpSdrPdfImport::isClip() const { return !maClip.getB2DRange().isEmpty(); } + +void ImpSdrPdfImport::ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex) +{ + if (pPageObject == nullptr) + return; + + const int nPageObjectType = FPDFPageObj_GetType(pPageObject); + switch (nPageObjectType) + { + case FPDF_PAGEOBJ_TEXT: + ImportText(pPageObject, nPageObjectIndex); + break; + case FPDF_PAGEOBJ_PATH: + ImportPath(pPageObject, nPageObjectIndex); + break; + case FPDF_PAGEOBJ_IMAGE: + ImportImage(pPageObject, nPageObjectIndex); + break; + case FPDF_PAGEOBJ_SHADING: + SAL_WARN("sd.filter", "Got page object SHADING: " << nPageObjectIndex); + break; + case FPDF_PAGEOBJ_FORM: + ImportForm(pPageObject, nPageObjectIndex); + break; + default: + SAL_WARN("sd.filter", "Unknown PDF page object #" << nPageObjectIndex + << " of type: " << nPageObjectType); + break; + } +} + +void ImpSdrPdfImport::ImportForm(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex) +{ + SAL_WARN("sd.filter", "Got page object FORM: " << nPageObjectIndex); + + const int nCount = FPDFFormObj_CountSubObjects(pPageObject); + for (int nIndex = 0; nIndex < nCount; ++nIndex) + { + FPDF_PAGEOBJECT pFormObject = FPDFFormObj_GetSubObject(pPageObject, nIndex); + ImportPdfObject(pFormObject, -1); + } +} + void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex) { SAL_WARN("sd.filter", "Got page object TEXT: " << nPageObjectIndex); diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx index 2063788290d9..d98f97d8cd09 100644 --- a/svx/source/svdraw/svdpdf.hxx +++ b/svx/source/svdraw/svdpdf.hxx @@ -100,13 +100,14 @@ class ImpSdrPdfImport final void checkClip(); bool isClip() const; + void ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); + void ImportForm(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); void ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); - void SetupPageScale(const double dPageWidth, const double dPageHeight); - void ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); - void ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); void ImportText(const Point& rPos, const Size& rSize, const OUString& rStr); + + void SetupPageScale(const double dPageWidth, const double dPageHeight); void SetAttributes(SdrObject* pObj, bool bForceTextAttr = false); void InsertObj(SdrObject* pObj, bool bScale = true); void MapScaling(); commit d9613326d8ed09899940c1bbfcd01f273fe9c0f5 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun Apr 15 20:32:52 2018 -0400 sd: support breaking any PDF page Change-Id: Ifa5f58163bef209a988fc0f88e2b609b1973e0d4 diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 48ab0641ffcb..58568666bf5a 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -207,16 +207,17 @@ ImpSdrPdfImport::~ImpSdrPdfImport() FPDF_DestroyLibrary(); } -void ImpSdrPdfImport::DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport) +void ImpSdrPdfImport::DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport, + int nPageIndex) { const int nPageCount = FPDF_GetPageCount(mpPdfDocument); - SAL_WARN("sd.filter", "Pages: " << nPageCount); - for (size_t nPageIndex = 0; nPageIndex <= 0; ++nPageIndex) + SAL_WARN("sd.filter", "Importing page " << nPageIndex << " of " << nPageCount); + if (nPageCount > 0 && nPageIndex >= 0 && nPageIndex < nPageCount) { // Render next page. FPDF_PAGE pPdfPage = FPDF_LoadPage(mpPdfDocument, nPageIndex); if (pPdfPage == nullptr) - break; + return; const double dPageWidth = FPDF_GetPageWidth(pPdfPage); const double dPageHeight = FPDF_GetPageHeight(pPdfPage); @@ -482,7 +483,7 @@ void ImpSdrPdfImport::SetupPageScale(const double dPageWidth, const double dPage << "(" << mfScaleY << ")"); } -size_t ImpSdrPdfImport::DoImport(SdrObjList& rOL, size_t nInsPos, size_t nPageNumber, +size_t ImpSdrPdfImport::DoImport(SdrObjList& rOL, size_t nInsPos, int nPageNumber, SvdProgressInfo* pProgrInfo) { if (pProgrInfo) @@ -493,7 +494,7 @@ size_t ImpSdrPdfImport::DoImport(SdrObjList& rOL, size_t nInsPos, size_t nPageNu sal_uInt32 nActionsToReport(0); // execute - DoLoopActions(pProgrInfo, &nActionsToReport); + DoLoopActions(pProgrInfo, &nActionsToReport, nPageNumber); if (pProgrInfo) { diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx index dc62b234a688..2063788290d9 100644 --- a/svx/source/svdraw/svdpdf.hxx +++ b/svx/source/svdraw/svdpdf.hxx @@ -115,7 +115,7 @@ class ImpSdrPdfImport final bool CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly); bool CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon& rPolyPolygon); - void DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport); + void DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport, int nPageIndex); // Copy assignment is forbidden and not implemented. ImpSdrPdfImport(const ImpSdrPdfImport&) = delete; @@ -128,7 +128,7 @@ public: int GetPageCount() const { return mnPageCount; } - size_t DoImport(SdrObjList& rDestList, size_t nInsPos, size_t nPageNumber, + size_t DoImport(SdrObjList& rDestList, size_t nInsPos, int nPageNumber, SvdProgressInfo* pProgrInfo = nullptr); }; diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index efa6420864d4..c2e4d5d21a55 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -120,7 +120,7 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) , mnSizeBytes(rImpGraphic.mnSizeBytes) , mbSwapOut(rImpGraphic.mbSwapOut) , mbDummyContext(rImpGraphic.mbDummyContext) - , mnPageNumber(-1) + , mnPageNumber(rImpGraphic.mnPageNumber) , maVectorGraphicData(rImpGraphic.maVectorGraphicData) , mpPdfData(rImpGraphic.mpPdfData) , msOriginURL(rImpGraphic.msOriginURL) @@ -147,7 +147,7 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) , mnSizeBytes(rImpGraphic.mnSizeBytes) , mbSwapOut(rImpGraphic.mbSwapOut) , mbDummyContext(rImpGraphic.mbDummyContext) - , mnPageNumber(-1) + , mnPageNumber(rImpGraphic.mnPageNumber) , maVectorGraphicData(std::move(rImpGraphic.maVectorGraphicData)) , mpPdfData(std::move(rImpGraphic.mpPdfData)) , msOriginURL(rImpGraphic.msOriginURL) commit 405504b9e902893f254e4f248ee014e1044cf197 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun Apr 15 19:44:12 2018 -0400 sd: pdf: really share the PDF stream Change-Id: I5b25b3532912c7982a6db9dcc80fb7a72a41af38 diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx index 35f2bee5a791..9e180c9ea25f 100644 --- a/sd/source/filter/pdf/sdpdffilter.cxx +++ b/sd/source/filter/pdf/sdpdffilter.cxx @@ -110,6 +110,7 @@ bool SdPdfFilter::Import() std::unique_ptr<sal_uInt8[]> pGraphicContent(new sal_uInt8[nGraphicContentSize]); memcpy(pGraphicContent.get(), aPdfData.get(), nGraphicContentSize); GfxLink aGfxLink(std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf); + auto pPdfData = std::make_shared<uno::Sequence<sal_Int8>>(aPdfData); mrDocument.CreateFirstPages(); for (size_t i = 0; i < aBitmaps.size() - 1; ++i) @@ -122,7 +123,7 @@ bool SdPdfFilter::Import() { // Create the Graphic and link the original PDF stream. Graphic aGraphic(aBitmap); - aGraphic.setPdfData(std::make_shared<uno::Sequence<sal_Int8>>(aPdfData)); + aGraphic.setPdfData(pPdfData); aGraphic.setPageNumber(nPageNumber); aGraphic.SetLink(aGfxLink); commit df1ce94b433f2ff9e3123f5debdc6ba622f23e73 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun Apr 15 11:11:33 2018 -0400 svx: path line width is given as full thickness in PDF Change-Id: I728d962ea65ad1671e3b4c76034d396bee84228e diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 8dcc2f116069..48ab0641ffcb 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -1391,6 +1391,7 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd const double dWidth = fabs(sqrt2(a, c) * fWidth); SAL_WARN("sd.filter", "Path Stroke Width scaled: " << dWidth); mnLineWidth = lcl_ToLogic(lcl_PointToPixel(dWidth)); + mnLineWidth /= 2; unsigned int nR; unsigned int nG; commit 6f32334f9a486ef9c043474a27da8e52321bacc8 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun Apr 15 10:51:39 2018 -0400 svx: support color text for imported PDFs Change-Id: I01cba9456b37bd7a63c823bbe332d686f7ede389 diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1 index 96e0fa4f9725..02e0b44c3e87 100644 --- a/external/pdfium/edit.patch.1 +++ b/external/pdfium/edit.patch.1 @@ -1,12 +1,73 @@ +diff --git a/core/fpdfapi/page/cpdf_colorstate.cpp b/core/fpdfapi/page/cpdf_colorstate.cpp +index 693fcf1..d3e1202 100644 +--- a/core/fpdfapi/page/cpdf_colorstate.cpp ++++ b/core/fpdfapi/page/cpdf_colorstate.cpp +@@ -74,6 +74,8 @@ void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS, + uint32_t nValues) { + ColorData* pData = m_Ref.GetPrivateCopy(); + SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues); ++ if (pData->m_FillRGB != 0 && pData->m_FillRGB != 0xFFFFFFFF) ++ fprintf(stderr, "COLOR FILL!!!!> %x\n", pData->m_FillRGB); + } + + void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS, +@@ -81,6 +83,8 @@ void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS, + uint32_t nValues) { + ColorData* pData = m_Ref.GetPrivateCopy(); + SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues); ++ if (pData->m_StrokeRGB != 0 && pData->m_StrokeRGB != 0xFFFFFFFF) ++ fprintf(stderr, "COLOR STROkE!!!!> %x\n", pData->m_StrokeRGB); + } + + void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern, +@@ -99,6 +103,8 @@ void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern, + } + } + pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : 0xFFFFFFFF; ++ if (pData->m_FillRGB != 0 && pData->m_FillRGB != 0xFFFFFFFF) ++ fprintf(stderr, "COLOR FILL!!!!> %x\n", pData->m_FillRGB); + } + + void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, +@@ -118,13 +124,15 @@ void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, + } + pData->m_StrokeRGB = + pData->m_StrokeColor.GetRGB(&R, &G, &B) ? FXSYS_RGB(R, G, B) : 0xFFFFFFFF; ++ if (pData->m_StrokeRGB != 0 && pData->m_StrokeRGB != 0xFFFFFFFF) ++ fprintf(stderr, "COLOR STROkE!!!!> %x\n", pData->m_StrokeRGB); + } + + void CPDF_ColorState::SetColor(CPDF_Color& color, + uint32_t& rgb, + CPDF_ColorSpace* pCS, + float* pValue, +- uint32_t nValues) { ++ uint32_t nValues) const { + if (pCS) + color.SetColorSpace(pCS); + else if (color.IsNull()) +diff --git a/core/fpdfapi/page/cpdf_colorstate.h b/core/fpdfapi/page/cpdf_colorstate.h +index 9619051..dbe9c47 100644 +--- a/core/fpdfapi/page/cpdf_colorstate.h ++++ b/core/fpdfapi/page/cpdf_colorstate.h +@@ -64,7 +64,7 @@ class CPDF_ColorState { + uint32_t& rgb, + CPDF_ColorSpace* pCS, + float* pValue, +- uint32_t nValues); ++ uint32_t nValues) const; + + SharedCopyOnWrite<ColorData> m_Ref; + }; diff --git a/core/fpdfapi/page/cpdf_imageobject.cpp b/core/fpdfapi/page/cpdf_imageobject.cpp -index 3b5a740..58ef90a 100644 +index 3b5a740..416d82d 100644 --- a/core/fpdfapi/page/cpdf_imageobject.cpp +++ b/core/fpdfapi/page/cpdf_imageobject.cpp @@ -43,6 +43,7 @@ const CPDF_ImageObject* CPDF_ImageObject::AsImage() const { void CPDF_ImageObject::CalcBoundingBox() { std::tie(m_Left, m_Right, m_Top, m_Bottom) = m_Matrix.TransformRect(0.f, 1.f, 1.f, 0.f); -+ fprintf(stderr, "Image BB: %f, %f, %f, %f\n", m_Left, m_Right, m_Top, m_Bottom); ++ // fprintf(stderr, "Image BB: %f, %f, %f, %f\n", m_Left, m_Right, m_Top, m_Bottom); } void CPDF_ImageObject::SetImage(const RetainPtr<CPDF_Image>& pImage) { @@ -62,14 +123,14 @@ index 0a01ae0..6947e3a 100644 DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, &text_matrix, bFill, bStroke); diff --git a/core/fxge/cfx_pathdata.cpp b/core/fxge/cfx_pathdata.cpp -index 4ac5cf6..28ea81f 100644 +index 4ac5cf6..4286de4 100644 --- a/core/fxge/cfx_pathdata.cpp +++ b/core/fxge/cfx_pathdata.cpp @@ -199,6 +199,7 @@ void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix) { void CFX_PathData::AppendPoint(const CFX_PointF& point, FXPT_TYPE type, bool closeFigure) { -+ fprintf(stderr, "Append: %f, %f (%s)\n", point.x, point.y, closeFigure ? "CLOSE" : "OPEN"); ++// fprintf(stderr, "Append: %f, %f (%s)\n", point.x, point.y, closeFigure ? "CLOSE" : "OPEN"); m_Points.push_back(FX_PATHPOINT(point, type, closeFigure)); } @@ -77,7 +138,7 @@ index 4ac5cf6..28ea81f 100644 void CFX_PathData::Transform(const CFX_Matrix* pMatrix) { if (!pMatrix) return; -+ fprintf(stderr, "XForm: %f, %f %f, %f, %f, %f\n", pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, pMatrix->e, pMatrix->f); ++// fprintf(stderr, "XForm: %f, %f %f, %f, %f, %f\n", pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, pMatrix->e, pMatrix->f); for (auto& point : m_Points) point.m_Point = pMatrix->Transform(point.m_Point); } @@ -113,7 +174,7 @@ index 0d7ba56..37bdf99 100644 FPDFImageObj_GetImageDataDecoded(FPDF_PAGEOBJECT image_object, void* buffer, diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp -index ca2cf3f..e7d633f 100644 +index ca2cf3f..f86201d 100644 --- a/fpdfsdk/fpdfeditpage.cpp +++ b/fpdfsdk/fpdfeditpage.cpp @@ -11,12 +11,14 @@ @@ -131,7 +192,7 @@ index ca2cf3f..e7d633f 100644 #include "core/fpdfapi/page/cpdf_shadingobject.h" #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_document.h" -@@ -363,3 +365,128 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject, +@@ -363,3 +365,157 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject, *top = bbox.top; return true; } @@ -242,22 +303,51 @@ index ca2cf3f..e7d633f 100644 +} + +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -+FPDFTextObj_GetStrokeColor(FPDF_PAGEOBJECT text_object, -+ unsigned int* R, -+ unsigned int* G, -+ unsigned int* B, -+ unsigned int* A) ++FPDFTextObj_GetColor(FPDF_PAGEOBJECT text_object, ++ unsigned int* R, ++ unsigned int* G, ++ unsigned int* B, ++ unsigned int* A) +{ + CPDF_TextObject* pTxtObj = CPDFTextObjectFromFPDFPageObject(text_object); + if (!pTxtObj || !R || !G || !B || !A) + return false; + -+ const uint32_t strokeRGB = pTxtObj->m_ColorState.GetStrokeRGB(); -+ *R = FXSYS_GetRValue(strokeRGB); -+ *G = FXSYS_GetGValue(strokeRGB); -+ *B = FXSYS_GetBValue(strokeRGB); ++ bool bFill = false; ++ bool bStroke = false; ++ CPDF_Font* pFont = pTxtObj->m_TextState.GetFont(); ++ const TextRenderingMode text_render_mode = pTxtObj->m_TextState.GetTextMode(); ++ switch (text_render_mode) ++ { ++ case TextRenderingMode::MODE_FILL: ++ case TextRenderingMode::MODE_FILL_CLIP: ++ bFill = true; ++ break; ++ case TextRenderingMode::MODE_STROKE: ++ case TextRenderingMode::MODE_STROKE_CLIP: ++ if (pFont->GetFace()) ++ bStroke = true; ++ else ++ bFill = true; ++ break; ++ case TextRenderingMode::MODE_FILL_STROKE: ++ case TextRenderingMode::MODE_FILL_STROKE_CLIP: ++ bFill = true; ++ if (pFont->GetFace()) ++ bStroke = true; ++ break; ++ case TextRenderingMode::MODE_INVISIBLE: ++ case TextRenderingMode::MODE_CLIP: ++ return false; ++ } ++ ++ const uint32_t RGB = bStroke ? pTxtObj->m_ColorState.GetStrokeRGB() : pTxtObj->m_ColorState.GetFillRGB(); ++ *R = FXSYS_GetRValue(RGB); ++ *G = FXSYS_GetGValue(RGB); ++ *B = FXSYS_GetBValue(RGB); + *A = static_cast<unsigned int>( + (pTxtObj->m_GeneralState.GetStrokeAlpha() * 255.f) + 0.5f); ++ + return true; +} diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp @@ -409,7 +499,7 @@ index 77c2315..db3e734 100644 CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h -index 54735a3..c86b638 100644 +index 54735a3..c0231c2 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path, @@ -534,11 +624,11 @@ index 54735a3..c86b638 100644 +// +// Returns TRUE on success. +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV -+FPDFTextObj_GetStrokeColor(FPDF_PAGEOBJECT text_object, -+ unsigned int* R, -+ unsigned int* G, -+ unsigned int* B, -+ unsigned int* A); ++FPDFTextObj_GetColor(FPDF_PAGEOBJECT text_object, ++ unsigned int* R, ++ unsigned int* G, ++ unsigned int* B, ++ unsigned int* A); + #ifdef __cplusplus } // extern "C" diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 0330586c3afa..8dcc2f116069 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -1070,13 +1070,25 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd dFontSizeV = lcl_ToLogic(dFontSizeV); SAL_WARN("sd.filter", "Got Logic Font Size H: " << dFontSizeH << ", V: " << dFontSizeV); + const Size aFontSize(dFontSizeH, dFontSizeV); + vcl::Font aFnt = mpVD->GetFont(); + if (aFontSize != aFnt.GetFontSize()) + { + aFnt.SetFontSize(aFontSize); + mpVD->SetFont(aFnt); + mbFntDirty = true; + } + + Color aTextColor(COL_TRANSPARENT); unsigned int nR, nG, nB, nA; - if (FPDFTextObj_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA)) - mpVD->SetTextColor(Color(nR, nG, nB)); + if (FPDFTextObj_GetColor(pPageObject, &nR, &nG, &nB, &nA)) + aTextColor = Color(nR, nG, nB); - vcl::Font aFnt = mpVD->GetFont(); - aFnt.SetFontSize(Size(dFontSizeH, dFontSizeV)); - mpVD->SetFont(aFnt); + if (aTextColor != mpVD->GetTextColor()) + { + mpVD->SetTextColor(aTextColor); + mbFntDirty = true; + } ImportText(aRect.TopLeft(), aRect.GetSize(), sText); } @@ -1408,14 +1420,14 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd Point ImpSdrPdfImport::PointsToLogic(double x, double y) const { y = correctVertOrigin(y); - SAL_WARN("sd.filter", "Corrected point x: " << x << ", y: " << y); + // SAL_WARN("sd.filter", "Corrected point x: " << x << ", y: " << y); x = lcl_PointToPixel(x); y = lcl_PointToPixel(y); - SAL_WARN("sd.filter", "Pixel point x: " << x << ", y: " << y); + // SAL_WARN("sd.filter", "Pixel point x: " << x << ", y: " << y); Point aPos(lcl_ToLogic(x), lcl_ToLogic(y)); - SAL_WARN("sd.filter", "Logical Pos: " << aPos); + // SAL_WARN("sd.filter", "Logical Pos: " << aPos); return aPos; } @@ -1425,24 +1437,20 @@ tools::Rectangle ImpSdrPdfImport::PointsToLogic(double left, double right, doubl { top = correctVertOrigin(top); bottom = correctVertOrigin(bottom); - SAL_WARN("sd.filter", "Corrected bounds left: " << left << ", right: " << right - << ", top: " << top << ", bottom: " << bottom); + // SAL_WARN("sd.filter", "Corrected bounds left: " << left << ", right: " << right + // << ", top: " << top << ", bottom: " << bottom); left = lcl_PointToPixel(left); right = lcl_PointToPixel(right); top = lcl_PointToPixel(top); bottom = lcl_PointToPixel(bottom); - // if (top > bottom) - // std::swap(top, bottom); - // if (left > right) - // std::swap(left, right); - SAL_WARN("sd.filter", "Pixel bounds left: " << left << ", right: " << right << ", top: " << top - << ", bottom: " << bottom); + // SAL_WARN("sd.filter", "Pixel bounds left: " << left << ", right: " << right << ", top: " << top + // << ", bottom: " << bottom); Point aPos(lcl_ToLogic(left), lcl_ToLogic(top)); Size aSize(lcl_ToLogic(right - left), lcl_ToLogic(bottom - top)); tools::Rectangle aRect(aPos, aSize); - SAL_WARN("sd.filter", "Logical BBox: " << aRect); + // SAL_WARN("sd.filter", "Logical BBox: " << aRect); return aRect; } commit 5e636ada3b89b05fecba0b916ec791383e1555ae Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sat Apr 14 16:20:11 2018 -0400 svx: more accurate PDF imported text size Change-Id: I22880afdd9d36d9096003d86bba15098b465e0b3 diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 1136fb30c849..0330586c3afa 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -1034,6 +1034,8 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd return; } + const tools::Rectangle aRect = PointsToLogic(left, right, top, bottom); + const int nChars = FPDFTextObj_CountChars(pPageObject); std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null @@ -1054,6 +1056,7 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd << ", " << e << ", " << f << ')'); Point aPos = PointsToLogic(e, f); SAL_WARN("sd.filter", "Got TEXT origin: " << aPos); + SAL_WARN("sd.filter", "Got TEXT Bounds: " << aRect); const double dFontSize = FPDFTextObj_GetFontSize(pPageObject); double dFontSizeH = fabs(sqrt2(a, c) * dFontSize); @@ -1075,10 +1078,10 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd aFnt.SetFontSize(Size(dFontSizeH, dFontSizeV)); mpVD->SetFont(aFnt); - ImportText(aPos, sText); + ImportText(aRect.TopLeft(), aRect.GetSize(), sText); } -void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr) +void ImpSdrPdfImport::ImportText(const Point& rPos, const Size& rSize, const OUString& rStr) { // calc text box size, add 5% to make it fit safely @@ -1093,6 +1096,7 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr) << ", Scaled: " << nTextWidth << 'x' << nTextHeight); Point aPos(FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y())); + Size bSize(FRound(rSize.Width() * mfScaleX), FRound(rSize.Height() * mfScaleY)); Size aSize(nTextWidth, nTextHeight); if (eAlg == ALIGN_BASELINE) @@ -1100,8 +1104,11 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr) else if (eAlg == ALIGN_BOTTOM) aPos.AdjustY(-nTextHeight); - tools::Rectangle aTextRect(aPos, aSize); - SAL_WARN("sd.filter", "Text Rect: " << aTextRect); + SAL_WARN("sd.filter", "Final POS: " << aPos); + SAL_WARN("sd.filter", "Final Text Size: " << aSize); + SAL_WARN("sd.filter", "Final Bound Size: " << bSize); + tools::Rectangle aTextRect(aPos, bSize); + // SAL_WARN("sd.filter", "Text Rect: " << aTextRect); SdrRectObj* pText = new SdrRectObj(*mpModel, OBJ_TEXT, aTextRect); pText->SetMergedItem(makeSdrTextUpperDistItem(0)); diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx index 17b926b43619..dc62b234a688 100644 --- a/svx/source/svdraw/svdpdf.hxx +++ b/svx/source/svdraw/svdpdf.hxx @@ -106,7 +106,7 @@ class ImpSdrPdfImport final void ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); void ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); - void ImportText(const Point& rPos, const OUString& rStr); + void ImportText(const Point& rPos, const Size& rSize, const OUString& rStr); void SetAttributes(SdrObject* pObj, bool bForceTextAttr = false); void InsertObj(SdrObject* pObj, bool bScale = true); void MapScaling(); commit 7330abe573a182e0e2edbcc225a48815edf974f4 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sat Apr 14 11:40:18 2018 -0400 svx: correct the positioning of PDF Paths and the stroke width Change-Id: I5b150721cc1b61b028f282062c1466ef6a67fcae diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1 index 982560a3fab7..96e0fa4f9725 100644 --- a/external/pdfium/edit.patch.1 +++ b/external/pdfium/edit.patch.1 @@ -10,6 +10,33 @@ index 3b5a740..58ef90a 100644 } void CPDF_ImageObject::SetImage(const RetainPtr<CPDF_Image>& pImage) { +diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp +index ba93f4a..70d398b 100644 +--- a/core/fpdfapi/page/cpdf_page.cpp ++++ b/core/fpdfapi/page/cpdf_page.cpp +@@ -35,12 +35,14 @@ CPDF_Page::CPDF_Page(CPDF_Document* pDocument, + CFX_FloatRect mediabox = GetBox("MediaBox"); + if (mediabox.IsEmpty()) + mediabox = CFX_FloatRect(0, 0, 612, 792); ++ fprintf(stderr, "Page mediabox: %f, %f, %f, %f\n", mediabox.left, mediabox.right, mediabox.top, mediabox.bottom); + + m_BBox = GetBox("CropBox"); + if (m_BBox.IsEmpty()) + m_BBox = mediabox; + else + m_BBox.Intersect(mediabox); ++ fprintf(stderr, "Page cropbox: %f, %f, %f, %f\n", m_BBox.left, m_BBox.right, m_BBox.top, m_BBox.bottom); + + m_PageSize.width = m_BBox.Width(); + m_PageSize.height = m_BBox.Height(); +@@ -48,6 +50,7 @@ CPDF_Page::CPDF_Page(CPDF_Document* pDocument, + int rotate = GetPageRotation(); + if (rotate % 2) + std::swap(m_PageSize.width, m_PageSize.height); ++ fprintf(stderr, "Page rotate: %d, Page Width: %f, Page Height: %f\n", rotate, m_PageSize.width, m_PageSize.height); + + switch (rotate) { + case 0: diff --git a/core/fpdfapi/page/cpdf_pageobject.cpp b/core/fpdfapi/page/cpdf_pageobject.cpp index 8bb5bf5..9b5e2ce 100644 --- a/core/fpdfapi/page/cpdf_pageobject.cpp @@ -23,17 +50,37 @@ index 8bb5bf5..9b5e2ce 100644 return rect.GetOuterRect(); } diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp -index 0a01ae0..fad2920 100644 +index 0a01ae0..6947e3a 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -1793,6 +1793,7 @@ bool CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj, return true; float font_size = textobj->m_TextState.GetFontSize(); -+ fprintf(stderr, "Font size: %f, matrix a: %f, b: %f, c: %f, d: %f, e: %f, f: %f\n", font_size, text_matrix.a, text_matrix.b, text_matrix.c, text_matrix.d, text_matrix.e, text_matrix.f); ++// fprintf(stderr, "Font size: %f, matrix a: %f, b: %f, c: %f, d: %f, e: %f, f: %f\n", font_size, text_matrix.a, text_matrix.b, text_matrix.c, text_matrix.d, text_matrix.e, text_matrix.f); if (bPattern) { DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, &text_matrix, bFill, bStroke); +diff --git a/core/fxge/cfx_pathdata.cpp b/core/fxge/cfx_pathdata.cpp +index 4ac5cf6..28ea81f 100644 +--- a/core/fxge/cfx_pathdata.cpp ++++ b/core/fxge/cfx_pathdata.cpp +@@ -199,6 +199,7 @@ void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix) { + void CFX_PathData::AppendPoint(const CFX_PointF& point, + FXPT_TYPE type, + bool closeFigure) { ++ fprintf(stderr, "Append: %f, %f (%s)\n", point.x, point.y, closeFigure ? "CLOSE" : "OPEN"); + m_Points.push_back(FX_PATHPOINT(point, type, closeFigure)); + } + +@@ -290,6 +291,7 @@ CFX_FloatRect CFX_PathData::GetBoundingBox(float line_width, + void CFX_PathData::Transform(const CFX_Matrix* pMatrix) { + if (!pMatrix) + return; ++ fprintf(stderr, "XForm: %f, %f %f, %f, %f, %f\n", pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, pMatrix->e, pMatrix->f); + for (auto& point : m_Points) + point.m_Point = pMatrix->Transform(point.m_Point); + } diff --git a/fpdfsdk/fpdfeditimg.cpp b/fpdfsdk/fpdfeditimg.cpp index 0d7ba56..37bdf99 100644 --- a/fpdfsdk/fpdfeditimg.cpp @@ -214,7 +261,7 @@ index ca2cf3f..e7d633f 100644 + return true; +} diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp -index a291987..1ac8257 100644 +index a291987..0202284 100644 --- a/fpdfsdk/fpdfeditpath.cpp +++ b/fpdfsdk/fpdfeditpath.cpp @@ -101,6 +101,16 @@ FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width) { @@ -275,14 +322,14 @@ index a291987..1ac8257 100644 + if (!path_object || !a || !b || !c || !d || !e || !f) + return false; + -+ auto* pPathObj = CPDFPageObjectFromFPDFPageObject(path_object); -+ CFX_Matrix* pMatrix = pPathObj->m_GeneralState.GetMutableMatrix(); -+ *a = pMatrix->a; -+ *b = pMatrix->b; -+ *c = pMatrix->c; -+ *d = pMatrix->d; -+ *e = pMatrix->e; -+ *f = pMatrix->f; ++ CPDF_PathObject* pPathObj = CPDFPathObjectFromFPDFPageObject(path_object); ++ const CFX_Matrix& pMatrix = pPathObj->m_Matrix; ++ *a = pMatrix.a; ++ *b = pMatrix.b; ++ *c = pMatrix.c; ++ *d = pMatrix.d; ++ *e = pMatrix.e; ++ *f = pMatrix.f; + + return true; +} diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 696b340c6767..1136fb30c849 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -1309,12 +1309,16 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd continue; } - SAL_WARN("sd.filter", "Got point (" << x << ", " << y << ")"); + SAL_WARN("sd.filter", "Got point (" << x << ", " << y << ") matrix (" << a << ", " << b + << ", " << c << ", " << d << ", " << e << ", " << f + << ')'); x = a * x + c * y + e; y = b * x + d * y + f; const bool bClose = FPDFPathSegment_GetClose(pPathSegment); + if (bClose) + aPoly.setClosed(bClose); // TODO: Review SAL_WARN("sd.filter", "Point corrected (" << x << ", " << y << "): " << (bClose ? "CLOSE" : "OPEN")); Point aPoint = PointsToLogic(x, y); @@ -1364,7 +1368,10 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd float fWidth = 1; FPDFPath_GetStrokeWidth(pPageObject, &fWidth); - mnLineWidth = lcl_ToLogic(lcl_PointToPixel(fWidth)); + SAL_WARN("sd.filter", "Path Stroke Width: " << fWidth); + const double dWidth = fabs(sqrt2(a, c) * fWidth); + SAL_WARN("sd.filter", "Path Stroke Width scaled: " << dWidth); + mnLineWidth = lcl_ToLogic(lcl_PointToPixel(dWidth)); unsigned int nR; unsigned int nG; @@ -1386,7 +1393,6 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd // if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource))) - aPoly.setClosed(true); // TODO: Review SdrPathObj* pPath = new SdrPathObj(*mpModel, OBJ_POLY, basegfx::B2DPolyPolygon(aPoly)); SetAttributes(pPath); InsertObj(pPath, false); commit 3379cb362236fa058278a38434fd3ad57e51144d Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Fri Apr 13 20:26:11 2018 -0400 svx: improved text importing from PDF Change-Id: I9a2fc2c8511655c1aa362c1a03a5e82ae3ba697e diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1 index 86cda347f262..982560a3fab7 100644 --- a/external/pdfium/edit.patch.1 +++ b/external/pdfium/edit.patch.1 @@ -66,7 +66,7 @@ index 0d7ba56..37bdf99 100644 FPDFImageObj_GetImageDataDecoded(FPDF_PAGEOBJECT image_object, void* buffer, diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp -index ca2cf3f..8073a18 100644 +index ca2cf3f..e7d633f 100644 --- a/fpdfsdk/fpdfeditpage.cpp +++ b/fpdfsdk/fpdfeditpage.cpp @@ -11,12 +11,14 @@ @@ -84,7 +84,7 @@ index ca2cf3f..8073a18 100644 #include "core/fpdfapi/page/cpdf_shadingobject.h" #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_document.h" -@@ -363,3 +365,123 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject, +@@ -363,3 +365,128 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject, *top = bbox.top; return true; } @@ -114,8 +114,11 @@ index ca2cf3f..8073a18 100644 + double* a, + double* b, + double* c, -+ double* d) { -+ if (!text_object) ++ double* d, ++ double* e, ++ double* f) ++{ ++ if (!text_object || !a || !b || !c || !d || !e || !f) + return; + + CPDF_TextObject* pTxtObj = CPDFTextObjectFromFPDFPageObject(text_object); @@ -124,6 +127,8 @@ index ca2cf3f..8073a18 100644 + *b = matrix.b; + *c = matrix.c; + *d = matrix.d; ++ *e = matrix.e; ++ *f = matrix.f; +} + +FPDF_EXPORT int FPDF_CALLCONV @@ -357,7 +362,7 @@ index 77c2315..db3e734 100644 CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h -index 54735a3..a415c98 100644 +index 54735a3..c86b638 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path, @@ -413,7 +418,7 @@ index 54735a3..a415c98 100644 // Create a new text object using one of the standard PDF fonts. // // document - handle to the document. -@@ -761,6 +800,73 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document, +@@ -761,6 +800,77 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document, FPDF_FONT font, float font_size); @@ -445,12 +450,16 @@ index 54735a3..a415c98 100644 +// b - Pointer to a double value receiving coefficient "b" of the matrix. +// c - Pointer to a double value receiving coefficient "c" of the matrix. +// d - Pointer to a double value receiving coefficient "d" of the matrix. ++// e - Pointer to a double value receiving coefficient "e" of the matrix. ++// f - Pointer to a double value receiving coefficient "f" of the matrix. +FPDF_EXPORT void FPDF_CALLCONV +FPDFTextObj_GetMatrix(FPDF_PAGEOBJECT text_object, + double* a, + double* b, + double* c, -+ double* d); ++ double* d, ++ double* e, ++ double* f); + +// Get the unicode of a special character in a text object. +// diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 49139d7eacd0..696b340c6767 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -103,6 +103,8 @@ static inline long lcl_ToLogic(double value) const long out = OutputDevice::LogicToLogic(in, MapUnit::MapPixel, MapUnit::Map100thMM); return out / 100; } + +static inline double sqrt2(double a, double b) { return sqrt(a * a + b * b); } } struct FPDFBitmapDeleter @@ -1024,53 +1026,56 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd SAL_WARN("sd.filter", "FAILED to get TEXT bounds"); } - SAL_WARN("sd.filter", "Got TEXT bounds left: " << left << ", right: " << right - << ", top: " << top << ", bottom: " << bottom); - tools::Rectangle aRect = PointsToLogic(left, right, top, bottom); + if (left == right || top == bottom) + { + SAL_WARN("sd.filter", "Skipping empty TEXT #" << nPageObjectIndex << " left: " << left + << ", right: " << right << ", top: " << top + << ", bottom: " << bottom); + return; + } - double dFontScale = 1.0; - geometry::Matrix2D aMatrix; - FPDFTextObj_GetMatrix(pPageObject, &aMatrix.m00, &aMatrix.m01, &aMatrix.m10, &aMatrix.m11); - if (aMatrix.m00 != aMatrix.m11 || aMatrix.m00 <= 0) + const int nChars = FPDFTextObj_CountChars(pPageObject); + std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null + + unsigned short* pShortText = reinterpret_cast<unsigned short*>(pText.get()); + const int nActualChars = FPDFTextObj_GetText(pPageObject, 0, nChars, pShortText); + if (nActualChars <= 0) { - SAL_WARN("sd.filter", "Bogus font scale matrix (" << aMatrix.m00 << ',' << aMatrix.m11 - << "), will use heuristic height of " - << aRect.GetHeight() << "."); - dFontScale = aRect.GetHeight(); + SAL_WARN("sd.filter", "Got not TEXT"); + return; } - else - dFontScale = aMatrix.m00; - double dFontSize = FPDFTextObj_GetFontSize(pPageObject); - SAL_WARN("sd.filter", "Got Font Size: " << dFontSize); - dFontSize *= dFontScale; - SAL_WARN("sd.filter", "Got Font Size Scaled: " << dFontSize); - dFontSize = lcl_PointToPixel(dFontSize); - SAL_WARN("sd.filter", "Got Font Pixel Size: " << dFontSize); - dFontSize = lcl_ToLogic(dFontSize); - SAL_WARN("sd.filter", "Got Font Logic Size: " << dFontSize); + OUString sText(pText.get(), nActualChars); + SAL_WARN("sd.filter", "Got Text (" << nChars << "): [" << sText << "]."); + + double a, b, c, d, e, f; + FPDFTextObj_GetMatrix(pPageObject, &a, &b, &c, &d, &e, &f); + SAL_WARN("sd.filter", "Got font scale matrix (" << a << ", " << b << ", " << c << ", " << d + << ", " << e << ", " << f << ')'); + Point aPos = PointsToLogic(e, f); + SAL_WARN("sd.filter", "Got TEXT origin: " << aPos); + + const double dFontSize = FPDFTextObj_GetFontSize(pPageObject); + double dFontSizeH = fabs(sqrt2(a, c) * dFontSize); + double dFontSizeV = fabs(sqrt2(b, d) * dFontSize); + SAL_WARN("sd.filter", "Got Font Size: " << dFontSize << ", Scaled Font Size H: " << dFontSizeH + << ", V: " << dFontSizeV); + dFontSizeH = lcl_PointToPixel(dFontSizeH); + dFontSizeV = lcl_PointToPixel(dFontSizeV); + SAL_WARN("sd.filter", "Got Pixel Font Size H: " << dFontSizeH << ", V: " << dFontSizeV); + dFontSizeH = lcl_ToLogic(dFontSizeH); + dFontSizeV = lcl_ToLogic(dFontSizeV); + SAL_WARN("sd.filter", "Got Logic Font Size H: " << dFontSizeH << ", V: " << dFontSizeV); unsigned int nR, nG, nB, nA; if (FPDFTextObj_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA)) mpVD->SetTextColor(Color(nR, nG, nB)); vcl::Font aFnt = mpVD->GetFont(); - aFnt.SetFontSize(Size(dFontSize, dFontSize)); + aFnt.SetFontSize(Size(dFontSizeH, dFontSizeV)); mpVD->SetFont(aFnt); - const int nChars = FPDFTextObj_CountChars(pPageObject); - std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null - - unsigned short* pShortText = reinterpret_cast<unsigned short*>(pText.get()); - const int nActualChars = FPDFTextObj_GetText(pPageObject, 0, nChars, pShortText); - OUString sText(pText.get(), nActualChars); - - // for (int nChar = 0; nChar < nChars; ++nChar) - // pText[nChar] = static_cast<sal_Unicode>(FPDFTextObj_GetUnicode(pPageObject, nChar)); - // OUString sText(pText.get(), nChars); - SAL_WARN("sd.filter", "Got Text (" << nChars << "): [" << sText << "]."); - - ImportText(aRect.TopLeft(), sText); + ImportText(aPos, sText); } void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr) @@ -1083,11 +1088,12 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr) sal_Int32 nTextWidth = static_cast<sal_Int32>(mpVD->GetTextWidth(rStr) * mfScaleX); sal_Int32 nTextHeight = static_cast<sal_Int32>(mpVD->GetTextHeight() * mfScaleY); - SAL_WARN("sd.filter", "TextWidth: " << nTextWidth << ", TextHeight: " << nTextHeight); + SAL_WARN("sd.filter", + "Unscaled text size: " << mpVD->GetTextWidth(rStr) << 'x' << mpVD->GetTextHeight() + << ", Scaled: " << nTextWidth << 'x' << nTextHeight); Point aPos(FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y())); Size aSize(nTextWidth, nTextHeight); - SAL_WARN("sd.filter", "Text Pos: " << aPos << ", Size: " << aSize); if (eAlg == ALIGN_BASELINE) aPos.AdjustY(-(FRound(aFontMetric.GetAscent() * mfScaleY))); commit 336f8f40b728ec5df78df72645039cc9b5e17757 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Fri Apr 13 18:59:56 2018 -0400 svx: improve path importing from PDF Change-Id: I8e63b2a35d841e065ef32fea95c0a5f22ca6f049 diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1 index 03b4ab221730..86cda347f262 100644 --- a/external/pdfium/edit.patch.1 +++ b/external/pdfium/edit.patch.1 @@ -209,7 +209,7 @@ index ca2cf3f..8073a18 100644 + return true; +} diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp -index a291987..d3b0bc1 100644 +index a291987..1ac8257 100644 --- a/fpdfsdk/fpdfeditpath.cpp +++ b/fpdfsdk/fpdfeditpath.cpp @@ -101,6 +101,16 @@ FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width) { @@ -229,6 +229,63 @@ index a291987..d3b0bc1 100644 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_SetFillColor(FPDF_PAGEOBJECT path, unsigned int R, unsigned int G, +@@ -217,6 +227,25 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path, + return true; + } + ++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_GetDrawMode(FPDF_PAGEOBJECT path, ++ int* fillmode, ++ FPDF_BOOL* stroke) ++{ ++ auto* pPathObj = CPDFPathObjectFromFPDFPageObject(path); ++ if (!pPathObj || !fillmode || !stroke) ++ return false; ++ ++ if (pPathObj->m_FillType == FXFILL_ALTERNATE) ++ *fillmode = FPDF_FILLMODE_ALTERNATE; ++ else if (pPathObj->m_FillType == FXFILL_WINDING) ++ *fillmode = FPDF_FILLMODE_WINDING; ++ else ++ *fillmode = 0; // no fill ++ ++ *stroke = pPathObj->m_bStroke; ++ return true; ++} ++ + FPDF_EXPORT void FPDF_CALLCONV FPDFPath_SetLineJoin(FPDF_PAGEOBJECT path, + int line_join) { + if (!path) +@@ -250,6 +279,30 @@ FPDF_EXPORT void FPDF_CALLCONV FPDFPath_SetLineCap(FPDF_PAGEOBJECT path, + } + + FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV ++FPDFPath_GetMatrix(FPDF_PAGEOBJECT path_object, ++ double* a, ++ double* b, ++ double* c, ++ double* d, ++ double* e, ++ double* f) ++{ ++ if (!path_object || !a || !b || !c || !d || !e || !f) ++ return false; ++ ++ auto* pPathObj = CPDFPageObjectFromFPDFPageObject(path_object); ++ CFX_Matrix* pMatrix = pPathObj->m_GeneralState.GetMutableMatrix(); ++ *a = pMatrix->a; ++ *b = pMatrix->b; ++ *c = pMatrix->c; ++ *d = pMatrix->d; ++ *e = pMatrix->e; ++ *f = pMatrix->f; ++ ++ return true; ++} ++ ++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV + FPDFPathSegment_GetPoint(FPDF_PATHSEGMENT segment, float* x, float* y) { + auto* pPathPoint = FXPathPointFromFPDFPathSegment(segment); + if (!pPathPoint || !x || !y) diff --git a/fpdfsdk/fpdftext.cpp b/fpdfsdk/fpdftext.cpp index 68bf4f8..e073b20 100644 --- a/fpdfsdk/fpdftext.cpp @@ -300,7 +357,7 @@ index 77c2315..db3e734 100644 CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h -index 54735a3..282bcdb 100644 +index 54735a3..a415c98 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path, @@ -319,7 +376,44 @@ index 54735a3..282bcdb 100644 // Set the line join of |page_object|. // // page_object - handle to a page object. -@@ -761,6 +770,73 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document, +@@ -688,6 +697,36 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path, + int fillmode, + FPDF_BOOL stroke); + ++// Get the drawing mode of a path. ++// ++// path - the handle to the path object. ++// fillmode - the filling mode to be set: 0 for no fill, 1 for alternate, 2 for ++// winding. ++// stroke - a boolean specifying if the path should be stroked or not. ++// ++// Returns TRUE on success ++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_GetDrawMode(FPDF_PAGEOBJECT path, ++ int* fillmode, ++ FPDF_BOOL* stroke); ++ ++// Get the matrix of a particular text object. ++// ++// path_object - Handle of path object returned by FPDFPath_NewPathObj ++// a - Pointer to a double value receiving coefficient "a" of the matrix. ++// b - Pointer to a double value receiving coefficient "b" of the matrix. ++// c - Pointer to a double value receiving coefficient "c" of the matrix. ++// d - Pointer to a double value receiving coefficient "d" of the matrix. ++// e - Pointer to a double value receiving coefficient "e" of the matrix. ++// f - Pointer to a double value receiving coefficient "f" of the matrix. ++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV ++FPDFPath_GetMatrix(FPDF_PAGEOBJECT path_object, ++ double* a, ++ double* b, ++ double* c, ++ double* d, ++ double* e, ++ double* f); ++ + // Create a new text object using one of the standard PDF fonts. + // + // document - handle to the document. +@@ -761,6 +800,73 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document, FPDF_FONT font, float font_size); diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 3f585b58fb6b..49139d7eacd0 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -568,7 +568,7 @@ void ImpSdrPdfImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr) if (mpVD->IsLineColor()) { - mpLineAttr->Put(XLineStyleItem(drawing::LineStyle_SOLID)); + mpLineAttr->Put(XLineStyleItem(drawing::LineStyle_SOLID)); //TODO support dashed lines. mpLineAttr->Put(XLineColorItem(OUString(), mpVD->GetLineColor())); } else @@ -1283,6 +1283,10 @@ void ImpSdrPdfImport::ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIn void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex) { SAL_WARN("sd.filter", "Got page object PATH: " << nPageObjectIndex); + + double a, b, c, d, e, f; + FPDFPath_GetMatrix(pPageObject, &a, &b, &c, &d, &e, &f); + basegfx::B2DPolygon aPoly; std::vector<basegfx::B2DPoint> aBezier; @@ -1299,9 +1303,14 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd continue; } + SAL_WARN("sd.filter", "Got point (" << x << ", " << y << ")"); + + x = a * x + c * y + e; + y = b * x + d * y + f; + const bool bClose = FPDFPathSegment_GetClose(pPathSegment); SAL_WARN("sd.filter", - "Got (" << x << ", " << y << "): " << (bClose ? "CLOSE" : "OPEN")); + "Point corrected (" << x << ", " << y << "): " << (bClose ? "CLOSE" : "OPEN")); Point aPoint = PointsToLogic(x, y); x = aPoint.X(); y = aPoint.Y(); @@ -1351,15 +1360,23 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd FPDFPath_GetStrokeWidth(pPageObject, &fWidth); mnLineWidth = lcl_ToLogic(lcl_PointToPixel(fWidth)); - unsigned int r; - unsigned int g; - unsigned int b; - unsigned int a; - FPDFPath_GetFillColor(pPageObject, &r, &g, &b, &a); - mpVD->SetFillColor(Color(r, g, b)); - - FPDFPath_GetStrokeColor(pPageObject, &r, &g, &b, &a); - mpVD->SetLineColor(Color(r, g, b)); + unsigned int nR; + unsigned int nG; + unsigned int nB; + unsigned int nA; + FPDFPath_GetFillColor(pPageObject, &nR, &nG, &nB, &nA); + SAL_WARN("sd.filter", "Got PATH fill color: " << nR << ", " << nG << ", " << nB << ", " << nA); + mpVD->SetFillColor(Color(nR, nG, nB)); + + FPDFPath_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA); + SAL_WARN("sd.filter", + "Got PATH stroke color: " << nR << ", " << nG << ", " << nB << ", " << nA); + mpVD->SetLineColor(Color(nR, nG, nB)); + + // int nFillMode = 0; // No fill. + // bool bStroke = false; + // FPDFPath_GetDrawMode(pPageObject, &nFillMode, &bStroke); + // mpVD->Setstroke(Color(r, g, b)); // if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource))) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits