oox/Library_oox.mk | 1 oox/inc/oox/export/vmlexport.hxx | 23 +++++++- oox/source/export/vmlexport.cxx | 72 ++++++++++++++++++++++++--- sw/source/filter/ww8/docxattributeoutput.cxx | 51 ++++++++++++++++++- sw/source/filter/ww8/docxattributeoutput.hxx | 7 ++ sw/source/filter/ww8/docxexport.cxx | 2 6 files changed, 145 insertions(+), 11 deletions(-)
New commits: commit c3039612b838c68c00c4aaf993497c17d28163b3 Author: Miklos Vajna <vmik...@suse.cz> Date: Mon Aug 13 17:37:46 2012 +0200 fdo#53113 various docx shape export fixes - docx export: initial shape text support - vml export: handle custom segment types - docx: export fillBlip shape property Change-Id: I8453d76cfb91386c8beaedc874e09a291234babb Reviewed-on: https://gerrit.libreoffice.org/411 Reviewed-by: Bosdonnat Cedric <cedric.bosdon...@free.fr> Tested-by: Bosdonnat Cedric <cedric.bosdon...@free.fr> diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk index 928e0b6..a7a658a 100644 --- a/oox/Library_oox.mk +++ b/oox/Library_oox.mk @@ -64,6 +64,7 @@ $(eval $(call gb_Library_use_libraries,oox,\ comphelper \ cppu \ cppuhelper \ + editeng \ msfilter \ sal \ sax \ diff --git a/oox/inc/oox/export/vmlexport.hxx b/oox/inc/oox/export/vmlexport.hxx index 0667a57..ad53fca 100644 --- a/oox/inc/oox/export/vmlexport.hxx +++ b/oox/inc/oox/export/vmlexport.hxx @@ -30,8 +30,10 @@ #define _OOX_EXPORT_VMLEXPORT_HXX_ #include <oox/dllapi.h> +#include <oox/export/drawingml.hxx> #include <sax/fshelper.hxx> #include <filter/msfilter/escherex.hxx> +#include <editeng/outlobj.hxx> namespace rtl { class OString; @@ -42,11 +44,28 @@ namespace oox { namespace vml { +/// Interface to be implemented by the parent exporter that knows how to handle shape text. +class OOX_DLLPUBLIC VMLTextExport +{ +public: + virtual void WriteOutliner(const OutlinerParaObject& rParaObj) = 0; + virtual oox::drawingml::DrawingML& GetDrawingML() = 0; +protected: + VMLTextExport() {} + virtual ~VMLTextExport() {} +}; + class OOX_DLLPUBLIC VMLExport : public EscherEx { /// Fast serializer to output the data ::sax_fastparser::FSHelperPtr m_pSerializer; + /// Parent exporter, used for text callback. + VMLTextExport* m_pTextExport; + + /// The object we're exporting. + const SdrObject* m_pSdrObject; + /// Fill the shape attributes as they come. ::sax_fastparser::FastAttributeList *m_pShapeAttrList; @@ -63,7 +82,7 @@ class OOX_DLLPUBLIC VMLExport : public EscherEx bool *m_pShapeTypeWritten; public: - VMLExport( ::sax_fastparser::FSHelperPtr pSerializer ); + VMLExport( ::sax_fastparser::FSHelperPtr pSerializer, VMLTextExport* pTextExport = 0 ); virtual ~VMLExport(); ::sax_fastparser::FSHelperPtr @@ -72,7 +91,7 @@ public: /// Export the sdr object as VML. /// /// Call this when you need to export the object as VML. - using EscherEx::AddSdrObject; + sal_uInt32 AddSdrObject( const SdrObject& rObj ); protected: /// Add an attribute to the generated <v:shape/> element. diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx index 1912381..62933fe 100644 --- a/oox/source/export/vmlexport.cxx +++ b/oox/source/export/vmlexport.cxx @@ -34,6 +34,8 @@ #include <rtl/ustring.hxx> #include <tools/stream.hxx> +#include <svx/svdotext.hxx> +#include <vcl/cvtgrf.hxx> #include <cstdio> @@ -45,9 +47,11 @@ using rtl::OUStringBuffer; using namespace sax_fastparser; using namespace oox::vml; -VMLExport::VMLExport( ::sax_fastparser::FSHelperPtr pSerializer ) +VMLExport::VMLExport( ::sax_fastparser::FSHelperPtr pSerializer, VMLTextExport* pTextExport ) : EscherEx( EscherExGlobalRef(new EscherExGlobal(0)), 0 ), m_pSerializer( pSerializer ), + m_pTextExport( pTextExport ), + m_pSdrObject( 0 ), m_pShapeAttrList( NULL ), m_nShapeType( ESCHER_ShpInst_Nil ), m_pShapeStyle( new OStringBuffer( 200 ) ), @@ -472,9 +476,13 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect aPath.append( "e" ); break; default: -#if OSL_DEBUG_LEVEL > 0 - fprintf( stderr, "TODO: unhandled segment '%x' in the path\n", nSeg ); -#endif + // See EscherPropertyContainer::CreateCustomShapeProperties, by default nSeg is simply the number of points. + for (int i = 0; i < nSeg; ++i) + { + sal_Int32 nX = impl_GetPointComponent(pVerticesIt, nPointSize); + sal_Int32 nY = impl_GetPointComponent(pVerticesIt, nPointSize); + aPath.append("l").append(nX).append(",").append(nY); + } break; } } @@ -494,6 +502,7 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect case ESCHER_Prop_fillType: // 384 case ESCHER_Prop_fillColor: // 385 case ESCHER_Prop_fillBackColor: // 387 + case ESCHER_Prop_fillBlip: // 390 case ESCHER_Prop_fNoFillHitTest: // 447 { sal_uInt32 nValue; @@ -506,7 +515,7 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect { case ESCHER_FillSolid: pFillType = "solid"; break; // TODO case ESCHER_FillPattern: pFillType = ""; break; - // TODO case ESCHER_FillTexture: pFillType = ""; break; + case ESCHER_FillTexture: pFillType = "tile"; break; // TODO case ESCHER_FillPicture: pFillType = ""; break; // TODO case ESCHER_FillShade: pFillType = ""; break; // TODO case ESCHER_FillShadeCenter: pFillType = ""; break; @@ -530,6 +539,19 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect if ( rProps.GetOpt( ESCHER_Prop_fillBackColor, nValue ) ) impl_AddColor( pAttrList, XML_color2, nValue ); + EscherPropSortStruct aStruct; + if ( rProps.GetOpt( ESCHER_Prop_fillBlip, aStruct ) && m_pTextExport) + { + SvMemoryStream aStream; + int nHeaderSize = 25; // The first bytes are WW8-specific, we're only interested in the PNG + aStream.Write(aStruct.pBuf + nHeaderSize, aStruct.nPropSize - nHeaderSize); + aStream.Seek(0); + Graphic aGraphic; + GraphicConverter::Import(aStream, aGraphic, CVT_PNG); + OUString aImageId = m_pTextExport->GetDrawingML().WriteImage( aGraphic ); + pAttrList->add(FSNS(XML_r, XML_id), OUStringToOString(aImageId, RTL_TEXTENCODING_UTF8)); + } + if ( rProps.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ) ) impl_AddBool( pAttrList, XML_detectmouseclick, nValue ); @@ -538,6 +560,7 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect bAlreadyWritten[ ESCHER_Prop_fillType ] = true; bAlreadyWritten[ ESCHER_Prop_fillColor ] = true; bAlreadyWritten[ ESCHER_Prop_fillBackColor ] = true; + bAlreadyWritten[ ESCHER_Prop_fillBlip ] = true; bAlreadyWritten[ ESCHER_Prop_fNoFillHitTest ] = true; break; @@ -648,7 +671,7 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect default: #if OSL_DEBUG_LEVEL > 0 fprintf( stderr, "TODO VMLExport::Commit(), unimplemented id: %d, value: %" SAL_PRIuUINT32 ", data: [%" SAL_PRIuUINT32 ", %p]\n", - it->nPropId, it->nPropValue, it->nPropSize, it->pBuf ); + nId, it->nPropValue, it->nPropSize, it->pBuf ); if ( it->nPropSize ) { const sal_uInt8 *pIt = it->pBuf; @@ -806,6 +829,37 @@ sal_Int32 VMLExport::StartShape() m_pSerializer->startElementNS( XML_v, nShapeElement, XFastAttributeListRef( m_pShapeAttrList ) ); } + // now check if we have some text and we have a text exporter registered + const SdrTextObj* pTxtObj = PTR_CAST(SdrTextObj, m_pSdrObject); + if (pTxtObj && m_pTextExport) + { + const OutlinerParaObject* pParaObj = 0; + bool bOwnParaObj = false; + + /* + #i13885# + When the object is actively being edited, that text is not set into + the objects normal text object, but lives in a seperate object. + */ + if (pTxtObj->IsTextEditActive()) + { + pParaObj = pTxtObj->GetEditOutlinerParaObject(); + bOwnParaObj = true; + } + else + { + pParaObj = pTxtObj->GetOutlinerParaObject(); + } + + if( pParaObj ) + { + // this is reached only in case some text is attached to the shape + m_pTextExport->WriteOutliner(*pParaObj); + if( bOwnParaObj ) + delete pParaObj; + } + } + return nShapeElement; } @@ -818,4 +872,10 @@ void VMLExport::EndShape( sal_Int32 nShapeElement ) } } +sal_uInt32 VMLExport::AddSdrObject( const SdrObject& rObj ) +{ + m_pSdrObject = &rObj; + return EscherEx::AddSdrObject(rObj); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 7ad5a1e..179c2f6 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -45,7 +45,6 @@ #include <oox/token/tokens.hxx> #include <oox/export/drawingml.hxx> #include <oox/export/utils.hxx> -#include <oox/export/vmlexport.hxx> #include <oox/mathml/export.hxx> #include <i18npool/mslangid.hxx> @@ -94,6 +93,7 @@ #include <editeng/blnkitem.hxx> #include <editeng/charhiddenitem.hxx> #include <editeng/opaqitem.hxx> +#include <editeng/editobj.hxx> #include <svx/svdmodel.hxx> #include <svx/svdobj.hxx> #include <sfx2/sfxbasemodel.hxx> @@ -2423,6 +2423,55 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE ); } +void DocxAttributeOutput::WriteOutliner(const OutlinerParaObject& rParaObj) +{ + const EditTextObject& rEditObj = rParaObj.GetTextObject(); + MSWord_SdrAttrIter aAttrIter( m_rExport, rEditObj, TXT_HFTXTBOX ); + + sal_uInt16 nPara = rEditObj.GetParagraphCount(); + + m_pSerializer->startElementNS( XML_w, XML_textbox, FSEND ); + m_pSerializer->startElementNS( XML_w, XML_txbxContent, FSEND ); + for (sal_uInt16 n = 0; n < nPara; ++n) + { + if( n ) + aAttrIter.NextPara( n ); + + String aStr( rEditObj.GetText( n )); + xub_StrLen nAktPos = 0; + xub_StrLen nEnd = aStr.Len(); + + m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); + do { + xub_StrLen nNextAttr = aAttrIter.WhereNext(); + if( nNextAttr > nEnd ) + nNextAttr = nEnd; + + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos ); + if( !bTxtAtr ) + { + String aOut( aStr.Copy( nAktPos, nNextAttr - nAktPos ) ); + RunText(aOut); + } + + m_pSerializer->endElementNS( XML_w, XML_r ); + + nAktPos = nNextAttr; + aAttrIter.NextPos(); + } + while( nAktPos < nEnd ); + m_pSerializer->endElementNS( XML_w, XML_p ); + } + m_pSerializer->endElementNS( XML_w, XML_txbxContent ); + m_pSerializer->endElementNS( XML_w, XML_textbox ); +} + +oox::drawingml::DrawingML& DocxAttributeOutput::GetDrawingML() +{ + return m_rDrawingML; +} + void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt, sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId, bool bAutoUpdate ) { diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index db78516..4caf047 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -42,6 +42,7 @@ #include <vector> #include <boost/scoped_ptr.hpp> +#include <oox/export/vmlexport.hxx> class SwGrfNode; class SdrObject; @@ -68,7 +69,7 @@ enum DocxColBreakStatus }; /// The class that has handlers for various resource types when exporting as DOCX. -class DocxAttributeOutput : public AttributeOutputBase +class DocxAttributeOutput : public AttributeOutputBase, public oox::vml::VMLTextExport { public: /// Export the state of RTL/CJK. @@ -633,6 +634,10 @@ public: bool HasPostitFields() const; void WritePostitFields(); + + /// VMLTextExport + virtual void WriteOutliner(const OutlinerParaObject& rParaObj); + virtual oox::drawingml::DrawingML& GetDrawingML(); }; #endif // _DOCXATTRIBUTEOUTPUT_HXX_ diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 418589d..6d1db6c 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -824,7 +824,7 @@ DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCur m_pAttrOutput = new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML ); // the related VMLExport - m_pVMLExport = new VMLExport( m_pDocumentFS ); + m_pVMLExport = new VMLExport( m_pDocumentFS, m_pAttrOutput ); } DocxExport::~DocxExport() _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits