[Libreoffice-commits] core.git: Branch 'private/Ashod/cd-5.3.3.2' - 26 commits - external/pdfium include/svx include/vcl sd/source svx/Library_svxcore.mk svx/source vcl/inc vcl/source

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon May 14 14:00:51 UTC 2018


Rebased ref, commits from common ancestor:
commit 65329eb45d2f17d24120e15ba24f257204133b2c
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Apr 22 17:21:30 2018 -0400

    svx: support no fill and no stroke paths in PDF import
    
    Change-Id: Ida5daa71d469805fd52e08e804fb9fa182d7d008

diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 79cd86d850c1..bb241986a199 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -1410,11 +1410,24 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
 
     float fWidth = 1;
     FPDFPath_GetStrokeWidth(pPageObject, &fWidth);
-    SAL_WARN("sd.filter", "Path Stroke Width: " << fWidth);
-    const double dWidth = fabs(sqrt2(a, c) * fWidth);
-    SAL_WARN("sd.filter", "Path Stroke Width scaled: " << dWidth);
+    const double dWidth = 0.5 * fabs(sqrt2(mCurMatrix.a(), mCurMatrix.c()) * fWidth);
     mnLineWidth = lcl_ToLogic(lcl_PointToPixel(dWidth));
     mnLineWidth /= 2;
+    SAL_WARN("sd.filter", "Path Stroke Width: " << fWidth << ",  scaled: " << dWidth
+                                                << ", Logical: " << mnLineWidth);
+
+    int nFillMode = FPDF_FILLMODE_ALTERNATE;
+    FPDF_BOOL bStroke = true;
+    if (FPDFPath_GetDrawMode(pPageObject, &nFillMode, &bStroke))
+    {
+        SAL_WARN("sd.filter", "Got PATH FillMode: " << nFillMode << ", Storke: " << bStroke);
+        if (nFillMode == FPDF_FILLMODE_ALTERNATE)
+            mpVD->SetDrawMode(DrawModeFlags::Default);
+        else if (nFillMode == FPDF_FILLMODE_WINDING)
+            mpVD->SetDrawMode(DrawModeFlags::Default);
+        else
+            mpVD->SetDrawMode(DrawModeFlags::NoFill);
+    }
 
     unsigned int nR;
     unsigned int nG;
@@ -1424,15 +1437,15 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
     SAL_WARN("sd.filter", "Got PATH fill color: " << nR << ", " << nG << ", " << nB << ", " << nA);
     mpVD->SetFillColor(Color(nR, nG, nB));
 
-    FPDFPath_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA);
-    SAL_WARN("sd.filter",
-             "Got PATH stroke color: " << nR << ", " << nG << ", " << nB << ", " << nA);
-    mpVD->SetLineColor(Color(nR, nG, nB));
-
-    // int nFillMode = 0; // No fill.
-    // bool bStroke = false;
-    // FPDFPath_GetDrawMode(pPageObject, &nFillMode, &bStroke);
-    // mpVD->Setstroke(Color(r, g, b));
+    if (bStroke)
+    {
+        FPDFPath_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA);
+        SAL_WARN("sd.filter",
+                 "Got PATH stroke color: " << nR << ", " << nG << ", " << nB << ", " << nA);
+        mpVD->SetLineColor(Color(nR, nG, nB));
+    }
+    else
+        mpVD->SetLineColor(COL_TRANSPARENT);
 
     // if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
 
commit ab1f0fd674ac321f3ce597aebfc7fe2d97fa3cfc
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Apr 22 17:01:18 2018 -0400

    svx: support sub-paths in PDF import
    
    Change-Id: Ibcfd30383db6846e791aea7609ab196c4f3f2da4

diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index c1c2e24b20b6..79cd86d850c1 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -1313,17 +1313,19 @@ void ImpSdrPdfImport::ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIn
 
 void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
 {
-    SAL_WARN("sd.filter", "Got page object PATH: " << nPageObjectIndex);
-
     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::B2DPolyPolygon aPolyPoly;
     basegfx::B2DPolygon aPoly;
     std::vector<basegfx::B2DPoint> aBezier;
 
     const int nSegments = FPDFPath_CountSegments(pPageObject);
+    SAL_WARN("sd.filter",
+             "Got page object PATH: " << nPageObjectIndex << " with " << nSegments << " segments.");
+
     for (int nSegmentIndex = 0; nSegmentIndex < nSegments; ++nSegmentIndex)
     {
         FPDF_PATHSEGMENT pPathSegment = FPDFPath_GetPathSegment(pPageObject, nSegmentIndex);
@@ -1338,16 +1340,16 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
 
             double x = fx;
             double y = fy;
-            SAL_WARN("sd.filter", "Got point (" << x << ", " << y << ") matrix (" << a << ", " << b
-                                                << ", " << c << ", " << d << ", " << e << ", " << f
-                                                << ')');
             aPathMatrix.Transform(x, y);
-
             const bool bClose = FPDFPathSegment_GetClose(pPathSegment);
             if (bClose)
                 aPoly.setClosed(bClose); // TODO: Review
-            SAL_WARN("sd.filter",
-                     "Point corrected (" << x << ", " << y << "): " << (bClose ? "CLOSE" : "OPEN"));
+
+            SAL_WARN("sd.filter", "Got " << (bClose ? "CLOSE" : "OPEN") << " point (" << fx << ", "
+                                         << fy << ") matrix (" << a << ", " << b << ", " << c
+                                         << ", " << d << ", " << e << ", " << f << ") -> (" << x
+                                         << ", " << y << ")");
+
             Point aPoint = PointsToLogic(x, y);
             x = aPoint.X();
             y = aPoint.Y();
@@ -1372,6 +1374,13 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
 
                 case FPDF_SEGMENT_MOVETO:
                     SAL_WARN("sd.filter", "Got MoveTo Segment.");
+                    // New Poly.
+                    if (aPoly.count() > 0)
+                    {
+                        aPolyPoly.append(aPoly, 1);
+                        aPoly.clear();
+                    }
+
                     aPoly.append(basegfx::B2DPoint(x, y));
                     break;
 
@@ -1389,9 +1398,15 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
         aBezier.clear();
     }
 
+    if (aPoly.count() > 0)
+    {
+        aPolyPoly.append(aPoly, 1);
+        aPoly.clear();
+    }
+
     const basegfx::B2DHomMatrix aTransform(
         basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
-    aPoly.transform(aTransform);
+    aPolyPoly.transform(aTransform);
 
     float fWidth = 1;
     FPDFPath_GetStrokeWidth(pPageObject, &fWidth);
@@ -1421,7 +1436,7 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
 
     // if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
 
-    SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aPoly));
+    SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aPolyPoly);
     SetAttributes(pPath);
     InsertObj(pPath, false);
 }
commit e4477eb7bb3ce80214dfe5cea1eecc9c6913438c
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Apr 22 10:48:51 2018 -0400

    svx: import processed PDF text
    
    Some PDFs don't include spaces in the text.
    Instead, they rely on the explicit positioning
    of each character to render visually separated words.
    Latex seems to be prone to this approach, though not
    exclusively.
    
    Luckily, PDFium does process text and inserts
    "generated" spaces where necessary, which is what
    we retrieve and use as the text string while importing.
    
    Change-Id: Ic21fe6c8416ecaba66f06b6260f1d6b040ff12af

diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1
index 270dceb871b6..a110313017da 100644
--- a/external/pdfium/edit.patch.1
+++ b/external/pdfium/edit.patch.1
@@ -147,6 +147,56 @@ index 0a01ae0..6947e3a 100644
    if (bPattern) {
      DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size,
                              &text_matrix, bFill, bStroke);
+diff --git a/core/fpdftext/cpdf_textpage.cpp b/core/fpdftext/cpdf_textpage.cpp
+index e712549..a7973f7 100644
+--- a/core/fpdftext/cpdf_textpage.cpp
++++ b/core/fpdftext/cpdf_textpage.cpp
+@@ -1490,3 +1490,32 @@ bool CPDF_TextPage::IsRectIntersect(const CFX_FloatRect& rect1,
+   rect.Intersect(rect2);
+   return !rect.IsEmpty();
+ }
++
++WideString CPDF_TextPage::GetTextObjectText(CPDF_TextObject* pTextObj)
++{
++  if (!m_bIsParsed)
++    return WideString();
++
++  float posy = 0;
++  bool IsContainPreChar = false;
++  bool IsAddLineFeed = false;
++  WideString strText;
++  for (const auto& charinfo : m_CharList) {
++    if (charinfo.m_pTextObj == pTextObj) {
++      IsContainPreChar = true;
++      IsAddLineFeed = false;
++      if (charinfo.m_Unicode)
++        strText += charinfo.m_Unicode;
++    } else if (charinfo.m_Unicode == 32) {
++      if (IsContainPreChar && charinfo.m_Unicode) {
++        strText += charinfo.m_Unicode;
++        IsContainPreChar = false;
++        IsAddLineFeed = false;
++      }
++    } else {
++      IsContainPreChar = false;
++      IsAddLineFeed = true;
++    }
++  }
++  return strText;
++}
+diff --git a/core/fpdftext/cpdf_textpage.h b/core/fpdftext/cpdf_textpage.h
+index c87ab00..e5a1ba8 100644
+--- a/core/fpdftext/cpdf_textpage.h
++++ b/core/fpdftext/cpdf_textpage.h
+@@ -110,6 +110,8 @@ class CPDF_TextPage {
+   WideString GetPageText(int start, int count) const;
+   WideString GetAllPageText() const { return GetPageText(0, CountChars()); }
+ 
++  WideString GetTextObjectText(CPDF_TextObject* pTextObj);
++
+   int CountRects(int start, int nCount);
+   bool GetRect(int rectIndex, CFX_FloatRect* pRect) const;
+ 
 diff --git a/core/fxge/cfx_pathdata.cpp b/core/fxge/cfx_pathdata.cpp
 index 4ac5cf6..4286de4 100644
 --- a/core/fxge/cfx_pathdata.cpp
@@ -199,7 +249,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..832a9ae 100644
+index ca2cf3f..2162625 100644
 --- a/fpdfsdk/fpdfeditpage.cpp
 +++ b/fpdfsdk/fpdfeditpage.cpp
 @@ -11,12 +11,14 @@
@@ -217,7 +267,15 @@ index ca2cf3f..832a9ae 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,212 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
+@@ -24,6 +26,7 @@
+ #include "core/fpdfapi/parser/cpdf_string.h"
+ #include "core/fpdfdoc/cpdf_annot.h"
+ #include "core/fpdfdoc/cpdf_annotlist.h"
++#include "core/fpdftext/cpdf_textpage.h"
+ #include "fpdfsdk/fsdk_define.h"
+ #include "public/fpdf_formfill.h"
+ #include "third_party/base/logging.h"
+@@ -363,3 +366,252 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
    *top = bbox.top;
    return true;
  }
@@ -327,6 +385,46 @@ index ca2cf3f..832a9ae 100644
 +  return ret_count;
 +}
 +
