diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2020-06-28 13:46:41 +0200 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2020-06-29 23:38:48 +0200 |
commit | af7b619f2752fcac3492c53444e836371efbd5fe (patch) | |
tree | df5f559b45ce689a1a3740bc9b0d407a0b1b5205 | |
parent | f5124552d87e84b5b6d6707c30b5f8a5defed69e (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.hxx | 7 | ||||
-rw-r--r-- | sd/qa/unit/SdrPdfImportTest.cxx | 11 | ||||
-rw-r--r-- | svx/source/inc/svdpdf.hxx | 4 | ||||
-rw-r--r-- | svx/source/svdraw/svdpdf.cxx | 71 | ||||
-rw-r--r-- | vcl/qa/cppunit/PDFiumLibraryTest.cxx | 14 | ||||
-rw-r--r-- | vcl/source/pdf/PDFiumLibrary.cxx | 60 |
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) |