diff -r 000000000000 -r 88edb906c587 svgtopt/SVG/SVGImpl/src/SVGUseElementImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtopt/SVG/SVGImpl/src/SVGUseElementImpl.cpp Wed Nov 03 18:56:10 2010 +0200 @@ -0,0 +1,673 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: SVG Implementation source file + * +*/ + + +#if !defined(__E32BASE_H__) +#include +#endif + +#include "SVGUseElementImpl.h" +#include "SVGElementImpl.h" +#include "SVGDocumentImpl.h" + +#include "GfxAffineTransform.h" + +#include "SVGImageElementImpl.h" + +_LIT( XLINKHREF, "xlink:href" ); +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- + +CSvgUseElementImpl* CSvgUseElementImpl::NewL( const TUint8 aElemID, + CSvgDocumentImpl* aDoc ) + { + CSvgUseElementImpl* self = new ( ELeave ) CSvgUseElementImpl( aDoc ); + CleanupStack::PushL( self ); + self->ConstructL( aElemID ); + + CleanupStack::Pop(); + + return self; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- + +CSvgUseElementImpl* CSvgUseElementImpl::NewLC( const TUint8 aElemID, + CSvgDocumentImpl* aDoc ) + + { + CSvgUseElementImpl* self = new ( ELeave ) CSvgUseElementImpl( aDoc ); + CleanupStack::PushL( self ); + self->ConstructL( aElemID ); + + return self; + } + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgUseElementImpl::ConstructL( const TUint8 aElemID) + { + CSvgElementImpl::InitializeL( aElemID ); + + iSvgStyleProperties = new(ELeave) RPointerArray(KCSS_MAX_ATTR); + User::LeaveIfError( iSvgStyleProperties->Append( NULL ) ); + iSvgStyleProperties->Remove( 0 ); + iSvgTransformable = CSvgTransformableImpl::NewL(); + iSvgUriReferenceImpl = CSvgUriReferenceImpl::NewL(); + + #ifdef SVG_FLOAT_BUILD + iX = 0 ; + iY = 0 ; + #else + iX.operator = ( 0 ); + iY.operator = ( 0 ); + #endif + //iXSet = EFalse; + //iYSet = EFalse; + + iReqAttrFlag = KAtrXlinkhref; + } +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +CSvgUseElementImpl::~CSvgUseElementImpl() + { + + if ( iSvgUriReferenceImpl ) + { + delete iSvgUriReferenceImpl; + iSvgUriReferenceImpl = NULL; + } + + if ( iSvgStyleProperties ) + { + iSvgStyleProperties->Close(); + delete iSvgStyleProperties; + iSvgStyleProperties = NULL; + } + if ( iUseHRef ) + { + delete iUseHRef; + iUseHRef = NULL; + } + } + +// ******************************************************* +// From SVG DOM + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgUseElementImpl::X() + { + return iX; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgUseElementImpl::Y() + { + return iY; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgUseElementImpl::Width() + { + return iWidth; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TFloatFixPt CSvgUseElementImpl::Height() + { + return iHeight; + } + +// ******************************************************* +// SVG Implementation + + +// ******************************************************* +// From MXmlElement + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgUseElementImpl::SetAttributeL( const TDesC& aName, + const TDesC& aValue ) + { + + CSvgElementImpl::SetAttributeL(aName,aValue); + // Get the path from the xlink + _LIT( KXLink, "xlink:href" ); + if ( aName == KXLink ) + { + iReqAttrFlag = 0; + + // STEP 1 - Get the reference element + // If the first char is '#' then remove it + // This is possible if coming from cXML parser and not CVG Decoder + + TInt pos1 = aValue.Locate('/'); + + if ( pos1 != KErrNotFound) + { + if (iOwnerDocument) + { + _LIT( KMsg, "Non-local valid URI in element" ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetIsWarning( ETrue ); + } + } + + TInt pos = aValue.Locate( '#' ); + if ( pos != KErrNotFound && pos == 0 ) + { + TPtrC ptr( &aValue[1], aValue.Length() - 1); + + // Maintain one more class level member for JSR + // This member will contain the value starting with '#' + if ( iUseHRef ) + { + delete iUseHRef; + iUseHRef = NULL; + } + + iUseHRef = aValue.AllocL(); + + if ( this->SetXlinkAttributeL( aName, ptr ) ) + { + ireferenceEl = NULL; + if ( iOwnerDocument ) + { + ireferenceEl = (CSvgElementImpl*)((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( ptr ); + + if ( ireferenceEl && ireferenceEl->ElemID() == KSvgUseElement) + { + ((CSvgUseElementImpl*)ireferenceEl)->iUseElementThatUsesThisUse = this; + + if ( ((CSvgUseElementImpl*)ireferenceEl)->iUseElementThatUsesThisUse == iUseElementThatUsesThisUse ) + { + //then there are use elements in recursion + // Set error in document + _LIT( KMsg, "URI in causes recursion loop with another : " ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetIsWarning( EFalse ); + + //get rid of the loop by removing this one + ireferenceEl = NULL; + } + } + + + } + if(ireferenceEl == NULL) + { + // Set error in document + if ( iOwnerDocument && ((CSvgDocumentImpl*)iOwnerDocument)->iFinishedParsing ) + { + _LIT( KMsg, "Invalid URI in element: " ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue ); + } + return KErrReferencedElementNotFound; // failure in finding the referenced element + } + } + } + else if ( pos > 0 && iOwnerDocument && ((CSvgDocumentImpl*)iOwnerDocument)->iFinishedParsing ) + { + // Set error in document + _LIT( KMsg, "Non-local valid URI in element: " ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue ); + } + else if( pos == KErrNotFound ) + { + + // Maintain one more class level member for JSR + // This member will contain the value starting with '#' + if ( iUseHRef ) + { + delete iUseHRef; + iUseHRef = NULL; + } + + iUseHRef = aValue.AllocL(); + TPtrC ptr( &aValue[0], aValue.Length()); + this->SetXlinkAttributeL( aName, ptr); + } + } + return KErrNone; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgUseElementImpl::SetAttributeDesL( const TInt aNameId, + const TDesC& aValue ) +{ + switch ( aNameId ) + { + case KAtrXlinkhref: + { + iReqAttrFlag = 0; + + // STEP 1 - Get the reference element + // If the first char is '#' then remove it + // This is possible if coming from cXML parser and not CVG Decoder + TInt pos1 = aValue.Locate('/'); + + if ( pos1 != KErrNotFound) + { + if (iOwnerDocument) + { + _LIT( KMsg, "Non-local valid URI in element" ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetIsWarning( ETrue ); + } + } + + + TInt pos = aValue.Locate( '#' ); + if ( pos != KErrNotFound && pos == 0 ) + { + + TPtrC ptr( &aValue[1], aValue.Length() - 1); + // Maintain one more class level member for JSR + // This member will contain the value starting with '#' + if ( iUseHRef ) + { + delete iUseHRef; + iUseHRef = NULL; + } + iUseHRef = aValue.AllocL(); + + if ( this->SetXlinkAttributeL( XLINKHREF, ptr ) ) + { + ireferenceEl = NULL; + if ( iOwnerDocument ) + { + ireferenceEl = (CSvgElementImpl*)((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( ptr ); + + if (ireferenceEl && ireferenceEl->ElemID() == KSvgUseElement) + { + ((CSvgUseElementImpl*)ireferenceEl)->iUseElementThatUsesThisUse = this; + + if ( ((CSvgUseElementImpl*)ireferenceEl)->iUseElementThatUsesThisUse == iUseElementThatUsesThisUse ) + { + //then there are use elements in recursion + _LIT( KMsg, "URI in causes recursion loop with another : " ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetIsWarning( EFalse ); + + //get rid of the loop by removing this one + ireferenceEl = NULL; + } + } + + } + if(ireferenceEl == NULL) + { + // Set error in document + if ( iOwnerDocument && ((CSvgDocumentImpl*)iOwnerDocument)->iFinishedParsing) + { + _LIT( KMsg, "Invalid URI in element: " ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue ); + } + return KErrReferencedElementNotFound; // failure in finding the referenced element + } + } + } + else if ( pos > 0 && iOwnerDocument && ((CSvgDocumentImpl*)iOwnerDocument)->iFinishedParsing ) + { + // Set error in document + _LIT( KMsg, "Non-local valid URI in element: " ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue ); + } + else if( pos == KErrNotFound ) + { + // Maintain one more class level member for JSR + // This member will contain the value starting with '#' + if ( iUseHRef ) + { + delete iUseHRef; + iUseHRef = NULL; + } + + iUseHRef = aValue.AllocL(); + + TPtrC ptr( &aValue[0], aValue.Length()); + this->SetXlinkAttributeL( XLINKHREF, ptr); + } + return KErrNone; + } + + default: + { + return CSvgElementImpl::SetAttributeDesL( aNameId, aValue ); + } + } + } + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgUseElementImpl::GetAttributeDes( const TInt aNameId, TPtrC16& aValue ) + { + + if ( aNameId == KAtrXlinkhref ) + { + // iUseHRef contains value starting with '#' + if ( iUseHRef ) + { + aValue.Set( *iUseHRef ); + return KErrNone; + } + + if ( iSvgUriReferenceImpl ) + { + aValue.Set( iSvgUriReferenceImpl->Href()); + return KErrNone; + } + + } + + return CSvgElementImpl::GetAttributeDes( aNameId, aValue ); + + } + + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgUseElementImpl::SetAttributeFloatL( const TInt aNameId, + const TFloatFixPt aValue ) + { + switch ( aNameId ) + { + case KAtrX: + iX = aValue; + //iXSet = ETrue; + break; + case KAtrY: + + iY = aValue; + //iYSet = ETrue; + break; + case KAtrWidth: + iWidth = aValue; + break; + + case KAtrHeight: + iHeight = aValue; + break; + default: + return CSvgElementImpl::SetAttributeFloatL( aNameId, aValue ); + } + return KErrNone; + } + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TInt CSvgUseElementImpl::GetAttributeFloat( const TInt aNameId, + TFloatFixPt& aValue ) + { + switch ( aNameId ) + { + case KAtrX: + aValue = iX ; + break; + case KAtrY: + + aValue = iY ; + break; + case KAtrWidth: + aValue = iWidth ; + break; + + case KAtrHeight: + aValue = iHeight ; + break; + default: + return CSvgElementImpl::GetAttributeFloat( aNameId, aValue ); + } + return KErrNone; + } + + +// ******************************************************* +// From MXmlElementOpt + +// ******************************************************* +// From CSvgElementImpl + +// perform a deep clone of this object +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +MXmlElement* CSvgUseElementImpl::CloneL(MXmlElement* aParentElement) + { + + CSvgUseElementImpl* newElement = CSvgUseElementImpl::NewL( this->ElemID(), + ((CSvgDocumentImpl*)iOwnerDocument) ); + CleanupStack::PushL(newElement); + + newElement->iParentNode = aParentElement; + // copy everything over + this->CopyL(newElement); +CleanupStack::Pop(); + return newElement; + } + +//--------------------------------------------------------------------------- +// perform a deep copy of this object +// +//--------------------------------------------------------------------------- +void CSvgUseElementImpl::CopyL( CSvgUseElementImpl* aDestElement ) + { + if(aDestElement) + { + // copy stuff from superclass + this->CSvgElementImpl::CopyL(aDestElement); + + // copy iRectangle items special to circle + aDestElement->iX = this->iX; + aDestElement->iY = this->iY; + aDestElement->iHeight = this->iHeight; + aDestElement->iWidth = this->iWidth; + + aDestElement->ireferenceEl = this->ireferenceEl; + aDestElement->iUseElementThatUsesThisUse = this->iUseElementThatUsesThisUse; + + // copy the reference to idoc (CSvgDocumentImpl) + aDestElement->iOwnerDocument = this->iOwnerDocument; + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +TBool CSvgUseElementImpl::DrawL( CGfx2dGc* /* aGc */, + CSvgElementImpl* /* aElement */ ) + { + return ETrue; + } + +// ******************************************************* +// Private + + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +CSvgUseElementImpl::CSvgUseElementImpl( CSvgDocumentImpl* aDoc ) + { + SetOwnerDocument(aDoc); + } + +/* +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgUseElementImpl::DeepClone( MXmlElement* aReferenceEl ) + { + CSvgElementImpl*aNewElement = ( CSvgElementImpl* ) + aReferenceEl->FirstChild(); + while ( aNewElement ) + { + DeepClone( aNewElement ); + aNewElement = ( CSvgElementImpl * ) aNewElement->NextSibling(); + } + } +*/ + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +void CSvgUseElementImpl::SetReferenceElementL() + { + if( ireferenceEl != NULL ) + { + CSvgElementImpl* theElement = (CSvgElementImpl *)ireferenceEl->CloneL((MXmlElement*)this); + CleanupStack::PushL(theElement); + this->CXmlElementImpl::AppendChildL(theElement); + CleanupStack::Pop(); + + //if reference element is a use element check for recursion loop + if (ireferenceEl->ElemID() == KSvgUseElement) + { + ((CSvgUseElementImpl*)ireferenceEl)->iUseElementThatUsesThisUse = this; + + if ( ireferenceEl == iUseElementThatUsesThisUse ) + { + //then there are use elements in recursion + _LIT( KMsg, "URI in causes recursion loop with another : " ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, Href() ); + ((CSvgDocumentImpl*)iOwnerDocument)->SetIsWarning( EFalse ); + + //get rid of the loop by removing this one + ireferenceEl = NULL; + } + } + } + } + + +CSvgElementImpl* CSvgUseElementImpl::GetReferenceElementL() +{ + return ireferenceEl; +} + +TInt CSvgUseElementImpl::SetRefElemById(const TDesC& aName) + { + ireferenceEl = ( CSvgElementImpl * ) + ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( aName ); + iReqAttrFlag = 0; + + return ( ireferenceEl == NULL ) ? KErrNotFound : KErrNone; + } + +void CSvgUseElementImpl::GetUnscaledBBox( TGfxRectangle2D& aBbox ) +{ + TGfxRectangle2D lReferenceBbox; + if (ireferenceEl != NULL) + { + ((CSvgElementImpl*)ireferenceEl)->GetUnscaledBBox(lReferenceBbox); + } + + // width and height + aBbox.iX = lReferenceBbox.iX + X(); + aBbox.iY = lReferenceBbox.iY + Y(); + aBbox.iWidth = lReferenceBbox.iWidth; + aBbox.iHeight = lReferenceBbox.iHeight; +} + +TBool CSvgUseElementImpl::IsViewable( ) +{ + if (ireferenceEl) + { + return ireferenceEl->IsViewable(); + } + + return EFalse; +} + +void CSvgUseElementImpl::GetBBox( TGfxRectangle2D& aBbox ) +{ + TGfxRectangle2D lReferenceBbox; + if (ireferenceEl) + { + ((CSvgElementImpl*)ireferenceEl)->GetBBox(lReferenceBbox); + } + + // width and height + aBbox.iX = lReferenceBbox.iX + X(); + aBbox.iY = lReferenceBbox.iY + Y(); + aBbox.iWidth = lReferenceBbox.iWidth; + aBbox.iHeight = lReferenceBbox.iHeight; + +} + +void CSvgUseElementImpl::Print( TBool aIsEncodeOn ) +{ + if (!aIsEncodeOn) + { + #ifdef _DEBUG + RDebug::Printf("", (int)iX, (int)iY, (int)iWidth, (int)iHeight/*, Href()*/); + #endif + } +} +// new function +void CSvgUseElementImpl::GetBoundingBox( TGfxRectangle2D& aBbox ) +{ + TGfxRectangle2D lReferenceBbox; + if (ireferenceEl != NULL) + { + TGfxAffineTransform lTempCTM = ((CSvgElementImpl*)ireferenceEl)->GetCTM(); + TGfxAffineTransform lElementCTM = ((CSvgElementImpl*)this)->GetCTM(); + MSvgTransformList* trList; + TGfxAffineTransform lElementTransform; + ((CSvgElementImpl*)ireferenceEl)->GetTransform( trList); + lElementTransform = trList->Consolidate( ((CSvgElementImpl*)ireferenceEl)->IsOverwriteTransforms() ); + lElementTransform.Concatenate(lElementCTM); + + ((CSvgElementImpl*)ireferenceEl)->SetCTM(lElementTransform); + //((CSvgElementImpl*)ireferenceEl)->GetBBox(lReferenceBbox); + ((CSvgElementImpl*)ireferenceEl)->GetUnscaledBBox(lReferenceBbox); + lReferenceBbox.GetBounds(lElementTransform, lReferenceBbox); + + ((CSvgElementImpl*)ireferenceEl)->SetCTM(lTempCTM); + } + // width and height + aBbox.iX = lReferenceBbox.iX + X(); + aBbox.iY = lReferenceBbox.iY + Y(); + aBbox.iWidth = lReferenceBbox.iWidth; + aBbox.iHeight = lReferenceBbox.iHeight; + +}