++FPDF_EXPORT int FPDF_CALLCONV
++FPDFTextObj_GetTextProcessed(FPDF_PAGEOBJECT text_object,
++                             FPDF_TEXTPAGE page,
++                             int char_start,
++                             int char_count,
++                             unsigned short* result)
++{
++  if (!page || !text_object || char_start < 0 || char_count < 0 || !result)
++    return 0;
++
++  CPDF_TextObject* pTxtObj = CPDFTextObjectFromFPDFPageObject(text_object);
++  CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(page);
++  int char_available = textpage->CountChars() - char_start;
++  if (char_available <= 0)
++    return 0;
++
++  char_count = std::min(char_count, char_available);
++  if (char_count == 0) {
++    // Writing out "", which has a character count of 1 due to the NUL.
++    *result = '\0';
++    return 1;
++  }
++
++  WideString str = textpage->GetTextObjectText(pTxtObj);
++
++  if (str.GetLength() > static_cast<size_t>(char_count))
++    str = str.Left(static_cast<size_t>(char_count));
++
++  // UFT16LE_Encode doesn't handle surrogate pairs properly, so it is expected
++  // the number of items to stay the same.
++  ByteString byte_str = str.UTF16LE_Encode();
++  size_t byte_str_len = byte_str.GetLength();
++  constexpr size_t kBytesPerCharacter = sizeof(unsigned short);
++  int ret_count = byte_str_len / kBytesPerCharacter;
++
++  ASSERT(ret_count <= char_count + 1);  // +1 to account for the NUL terminator.
++  memcpy(result, byte_str.GetBuffer(byte_str_len), byte_str_len);
++  return ret_count;
++}
++
 +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
 +FPDFTextObj_GetColor(FPDF_PAGEOBJECT text_object,
 +                     unsigned int* R,
@@ -509,10 +607,21 @@ index a291987..0202284 100644
    auto* pPathPoint = FXPathPointFromFPDFPathSegment(segment);
    if (!pPathPoint || !x || !y)
 diff --git a/fpdfsdk/fpdftext.cpp b/fpdfsdk/fpdftext.cpp
-index 68bf4f8..e073b20 100644
+index 68bf4f8..1cac9c7 100644
 --- a/fpdfsdk/fpdftext.cpp
 +++ b/fpdfsdk/fpdftext.cpp
-@@ -105,6 +105,28 @@ FPDF_EXPORT double FPDF_CALLCONV FPDFText_GetFontSize(FPDF_TEXTPAGE text_page,
+@@ -31,10 +31,6 @@ namespace {
+ 
+ constexpr size_t kBytesPerCharacter = sizeof(unsigned short);
+ 
+-CPDF_TextPage* CPDFTextPageFromFPDFTextPage(FPDF_TEXTPAGE text_page) {
+-  return static_cast<CPDF_TextPage*>(text_page);
+-}
+-
+ CPDF_TextPageFind* CPDFTextPageFindFromFPDFSchHandle(FPDF_SCHHANDLE handle) {
+   return static_cast<CPDF_TextPageFind*>(handle);
+ }
+@@ -105,6 +101,28 @@ FPDF_EXPORT double FPDF_CALLCONV FPDFText_GetFontSize(FPDF_TEXTPAGE text_page,
    return charinfo.m_FontSize;
  }
  
@@ -542,13 +651,17 @@ index 68bf4f8..e073b20 100644
                                                          int index,
                                                          double* left,
 diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
-index e890aa0..b62283f 100644
+index e890aa0..09d2345 100644
 --- a/fpdfsdk/fpdfview.cpp
 +++ b/fpdfsdk/fpdfview.cpp
-@@ -336,6 +336,16 @@ CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
+@@ -336,6 +336,20 @@ CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
  #endif  // PDF_ENABLE_XFA
  }
  
++CPDF_TextPage* CPDFTextPageFromFPDFTextPage(FPDF_TEXTPAGE text_page) {
++  return static_cast<CPDF_TextPage*>(text_page);
++}
++
 +CPDF_TextObject* CPDFTextObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
 +  auto* obj = CPDFPageObjectFromFPDFPageObject(page_object);
 +  return obj ? obj->AsText() : nullptr;
@@ -563,22 +676,25 @@ index e890aa0..b62283f 100644
    auto* obj = CPDFPageObjectFromFPDFPageObject(page_object);
    return obj ? obj->AsPath() : nullptr;
 diff --git a/fpdfsdk/fsdk_define.h b/fpdfsdk/fsdk_define.h
-index 77c2315..b61f447 100644
+index 77c2315..e9a309a 100644
 --- a/fpdfsdk/fsdk_define.h
 +++ b/fpdfsdk/fsdk_define.h
-@@ -25,6 +25,8 @@ class CPDF_Annot;
+@@ -25,6 +25,9 @@ class CPDF_Annot;
  class CPDF_Page;
  class CPDF_PageObject;
  class CPDF_PageRenderContext;
 +class CPDF_TextObject;
++class CPDF_TextPage;
 +class CPDF_FormObject;
  class CPDF_PathObject;
  class CPDF_Stream;
  class IFSDK_PAUSE_Adapter;
-@@ -65,6 +67,10 @@ FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc);
+@@ -65,6 +68,12 @@ FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc);
  
  CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page);
  
++CPDF_TextPage* CPDFTextPageFromFPDFTextPage(FPDF_TEXTPAGE text_page);
++
 +CPDF_TextObject* CPDFTextObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
 +
 +CPDF_FormObject* CPDFFormObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
@@ -587,7 +703,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..2e7e2e7 100644
+index 54735a3..4d81aac 100644
 --- a/public/fpdf_edit.h
 +++ b/public/fpdf_edit.h
 @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path,
@@ -643,7 +759,7 @@ index 54735a3..2e7e2e7 100644
  // Create a new text object using one of the standard PDF fonts.
  //
  // document   - handle to the document.
-@@ -761,6 +800,112 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
+@@ -761,6 +800,125 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
                            FPDF_FONT font,
                            float font_size);
  
@@ -702,6 +818,19 @@ index 54735a3..2e7e2e7 100644
 +                    int char_count,
 +                    unsigned short* result);
 +
++// Get the processed text of a text object.
++//
++// text_object - Handle of text object returned by FPDFPageObj_NewTextObj
++//               or FPDFPageObj_NewTextObjEx.
++// Return Value:
++// The number of characters (not bytes) written in result.
++FPDF_EXPORT int FPDF_CALLCONV
++FPDFTextObj_GetTextProcessed(FPDF_PAGEOBJECT text_object,
++                             FPDF_TEXTPAGE page,
++                             int char_start,
++                             int char_count,
++                             unsigned short* result);
++
 +// Get the stroke RGBA of a text. Range of values: 0 - 255.
 +//
 +// path   - the handle to the path object.
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 33d6747e2a7f..c1c2e24b20b6 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -222,13 +222,18 @@ void ImpSdrPdfImport::DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pAc
                                               << ", height: " << dPageHeight);
         SetupPageScale(dPageWidth, dPageHeight);
 
+        // Load the page text to extract it when we get text elements.
+        FPDF_TEXTPAGE pTextPage = FPDFText_LoadPage(pPdfPage);
+
         const int nPageObjectCount = FPDFPage_CountObject(pPdfPage);
         for (int nPageObjectIndex = 0; nPageObjectIndex < nPageObjectCount; ++nPageObjectIndex)
         {
             FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(pPdfPage, nPageObjectIndex);
-            ImportPdfObject(pPageObject, nPageObjectIndex);
+            ImportPdfObject(pPageObject, pTextPage, nPageObjectIndex);
         }
 
+        FPDFText_ClosePage(pTextPage);
+
 #if 0
         // Now do the text.
         FPDF_TEXTPAGE pTextPage = FPDFText_LoadPage(pPdfPage);
@@ -986,8 +991,8 @@ void ImpSdrPdfImport::checkClip()
 }
 
 bool ImpSdrPdfImport::isClip() const { return !maClip.getB2DRange().isEmpty(); }
-
-void ImpSdrPdfImport::ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
+void ImpSdrPdfImport::ImportPdfObject(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage,
+                                      int nPageObjectIndex)
 {
     if (pPageObject == nullptr)
         return;
@@ -996,7 +1001,7 @@ void ImpSdrPdfImport::ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObje
     switch (nPageObjectType)
     {
         case FPDF_PAGEOBJ_TEXT:
-            ImportText(pPageObject, nPageObjectIndex);
+            ImportText(pPageObject, pTextPage, nPageObjectIndex);
             break;
         case FPDF_PAGEOBJ_PATH:
             ImportPath(pPageObject, nPageObjectIndex);
@@ -1008,7 +1013,7 @@ void ImpSdrPdfImport::ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObje
             SAL_WARN("sd.filter", "Got page object SHADING: " << nPageObjectIndex);
             break;
         case FPDF_PAGEOBJ_FORM:
-            ImportForm(pPageObject, nPageObjectIndex);
+            ImportForm(pPageObject, pTextPage, nPageObjectIndex);
             break;
         default:
             SAL_WARN("sd.filter", "Unknown PDF page object #" << nPageObjectIndex
@@ -1017,7 +1022,8 @@ void ImpSdrPdfImport::ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObje
     }
 }
 
-void ImpSdrPdfImport::ImportForm(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
+void ImpSdrPdfImport::ImportForm(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage,
+                                 int nPageObjectIndex)
 {
     SAL_WARN("sd.filter", "Got page object FORM: " << nPageObjectIndex);
 
@@ -1032,14 +1038,15 @@ void ImpSdrPdfImport::ImportForm(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
     for (int nIndex = 0; nIndex < nCount; ++nIndex)
     {
         FPDF_PAGEOBJECT pFormObject = FPDFFormObj_GetSubObject(pPageObject, nIndex);
-        ImportPdfObject(pFormObject, -1);
+        ImportPdfObject(pFormObject, pTextPage, -1);
     }
 
     // Restore the old one.
     mCurMatrix = aOldMatrix;
 }
 
-void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
+void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage,
+                                 int nPageObjectIndex)
 {
     SAL_WARN("sd.filter", "Got page object TEXT: " << nPageObjectIndex);
     float left;
@@ -1071,14 +1078,15 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
     SAL_WARN("sd.filter", "Got TEXT origin: " << aPos);
     SAL_WARN("sd.filter", "Got TEXT Bounds: " << aRect);
 
-    const int nChars = FPDFTextObj_CountChars(pPageObject);
+    const int nChars = FPDFTextObj_CountChars(pPageObject) * 2;
     std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null
 
     unsigned short* pShortText = reinterpret_cast<unsigned short*>(pText.get());
-    const int nActualChars = FPDFTextObj_GetText(pPageObject, 0, nChars, pShortText);
+    const int nActualChars
+        = FPDFTextObj_GetTextProcessed(pPageObject, pTextPage, 0, nChars, pShortText);
     if (nActualChars <= 0)
     {
-        SAL_WARN("sd.filter", "Got not TEXT");
+        SAL_WARN("sd.filter", "Got no TEXT");
         return;
     }
 
diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx
index a3c3cb6d4080..bb8dfb159b30 100644
--- a/svx/source/svdraw/svdpdf.hxx
+++ b/svx/source/svdraw/svdpdf.hxx
@@ -42,6 +42,7 @@ class SdrObject;
 class SvdProgressInfo;
 typedef void* FPDF_DOCUMENT;
 typedef void* FPDF_PAGEOBJECT;
+typedef void* FPDF_TEXTPAGE;
 
 // Helper Class to import PDF
 class ImpSdrPdfImport final
@@ -86,7 +87,6 @@ class ImpSdrPdfImport final
         double d() const { return md; }
         double e() const { return me; }
         double f() const { return mf; }
-
         /// Mutliply this * other.
         void Concatinate(const Matrix& other)
         {
@@ -156,7 +156,6 @@ class ImpSdrPdfImport final
     /// Correct the vertical coordinate to start at the top.
     /// PDF coordinate system has orign at the bottom right.
     double correctVertOrigin(double offsetPts) const { return mdPageHeightPts - offsetPts; }
-
     /// Convert PDF points to logic (twips).
     Rectangle PointsToLogic(double left, double right, double top, double bottom) const;
     Point PointsToLogic(double x, double y) const;
@@ -165,11 +164,12 @@ class ImpSdrPdfImport final
     void checkClip();
     bool isClip() const;
 
-    void ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
-    void ImportForm(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
+    void ImportPdfObject(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage,
+                         int nPageObjectIndex);
+    void ImportForm(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage, int nPageObjectIndex);
     void ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
     void ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
-    void ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
+    void ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage, int nPageObjectIndex);
     void ImportText(const Point& rPos, const Size& rSize, const OUString& rStr);
 
     void SetupPageScale(const double dPageWidth, const double dPageHeight);
@@ -193,7 +193,6 @@ public:
     ~ImpSdrPdfImport();
 
     int GetPageCount() const { return mnPageCount; }
-
     size_t DoImport(SdrObjList& rDestList, size_t nInsPos, int nPageNumber,
                     SvdProgressInfo* pProgrInfo = nullptr);
 };
commit 492c9c866c74cd5b2a1075b261ede2f094ad836a
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Wed Apr 18 21:27:27 2018 -0400

    svx: correctly possition form objects from PDF
    
    Change-Id: I7d216ca61b8a10219628877db7dd593a4987ef60

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 77aabd9d0f8b..33d6747e2a7f 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -1021,12 +1021,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)
@@ -1051,6 +1061,16 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
 
     const 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
 
@@ -1065,14 +1085,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);
@@ -1297,6 +1309,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;
@@ -1307,19 +1321,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 5caf4a1a03f5..a3c3cb6d4080 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;
     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.
commit 1019281ee05a5ac0eadc7acd8fab341347f57909
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Apr 15 21:56:49 2018 -0400

    svx: support importing forms from PDFs
    
    Still missing the context matrix transformations.
    
    Change-Id: Id9457c6475463127d3bc444f36fa373a6ec8fcb6

diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1
index 02e0b44c3e87..09f609320169 100644
--- a/external/pdfium/edit.patch.1
+++ b/external/pdfium/edit.patch.1
@@ -110,6 +110,31 @@ index 8bb5bf5..9b5e2ce 100644
 +  fprintf(stderr, "PageObject BB: %f, %f, %f, %f\n", rc.left, rc.right, rc.top, rc.bottom);
    return rect.GetOuterRect();
  }
