svgtopt/SVG/SVGImpl/src/SVGFitToViewBoxImpl.cpp
changeset 46 88edb906c587
equal deleted inserted replaced
-1:000000000000 46:88edb906c587
       
     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 
       
    20 #include <e32base.h>
       
    21 
       
    22 #include "SVGFitToViewBoxImpl.h"
       
    23 #include "SVGSvgElementImpl.h"
       
    24 
       
    25 
       
    26 // ---------------------------------------------------------------------------
       
    27 //
       
    28 // ---------------------------------------------------------------------------
       
    29 CSvgFitToViewBoxImpl* CSvgFitToViewBoxImpl::NewL()
       
    30     {
       
    31     CSvgFitToViewBoxImpl* self = new ( ELeave ) CSvgFitToViewBoxImpl();
       
    32     CleanupStack::PushL( self );
       
    33     self->ConstructL();
       
    34     CleanupStack::Pop();
       
    35 
       
    36     return self;
       
    37     }
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 //
       
    41 // ---------------------------------------------------------------------------
       
    42 CSvgFitToViewBoxImpl* CSvgFitToViewBoxImpl::NewLC()
       
    43     {
       
    44     CSvgFitToViewBoxImpl* self = new ( ELeave ) CSvgFitToViewBoxImpl();
       
    45     CleanupStack::PushL( self );
       
    46     self->ConstructL();
       
    47 
       
    48     return self;
       
    49     }
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 // ---------------------------------------------------------------------------
       
    54 CSvgFitToViewBoxImpl::~CSvgFitToViewBoxImpl()
       
    55     {
       
    56     if ( iAspectRatio )
       
    57     {
       
    58         delete iAspectRatio;
       
    59         iAspectRatio = NULL;
       
    60 	}
       
    61 
       
    62     }
       
    63 
       
    64 // *******************************************************
       
    65 // From SVG DOM
       
    66 
       
    67 /// Returns (parameter 1):
       
    68 ///     preserveAspectio attribute value: if defined for this element
       
    69 ///     NULL: if not defined
       
    70 // ---------------------------------------------------------------------------
       
    71 //
       
    72 // ---------------------------------------------------------------------------
       
    73 void CSvgFitToViewBoxImpl::GetPreserveAspectRatio( MSvgPreserveAspectRatio*& aAspectRatio )
       
    74     {
       
    75     aAspectRatio = iAspectRatio;
       
    76     }
       
    77 
       
    78 /// Returns:
       
    79 ///     TRUE: If Viewbox defined
       
    80 ///     FALSE: If Viewbox is not defined
       
    81 ///     aViewBox: Element's viewbox (if defined).
       
    82 // ---------------------------------------------------------------------------
       
    83 //
       
    84 // ---------------------------------------------------------------------------
       
    85 TBool CSvgFitToViewBoxImpl::GetViewBox( TGfxRectangle2D& aViewBox )
       
    86     {
       
    87     aViewBox = iViewBox;
       
    88     return iViewBoxDefined;
       
    89     }
       
    90 
       
    91 // *******************************************************
       
    92 // SVG Implementation
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 // ---------------------------------------------------------------------------
       
    97 void CSvgFitToViewBoxImpl::SetPreserveAspectRatioL( TSvgPreserveAspectAlignType aAlign,
       
    98                                                     TSvgMeetOrSliceType aMeetSlice )
       
    99     {
       
   100     iAspectRatio->SetAlign( aAlign );
       
   101     iAspectRatio->SetMeetOrSlice( aMeetSlice );
       
   102     }
       
   103 
       
   104 // ---------------------------------------------------------------------------
       
   105 //
       
   106 // ---------------------------------------------------------------------------
       
   107 void CSvgFitToViewBoxImpl::SetViewBoxL( TGfxRectangle2D aViewBox )
       
   108     {
       
   109     iViewBox = aViewBox;
       
   110     iViewBoxDefined = ETrue;
       
   111     }
       
   112 
       
   113 // ---------------------------------------------------------------------------
       
   114 //
       
   115 // ---------------------------------------------------------------------------
       
   116 TBool CSvgFitToViewBoxImpl::ViewBoxDefined()
       
   117     {
       
   118     return iViewBoxDefined;
       
   119     }
       
   120 
       
   121 // ---------------------------------------------------------------------------
       
   122 //
       
   123 // ---------------------------------------------------------------------------
       
   124 TBool CSvgFitToViewBoxImpl::SetViewBoxL( const TDesC& aAttributeName,
       
   125                                         const TDesC& aValue )
       
   126     {
       
   127     // If this attribute is not viewBox attribute, return immediately.
       
   128     _LIT( KViewBox, "viewBox" );
       
   129     _LIT( KPreserveAspectRatio, "preserveAspectRatio" );
       
   130     _LIT( KNone, "none" );
       
   131     _LIT( KXMidYMid, "xMidYMid" );
       
   132     _LIT( KXMidYMin, "xMidYMin" );
       
   133     _LIT( KXMidYMax, "xMidYMax" );
       
   134     _LIT( KXMinYMin, "xMinYMin" );
       
   135     _LIT( KXMinYMid, "xMinYMid" );
       
   136     _LIT( KXMinYMax, "xMinYMax" );
       
   137     _LIT( KXMaxYMin, "xMaxYMin" );
       
   138     _LIT( KXMaxYMid, "xMaxYMid" );
       
   139     _LIT( KXMaxYMax, "xMaxYMax" );
       
   140 
       
   141     _LIT( KMeet, "meet" );
       
   142 	_LIT( KSlice, "slice" );
       
   143 
       
   144     TLex input( aValue );
       
   145 
       
   146     if ( aAttributeName == KViewBox )
       
   147         {
       
   148         TReal32 vBoxX=0;
       
   149         TReal32 vBoxY=0;
       
   150         TReal32 vBoxW=0;
       
   151         TReal32 vBoxH=0;
       
   152 
       
   153         input.SkipSpace();
       
   154         if (input.Val( vBoxX, '.' ) != KErrNone)
       
   155         	 return ETrue;
       
   156 
       
   157         if( input.Peek() == ',' )
       
   158         	input.Inc();
       
   159         input.SkipSpace();
       
   160         if( input.Peek() == ',' )
       
   161         	input.Inc();
       
   162 
       
   163         if (input.Val( vBoxY, '.' ) != KErrNone)
       
   164         	 return ETrue;
       
   165 
       
   166 
       
   167           if( input.Peek() == ',' )
       
   168         	input.Inc();
       
   169         input.SkipSpace();
       
   170         if( input.Peek() == ',' )
       
   171         	input.Inc();
       
   172 
       
   173         if (input.Val( vBoxW, '.' ) != KErrNone)
       
   174         	 return ETrue;
       
   175 
       
   176           if( input.Peek() == ',' )
       
   177         	input.Inc();
       
   178         input.SkipSpace();
       
   179         if( input.Peek() == ',' )
       
   180         	input.Inc();
       
   181 
       
   182         if (input.Val( vBoxH, '.' ) != KErrNone)
       
   183         	  return ETrue;
       
   184         //Error Checking
       
   185         if (vBoxW < 0)
       
   186             vBoxW = 0;
       
   187         if (vBoxH < 0)
       
   188             vBoxH = 0;
       
   189         
       
   190 
       
   191         
       
   192 
       
   193         TGfxRectangle2D tr = TGfxRectangle2D( vBoxX, vBoxY, vBoxW, vBoxH );
       
   194         this->SetViewBoxL( tr );
       
   195         return ETrue;
       
   196         }
       
   197     else if ( aAttributeName == KPreserveAspectRatio )
       
   198         {
       
   199 
       
   200         input.Mark();
       
   201         input.SkipCharacters();
       
   202         TChar test = input.Peek();
       
   203         TPtrC token = input.MarkedToken();    // then extract token
       
   204 
       
   205         if ( token == KNone )
       
   206             {
       
   207             this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_None,
       
   208                                            ESvgMeetOrSlice_Unknown );
       
   209             }
       
   210         else if ( token == KXMidYMid )
       
   211             {
       
   212 
       
   213             //check meet and slice parsing
       
   214             //AJD need to seperate SetPreserveAspectRatio calls too...
       
   215             TPtrC token = input.NextToken();
       
   216 
       
   217             if ( token == KMeet )
       
   218                 {
       
   219                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmid,
       
   220                                                ESvgMeetOrSlice_Meet );
       
   221                 }
       
   222             else if ( token == KSlice )
       
   223             	{
       
   224             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmid,
       
   225                                                ESvgMeetOrSlice_Slice );
       
   226             	}
       
   227             else {
       
   228             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmid,
       
   229                                                ESvgMeetOrSlice_Meet );
       
   230             	}
       
   231             }
       
   232         else if ( token == KXMidYMin )
       
   233             {
       
   234             TPtrC token = input.NextToken();    // then extract token
       
   235 
       
   236             if ( token == KMeet )
       
   237                 {
       
   238                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmin,
       
   239                                                ESvgMeetOrSlice_Meet );
       
   240                 }
       
   241             else if ( token == KSlice )
       
   242             	{
       
   243             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmin,
       
   244                                                ESvgMeetOrSlice_Slice );
       
   245             	}
       
   246             else {
       
   247             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmin,
       
   248                                                ESvgMeetOrSlice_Meet );
       
   249             	}
       
   250             }
       
   251         else if ( token == KXMidYMax )
       
   252             {
       
   253             TPtrC token = input.NextToken();    // then extract token
       
   254 
       
   255             if ( token == KMeet )
       
   256                 {
       
   257                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmax,
       
   258                                                ESvgMeetOrSlice_Meet );
       
   259                 }
       
   260             else if ( token == KSlice )
       
   261             	{
       
   262             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmax,
       
   263                                                ESvgMeetOrSlice_Slice );
       
   264             	}
       
   265             else {
       
   266             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmidYmax,
       
   267                                                ESvgMeetOrSlice_Meet );
       
   268             	}
       
   269             }
       
   270         else if ( token == KXMinYMin )
       
   271             {
       
   272             TPtrC token = input.NextToken();    // then extract token
       
   273             if ( token == KMeet )
       
   274                 {
       
   275                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmin,
       
   276                                                ESvgMeetOrSlice_Meet );
       
   277                 }
       
   278             else if ( token == KSlice )
       
   279             	{
       
   280             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmin,
       
   281                                                ESvgMeetOrSlice_Slice );
       
   282             	}
       
   283             else {
       
   284             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmin,
       
   285                                                ESvgMeetOrSlice_Meet );
       
   286             	}
       
   287             }
       
   288         else if ( token == KXMinYMid )
       
   289             {
       
   290             TPtrC token = input.NextToken();    // then extract token
       
   291             if ( token == KMeet )
       
   292                 {
       
   293                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmid,
       
   294                                                ESvgMeetOrSlice_Meet );
       
   295                 }
       
   296             else if ( token == KSlice )
       
   297             	{
       
   298             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmid,
       
   299                                                ESvgMeetOrSlice_Slice );
       
   300             	}
       
   301             else {
       
   302             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmid,
       
   303                                                ESvgMeetOrSlice_Meet );
       
   304             	}
       
   305             }
       
   306         else if ( token == KXMinYMax )
       
   307             {
       
   308             TPtrC token = input.NextToken();    // then extract token
       
   309             if ( token == KMeet )
       
   310                 {
       
   311                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmax,
       
   312                                                ESvgMeetOrSlice_Meet );
       
   313                 }
       
   314             else if ( token == KSlice )
       
   315             	{
       
   316             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmax,
       
   317                                                ESvgMeetOrSlice_Slice );
       
   318             	}
       
   319             else {
       
   320             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XminYmax,
       
   321                                                ESvgMeetOrSlice_Meet );
       
   322             	}
       
   323             }
       
   324         else if ( token == KXMaxYMin )
       
   325             {
       
   326             TPtrC token = input.NextToken();  // then extract token
       
   327             if ( token == KMeet )
       
   328                 {
       
   329                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmin,
       
   330                                                ESvgMeetOrSlice_Meet );
       
   331                 }
       
   332             else if ( token == KSlice )
       
   333             	{
       
   334             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmin,
       
   335                                                ESvgMeetOrSlice_Slice );
       
   336             	}
       
   337             else {
       
   338             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmin,
       
   339                                                ESvgMeetOrSlice_Meet );
       
   340             	}
       
   341             }
       
   342         else if ( token == KXMaxYMid )
       
   343             {
       
   344             TPtrC token = input.NextToken();    // then extract token
       
   345             if ( token == KMeet )
       
   346                 {
       
   347                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmid,
       
   348                                                ESvgMeetOrSlice_Meet );
       
   349                 }
       
   350             else if ( token == KSlice )
       
   351             	{
       
   352             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmid,
       
   353                                                ESvgMeetOrSlice_Slice );
       
   354             	}
       
   355             else {
       
   356             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmid,
       
   357                                                ESvgMeetOrSlice_Meet );
       
   358             	}
       
   359             }
       
   360         else if ( token == KXMaxYMax )
       
   361             {
       
   362             TPtrC token = input.NextToken();    // then extract token
       
   363             if ( token == KMeet )
       
   364                 {
       
   365                 this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmax,
       
   366                                                ESvgMeetOrSlice_Meet );
       
   367                 }
       
   368             else if ( token == KSlice )
       
   369             	{
       
   370             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmax,
       
   371                                                ESvgMeetOrSlice_Slice );
       
   372             	}
       
   373             else {
       
   374             	this->SetPreserveAspectRatioL( ESvgPreserveAspectRatio_XmaxYmax,
       
   375                                                ESvgMeetOrSlice_Meet );
       
   376             	}
       
   377             }
       
   378 
       
   379         return ETrue;
       
   380         }
       
   381     else
       
   382         return EFalse;
       
   383     }
       
   384 
       
   385 
       
   386 
       
   387 /// Sets window-viewport transformation
       
   388 /// Foley, Van Dam, 2nd ed, p 212
       
   389 /// Currenly, only SVG element can have viewport.
       
   390 /// aXYWH: x, y, width, height attributes of the element.
       
   391 /// aTr: transformations up to element.
       
   392 // ---------------------------------------------------------------------------
       
   393 //
       
   394 // ---------------------------------------------------------------------------
       
   395 void CSvgFitToViewBoxImpl::SetWindowViewportTrans( TGfxRectangle2D aXYWH,
       
   396                                                    TGfxAffineTransform& aTr,
       
   397                                                    TSize aSize )
       
   398     {
       
   399     TGfxAffineTransform tr;
       
   400     TGfxAffineTransform tr2;
       
   401 
       
   402 	//VIEWPORT NUMBERS
       
   403     TFloatFixPt lViewPortX = aXYWH.MinX();
       
   404     TFloatFixPt lViewPortY = aXYWH.MinY();
       
   405     TFloatFixPt lViewPortWidth = aXYWH.MaxX() - lViewPortX;
       
   406     TFloatFixPt lViewPortHeight = aXYWH.MaxY() - lViewPortY;
       
   407 
       
   408     tr.SetTransform( 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f );
       
   409 
       
   410     /* 1. Translate to origin */
       
   411     tr.Translate( lViewPortX, lViewPortY );
       
   412 
       
   413     /* 2. Scale */
       
   414 
       
   415     TFloatFixPt lViewBoxXmin;
       
   416     TFloatFixPt lViewBoxYmin;
       
   417     TFloatFixPt lViewBoxWidth;
       
   418     TFloatFixPt lViewBoxHeight;
       
   419 
       
   420     if ( iViewBoxDefined ) //
       
   421         {
       
   422         lViewBoxXmin = iViewBox.MinX();
       
   423         lViewBoxYmin = iViewBox.MinY();
       
   424         lViewBoxWidth = iViewBox.MaxX() - lViewBoxXmin;
       
   425         lViewBoxHeight = iViewBox.MaxY() - lViewBoxYmin;
       
   426         }
       
   427     else
       
   428         {
       
   429         //this will default viewBox to <svg> element width and height
       
   430         lViewBoxXmin = 0;
       
   431         lViewBoxYmin = 0;
       
   432         lViewBoxWidth = aSize.iWidth;
       
   433         lViewBoxHeight = aSize.iHeight;
       
   434         }
       
   435 
       
   436 	#ifdef SVG_FLOAT_BUILD
       
   437     if ( lViewBoxWidth == TFloatFixPt(0.0f) || lViewBoxHeight == TFloatFixPt(0.0f) )
       
   438 	#else
       
   439     if ( lViewBoxWidth == TFloatFixPt( 0 , ETrue ) || lViewBoxHeight == TFloatFixPt( 0,ETrue ) )
       
   440 	#endif
       
   441         return;
       
   442 
       
   443 	TFloatFixPt sx = TFloatFixPt(1.0f);
       
   444 	TFloatFixPt sy = TFloatFixPt(1.0f);
       
   445 
       
   446     sx = lViewPortWidth / lViewBoxWidth;
       
   447     sy = lViewPortHeight / lViewBoxHeight;
       
   448 
       
   449 	#ifdef SVG_FLOAT_BUILD
       
   450    if ( sx == TFloatFixPt(0.0f) || sy == TFloatFixPt(0.0f) )
       
   451 	#else
       
   452    if ( sx == TFloatFixPt( 0 , ETrue ) || sy == TFloatFixPt( 0,ETrue ) )
       
   453 	#endif
       
   454         return;
       
   455 
       
   456     TSvgPreserveAspectAlignType align = iAspectRatio->GetAlign();
       
   457 	TSvgMeetOrSliceType meetSlice = iAspectRatio->GetMeetOrSlice();
       
   458 
       
   459     TFloatFixPt xtrans = TFloatFixPt( -1.0f ) * lViewBoxXmin;
       
   460     TFloatFixPt ytrans = TFloatFixPt( -1.0f ) * lViewBoxYmin;
       
   461 
       
   462     switch ( align )
       
   463         {
       
   464             case ESvgPreserveAspectRatio_None:
       
   465             /* Non uniform scaling */
       
   466             //none - Do not force uniform scaling.
       
   467             //Scale the graphic content of the given element
       
   468             //non-uniformly if necessary such that the element's
       
   469             //bounding box exactly matches the viewport rectangle.
       
   470 
       
   471             //(Note: if <align> is none, then the optional <meetOrSlice> value is ignored.)
       
   472             break;
       
   473 
       
   474             case ESvgPreserveAspectRatio_XminYmin:
       
   475             //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
       
   476             //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
       
   477 
       
   478             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   479             {
       
   480                 if ( sx > sy )
       
   481                 {
       
   482                     sx = sy;
       
   483                     //no change for xtrans...default above
       
   484                 }
       
   485                 else // ( sx < sy )
       
   486                 {
       
   487                     sy = sx;
       
   488                     //no change for ytrans...default above
       
   489                 }
       
   490             }
       
   491             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   492             {
       
   493                 if (sx > sy)
       
   494                 {
       
   495                     sy = sx;
       
   496                 }
       
   497                 else // ( sx < sy )
       
   498                 {
       
   499                     sx = sy;
       
   500                 }
       
   501             }
       
   502             break;
       
   503 
       
   504             case ESvgPreserveAspectRatio_XmidYmin:
       
   505             //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
       
   506             //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
       
   507             //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
       
   508             //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
       
   509 
       
   510             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   511             {
       
   512                 if ( sx > sy )
       
   513                 {
       
   514                     sx = sy;
       
   515 	#ifdef SVG_FLOAT_BUILD	
       
   516                     xtrans = ( ( TFloatFixPt )
       
   517                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) * TFloatFixPt(.5f) ) / sx - lViewBoxXmin;
       
   518 	#else
       
   519                     xtrans = ( ( TFloatFixPt )
       
   520                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) >> 1 ) / sx - lViewBoxXmin;
       
   521 	#endif
       
   522                 }
       
   523                 else // ( sx < sy )
       
   524                 {
       
   525                     sy = sx;
       
   526                     //no change for ytrans...default above
       
   527                 }
       
   528             }
       
   529             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   530             {
       
   531                 if ( sx > sy )
       
   532                 {
       
   533                     sy = sx;
       
   534                 }
       
   535                 else //( sx < sy )
       
   536                 {
       
   537                     sx = sy;
       
   538                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   539                     xtrans = xtrans/sx;
       
   540                     xtrans = xtrans/TFloatFixPt(2) - lViewBoxXmin;
       
   541                 }
       
   542             }
       
   543             break;
       
   544 
       
   545             case ESvgPreserveAspectRatio_XmaxYmin:
       
   546             //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
       
   547             //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
       
   548             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   549             {
       
   550                 if ( sx > sy )
       
   551                 {
       
   552                     sx = sy;
       
   553 	
       
   554                     xtrans = ( ( TFloatFixPt )
       
   555                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx - lViewBoxXmin;
       
   556                 }
       
   557                 else // ( sx < sy )
       
   558                 {
       
   559                     sy = sx;
       
   560                     //no change for ytrans...default above
       
   561                 }
       
   562             }
       
   563             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   564             {
       
   565                 if ( sx > sy )
       
   566                 {
       
   567                     sy = sx;
       
   568                     //no change for ytrans...default above
       
   569                 }
       
   570                 else // ( sx < sy )
       
   571                 {
       
   572                     sx = sy;
       
   573                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   574                     xtrans = xtrans/sx - lViewBoxXmin;
       
   575                 }
       
   576             }
       
   577             break;
       
   578 
       
   579             case ESvgPreserveAspectRatio_XminYmid:
       
   580             //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
       
   581             //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
       
   582             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   583             {
       
   584                 if ( sx > sy )
       
   585                 {
       
   586                     sx = sy;
       
   587                     //no change for xtrans...default above
       
   588                 }
       
   589                 else // ( sx < sy )
       
   590                 {
       
   591                     sy = sx;
       
   592 	#ifdef SVG_FLOAT_BUILD                    
       
   593                     ytrans = ( ( TFloatFixPt )
       
   594                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) * TFloatFixPt(.5f) ) /sy - lViewBoxYmin;
       
   595 	#else
       
   596                     ytrans = ( ( TFloatFixPt )
       
   597                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) >> 1 ) /sy - lViewBoxYmin;
       
   598 	#endif
       
   599                 }
       
   600             }
       
   601             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   602             {
       
   603                 if ( sx > sy )
       
   604                 {
       
   605                     sy = sx;
       
   606                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   607                     ytrans = ytrans/sx;
       
   608                     ytrans = ytrans/TFloatFixPt(2) - lViewBoxYmin;
       
   609                 }
       
   610                 else // ( sx < sy )
       
   611                 {
       
   612                     sx = sy;
       
   613                 }
       
   614             }
       
   615             break;
       
   616 
       
   617             case ESvgPreserveAspectRatio_XmidYmid:
       
   618             //(default) case
       
   619             //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
       
   620             //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
       
   621             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   622             {
       
   623                 if ( sx > sy )
       
   624                 {
       
   625                     sx = sy;
       
   626 	#ifdef SVG_FLOAT_BUILD
       
   627                     xtrans = ( ( TFloatFixPt )
       
   628                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) * TFloatFixPt(.5f) ) / sx - lViewBoxXmin;
       
   629 	#else
       
   630                     xtrans = ( ( TFloatFixPt )
       
   631                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) >> 1 ) / sx - lViewBoxXmin;
       
   632 	#endif
       
   633                 }
       
   634                 else if ( sx < sy )
       
   635                 {
       
   636                     sy = sx;
       
   637 	#ifdef SVG_FLOAT_BUILD
       
   638 	
       
   639                     ytrans = ( ( TFloatFixPt )
       
   640                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) * TFloatFixPt(.5f) ) /sy - lViewBoxYmin;
       
   641 	#else
       
   642                     ytrans = ( ( TFloatFixPt )
       
   643                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) >> 1 ) /sy - lViewBoxYmin;
       
   644 	#endif
       
   645                 }
       
   646             }
       
   647             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   648             {
       
   649                 if ( sx > sy )
       
   650                 {
       
   651                     sy = sx;
       
   652                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   653                     ytrans = ytrans/sx;
       
   654                     ytrans = ytrans/TFloatFixPt(2) - lViewBoxYmin;
       
   655                 }
       
   656                 else // ( sx < sy )
       
   657                 {
       
   658                     sx = sy;
       
   659                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   660                     xtrans = xtrans/sx;
       
   661                     xtrans = xtrans/TFloatFixPt(2) - lViewBoxXmin;
       
   662                 }
       
   663             }
       
   664             break;
       
   665 
       
   666             case ESvgPreserveAspectRatio_XmaxYmid:
       
   667             //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
       
   668             //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
       
   669             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   670             {
       
   671                 if ( sx > sy )
       
   672                 {
       
   673                     sx = sy;
       
   674                     xtrans = ( ( TFloatFixPt )
       
   675                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx - lViewBoxXmin;
       
   676                 }
       
   677                 else //( sx < sy )
       
   678                 {
       
   679                     sy = sx;
       
   680 	#ifdef SVG_FLOAT_BUILD
       
   681 
       
   682                     ytrans = ( ( TFloatFixPt )
       
   683                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) * TFloatFixPt(.5f) ) /sy - lViewBoxYmin;
       
   684 	#else
       
   685                     ytrans = ( ( TFloatFixPt )
       
   686                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) >> 1 ) /sy - lViewBoxYmin;
       
   687 	#endif
       
   688                 }
       
   689             }
       
   690             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   691             {
       
   692                 if ( sx > sy )
       
   693                 {
       
   694                     sy = sx;
       
   695                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   696                     ytrans = ytrans/sx;
       
   697                     ytrans = ytrans/TFloatFixPt(2) - lViewBoxYmin;
       
   698                 }
       
   699                 else //( sx < sy )
       
   700                 {
       
   701                     sx = sy;
       
   702                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   703                     xtrans = xtrans/sx - lViewBoxXmin;
       
   704                 }
       
   705             }
       
   706             break;
       
   707 
       
   708             case ESvgPreserveAspectRatio_XminYmax:
       
   709             //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
       
   710             //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
       
   711             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   712             {
       
   713                 if ( sx > sy )
       
   714                 {
       
   715                     sx = sy;
       
   716                     //no change for xtrans...default above
       
   717                 }
       
   718                 else //( sx < sy )
       
   719                 {
       
   720                     sy = sx;
       
   721 
       
   722                     ytrans = ( ( TFloatFixPt )
       
   723                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy - lViewBoxYmin;
       
   724                 }
       
   725             }
       
   726             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   727             {
       
   728                 if ( sx > sy )
       
   729                 {
       
   730                     sy = sx;
       
   731                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   732                     ytrans = ytrans/sx - lViewBoxYmin;
       
   733                 }
       
   734                 else //( sx < sy )
       
   735                 {
       
   736                     sx = sy;
       
   737                 }
       
   738             }
       
   739             break;
       
   740 
       
   741             case ESvgPreserveAspectRatio_XmidYmax:
       
   742             //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
       
   743             //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
       
   744             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   745             {
       
   746                 if ( sx > sy )
       
   747                 {
       
   748                     sx = sy;
       
   749 	#ifdef SVG_FLOAT_BUILD
       
   750 	
       
   751                     xtrans = ( ( TFloatFixPt )
       
   752                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) * TFloatFixPt(.5f) ) / sx - lViewBoxXmin;
       
   753 	#else
       
   754                     xtrans = ( ( TFloatFixPt )
       
   755                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) >> 1 ) / sx - lViewBoxXmin;
       
   756 
       
   757 	#endif
       
   758                 }
       
   759                 else //( sx < sy )
       
   760                 {
       
   761                     sy = sx;
       
   762 
       
   763                     ytrans = ( ( TFloatFixPt )
       
   764                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy - lViewBoxYmin;
       
   765                 }
       
   766             }
       
   767             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   768             {
       
   769                 if ( sx > sy )
       
   770                 {
       
   771                     sy = sx;
       
   772                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   773                     ytrans = ytrans/sx - lViewBoxYmin;
       
   774                 }
       
   775                 else //( sx < sy )
       
   776                 {
       
   777                     sx = sy;
       
   778                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   779                     xtrans = xtrans/sx;
       
   780                     xtrans = xtrans/TFloatFixPt(2) - lViewBoxXmin;
       
   781                 }
       
   782             }
       
   783             break;
       
   784 
       
   785             case ESvgPreserveAspectRatio_XmaxYmax:
       
   786             //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
       
   787             //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
       
   788             if (meetSlice == ESvgMeetOrSlice_Meet)
       
   789             {
       
   790                 if ( sx > sy )
       
   791                 {
       
   792                     sx = sy;
       
   793 
       
   794                     xtrans = ( ( TFloatFixPt )
       
   795                            ( lViewPortWidth - ( ( TFloatFixPt ) ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx - lViewBoxXmin;
       
   796                 }
       
   797                 else //( sx < sy )
       
   798                 {
       
   799                     sy = sx;
       
   800 
       
   801                     ytrans = ( ( TFloatFixPt )
       
   802                            ( lViewPortHeight - ( ( TFloatFixPt ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy - lViewBoxYmin;
       
   803                 }
       
   804             }
       
   805             else if (meetSlice == ESvgMeetOrSlice_Slice)
       
   806             {
       
   807                 if ( sx > sy )
       
   808                 {
       
   809                     sy = sx;
       
   810                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   811                     ytrans = ytrans/sx - lViewBoxYmin;
       
   812                 }
       
   813                 else //( sx < sy )
       
   814                 {
       
   815                     sx = sy;
       
   816                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   817                     xtrans = xtrans/sx - lViewBoxXmin;
       
   818                 }
       
   819             }
       
   820             break;
       
   821 
       
   822         default:
       
   823             break;
       
   824         }
       
   825 
       
   826     tr2.SetTransform( sx, 0.0f, 0.0f, sy, 0.0f, 0.0f );
       
   827     tr.Concatenate( tr2 );
       
   828 
       
   829     /* 3. Translate to viewport origin */
       
   830     tr.Translate( xtrans, ytrans );
       
   831 
       
   832     //this aTr should be the CTM for the root element
       
   833     //and should change when the viewBox is set because that could cause scaling
       
   834     aTr.Concatenate( tr );
       
   835     }
       
   836 
       
   837 // *******************************************************
       
   838 // Private
       
   839 
       
   840 // ---------------------------------------------------------------------------
       
   841 //
       
   842 // ---------------------------------------------------------------------------
       
   843 void CSvgFitToViewBoxImpl::ConstructL()
       
   844     {
       
   845 
       
   846     //defaults to xMidYMid and Meet
       
   847     iAspectRatio = CSvgPreserveAspectRatioImpl::NewL();
       
   848 
       
   849     }
       
   850 
       
   851 // ---------------------------------------------------------------------------
       
   852 //
       
   853 // ---------------------------------------------------------------------------
       
   854 CSvgFitToViewBoxImpl::CSvgFitToViewBoxImpl() : iViewBox( 0, 0, 0, 0 ),
       
   855                                                iViewBoxDefined( EFalse )
       
   856 
       
   857     {
       
   858     }
       
   859 
       
   860 
       
   861 // ---------------------------------------------------------------------------
       
   862 //
       
   863 // ---------------------------------------------------------------------------
       
   864 CSvgFitToViewBoxImpl* CSvgFitToViewBoxImpl::CloneL()
       
   865     {
       
   866     CSvgFitToViewBoxImpl* retValue = CSvgFitToViewBoxImpl::NewL();
       
   867 
       
   868         CleanupStack::PushL(retValue);
       
   869 
       
   870     // *** copy iAspectRatio
       
   871     if ( this->iAspectRatio != NULL )
       
   872         {
       
   873         if ( retValue->iAspectRatio != NULL )
       
   874             {
       
   875                 delete retValue->iAspectRatio;
       
   876                 retValue->iAspectRatio = NULL;
       
   877             }
       
   878         retValue->iAspectRatio = this->iAspectRatio->CloneL();
       
   879         }
       
   880 
       
   881     // *** copy other simple instance variables
       
   882     retValue->iViewBox = this->iViewBox;
       
   883     retValue->iViewBoxDefined = this->iViewBoxDefined;
       
   884 
       
   885     CleanupStack::Pop(retValue);
       
   886 
       
   887     return retValue;
       
   888     }
       
   889