[Libreoffice-commits] core.git: sdext/source

Vort vvort at yandex.ru
Tue Apr 8 07:50:36 PDT 2014


 sdext/source/pdfimport/tree/drawtreevisiting.cxx      |    9 
 sdext/source/pdfimport/tree/genericelements.hxx       |    3 
 sdext/source/pdfimport/tree/pdfiprocessor.cxx         |  164 ++++++------------
 sdext/source/pdfimport/tree/pdfiprocessor.hxx         |   34 +--
 sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx |    7 
 5 files changed, 83 insertions(+), 134 deletions(-)

New commits:
commit a20e145cf901f6589ca96e3a4a5ded413eb20907
Author: Vort <vvort at yandex.ru>
Date:   Tue Apr 8 08:39:02 2014 +0300

    fdo#45001 fdo#77105 PDF Import: rotated text fixes
    
    1. Fix 180 degrees text rotation;
    2. Make rotated text fully editable.
    
    Change-Id: Ie937f29031bbd0146207ce83678db351b65d2f8d
    Reviewed-on: https://gerrit.libreoffice.org/8890
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
index 626480d..98a677e 100644
--- a/sdext/source/pdfimport/tree/drawtreevisiting.cxx
+++ b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
@@ -222,6 +222,15 @@ void DrawXmlEmitter::fillFrameProps( DrawElement&       rElem,
         if( rElem.MirrorVertical )
             fRotate += M_PI;
 
+        // First check here is to skip image frame case
+        if (rElem.IsForText &&
+            (aScale.getX() < 0) &&
+            (aScale.getY() > 0) &&
+            (basegfx::fTools::equalZero(aScale.getX() + aScale.getY(), 0.0001)))
+        {
+            fRotate += M_PI;
+        }
+
         // build transformation string
         if( fShearX != 0.0 )
         {
diff --git a/sdext/source/pdfimport/tree/genericelements.hxx b/sdext/source/pdfimport/tree/genericelements.hxx
index 5593ecb..78f85df 100644
--- a/sdext/source/pdfimport/tree/genericelements.hxx
+++ b/sdext/source/pdfimport/tree/genericelements.hxx
@@ -127,11 +127,12 @@ namespace pdfi
     {
     protected:
         GraphicalElement( Element* pParent, sal_Int32 nGCId )
-        : Element( pParent ), GCId( nGCId ), MirrorVertical( false ) {}
+        : Element( pParent ), GCId( nGCId ), MirrorVertical( false ), IsForText (false) {}
 
     public:
         sal_Int32 GCId;
         bool      MirrorVertical;
+        bool      IsForText;
     };
 
     struct DrawElement : public GraphicalElement
diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.cxx b/sdext/source/pdfimport/tree/pdfiprocessor.cxx
index 581f052..5eb84db 100644
--- a/sdext/source/pdfimport/tree/pdfiprocessor.cxx
+++ b/sdext/source/pdfimport/tree/pdfiprocessor.cxx
@@ -56,9 +56,7 @@ namespace pdfi
             com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >  xContext) :
 
     m_xContext(xContext),
-    fYPrevTextPosition(-10000.0),
-    fXPrevTextPosition(0.0),
-    fPrevTextWidth(0.0),
+    prevCharWidth(0),
     m_pElFactory( new ElementFactory() ),
     m_pDocument( m_pElFactory->createDocumentElement() ),
     m_pCurPage(0),
@@ -224,9 +222,7 @@ void PDFIProcessor::processGlyphLine()
 
         if ((ch == 0x20) || (ch == 0xa0))
         {
-            double spaceWidth =
-                m_GlyphsList[i].getRect().X2 -
-                m_GlyphsList[i].getRect().X1;
+            double spaceWidth = m_GlyphsList[i].getWidth();
             spaceDetectBoundary = spaceWidth * 0.5;
             break;
         }
@@ -237,129 +233,89 @@ void PDFIProcessor::processGlyphLine()
     {
         double avgGlyphWidth = 0.0;
         for (size_t i = 0; i < m_GlyphsList.size(); i++)
-        {
-            avgGlyphWidth +=
-                m_GlyphsList[i].getRect().X2 -
-                m_GlyphsList[i].getRect().X1;
-        }
+            avgGlyphWidth += m_GlyphsList[i].getWidth();
         avgGlyphWidth /= m_GlyphsList.size();
         spaceDetectBoundary = avgGlyphWidth * 0.2;
     }
 
-    FrameElement* frame = m_pElFactory->createFrameElement(m_GlyphsList[0].getCurElement(),
-        getGCId(getTransformGlyphContext(m_GlyphsList[0])));
+    FrameElement* frame = m_pElFactory->createFrameElement(
+        m_GlyphsList[0].getCurElement(),
+        getGCId(m_GlyphsList[0].getGC()));
     frame->ZOrder = m_nNextZOrder++;
+    frame->IsForText = true;
     ParagraphElement* para = m_pElFactory->createParagraphElement(frame);
 
     for (size_t i = 0; i < m_GlyphsList.size(); i++)
     {
         bool prependSpace = false;
-        if (i != 0)
+        TextElement* text = m_pElFactory->createTextElement(
+            para,
+            getGCId(m_GlyphsList[i].getGC()),
+            m_GlyphsList[i].getGC().FontId);
+        if (i == 0)
         {
-            double spaceSize =
-                m_GlyphsList[i].getRect().X1 -
-                m_GlyphsList[i - 1].getRect().X2;
+            text->x = m_GlyphsList[0].getGC().Transformation.get(0, 2);
+            text->y = m_GlyphsList[0].getGC().Transformation.get(1, 2);
+            text->w = 0;
+            text->h = 0;
+            para->updateGeometryWith(text);
+            frame->updateGeometryWith(para);
+        }
+        else
+        {
+            double spaceSize = m_GlyphsList[i].getPrevSpaceWidth();
             prependSpace = spaceSize > spaceDetectBoundary;
         }
-        drawCharGlyphs(m_GlyphsList[i].getGlyph(),
-                       m_GlyphsList[i].getRect(),
-                       m_GlyphsList[i].getGC(),
-                       para,
-                       frame,
-                       prependSpace);
+        if (prependSpace)
+            text->Text.append(" ");
+        text->Text.append(m_GlyphsList[i].getGlyph());
     }
 
     m_GlyphsList.clear();
 }
 
