sw/source/filter/ww8/docxattributeoutput.cxx | 230 +++++++++++++++++---------- sw/source/filter/ww8/docxattributeoutput.hxx | 10 - 2 files changed, 160 insertions(+), 80 deletions(-)
New commits: commit 4614af18d3e033e0eed27db3d4c897afb8c8baa1 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Dec 10 15:55:13 2013 +0100 DOCX shape export: when in experimental mode, use DML instead of VML Change-Id: I8a07b74c047dfa2c4b1096e3cd3ace3bd5f93d0a diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 8e33651..b546b37 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -110,6 +110,7 @@ #include <osl/file.hxx> #include <rtl/tencinfo.h> #include <vcl/embeddedfontshelper.hxx> +#include <svtools/miscopt.hxx> #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> @@ -1058,7 +1059,10 @@ void DocxAttributeOutput::StartRunProperties() m_postponedDiagram = new std::list< PostponedDiagram >; OSL_ASSERT( m_postponedVMLDrawing == NULL ); - m_postponedVMLDrawing = new std::list< PostponedVMLDrawing >; + m_postponedVMLDrawing = new std::list< PostponedDrawing >; + + assert(!m_postponedDMLDrawing); + m_postponedDMLDrawing = new std::list< PostponedDrawing >; } void DocxAttributeOutput::InitCollectedRunProperties() @@ -1178,6 +1182,7 @@ void DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData ) //We need to write w:pict tag after the w:rPr. WritePostponedVMLDrawing(); + WritePostponedDMLDrawing(); // merge the properties _before_ the run text (strictly speaking, just // after the start of the run) @@ -3316,7 +3321,7 @@ void DocxAttributeOutput::WritePostponedVMLDrawing() if(m_postponedVMLDrawing == NULL) return; - for( std::list< PostponedVMLDrawing >::iterator it = m_postponedVMLDrawing->begin(); + for( std::list< PostponedDrawing >::iterator it = m_postponedVMLDrawing->begin(); it != m_postponedVMLDrawing->end(); ++it ) { @@ -3326,6 +3331,21 @@ void DocxAttributeOutput::WritePostponedVMLDrawing() m_postponedVMLDrawing = NULL; } +void DocxAttributeOutput::WritePostponedDMLDrawing() +{ + if(m_postponedDMLDrawing == NULL) + return; + + for( std::list< PostponedDrawing >::iterator it = m_postponedDMLDrawing->begin(); + it != m_postponedDMLDrawing->end(); + ++it ) + { + WriteDMLDrawing(it->object, it->frame); + } + delete m_postponedDMLDrawing; + m_postponedDMLDrawing = NULL; +} + void DocxAttributeOutput::WriteDMLDrawing( const SdrObject* pSdrObject, const SwFrmFmt* pFrmFmt ) { Size aSize(pSdrObject->GetSnapRect().GetWidth(), pSdrObject->GetSnapRect().GetHeight()); @@ -3422,11 +3442,23 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po } else { - if ( m_postponedVMLDrawing == NULL ) - WriteVMLDrawing( pSdrObj, rFrame.GetFrmFmt(), rNdTopLeft); - else // we are writing out attributes, but w:pict should not be inside w:rPr, - { // so write it out later - m_postponedVMLDrawing->push_back( PostponedVMLDrawing( pSdrObj, &(rFrame.GetFrmFmt()), &rNdTopLeft ) ); + SvtMiscOptions aMiscOptions; + if (aMiscOptions.IsExperimentalMode()) + { + if ( m_postponedDMLDrawing == NULL ) + WriteDMLDrawing( pSdrObj, &rFrame.GetFrmFmt()); + else + // we are writing out attributes, but w:drawing should not be inside w:rPr, so write it out later + m_postponedDMLDrawing->push_back(PostponedDrawing(pSdrObj, &(rFrame.GetFrmFmt()), &rNdTopLeft)); + } + else + { + if ( m_postponedVMLDrawing == NULL ) + WriteVMLDrawing( pSdrObj, rFrame.GetFrmFmt(), rNdTopLeft); + else // we are writing out attributes, but w:pict should not be inside w:rPr, + { // so write it out later + m_postponedVMLDrawing->push_back( PostponedDrawing( pSdrObj, &(rFrame.GetFrmFmt()), &rNdTopLeft ) ); + } } } } @@ -6406,6 +6438,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri m_postponedGraphic( NULL ), m_postponedDiagram( NULL ), m_postponedVMLDrawing(NULL), + m_postponedDMLDrawing(NULL), m_postponedMath( NULL ), m_postponedChart( NULL ), pendingPlaceholder( NULL ), diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 4326cde..bac7c8a 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -646,6 +646,7 @@ private: void WritePostponedDiagram(); void WritePostponedChart(); void WritePostponedVMLDrawing(); + void WritePostponedDMLDrawing(); void WriteCommentRanges(); void StartField_Impl( FieldInfos& rInfos, bool bWriteRun = sal_False ); @@ -747,14 +748,15 @@ private: }; std::list< PostponedDiagram >* m_postponedDiagram; - struct PostponedVMLDrawing + struct PostponedDrawing { - PostponedVMLDrawing( const SdrObject* sdrObj, const SwFrmFmt* frm, const Point* pt ) : object( sdrObj ), frame( frm ), point( pt ) {}; + PostponedDrawing( const SdrObject* sdrObj, const SwFrmFmt* frm, const Point* pt ) : object( sdrObj ), frame( frm ), point( pt ) {}; const SdrObject* object; const SwFrmFmt* frame; const Point* point; }; - std::list< PostponedVMLDrawing >* m_postponedVMLDrawing; + std::list< PostponedDrawing >* m_postponedVMLDrawing; + std::list< PostponedDrawing >* m_postponedDMLDrawing; const SwOLENode* m_postponedMath; const SdrObject* m_postponedChart; commit 03f0128c15ef59bbcf193bcd85e1763111c29ad7 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Dec 10 15:36:53 2013 +0100 DOCX export: add method to write wp + dml markup for an SdrObject Also, factor out common code from FlyFrameGraphic() and WriteDMLDrawing() to lcl_startDMLAnchorInline() and lcl_endDMLAnchorInline() to avoid code duplication. Change-Id: Ic1bed48e45b1cdb2d061ed7099206c0b1aa4f9f7 diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 9e0c8a3..8e33651 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2750,50 +2750,17 @@ void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj ) } } -void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj ) +void lcl_endDMLAnchorInline(sax_fastparser::FSHelperPtr pSerializer, const SwFrmFmt* pFrmFmt) { - OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj ) - some stuff still missing" ); - // detect mis-use of the API - assert(pGrfNode || (pOLEFrmFmt && pOLENode)); - const SwFrmFmt* pFrmFmt = pGrfNode ? pGrfNode->GetFlyFmt() : pOLEFrmFmt; - // create the relation ID - OString aRelId; - sal_Int32 nImageType; - if ( pGrfNode && pGrfNode->IsLinkedFile() ) - { - // linked image, just create the relation - OUString aFileName; - pGrfNode->GetFileFilterNms( &aFileName, 0 ); - - // TODO Convert the file name to relative for better interoperability - - aRelId = m_rExport.AddRelation( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - aFileName ); - - nImageType = XML_link; - } - else - { - // inline, we also have to write the image itself - const Graphic* pGraphic = 0; - if (pGrfNode) - pGraphic = &const_cast< Graphic& >( pGrfNode->GetGrf() ); - else - pGraphic = pOLENode->GetGraphic(); - - m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream - OUString aImageId = m_rDrawingML.WriteImage( *pGraphic ); - - aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 ); - - nImageType = XML_embed; - } + bool isAnchor = pFrmFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR; + pSerializer->endElementNS( XML_wp, isAnchor ? XML_anchor : XML_inline ); - if ( aRelId.isEmpty() ) - return; + pSerializer->endElementNS( XML_w, XML_drawing ); +} - m_pSerializer->startElementNS( XML_w, XML_drawing, FSEND ); +void lcl_startDMLAnchorInline(sax_fastparser::FSHelperPtr pSerializer, const SwFrmFmt* pFrmFmt, const Size& rSize) +{ + pSerializer->startElementNS( XML_w, XML_drawing, FSEND ); const SvxLRSpaceItem pLRSpaceItem = pFrmFmt->GetLRSpace(false); const SvxULSpaceItem pULSpaceItem = pFrmFmt->GetULSpace(false); @@ -2801,7 +2768,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size bool isAnchor = pFrmFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR; if( isAnchor ) { - ::sax_fastparser::FastAttributeList* attrList = m_pSerializer->createAttrList(); + ::sax_fastparser::FastAttributeList* attrList = pSerializer->createAttrList(); attrList->add( XML_behindDoc, pFrmFmt->GetOpaque().GetValue() ? "0" : "1" ); attrList->add( XML_distT, OString::number( TwipsToEMU( pULSpaceItem.GetUpper() ) ).getStr( ) ); attrList->add( XML_distB, OString::number( TwipsToEMU( pULSpaceItem.GetLower() ) ).getStr( ) ); @@ -2813,8 +2780,8 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size attrList->add( XML_allowOverlap, "1" ); // TODO if( const SdrObject* pObj = pFrmFmt->FindRealSdrObject()) attrList->add( XML_relativeHeight, OString::number( pObj->GetOrdNum())); - m_pSerializer->startElementNS( XML_wp, XML_anchor, XFastAttributeListRef( attrList )); - m_pSerializer->singleElementNS( XML_wp, XML_simplePos, XML_x, "0", XML_y, "0", FSEND ); // required, unused + pSerializer->startElementNS( XML_wp, XML_anchor, XFastAttributeListRef( attrList )); + pSerializer->singleElementNS( XML_wp, XML_simplePos, XML_x, "0", XML_y, "0", FSEND ); // required, unused const char* relativeFromH; const char* relativeFromV; const char* alignH = NULL; @@ -2897,49 +2864,50 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size default: break; } - m_pSerializer->startElementNS( XML_wp, XML_positionH, XML_relativeFrom, relativeFromH, FSEND ); + pSerializer->startElementNS( XML_wp, XML_positionH, XML_relativeFrom, relativeFromH, FSEND ); if( alignH != NULL ) { - m_pSerializer->startElementNS( XML_wp, XML_align, FSEND ); - m_pSerializer->write( alignH ); - m_pSerializer->endElementNS( XML_wp, XML_align ); + pSerializer->startElementNS( XML_wp, XML_align, FSEND ); + pSerializer->write( alignH ); + pSerializer->endElementNS( XML_wp, XML_align ); } else { - m_pSerializer->startElementNS( XML_wp, XML_posOffset, FSEND ); - m_pSerializer->write( TwipsToEMU( pFrmFmt->GetHoriOrient().GetPos())); - m_pSerializer->endElementNS( XML_wp, XML_posOffset ); + pSerializer->startElementNS( XML_wp, XML_posOffset, FSEND ); + pSerializer->write( TwipsToEMU( pFrmFmt->GetHoriOrient().GetPos())); + pSerializer->endElementNS( XML_wp, XML_posOffset ); } - m_pSerializer->endElementNS( XML_wp, XML_positionH ); - m_pSerializer->startElementNS( XML_wp, XML_positionV, XML_relativeFrom, relativeFromV, FSEND ); + pSerializer->endElementNS( XML_wp, XML_positionH ); + pSerializer->startElementNS( XML_wp, XML_positionV, XML_relativeFrom, relativeFromV, FSEND ); if( alignV != NULL ) { - m_pSerializer->startElementNS( XML_wp, XML_align, FSEND ); - m_pSerializer->write( alignV ); - m_pSerializer->endElementNS( XML_wp, XML_align ); + pSerializer->startElementNS( XML_wp, XML_align, FSEND ); + pSerializer->write( alignV ); + pSerializer->endElementNS( XML_wp, XML_align ); } else { - m_pSerializer->startElementNS( XML_wp, XML_posOffset, FSEND ); - m_pSerializer->write( TwipsToEMU( pFrmFmt->GetVertOrient().GetPos())); - m_pSerializer->endElementNS( XML_wp, XML_posOffset ); + pSerializer->startElementNS( XML_wp, XML_posOffset, FSEND ); + pSerializer->write( TwipsToEMU( pFrmFmt->GetVertOrient().GetPos())); + pSerializer->endElementNS( XML_wp, XML_posOffset ); } - m_pSerializer->endElementNS( XML_wp, XML_positionV ); + pSerializer->endElementNS( XML_wp, XML_positionV ); } else { - m_pSerializer->startElementNS( XML_wp, XML_inline, + pSerializer->startElementNS( XML_wp, XML_inline, XML_distT, OString::number( TwipsToEMU( pULSpaceItem.GetUpper() ) ).getStr( ), XML_distB, OString::number( TwipsToEMU( pULSpaceItem.GetLower() ) ).getStr( ), XML_distL, OString::number( TwipsToEMU( pLRSpaceItem.GetLeft() ) ).getStr( ), XML_distR, OString::number( TwipsToEMU( pLRSpaceItem.GetRight() ) ).getStr( ), FSEND ); } + // now the common parts // extent of the image OString aWidth( OString::number( TwipsToEMU( rSize.Width() ) ) ); OString aHeight( OString::number( TwipsToEMU( rSize.Height() ) ) ); - m_pSerializer->singleElementNS( XML_wp, XML_extent, + pSerializer->singleElementNS( XML_wp, XML_extent, XML_cx, aWidth.getStr(), XML_cy, aHeight.getStr(), FSEND ); @@ -2970,7 +2938,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size } } - m_pSerializer->singleElementNS( XML_wp, XML_effectExtent, + pSerializer->singleElementNS( XML_wp, XML_effectExtent, XML_l, aLeftExt, XML_t, aTopExt, XML_r, aRightExt, XML_b, aBottomExt, FSEND ); @@ -2979,22 +2947,69 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size switch( pFrmFmt->GetSurround().GetValue()) { case SURROUND_NONE: - m_pSerializer->singleElementNS( XML_wp, XML_wrapTopAndBottom, FSEND ); + pSerializer->singleElementNS( XML_wp, XML_wrapTopAndBottom, FSEND ); break; case SURROUND_THROUGHT: - m_pSerializer->singleElementNS( XML_wp, XML_wrapNone, FSEND ); + pSerializer->singleElementNS( XML_wp, XML_wrapNone, FSEND ); break; case SURROUND_PARALLEL: - m_pSerializer->singleElementNS( XML_wp, XML_wrapSquare, + pSerializer->singleElementNS( XML_wp, XML_wrapSquare, XML_wrapText, "bothSides", FSEND ); break; case SURROUND_IDEAL: default: - m_pSerializer->singleElementNS( XML_wp, XML_wrapSquare, + pSerializer->singleElementNS( XML_wp, XML_wrapSquare, XML_wrapText, "largest", FSEND ); break; } } +} + +void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj ) +{ + OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj ) - some stuff still missing" ); + // detect mis-use of the API + assert(pGrfNode || (pOLEFrmFmt && pOLENode)); + const SwFrmFmt* pFrmFmt = pGrfNode ? pGrfNode->GetFlyFmt() : pOLEFrmFmt; + // create the relation ID + OString aRelId; + sal_Int32 nImageType; + if ( pGrfNode && pGrfNode->IsLinkedFile() ) + { + // linked image, just create the relation + OUString aFileName; + pGrfNode->GetFileFilterNms( &aFileName, 0 ); + + // TODO Convert the file name to relative for better interoperability + + aRelId = m_rExport.AddRelation( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", + aFileName ); + + nImageType = XML_link; + } + else + { + // inline, we also have to write the image itself + const Graphic* pGraphic = 0; + if (pGrfNode) + pGraphic = &const_cast< Graphic& >( pGrfNode->GetGrf() ); + else + pGraphic = pOLENode->GetGraphic(); + + m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream + OUString aImageId = m_rDrawingML.WriteImage( *pGraphic ); + + aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 ); + + nImageType = XML_embed; + } + + if ( aRelId.isEmpty() ) + return; + + lcl_startDMLAnchorInline(m_pSerializer, pFrmFmt, rSize); + // picture description (used for pic:cNvPr later too) ::sax_fastparser::FastAttributeList* docPrattrList = m_pSerializer->createAttrList(); docPrattrList->add( XML_id, OString::number( m_anchorId++).getStr()); @@ -3078,6 +3093,8 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size m_pSerializer->singleElementNS( XML_a, XML_off, XML_x, "0", XML_y, "0", FSEND ); + OString aWidth( OString::number( TwipsToEMU( rSize.Width() ) ) ); + OString aHeight( OString::number( TwipsToEMU( rSize.Height() ) ) ); m_pSerializer->singleElementNS( XML_a, XML_ext, XML_cx, aWidth.getStr(), XML_cy, aHeight.getStr(), @@ -3106,6 +3123,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size m_pSerializer->endElementNS( XML_a, XML_ln ); // Output effects + SvxShadowItem aShadowItem = pFrmFmt->GetShadow(); if ( aShadowItem.GetLocation() != SVX_SHADOW_NONE ) { // Distance is measured diagonally from corner @@ -3149,9 +3167,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size m_pSerializer->endElementNS( XML_a, XML_graphicData ); m_pSerializer->endElementNS( XML_a, XML_graphic ); - m_pSerializer->endElementNS( XML_wp, isAnchor ? XML_anchor : XML_inline ); - - m_pSerializer->endElementNS( XML_w, XML_drawing ); + lcl_endDMLAnchorInline(m_pSerializer, pFrmFmt); } void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rOLENode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt ) @@ -3310,6 +3326,33 @@ void DocxAttributeOutput::WritePostponedVMLDrawing() m_postponedVMLDrawing = NULL; } +void DocxAttributeOutput::WriteDMLDrawing( const SdrObject* pSdrObject, const SwFrmFmt* pFrmFmt ) +{ + Size aSize(pSdrObject->GetSnapRect().GetWidth(), pSdrObject->GetSnapRect().GetHeight()); + lcl_startDMLAnchorInline(m_pSerializer, pFrmFmt, aSize); + + sax_fastparser::FastAttributeList* pDocPrAttrList = m_pSerializer->createAttrList(); + pDocPrAttrList->add( XML_id, OString::number( m_anchorId++).getStr()); + pDocPrAttrList->add( XML_name, OUStringToOString(pSdrObject->GetName(), RTL_TEXTENCODING_UTF8).getStr() ); + XFastAttributeListRef xDocPrAttrListRef( pDocPrAttrList ); + m_pSerializer->singleElementNS( XML_wp, XML_docPr, xDocPrAttrListRef ); + + m_pSerializer->startElementNS( XML_a, XML_graphic, + FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main", + FSEND ); + m_pSerializer->startElementNS( XML_a, XML_graphicData, + XML_uri, "http://schemas.microsoft.com/office/word/2010/wordprocessingShape", + FSEND ); + + uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pSdrObject)->getUnoShape(), uno::UNO_QUERY_THROW); + m_rExport.OutputDML(xShape); + + m_pSerializer->endElementNS( XML_a, XML_graphicData ); + m_pSerializer->endElementNS( XML_a, XML_graphic ); + + lcl_endDMLAnchorInline(m_pSerializer, pFrmFmt); +} + void DocxAttributeOutput::WriteVMLDrawing( const SdrObject* sdrObj, const SwFrmFmt& rFrmFmt,const Point& rNdTopLeft ) { bool bSwapInPage = false; diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 65416af..4326cde 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -374,6 +374,8 @@ private: /// writes VML data void WriteVMLDrawing( const SdrObject* sdrObj, const SwFrmFmt& rFrmFmt,const Point& rNdTopLeft ); + /// Writes wp wrapper code around an SdrObject, which itself is written using drawingML syntax. + void WriteDMLDrawing( const SdrObject* pSdrObj, const SwFrmFmt* pFrmFmt ); void InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); void StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); void StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits