diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2018-04-18 21:27:27 -0400 |
---|---|---|
committer | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2018-06-05 21:02:05 -0400 |
commit | df639a5b53a908cc8d86af22c31e04bd9b8bd28b (patch) | |
tree | 806baa93eb59cf5c4a74e876fc4cbb392a4421d8 | |
parent | dd8514b424f0ae10e756628d797c69622d5192b9 (diff) |
svx: correctly possition form objects from PDF
Change-Id: I7d216ca61b8a10219628877db7dd593a4987ef60
-rw-r--r-- | external/pdfium/edit.patch.1 | 51 | ||||
-rw-r--r-- | svx/source/svdraw/svdpdf.cxx | 40 | ||||
-rw-r--r-- | svx/source/svdraw/svdpdf.hxx | 65 |
3 files changed, 139 insertions, 17 deletions
diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1 index 09f609320169..270dceb871b6 100644 --- a/external/pdfium/edit.patch.1 +++ b/external/pdfium/edit.patch.1 @@ -199,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..8ecab60 100644 +index ca2cf3f..832a9ae 100644 --- a/fpdfsdk/fpdfeditpage.cpp +++ b/fpdfsdk/fpdfeditpage.cpp @@ -11,12 +11,14 @@ @@ -217,7 +217,7 @@ index ca2cf3f..8ecab60 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,187 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject, +@@ -363,3 +365,212 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject, *top = bbox.top; return true; } @@ -405,6 +405,31 @@ index ca2cf3f..8ecab60 100644 + + return nullptr; +} ++ ++FPDF_EXPORT void FPDF_CALLCONV ++FPDFFormObj_GetMatrix(FPDF_PAGEOBJECT form_object, ++ double* a, ++ double* b, ++ double* c, ++ double* d, ++ double* e, ++ double* f) ++{ ++ if (!form_object || !a || !b || !c || !d || !e || !f) ++ return; ++ ++ CPDF_FormObject* pFrmObj = CPDFFormObjectFromFPDFPageObject(form_object); ++ if (pFrmObj) ++ { ++ const CFX_Matrix& matrix = pFrmObj->form_matrix(); ++ *a = matrix.a; ++ *b = matrix.b; ++ *c = matrix.c; ++ *d = matrix.d; ++ *e = matrix.e; ++ *f = matrix.f; ++ } ++} diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp index a291987..0202284 100644 --- a/fpdfsdk/fpdfeditpath.cpp @@ -562,7 +587,7 @@ index 77c2315..b61f447 100644 CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h -index 54735a3..1b933bb 100644 +index 54735a3..2e7e2e7 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path, @@ -618,7 +643,7 @@ index 54735a3..1b933bb 100644 // Create a new text object using one of the standard PDF fonts. // // document - handle to the document. -@@ -761,6 +800,94 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document, +@@ -761,6 +800,112 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document, FPDF_FONT font, float font_size); @@ -710,6 +735,24 @@ index 54735a3..1b933bb 100644 +FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV +FPDFFormObj_GetSubObject(FPDF_PAGEOBJECT form_object, int index); + ++// Get the matrix of a particular form object. ++// ++// form_object - Handle of form object ++// 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 void FPDF_CALLCONV ++FPDFFormObj_GetMatrix(FPDF_PAGEOBJECT form_object, ++ double* a, ++ double* b, ++ double* c, ++ double* d, ++ double* e, ++ double* f); ++ #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 89f10900925b..d1663dfa787a 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -1025,12 +1025,22 @@ void ImpSdrPdfImport::ImportForm(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd { SAL_WARN("sd.filter", "Got page object FORM: " << nPageObjectIndex); + // Get the form matrix to perform correct translation/scaling of the form sub-objects. + const Matrix aOldMatrix = mCurMatrix; + + double a, b, c, d, e, f; + FPDFFormObj_GetMatrix(pPageObject, &a, &b, &c, &d, &e, &f); + mCurMatrix = Matrix(a, b, c, d, e, f); + const int nCount = FPDFFormObj_CountSubObjects(pPageObject); for (int nIndex = 0; nIndex < nCount; ++nIndex) { FPDF_PAGEOBJECT pFormObject = FPDFFormObj_GetSubObject(pPageObject, nIndex); ImportPdfObject(pFormObject, -1); } + + // Restore the old one. + mCurMatrix = aOldMatrix; } void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex) @@ -1055,6 +1065,16 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd const tools::Rectangle aRect = PointsToLogic(left, right, top, bottom); + double a, b, c, d, e, f; + FPDFTextObj_GetMatrix(pPageObject, &a, &b, &c, &d, &e, &f); + Matrix aTextMatrix(a, b, c, d, e, f); + aTextMatrix.Concatinate(mCurMatrix); + 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); + SAL_WARN("sd.filter", "Got TEXT Bounds: " << aRect); + const int nChars = FPDFTextObj_CountChars(pPageObject); std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null @@ -1069,14 +1089,6 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd 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); - SAL_WARN("sd.filter", "Got TEXT Bounds: " << aRect); - const double dFontSize = FPDFTextObj_GetFontSize(pPageObject); double dFontSizeH = fabs(sqrt2(a, c) * dFontSize); double dFontSizeV = fabs(sqrt2(b, d) * dFontSize); @@ -1301,6 +1313,8 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd double a, b, c, d, e, f; FPDFPath_GetMatrix(pPageObject, &a, &b, &c, &d, &e, &f); + Matrix aPathMatrix(a, b, c, d, e, f); + aPathMatrix.Concatinate(mCurMatrix); basegfx::B2DPolygon aPoly; std::vector<basegfx::B2DPoint> aBezier; @@ -1311,19 +1325,19 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd FPDF_PATHSEGMENT pPathSegment = FPDFPath_GetPathSegment(pPageObject, nSegmentIndex); if (pPathSegment != nullptr) { - float x, y; - if (!FPDFPathSegment_GetPoint(pPathSegment, &x, &y)) + float fx, fy; + if (!FPDFPathSegment_GetPoint(pPathSegment, &fx, &fy)) { SAL_WARN("sd.filter", "Failed to get PDF path segement point"); continue; } + double x = fx; + double y = fy; 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; + aPathMatrix.Transform(x, y); const bool bClose = FPDFPathSegment_GetClose(pPathSegment); if (bClose) diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx index d98f97d8cd09..798f1e999bd6 100644 --- a/svx/source/svdraw/svdpdf.hxx +++ b/svx/source/svdraw/svdpdf.hxx @@ -46,6 +46,69 @@ typedef void* FPDF_PAGEOBJECT; // Helper Class to import PDF class ImpSdrPdfImport final { + class Matrix + { + public: + Matrix() + : Matrix(1, 0, 0, 1, 0, 0) + { + } + + Matrix(const Matrix& other) + : Matrix(other.ma, other.mb, other.mc, other.md, other.me, other.mf) + { + } + + Matrix(double a, double b, double c, double d, double e, double f) + : ma(a) + , mb(b) + , mc(c) + , md(d) + , me(e) + , mf(f) + { + } + + const Matrix& operator=(const Matrix& other) + { + ma = other.ma; + mb = other.mb; + mc = other.mc; + md = other.md; + me = other.me; + mf = other.mf; + return *this; + } + + double a() const { return ma; } + double b() const { return mb; } + double c() const { return mc; } + double d() const { return md; } + double e() const { return me; } + double f() const { return mf; } + + /// Mutliply this * other. + void Concatinate(const Matrix& other) + { + ma = ma * other.ma + mb * other.mc; + mb = ma * other.mb + mb * other.md; + mc = mc * other.ma + md * other.mc; + md = mc * other.mb + md * other.md; + me = me * other.ma + mf * other.mc + other.me; + mf = me * other.mb + mf * other.md + other.mf; + } + + /// Transform the point (x, y) by this Matrix. + void Transform(double& x, double& y) + { + x = ma * x + mc * y + me; + y = mb * x + md * y + mf; + } + + private: + double ma, mb, mc, md, me, mf; + }; + ::std::vector<SdrObject*> maTmpList; ScopedVclPtr<VirtualDevice> mpVD; tools::Rectangle maScaleRect; @@ -87,6 +150,8 @@ class ImpSdrPdfImport final int mnPageCount; double mdPageWidthPts; double mdPageHeightPts; + /// The current transformation matrix, typically used with Form objects. + Matrix mCurMatrix; /// Correct the vertical coordinate to start at the top. /// PDF coordinate system has orign at the bottom right. |