summaryrefslogtreecommitdiff
path: root/svx/source
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-04-18 21:27:27 -0400
committerJan Holesovsky <kendy@collabora.com>2018-06-01 08:59:20 +0200
commit3a1b92b9b2c60f0206545395dc017e6a764c1e4f (patch)
treed0aa3a3edc982ca81f9e3146b0c89343cf12b36e /svx/source
parentd6fa53ee707b516eacd2179c7961f93da068d949 (diff)
svx: correctly possition form objects from PDF
Change-Id: I7d216ca61b8a10219628877db7dd593a4987ef60
Diffstat (limited to 'svx/source')
-rw-r--r--svx/source/svdraw/svdpdf.cxx40
-rw-r--r--svx/source/svdraw/svdpdf.hxx65
2 files changed, 92 insertions, 13 deletions
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index c6a6d0d3f9fb..466f712458fd 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -1024,12 +1024,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)
@@ -1054,6 +1064,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
@@ -1068,14 +1088,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);
@@ -1300,6 +1312,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;
@@ -1310,19 +1324,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.