+diff --git a/core/fpdfapi/page/cpdf_pageobjectlist.cpp b/core/fpdfapi/page/cpdf_pageobjectlist.cpp
+index afd2c98..2c8e061 100644
+--- a/core/fpdfapi/page/cpdf_pageobjectlist.cpp
++++ b/core/fpdfapi/page/cpdf_pageobjectlist.cpp
+@@ -8,6 +8,6 @@
+ 
+ #include "third_party/base/stl_util.h"
+ 
+-CPDF_PageObject* CPDF_PageObjectList::GetPageObjectByIndex(int index) {
++CPDF_PageObject* CPDF_PageObjectList::GetPageObjectByIndex(int index) const {
+   return pdfium::IndexInBounds(*this, index) ? (*this)[index].get() : nullptr;
+ }
+diff --git a/core/fpdfapi/page/cpdf_pageobjectlist.h b/core/fpdfapi/page/cpdf_pageobjectlist.h
+index b450537..77c7d81 100644
+--- a/core/fpdfapi/page/cpdf_pageobjectlist.h
++++ b/core/fpdfapi/page/cpdf_pageobjectlist.h
+@@ -15,7 +15,7 @@ class CPDF_PageObject;
+ class CPDF_PageObjectList
+     : public std::deque<std::unique_ptr<CPDF_PageObject>> {
+  public:
+-  CPDF_PageObject* GetPageObjectByIndex(int index);
++  CPDF_PageObject* GetPageObjectByIndex(int index) const;
+ };
+ 
+ #endif  // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTLIST_H_
 diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
 index 0a01ae0..6947e3a 100644
 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -174,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..f86201d 100644
+index ca2cf3f..8ecab60 100644
 --- a/fpdfsdk/fpdfeditpage.cpp
 +++ b/fpdfsdk/fpdfeditpage.cpp
 @@ -11,12 +11,14 @@
@@ -192,7 +217,7 @@ index ca2cf3f..f86201d 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,157 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
+@@ -363,3 +365,187 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
    *top = bbox.top;
    return true;
  }
@@ -350,6 +375,36 @@ index ca2cf3f..f86201d 100644
 +
 +  return true;
 +}
++
++FPDF_EXPORT int FPDF_CALLCONV
++FPDFFormObj_CountSubObjects(FPDF_PAGEOBJECT form_object)
++{
++  CPDF_FormObject* pFrmObj = CPDFFormObjectFromFPDFPageObject(form_object);
++  if (pFrmObj)
++  {
++    const CPDF_PageObjectList* pObjectList = pFrmObj->form()->GetPageObjectList();
++    if (pObjectList)
++        return pObjectList->size();
++  }
++
++  return 0;
++}
++
++FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV
++FPDFFormObj_GetSubObject(FPDF_PAGEOBJECT form_object, int index)
++{
++  CPDF_FormObject* pFrmObj = CPDFFormObjectFromFPDFPageObject(form_object);
++  if (pFrmObj)
++  {
++    const CFX_Matrix& matrix = pFrmObj->form_matrix();
++    fprintf(stderr, "Form matrix a: %f, b: %f, c: %f, d: %f, e: %f, f: %f\n", matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
++    const CPDF_PageObjectList* pObjectList = pFrmObj->form()->GetPageObjectList();
++    if (pObjectList)
++        return pObjectList->GetPageObjectByIndex(index);
++  }
++
++  return nullptr;
++}
 diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
 index a291987..0202284 100644
 --- a/fpdfsdk/fpdfeditpath.cpp
@@ -462,10 +517,10 @@ index 68bf4f8..e073b20 100644
                                                          int index,
                                                          double* left,
 diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
-index e890aa0..709bea3 100644
+index e890aa0..b62283f 100644
 --- a/fpdfsdk/fpdfview.cpp
 +++ b/fpdfsdk/fpdfview.cpp
-@@ -336,6 +336,11 @@ CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
+@@ -336,6 +336,16 @@ CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
  #endif  // PDF_ENABLE_XFA
  }
  
@@ -474,32 +529,40 @@ index e890aa0..709bea3 100644
 +  return obj ? obj->AsText() : nullptr;
 +}
 +
++CPDF_FormObject* CPDFFormObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
++  auto* obj = CPDFPageObjectFromFPDFPageObject(page_object);
++  return obj ? obj->AsForm() : nullptr;
++}
++
  CPDF_PathObject* CPDFPathObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
    auto* obj = CPDFPageObjectFromFPDFPageObject(page_object);
    return obj ? obj->AsPath() : nullptr;
 diff --git a/fpdfsdk/fsdk_define.h b/fpdfsdk/fsdk_define.h
-index 77c2315..db3e734 100644
+index 77c2315..b61f447 100644
 --- a/fpdfsdk/fsdk_define.h
 +++ b/fpdfsdk/fsdk_define.h
-@@ -25,6 +25,7 @@ class CPDF_Annot;
+@@ -25,6 +25,8 @@ class CPDF_Annot;
  class CPDF_Page;
  class CPDF_PageObject;
  class CPDF_PageRenderContext;
 +class CPDF_TextObject;
++class CPDF_FormObject;
  class CPDF_PathObject;
  class CPDF_Stream;
  class IFSDK_PAUSE_Adapter;
-@@ -65,6 +66,8 @@ FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc);
+@@ -65,6 +67,10 @@ FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc);
  
  CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page);
  
 +CPDF_TextObject* CPDFTextObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
 +
++CPDF_FormObject* CPDFFormObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
++
  CPDF_PathObject* CPDFPathObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
  
  CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
 diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
-index 54735a3..c0231c2 100644
+index 54735a3..1b933bb 100644
 --- a/public/fpdf_edit.h
 +++ b/public/fpdf_edit.h
 @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path,
@@ -555,7 +618,7 @@ index 54735a3..c0231c2 100644
  // Create a new text object using one of the standard PDF fonts.
  //
  // document   - handle to the document.
-@@ -761,6 +800,77 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
+@@ -761,6 +800,94 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
                            FPDF_FONT font,
                            float font_size);
  
@@ -630,6 +693,23 @@ index 54735a3..c0231c2 100644
 +                     unsigned int* B,
 +                     unsigned int* A);
 +
++// Get number of page objects inside the form object.
++//
++// form_object - Handle to a form object. Returned by FPDFPage_GetObject.
++// Return value:
++// The number of the page objects.
++FPDF_EXPORT int FPDF_CALLCONV
++FPDFFormObj_CountSubObjects(FPDF_PAGEOBJECT form_object);
++
++// Get the page object from a form object.
++//
++// form_object - Handle to a form object. Returned by FPDFPage_GetObject.
++// index - The index of a page object.
++// Return value:
++// The handle of the page object. Null for failed.
++FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV
++FPDFFormObj_GetSubObject(FPDF_PAGEOBJECT form_object, int index);
++
  #ifdef __cplusplus
  }  // extern "C"
  #endif  // __cplusplus
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 03b6f3623a14..77aabd9d0f8b 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -226,32 +226,7 @@ void ImpSdrPdfImport::DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pAc
         for (int nPageObjectIndex = 0; nPageObjectIndex < nPageObjectCount; ++nPageObjectIndex)
         {
             FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(pPdfPage, nPageObjectIndex);
-            if (pPageObject == nullptr)
-                continue;
-
-            const int nPageObjectType = FPDFPageObj_GetType(pPageObject);
-            switch (nPageObjectType)
-            {
-                case FPDF_PAGEOBJ_TEXT:
-                    ImportText(pPageObject, nPageObjectIndex);
-                    break;
-                case FPDF_PAGEOBJ_PATH:
-                    ImportPath(pPageObject, nPageObjectIndex);
-                    break;
-                case FPDF_PAGEOBJ_IMAGE:
-                    ImportImage(pPageObject, nPageObjectIndex);
-                    break;
-                case FPDF_PAGEOBJ_SHADING:
-                    SAL_WARN("sd.filter", "Got page object SHADING: " << nPageObjectIndex);
-                    break;
-                case FPDF_PAGEOBJ_FORM:
-                    SAL_WARN("sd.filter", "Got page object FORM: " << nPageObjectIndex);
-                    break;
-                default:
-                    SAL_WARN("sd.filter", "Unknown PDF page object type: "
-                                              << nPageObjectType << ": " << nPageObjectIndex);
-                    break;
-            }
+            ImportPdfObject(pPageObject, nPageObjectIndex);
         }
 
 #if 0
