diff options
Diffstat (limited to 'sdext/source/pdfimport/tree')
-rw-r--r-- | sdext/source/pdfimport/tree/drawtreevisiting.cxx | 165 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/drawtreevisiting.hxx | 11 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/genericelements.hxx | 13 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/pdfiprocessor.cxx | 7 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/pdfiprocessor.hxx | 5 |
5 files changed, 168 insertions, 33 deletions
diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx index 664a19c7763d..2fd17d059e23 100644 --- a/sdext/source/pdfimport/tree/drawtreevisiting.cxx +++ b/sdext/source/pdfimport/tree/drawtreevisiting.cxx @@ -39,10 +39,46 @@ #include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/range/b2drange.hxx> +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include "comphelper/processfactory.hxx" +#include <com/sun/star/i18n/ScriptType.hpp> +#include <string.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::uno; namespace pdfi { +const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator >& DrawXmlOptimizer::GetBreakIterator() +{ + if ( !mxBreakIter.is() ) + { + Reference< XComponentContext > xContext( this->m_rProcessor.m_xContext, uno::UNO_SET_THROW ); + Reference< XMultiComponentFactory > xMSF( xContext->getServiceManager(), uno::UNO_SET_THROW ); + Reference < XInterface > xInterface = xMSF->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator"), xContext); + + mxBreakIter = uno::Reference< i18n::XBreakIterator >( xInterface, uno::UNO_QUERY ); + } + return mxBreakIter; +} + +const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator >& DrawXmlEmitter::GetBreakIterator() +{ + if ( !mxBreakIter.is() ) + { + Reference< XComponentContext > xContext( m_rEmitContext.m_xContext, uno::UNO_SET_THROW ); + Reference< XMultiComponentFactory > xMSF( xContext->getServiceManager(), uno::UNO_SET_THROW ); + Reference < XInterface > xInterface = xMSF->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator"), xContext); + mxBreakIter = uno::Reference< i18n::XBreakIterator >( xInterface, uno::UNO_QUERY ); + } + return mxBreakIter; +} + void DrawXmlEmitter::visit( HyperlinkElement& elem, const std::list< Element* >::const_iterator& ) { if( elem.Children.empty() ) @@ -72,6 +108,7 @@ void DrawXmlEmitter::visit( TextElement& elem, const std::list< Element* >::cons return; rtl::OUString strSpace(32); + rtl::OUString strNbSpace(160); rtl::OUString tabSpace(0x09); PropertyMap aProps; if( elem.StyleId != -1 ) @@ -80,27 +117,50 @@ void DrawXmlEmitter::visit( TextElement& elem, const std::list< Element* >::cons m_rEmitContext.rStyles.getStyleName( elem.StyleId ); } + rtl::OUString str(elem.Text.getStr()); + + // Check for CTL + bool isComplex = false; + for(int i=0; i< elem.Text.getLength(); i++) + { + sal_Int16 nType = GetBreakIterator()->getScriptType( str, i + 1); + if (nType == ::com::sun::star::i18n::ScriptType::COMPLEX) + isComplex = true; + } + + #if 0 + // FIXME: need to have a service to do this mirroring + if (isComplex) // If so, reverse string + { + rtl::OUString flippedStr(RTL_CONSTASCII_USTRINGPARAM( "" )); + for(int i = str.getLength() - 1; i >= 0; i--) + { + sal_Unicode cChar = str[ i ]; + cChar = static_cast<sal_Unicode>(GetMirroredChar( cChar )); + rtl::OUString uC(cChar); + flippedStr += uC; + } + str = flippedStr; + } + #endif + m_rEmitContext.rEmitter.beginTag( "text:span", aProps ); - rtl::OUString str(elem.Text.getStr()); for(int i=0; i< elem.Text.getLength(); i++) { rtl::OUString strToken= str.copy(i,1) ; - if( strSpace.equals(strToken) ) + if( strSpace.equals(strToken) || strNbSpace.equals(strToken)) { aProps[ USTR( "text:c" ) ] = USTR( "1" ); m_rEmitContext.rEmitter.beginTag( "text:s", aProps ); m_rEmitContext.rEmitter.endTag( "text:s"); - } else { if( tabSpace.equals(strToken) ) { - m_rEmitContext.rEmitter.beginTag( "text:tab", aProps ); m_rEmitContext.rEmitter.endTag( "text:tab"); - } else { @@ -608,6 +668,29 @@ void DrawXmlOptimizer::visit( PageElement& elem, const std::list< Element* >::co elem.applyToChildren(*this); } +bool isSpaces(TextElement* pTextElem) +{ + rtl::OUString strSpace(32); + ::rtl::OUString ouTxt2(pTextElem->Text); + for(int i=0; i< pTextElem->Text.getLength(); i++) + { + rtl::OUString strToken = ouTxt2.copy(i,1) ; + if( !strSpace.equals(strToken) ) + return false; + } + return true; +} + +bool notTransformed(GraphicsContext GC) +{ + return ( + GC.Transformation.get(0,0) == 100.00 && + GC.Transformation.get(1,0) == 0.00 && + GC.Transformation.get(0,1) == 0.00 && + GC.Transformation.get(1,1) == -100.00 + ); +} + void DrawXmlOptimizer::optimizeTextElements(Element& rParent) { if( rParent.Children.empty() ) // this should not happen @@ -616,9 +699,6 @@ void DrawXmlOptimizer::optimizeTextElements(Element& rParent) return; } - bool bFirstTime= true; - double fPrevY = 0; - // concatenate child elements with same font id std::list< Element* >::iterator next = rParent.Children.begin(); std::list< Element* >::iterator it = next++; @@ -634,15 +714,22 @@ void DrawXmlOptimizer::optimizeTextElements(Element& rParent) { bool bConcat = false; TextElement* pCur = dynamic_cast<TextElement*>(*it); - if( bFirstTime ) - { - bFirstTime=false; - fPrevY = pCur->y; - } if( pCur ) { TextElement* pNext = dynamic_cast<TextElement*>(*next); + bool isComplex = false; + rtl::OUString str(pCur->Text.getStr()); + for(int i=0; i< str.getLength(); i++) + { + sal_Int16 nType = GetBreakIterator()->getScriptType( str, i ); + if (nType == ::com::sun::star::i18n::ScriptType::COMPLEX) + isComplex = true; + } + bool bPara = strspn("ParagraphElement", typeid(rParent).name()); + ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(&rParent); + if (bPara && isComplex) + pPara->bRtl = true; if( pNext ) { const GraphicsContext& rCurGC = m_rProcessor.getGraphicsContext( pCur->GCId ); @@ -650,20 +737,29 @@ void DrawXmlOptimizer::optimizeTextElements(Element& rParent) // line and space optimization; works only in strictly horizontal mode - // concatenate consecutive text elements unless there is a // font or text color or matrix change, leave a new span in that case - if( pCur->FontId == pNext->FontId && + if( (pCur->FontId == pNext->FontId || isSpaces(pNext)) && rCurGC.FillColor.Red == rNextGC.FillColor.Red && rCurGC.FillColor.Green == rNextGC.FillColor.Green && rCurGC.FillColor.Blue == rNextGC.FillColor.Blue && rCurGC.FillColor.Alpha == rNextGC.FillColor.Alpha && - rCurGC.Transformation == rNextGC.Transformation + (rCurGC.Transformation == rNextGC.Transformation || notTransformed(rNextGC)) ) { pCur->updateGeometryWith( pNext ); // append text to current element - pCur->Text.append( pNext->Text.getStr(), pNext->Text.getLength() ); + pCur->Text.append( pNext->Text.getStr(), pNext->Text.getLength() ); + + str = pCur->Text.getStr(); + for(int i=0; i< str.getLength(); i++) + { + sal_Int16 nType = GetBreakIterator()->getScriptType( str, i ); + if (nType == ::com::sun::star::i18n::ScriptType::COMPLEX) + isComplex = true; + } + if (bPara && isComplex) + pPara->bRtl = true; // append eventual children to current element // and clear children (else the children just // appended to pCur would be destroyed) @@ -677,16 +773,11 @@ void DrawXmlOptimizer::optimizeTextElements(Element& rParent) } else if( dynamic_cast<HyperlinkElement*>(*it) ) optimizeTextElements( **it ); - if( bConcat ) - { + if ( bConcat ) next = it; - ++next; - } else - { ++it; - ++next; - } + ++next; } } @@ -763,19 +854,21 @@ void DrawXmlFinalizer::visit( TextElement& elem, const std::list< Element* >::co // family name aFontProps[ USTR( "fo:font-family" ) ] = rFont.familyName; + aFontProps[ USTR( "style:font-family-complex" ) ] = rFont.familyName; + // bold if( rFont.isBold ) { aFontProps[ USTR( "fo:font-weight" ) ] = USTR( "bold" ); aFontProps[ USTR( "fo:font-weight-asian" ) ] = USTR( "bold" ); - aFontProps[ USTR( "fo:font-weight-complex" ) ] = USTR( "bold" ); + aFontProps[ USTR( "style:font-weight-complex" ) ] = USTR( "bold" ); } // italic if( rFont.isItalic ) { aFontProps[ USTR( "fo:font-style" ) ] = USTR( "italic" ); aFontProps[ USTR( "fo:font-style-asian" ) ] = USTR( "italic" ); - aFontProps[ USTR( "fo:font-style-complex" ) ] = USTR( "italic" ); + aFontProps[ USTR( "style:font-style-complex" ) ] = USTR( "italic" ); } // underline if( rFont.isUnderline ) @@ -809,6 +902,26 @@ void DrawXmlFinalizer::visit( TextElement& elem, const std::list< Element* >::co void DrawXmlFinalizer::visit( ParagraphElement& elem, const std::list< Element* >::const_iterator& ) { + + PropertyMap aProps; + aProps[ USTR( "style:family" ) ] = USTR( "paragraph" ); + // generate standard paragraph style if necessary + m_rStyleContainer.getStandardStyleId( "paragraph" ); + + PropertyMap aParProps; + + aParProps[ USTR("fo:text-align")] = USTR("start"); + if (elem.bRtl) + aParProps[ USTR("style:writing-mode")] = USTR("rl-tb"); + else + aParProps[ USTR("style:writing-mode")] = USTR("lr-tb"); + + StyleContainer::Style aStyle( "style:style", aProps ); + StyleContainer::Style aSubStyle( "style:paragraph-properties", aParProps ); + aStyle.SubStyles.push_back( &aSubStyle ); + + elem.StyleId = m_rStyleContainer.getStyleId( aStyle ); + // update page boundaries if( elem.Parent ) { diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.hxx b/sdext/source/pdfimport/tree/drawtreevisiting.hxx index b7b94371c6da..fd347fa4f302 100644 --- a/sdext/source/pdfimport/tree/drawtreevisiting.hxx +++ b/sdext/source/pdfimport/tree/drawtreevisiting.hxx @@ -29,7 +29,9 @@ #define INCLUDED_PDFI_DRAWTREEVISITING_HXX #include "treevisiting.hxx" - +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> namespace pdfi { @@ -42,6 +44,8 @@ namespace pdfi void optimizeTextElements(Element& rParent); public: + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > mxBreakIter; + const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator >& GetBreakIterator(); explicit DrawXmlOptimizer(PDFIProcessor& rProcessor) : m_rProcessor(rProcessor) {} @@ -82,6 +86,10 @@ namespace pdfi class DrawXmlEmitter : public ElementTreeVisitor { private: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > xCtx; + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > mxBreakIter; + EmitContext& m_rEmitContext ; /// writes Impress doc when false const bool m_bWriteDrawDocument; @@ -91,6 +99,7 @@ namespace pdfi const EmitContext& rEmitContext ); public: + const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator >& GetBreakIterator(); enum DocType{ DRAW_DOC, IMPRESS_DOC }; explicit DrawXmlEmitter(EmitContext& rEmitContext, DocType eDocType) : m_rEmitContext(rEmitContext), diff --git a/sdext/source/pdfimport/tree/genericelements.hxx b/sdext/source/pdfimport/tree/genericelements.hxx index 88293673ee3a..d7cd690aba61 100644 --- a/sdext/source/pdfimport/tree/genericelements.hxx +++ b/sdext/source/pdfimport/tree/genericelements.hxx @@ -32,6 +32,7 @@ #include "treevisiting.hxx" #include <com/sun/star/task/XStatusIndicator.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/range/b2drange.hxx> #include <rtl/ustring.hxx> @@ -56,12 +57,15 @@ namespace pdfi ImageContainer& _rImages, PDFIProcessor& _rProcessor, const com::sun::star::uno::Reference< - com::sun::star::task::XStatusIndicator>& _xStatusIndicator ) : + com::sun::star::task::XStatusIndicator>& _xStatusIndicator, + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext) + : rEmitter(_rEmitter), rStyles(_rStyles), rImages(_rImages), rProcessor(_rProcessor), - xStatusIndicator(_xStatusIndicator) + xStatusIndicator(_xStatusIndicator), + m_xContext(xContext) {} XmlEmitter& rEmitter; @@ -70,6 +74,8 @@ namespace pdfi PDFIProcessor& rProcessor; com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator> xStatusIndicator; + com::sun::star::uno::Reference< + com::sun::star::uno::XComponentContext > m_xContext; }; struct Element : public ElementTreeVisitable @@ -178,7 +184,7 @@ namespace pdfi { friend class ElementFactory; protected: - ParagraphElement( Element* pParent ) : Element( pParent ), Type( Normal ) {} + ParagraphElement( Element* pParent ) : Element( pParent ), Type( Normal ), bRtl( false ) {} public: // ElementTreeVisitable @@ -194,6 +200,7 @@ namespace pdfi enum ParagraphType { Normal, Headline }; ParagraphType Type; + bool bRtl; }; struct PolyPolyElement : public DrawElement diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.cxx b/sdext/source/pdfimport/tree/pdfiprocessor.cxx index d132c8f74c31..d823cac524cf 100644 --- a/sdext/source/pdfimport/tree/pdfiprocessor.cxx +++ b/sdext/source/pdfimport/tree/pdfiprocessor.cxx @@ -61,7 +61,10 @@ using namespace com::sun::star; namespace pdfi { - PDFIProcessor::PDFIProcessor( const uno::Reference< task::XStatusIndicator >& xStat ) : + PDFIProcessor::PDFIProcessor( const uno::Reference< task::XStatusIndicator >& xStat , + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext) : + + m_xContext(xContext), fYPrevTextPosition(-10000.0), fPrevTextHeight(0.0), fXPrevTextPosition(0.0), @@ -842,7 +845,7 @@ void PDFIProcessor::emit( XmlEmitter& rEmitter, m_pDocument->visitedBy( *finalizingVisitor, std::list<Element*>::iterator() ); - EmitContext aContext( rEmitter, aStyles, m_aImages, *this, m_xStatusIndicator ); + EmitContext aContext( rEmitter, aStyles, m_aImages, *this, m_xStatusIndicator, m_xContext ); ElementTreeVisitorSharedPtr aEmittingVisitor( rVisitorFactory.createEmittingVisitor(aContext)); diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.hxx b/sdext/source/pdfimport/tree/pdfiprocessor.hxx index 6a9d4ab85a4d..e646d6999df7 100644 --- a/sdext/source/pdfimport/tree/pdfiprocessor.hxx +++ b/sdext/source/pdfimport/tree/pdfiprocessor.hxx @@ -72,13 +72,16 @@ namespace pdfi class PDFIProcessor : public ContentSink { public: + com::sun::star::uno::Reference< + com::sun::star::uno::XComponentContext > m_xContext; double fYPrevTextPosition; double fPrevTextHeight; double fXPrevTextPosition; double fPrevTextWidth; enum DocumentTextDirecion { LrTb, RlTb, TbLr }; - explicit PDFIProcessor( const com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator >& ); + explicit PDFIProcessor( const com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator >& xStat, + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext) ; /// TEMP - enable writer-like text:p on doc level void enableToplevelText(); |