diff options
Diffstat (limited to 'filter')
-rw-r--r-- | filter/source/svg/presentation_engine.js | 243 | ||||
-rw-r--r-- | filter/source/svg/svgexport.cxx | 312 | ||||
-rw-r--r-- | filter/source/svg/svgwriter.cxx | 392 | ||||
-rw-r--r-- | filter/source/svg/svgwriter.hxx | 6 |
4 files changed, 665 insertions, 288 deletions
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js index 186ef95f59bf..27075cdff291 100644 --- a/filter/source/svg/presentation_engine.js +++ b/filter/source/svg/presentation_engine.js @@ -1098,6 +1098,7 @@ var aPresentationClipPathId = 'presentation_clip_path'; var aOOOAttrNumberOfSlides = 'number-of-slides'; var aOOOAttrStartSlideNumber= 'start-slide-number'; var aOOOAttrNumberingType = 'page-numbering-type'; +var aOOOAttrListItemNumberingType= 'numbering-type'; var aOOOAttrSlide = 'slide'; var aOOOAttrMaster = 'master'; @@ -5708,6 +5709,7 @@ function AnimationBaseNode( aAnimElem, aParentNode, aNodeContext ) this.sClassName = 'AnimationBaseNode'; this.bIsContainer = false; this.aTargetElement = null; + this.bIsTargetTextElement = false this.aAnimatedElement = null; this.aActivity = null; @@ -5736,6 +5738,10 @@ AnimationBaseNode.prototype.parseElement = function() log( 'AnimationBaseNode.parseElement: target element not found: ' + sTargetElementAttr ); } + // sub-item attribute for text animated element + var sSubItemAttr = aAnimElem.getAttribute( 'sub-item' ); + this.bIsTargetTextElement = ( sSubItemAttr && ( sSubItemAttr === 'text' ) ); + // additive attribute var sAdditiveAttr = aAnimElem.getAttribute( 'additive' ); if( sAdditiveAttr && aAddittiveModeInMap[sAdditiveAttr] ) @@ -5765,8 +5771,16 @@ AnimationBaseNode.prototype.parseElement = function() // create animated element if( !this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ] ) { - this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ] + if( this.bIsTargetTextElement ) + { + this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ] + = new AnimatedTextElement( this.aTargetElement ); + } + else + { + this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ] = new AnimatedElement( this.aTargetElement ); + } } this.aAnimatedElement = this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ]; @@ -7414,6 +7428,7 @@ ClippingAnimation.prototype.end = function() { this.aAnimatableElement.cleanClipPath(); this.bAnimationStarted = false; + this.aAnimatableElement.notifyAnimationEnd(); } }; @@ -7468,7 +7483,10 @@ GenericAnimation.prototype.start = function( aAnimatableElement ) GenericAnimation.prototype.end = function() { if( this.bAnimationStarted ) + { this.bAnimationStarted = false; + this.aAnimatableElement.notifyAnimationEnd(); + } }; GenericAnimation.prototype.perform = function( aValue ) @@ -9203,6 +9221,229 @@ AnimatedElement.prototype.DBG = function( sMessage, nTime ) aAnimatedElementDebugPrinter.print( 'AnimatedElement(' + this.getId() + ')' + sMessage, nTime ); }; +// ------------------------------------------------------------------------------------------ // +function AnimatedTextElement( aElement ) +{ + var theDocument = document; + + var sTextType = aElement.getAttribute( 'class' ); + var bIsListItem = ( sTextType === 'ListItem' ); + if( ( sTextType !== 'TextParagraph' ) && !bIsListItem ) + { + log( 'AnimatedTextElement: passed element is not a paragraph.' ); + return; + } + var aTextShapeElement = aElement.parentNode; + sTextType = aTextShapeElement.getAttribute( 'class' ); + if( sTextType !== 'TextShape' ) + { + log( 'AnimatedTextElement: element parent is not a text shape.' ); + return; + } + var aTextShapeGroup = aTextShapeElement.parentNode; + // We search for the helper group element used for inserting + // the element copy to be animated; if it doesn't exist we create it. + var aAnimatedElementGroup = getElementByClassName( aTextShapeGroup, 'AnimatedElements' ); + if( !aAnimatedElementGroup ) + { + aAnimatedElementGroup = theDocument.createElementNS( NSS['svg'], 'g' ); + aAnimatedElementGroup.setAttribute( 'class', 'AnimatedElements' ); + aTextShapeGroup.appendChild( aAnimatedElementGroup ); + } + + // Create element used on animating + var aAnimatableElement = theDocument.createElementNS( NSS['svg'], 'g' ); + var aTextElement = theDocument.createElementNS( NSS['svg'], 'text' ); + // Clone paragraph element <tspan> + var aParagraphElement = aElement.cloneNode( true ); + + // In case we are dealing with a list item that utilizes a bullet char + // we need to clone the related bullet char too. + var aBulletCharClone = null; + var aBulletCharElem = null; + var bIsBulletCharStyle = + ( aElement.getAttributeNS( NSS['ooo'], aOOOAttrListItemNumberingType ) === 'bullet-style' ); + if( bIsBulletCharStyle ) + { + var aBulletCharGroupElem = getElementByClassName( aTextShapeGroup, 'BulletChars' ); + if( aBulletCharGroupElem ) + { + var aBulletPlaceholderElem = getElementByClassName( aElement.firstElementChild, 'BulletPlaceholder' ); + if( aBulletPlaceholderElem ) + { + var sId = aBulletPlaceholderElem.getAttribute( 'id' ); + sId = 'bullet-char(' + sId + ')'; + aBulletCharElem = theDocument.getElementById( sId ); + if( aBulletCharElem ) + { + aBulletCharClone = aBulletCharElem.cloneNode( true ); + } + else + { + log( 'AnimatedTextElement: ' + sId + ' not found.' ); + } + } + else + { + log( 'AnimatedTextElement: no bullet placeholder found' ); + } + } + else + { + log( 'AnimatedTextElement: no bullet char group found' ); + } + } + + var aBitmapElemSet = new Array(); + var aBitmapCloneSet = new Array(); + var aBitmapPlaceholderSet = getElementsByClassName( aElement, 'BitmapPlaceholder' ); + if( aBitmapPlaceholderSet ) + { + var i; + for( i = 0; i < aBitmapPlaceholderSet.length; ++i ) + { + sId = aBitmapPlaceholderSet[i].getAttribute( 'id' ); + var sBitmapChecksum = sId.substring( 'bitmap-placeholder'.length + 1, sId.length - 1 ); + sId = 'embedded-bitmap(' + sBitmapChecksum + ')'; + aBitmapElemSet[i] = theDocument.getElementById( sId ); + if( aBitmapElemSet[i] ) + { + aBitmapCloneSet[i] = aBitmapElemSet[i].cloneNode( true ); + } + else + { + log( 'AnimatedTextElement: ' + sId + ' not found.' ); + } + } + } + + + // Change clone element id. + this.sParagraphId = sId = aParagraphElement.getAttribute( 'id' ); + aParagraphElement.setAttribute( 'id', sId +'.a' ); + if( aBulletCharClone ) + aBulletCharClone.removeAttribute( 'id' ); + for( i = 0; i < aBitmapCloneSet.length; ++i ) + { + if( aBitmapCloneSet[i] ) + aBitmapCloneSet[i].removeAttribute( 'id' ); + } + + // Hide original text paragraph. + var sVisibilityAttr = aElement.getAttribute( 'visibility' ); + if( sVisibilityAttr === 'hidden' ) + { + aAnimatableElement.setAttribute( 'visibility', 'hidden' ); + this.eInitialVisibility = HIDDEN; + } + else + { + aElement.setAttribute( 'visibility', 'hidden' ); + this.eInitialVisibility = VISIBLE; + } + aParagraphElement.setAttribute( 'visibility', 'inherit' ); + if( aBulletCharClone ) + aBulletCharClone.setAttribute( 'visibility', 'inherit' ); + if( aBulletCharElem ) + aBulletCharElem.setAttribute( 'visibility', 'hidden' ); + for( i = 0; i < aBitmapCloneSet.length; ++i ) + { + if( aBitmapElemSet[i] ) + aBitmapElemSet[i].setAttribute( 'visibility', 'hidden' ); + if( aBitmapCloneSet[i] ) + aBitmapCloneSet[i].setAttribute( 'visibility', 'inherit' ); + } + + + // Append each element to its parent. + // <g class='AnimatedElements'> + // <g> + // <text> + // <tspan class='TextParagraph'> ... </tspan> + // </text> + // [<g class='BulletChar'>...</g>] + // [<g class='EmbeddedBitmap'>...</g>] + // . + // . + // [<g class='EmbeddedBitmap'>...</g>] + // </g> + // </g> + + aTextElement.appendChild( aParagraphElement ); + aAnimatableElement.appendChild( aTextElement ); + if( aBulletCharClone ) + aAnimatableElement.appendChild( aBulletCharClone ); + for( i = 0; i < aBitmapCloneSet.length; ++i ) + { + if( aBitmapCloneSet[i] ) + aAnimatableElement.appendChild( aBitmapCloneSet[i] ); + } + aAnimatedElementGroup.appendChild( aAnimatableElement ); + + this.aParentTextElement = aElement.parentNode; + this.aParagraphElement = aElement; + this.aAnimatedElementGroup = aAnimatedElementGroup; + this.nRunningAnimations = 0; + + AnimatedTextElement.superclass.constructor.call( this, aAnimatableElement ); + +} +extend( AnimatedTextElement, AnimatedElement ); + +/* +AnimatedTextElement.prototype.notifySlideStart = function() +{ + var aClone = this.aBaseElement.cloneNode( true ); + this.aActiveElement.parentNode.replaceChild( aClone, this.aActiveElement ); + this.aActiveElement = aClone; + + var aAnimatedParagraphElement = this.aActiveElement.firstElementChild.firstElementChild; + if( aAnimatedParagraphElement ) + { + var aParagraphElement = aAnimatedParagraphElement.cloneNode( true ); + aParagraphElement.setAttribute( 'id', this.sParagraphId ); + aParagraphElement.setAttribute( 'visibility', aVisibilityAttributeValue[ this.eInitialVisibility ] ); + this.aParentTextElement.replaceChild( aParagraphElement, this.aParagraphElement ); + this.aParagraphElement = aParagraphElement; + } + this.aActiveElement.setAttribute( 'visibility', 'hidden' ); + + + this.initElement(); + this.DBG( '.notifySlideStart invoked' ); +}; + +AnimatedTextElement.prototype.notifyAnimationStart = function() +{ + log( 'AnimatedTextElement.notifyAnimationStart' ); + if( this.nRunningAnimations === 0 ) + { + this.aParagraphElement.setAttribute( 'visibility', 'hidden' ); + this.aActiveElement.setAttribute( 'visibility', aVisibilityAttributeValue[ this.eInitialVisibility ] ); + } + ++this.nRunningAnimations; +}; + +AnimatedTextElement.prototype.notifyAnimationEnd = function() +{ + log( 'AnimatedTextElement.notifyAnimationEnd' ); + --this.nRunningAnimations; + if( this.nRunningAnimations === 0 ) + { + var sVisibilityAttr = this.aActiveElement.getAttribute( 'visibility' ); + var aAnimatedParagraphElement = this.aActiveElement.firstElementChild.firstElementChild; + if( aAnimatedParagraphElement ) + { + var aParagraphElement = aAnimatedParagraphElement.cloneNode( true ); + aParagraphElement.setAttribute( 'visibility', sVisibilityAttr ); + aParagraphElement.setAttribute( 'id', this.sParagraphId ); + this.aParentTextElement.replaceChild( aParagraphElement, this.aParagraphElement ); + this.aParagraphElement = aParagraphElement; + } + this.aActiveElement.setAttribute( 'visibility', 'hidden' ); + } +}; +*/ // ------------------------------------------------------------------------------------------ // diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx index ae2d6dc23403..038b2dbada10 100644 --- a/filter/source/svg/svgexport.cxx +++ b/filter/source/svg/svgexport.cxx @@ -1057,10 +1057,14 @@ sal_Bool SVGFilter::implGenerateMetaData() sElemId += OUString::valueOf( i ); mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sElemId ); aFieldSet[i]->elementExport( mpSVGExport ); - - aFieldSet[i]->growCharSet( mTextFieldCharSets ); } - + if( mpSVGExport->IsEmbedFonts() && mpSVGExport->IsUsePositionedCharacters() ) + { + for( sal_Int32 i = 0, nSize = aFieldSet.size(); i < nSize; ++i ) + { + aFieldSet[i]->growCharSet( mTextFieldCharSets ); + } + } } // text fields are used only for generating meta info so we don't need them anymore for( sal_uInt32 i = 0; i < aFieldSet.size(); ++i ) @@ -2018,170 +2022,184 @@ OUString SVGFilter::implGetInterfaceName( const Reference< XInterface >& rxIf ) IMPL_LINK( SVGFilter, CalcFieldHdl, EditFieldInfo*, pInfo ) { - sal_Bool bFieldProcessed = sal_False; + sal_Bool bFieldProcessed = sal_False; + if( pInfo && mbPresentation ) { bFieldProcessed = true; OUString aRepresentation = B2UCONST(""); if( !mbSinglePage ) { - // to notify to the SVGActionWriter::ImplWriteText method - // that we are dealing with a placeholder shape - aRepresentation = sPlaceholderTag; - - if( !mCreateOjectsCurrentMasterPage.is() ) + if( mpSVGExport->IsEmbedFonts() && mpSVGExport->IsUsePositionedCharacters() ) { - OSL_FAIL( "error: !mCreateOjectsCurrentMasterPage.is()" ); - return 0; - } - sal_Bool bHasCharSetMap = !( mTextFieldCharSets.find( mCreateOjectsCurrentMasterPage ) == mTextFieldCharSets.end() ); + // to notify to the SVGActionWriter::ImplWriteText method + // that we are dealing with a placeholder shape + aRepresentation = sPlaceholderTag; - static const ::rtl::OUString aHeaderId( B2UCONST( aOOOAttrHeaderField ) ); - static const ::rtl::OUString aFooterId( B2UCONST( aOOOAttrFooterField ) ); - static const ::rtl::OUString aDateTimeId( B2UCONST( aOOOAttrDateTimeField ) ); - static const ::rtl::OUString aVariableDateTimeId( B2UCONST( aOOOAttrDateTimeField ) + B2UCONST( "-variable" ) ); + if( !mCreateOjectsCurrentMasterPage.is() ) + { + OSL_FAIL( "error: !mCreateOjectsCurrentMasterPage.is()" ); + return 0; + } + sal_Bool bHasCharSetMap = !( mTextFieldCharSets.find( mCreateOjectsCurrentMasterPage ) == mTextFieldCharSets.end() ); - const UCharSet * pCharSet = NULL; - UCharSetMap * pCharSetMap = NULL; - if( bHasCharSetMap ) - { - pCharSetMap = &( mTextFieldCharSets[ mCreateOjectsCurrentMasterPage ] ); - } - const SvxFieldData* pField = pInfo->GetField().GetField(); - if( bHasCharSetMap && ( pField->GetClassId() == text::textfield::Type::PRESENTATION_HEADER ) && ( pCharSetMap->find( aHeaderId ) != pCharSetMap->end() ) ) - { - pCharSet = &( (*pCharSetMap)[ aHeaderId ] ); - } - else if( bHasCharSetMap && ( pField->GetClassId() == text::textfield::Type::PRESENTATION_FOOTER ) && ( pCharSetMap->find( aFooterId ) != pCharSetMap->end() ) ) - { - pCharSet = &( (*pCharSetMap)[ aFooterId ] ); - } - else if( pField->GetClassId() == text::textfield::Type::PRESENTATION_DATE_TIME ) - { - if( bHasCharSetMap && ( pCharSetMap->find( aDateTimeId ) != pCharSetMap->end() ) ) + static const ::rtl::OUString aHeaderId( B2UCONST( aOOOAttrHeaderField ) ); + static const ::rtl::OUString aFooterId( B2UCONST( aOOOAttrFooterField ) ); + static const ::rtl::OUString aDateTimeId( B2UCONST( aOOOAttrDateTimeField ) ); + static const ::rtl::OUString aVariableDateTimeId( B2UCONST( aOOOAttrDateTimeField ) + B2UCONST( "-variable" ) ); + + const UCharSet * pCharSet = NULL; + UCharSetMap * pCharSetMap = NULL; + if( bHasCharSetMap ) + { + pCharSetMap = &( mTextFieldCharSets[ mCreateOjectsCurrentMasterPage ] ); + } + const SvxFieldData* pField = pInfo->GetField().GetField(); + if( bHasCharSetMap && ( pField->GetClassId() == text::textfield::Type::PRESENTATION_HEADER ) && ( pCharSetMap->find( aHeaderId ) != pCharSetMap->end() ) ) + { + pCharSet = &( (*pCharSetMap)[ aHeaderId ] ); + } + else if( bHasCharSetMap && ( pField->GetClassId() == text::textfield::Type::PRESENTATION_FOOTER ) && ( pCharSetMap->find( aFooterId ) != pCharSetMap->end() ) ) { - pCharSet = &( (*pCharSetMap)[ aDateTimeId ] ); + pCharSet = &( (*pCharSetMap)[ aFooterId ] ); } - if( bHasCharSetMap && ( pCharSetMap->find( aVariableDateTimeId ) != pCharSetMap->end() ) && !(*pCharSetMap)[ aVariableDateTimeId ].empty() ) + else if( pField->GetClassId() == text::textfield::Type::PRESENTATION_DATE_TIME ) { - SvxDateFormat eDateFormat = SVXDATEFORMAT_B, eCurDateFormat; - const UCharSet & aCharSet = (*pCharSetMap)[ aVariableDateTimeId ]; - UCharSet::const_iterator aChar = aCharSet.begin(); - // we look for the most verbose date format - for( ; aChar != aCharSet.end(); ++aChar ) + if( bHasCharSetMap && ( pCharSetMap->find( aDateTimeId ) != pCharSetMap->end() ) ) { - eCurDateFormat = (SvxDateFormat)( (int)( *aChar ) & 0x0f ); - switch( eDateFormat ) + pCharSet = &( (*pCharSetMap)[ aDateTimeId ] ); + } + if( bHasCharSetMap && ( pCharSetMap->find( aVariableDateTimeId ) != pCharSetMap->end() ) && !(*pCharSetMap)[ aVariableDateTimeId ].empty() ) + { + SvxDateFormat eDateFormat = SVXDATEFORMAT_B, eCurDateFormat; + const UCharSet & aCharSet = (*pCharSetMap)[ aVariableDateTimeId ]; + UCharSet::const_iterator aChar = aCharSet.begin(); + // we look for the most verbose date format + for( ; aChar != aCharSet.end(); ++aChar ) { - case SVXDATEFORMAT_STDSMALL: ; - case SVXDATEFORMAT_A: ; // 13.02.96 - case SVXDATEFORMAT_B: // 13.02.1996 - switch( eCurDateFormat ) - { - case SVXDATEFORMAT_C: ; // 13.Feb 1996 - case SVXDATEFORMAT_D: // 13.February 1996 - case SVXDATEFORMAT_E: ; // Tue, 13.February 1996 - case SVXDATEFORMAT_STDBIG: ; - case SVXDATEFORMAT_F: // Tuesday, 13.February 1996 - eDateFormat = eCurDateFormat; - break; - default: - break; - } - case SVXDATEFORMAT_C: ; // 13.Feb 1996 - case SVXDATEFORMAT_D: // 13.February 1996 - switch( eCurDateFormat ) - { - case SVXDATEFORMAT_E: ; // Tue, 13.February 1996 - case SVXDATEFORMAT_STDBIG: ; - case SVXDATEFORMAT_F: // Tuesday, 13.February 1996 - eDateFormat = eCurDateFormat; - break; - default: - break; - } - break; - default: - break; + eCurDateFormat = (SvxDateFormat)( (int)( *aChar ) & 0x0f ); + switch( eDateFormat ) + { + case SVXDATEFORMAT_STDSMALL: ; + case SVXDATEFORMAT_A: ; // 13.02.96 + case SVXDATEFORMAT_B: // 13.02.1996 + switch( eCurDateFormat ) + { + case SVXDATEFORMAT_C: ; // 13.Feb 1996 + case SVXDATEFORMAT_D: // 13.February 1996 + case SVXDATEFORMAT_E: ; // Tue, 13.February 1996 + case SVXDATEFORMAT_STDBIG: ; + case SVXDATEFORMAT_F: // Tuesday, 13.February 1996 + eDateFormat = eCurDateFormat; + break; + default: + break; + } + case SVXDATEFORMAT_C: ; // 13.Feb 1996 + case SVXDATEFORMAT_D: // 13.February 1996 + switch( eCurDateFormat ) + { + case SVXDATEFORMAT_E: ; // Tue, 13.February 1996 + case SVXDATEFORMAT_STDBIG: ; + case SVXDATEFORMAT_F: // Tuesday, 13.February 1996 + eDateFormat = eCurDateFormat; + break; + default: + break; + } + break; + default: + break; + } } - } - // Independently of the date format, we always put all these characters by default. - // They should be enough to cover every time format. - aRepresentation += B2UCONST( "0123456789.:/-APM" ); + // Independently of the date format, we always put all these characters by default. + // They should be enough to cover every time format. + aRepresentation += B2UCONST( "0123456789.:/-APM" ); - if( eDateFormat ) - { - String sDate; - LanguageType eLang = pInfo->GetOutliner()->GetLanguage( pInfo->GetPara(), pInfo->GetPos() ); - SvNumberFormatter * pNumberFormatter = new SvNumberFormatter( ::comphelper::getProcessServiceFactory(), LANGUAGE_SYSTEM ); - // We always collect the characters obtained by using the SVXDATEFORMAT_B (as: 13.02.1996) - // so we are sure to include any unusual day|month|year separator. - Date aDate( 1, 1, 1996 ); - sDate += SvxDateField::GetFormatted( aDate, SVXDATEFORMAT_B, *pNumberFormatter, eLang ); - switch( eDateFormat ) + if( eDateFormat ) { - case SVXDATEFORMAT_E: ; // Tue, 13.February 1996 - case SVXDATEFORMAT_STDBIG: ; - case SVXDATEFORMAT_F: // Tuesday, 13.February 1996 - for( sal_uInt16 i = 1; i <= 7; ++i ) // we get all days in a week - { - aDate.SetDay( i ); - sDate += SvxDateField::GetFormatted( aDate, eDateFormat, *pNumberFormatter, eLang ); - } - // No break here! We need months too! - case SVXDATEFORMAT_C: ; // 13.Feb 1996 - case SVXDATEFORMAT_D: // 13.February 1996 - for( sal_uInt16 i = 1; i <= 12; ++i ) // we get all months in a year - { - aDate.SetMonth( i ); - sDate += SvxDateField::GetFormatted( aDate, eDateFormat, *pNumberFormatter, eLang ); - } - break; - case SVXDATEFORMAT_STDSMALL: ; - case SVXDATEFORMAT_A: ; // 13.02.96 - case SVXDATEFORMAT_B: ; // 13.02.1996 - default: - // nothing to do here, we always collect the characters needed for these cases. - break; + String sDate; + LanguageType eLang = pInfo->GetOutliner()->GetLanguage( pInfo->GetPara(), pInfo->GetPos() ); + SvNumberFormatter * pNumberFormatter = new SvNumberFormatter( ::comphelper::getProcessServiceFactory(), LANGUAGE_SYSTEM ); + // We always collect the characters obtained by using the SVXDATEFORMAT_B (as: 13.02.1996) + // so we are sure to include any unusual day|month|year separator. + Date aDate( 1, 1, 1996 ); + sDate += SvxDateField::GetFormatted( aDate, SVXDATEFORMAT_B, *pNumberFormatter, eLang ); + switch( eDateFormat ) + { + case SVXDATEFORMAT_E: ; // Tue, 13.February 1996 + case SVXDATEFORMAT_STDBIG: ; + case SVXDATEFORMAT_F: // Tuesday, 13.February 1996 + for( sal_uInt16 i = 1; i <= 7; ++i ) // we get all days in a week + { + aDate.SetDay( i ); + sDate += SvxDateField::GetFormatted( aDate, eDateFormat, *pNumberFormatter, eLang ); + } + // No break here! We need months too! + case SVXDATEFORMAT_C: ; // 13.Feb 1996 + case SVXDATEFORMAT_D: // 13.February 1996 + for( sal_uInt16 i = 1; i <= 12; ++i ) // we get all months in a year + { + aDate.SetMonth( i ); + sDate += SvxDateField::GetFormatted( aDate, eDateFormat, *pNumberFormatter, eLang ); + } + break; + case SVXDATEFORMAT_STDSMALL: ; + case SVXDATEFORMAT_A: ; // 13.02.96 + case SVXDATEFORMAT_B: ; // 13.02.1996 + default: + // nothing to do here, we always collect the characters needed for these cases. + break; + } + aRepresentation += sDate; } - aRepresentation += sDate; } } - } - else if( pField->GetClassId() == text::textfield::Type::PAGE ) - { - switch( mVisiblePagePropSet.nPageNumberingType ) + else if( pField->GetClassId() == text::textfield::Type::PAGE ) { - case SVX_CHARS_UPPER_LETTER: - aRepresentation += B2UCONST( "QWERTYUIOPASDFGHJKLZXCVBNM" ); - break; - case SVX_CHARS_LOWER_LETTER: - aRepresentation += B2UCONST( "qwertyuiopasdfghjklzxcvbnm" ); - break; - case SVX_ROMAN_UPPER: - aRepresentation += B2UCONST( "IVXLCDM" ); - break; - case SVX_ROMAN_LOWER: - aRepresentation += B2UCONST( "ivxlcdm" ); - break; - // arabic numbering type is the default - case SVX_ARABIC: ; - // in case the numbering type is not handled we fall back on arabic numbering - default: - aRepresentation += B2UCONST( "0123456789" ); - break; + switch( mVisiblePagePropSet.nPageNumberingType ) + { + case SVX_CHARS_UPPER_LETTER: + aRepresentation += B2UCONST( "QWERTYUIOPASDFGHJKLZXCVBNM" ); + break; + case SVX_CHARS_LOWER_LETTER: + aRepresentation += B2UCONST( "qwertyuiopasdfghjklzxcvbnm" ); + break; + case SVX_ROMAN_UPPER: + aRepresentation += B2UCONST( "IVXLCDM" ); + break; + case SVX_ROMAN_LOWER: + aRepresentation += B2UCONST( "ivxlcdm" ); + break; + // arabic numbering type is the default + case SVX_ARABIC: ; + // in case the numbering type is not handled we fall back on arabic numbering + default: + aRepresentation += B2UCONST( "0123456789" ); + break; + } } - } - - if( pCharSet != NULL ) - { - UCharSet::const_iterator aChar = pCharSet->begin(); - for( ; aChar != pCharSet->end(); ++aChar ) + else { - aRepresentation += OUString::valueOf( *aChar ); + bFieldProcessed = sal_False; } + if( bFieldProcessed ) + { + if( pCharSet != NULL ) + { + UCharSet::const_iterator aChar = pCharSet->begin(); + for( ; aChar != pCharSet->end(); ++aChar ) + { + aRepresentation += OUString::valueOf( *aChar ); + } + } + pInfo->SetRepresentation( aRepresentation ); + } + } + else + { + bFieldProcessed = sal_False; } - pInfo->SetRepresentation( aRepresentation ); } else // single page case { @@ -2226,8 +2244,16 @@ IMPL_LINK( SVGFilter, CalcFieldHdl, EditFieldInfo*, pInfo ) break; } } + else + { + bFieldProcessed = sal_False; + } + if( bFieldProcessed ) + { + pInfo->SetRepresentation( aRepresentation ); + } } - pInfo->SetRepresentation( aRepresentation ); + } } return ( bFieldProcessed ? 0 : maOldFieldHdl.Call( pInfo ) ); diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index 4880161338b9..ca3f5393c7cb 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -457,6 +457,7 @@ SVGTextWriter::SVGTextWriter( SVGExport& rExport, SVGFontExport& rFontExport ) mpVDev( NULL ), mrTextShape(), mrParagraphEnumeration(), + mrCurrentTextParagraph(), mrTextPortionEnumeration(), mrCurrentTextPortion(), mpTextEmbeddedBitmapMtf( NULL ), @@ -468,7 +469,7 @@ SVGTextWriter::SVGTextWriter( SVGExport& rExport, SVGFontExport& rFontExport ) maTextPos(0,0), mnTextWidth(0), mbPositioningNeeded( sal_False ), - mbIsNumbering( sal_False ), + mbIsNewListItem( sal_False ), maBulletListItemMap(), mbIsListLevelStyleImage( sal_False ), mbLineBreak( sal_False ), @@ -575,6 +576,17 @@ sal_Bool SVGTextWriter::implGetTextPosition<MetaTextRectAction>( const MetaActio // ----------------------------------------------------------------------------- +template<> +sal_Bool SVGTextWriter::implGetTextPosition<MetaBmpExScaleAction>( const MetaAction* pAction, Point& raPos, sal_Bool& rbEmpty ) +{ + const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction; + raPos = pA->GetPoint(); + rbEmpty = sal_False; + return sal_True; +} + +// ----------------------------------------------------------------------------- + /** setTextPosition * Set the start position of the next line of text. In case no text is found * the current action index is updated to the index value we reached while @@ -628,6 +640,12 @@ sal_Int32 SVGTextWriter::setTextPosition( const GDIMetaFile& rMtf, sal_uLong& nC } break; + case( META_BMPEXSCALE_ACTION ): + { + bConfigured = implGetTextPosition<MetaBmpExScaleAction>( pAction, aPos, bEmpty ); + } + break; + // If we reach the end of the current line, paragraph or text shape // without finding any text we stop searching case( META_COMMENT_ACTION ): @@ -641,6 +659,37 @@ sal_Int32 SVGTextWriter::setTextPosition( const GDIMetaFile& rMtf, sal_uLong& nC else if( rsComment.equalsIgnoreAsciiCaseL( RTL_CONSTASCII_STRINGPARAM( "XTEXT_EOP" ) ) ) { bEOP = true; + + ::rtl::OUString sContent; + while( nextTextPortion() ) + { + sContent = mrCurrentTextPortion->getString(); + if( sContent.isEmpty() ) + { + continue; + } + else + { + if( sContent.equalsAscii( "\n" ) ) + mbLineBreak = sal_True; + } + } + if( nextParagraph() ) + { + while( nextTextPortion() ) + { + sContent = mrCurrentTextPortion->getString(); + if( sContent.isEmpty() ) + { + continue; + } + else + { + if( sContent.equalsAscii( "\n" ) ) + mbLineBreak = sal_True; + } + } + } } else if( rsComment.equalsIgnoreAsciiCaseL( RTL_CONSTASCII_STRINGPARAM( "XTEXT_PAINTSHAPE_END" ) ) ) { @@ -858,9 +907,37 @@ void SVGTextWriter::implSetFontFamily() // ----------------------------------------------------------------------------- +sal_Bool SVGTextWriter::createParagraphEnumeration() +{ + if( mrTextShape.is() ) + { + Reference< XEnumerationAccess > xEnumerationAccess( mrTextShape, UNO_QUERY_THROW ); + Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); + if( xEnumeration.is() ) + { + mrParagraphEnumeration.set( xEnumeration ); + return sal_True; + } + else + { + OSL_FAIL( "SVGTextWriter::createParagraphEnumeration: no valid xEnumeration interface found." ); + } + } + else + { + OSL_FAIL( "SVGTextWriter::createParagraphEnumeration: no valid XText interface found." ); + } + return sal_False; +} + +// ----------------------------------------------------------------------------- + sal_Bool SVGTextWriter::nextParagraph() { mrTextPortionEnumeration.clear(); + mrCurrentTextParagraph.clear(); + mbIsNewListItem = sal_False; + mbIsListLevelStyleImage = sal_False; if( mrParagraphEnumeration.is() && mrParagraphEnumeration->hasMoreElements() ) { Reference < XTextContent > xTextContent( mrParagraphEnumeration->nextElement(), UNO_QUERY_THROW ); @@ -872,16 +949,30 @@ sal_Bool SVGTextWriter::nextParagraph() OUString sInfo; if( xServiceInfo->supportsService( B2UCONST( "com.sun.star.text.Paragraph" ) ) ) { +// { +// Reference < XEnumeration> xContentEnum; +// Reference < XContentEnumerationAccess > xCEA( xTextContent, UNO_QUERY ); +// if( xCEA.is() ) +// xContentEnum.set(xCEA->createContentEnumeration( B2UCONST( "com.sun.star.text.Paragraph" ) )); +// const sal_Bool bHasContentEnum = xContentEnum.is() && +// xContentEnum->hasMoreElements(); +// +// if( bHasContentEnum ) +// { +// sInfo = B2UCONST( "true" ); +// mrExport.AddAttribute( XML_NAMESPACE_NONE, "has-content-enum", sInfo ); +// } +// } + + mrCurrentTextParagraph.set( xTextContent ); Reference< XPropertySet > xPropSet( xTextContent, UNO_QUERY_THROW ); Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); - mbIsNumbering = sal_False; - mbIsListLevelStyleImage = sal_False; if( xPropSetInfo->hasPropertyByName( B2UCONST( "NumberingLevel" ) ) ) { sal_Int16 nListLevel = 0; if( xPropSet->getPropertyValue( B2UCONST( "NumberingLevel" ) ) >>= nListLevel ) { - mbIsNumbering = sal_True; + mbIsNewListItem = sal_True; sInfo = B2UCONST( "NumberingLevel: " ); sInfo += OUString::valueOf( (sal_Int32)nListLevel ); mrExport.AddAttribute( XML_NAMESPACE_NONE, "style", sInfo ); @@ -893,46 +984,66 @@ sal_Bool SVGTextWriter::nextParagraph() } if( xNumRules.is() && ( nListLevel < xNumRules->getCount() ) ) { - Sequence<PropertyValue> aProps; - if( xNumRules->getByIndex( nListLevel ) >>= aProps ) + sal_Bool bIsNumbered = sal_True; + OUString msNumberingIsNumber(RTL_CONSTASCII_USTRINGPARAM("NumberingIsNumber")); + if( xPropSetInfo->hasPropertyByName( msNumberingIsNumber ) ) { - sal_Int16 eType = NumberingType::CHAR_SPECIAL; - sal_Unicode cBullet = 0xf095; - const sal_Int32 nCount = aProps.getLength(); - const PropertyValue* pPropArray = aProps.getConstArray(); - for( sal_Int32 i = 0; i < nCount; ++i ) + if( !(xPropSet->getPropertyValue( msNumberingIsNumber ) >>= bIsNumbered ) ) { - const PropertyValue& rProp = pPropArray[i]; - if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_NUMBERINGTYPE, sizeof(XML_UNO_NAME_NRULE_NUMBERINGTYPE)-1 ) ) - { - rProp.Value >>= eType; - } - else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_CHAR, sizeof(XML_UNO_NAME_NRULE_BULLET_CHAR)-1 ) ) + OSL_FAIL( "numbered paragraph without number info" ); + bIsNumbered = sal_False; + } + if( bIsNumbered ) + { + sInfo = B2UCONST( "true" ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, "is-numbered", sInfo ); + } + } + mbIsNewListItem = bIsNumbered; + + if( bIsNumbered ) + { + Sequence<PropertyValue> aProps; + if( xNumRules->getByIndex( nListLevel ) >>= aProps ) + { + sal_Int16 eType = NumberingType::CHAR_SPECIAL; + sal_Unicode cBullet = 0xf095; + const sal_Int32 nCount = aProps.getLength(); + const PropertyValue* pPropArray = aProps.getConstArray(); + for( sal_Int32 i = 0; i < nCount; ++i ) { - OUString sValue; - rProp.Value >>= sValue; - if( !sValue.isEmpty() ) + const PropertyValue& rProp = pPropArray[i]; + if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_NUMBERINGTYPE, sizeof(XML_UNO_NAME_NRULE_NUMBERINGTYPE)-1 ) ) { - cBullet = (sal_Unicode)sValue[0]; + rProp.Value >>= eType; + } + else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_CHAR, sizeof(XML_UNO_NAME_NRULE_BULLET_CHAR)-1 ) ) + { + OUString sValue; + rProp.Value >>= sValue; + if( !sValue.isEmpty() ) + { + cBullet = (sal_Unicode)sValue[0]; + } } } - } - meNumberingType = eType; - mbIsListLevelStyleImage = ( NumberingType::BITMAP == meNumberingType ); - if( NumberingType::CHAR_SPECIAL == meNumberingType ) - { - if( cBullet ) + meNumberingType = eType; + mbIsListLevelStyleImage = ( NumberingType::BITMAP == meNumberingType ); + if( NumberingType::CHAR_SPECIAL == meNumberingType ) { - if( cBullet < ' ' ) + if( cBullet ) { - cBullet = 0xF000 + 149; + if( cBullet < ' ' ) + { + cBullet = 0xF000 + 149; + } + mcBulletChar = cBullet; + // text:bullet-char="..." + sInfo = OUString::valueOf( (sal_Int32) cBullet ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, "bullet-char", sInfo ); } - mcBulletChar = cBullet; - // text:bullet-char="..." - sInfo = OUString::valueOf( (sal_Int32) cBullet ); - mrExport.AddAttribute( XML_NAMESPACE_NONE, "bullet-char", sInfo ); - } + } } } } @@ -960,6 +1071,11 @@ sal_Bool SVGTextWriter::nextParagraph() mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", sInfo ); SvXMLElementExport aParaElem( mrExport, XML_NAMESPACE_NONE, "desc", mbIWS, mbIWS ); } + else + { + OSL_FAIL( "SVGTextWriter::nextParagraph: no XServiceInfo interface available for text content." ); + return sal_False; + } Reference< XInterface > xRef( xTextContent, UNO_QUERY ); const OUString& rParagraphId = implGetValidIDFromInterface( xRef ); @@ -979,6 +1095,7 @@ sal_Bool SVGTextWriter::nextTextPortion() { mrCurrentTextPortion.clear(); mbIsURLField = sal_False; + mbIsPlacehlolderShape = sal_False; if( mrTextPortionEnumeration.is() && mrTextPortionEnumeration->hasMoreElements() ) { OUString sInfo; @@ -1010,8 +1127,11 @@ sal_Bool SVGTextWriter::nextTextPortion() if( xTextField.is() ) { const ::rtl::OUString sServicePrefix( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.textfield.") ); + const ::rtl::OUString sPresentationServicePrefix( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.TextField.") ); + Reference< XServiceInfo > xService( xTextField, UNO_QUERY ); const Sequence< OUString > aServices = xService->getSupportedServiceNames(); + const OUString* pNames = aServices.getConstArray(); sal_Int32 nCount = aServices.getLength(); @@ -1026,6 +1146,12 @@ sal_Bool SVGTextWriter::nextTextPortion() sFieldName = pNames->copy( sServicePrefix.getLength() ); break; } + else if( 0 == pNames->compareTo( sPresentationServicePrefix, sPresentationServicePrefix.getLength() ) ) + { + // TextField found => postfix is field type! + sFieldName = pNames->copy( sPresentationServicePrefix.getLength() ); + break; + } ++pNames; } @@ -1034,29 +1160,38 @@ sal_Bool SVGTextWriter::nextTextPortion() sInfo += sFieldName; sInfo += B2UCONST( "; " ); - mbIsURLField = sFieldName.equalsAscii( "URL" ); - if( mbIsURLField ) + if( sFieldName.equalsAscii( "DateTime" ) || sFieldName.equalsAscii( "Header" ) + || sFieldName.equalsAscii( "Footer" ) || sFieldName.equalsAscii( "PageNumber" ) ) { - Reference<XPropertySet> xTextFieldPropSet(xTextField, UNO_QUERY); - if( xTextFieldPropSet.is() ) + mbIsPlacehlolderShape = sal_True; + } + else + { + mbIsURLField = sFieldName.equalsAscii( "URL" ); + + if( mbIsURLField ) { - OUString sURL; - if( ( xTextFieldPropSet->getPropertyValue( sFieldName ) ) >>= sURL ) + Reference<XPropertySet> xTextFieldPropSet(xTextField, UNO_QUERY); + if( xTextFieldPropSet.is() ) { - sInfo += B2UCONST( "url: " ); - sInfo += mrExport.GetRelativeReference( sURL ); - - msUrl = mrExport.GetRelativeReference( sURL ); - if( !msUrl.isEmpty() ) + OUString sURL; + if( ( xTextFieldPropSet->getPropertyValue( sFieldName ) ) >>= sURL ) { - implRegisterInterface( xPortionTextRange ); + sInfo += B2UCONST( "url: " ); + sInfo += mrExport.GetRelativeReference( sURL ); - Reference< XInterface > xRef( xPortionTextRange, UNO_QUERY ); - const OUString& rTextPortionId = implGetValidIDFromInterface( xRef ); - if( !rTextPortionId.isEmpty() ) + msUrl = mrExport.GetRelativeReference( sURL ); + if( !msUrl.isEmpty() ) { - msHyperlinkIdList += rTextPortionId; - msHyperlinkIdList += B2UCONST( " " ); + implRegisterInterface( xPortionTextRange ); + + Reference< XInterface > xRef( xPortionTextRange, UNO_QUERY ); + const OUString& rTextPortionId = implGetValidIDFromInterface( xRef ); + if( !rTextPortionId.isEmpty() ) + { + msHyperlinkIdList += rTextPortionId; + msHyperlinkIdList += B2UCONST( " " ); + } } } } @@ -1078,21 +1213,11 @@ sal_Bool SVGTextWriter::nextTextPortion() void SVGTextWriter::startTextShape() { - if( mrTextShape.is() ) - { - Reference< XEnumerationAccess > xEnumerationAccess( mrTextShape, UNO_QUERY_THROW ); - Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); - if( xEnumeration.is() && xEnumeration->hasMoreElements() ) - { - mrParagraphEnumeration.set( xEnumeration ); - } - } - if( mpTextShapeElem ) { OSL_FAIL( "SVGTextWriter::startTextShape: text shape already defined." ); } - else + { maParentFont = Font(); mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "TextShape" ) ); @@ -1110,6 +1235,8 @@ void SVGTextWriter::endTextShape() mrTextShape.clear(); if( mrParagraphEnumeration.is() ) mrParagraphEnumeration.clear(); + if( mrCurrentTextParagraph.is() ) + mrCurrentTextParagraph.clear(); if( mpTextShapeElem ) { delete mpTextShapeElem; @@ -1128,7 +1255,7 @@ void SVGTextWriter::startTextParagraph() { endTextParagraph(); nextParagraph(); - if( mbIsNumbering ) + if( mbIsNewListItem ) { OUString sNumberingType; switch( meNumberingType ) @@ -1163,8 +1290,9 @@ void SVGTextWriter::startTextParagraph() void SVGTextWriter::endTextParagraph() { + mrCurrentTextPortion.clear(); endTextPosition(); - mbIsNumbering = sal_False; + mbIsNewListItem = sal_False; mbIsListLevelStyleImage = sal_False; mbPositioningNeeded = sal_False; @@ -1237,6 +1365,7 @@ void SVGTextWriter::implWriteBulletChars() sId += it->first; sId += B2UCONST( ")" ); mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", sId ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "BulletChar" ) ); SvXMLElementExport aBulletCharElem( mrExport, XML_NAMESPACE_NONE, aXMLElemG, sal_True, sal_True ); // <g transform="translate(x,y)" > @@ -1291,9 +1420,9 @@ void SVGTextWriter::writeBitmapPlaceholder( const MetaBmpExScaleAction* pAction implMap( rPos, maTextPos ); startTextPosition(); mbPositioningNeeded = sal_True; - if( mbIsNumbering ) + if( mbIsNewListItem ) { - mbIsNumbering = sal_False; + mbIsNewListItem = sal_False; mbIsListLevelStyleImage = sal_False; } @@ -1302,10 +1431,13 @@ void SVGTextWriter::writeBitmapPlaceholder( const MetaBmpExScaleAction* pAction OUString sId = B2UCONST( "bitmap-placeholder(" ); sId += OUString::valueOf( (sal_Int64)nId ); sId += B2UCONST( ")" ); - mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", sId ); - mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "BitmapPlaceholder" ) ); - SvXMLElementExport aSVGTspanElem( mrExport, XML_NAMESPACE_NONE, aXMLElemTspan, mbIWS, mbIWS ); + { + mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", sId ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "BitmapPlaceholder" ) ); + SvXMLElementExport aSVGTspanElem( mrExport, XML_NAMESPACE_NONE, aXMLElemTspan, mbIWS, mbIWS ); + } + endTextPosition(); } // ----------------------------------------------------------------------------- @@ -1334,6 +1466,7 @@ void SVGTextWriter::implWriteEmbeddedBitmaps() sId += OUString::valueOf( (sal_Int64)nId ); sId += B2UCONST( ")" ); mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", sId ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "EmbeddedBitmap" ) ); SvXMLElementExport aEmbBitmapElem( mrExport, XML_NAMESPACE_NONE, aXMLElemG, sal_True, sal_True ); @@ -1374,13 +1507,13 @@ void SVGTextWriter::writeTextPortion( const Point& rPos, mbLineBreak = sal_False; - if( !mbIsNumbering || mbIsListLevelStyleImage ) + if( !mbIsNewListItem || mbIsListLevelStyleImage ) { bool bNotSync = true; OUString sContent; sal_Int32 nStartPos; - do - { +// do +// { while( bNotSync ) { if( mnLeftTextPortionLength <= 0 ) @@ -1409,7 +1542,7 @@ void SVGTextWriter::writeTextPortion( const Point& rPos, if( sContent.match( rText, nStartPos ) ) bNotSync = false; } - } while( bNotSync && nextParagraph() ); +// } while( bNotSync && nextParagraph() ); } if( !mpVDev ) @@ -1552,29 +1685,30 @@ void SVGTextWriter::implWriteTextPortion( const Point& rPos, } } // we are dealing with a bullet, so set up this for the next text portion - if( mbIsNumbering ) + if( mbIsNewListItem ) { - mbIsNumbering = sal_False; + mbIsNewListItem = sal_False; mbPositioningNeeded = sal_True; if( meNumberingType == NumberingType::CHAR_SPECIAL ) { // Create an id for the current text portion - implRegisterInterface( mrCurrentTextPortion ); + implRegisterInterface( mrCurrentTextParagraph ); // Add the needed info to the BulletListItemMap - Reference< XInterface > xRef( mrCurrentTextPortion, UNO_QUERY ); - const OUString& rId = implGetValidIDFromInterface( xRef ); - if( !rId.isEmpty() ) + Reference< XInterface > xRef( mrCurrentTextParagraph, UNO_QUERY ); + OUString sId = implGetValidIDFromInterface( xRef ); + if( !sId.isEmpty() ) { - BulletListItemInfo& aBulletListItemInfo = maBulletListItemMap[ rId ]; + sId += ".bp"; + BulletListItemInfo& aBulletListItemInfo = maBulletListItemMap[ sId ]; aBulletListItemInfo.nFontSize = rFont.GetHeight(); aBulletListItemInfo.aColor = aTextColor; aBulletListItemInfo.aPos = maTextPos; aBulletListItemInfo.cBulletChar = mcBulletChar; // Make this text portion a bullet placeholder - mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", rId ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", sId ); mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "BulletPlaceholder" ) ); SvXMLElementExport aSVGTspanElem( mrExport, XML_NAMESPACE_NONE, aXMLElemTspan, mbIWS, mbIWS ); return; @@ -1589,9 +1723,15 @@ void SVGTextWriter::implWriteTextPortion( const Point& rPos, mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", rTextPortionId ); } - if( mbIsURLField && !msUrl.isEmpty() ) + if( mbIsPlacehlolderShape ) + { + mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "PlaceholderText" ) ); + mbIsPlacehlolderShape = sal_False; + } + else if( mbIsURLField && !msUrl.isEmpty() ) { mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrXLinkHRef, msUrl ); + mbIsURLField = sal_False; } @@ -1599,40 +1739,9 @@ void SVGTextWriter::implWriteTextPortion( const Point& rPos, mpContext->AddPaintAttr( COL_TRANSPARENT, aTextColor ); SvXMLElementExport aSVGTspanElem( mrExport, XML_NAMESPACE_NONE, aXMLElemTspan, mbIWS, mbIWS ); - - sal_Bool bIsPlaceholderField = sal_False; - - if( false && mbIsPlacehlolderShape ) - { - OUString sTextContent = rText; - bIsPlaceholderField = sTextContent.match( sPlaceholderTag ); - // for a placeholder text field we export only one <text> svg element - if( bIsPlaceholderField ) - { - OUString sCleanTextContent; - static const sal_Int32 nFrom = sPlaceholderTag.getLength(); - if( sTextContent.getLength() > nFrom ) - { - sCleanTextContent = sTextContent.copy( nFrom ); - } - mrExport.AddAttribute( XML_NAMESPACE_NONE, "class", B2UCONST( "PlaceholderText" ) ); - mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX, ::rtl::OUString::valueOf( aPos.X() ) ); - mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY, ::rtl::OUString::valueOf( aPos.Y() ) ); - { - //SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, aXMLElemSpan, sal_True, sal_False ); - // At least for the single slide case we need really to export placeholder text - mrExport.GetDocHandler()->characters( sCleanTextContent ); - } - } - } - - if( !bIsPlaceholderField ) - { - OUString sTextContent = rText; - mrExport.GetDocHandler()->characters( sTextContent ); - mnTextWidth += mpVDev->GetTextWidth( sTextContent ); - } - + OUString sTextContent = rText; + mrExport.GetDocHandler()->characters( sTextContent ); + mnTextWidth += mpVDev->GetTextWidth( sTextContent ); } // ------------------- @@ -2648,11 +2757,9 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, } mbIsPlacehlolderShape = false; - maTextWriter.setPlaceholderShapeFlag( false ); if( ( pElementId != NULL ) && ( *pElementId == sPlaceholderTag ) ) { mbIsPlacehlolderShape = true; - maTextWriter.setPlaceholderShapeFlag( true ); // since we utilize pElementId in an improper way we reset it to NULL before to go on pElementId = NULL; } @@ -3118,29 +3225,31 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, { if( ( pA->GetComment().equalsIgnoreAsciiCaseL( RTL_CONSTASCII_STRINGPARAM( "XTEXT_PAINTSHAPE_BEGIN" ) ) ) ) { - // nTextFound == -1 => no text found - // nTextFound == 0 => no text found and end of text shape reached - // nTextFound == 1 => text found! - sal_Int32 nTextFound = -1; - while( ( nTextFound < 0 ) && ( nCurAction < nCount ) ) - { - nTextFound = maTextWriter.setTextPosition( rMtf, nCurAction ); - } - // We found some text in the current text shape. - if( nTextFound > 0 ) - { - maTextWriter.setTextProperties( rMtf, nCurAction ); - //ImplSetCorrectFontHeight(); - maTextWriter.startTextShape(); - } - // We reached the end of the current text shape - // without finding any text. So we need to go back - // by one action in order to handle the - // XTEXT_PAINTSHAPE_END action because on the next - // loop the nCurAction is incremented by one. - else + maTextWriter.createParagraphEnumeration(); { - --nCurAction; + // nTextFound == -1 => no text found + // nTextFound == 0 => no text found and end of text shape reached + // nTextFound == 1 => text found! + sal_Int32 nTextFound = -1; + while( ( nTextFound < 0 ) && ( nCurAction < nCount ) ) + { + nTextFound = maTextWriter.setTextPosition( rMtf, nCurAction ); + } + // We found some text in the current text shape. + if( nTextFound > 0 ) + { + maTextWriter.setTextProperties( rMtf, nCurAction ); + maTextWriter.startTextShape(); + } + // We reached the end of the current text shape + // without finding any text. So we need to go back + // by one action in order to handle the + // XTEXT_PAINTSHAPE_END action because on the next + // loop the nCurAction is incremented by one. + else + { + --nCurAction; + } } } else if( ( pA->GetComment().equalsIgnoreAsciiCaseL( RTL_CONSTASCII_STRINGPARAM( "XTEXT_PAINTSHAPE_END" ) ) ) ) @@ -3166,7 +3275,6 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, if( nTextFound > 0 ) { maTextWriter.setTextProperties( rMtf, nCurAction ); - //ImplSetCorrectFontHeight(); maTextWriter.startTextParagraph(); } // We reached the end of the current text shape @@ -3199,8 +3307,6 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, // paragraph. if( nTextFound > 0 ) { - //maTextWriter.setTextProperties( rMtf, nCurAction ); - //ImplSetCorrectFontHeight(); maTextWriter.startTextPosition(); } // We reached the end of the current paragraph diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx index 3a23f5fa52ad..125c5efe157c 100644 --- a/filter/source/svg/svgwriter.hxx +++ b/filter/source/svg/svgwriter.hxx @@ -46,6 +46,7 @@ #include <com/sun/star/uno/Reference.h> #include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> #include <com/sun/star/container/XEnumeration.hpp> #include <com/sun/star/container/XIndexReplace.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> @@ -68,6 +69,7 @@ #include <com/sun/star/text/XTextField.hpp> #include <com/sun/star/style/NumberingType.hpp> + // ----------------------------------------------------------------------------- using namespace ::com::sun::star::uno; @@ -204,6 +206,7 @@ class SVGTextWriter VirtualDevice* mpVDev; Reference<XText> mrTextShape; Reference<XEnumeration> mrParagraphEnumeration; + Reference<XTextContent> mrCurrentTextParagraph; Reference<XEnumeration> mrTextPortionEnumeration; Reference<XTextRange> mrCurrentTextPortion; const GDIMetaFile* mpTextEmbeddedBitmapMtf; @@ -215,7 +218,7 @@ class SVGTextWriter Point maTextPos; long int mnTextWidth; sal_Bool mbPositioningNeeded; - sal_Bool mbIsNumbering; + sal_Bool mbIsNewListItem; sal_Int16 meNumberingType; sal_Unicode mcBulletChar; BulletListItemInfoMap maBulletListItemMap; @@ -237,6 +240,7 @@ class SVGTextWriter void setTextProperties( const GDIMetaFile& rMtf, sal_uLong nCurAction ); void addFontAttributes( sal_Bool bIsTextContainer ); + sal_Bool createParagraphEnumeration(); sal_Bool nextParagraph(); sal_Bool nextTextPortion(); |