@@ -1011,6 +986,49 @@ void ImpSdrPdfImport::checkClip()
 }
 
 bool ImpSdrPdfImport::isClip() const { return !maClip.getB2DRange().isEmpty(); }
+
+void ImpSdrPdfImport::ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
+{
+    if (pPageObject == nullptr)
+        return;
+
+    const int nPageObjectType = FPDFPageObj_GetType(pPageObject);
+    switch (nPageObjectType)
+    {
+        case FPDF_PAGEOBJ_TEXT:
+            ImportText(pPageObject, nPageObjectIndex);
+            break;
+        case FPDF_PAGEOBJ_PATH:
+            ImportPath(pPageObject, nPageObjectIndex);
+            break;
+        case FPDF_PAGEOBJ_IMAGE:
+            ImportImage(pPageObject, nPageObjectIndex);
+            break;
+        case FPDF_PAGEOBJ_SHADING:
+            SAL_WARN("sd.filter", "Got page object SHADING: " << nPageObjectIndex);
+            break;
+        case FPDF_PAGEOBJ_FORM:
+            ImportForm(pPageObject, nPageObjectIndex);
+            break;
+        default:
+            SAL_WARN("sd.filter", "Unknown PDF page object #" << nPageObjectIndex
+                                                              << " of type: " << nPageObjectType);
+            break;
+    }
+}
+
+void ImpSdrPdfImport::ImportForm(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
+{
+    SAL_WARN("sd.filter", "Got page object FORM: " << nPageObjectIndex);
+
+    const int nCount = FPDFFormObj_CountSubObjects(pPageObject);
+    for (int nIndex = 0; nIndex < nCount; ++nIndex)
+    {
+        FPDF_PAGEOBJECT pFormObject = FPDFFormObj_GetSubObject(pPageObject, nIndex);
+        ImportPdfObject(pFormObject, -1);
+    }
+}
+
 void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
 {
     SAL_WARN("sd.filter", "Got page object TEXT: " << nPageObjectIndex);
diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx
index e9debb2364c7..5caf4a1a03f5 100644
--- a/svx/source/svdraw/svdpdf.hxx
+++ b/svx/source/svdraw/svdpdf.hxx
@@ -100,13 +100,14 @@ class ImpSdrPdfImport final
     void checkClip();
     bool isClip() const;
 
+    void ImportPdfObject(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
+    void ImportForm(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
     void ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
-    void SetupPageScale(const double dPageWidth, const double dPageHeight);
-
     void ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
-
     void ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
     void ImportText(const Point& rPos, const Size& rSize, const OUString& rStr);
+
+    void SetupPageScale(const double dPageWidth, const double dPageHeight);
     void SetAttributes(SdrObject* pObj, bool bForceTextAttr = false);
     void InsertObj(SdrObject* pObj, bool bScale = true);
     void MapScaling();
commit efa8d2000e70a045757df5514afff9f5aa0026b9
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Apr 15 20:32:52 2018 -0400

    sd: support breaking any PDF page
    
    Change-Id: Ifa5f58163bef209a988fc0f88e2b609b1973e0d4

diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index fabd2d412c86..03b6f3623a14 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -204,16 +204,17 @@ ImpSdrPdfImport::~ImpSdrPdfImport()
     FPDF_DestroyLibrary();
 }
 
-void ImpSdrPdfImport::DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport)
+void ImpSdrPdfImport::DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport,
+                                    int nPageIndex)
 {
     const int nPageCount = FPDF_GetPageCount(mpPdfDocument);
-    SAL_WARN("sd.filter", "Pages: " << nPageCount);
-    for (size_t nPageIndex = 0; nPageIndex <= 0; ++nPageIndex)
+    SAL_WARN("sd.filter", "Importing page " << nPageIndex << " of " << nPageCount);
+    if (nPageCount > 0 && nPageIndex >= 0 && nPageIndex < nPageCount)
     {
         // Render next page.
         FPDF_PAGE pPdfPage = FPDF_LoadPage(mpPdfDocument, nPageIndex);
         if (pPdfPage == nullptr)
-            break;
+            return;
 
         const double dPageWidth = FPDF_GetPageWidth(pPdfPage);
         const double dPageHeight = FPDF_GetPageHeight(pPdfPage);
@@ -479,7 +480,7 @@ void ImpSdrPdfImport::SetupPageScale(const double dPageWidth, const double dPage
     //                                 << "(" << mfScaleY << ")");
 }
 
-size_t ImpSdrPdfImport::DoImport(SdrObjList& rOL, size_t nInsPos, size_t nPageNumber,
+size_t ImpSdrPdfImport::DoImport(SdrObjList& rOL, size_t nInsPos, int nPageNumber,
                                  SvdProgressInfo* pProgrInfo)
 {
     if (pProgrInfo)
@@ -490,7 +491,7 @@ size_t ImpSdrPdfImport::DoImport(SdrObjList& rOL, size_t nInsPos, size_t nPageNu
     sal_uInt32 nActionsToReport(0);
 
     // execute
-    DoLoopActions(pProgrInfo, &nActionsToReport);
+    DoLoopActions(pProgrInfo, &nActionsToReport, nPageNumber);
 
     if (pProgrInfo)
     {
diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx
index e0366deeef46..e9debb2364c7 100644
--- a/svx/source/svdraw/svdpdf.hxx
+++ b/svx/source/svdraw/svdpdf.hxx
@@ -115,7 +115,7 @@ class ImpSdrPdfImport final
     bool CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly);
     bool CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon& rPolyPolygon);
 
-    void DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport);
+    void DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pActionsToReport, int nPageIndex);
 
     // Copy assignment is forbidden and not implemented.
     ImpSdrPdfImport(const ImpSdrPdfImport&) = delete;
@@ -128,7 +128,7 @@ public:
 
     int GetPageCount() const { return mnPageCount; }
 
-    size_t DoImport(SdrObjList& rDestList, size_t nInsPos, size_t nPageNumber,
+    size_t DoImport(SdrObjList& rDestList, size_t nInsPos, int nPageNumber,
                     SvdProgressInfo* pProgrInfo = nullptr);
 };
 
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index 8d5e28a30776..beb950b79d81 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -122,7 +122,7 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic)
     , maSvgData(rImpGraphic.maSvgData)
     , mpPdfData(rImpGraphic.mpPdfData)
     , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
-    , mnPageNumber(-1)
+    , mnPageNumber(rImpGraphic.mnPageNumber)
 {
     if( rImpGraphic.mpGfxLink )
         mpGfxLink = o3tl::make_unique<GfxLink>( *rImpGraphic.mpGfxLink );
@@ -149,7 +149,7 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic)
     , maSvgData(std::move(rImpGraphic.maSvgData))
     , mpPdfData(std::move(rImpGraphic.mpPdfData))
     , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
-    , mnPageNumber(-1)
+    , mnPageNumber(rImpGraphic.mnPageNumber)
 {
     rImpGraphic.ImplClear();
     rImpGraphic.mbDummyContext = false;
commit 6fd71a520bb14d327723758892a9df608d60b291
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Apr 15 11:11:33 2018 -0400

    svx: path line width is given as full thickness in PDF
    
    Change-Id: I728d962ea65ad1671e3b4c76034d396bee84228e

diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index f0674ca9a694..fabd2d412c86 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -1358,6 +1358,7 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
     const double dWidth = fabs(sqrt2(a, c) * fWidth);
     SAL_WARN("sd.filter", "Path Stroke Width scaled: " << dWidth);
     mnLineWidth = lcl_ToLogic(lcl_PointToPixel(dWidth));
+    mnLineWidth /= 2;
 
     unsigned int nR;
     unsigned int nG;
commit fe0b9d7df5f5deb50c34141cb3f5c320fe914086
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Apr 15 10:51:39 2018 -0400

    svx: support color text for imported PDFs
    
    Change-Id: I01cba9456b37bd7a63c823bbe332d686f7ede389

diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1
index 96e0fa4f9725..02e0b44c3e87 100644
--- a/external/pdfium/edit.patch.1
+++ b/external/pdfium/edit.patch.1
@@ -1,12 +1,73 @@
+diff --git a/core/fpdfapi/page/cpdf_colorstate.cpp b/core/fpdfapi/page/cpdf_colorstate.cpp
+index 693fcf1..d3e1202 100644
+--- a/core/fpdfapi/page/cpdf_colorstate.cpp
++++ b/core/fpdfapi/page/cpdf_colorstate.cpp
+@@ -74,6 +74,8 @@ void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS,
+                                    uint32_t nValues) {
+   ColorData* pData = m_Ref.GetPrivateCopy();
+   SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues);
++  if (pData->m_FillRGB != 0 && pData->m_FillRGB != 0xFFFFFFFF)
++    fprintf(stderr, "COLOR FILL!!!!> %x\n", pData->m_FillRGB);
+ }
+ 
+ void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS,
+@@ -81,6 +83,8 @@ void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS,
+                                      uint32_t nValues) {
+   ColorData* pData = m_Ref.GetPrivateCopy();
+   SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues);
++  if (pData->m_StrokeRGB != 0 && pData->m_StrokeRGB != 0xFFFFFFFF)
++    fprintf(stderr, "COLOR STROkE!!!!> %x\n", pData->m_StrokeRGB);
+ }
+ 
+ void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern,
+@@ -99,6 +103,8 @@ void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern,
+     }
+   }
+   pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : 0xFFFFFFFF;
++  if (pData->m_FillRGB != 0 && pData->m_FillRGB != 0xFFFFFFFF)
++    fprintf(stderr, "COLOR FILL!!!!> %x\n", pData->m_FillRGB);
+ }
+ 
+ void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern,
+@@ -118,13 +124,15 @@ void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern,
+   }
+   pData->m_StrokeRGB =
+       pData->m_StrokeColor.GetRGB(&R, &G, &B) ? FXSYS_RGB(R, G, B) : 0xFFFFFFFF;
++  if (pData->m_StrokeRGB != 0 && pData->m_StrokeRGB != 0xFFFFFFFF)
++    fprintf(stderr, "COLOR STROkE!!!!> %x\n", pData->m_StrokeRGB);
+ }
+ 
+ void CPDF_ColorState::SetColor(CPDF_Color& color,
+                                uint32_t& rgb,
+                                CPDF_ColorSpace* pCS,
+                                float* pValue,
+-                               uint32_t nValues) {
++                               uint32_t nValues) const {
+   if (pCS)
+     color.SetColorSpace(pCS);
+   else if (color.IsNull())
+diff --git a/core/fpdfapi/page/cpdf_colorstate.h b/core/fpdfapi/page/cpdf_colorstate.h
+index 9619051..dbe9c47 100644
+--- a/core/fpdfapi/page/cpdf_colorstate.h
++++ b/core/fpdfapi/page/cpdf_colorstate.h
+@@ -64,7 +64,7 @@ class CPDF_ColorState {
+                 uint32_t& rgb,
+                 CPDF_ColorSpace* pCS,
+                 float* pValue,
+-                uint32_t nValues);
++                uint32_t nValues) const;
+ 
+   SharedCopyOnWrite<ColorData> m_Ref;
+ };
 diff --git a/core/fpdfapi/page/cpdf_imageobject.cpp b/core/fpdfapi/page/cpdf_imageobject.cpp
