svgtopt/SVG/SVGImpl/src/SVGPathElementImpl.cpp
changeset 0 d46562c3d99d
equal deleted inserted replaced
-1:000000000000 0:d46562c3d99d
       
     1 /*
       
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  SVG Implementation source file
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #if !defined(__E32BASE_H__)
       
    20 #include <e32base.h>
       
    21 #endif
       
    22 
       
    23 #include "SVGPathElementImpl.h"
       
    24 #include "GfxGeneralPath.h"
       
    25 #include "SVGDocumentImpl.h"
       
    26 #include "SVGSchemaData.h"
       
    27 #include "SVGPathDataParser.h"
       
    28 
       
    29 _LIT( D, "d" );
       
    30 
       
    31 // ---------------------------------------------------------------------------
       
    32 //
       
    33 // ---------------------------------------------------------------------------
       
    34 
       
    35 CSvgPathElementImpl* CSvgPathElementImpl::NewL(  const TUint8 aElemID,
       
    36                                                 CSvgDocumentImpl* aDoc )
       
    37     {
       
    38     CSvgPathElementImpl*self    = new ( ELeave ) CSvgPathElementImpl( aDoc );
       
    39     CleanupStack::PushL( self );
       
    40     self->ConstructL( aElemID );
       
    41     CleanupStack::Pop();
       
    42 
       
    43     return self;
       
    44     }
       
    45 
       
    46 
       
    47 
       
    48 // ---------------------------------------------------------------------------
       
    49 //
       
    50 // ---------------------------------------------------------------------------
       
    51 CSvgPathElementImpl::~CSvgPathElementImpl()
       
    52     {
       
    53     if(iShape)
       
    54 		{
       
    55 		delete iShape;
       
    56 		iShape = NULL;
       
    57         }
       
    58 	if(iSvgStyleProperties)
       
    59 		{
       
    60 		iSvgStyleProperties->Close();
       
    61 		delete iSvgStyleProperties;
       
    62 		iSvgStyleProperties = NULL;
       
    63 		}
       
    64     }
       
    65 
       
    66 // *******************************************************
       
    67 // From MXmlElement
       
    68 
       
    69 
       
    70 // ---------------------------------------------------------------------------
       
    71 //
       
    72 // ---------------------------------------------------------------------------
       
    73 TInt CSvgPathElementImpl::SetAttributeL( const TDesC& aName,
       
    74                                          const TDesC& aValue )
       
    75     {
       
    76 
       
    77 
       
    78 	CSvgElementImpl::SetAttributeL(aName,aValue);
       
    79 
       
    80     if ( aName == D )
       
    81         {
       
    82         iReqAttrFlag = 0;
       
    83         TSvgPathDataParser::ParsePathData( aValue, iShape );
       
    84 
       
    85         // verify path starts with move command
       
    86         RArray<TUint32>* typeArray = iShape->PointTypeArray();
       
    87         if ( !typeArray || ( typeArray->Count() > 0 && (*typeArray)[0] != EGfxSegMoveTo ) )
       
    88             {
       
    89             if ( iOwnerDocument )
       
    90                 {
       
    91                 _LIT( msg1, "Missing 'move to segment' in <path>" );
       
    92                 _LIT(msg2, "");
       
    93                 ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, msg1, msg2 );
       
    94                 }
       
    95             }
       
    96         }
       
    97 
       
    98 	if (( ((CSvgElementImpl*)iParentNode) != NULL && ((CSvgElementImpl*)iParentNode)->ElemID() == KSvgGlyphElement ) && ( aName == D) )
       
    99 	    {
       
   100        ((CSvgElementImpl*)iParentNode)->SetAttributeL(aName,aValue);
       
   101 	    }
       
   102 
       
   103     return KErrNone;
       
   104     }
       
   105 
       
   106 // From MXmlElementOpt
       
   107 
       
   108 // ---------------------------------------------------------------------------
       
   109 //
       
   110 // ---------------------------------------------------------------------------
       
   111 TInt CSvgPathElementImpl::GetAttributeFloat( const TInt aNameId,
       
   112                                              TFloatFixPt& aValue )
       
   113     {
       
   114     switch ( aNameId )
       
   115         {
       
   116         case KAtrRefX:
       
   117         aValue = iShape->PointCoordsArray()[0];
       
   118         break;
       
   119         case KAtrRefY:
       
   120         aValue = iShape->PointCoordsArray()[1];
       
   121         break;
       
   122         default:
       
   123         return CSvgElementImpl::GetAttributeFloat( aNameId, aValue );
       
   124         }
       
   125     return KErrNone;
       
   126     }
       
   127 
       
   128 // ---------------------------------------------------------------------------
       
   129 //
       
   130 // ---------------------------------------------------------------------------
       
   131 TInt CSvgPathElementImpl::GetAttributePath( const TInt aNameId,
       
   132                                             CGfxGeneralPath*& aValue )
       
   133     {
       
   134     if ( aNameId == KAtrData )
       
   135         {
       
   136         aValue = iShape;
       
   137         }
       
   138     else
       
   139         {
       
   140         aValue = NULL;
       
   141         return KErrNoAttribute;
       
   142         }
       
   143 
       
   144     return KErrNone;
       
   145     }
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 //
       
   149 // ---------------------------------------------------------------------------
       
   150 TInt CSvgPathElementImpl::SetAttributePathL( const TInt aNameId,
       
   151                                              CGfxGeneralPath* aValue )
       
   152     {
       
   153     if ( aNameId == KAtrData )
       
   154         {
       
   155         // copy aValue into iShape not just reassign pointers - that will cause memory leak
       
   156         // copy when CGfxGeneralPath implements a copy method
       
   157         iShape->SetPointTypeArrayL( aValue->PointTypeArray() );
       
   158         iShape->SetPointCoordsArrayL( aValue->PointCoordsArrayAll() );
       
   159         if( WasTurnedOff() )
       
   160 			{
       
   161 			// turn it on. this means all the required attributes Are present and
       
   162 			// hence we can render it.
       
   163 			_LIT(KInline , "inline");
       
   164 			CSvgElementImpl::SetPropertyL(KCSS_ATTR_DISPLAY, KInline);
       
   165 			SetTurnOff( EFalse );
       
   166 			}
       
   167         
       
   168         }
       
   169     else
       
   170         {
       
   171         return KErrNoAttribute;
       
   172         }
       
   173 
       
   174     return KErrNone;
       
   175     }
       
   176 
       
   177 // ---------------------------------------------------------------------------
       
   178 //
       
   179 // ---------------------------------------------------------------------------
       
   180 TInt CSvgPathElementImpl::SetAttributePathRef( const TInt aNameId,
       
   181                                               CGfxGeneralPath*&  aValue  )
       
   182     {
       
   183     if ( aNameId == KAtrData )
       
   184         {
       
   185 
       
   186 	    if(iShape)
       
   187 			{
       
   188 			delete iShape;
       
   189 			iShape= NULL;
       
   190 			}
       
   191 		iShape= aValue;
       
   192 		
       
   193 		if (( ((CSvgElementImpl*)iParentNode) != NULL && ((CSvgElementImpl*)iParentNode)->ElemID() == KSvgGlyphElement ) && ( aNameId == KAtrD) )
       
   194 		    {
       
   195             ((CSvgElementImpl*)iParentNode)->SetPathAttribute(aNameId,aValue);
       
   196 		    }
       
   197 		
       
   198         }
       
   199     else
       
   200         {
       
   201         return KErrNoAttribute;
       
   202         }
       
   203 
       
   204     return KErrNone;
       
   205     }
       
   206 
       
   207 // ---------------------------------------------------------------------------
       
   208 //
       
   209 // ---------------------------------------------------------------------------
       
   210 TBool CSvgPathElementImpl::DrawL( CGfx2dGc* aGc, CSvgElementImpl* aElement )
       
   211     {
       
   212     this->DrawShapeL( aGc, *iShape, aElement );
       
   213     return ETrue;
       
   214     }
       
   215 
       
   216 // ---------------------------------------------------------------------------
       
   217 //
       
   218 // ---------------------------------------------------------------------------
       
   219 void CSvgPathElementImpl::ConstructL(  const TUint8 aElemID )
       
   220     {
       
   221     CSvgElementImpl::InitializeL( aElemID );
       
   222 
       
   223     iSvgStyleProperties = new(ELeave) RPointerArray<CCssValue>(KCSS_MAX_ATTR);
       
   224     User::LeaveIfError( iSvgStyleProperties->Append( NULL ) );
       
   225     iSvgStyleProperties->Remove( 0 );
       
   226     iSvgTransformable = CSvgTransformableImpl::NewL();
       
   227 
       
   228     iShape = CGfxGeneralPath::NewL();
       
   229 	iReqAttrFlag=KSVG_PATH_ELEMFLAG;
       
   230 
       
   231     }
       
   232 
       
   233 // ---------------------------------------------------------------------------
       
   234 //
       
   235 // ---------------------------------------------------------------------------
       
   236 CSvgPathElementImpl::CSvgPathElementImpl( CSvgDocumentImpl* aDoc )
       
   237     {
       
   238 	SetOwnerDocument(aDoc);
       
   239     }
       
   240 
       
   241 
       
   242 // ---------------------------------------------------------------------------
       
   243 //
       
   244 // ---------------------------------------------------------------------------
       
   245 void CSvgPathElementImpl::GetBBox( TGfxRectangle2D& aBbox )
       
   246     {
       
   247 
       
   248     if (!iShape || iShape->PointTypeArray()->Count() == 0)
       
   249     {
       
   250     	// The D attribute has not been set yet
       
   251     	return;
       
   252     }
       
   253 
       
   254     iShape->GetBounds( GetCTM(), aBbox );
       
   255     }
       
   256 
       
   257 // ---------------------------------------------------------------------------
       
   258 //
       
   259 // ---------------------------------------------------------------------------
       
   260 void CSvgPathElementImpl::GetUnscaledBBox( TGfxRectangle2D& aBbox )
       
   261     {
       
   262     	if (!iShape || iShape->PointTypeArray()->Count() == 0)
       
   263     	{
       
   264     	// The D attribute has not been set yet
       
   265     	return;
       
   266     	}
       
   267 
       
   268     TGfxAffineTransform identityTx;
       
   269     iShape->GetBounds( identityTx, aBbox );
       
   270     }
       
   271 
       
   272 // ---------------------------------------------------------------------------
       
   273 // perform a deep clone of this object
       
   274 // ---------------------------------------------------------------------------
       
   275 MXmlElement* CSvgPathElementImpl::CloneL(MXmlElement* aParentElement)
       
   276     {
       
   277     // create new polyline
       
   278 	CSvgPathElementImpl* newElement = CSvgPathElementImpl::NewL( this->ElemID(), ((CSvgDocumentImpl*)iOwnerDocument) );
       
   279 
       
   280 	CleanupStack::PushL(newElement);
       
   281 	newElement->iParentNode = aParentElement;
       
   282     // copy everything over
       
   283     this->CopyL(newElement);
       
   284 	CleanupStack::Pop();
       
   285     return newElement;
       
   286     }
       
   287 
       
   288 // ---------------------------------------------------------------------------
       
   289 // perform a deep copy of this object
       
   290 // ---------------------------------------------------------------------------
       
   291 void CSvgPathElementImpl::CopyL( CSvgPathElementImpl* aDestElement )
       
   292     {
       
   293     if(aDestElement)
       
   294 	    {
       
   295 	    // copy stuff from superclass
       
   296 	    this->CSvgElementImpl::CopyL(aDestElement);
       
   297 
       
   298 	    // copy iShape
       
   299         RArray<TUint32>* lTypes = this->iShape->PointTypeArray();
       
   300         RArray<TFloatFixPt>* lCoords = this->iShape->PointCoordsArrayAll();
       
   301         aDestElement->iShape->SetPointTypeArrayL(lTypes);
       
   302         aDestElement->iShape->SetPointCoordsArrayL(lCoords);
       
   303 
       
   304 	    // copy the reference to idoc (CSvgDocumentImpl)
       
   305 	    aDestElement->iOwnerDocument = this->iOwnerDocument;
       
   306 	    }
       
   307 
       
   308     }
       
   309 // ---------------------------------------------------------------------------
       
   310 //
       
   311 // ---------------------------------------------------------------------------
       
   312 CGfxGeneralPath* CSvgPathElementImpl::GetPathAttribute(TInt aAttributeId)
       
   313 {
       
   314 	if(aAttributeId == KAtrD)
       
   315 		{
       
   316 		return iShape;
       
   317 		}
       
   318 	return NULL;
       
   319 }
       
   320 // ---------------------------------------------------------------------------
       
   321 //
       
   322 // ---------------------------------------------------------------------------
       
   323 void CSvgPathElementImpl::SetPathAttribute(TInt aAttributeId, CGfxGeneralPath* aPathHandle)
       
   324 {
       
   325 	if(aAttributeId == KAtrD)
       
   326 		{
       
   327 		if(iShape != aPathHandle)
       
   328 			{
       
   329 			delete iShape;
       
   330 			iShape = aPathHandle;
       
   331 			}
       
   332 		}
       
   333 }
       
   334 
       
   335 void CSvgPathElementImpl::Print( TBool aIsEncodeOn )
       
   336 {
       
   337 	if (!aIsEncodeOn)
       
   338 	{
       
   339 	#ifdef _DEBUG
       
   340 	RArray<TUint32>* lTypes = this->iShape->PointTypeArray();
       
   341 	RArray<TFloatFixPt>* lCoords = this->iShape->PointCoordsArrayAll();
       
   342 
       
   343 	if (lTypes->Count() != lCoords->Count())
       
   344 	{
       
   345 		RDebug::Printf("Invalid path points and types didnt match", this);
       
   346 		return;
       
   347 	}
       
   348 
       
   349 	RDebug::Printf("<path d=\"", this);
       
   350 	
       
   351 	TInt lTypesCnt = lTypes->Count();
       
   352 	for (TInt i=0; i < lTypesCnt; i++)
       
   353 	{
       
   354 		RDebug::Printf("%c ", lTypes->operator[]( i ));
       
   355 		RDebug::Printf("%d ", (int)(lCoords->operator[]( i )));
       
   356 	}
       
   357 
       
   358 	RDebug::Printf(" z\">", this);
       
   359 
       
   360 	#endif
       
   361 	}
       
   362 }