summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-04-18 21:27:27 -0400
committerAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-06-05 21:02:05 -0400
commitdf639a5b53a908cc8d86af22c31e04bd9b8bd28b (patch)
tree806baa93eb59cf5c4a74e876fc4cbb392a4421d8
parentdd8514b424f0ae10e756628d797c69622d5192b9 (diff)
svx: correctly possition form objects from PDF
Change-Id: I7d216ca61b8a10219628877db7dd593a4987ef60
-rw-r--r--external/pdfium/edit.patch.151
-rw-r--r--svx/source/svdraw/svdpdf.cxx40
-rw-r--r--svx/source/svdraw/svdpdf.hxx65
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.