-index 3b5a740..58ef90a 100644
+index 3b5a740..416d82d 100644
 --- a/core/fpdfapi/page/cpdf_imageobject.cpp
 +++ b/core/fpdfapi/page/cpdf_imageobject.cpp
 @@ -43,6 +43,7 @@ const CPDF_ImageObject* CPDF_ImageObject::AsImage() const {
  void CPDF_ImageObject::CalcBoundingBox() {
    std::tie(m_Left, m_Right, m_Top, m_Bottom) =
        m_Matrix.TransformRect(0.f, 1.f, 1.f, 0.f);
-+    fprintf(stderr, "Image BB: %f, %f, %f, %f\n", m_Left, m_Right, m_Top, m_Bottom);
++    // fprintf(stderr, "Image BB: %f, %f, %f, %f\n", m_Left, m_Right, m_Top, m_Bottom);
  }
  
  void CPDF_ImageObject::SetImage(const RetainPtr<CPDF_Image>& pImage) {
@@ -62,14 +123,14 @@ index 0a01ae0..6947e3a 100644
      DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size,
                              &text_matrix, bFill, bStroke);
 diff --git a/core/fxge/cfx_pathdata.cpp b/core/fxge/cfx_pathdata.cpp
-index 4ac5cf6..28ea81f 100644
+index 4ac5cf6..4286de4 100644
 --- a/core/fxge/cfx_pathdata.cpp
 +++ b/core/fxge/cfx_pathdata.cpp
 @@ -199,6 +199,7 @@ void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix) {
  void CFX_PathData::AppendPoint(const CFX_PointF& point,
                                 FXPT_TYPE type,
                                 bool closeFigure) {
-+  fprintf(stderr, "Append: %f, %f (%s)\n", point.x, point.y, closeFigure ? "CLOSE" : "OPEN");
++//   fprintf(stderr, "Append: %f, %f (%s)\n", point.x, point.y, closeFigure ? "CLOSE" : "OPEN");
    m_Points.push_back(FX_PATHPOINT(point, type, closeFigure));
  }
  
@@ -77,7 +138,7 @@ index 4ac5cf6..28ea81f 100644
  void CFX_PathData::Transform(const CFX_Matrix* pMatrix) {
    if (!pMatrix)
      return;
-+  fprintf(stderr, "XForm: %f, %f %f, %f, %f, %f\n", pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, pMatrix->e, pMatrix->f);
++//   fprintf(stderr, "XForm: %f, %f %f, %f, %f, %f\n", pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, pMatrix->e, pMatrix->f);
    for (auto& point : m_Points)
      point.m_Point = pMatrix->Transform(point.m_Point);
  }
@@ -113,7 +174,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..e7d633f 100644
+index ca2cf3f..f86201d 100644
 --- a/fpdfsdk/fpdfeditpage.cpp
 +++ b/fpdfsdk/fpdfeditpage.cpp
 @@ -11,12 +11,14 @@
@@ -131,7 +192,7 @@ index ca2cf3f..e7d633f 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,128 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
+@@ -363,3 +365,157 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
    *top = bbox.top;
    return true;
  }
@@ -242,22 +303,51 @@ index ca2cf3f..e7d633f 100644
 +}
 +
 +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
-+FPDFTextObj_GetStrokeColor(FPDF_PAGEOBJECT text_object,
-+                           unsigned int* R,
-+                           unsigned int* G,
-+                           unsigned int* B,
-+                           unsigned int* A)
++FPDFTextObj_GetColor(FPDF_PAGEOBJECT text_object,
++                     unsigned int* R,
++                     unsigned int* G,
++                     unsigned int* B,
++                     unsigned int* A)
 +{
 +  CPDF_TextObject* pTxtObj = CPDFTextObjectFromFPDFPageObject(text_object);
 +  if (!pTxtObj || !R || !G || !B || !A)
 +    return false;
 +
-+  const uint32_t strokeRGB = pTxtObj->m_ColorState.GetStrokeRGB();
-+  *R = FXSYS_GetRValue(strokeRGB);
-+  *G = FXSYS_GetGValue(strokeRGB);
-+  *B = FXSYS_GetBValue(strokeRGB);
++  bool bFill = false;
++  bool bStroke = false;
++  CPDF_Font* pFont = pTxtObj->m_TextState.GetFont();
++  const TextRenderingMode text_render_mode = pTxtObj->m_TextState.GetTextMode();
++  switch (text_render_mode)
++  {
++    case TextRenderingMode::MODE_FILL:
++    case TextRenderingMode::MODE_FILL_CLIP:
++      bFill = true;
++      break;
++    case TextRenderingMode::MODE_STROKE:
++    case TextRenderingMode::MODE_STROKE_CLIP:
++      if (pFont->GetFace())
++        bStroke = true;
++      else
++        bFill = true;
++      break;
++    case TextRenderingMode::MODE_FILL_STROKE:
++    case TextRenderingMode::MODE_FILL_STROKE_CLIP:
++      bFill = true;
++      if (pFont->GetFace())
++        bStroke = true;
++      break;
++    case TextRenderingMode::MODE_INVISIBLE:
++    case TextRenderingMode::MODE_CLIP:
++      return false;
++  }
++
++  const uint32_t RGB = bStroke ? pTxtObj->m_ColorState.GetStrokeRGB() : pTxtObj->m_ColorState.GetFillRGB();
++  *R = FXSYS_GetRValue(RGB);
++  *G = FXSYS_GetGValue(RGB);
++  *B = FXSYS_GetBValue(RGB);
 +  *A = static_cast<unsigned int>(
 +      (pTxtObj->m_GeneralState.GetStrokeAlpha() * 255.f) + 0.5f);
++
 +  return true;
 +}
 diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
@@ -409,7 +499,7 @@ index 77c2315..db3e734 100644
  
  CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
 diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
-index 54735a3..c86b638 100644
+index 54735a3..c0231c2 100644
 --- a/public/fpdf_edit.h
 +++ b/public/fpdf_edit.h
 @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path,
@@ -534,11 +624,11 @@ index 54735a3..c86b638 100644
 +//
 +// Returns TRUE on success.
 +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
-+FPDFTextObj_GetStrokeColor(FPDF_PAGEOBJECT text_object,
-+                           unsigned int* R,
-+                           unsigned int* G,
-+                           unsigned int* B,
-+                           unsigned int* A);
++FPDFTextObj_GetColor(FPDF_PAGEOBJECT text_object,
++                     unsigned int* R,
++                     unsigned int* G,
++                     unsigned int* B,
++                     unsigned int* A);
 +
  #ifdef __cplusplus
  }  // extern "C"
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 32672d7223e1..f0674ca9a694 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -1030,7 +1030,7 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
         return;
     }
 
-    const tools::Rectangle aRect = PointsToLogic(left, right, top, bottom);
+    const Rectangle aRect = PointsToLogic(left, right, top, bottom);
 
     const int nChars = FPDFTextObj_CountChars(pPageObject);
     std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null
@@ -1066,13 +1066,25 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
     dFontSizeV = lcl_ToLogic(dFontSizeV);
     SAL_WARN("sd.filter", "Got Logic Font Size H: " << dFontSizeH << ", V: " << dFontSizeV);
 
+    const Size aFontSize(dFontSizeH, dFontSizeV);
+    vcl::Font aFnt = mpVD->GetFont();
+    if (aFontSize != aFnt.GetFontSize())
+    {
+        aFnt.SetFontSize(aFontSize);
+        mpVD->SetFont(aFnt);
+        mbFntDirty = true;
+    }
+
+    Color aTextColor(COL_TRANSPARENT);
     unsigned int nR, nG, nB, nA;
-    if (FPDFTextObj_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA))
-        mpVD->SetTextColor(Color(nR, nG, nB));
+    if (FPDFTextObj_GetColor(pPageObject, &nR, &nG, &nB, &nA))
+        aTextColor = Color(nR, nG, nB);
 
-    vcl::Font aFnt = mpVD->GetFont();
-    aFnt.SetFontSize(Size(dFontSizeH, dFontSizeV));
-    mpVD->SetFont(aFnt);
+    if (aTextColor != mpVD->GetTextColor())
+    {
+        mpVD->SetTextColor(aTextColor);
+        mbFntDirty = true;
+    }
 
     ImportText(aRect.TopLeft(), aRect.GetSize(), sText);
 }
@@ -1375,14 +1387,14 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
 Point ImpSdrPdfImport::PointsToLogic(double x, double y) const
 {
     y = correctVertOrigin(y);
-    SAL_WARN("sd.filter", "Corrected point x: " << x << ", y: " << y);
+    // SAL_WARN("sd.filter", "Corrected point x: " << x << ", y: " << y);
     x = lcl_PointToPixel(x);
     y = lcl_PointToPixel(y);
 
-    SAL_WARN("sd.filter", "Pixel point x: " << x << ", y: " << y);
+    // SAL_WARN("sd.filter", "Pixel point x: " << x << ", y: " << y);
 
     Point aPos(lcl_ToLogic(x), lcl_ToLogic(y));
-    SAL_WARN("sd.filter", "Logical Pos: " << aPos);
+    // SAL_WARN("sd.filter", "Logical Pos: " << aPos);
 
     return aPos;
 }
@@ -1392,24 +1404,20 @@ Rectangle ImpSdrPdfImport::PointsToLogic(double left, double right, double top,
 {
     top = correctVertOrigin(top);
     bottom = correctVertOrigin(bottom);
-    SAL_WARN("sd.filter", "Corrected bounds left: " << left << ", right: " << right
-                                                    << ", top: " << top << ", bottom: " << bottom);
+    // SAL_WARN("sd.filter", "Corrected bounds left: " << left << ", right: " << right
+    //                                                 << ", top: " << top << ", bottom: " << bottom);
     left = lcl_PointToPixel(left);
     right = lcl_PointToPixel(right);
     top = lcl_PointToPixel(top);
     bottom = lcl_PointToPixel(bottom);
-    // if (top > bottom)
-    //     std::swap(top, bottom);
-    // if (left > right)
-    //     std::swap(left, right);
 
-    SAL_WARN("sd.filter", "Pixel bounds left: " << left << ", right: " << right << ", top: " << top
-                                                << ", bottom: " << bottom);
+    // SAL_WARN("sd.filter", "Pixel bounds left: " << left << ", right: " << right << ", top: " << top
+    //                                             << ", bottom: " << bottom);
 
     Point aPos(lcl_ToLogic(left), lcl_ToLogic(top));
     Size aSize(lcl_ToLogic(right - left), lcl_ToLogic(bottom - top));
     Rectangle aRect(aPos, aSize);
-    SAL_WARN("sd.filter", "Logical BBox: " << aRect);
+    // SAL_WARN("sd.filter", "Logical BBox: " << aRect);
 
     return aRect;
 }
commit 7987a05ab686e332fa0419b70c340b4382b8e6a7
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat Apr 14 16:20:11 2018 -0400

    svx: more accurate PDF imported text size
    
    Change-Id: I22880afdd9d36d9096003d86bba15098b465e0b3

diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 8481093d6d63..32672d7223e1 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -1030,6 +1030,8 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
         return;
     }
 
+    const tools::Rectangle aRect = PointsToLogic(left, right, top, bottom);
+
     const int nChars = FPDFTextObj_CountChars(pPageObject);
     std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null
 
@@ -1050,6 +1052,7 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
                                                     << ", " << 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);