-void PDFIProcessor::drawGlyphLine( const OUString&             rGlyphs,
-                                   const geometry::RealRectangle2D& rRect,
-                                   const geometry::Matrix2D&        rFontMatrix )
+void PDFIProcessor::drawGlyphs( const OUString&             rGlyphs,
+                                const geometry::RealRectangle2D& rRect,
+                                const geometry::Matrix2D&        rFontMatrix )
 {
-    ::basegfx::B2DPoint point1(rRect.X1, rRect.Y1);
-    ::basegfx::B2DPoint point2(rRect.X2, rRect.Y2);
-    point1 *= getCurrentContext().Transformation;
-    point2 *= getCurrentContext().Transformation;
-
-    if ((fYPrevTextPosition != point1.getY()) ||
-        (fXPrevTextPosition > point2.getX()) ||
-        ((fXPrevTextPosition + fPrevTextWidth * 1.3) < point1.getX()))
+    basegfx::B2DHomMatrix totalTextMatrix1(
+        rFontMatrix.m00, rFontMatrix.m01, rRect.X1,
+        rFontMatrix.m10, rFontMatrix.m11, rRect.Y1);
+    basegfx::B2DHomMatrix totalTextMatrix2(
+        rFontMatrix.m00, rFontMatrix.m01, rRect.X2,
+        rFontMatrix.m10, rFontMatrix.m11, rRect.Y2);
+    totalTextMatrix1 *= getCurrentContext().Transformation;
+    totalTextMatrix2 *= getCurrentContext().Transformation;
+
+    basegfx::B2DHomMatrix invMatrix(totalTextMatrix1);
+    basegfx::B2DHomMatrix invPrevMatrix(prevTextMatrix);
+    invMatrix.invert();
+    invPrevMatrix.invert();
+    basegfx::B2DHomMatrix offsetMatrix1(totalTextMatrix1);
+    basegfx::B2DHomMatrix offsetMatrix2(totalTextMatrix2);
+    offsetMatrix1 *= invPrevMatrix;
+    offsetMatrix2 *= invMatrix;
+
+    double charWidth = offsetMatrix2.get(0, 2);
+    double prevSpaceWidth = offsetMatrix1.get(0, 2) - prevCharWidth;
+
+    if ((totalTextMatrix1.get(0, 0) != prevTextMatrix.get(0, 0)) ||
+        (totalTextMatrix1.get(0, 1) != prevTextMatrix.get(0, 1)) ||
+        (totalTextMatrix1.get(1, 0) != prevTextMatrix.get(1, 0)) ||
+        (totalTextMatrix1.get(1, 1) != prevTextMatrix.get(1, 1)) ||
+        (offsetMatrix1.get(0, 2) < 0.0) ||
+        (prevSpaceWidth > prevCharWidth * 1.3) ||
+        (!basegfx::fTools::equalZero(offsetMatrix1.get(1, 2), 0.0001)))
     {
         processGlyphLine();
     }
 
-    CharGlyph aGlyph(m_pCurElement, getCurrentContext(), rFontMatrix, rRect, rGlyphs);
-
-    getGCId(getCurrentContext());
-
+    CharGlyph aGlyph(m_pCurElement, getCurrentContext(), charWidth, prevSpaceWidth, rGlyphs);
+    aGlyph.getGC().Transformation = totalTextMatrix1;
     m_GlyphsList.push_back(aGlyph);
 
-    fYPrevTextPosition  = point1.getY();
-    fXPrevTextPosition  = point2.getX();
-    fPrevTextWidth      = point2.getX() - point1.getX();
-}
-
-GraphicsContext& PDFIProcessor::getTransformGlyphContext( CharGlyph& rGlyph )
-{
-    geometry::RealRectangle2D   rRect = rGlyph.getRect();
-    geometry::Matrix2D          rFontMatrix = rGlyph.getFontMatrix();
-
-    basegfx::B2DHomMatrix aFontMatrix;
-    basegfx::unotools::homMatrixFromMatrix(
-        aFontMatrix,
-        rFontMatrix );
-
-    FontAttributes aFontAttrs = m_aIdToFont[ rGlyph.getGC().FontId ];
-
-    // add transformation to GC
-    basegfx::B2DHomMatrix aFontTransform(basegfx::tools::createTranslateB2DHomMatrix(-rRect.X1, -rRect.Y1));
-    aFontTransform *= aFontMatrix;
-    aFontTransform.translate( rRect.X1, rRect.Y1 );
-
-
-    rGlyph.getGC().Transformation = rGlyph.getGC().Transformation * aFontTransform;
-    getGCId(rGlyph.getGC());
-
-    return rGlyph.getGC();
-}
-
-void PDFIProcessor::drawCharGlyphs( OUString&             rGlyphs,
-                                    geometry::RealRectangle2D& rRect,
-                                    const GraphicsContext& aGC,
-                                    ParagraphElement* pPara,
-                                    FrameElement* pFrame,
-                                    bool bSpaceFlag )
-{
-    OUString tempStr( 32 );
-
-    // check whether there was a previous draw frame
-    TextElement* pText = m_pElFactory->createTextElement( pPara,
-                                                          getGCId(aGC),
-                                                          aGC.FontId );
-    if( bSpaceFlag )
-        pText->Text.append( tempStr );
-
-    pText->Text.append( rGlyphs );
-
-    ::basegfx::B2DPoint point(rRect.X1, rRect.Y1);
-    point *= aGC.Transformation;
-
-    pText->x = point.getX();
-    pText->y = point.getY();
-    pText->w = 0.0001; // hack for solving of size auto-grow problem
-    pText->h = 0.0001;
-
-    pPara->updateGeometryWith( pText );
-
-    if( pFrame )
-      pFrame->updateGeometryWith( pPara );
-}
-
-void PDFIProcessor::drawGlyphs( const OUString&             rGlyphs,
-                                const geometry::RealRectangle2D& rRect,
-                                const geometry::Matrix2D&        rFontMatrix )
-{
-     drawGlyphLine( rGlyphs, rRect, rFontMatrix );
+    prevCharWidth = charWidth;
+    prevTextMatrix = totalTextMatrix1;
 }
 
 void PDFIProcessor::endText()
diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.hxx b/sdext/source/pdfimport/tree/pdfiprocessor.hxx
index f2b02bd..81ef37b 100644
--- a/sdext/source/pdfimport/tree/pdfiprocessor.hxx
+++ b/sdext/source/pdfimport/tree/pdfiprocessor.hxx
@@ -66,9 +66,8 @@ namespace pdfi
     public:
         com::sun::star::uno::Reference<
             com::sun::star::uno::XComponentContext >  m_xContext;
-        double fYPrevTextPosition;
-        double fXPrevTextPosition;
-        double fPrevTextWidth;
+        basegfx::B2DHomMatrix prevTextMatrix;
+        double prevCharWidth;
         enum DocumentTextDirecion { LrTb, RlTb, TbLr };
 
         explicit PDFIProcessor( const com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator >& xStat,
@@ -103,19 +102,6 @@ namespace pdfi
     private:
         void processGlyphLine();
 
-        void drawGlyphLine( const OUString&                               rGlyphs,
-                            const ::com::sun::star::geometry::RealRectangle2D& rRect,
-                            const ::com::sun::star::geometry::Matrix2D&        rFontMatrix  );
-
-        void drawCharGlyphs( OUString&             rGlyphs,
-                             ::com::sun::star::geometry::RealRectangle2D&  rRect,
-                             const GraphicsContext& aGC,
-                             ParagraphElement* pPara,
-                             FrameElement* pFrame,
-                             bool bSpaceFlag );
-
-        GraphicsContext& getTransformGlyphContext( CharGlyph& rGlyph );
-
         // ContentSink interface implementation
 
         virtual void setPageNum( sal_Int32 nNumPages ) SAL_OVERRIDE;
@@ -226,24 +212,24 @@ namespace pdfi
     class CharGlyph
     {
         public:
-            CharGlyph(Element* pCurElement, const GraphicsContext& rCurrentContext, const com::sun::star::geometry::Matrix2D& rFontMatrix,
-               const com::sun::star::geometry::RealRectangle2D& rRect, const OUString& rGlyphs  )
+            CharGlyph(Element* pCurElement, const GraphicsContext& rCurrentContext,
+                double width, double prevSpaceWidth, const OUString& rGlyphs  )
                : m_pCurElement(pCurElement), m_rCurrentContext(rCurrentContext),
-                 m_rFontMatrix(rFontMatrix), m_rRect(rRect), m_rGlyphs(rGlyphs) {};
+                 m_Width(width), m_PrevSpaceWidth(prevSpaceWidth), m_rGlyphs(rGlyphs) {};
 
             virtual ~CharGlyph(){};
             OUString& getGlyph(){ return m_rGlyphs; }
-            com::sun::star::geometry::RealRectangle2D& getRect(){ return m_rRect; }
-            com::sun::star::geometry::Matrix2D&  getFontMatrix(){ return m_rFontMatrix; }
+            double getWidth(){ return m_Width; }
+            double getPrevSpaceWidth(){ return m_PrevSpaceWidth; }
             GraphicsContext&  getGC(){ return m_rCurrentContext; }
             Element*  getCurElement(){ return m_pCurElement; }
 
         private:
             Element*                    m_pCurElement ;
             GraphicsContext             m_rCurrentContext ;
-            com::sun::star::geometry::Matrix2D          m_rFontMatrix ;
-            com::sun::star::geometry::RealRectangle2D   m_rRect ;
-            OUString               m_rGlyphs ;
+            double                      m_Width ;
+            double                      m_PrevSpaceWidth ;
+            OUString                    m_rGlyphs ;
     };
 }
 
diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
index c5b145f..e186dda 100644
--- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
+++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
@@ -821,16 +821,13 @@ void PDFOutDev::drawChar(GfxState *state, double x, double y,
 
     const double aPositionX(x-originX);
     const double aPositionY(y-originY);
-    // TODO(F2): use leading here, when set
-    const double nWidth(dx != 0.0 ? dx : fFontSize);
-    const double nHeight(dy != 0.0 ? dy : fFontSize);
 
     const double* pTextMat=state->getTextMat();
     printf( "drawChar %f %f %f %f %f %f %f %f ",
             normalize(aPositionX),
             normalize(aPositionY),
-            normalize(aPositionX+nWidth),
-            normalize(aPositionY-nHeight),
+            normalize(aPositionX + dx),
+            normalize(aPositionY + dy),
             normalize(pTextMat[0]),
             normalize(pTextMat[2]),
             normalize(pTextMat[1]),


More information about the Libreoffice-commits mailing list