diff options
author | Vort <vvort@yandex.ru> | 2014-04-08 08:39:02 +0300 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2014-04-08 14:50:13 +0000 |
commit | a20e145cf901f6589ca96e3a4a5ded413eb20907 (patch) | |
tree | e72fe413d1c6e2da2bb494f6bbd5ca9c3b15b3ee | |
parent | f704d5a579eaa3bed1b40f8bdf5e40084622c79d (diff) |
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@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | sdext/source/pdfimport/tree/drawtreevisiting.cxx | 9 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/genericelements.hxx | 3 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/pdfiprocessor.cxx | 164 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/pdfiprocessor.hxx | 34 | ||||
-rw-r--r-- | sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx | 7 |
5 files changed, 83 insertions, 134 deletions
diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx index 626480d263c2..98a677e142ee 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 5593ecb776f6..78f85dfa024f 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 581f0527a6d5..5eb84db5622a 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 f2b02bdc1b42..81ef37b766e5 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 c5b145f0a00a..e186dda13aa0 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]), |