@@ -1071,10 +1074,10 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
     aFnt.SetFontSize(Size(dFontSizeH, dFontSizeV));
     mpVD->SetFont(aFnt);
 
-    ImportText(aPos, sText);
+    ImportText(aRect.TopLeft(), aRect.GetSize(), sText);
 }
 
-void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr)
+void ImpSdrPdfImport::ImportText(const Point& rPos, const Size& rSize, const OUString& rStr)
 {
     // calc text box size, add 5% to make it fit safely
 
@@ -1089,6 +1092,7 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr)
                                     << ", Scaled: " << nTextWidth << 'x' << nTextHeight);
 
     Point aPos(FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()));
+    Size bSize(FRound(rSize.Width() * mfScaleX), FRound(rSize.Height() * mfScaleY));
     Size aSize(nTextWidth, nTextHeight);
 
     if (eAlg == ALIGN_BASELINE)
@@ -1096,8 +1100,11 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr)
     else if (eAlg == ALIGN_BOTTOM)
         aPos.Y() -= nTextHeight;
 
-    Rectangle aTextRect(aPos, aSize);
-    SAL_WARN("sd.filter", "Text Rect: " << aTextRect);
+    SAL_WARN("sd.filter", "Final POS: " << aPos);
+    SAL_WARN("sd.filter", "Final Text Size: " << aSize);
+    SAL_WARN("sd.filter", "Final Bound Size: " << bSize);
+    Rectangle aTextRect(aPos, bSize);
+    // SAL_WARN("sd.filter", "Text Rect: " << aTextRect);
     SdrRectObj* pText = new SdrRectObj(OBJ_TEXT, aTextRect);
 
     pText->SetMergedItem(makeSdrTextUpperDistItem(0));
diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx
index 8bce23449a06..e0366deeef46 100644
--- a/svx/source/svdraw/svdpdf.hxx
+++ b/svx/source/svdraw/svdpdf.hxx
@@ -106,7 +106,7 @@ class ImpSdrPdfImport final
     void ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
 
     void ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex);
-    void ImportText(const Point& rPos, const OUString& rStr);
+    void ImportText(const Point& rPos, const Size& rSize, const OUString& rStr);
     void SetAttributes(SdrObject* pObj, bool bForceTextAttr = false);
     void InsertObj(SdrObject* pObj, bool bScale = true);
     void MapScaling();
commit 368873cb1d4b551f8ce0365162545fb3c8079b99
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat Apr 14 11:40:18 2018 -0400

    svx: correct the positioning of PDF Paths and the stroke width
    
    Change-Id: I5b150721cc1b61b028f282062c1466ef6a67fcae

diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1
index 982560a3fab7..96e0fa4f9725 100644
--- a/external/pdfium/edit.patch.1
+++ b/external/pdfium/edit.patch.1
@@ -10,6 +10,33 @@ index 3b5a740..58ef90a 100644
  }
  
  void CPDF_ImageObject::SetImage(const RetainPtr<CPDF_Image>& pImage) {
+diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
+index ba93f4a..70d398b 100644
+--- a/core/fpdfapi/page/cpdf_page.cpp
++++ b/core/fpdfapi/page/cpdf_page.cpp
+@@ -35,12 +35,14 @@ CPDF_Page::CPDF_Page(CPDF_Document* pDocument,
+   CFX_FloatRect mediabox = GetBox("MediaBox");
+   if (mediabox.IsEmpty())
+     mediabox = CFX_FloatRect(0, 0, 612, 792);
++  fprintf(stderr, "Page mediabox: %f, %f, %f, %f\n", mediabox.left, mediabox.right, mediabox.top, mediabox.bottom);
+ 
+   m_BBox = GetBox("CropBox");
+   if (m_BBox.IsEmpty())
+     m_BBox = mediabox;
+   else
+     m_BBox.Intersect(mediabox);
++  fprintf(stderr, "Page cropbox: %f, %f, %f, %f\n", m_BBox.left, m_BBox.right, m_BBox.top, m_BBox.bottom);
+ 
+   m_PageSize.width = m_BBox.Width();
+   m_PageSize.height = m_BBox.Height();
+@@ -48,6 +50,7 @@ CPDF_Page::CPDF_Page(CPDF_Document* pDocument,
+   int rotate = GetPageRotation();
+   if (rotate % 2)
+     std::swap(m_PageSize.width, m_PageSize.height);
++  fprintf(stderr, "Page rotate: %d, Page Width: %f, Page Height: %f\n", rotate, m_PageSize.width, m_PageSize.height);
+ 
+   switch (rotate) {
+     case 0:
 diff --git a/core/fpdfapi/page/cpdf_pageobject.cpp b/core/fpdfapi/page/cpdf_pageobject.cpp
 index 8bb5bf5..9b5e2ce 100644
 --- a/core/fpdfapi/page/cpdf_pageobject.cpp
@@ -23,17 +50,37 @@ index 8bb5bf5..9b5e2ce 100644
    return rect.GetOuterRect();
  }
 diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
-index 0a01ae0..fad2920 100644
+index 0a01ae0..6947e3a 100644
 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp
 +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
 @@ -1793,6 +1793,7 @@ bool CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj,
      return true;
  
    float font_size = textobj->m_TextState.GetFontSize();
-+  fprintf(stderr, "Font size: %f, matrix a: %f, b: %f, c: %f, d: %f, e: %f, f: %f\n", font_size, text_matrix.a, text_matrix.b, text_matrix.c, text_matrix.d, text_matrix.e, text_matrix.f);
++//   fprintf(stderr, "Font size: %f, matrix a: %f, b: %f, c: %f, d: %f, e: %f, f: %f\n", font_size, text_matrix.a, text_matrix.b, text_matrix.c, text_matrix.d, text_matrix.e, text_matrix.f);
    if (bPattern) {
      DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size,
                              &text_matrix, bFill, bStroke);
+diff --git a/core/fxge/cfx_pathdata.cpp b/core/fxge/cfx_pathdata.cpp
+index 4ac5cf6..28ea81f 100644
+--- a/core/fxge/cfx_pathdata.cpp
++++ b/core/fxge/cfx_pathdata.cpp
+@@ -199,6 +199,7 @@ void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix) {
+ void CFX_PathData::AppendPoint(const CFX_PointF& point,
+                                FXPT_TYPE type,
+                                bool closeFigure) {
++  fprintf(stderr, "Append: %f, %f (%s)\n", point.x, point.y, closeFigure ? "CLOSE" : "OPEN");
+   m_Points.push_back(FX_PATHPOINT(point, type, closeFigure));
+ }
+ 
+@@ -290,6 +291,7 @@ CFX_FloatRect CFX_PathData::GetBoundingBox(float line_width,
+ void CFX_PathData::Transform(const CFX_Matrix* pMatrix) {
+   if (!pMatrix)
+     return;
++  fprintf(stderr, "XForm: %f, %f %f, %f, %f, %f\n", pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, pMatrix->e, pMatrix->f);
+   for (auto& point : m_Points)
+     point.m_Point = pMatrix->Transform(point.m_Point);
+ }
 diff --git a/fpdfsdk/fpdfeditimg.cpp b/fpdfsdk/fpdfeditimg.cpp
 index 0d7ba56..37bdf99 100644
 --- a/fpdfsdk/fpdfeditimg.cpp
@@ -214,7 +261,7 @@ index ca2cf3f..e7d633f 100644
 +  return true;
 +}
 diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
-index a291987..1ac8257 100644
+index a291987..0202284 100644
 --- a/fpdfsdk/fpdfeditpath.cpp
 +++ b/fpdfsdk/fpdfeditpath.cpp
 @@ -101,6 +101,16 @@ FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width) {
@@ -275,14 +322,14 @@ index a291987..1ac8257 100644
 +  if (!path_object || !a || !b || !c || !d || !e || !f)
 +    return false;
 +
-+  auto* pPathObj = CPDFPageObjectFromFPDFPageObject(path_object);
-+  CFX_Matrix* pMatrix = pPathObj->m_GeneralState.GetMutableMatrix();
-+  *a = pMatrix->a;
-+  *b = pMatrix->b;
-+  *c = pMatrix->c;
-+  *d = pMatrix->d;
-+  *e = pMatrix->e;
-+  *f = pMatrix->f;
++  CPDF_PathObject* pPathObj = CPDFPathObjectFromFPDFPageObject(path_object);
++  const CFX_Matrix& pMatrix = pPathObj->m_Matrix;
++  *a = pMatrix.a;
++  *b = pMatrix.b;
++  *c = pMatrix.c;
++  *d = pMatrix.d;
++  *e = pMatrix.e;
++  *f = pMatrix.f;
 +
 +  return true;
 +}
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 2735ae4c94a1..8481093d6d63 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -1276,12 +1276,16 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
                 continue;
             }
 
-            SAL_WARN("sd.filter", "Got point (" << x << ", " << y << ")");
+            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;
 
             const bool bClose = FPDFPathSegment_GetClose(pPathSegment);
+            if (bClose)
+                aPoly.setClosed(bClose); // TODO: Review
             SAL_WARN("sd.filter",
                      "Point corrected (" << x << ", " << y << "): " << (bClose ? "CLOSE" : "OPEN"));
             Point aPoint = PointsToLogic(x, y);
@@ -1331,7 +1335,10 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
 
     float fWidth = 1;
     FPDFPath_GetStrokeWidth(pPageObject, &fWidth);
-    mnLineWidth = lcl_ToLogic(lcl_PointToPixel(fWidth));
+    SAL_WARN("sd.filter", "Path Stroke Width: " << fWidth);
+    const double dWidth = fabs(sqrt2(a, c) * fWidth);
+    SAL_WARN("sd.filter", "Path Stroke Width scaled: " << dWidth);
+    mnLineWidth = lcl_ToLogic(lcl_PointToPixel(dWidth));
 
     unsigned int nR;
     unsigned int nG;
@@ -1353,7 +1360,6 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
 
     // if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
 
-    aPoly.setClosed(true); // TODO: Review
     SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aPoly));
     SetAttributes(pPath);
     InsertObj(pPath, false);
commit 80e1a9981dcd6b43a297518e55887a56343c8090
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Fri Apr 13 20:26:11 2018 -0400

    svx: improved text importing from PDF
    
    Change-Id: I9a2fc2c8511655c1aa362c1a03a5e82ae3ba697e

diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1
index 86cda347f262..982560a3fab7 100644
--- a/external/pdfium/edit.patch.1
+++ b/external/pdfium/edit.patch.1
@@ -66,7 +66,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..8073a18 100644
+index ca2cf3f..e7d633f 100644
 --- a/fpdfsdk/fpdfeditpage.cpp
 +++ b/fpdfsdk/fpdfeditpage.cpp
 @@ -11,12 +11,14 @@
@@ -84,7 +84,7 @@ index ca2cf3f..8073a18 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,123 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
+@@ -363,3 +365,128 @@ FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
    *top = bbox.top;
    return true;
  }
@@ -114,8 +114,11 @@ index ca2cf3f..8073a18 100644
 +                      double* a,
 +                      double* b,
 +                      double* c,
