diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2018-04-18 21:27:27 -0400 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2018-06-07 10:45:29 +0200 |
commit | d28e9e10a893b60b4bad5a1d0bae47a986dd2bdb (patch) | |
tree | 2d0619ecbf9ecf70ace1dba01b0e41f41b4a9624 /svx/source | |
parent | 3ac5ec542031e08996768918d8793b5da3648fda (diff) |
svx: correctly possition form objects from PDF
Change-Id: I7d216ca61b8a10219628877db7dd593a4987ef60
(cherry picked from commit 81f16107c1b0b5315537f38a9830cf967e4abb68)
Diffstat (limited to 'svx/source')
-rw-r--r-- | svx/source/svdraw/svdpdf.cxx | 40 | ||||
-rw-r--r-- | svx/source/svdraw/svdpdf.hxx | 65 |
2 files changed, 92 insertions, 13 deletions
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index acb85166bfd7..f2fbd7a835ed 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); @@ -1302,6 +1314,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; @@ -1312,19 +1326,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..460b508e83a8 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 da, double db, double dc, double dd, double de, double df) + : ma(da) + , mb(db) + , mc(dc) + , md(dd) + , me(de) + , mf(df) + { + } + + 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. |