svgtopt/nvgdecoder/src/nvgfittoviewbox.cpp
author Stefan Karlsson <stefan.karlsson@nokia.com>
Sat, 10 Apr 2010 13:41:47 +0100
branchCompilerCompatibility
changeset 14 23922a3276bd
parent 0 d46562c3d99d
permissions -rw-r--r--
Got rid of some trivial warnings (nested comments and tokens after #endif).

/*
* Copyright (c) 2008 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:  NVG Decoder source file
 *
*/


#include "nvgfittoviewbox.h"

const TReal KZero  = 0.0;
const TReal KOne   = 1.0;


// ---------------------------------------------------------------------------
// 2 Phase Constructor
// ---------------------------------------------------------------------------
CNvgFitToViewBoxImpl* CNvgFitToViewBoxImpl::NewL()
    {
    CNvgFitToViewBoxImpl* self = new ( ELeave ) CNvgFitToViewBoxImpl();
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop(self);

    return self;
    }



// ---------------------------------------------------------------------------
// 2 Phase Constructor
// ---------------------------------------------------------------------------
CNvgFitToViewBoxImpl* CNvgFitToViewBoxImpl::NewLC()
    {
    CNvgFitToViewBoxImpl* self = new ( ELeave ) CNvgFitToViewBoxImpl();
    CleanupStack::PushL( self );
    self->ConstructL();

    return self;
    }



// ---------------------------------------------------------------------------
// Constuctor
// ---------------------------------------------------------------------------
CNvgFitToViewBoxImpl::CNvgFitToViewBoxImpl(): iM00(KOne),
                                            iM01(KZero),
                                            iM02(KZero),
                                            iM10(KZero),
                                            iM11(KOne),
                                            iM12(KZero),
                                            iViewBoxDefined(EFalse),
                                            iAlign(ENvgPreserveAspectRatio_XmidYmid),
                                            iMeetSlice(ENvgMeet)
    {
    ivbX    = 0.0;
    ivbY    = 0.0;
    ivbW   = 0.0;
    ivbH    = 0.0;

    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
void CNvgFitToViewBoxImpl::ConstructL()
    {

    }



// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
CNvgFitToViewBoxImpl::~CNvgFitToViewBoxImpl()
    {
    
    }



// ---------------------------------------------------------------------------
// Computation of the viewport to viewbox transformation matrix
// ---------------------------------------------------------------------------
void CNvgFitToViewBoxImpl::SetWindowViewportTrans(TRect aViewPort, TSize aSize)
    {
    
    //VIEWPORT NUMBERS
    TReal lViewPortX = aViewPort.iTl.iX;
    TReal lViewPortY = aViewPort.iTl.iY;
    TReal lViewPortWidth = aViewPort.Width();
    TReal lViewPortHeight = aViewPort.Height();
    
    vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
    vgTranslate(lViewPortX, lViewPortY );

    /* 2. Scale */

    TReal lViewBoxXmin;
    TReal lViewBoxYmin;
    TReal lViewBoxWidth;
    TReal lViewBoxHeight;

    if ( iViewBoxDefined ) 
        {
        lViewBoxXmin = ivbX;
        lViewBoxYmin = ivbY;
        lViewBoxWidth = ivbW;
        lViewBoxHeight = ivbH;
        }
    else
        {
        //this will default viewBox to <svg> element width and height
        lViewBoxXmin = 0;
        lViewBoxYmin = 0;
        lViewBoxWidth = aSize.iWidth;
        lViewBoxHeight = aSize.iHeight;
        }

	
    if ( lViewBoxWidth == 0.0f || lViewBoxHeight == 0.0f )
        {
        return;    
        }
	

	TReal sx = lViewPortWidth / lViewBoxWidth;
	TReal sy = lViewPortHeight / lViewBoxHeight;
	
    if ( sx == 0.0f || sy == 0.0f )
        {
        return;    
        }
    

    
    TReal xtrans = TReal( -1.0f ) * lViewBoxXmin;
    TReal ytrans = TReal( -1.0f ) * lViewBoxYmin;

    switch ( iAlign )
        {
            case ENvgPreserveAspectRatio_None:
            /* Non uniform scaling */
            //none - Do not force uniform scaling.
            //Scale the graphic content of the given element
            //non-uniformly if necessary such that the element's
            //bounding box exactly matches the viewport rectangle.

            //(Note: if <align> is none, then the optional <meetOrSlice> value is ignored.)
            break;

            case ENvgPreserveAspectRatio_XminYmin:
            //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
            //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.

            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;
                    //no change for xtrans...default above
                }
                else // ( sx < sy )
                {
                    sy = sx;
                    //no change for ytrans...default above
                }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if (sx > sy)
                {
                    sy = sx;
                }
                else // ( sx < sy )
                {
                    sx = sy;
                }
            }
            break;

            case ENvgPreserveAspectRatio_XmidYmin:
            //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
            //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
            //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
            //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.

            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;
	                xtrans = ( ( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) )\
                           * 0.5 ) / sx - lViewBoxXmin;
	            }
                else // ( sx < sy )
                {
                    sy = sx;
                    //no change for ytrans...default above
                }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if ( sx > sy )
                {
                    sy = sx;
                }
                else //( sx < sy )
                {
                    sx = sy;
                    xtrans = lViewPortWidth - sx*lViewBoxWidth;
                    xtrans = xtrans/sx;
                    xtrans = xtrans/2.0 - lViewBoxXmin;
                }
            }
            break;

            case ENvgPreserveAspectRatio_XmaxYmin:
            //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
            //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport.
            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;
	
                    xtrans = (( lViewPortWidth - ( ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx\
                           - lViewBoxXmin;
                }
                else // ( sx < sy )
                {
                    sy = sx;
                    //no change for ytrans...default above
                }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if ( sx > sy )
                {
                    sy = sx;
                    //no change for ytrans...default above
                }
                else // ( sx < sy )
                {
                    sx = sy;
                    xtrans = lViewPortWidth - sx*lViewBoxWidth;
                    xtrans = xtrans/sx - lViewBoxXmin;
                }
            }
            break;

            case ENvgPreserveAspectRatio_XminYmid:
            //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
            //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;
                    //no change for xtrans...default above
                }
                else // ( sx < sy )
                {
                    sy = sx;
	                ytrans = ( ( TReal )
                           ( lViewPortHeight - ( ( TReal ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) )\
                           * TReal(.5) ) /sy - lViewBoxYmin;
                }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if ( sx > sy )
                    {
                    sy = sx;
                    ytrans = lViewPortHeight - sx*lViewBoxHeight;
                    ytrans = ytrans/sx;
                    ytrans = ytrans/2.0 - lViewBoxYmin;
                    }
                else
                    {
                    sx = sy;
                    }
            }
            break;

            case ENvgPreserveAspectRatio_XmidYmid:
            //(default) case
            //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
            //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;
                    xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) * \
                            0.5 ) / sx - lViewBoxXmin;

                }
                else if ( sx < sy )
                {
                    sy = sx;
	
                    ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) * \
                           0.5 ) /sy - lViewBoxYmin;
	            }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if ( sx > sy )
                {
                    sy = sx;
                    ytrans = lViewPortHeight - sx*lViewBoxHeight;
                    ytrans = ytrans/sx;
                    ytrans = ytrans/2.0 - lViewBoxYmin;
                }
                else // ( sx < sy )
                {
                    sx = sy;
                    xtrans = lViewPortWidth - sx*lViewBoxWidth;
                    xtrans = xtrans/sx;
                    xtrans = xtrans/2.0 - lViewBoxXmin;
                }
            }
            break;

            case ENvgPreserveAspectRatio_XmaxYmid:
            //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
            //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.
            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;
                    xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx \
                           - lViewBoxXmin;
                }
                else //( sx < sy )
                {
                    sy = sx;
	
                    ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) \
                           * 0.5 ) /sy - lViewBoxYmin;
	            }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if ( sx > sy )
                {
                    sy = sx;
                    ytrans = lViewPortHeight - sx*lViewBoxHeight;
                    ytrans = ytrans/sx;
                    ytrans = ytrans/2.0 - lViewBoxYmin;
                }
                else //( sx < sy )
                {
                    sx = sy;
                    xtrans = lViewPortWidth - sx*lViewBoxWidth;
                    xtrans = xtrans/sx - lViewBoxXmin;
                }
            }
            break;

            case ENvgPreserveAspectRatio_XminYmax:
            //Align the <min-x> of the element's viewBox with the smallest X value of the viewport.
            //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;
                    //no change for xtrans...default above
                }
                else //( sx < sy )
                {
                    sy = sx;

                    ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \
                           - lViewBoxYmin;
                }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if ( sx > sy )
                {
                    sy = sx;
                    ytrans = lViewPortHeight - sx*lViewBoxHeight;
                    ytrans = ytrans/sx - lViewBoxYmin;
                }
                else //( sx < sy )
                {
                    sx = sy;
                }
            }
            break;

            case ENvgPreserveAspectRatio_XmidYmax:
            //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
            //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;
	
                    xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) \
                           * 0.5 ) / sx - lViewBoxXmin;
	            }
                else //( sx < sy )
                {
                    sy = sx;

                    ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \
                           - lViewBoxYmin;
                }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if ( sx > sy )
                {
                    sy = sx;
                    ytrans = lViewPortHeight - sx*lViewBoxHeight;
                    ytrans = ytrans/sx - lViewBoxYmin;
                }
                else //( sx < sy )
                {
                    sx = sy;
                    xtrans = lViewPortWidth - sx*lViewBoxWidth;
                    xtrans = xtrans/sx;
                    xtrans = xtrans/2.0 - lViewBoxXmin;
                }
            }
            break;

            case ENvgPreserveAspectRatio_XmaxYmax:
            //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport.
            //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport.
            if (iMeetSlice == ENvgMeet)
            {
                if ( sx > sy )
                {
                    sx = sy;

                    xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx\
                           - lViewBoxXmin;
                }
                else //( sx < sy )
                {
                    sy = sx;

                    ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \
                           - lViewBoxYmin;
                }
            }
            else if (iMeetSlice == ENvgSlice)
            {
                if ( sx > sy )
                {
                    sy = sx;
                    ytrans = lViewPortHeight - sx*lViewBoxHeight;
                    ytrans = ytrans/sx - lViewBoxYmin;
                }
                else //( sx < sy )
                {
                    sx = sy;
                    xtrans = lViewPortWidth - sx*lViewBoxWidth;
                    xtrans = xtrans/sx - lViewBoxXmin;
                }
            }
            break;

        default:
            break;
        }
    vgScale( sx, sy);

    vgTranslate( xtrans, ytrans );

    }

 void CNvgFitToViewBoxImpl::Concatenate( TReal aM00, TReal aM01, TReal aM02, TReal aM10, TReal aM11, TReal aM12 )
    {
    TReal m0, m1;
    m0  = iM00;
    m1  = iM01;
    iM00 = aM00 * m0 + aM10 * m1;
    iM01 = aM01 * m0 + aM11 * m1;
    iM02 += aM02 * m0 + aM12 * m1;
    m0 = iM10;
    m1 = iM11;
    iM11 = aM01 * m0 + aM11 * m1;
    iM10 = aM00 * m0 + aM10 * m1;
    iM12 += aM02 * m0 + aM12 * m1;
    }
//--------------------------------EndOfFile------------------------------------