-+                      double* d) {
-+  if (!text_object)
++                      double* d,
++                      double* e,
++                      double* f)
++{
++  if (!text_object || !a || !b || !c || !d || !e || !f)
 +    return;
 +
 +  CPDF_TextObject* pTxtObj = CPDFTextObjectFromFPDFPageObject(text_object);
@@ -124,6 +127,8 @@ index ca2cf3f..8073a18 100644
 +  *b = matrix.b;
 +  *c = matrix.c;
 +  *d = matrix.d;
++  *e = matrix.e;
++  *f = matrix.f;
 +}
 +
 +FPDF_EXPORT int FPDF_CALLCONV
@@ -357,7 +362,7 @@ index 77c2315..db3e734 100644
  
  CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
 diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
-index 54735a3..a415c98 100644
+index 54735a3..c86b638 100644
 --- a/public/fpdf_edit.h
 +++ b/public/fpdf_edit.h
 @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path,
@@ -413,7 +418,7 @@ index 54735a3..a415c98 100644
  // Create a new text object using one of the standard PDF fonts.
  //
  // document   - handle to the document.
-@@ -761,6 +800,73 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
+@@ -761,6 +800,77 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
                            FPDF_FONT font,
                            float font_size);
  
@@ -445,12 +450,16 @@ index 54735a3..a415c98 100644
 +//   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
 +FPDFTextObj_GetMatrix(FPDF_PAGEOBJECT text_object,
 +                      double* a,
 +                      double* b,
 +                      double* c,
-+                      double* d);
++                      double* d,
++                      double* e,
++                      double* f);
 +
 +// Get the unicode of a special character in a text object.
 +//
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 2dfba0f986dc..2735ae4c94a1 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -103,6 +103,8 @@ static inline long lcl_ToLogic(double value)
     const long out = OutputDevice::LogicToLogic(in, MapUnit::MapPixel, MapUnit::Map100thMM);
     return out / 100;
 }
+
+static inline double sqrt2(double a, double b) { return sqrt(a * a + b * b); }
 }
 
 struct FPDFBitmapDeleter
@@ -1020,53 +1022,56 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
         SAL_WARN("sd.filter", "FAILED to get TEXT bounds");
     }
 
-    SAL_WARN("sd.filter", "Got TEXT bounds left: " << left << ", right: " << right
-                                                   << ", top: " << top << ", bottom: " << bottom);
-    Rectangle aRect = PointsToLogic(left, right, top, bottom);
+    if (left == right || top == bottom)
+    {
+        SAL_WARN("sd.filter", "Skipping empty TEXT #" << nPageObjectIndex << " left: " << left
+                                                      << ", right: " << right << ", top: " << top
+                                                      << ", bottom: " << bottom);
+        return;
+    }
 
-    double dFontScale = 1.0;
-    geometry::Matrix2D aMatrix;
-    FPDFTextObj_GetMatrix(pPageObject, &aMatrix.m00, &aMatrix.m01, &aMatrix.m10, &aMatrix.m11);
-    if (aMatrix.m00 != aMatrix.m11 || aMatrix.m00 <= 0)
+    const int nChars = FPDFTextObj_CountChars(pPageObject);
+    std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null
+
+    unsigned short* pShortText = reinterpret_cast<unsigned short*>(pText.get());
+    const int nActualChars = FPDFTextObj_GetText(pPageObject, 0, nChars, pShortText);
+    if (nActualChars <= 0)
     {
-        SAL_WARN("sd.filter", "Bogus font scale matrix (" << aMatrix.m00 << ',' << aMatrix.m11
-                                                          << "), will use heuristic height of "
-                                                          << aRect.GetHeight() << ".");
-        dFontScale = aRect.GetHeight();
+        SAL_WARN("sd.filter", "Got not TEXT");
+        return;
     }
-    else
-        dFontScale = aMatrix.m00;
 
-    double dFontSize = FPDFTextObj_GetFontSize(pPageObject);
-    SAL_WARN("sd.filter", "Got Font Size: " << dFontSize);
-    dFontSize *= dFontScale;
-    SAL_WARN("sd.filter", "Got Font Size Scaled: " << dFontSize);
-    dFontSize = lcl_PointToPixel(dFontSize);
-    SAL_WARN("sd.filter", "Got Font Pixel Size: " << dFontSize);
-    dFontSize = lcl_ToLogic(dFontSize);
-    SAL_WARN("sd.filter", "Got Font Logic Size: " << dFontSize);
+    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);
+
+    const double dFontSize = FPDFTextObj_GetFontSize(pPageObject);
+    double dFontSizeH = fabs(sqrt2(a, c) * dFontSize);
+    double dFontSizeV = fabs(sqrt2(b, d) * dFontSize);
+    SAL_WARN("sd.filter", "Got Font Size: " << dFontSize << ", Scaled Font Size H: " << dFontSizeH
+                                            << ", V: " << dFontSizeV);
+    dFontSizeH = lcl_PointToPixel(dFontSizeH);
+    dFontSizeV = lcl_PointToPixel(dFontSizeV);
+    SAL_WARN("sd.filter", "Got Pixel Font Size H: " << dFontSizeH << ", V: " << dFontSizeV);
+    dFontSizeH = lcl_ToLogic(dFontSizeH);
+    dFontSizeV = lcl_ToLogic(dFontSizeV);
+    SAL_WARN("sd.filter", "Got Logic Font Size H: " << dFontSizeH << ", V: " << dFontSizeV);
 
     unsigned int nR, nG, nB, nA;
     if (FPDFTextObj_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA))
         mpVD->SetTextColor(Color(nR, nG, nB));
 
     vcl::Font aFnt = mpVD->GetFont();
-    aFnt.SetFontSize(Size(dFontSize, dFontSize));
+    aFnt.SetFontSize(Size(dFontSizeH, dFontSizeV));
     mpVD->SetFont(aFnt);
 
-    const int nChars = FPDFTextObj_CountChars(pPageObject);
-    std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nChars + 1]); // + terminating null
-
-    unsigned short* pShortText = reinterpret_cast<unsigned short*>(pText.get());
-    const int nActualChars = FPDFTextObj_GetText(pPageObject, 0, nChars, pShortText);
-    OUString sText(pText.get(), nActualChars);
-
-    // for (int nChar = 0; nChar < nChars; ++nChar)
-    //     pText[nChar] = static_cast<sal_Unicode>(FPDFTextObj_GetUnicode(pPageObject, nChar));
-    // OUString sText(pText.get(), nChars);
-    SAL_WARN("sd.filter", "Got Text (" << nChars << "): [" << sText << "].");
-
-    ImportText(aRect.TopLeft(), sText);
+    ImportText(aPos, sText);
 }
 
 void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr)
@@ -1079,11 +1084,12 @@ void ImpSdrPdfImport::ImportText(const Point& rPos, const OUString& rStr)
 
     sal_Int32 nTextWidth = static_cast<sal_Int32>(mpVD->GetTextWidth(rStr) * mfScaleX);
     sal_Int32 nTextHeight = static_cast<sal_Int32>(mpVD->GetTextHeight() * mfScaleY);
-    SAL_WARN("sd.filter", "TextWidth: " << nTextWidth << ", TextHeight: " << nTextHeight);
+    SAL_WARN("sd.filter",
+             "Unscaled text size: " << mpVD->GetTextWidth(rStr) << 'x' << mpVD->GetTextHeight()
+                                    << ", Scaled: " << nTextWidth << 'x' << nTextHeight);
 
     Point aPos(FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()));
     Size aSize(nTextWidth, nTextHeight);
-    SAL_WARN("sd.filter", "Text Pos: " << aPos << ", Size: " << aSize);
 
     if (eAlg == ALIGN_BASELINE)
         aPos.Y() -= FRound(aFontMetric.GetAscent() * mfScaleY);
commit 6dc1adfb4b6dc79f7a8a195f901078aca2d4e29e
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Fri Apr 13 18:59:56 2018 -0400

    svx: improve path importing from PDF
    
    Change-Id: I8e63b2a35d841e065ef32fea95c0a5f22ca6f049

diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1
index 03b4ab221730..86cda347f262 100644
--- a/external/pdfium/edit.patch.1
+++ b/external/pdfium/edit.patch.1
@@ -209,7 +209,7 @@ index ca2cf3f..8073a18 100644
 +  return true;
 +}
 diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
-index a291987..d3b0bc1 100644
+index a291987..1ac8257 100644
 --- a/fpdfsdk/fpdfeditpath.cpp
 +++ b/fpdfsdk/fpdfeditpath.cpp
 @@ -101,6 +101,16 @@ FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width) {
@@ -229,6 +229,63 @@ index a291987..d3b0bc1 100644
  FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_SetFillColor(FPDF_PAGEOBJECT path,
                                                            unsigned int R,
                                                            unsigned int G,
+@@ -217,6 +227,25 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path,
+   return true;
+ }
+ 
++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_GetDrawMode(FPDF_PAGEOBJECT path,
++                                                         int* fillmode,
++                                                         FPDF_BOOL* stroke)
++{
++  auto* pPathObj = CPDFPathObjectFromFPDFPageObject(path);
++  if (!pPathObj || !fillmode || !stroke)
++    return false;
++
++  if (pPathObj->m_FillType == FXFILL_ALTERNATE)
++    *fillmode = FPDF_FILLMODE_ALTERNATE;
++  else if (pPathObj->m_FillType == FXFILL_WINDING)
++    *fillmode = FPDF_FILLMODE_WINDING;
++  else
++    *fillmode = 0; // no fill
++
++  *stroke = pPathObj->m_bStroke;
++  return true;
++}
++
+ FPDF_EXPORT void FPDF_CALLCONV FPDFPath_SetLineJoin(FPDF_PAGEOBJECT path,
+                                                     int line_join) {
+   if (!path)
+@@ -250,6 +279,30 @@ FPDF_EXPORT void FPDF_CALLCONV FPDFPath_SetLineCap(FPDF_PAGEOBJECT path,
+ }
+ 
+ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
++FPDFPath_GetMatrix(FPDF_PAGEOBJECT path_object,
++                   double* a,
++                   double* b,
++                   double* c,
++                   double* d,
++                   double* e,
++                   double* f)
++{
++  if (!path_object || !a || !b || !c || !d || !e || !f)
++    return false;
++
++  auto* pPathObj = CPDFPageObjectFromFPDFPageObject(path_object);
++  CFX_Matrix* pMatrix = pPathObj->m_GeneralState.GetMutableMatrix();
++  *a = pMatrix->a;
++  *b = pMatrix->b;
++  *c = pMatrix->c;
++  *d = pMatrix->d;
++  *e = pMatrix->e;
++  *f = pMatrix->f;
++
++  return true;
++}
++
++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+ FPDFPathSegment_GetPoint(FPDF_PATHSEGMENT segment, float* x, float* y) {
+   auto* pPathPoint = FXPathPointFromFPDFPathSegment(segment);
+   if (!pPathPoint || !x || !y)
 diff --git a/fpdfsdk/fpdftext.cpp b/fpdfsdk/fpdftext.cpp
 index 68bf4f8..e073b20 100644
 --- a/fpdfsdk/fpdftext.cpp
@@ -300,7 +357,7 @@ index 77c2315..db3e734 100644
  
  CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
 diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
-index 54735a3..282bcdb 100644
+index 54735a3..a415c98 100644
 --- a/public/fpdf_edit.h
 +++ b/public/fpdf_edit.h
 @@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path,
@@ -319,7 +376,44 @@ index 54735a3..282bcdb 100644
  // Set the line join of |page_object|.
  //
  // page_object  - handle to a page object.
-@@ -761,6 +770,73 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
+@@ -688,6 +697,36 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path,
+                                                          int fillmode,
+                                                          FPDF_BOOL stroke);
+ 
++// Get the drawing mode of a path.
++//
++// path     - the handle to the path object.
++// fillmode - the filling mode to be set: 0 for no fill, 1 for alternate, 2 for
++// winding.
++// stroke   - a boolean specifying if the path should be stroked or not.
++//
++// Returns TRUE on success
++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_GetDrawMode(FPDF_PAGEOBJECT path,
++                                                         int* fillmode,
++                                                         FPDF_BOOL* stroke);
++
++// Get the matrix of a particular text object.
++//
++// path_object - Handle of path object returned by FPDFPath_NewPathObj
++//   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 FPDF_BOOL FPDF_CALLCONV
++FPDFPath_GetMatrix(FPDF_PAGEOBJECT path_object,
++                      double* a,
++                      double* b,
++                      double* c,
++                      double* d,
++                      double* e,
++                      double* f);
++
+ // Create a new text object using one of the standard PDF fonts.
+ //
+ // document   - handle to the document.
+@@ -761,6 +800,73 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
                            FPDF_FONT font,
                            float font_size);
  
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index cd10f7738f9e..2dfba0f986dc 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -565,7 +565,7 @@ void ImpSdrPdfImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr)
 
         if (mpVD->IsLineColor())
         {
-            mpLineAttr->Put(XLineStyleItem(drawing::LineStyle_SOLID));
+            mpLineAttr->Put(XLineStyleItem(drawing::LineStyle_SOLID)); //TODO support dashed lines.
             mpLineAttr->Put(XLineColorItem(OUString(), mpVD->GetLineColor()));
         }
         else
