svgtopt/nvgdecoder/src/nvgfittoviewbox.cpp
changeset 46 88edb906c587
equal deleted inserted replaced
-1:000000000000 46:88edb906c587
       
     1 /*
       
     2 * Copyright (c) 2008 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:  NVG Decoder source file
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #include "nvgfittoviewbox.h"
       
    20 
       
    21 const TReal KZero  = 0.0;
       
    22 const TReal KOne   = 1.0;
       
    23 
       
    24 
       
    25 // ---------------------------------------------------------------------------
       
    26 // 2 Phase Constructor
       
    27 // ---------------------------------------------------------------------------
       
    28 CNvgFitToViewBoxImpl* CNvgFitToViewBoxImpl::NewL()
       
    29     {
       
    30     CNvgFitToViewBoxImpl* self = new ( ELeave ) CNvgFitToViewBoxImpl();
       
    31     CleanupStack::PushL( self );
       
    32     self->ConstructL();
       
    33     CleanupStack::Pop(self);
       
    34 
       
    35     return self;
       
    36     }
       
    37 
       
    38 
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 // 2 Phase Constructor
       
    42 // ---------------------------------------------------------------------------
       
    43 CNvgFitToViewBoxImpl* CNvgFitToViewBoxImpl::NewLC()
       
    44     {
       
    45     CNvgFitToViewBoxImpl* self = new ( ELeave ) CNvgFitToViewBoxImpl();
       
    46     CleanupStack::PushL( self );
       
    47     self->ConstructL();
       
    48 
       
    49     return self;
       
    50     }
       
    51 
       
    52 
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // Constuctor
       
    56 // ---------------------------------------------------------------------------
       
    57 CNvgFitToViewBoxImpl::CNvgFitToViewBoxImpl(): iM00(KOne),
       
    58                                             iM01(KZero),
       
    59                                             iM02(KZero),
       
    60                                             iM10(KZero),
       
    61                                             iM11(KOne),
       
    62                                             iM12(KZero),
       
    63                                             iViewBoxDefined(EFalse),
       
    64                                             iAlign(ENvgPreserveAspectRatio_XmidYmid),
       
    65                                             iMeetSlice(ENvgMeet)
       
    66     {
       
    67     ivbX    = 0.0;
       
    68     ivbY    = 0.0;
       
    69     ivbW   = 0.0;
       
    70     ivbH    = 0.0;
       
    71 
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // 
       
    76 // ---------------------------------------------------------------------------
       
    77 void CNvgFitToViewBoxImpl::ConstructL()
       
    78     {
       
    79 
       
    80     }
       
    81 
       
    82 
       
    83 
       
    84 // ---------------------------------------------------------------------------
       
    85 // Destructor
       
    86 // ---------------------------------------------------------------------------
       
    87 CNvgFitToViewBoxImpl::~CNvgFitToViewBoxImpl()
       
    88     {
       
    89     
       
    90     }
       
    91 
       
    92 
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 // Computation of the viewport to viewbox transformation matrix
       
    96 // ---------------------------------------------------------------------------
       
    97 void CNvgFitToViewBoxImpl::SetWindowViewportTrans(TRect aViewPort, TSize aSize)
       
    98     {
       
    99     
       
   100     //VIEWPORT NUMBERS
       
   101     TReal lViewPortX = aViewPort.iTl.iX;
       
   102     TReal lViewPortY = aViewPort.iTl.iY;
       
   103     TReal lViewPortWidth = aViewPort.Width();
       
   104     TReal lViewPortHeight = aViewPort.Height();
       
   105     
       
   106     vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
       
   107     vgTranslate(lViewPortX, lViewPortY );
       
   108 
       
   109     /* 2. Scale */
       
   110 
       
   111     TReal lViewBoxXmin;
       
   112     TReal lViewBoxYmin;
       
   113     TReal lViewBoxWidth;
       
   114     TReal lViewBoxHeight;
       
   115 
       
   116     if ( iViewBoxDefined ) 
       
   117         {
       
   118         lViewBoxXmin = ivbX;
       
   119         lViewBoxYmin = ivbY;
       
   120         lViewBoxWidth = ivbW;
       
   121         lViewBoxHeight = ivbH;
       
   122         }
       
   123     else
       
   124         {
       
   125         //this will default viewBox to <svg> element width and height
       
   126         lViewBoxXmin = 0;
       
   127         lViewBoxYmin = 0;
       
   128         lViewBoxWidth = aSize.iWidth;
       
   129         lViewBoxHeight = aSize.iHeight;
       
   130         }
       
   131 
       
   132 	
       
   133     if ( lViewBoxWidth == 0.0f || lViewBoxHeight == 0.0f )
       
   134         {
       
   135         return;    
       
   136         }
       
   137 	
       
   138 
       
   139 	TReal sx = lViewPortWidth / lViewBoxWidth;
       
   140 	TReal sy = lViewPortHeight / lViewBoxHeight;
       
   141 	
       
   142     if ( sx == 0.0f || sy == 0.0f )
       
   143         {
       
   144         return;    
       
   145         }
       
   146     
       
   147 
       
   148     
       
   149     TReal xtrans = TReal( -1.0f ) * lViewBoxXmin;
       
   150     TReal ytrans = TReal( -1.0f ) * lViewBoxYmin;
       
   151 
       
   152     switch ( iAlign )
       
   153         {
       
   154             case ENvgPreserveAspectRatio_None:
       
   155             /* Non uniform scaling */
       
   156             //none - Do not force uniform scaling.
       
   157             //Scale the graphic content of the given element
       
   158             //non-uniformly if necessary such that the element's
       
   159             //bounding box exactly matches the viewport rectangle.
       
   160 
       
   161             //(Note: if <align> is none, then the optional <meetOrSlice> value is ignored.)
       
   162             break;
       
   163 
       
   164             case ENvgPreserveAspectRatio_XminYmin:
       
   165             //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
       
   166             //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
       
   167 
       
   168             if (iMeetSlice == ENvgMeet)
       
   169             {
       
   170                 if ( sx > sy )
       
   171                 {
       
   172                     sx = sy;
       
   173                     //no change for xtrans...default above
       
   174                 }
       
   175                 else // ( sx < sy )
       
   176                 {
       
   177                     sy = sx;
       
   178                     //no change for ytrans...default above
       
   179                 }
       
   180             }
       
   181             else if (iMeetSlice == ENvgSlice)
       
   182             {
       
   183                 if (sx > sy)
       
   184                 {
       
   185                     sy = sx;
       
   186                 }
       
   187                 else // ( sx < sy )
       
   188                 {
       
   189                     sx = sy;
       
   190                 }
       
   191             }
       
   192             break;
       
   193 
       
   194             case ENvgPreserveAspectRatio_XmidYmin:
       
   195             //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
       
   196             //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
       
   197             //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
       
   198             //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
       
   199 
       
   200             if (iMeetSlice == ENvgMeet)
       
   201             {
       
   202                 if ( sx > sy )
       
   203                 {
       
   204                     sx = sy;
       
   205 	                xtrans = ( ( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) )\
       
   206                            * 0.5 ) / sx - lViewBoxXmin;
       
   207 	            }
       
   208                 else // ( sx < sy )
       
   209                 {
       
   210                     sy = sx;
       
   211                     //no change for ytrans...default above
       
   212                 }
       
   213             }
       
   214             else if (iMeetSlice == ENvgSlice)
       
   215             {
       
   216                 if ( sx > sy )
       
   217                 {
       
   218                     sy = sx;
       
   219                 }
       
   220                 else //( sx < sy )
       
   221                 {
       
   222                     sx = sy;
       
   223                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   224                     xtrans = xtrans/sx;
       
   225                     xtrans = xtrans/2.0 - lViewBoxXmin;
       
   226                 }
       
   227             }
       
   228             break;
       
   229 
       
   230             case ENvgPreserveAspectRatio_XmaxYmin:
       
   231             //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
       
   232             //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
       
   233             if (iMeetSlice == ENvgMeet)
       
   234             {
       
   235                 if ( sx > sy )
       
   236                 {
       
   237                     sx = sy;
       
   238 	
       
   239                     xtrans = (( lViewPortWidth - ( ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx\
       
   240                            - lViewBoxXmin;
       
   241                 }
       
   242                 else // ( sx < sy )
       
   243                 {
       
   244                     sy = sx;
       
   245                     //no change for ytrans...default above
       
   246                 }
       
   247             }
       
   248             else if (iMeetSlice == ENvgSlice)
       
   249             {
       
   250                 if ( sx > sy )
       
   251                 {
       
   252                     sy = sx;
       
   253                     //no change for ytrans...default above
       
   254                 }
       
   255                 else // ( sx < sy )
       
   256                 {
       
   257                     sx = sy;
       
   258                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   259                     xtrans = xtrans/sx - lViewBoxXmin;
       
   260                 }
       
   261             }
       
   262             break;
       
   263 
       
   264             case ENvgPreserveAspectRatio_XminYmid:
       
   265             //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
       
   266             //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
       
   267             if (iMeetSlice == ENvgMeet)
       
   268             {
       
   269                 if ( sx > sy )
       
   270                 {
       
   271                     sx = sy;
       
   272                     //no change for xtrans...default above
       
   273                 }
       
   274                 else // ( sx < sy )
       
   275                 {
       
   276                     sy = sx;
       
   277 	                ytrans = ( ( TReal )
       
   278                            ( lViewPortHeight - ( ( TReal ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) )\
       
   279                            * TReal(.5) ) /sy - lViewBoxYmin;
       
   280                 }
       
   281             }
       
   282             else if (iMeetSlice == ENvgSlice)
       
   283             {
       
   284                 if ( sx > sy )
       
   285                     {
       
   286                     sy = sx;
       
   287                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   288                     ytrans = ytrans/sx;
       
   289                     ytrans = ytrans/2.0 - lViewBoxYmin;
       
   290                     }
       
   291                 else
       
   292                     {
       
   293                     sx = sy;
       
   294                     }
       
   295             }
       
   296             break;
       
   297 
       
   298             case ENvgPreserveAspectRatio_XmidYmid:
       
   299             //(default) case
       
   300             //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
       
   301             //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
       
   302             if (iMeetSlice == ENvgMeet)
       
   303             {
       
   304                 if ( sx > sy )
       
   305                 {
       
   306                     sx = sy;
       
   307                     xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) * \
       
   308                             0.5 ) / sx - lViewBoxXmin;
       
   309 
       
   310                 }
       
   311                 else if ( sx < sy )
       
   312                 {
       
   313                     sy = sx;
       
   314 	
       
   315                     ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) * \
       
   316                            0.5 ) /sy - lViewBoxYmin;
       
   317 	            }
       
   318             }
       
   319             else if (iMeetSlice == ENvgSlice)
       
   320             {
       
   321                 if ( sx > sy )
       
   322                 {
       
   323                     sy = sx;
       
   324                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   325                     ytrans = ytrans/sx;
       
   326                     ytrans = ytrans/2.0 - lViewBoxYmin;
       
   327                 }
       
   328                 else // ( sx < sy )
       
   329                 {
       
   330                     sx = sy;
       
   331                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   332                     xtrans = xtrans/sx;
       
   333                     xtrans = xtrans/2.0 - lViewBoxXmin;
       
   334                 }
       
   335             }
       
   336             break;
       
   337 
       
   338             case ENvgPreserveAspectRatio_XmaxYmid:
       
   339             //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
       
   340             //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
       
   341             if (iMeetSlice == ENvgMeet)
       
   342             {
       
   343                 if ( sx > sy )
       
   344                 {
       
   345                     sx = sy;
       
   346                     xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx \
       
   347                            - lViewBoxXmin;
       
   348                 }
       
   349                 else //( sx < sy )
       
   350                 {
       
   351                     sy = sx;
       
   352 	
       
   353                     ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) \
       
   354                            * 0.5 ) /sy - lViewBoxYmin;
       
   355 	            }
       
   356             }
       
   357             else if (iMeetSlice == ENvgSlice)
       
   358             {
       
   359                 if ( sx > sy )
       
   360                 {
       
   361                     sy = sx;
       
   362                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   363                     ytrans = ytrans/sx;
       
   364                     ytrans = ytrans/2.0 - lViewBoxYmin;
       
   365                 }
       
   366                 else //( sx < sy )
       
   367                 {
       
   368                     sx = sy;
       
   369                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   370                     xtrans = xtrans/sx - lViewBoxXmin;
       
   371                 }
       
   372             }
       
   373             break;
       
   374 
       
   375             case ENvgPreserveAspectRatio_XminYmax:
       
   376             //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
       
   377             //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
       
   378             if (iMeetSlice == ENvgMeet)
       
   379             {
       
   380                 if ( sx > sy )
       
   381                 {
       
   382                     sx = sy;
       
   383                     //no change for xtrans...default above
       
   384                 }
       
   385                 else //( sx < sy )
       
   386                 {
       
   387                     sy = sx;
       
   388 
       
   389                     ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \
       
   390                            - lViewBoxYmin;
       
   391                 }
       
   392             }
       
   393             else if (iMeetSlice == ENvgSlice)
       
   394             {
       
   395                 if ( sx > sy )
       
   396                 {
       
   397                     sy = sx;
       
   398                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   399                     ytrans = ytrans/sx - lViewBoxYmin;
       
   400                 }
       
   401                 else //( sx < sy )
       
   402                 {
       
   403                     sx = sy;
       
   404                 }
       
   405             }
       
   406             break;
       
   407 
       
   408             case ENvgPreserveAspectRatio_XmidYmax:
       
   409             //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
       
   410             //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
       
   411             if (iMeetSlice == ENvgMeet)
       
   412             {
       
   413                 if ( sx > sy )
       
   414                 {
       
   415                     sx = sy;
       
   416 	
       
   417                     xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) \
       
   418                            * 0.5 ) / sx - lViewBoxXmin;
       
   419 	            }
       
   420                 else //( sx < sy )
       
   421                 {
       
   422                     sy = sx;
       
   423 
       
   424                     ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \
       
   425                            - lViewBoxYmin;
       
   426                 }
       
   427             }
       
   428             else if (iMeetSlice == ENvgSlice)
       
   429             {
       
   430                 if ( sx > sy )
       
   431                 {
       
   432                     sy = sx;
       
   433                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   434                     ytrans = ytrans/sx - lViewBoxYmin;
       
   435                 }
       
   436                 else //( sx < sy )
       
   437                 {
       
   438                     sx = sy;
       
   439                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   440                     xtrans = xtrans/sx;
       
   441                     xtrans = xtrans/2.0 - lViewBoxXmin;
       
   442                 }
       
   443             }
       
   444             break;
       
   445 
       
   446             case ENvgPreserveAspectRatio_XmaxYmax:
       
   447             //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
       
   448             //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
       
   449             if (iMeetSlice == ENvgMeet)
       
   450             {
       
   451                 if ( sx > sy )
       
   452                 {
       
   453                     sx = sy;
       
   454 
       
   455                     xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx\
       
   456                            - lViewBoxXmin;
       
   457                 }
       
   458                 else //( sx < sy )
       
   459                 {
       
   460                     sy = sx;
       
   461 
       
   462                     ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \
       
   463                            - lViewBoxYmin;
       
   464                 }
       
   465             }
       
   466             else if (iMeetSlice == ENvgSlice)
       
   467             {
       
   468                 if ( sx > sy )
       
   469                 {
       
   470                     sy = sx;
       
   471                     ytrans = lViewPortHeight - sx*lViewBoxHeight;
       
   472                     ytrans = ytrans/sx - lViewBoxYmin;
       
   473                 }
       
   474                 else //( sx < sy )
       
   475                 {
       
   476                     sx = sy;
       
   477                     xtrans = lViewPortWidth - sx*lViewBoxWidth;
       
   478                     xtrans = xtrans/sx - lViewBoxXmin;
       
   479                 }
       
   480             }
       
   481             break;
       
   482 
       
   483         default:
       
   484             break;
       
   485         }
       
   486     vgScale( sx, sy);
       
   487 
       
   488     vgTranslate( xtrans, ytrans );
       
   489 
       
   490     }
       
   491 
       
   492  void CNvgFitToViewBoxImpl::Concatenate( TReal aM00, TReal aM01, TReal aM02, TReal aM10, TReal aM11, TReal aM12 )
       
   493     {
       
   494     TReal m0, m1;
       
   495     m0  = iM00;
       
   496     m1  = iM01;
       
   497     iM00 = aM00 * m0 + aM10 * m1;
       
   498     iM01 = aM01 * m0 + aM11 * m1;
       
   499     iM02 += aM02 * m0 + aM12 * m1;
       
   500     m0 = iM10;
       
   501     m1 = iM11;
       
   502     iM11 = aM01 * m0 + aM11 * m1;
       
   503     iM10 = aM00 * m0 + aM10 * m1;
       
   504     iM12 += aM02 * m0 + aM12 * m1;
       
   505     }
       
   506 //--------------------------------EndOfFile------------------------------------