summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVort <vvort@yandex.ru>2014-04-08 08:39:02 +0300
committerCaolán McNamara <caolanm@redhat.com>2014-04-08 14:50:13 +0000
commita20e145cf901f6589ca96e3a4a5ded413eb20907 (patch)
treee72fe413d1c6e2da2bb494f6bbd5ca9c3b15b3ee
parentf704d5a579eaa3bed1b40f8bdf5e40084622c79d (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.cxx9
-rw-r--r--sdext/source/pdfimport/tree/genericelements.hxx3
-rw-r--r--sdext/source/pdfimport/tree/pdfiprocessor.cxx164
-rw-r--r--sdext/source/pdfimport/tree/pdfiprocessor.hxx34
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx7
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]),