@@ -1250,6 +1250,10 @@ void ImpSdrPdfImport::ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIn
 void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
 {
     SAL_WARN("sd.filter", "Got page object PATH: " << nPageObjectIndex);
+
+    double a, b, c, d, e, f;
+    FPDFPath_GetMatrix(pPageObject, &a, &b, &c, &d, &e, &f);
+
     basegfx::B2DPolygon aPoly;
     std::vector<basegfx::B2DPoint> aBezier;
 
@@ -1266,9 +1270,14 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
                 continue;
             }
 
+            SAL_WARN("sd.filter", "Got point (" << x << ", " << y << ")");
+
+            x = a * x + c * y + e;
+            y = b * x + d * y + f;
+
             const bool bClose = FPDFPathSegment_GetClose(pPathSegment);
             SAL_WARN("sd.filter",
-                     "Got (" << x << ", " << y << "): " << (bClose ? "CLOSE" : "OPEN"));
+                     "Point corrected (" << x << ", " << y << "): " << (bClose ? "CLOSE" : "OPEN"));
             Point aPoint = PointsToLogic(x, y);
             x = aPoint.X();
             y = aPoint.Y();
@@ -1318,15 +1327,23 @@ void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectInd
     FPDFPath_GetStrokeWidth(pPageObject, &fWidth);
     mnLineWidth = lcl_ToLogic(lcl_PointToPixel(fWidth));
 
-    unsigned int r;
-    unsigned int g;
-    unsigned int b;
-    unsigned int a;
-    FPDFPath_GetFillColor(pPageObject, &r, &g, &b, &a);
-    mpVD->SetFillColor(Color(r, g, b));
-
-    FPDFPath_GetStrokeColor(pPageObject, &r, &g, &b, &a);
-    mpVD->SetLineColor(Color(r, g, b));
+    unsigned int nR;
+    unsigned int nG;
+    unsigned int nB;
+    unsigned int nA;
+    FPDFPath_GetFillColor(pPageObject, &nR, &nG, &nB, &nA);
+    SAL_WARN("sd.filter", "Got PATH fill color: " << nR << ", " << nG << ", " << nB << ", " << nA);
+    mpVD->SetFillColor(Color(nR, nG, nB));
+
+    FPDFPath_GetStrokeColor(pPageObject, &nR, &nG, &nB, &nA);
+    SAL_WARN("sd.filter",
+             "Got PATH stroke color: " << nR << ", " << nG << ", " << nB << ", " << nA);
+    mpVD->SetLineColor(Color(nR, nG, nB));
+
+    // int nFillMode = 0; // No fill.
+    // bool bStroke = false;
+    // FPDFPath_GetDrawMode(pPageObject, &nFillMode, &bStroke);
+    // mpVD->Setstroke(Color(r, g, b));
 
     // if(!mbLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
 
commit e5381616e803efc53f1cb574dc4c0fc4cdfbcd77
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Tue Apr 10 18:06:47 2018 -0400

    svx: support Paths in PDFs while importing
    
    Change-Id: Idba294cf5a3a8dd00988f94786715b110039e000

diff --git a/external/pdfium/edit.patch.1 b/external/pdfium/edit.patch.1
index 9099a4024b3e..03b4ab221730 100644
--- a/external/pdfium/edit.patch.1
+++ b/external/pdfium/edit.patch.1
@@ -208,6 +208,27 @@ index ca2cf3f..8073a18 100644
 +      (pTxtObj->m_GeneralState.GetStrokeAlpha() * 255.f) + 0.5f);
 +  return true;
 +}
+diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
+index a291987..d3b0bc1 100644
+--- a/fpdfsdk/fpdfeditpath.cpp
++++ b/fpdfsdk/fpdfeditpath.cpp
+@@ -101,6 +101,16 @@ FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width) {
+   return true;
+ }
+ 
++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
++FPDFPath_GetStrokeWidth(FPDF_PAGEOBJECT path, float* width) {
++  auto* pPathObj = CPDFPathObjectFromFPDFPageObject(path);
++  if (!pPathObj || !width)
++    return false;
++
++  *width = pPathObj->m_GraphState.GetLineWidth();
++  return true;
++}
++
+ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_SetFillColor(FPDF_PAGEOBJECT path,
+                                                           unsigned int R,
+                                                           unsigned int G,
 diff --git a/fpdfsdk/fpdftext.cpp b/fpdfsdk/fpdftext.cpp
 index 68bf4f8..e073b20 100644
 --- a/fpdfsdk/fpdftext.cpp
@@ -279,10 +300,26 @@ index 77c2315..db3e734 100644
  
  CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
 diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
-index 54735a3..15292f5 100644
+index 54735a3..282bcdb 100644
 --- a/public/fpdf_edit.h
 +++ b/public/fpdf_edit.h
-@@ -761,6 +761,73 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
+@@ -520,6 +520,15 @@ FPDFPath_GetStrokeColor(FPDF_PAGEOBJECT path,
+ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+ FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width);
+ 
++// Get the stroke width of a path.
++//
++// path   - the handle to the path object.
++// width  - the width of the stroke.
++//
++// Returns TRUE on success
++FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
++FPDFPath_GetStrokeWidth(FPDF_PAGEOBJECT path, float* width);
++
+ // Set the line join of |page_object|.
+ //
+ // page_object  - handle to a page object.
+@@ -761,6 +770,73 @@ FPDFPageObj_CreateTextObj(FPDF_DOCUMENT document,
                            FPDF_FONT font,
                            float font_size);
  
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 9b57adf737bc..cd10f7738f9e 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -233,7 +233,7 @@ void ImpSdrPdfImport::DoLoopActions(SvdProgressInfo* pProgrInfo, sal_uInt32* pAc
                     ImportText(pPageObject, nPageObjectIndex);
                     break;
                 case FPDF_PAGEOBJ_PATH:
-                    SAL_WARN("sd.filter", "Got page object PATH: " << nPageObjectIndex);
+                    ImportPath(pPageObject, nPageObjectIndex);
                     break;
                 case FPDF_PAGEOBJ_IMAGE:
                     ImportImage(pPageObject, nPageObjectIndex);
@@ -1247,6 +1247,95 @@ void ImpSdrPdfImport::ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIn
     InsertObj(pGraf);
 }
 
+void ImpSdrPdfImport::ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex)
+{
+    SAL_WARN("sd.filter", "Got page object PATH: " << nPageObjectIndex);
+    basegfx::B2DPolygon aPoly;
+    std::vector<basegfx::B2DPoint> aBezier;
+
+    const int nSegments = FPDFPath_CountSegments(pPageObject);
+    for (int nSegmentIndex = 0; nSegmentIndex < nSegments; ++nSegmentIndex)
+    {
+        FPDF_PATHSEGMENT pPathSegment = FPDFPath_GetPathSegment(pPageObject, nSegmentIndex);
+        if (pPathSegment != nullptr)
+        {
+            float x, y;
+            if (!FPDFPathSegment_GetPoint(pPathSegment, &x, &y))
+            {
+                SAL_WARN("sd.filter", "Failed to get PDF path segement point");
+                continue;
+            }
+
+            const bool bClose = FPDFPathSegment_GetClose(pPathSegment);
+            SAL_WARN("sd.filter",
+                     "Got (" << x << ", " << y << "): " << (bClose ? "CLOSE" : "OPEN"));
+            Point aPoint = PointsToLogic(x, y);
+            x = aPoint.X();
+            y = aPoint.Y();
+
+            const int nSegmentType = FPDFPathSegment_GetType(pPathSegment);
+            switch (nSegmentType)
+            {
+                case FPDF_SEGMENT_LINETO:
+                    SAL_WARN("sd.filter", "Got LineTo Segment.");
+                    aPoly.append(basegfx::B2DPoint(x, y));
+                    break;
+
+                case FPDF_SEGMENT_BEZIERTO:
+                    SAL_WARN("sd.filter", "Got BezierTo Segment.");
+                    aBezier.emplace_back(x, y);
+                    if (aBezier.size() == 3)
+                    {
+                        aPoly.appendBezierSegment(aBezier[0], aBezier[1], aBezier[2]);
+                        aBezier.clear();
+                    }
+                    break;
+
+                case FPDF_SEGMENT_MOVETO:
+                    SAL_WARN("sd.filter", "Got MoveTo Segment.");
+                    aPoly.append(basegfx::B2DPoint(x, y));
+                    break;
+
+                case FPDF_SEGMENT_UNKNOWN:
+                default:
+                    SAL_WARN("sd.filter", "Unknown path segment type in PDF: " << nSegmentType);
+                    break;
+            }
+        }
+    }
+
+    if (aBezier.size() == 3)
+    {
+        aPoly.appendBezierSegment(aBezier[0], aBezier[1], aBezier[2]);
+        aBezier.clear();
+    }
+
+    const basegfx::B2DHomMatrix aTransform(
+        basegfx::tools::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
+    aPoly.transform(aTransform);
+
+    float fWidth = 1;
+    FPDFPath_GetStrokeWidth(pPageObject, &fWidth);
+    mnLineWidth = lcl_ToLogic(lcl_PointToPixel(fWidth));
+
+    unsigned int r;
+    unsigned int g;
+    unsigned int b;
+    unsigned int a;
+    FPDFPath_GetFillColor(pPageObject, &r, &g, &b, &a);
+    mpVD->SetFillColor(Color(r, g, b));
+
+    FPDFPath_GetStrokeColor(pPageObject, &r, &g, &b, &a);
+    mpVD->SetLineColor(Color(r, g, b));
+

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list