summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2020-06-28 13:46:41 +0200
committerTomaž Vajngerl <quikee@gmail.com>2020-06-29 23:38:48 +0200
commitaf7b619f2752fcac3492c53444e836371efbd5fe (patch)
treedf5f559b45ce689a1a3740bc9b0d407a0b1b5205
parentf5124552d87e84b5b6d6707c30b5f8a5defed69e (diff)
pdf: add text page object attribs, refactor ImpSdrPdfImport, tests
This refactors ImpSdrPdfImport to push more functions into the PDFium wrapper. The focus is on text page object attributes. Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97366 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> (cherry picked from commit 4e9b03d04f740a0cbafa22a4f3cedfae7f37a994) Change-Id: Ie1faf5e3743eec7c77050835651533f9e227c2a7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97451 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r--include/vcl/filter/PDFiumLibrary.hxx7
-rw-r--r--sd/qa/unit/SdrPdfImportTest.cxx11
-rw-r--r--svx/source/inc/svdpdf.hxx4
-rw-r--r--svx/source/svdraw/svdpdf.cxx71
-rw-r--r--vcl/qa/cppunit/PDFiumLibraryTest.cxx14
-rw-r--r--vcl/source/pdf/PDFiumLibrary.cxx60
6 files changed, 110 insertions, 57 deletions
diff --git a/include/vcl/filter/PDFiumLibrary.hxx b/include/vcl/filter/PDFiumLibrary.hxx
index 9f34bdb92ad6..f7dcc4b2c99e 100644
--- a/include/vcl/filter/PDFiumLibrary.hxx
+++ b/include/vcl/filter/PDFiumLibrary.hxx
@@ -22,6 +22,7 @@
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <rtl/ustring.hxx>
+#include <tools/color.hxx>
#include <fpdf_doc.h>
@@ -93,6 +94,12 @@ public:
std::unique_ptr<PDFiumPageObject> getFormObject(int nIndex);
basegfx::B2DHomMatrix getMatrix();
+ basegfx::B2DRectangle getBounds();
+ double getFontSize();
+ OUString getFontName();
+ int getTextRenderMode();
+ Color getFillColor();
+ Color getStrokeColor();
};
class VCL_DLLPUBLIC PDFiumTextPage final
diff --git a/sd/qa/unit/SdrPdfImportTest.cxx b/sd/qa/unit/SdrPdfImportTest.cxx
index ca022d585c48..2ac548bb6c85 100644
--- a/sd/qa/unit/SdrPdfImportTest.cxx
+++ b/sd/qa/unit/SdrPdfImportTest.cxx
@@ -89,6 +89,9 @@ CPPUNIT_TEST_FIXTURE(SdrPdfImportTest, testImportSimpleText)
SdPage* pPage = pViewShell->GetActualPage();
CPPUNIT_ASSERT(pPage);
+ // Check there is one object on the page only
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
+
// Get the first object - there should be only one.
SdrObject* pObject = pPage->GetObj(0);
CPPUNIT_ASSERT(pObject);
@@ -110,11 +113,17 @@ CPPUNIT_TEST_FIXTURE(SdrPdfImportTest, testImportSimpleText)
// Execute the break operation - to turn the PDF into shapes/objects
pViewShell->GetDrawView()->DoImportMarkedMtf();
- // Check Objects after import
+ // Check there is one object on the page only
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
+ // Get the object
SdrObject* pImportedObject = pPage->GetObj(0);
CPPUNIT_ASSERT(pImportedObject);
+ // Check the object position
+ CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(2011, 2098), Size(2106 + 1, 302 + 1)),
+ pImportedObject->GetLogicRect());
+
// Object should be a text object containing one paragraph with
// content "This is PDF!"
diff --git a/svx/source/inc/svdpdf.hxx b/svx/source/inc/svdpdf.hxx
index 49c8d3e1b3c2..b1ad9d69ad12 100644
--- a/svx/source/inc/svdpdf.hxx
+++ b/svx/source/inc/svdpdf.hxx
@@ -120,7 +120,9 @@ class SVXCORE_DLLPUBLIC ImpSdrPdfImport final
int nPageObjectIndex);
void ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
void ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
- void ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage, int nPageObjectIndex);
+ void ImportText(std::unique_ptr<vcl::pdf::PDFiumPageObject> const& pPageObject,
+ std::unique_ptr<vcl::pdf::PDFiumTextPage> const& pTextPage,
+ int nPageObjectIndex);
void InsertTextObject(const Point& rPos, const Size& rSize, const OUString& rStr);
void SetupPageScale(const double dPageWidth, const double dPageHeight);
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 066c77f0798f..ff4029a00b54 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -694,7 +694,7 @@ void ImpSdrPdfImport::ImportPdfObject(
switch (nPageObjectType)
{
case FPDF_PAGEOBJ_TEXT:
- ImportText(pPageObject->getPointer(), pTextPage->getPointer(), nPageObjectIndex);
+ ImportText(pPageObject, pTextPage, nPageObjectIndex);
break;
case FPDF_PAGEOBJ_PATH:
ImportPath(pPageObject->getPointer(), nPageObjectIndex);
@@ -736,47 +736,23 @@ void ImpSdrPdfImport::ImportForm(std::unique_ptr<vcl::pdf::PDFiumPageObject> con
maCurrentMatrix = aOldMatrix;
}
-void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage,
+void ImpSdrPdfImport::ImportText(std::unique_ptr<vcl::pdf::PDFiumPageObject> const& pPageObject,
+ std::unique_ptr<vcl::pdf::PDFiumTextPage> const& pTextPage,
int /*nPageObjectIndex*/)
{
- float left;
- float bottom;
- float right;
- float top;
- if (!FPDFPageObj_GetBounds(pPageObject, &left, &bottom, &right, &top))
- {
- SAL_WARN("sd.filter", "FAILED to get TEXT bounds");
- }
-
- if (left == right || top == bottom)
- return;
-
- double a, b, c, d, e, f;
- FPDFTextObj_GetMatrix(pPageObject, &a, &b, &c, &d, &e, &f);
-
+ basegfx::B2DRectangle aTextRect = pPageObject->getBounds();
+ basegfx::B2DHomMatrix aMatrix = pPageObject->getMatrix();
basegfx::B2DHomMatrix aTextMatrix(maCurrentMatrix);
- basegfx::B2DRange aTextRect(left, top, right, bottom);
+
aTextRect *= aTextMatrix;
const tools::Rectangle aRect = PointsToLogic(aTextRect.getMinX(), aTextRect.getMaxX(),
aTextRect.getMinY(), aTextRect.getMaxY());
- const int nBytes = FPDFTextObj_GetText(pPageObject, pTextPage, nullptr, 0);
- std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nBytes]);
-
- const int nActualBytes = FPDFTextObj_GetText(pPageObject, pTextPage, pText.get(), nBytes);
- if (nActualBytes <= 0)
- {
- return;
- }
+ OUString sText = pPageObject->getText(pTextPage);
- // Let's rely on null-terminaton for the length of the string. We
- // just know the number of bytes the string takes, but in OUString
- // needs the number of charaters.
- OUString sText(pText.get());
-
- const double dFontSize = FPDFTextObj_GetFontSize(pPageObject);
- double dFontSizeH = fabs(sqrt2(a, c) * dFontSize);
- double dFontSizeV = fabs(sqrt2(b, d) * dFontSize);
+ const double dFontSize = pPageObject->getFontSize();
+ double dFontSizeH = fabs(sqrt2(aMatrix.a(), aMatrix.c()) * dFontSize);
+ double dFontSizeV = fabs(sqrt2(aMatrix.b(), aMatrix.d()) * dFontSize);
dFontSizeH = convertPointToMm100(dFontSizeH);
dFontSizeV = convertPointToMm100(dFontSizeV);
@@ -790,25 +766,18 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTex
mbFntDirty = true;
}
- const int nFontName = 80 + 1;
- std::unique_ptr<char[]> pFontName(new char[nFontName]); // + terminating null
- char* pCharFontName = reinterpret_cast<char*>(pFontName.get());
- int nFontNameChars = FPDFTextObj_GetFontName(pPageObject, pCharFontName, nFontName);
- if (nFontName >= nFontNameChars)
+ OUString sFontName = pPageObject->getFontName();
+ if (!sFontName.isEmpty() && sFontName != aFnt.GetFamilyName())
{
- OUString sFontName = OUString::createFromAscii(pFontName.get());
- if (sFontName != aFnt.GetFamilyName())
- {
- aFnt.SetFamilyName(sFontName);
- mpVD->SetFont(aFnt);
- mbFntDirty = true;
- }
+ aFnt.SetFamilyName(sFontName);
+ mpVD->SetFont(aFnt);
+ mbFntDirty = true;
}
Color aTextColor(COL_TRANSPARENT);
bool bFill = false;
bool bUse = true;
- switch (FPDFTextObj_GetTextRenderMode(pPageObject))
+ switch (pPageObject->getTextRenderMode())
{
case FPDF_TEXTRENDERMODE_FILL:
case FPDF_TEXTRENDERMODE_FILL_CLIP:
@@ -826,11 +795,9 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTex
}
if (bUse)
{
- unsigned int nR, nG, nB, nA;
- bool bRet = bFill ? FPDFPageObj_GetFillColor(pPageObject, &nR, &nG, &nB, &nA)
- : FPDFPageObj_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA);
- if (bRet)
- aTextColor = Color(nR, nG, nB);
+ Color aColor = bFill ? pPageObject->getFillColor() : pPageObject->getStrokeColor();
+ if (aColor != COL_TRANSPARENT)
+ aTextColor = aColor.GetRGBColor();
}
if (aTextColor != mpVD->GetTextColor())
diff --git a/vcl/qa/cppunit/PDFiumLibraryTest.cxx b/vcl/qa/cppunit/PDFiumLibraryTest.cxx
index 9c0c92607b14..f18681c0adda 100644
--- a/vcl/qa/cppunit/PDFiumLibraryTest.cxx
+++ b/vcl/qa/cppunit/PDFiumLibraryTest.cxx
@@ -134,10 +134,22 @@ void PDFiumLibraryTest::testPageObjects()
auto pPageObject = pPage->getObject(0);
auto pTextPage = pPage->getTextPage();
- CPPUNIT_ASSERT_EQUAL(1, pPageObject->getType());
+ CPPUNIT_ASSERT_EQUAL(1, pPageObject->getType()); // FPDF_PAGEOBJ_TEXT
+
CPPUNIT_ASSERT_EQUAL(OUString("The quick, brown fox jumps over a lazy dog. DJs flock by when "
"MTV ax quiz prog. Junk MTV quiz "),
pPageObject->getText(pTextPage));
+
+ CPPUNIT_ASSERT_EQUAL(12.0, pPageObject->getFontSize());
+ CPPUNIT_ASSERT_EQUAL(OUString("Liberation Serif"), pPageObject->getFontName());
+ CPPUNIT_ASSERT_EQUAL(0, pPageObject->getTextRenderMode()); // FPDF_TEXTRENDERMODE_FILL
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK, pPageObject->getFillColor());
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK, pPageObject->getStrokeColor());
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(057.01, pPageObject->getBounds().getMinX(), 1E-2);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(721.51, pPageObject->getBounds().getMinY(), 1E-2);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(539.48, pPageObject->getBounds().getMaxX(), 1E-2);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(732.54, pPageObject->getBounds().getMaxY(), 1E-2);
}
void PDFiumLibraryTest::testAnnotationsMadeInEvince()
diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx
index 7e30ba47b0bc..e86b7565dd1b 100644
--- a/vcl/source/pdf/PDFiumLibrary.cxx
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -254,9 +254,65 @@ std::unique_ptr<PDFiumPageObject> PDFiumPageObject::getFormObject(int nIndex)
basegfx::B2DHomMatrix PDFiumPageObject::getMatrix()
{
+ basegfx::B2DHomMatrix aB2DMatrix;
double a, b, c, d, e, f;
- FPDFTextObj_GetMatrix(mpPageObject, &a, &b, &c, &d, &e, &f);
- return basegfx::B2DHomMatrix::abcdef(a, b, c, d, e, f);
+ if (FPDFTextObj_GetMatrix(mpPageObject, &a, &b, &c, &d, &e, &f))
+ aB2DMatrix = basegfx::B2DHomMatrix::abcdef(a, b, c, d, e, f);
+ return aB2DMatrix;
+}
+
+basegfx::B2DRectangle PDFiumPageObject::getBounds()
+{
+ basegfx::B2DRectangle aB2DRectangle;
+
+ float left = 0;
+ float bottom = 0;
+ float right = 0;
+ float top = 0;
+ if (FPDFPageObj_GetBounds(mpPageObject, &left, &bottom, &right, &top))
+ {
+ aB2DRectangle = basegfx::B2DRectangle(left, top, right, bottom);
+ }
+ return aB2DRectangle;
+}
+
+double PDFiumPageObject::getFontSize() { return FPDFTextObj_GetFontSize(mpPageObject); }
+
+OUString PDFiumPageObject::getFontName()
+{
+ OUString sFontName;
+ const int nFontName = 80 + 1;
+ std::unique_ptr<char[]> pFontName(new char[nFontName]); // + terminating null
+ int nFontNameChars = FPDFTextObj_GetFontName(mpPageObject, pFontName.get(), nFontName);
+ if (nFontName >= nFontNameChars)
+ {
+ sFontName = OUString::createFromAscii(pFontName.get());
+ }
+ return sFontName;
+}
+
+int PDFiumPageObject::getTextRenderMode() { return FPDFTextObj_GetTextRenderMode(mpPageObject); }
+
+Color PDFiumPageObject::getFillColor()
+{
+ Color aColor = COL_TRANSPARENT;
+ unsigned int nR, nG, nB, nA;
+ if (FPDFPageObj_GetFillColor(mpPageObject, &nR, &nG, &nB, &nA))
+ {
+ aColor = Color(0xFF - nA, nR, nG, nB);
+ }
+ return aColor;
+}
+
+Color PDFiumPageObject::getStrokeColor()
+{
+ Color aColor = COL_TRANSPARENT;
+ unsigned int nR, nG, nB, nA;
+ if (FPDFPageObj_GetStrokeColor(mpPageObject, &nR, &nG, &nB, &nA))
+ {
+ aColor = Color(0xFF - nA, nR, nG, nB);
+ }
+ return aColor;
}
PDFiumAnnotation::PDFiumAnnotation(FPDF_ANNOTATION pAnnotation)