svgtopt/gfx2d/src/Gfxtrignometric.cpp
changeset 0 d46562c3d99d
equal deleted inserted replaced
-1:000000000000 0:d46562c3d99d
       
     1 /*
       
     2 * Copyright (c) 2002 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:  Graphics Extension Library source file
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 //File to implement functions to calculate trignomtric function
       
    22 
       
    23 #include "Gfxtrignometric.h"
       
    24 
       
    25 
       
    26  /*-------------------------------------------------------------------*/
       
    27 // --------------------------------------------------------------------------
       
    28 // TInt32 GfxMath::hgAbs32 (TInt32 a)
       
    29 // ---------------------------------------------------------------------------
       
    30 TInt32 GfxMath::hgAbs32 (TInt32 a)
       
    31 {
       
    32 
       
    33 	return (a >= 0) ? a : -a;
       
    34 }
       
    35 
       
    36 
       
    37 /*-------------------------------------------------------------------*//*!
       
    38  * \brief	Performs signed 32x32->64 multiplication, returns high 32 bits
       
    39  * \param	a	First 32-bit signed integer
       
    40  * \param	b	Second 32-bit signed integer
       
    41  * \return	((int64)(a)*b)>>32
       
    42  *//*-------------------------------------------------------------------*/
       
    43 
       
    44 // --------------------------------------------------------------------------
       
    45 // TInt32 GfxMath::hgLsl64h_0_31 (
       
    46 	// ---------------------------------------------------------------------------
       
    47 	TInt32 GfxMath::hgLsl64h_0_31 (
       
    48 							   // --------------------------------------------------------------------------
       
    49 							   // const GfxMath::TGfxInt64	a,
       
    50 							   // ---------------------------------------------------------------------------
       
    51 							   const GfxMath::TGfxInt64	a,
       
    52 							   TInt32			sh)
       
    53 {
       
    54 
       
    55 	return ((a.h << sh) | ((TUint32)(a.l) >> (32-sh)));
       
    56 }
       
    57 
       
    58 // --------------------------------------------------------------------------
       
    59 // GfxMath::TGfxInt64 GfxMath::hgSet64(TInt32 hh,TInt32 ll)
       
    60 // ---------------------------------------------------------------------------
       
    61 GfxMath::TGfxInt64 GfxMath::hgSet64(TInt32 hh,TInt32 ll)
       
    62 {
       
    63 	TGfxInt64 a;
       
    64 	a.l=ll;
       
    65 	a.h=hh;
       
    66 	return a;
       
    67 }
       
    68 
       
    69 
       
    70 // --------------------------------------------------------------------------
       
    71 // GfxMath::TGfxInt64 GfxMath::hgMul64 (
       
    72 	// ---------------------------------------------------------------------------
       
    73 	GfxMath::TGfxInt64 GfxMath::hgMul64 (
       
    74 	TInt32 a,
       
    75 	TInt32 b)
       
    76 {
       
    77 
       
    78 	TUint32 hh		= (TUint32)((a>>16)   *(b>>16));
       
    79 	TUint32 lh		= (TUint32)((a&0xFFFF)*(b>>16));
       
    80 	TUint32 hl		= (TUint32)((a>>16)   *(b&0xFFFF));
       
    81 	TUint32 ll		= (TUint32)((a&0xFFFF)*(b&0xFFFF));
       
    82 	TUint32 oldlo;
       
    83 
       
    84 	hh += (TInt32)(lh)>>16;
       
    85 	hh += (TInt32)(hl)>>16;
       
    86 
       
    87 	oldlo	=  ll;
       
    88 	ll		+= lh<<16;
       
    89 	if (ll < oldlo)
       
    90 		hh++;
       
    91 
       
    92 	oldlo	=  ll;
       
    93 	ll		+= hl<<16;
       
    94 	if (ll < oldlo)
       
    95 		hh++;
       
    96 
       
    97 	return hgSet64((TInt32)hh,(TInt32)ll);
       
    98 }
       
    99 
       
   100 
       
   101 // --------------------------------------------------------------------------
       
   102 // GfxMath::TGfxInt64 GfxMath::hgAdd64 (
       
   103 	// ---------------------------------------------------------------------------
       
   104 	GfxMath::TGfxInt64 GfxMath::hgAdd64 (
       
   105 	const TGfxInt64 a,
       
   106 	const TGfxInt64 b)
       
   107 {
       
   108 	TInt32 hi		= a.h+b.h;
       
   109 	TInt32 lo		= a.l+b.l;
       
   110 
       
   111 	hi += ((TUint32)(lo) < (TUint32)(a.l)) ? 1 : 0;
       
   112 	return hgSet64(hi, lo);
       
   113 }
       
   114 
       
   115 
       
   116 
       
   117 
       
   118 // --------------------------------------------------------------------------
       
   119 // GfxMath::TGfxInt64 GfxMath::hgMadd64 (
       
   120 	// ---------------------------------------------------------------------------
       
   121 	GfxMath::TGfxInt64 GfxMath::hgMadd64 (
       
   122 	 // --------------------------------------------------------------------------
       
   123 	 // GfxMath::TGfxInt64 a,
       
   124 	 // ---------------------------------------------------------------------------
       
   125 	 GfxMath::TGfxInt64 a,
       
   126 	TInt32 b,
       
   127 	TInt32 c)
       
   128 {
       
   129 
       
   130 	return hgAdd64(a,hgMul64(b,c));
       
   131 }
       
   132 
       
   133 
       
   134 
       
   135 
       
   136 /*-------------------------------------------------------------------*//*!
       
   137  * \brief	Performs unsigned 32x32->64 multiplication, returns high
       
   138  *			32 bits
       
   139  * \param	a	First 32-bit  unsigned integer
       
   140  * \param	b	Second 32-bit unsigned integer
       
   141  * \return	((unsigned int64)(a)*b)>>32
       
   142  *//*-------------------------------------------------------------------*/
       
   143  // --------------------------------------------------------------------------
       
   144  // TUint32 GfxMath::hgMulu64h (
       
   145 	 // ---------------------------------------------------------------------------
       
   146 	 TUint32 GfxMath::hgMulu64h (
       
   147 	TUint32 a,
       
   148 	TUint32 b)
       
   149 {
       
   150 
       
   151 	TUint32 hh = (a>>16)	* (b>>16);
       
   152 	TUint32 lh = (a&0xFFFF)* (b>>16);
       
   153 	TUint32 hl = (a>>16)	* (b&0xFFFFu);
       
   154 	TUint32 ll = (a&0xFFFF)* (b&0xFFFFu);
       
   155 	TUint32 oldlo;
       
   156 
       
   157 	hh += (lh>>16);
       
   158 	hh += (hl>>16);
       
   159 
       
   160 	oldlo = ll;
       
   161 	ll += lh<<16;
       
   162 	if (ll < oldlo)
       
   163 		hh++;
       
   164 
       
   165 	oldlo = ll;
       
   166 	ll += hl<<16;
       
   167 	if (ll < oldlo)
       
   168 		hh++;
       
   169 
       
   170 	return hh;
       
   171 }
       
   172 
       
   173 //-----------------------------------------------*/
       
   174 
       
   175 
       
   176  // --------------------------------------------------------------------------
       
   177  // GfxMath::TGfxInt64 GfxMath::hgMulu64 (
       
   178 	 // ---------------------------------------------------------------------------
       
   179 	 GfxMath::TGfxInt64 GfxMath::hgMulu64 (
       
   180 	TUint32 a,
       
   181 	TUint32 b)
       
   182 {
       
   183 
       
   184 	TUint32 hh = (a>>16)	* (b>>16);
       
   185 	TUint32 lh = (a&0xFFFF)* (b>>16);
       
   186 	TUint32 hl = (a>>16)	* (b&0xFFFFu);
       
   187 	TUint32 ll = (a&0xFFFF)* (b&0xFFFFu);
       
   188 	TUint32 oldlo;
       
   189 
       
   190 	hh += (lh>>16);
       
   191 	hh += (hl>>16);
       
   192 
       
   193 	oldlo = ll;
       
   194 	ll += lh<<16;
       
   195 	if (ll < oldlo)
       
   196 		hh++;
       
   197 
       
   198 	oldlo = ll;
       
   199 	ll += hl<<16;
       
   200 	if (ll < oldlo)
       
   201 		hh++;
       
   202 
       
   203 	return hgSet64((TInt32)(hh),(TInt32)(ll));
       
   204 }
       
   205 
       
   206 
       
   207 // --------------------------------------------------------------------------
       
   208 // TInt GfxMath::svgiRCos( TInt32 _x )
       
   209 // ---------------------------------------------------------------------------
       
   210 TInt GfxMath::svgiRCos( TInt32 _x )
       
   211 {
       
   212 	TUint32 fpi = 0x6487ED51;
       
   213 	TUint32 y;
       
   214 	TUint32 x = hgAbs32(_x);
       
   215 	y = x;
       
   216 
       
   217 	if(y > fpi>>1)
       
   218 		y = fpi-y;
       
   219 
       
   220 	y <<= 1;
       
   221 
       
   222 	/* Taylor series expansion around point x */
       
   223 	/* NOTE: to adjust approximation accuracy vs speed, remove or add iterations in pairs */
       
   224 	{
       
   225 		TUint32 t;
       
   226 		TGfxInt64 c  = hgMulu64(y,y<<1);
       
   227 		TInt32	x2 = hgLsl64h_0_31(c,1);
       
   228  		t = hgMulu64h(x2,x2);
       
   229 		c = hgMadd64(c, t,-(0x55555555>>1)-1);
       
   230 		t = hgMulu64h(t,x2);
       
   231 		c = hgMadd64(c, t, (0x5B05B05B>>4));
       
   232 		t = hgMulu64h(t,x2);
       
   233 		c = hgMadd64(c, t,-(0x68068068>>8)+1);
       
   234 		t = hgMulu64h(t,x2);
       
   235 		c = hgMadd64(c, t, (0x49F93EDD>>12)+1);
       
   236 		t = hgMulu64h(t,x2);
       
   237 		c = hgMadd64(c, t,-(0x47BB63BF>>17));
       
   238 		{
       
   239 			TInt32 r = c.h;
       
   240 			r = (0x40000000 - r)>>1;
       
   241 
       
   242 			if(x > (fpi>>1))
       
   243 				r =-r;
       
   244 
       
   245 			return r;
       
   246 		}
       
   247 	}
       
   248 }
       
   249 
       
   250 
       
   251 /*=======================================================================*/
       
   252 /*=======================================================================*/
       
   253 
       
   254 // --------------------------------------------------------------------------
       
   255 // TInt GfxMath::svgScalarSin( TInt r1 )
       
   256 // ---------------------------------------------------------------------------
       
   257 TInt GfxMath::svgScalarSin( TInt r1 )
       
   258 {
       
   259 	TInt32 foo;
       
   260 	r1 -= 0x6487ED51>>14;
       
   261 	foo = hgLsl64h_0_31(hgMul64(r1,0x517CC1B7),15);
       
   262 	foo = hgMulu64h(foo,0x6487ED51);
       
   263 	if( foo >= 0x6487ED51>>1 )
       
   264 		foo -= 0x6487ED51>>0;
       
   265 	return svgiRCos(foo<<1) >> 13;
       
   266 }
       
   267 
       
   268 /*=======================================================================*/
       
   269 /*=======================================================================*/
       
   270 
       
   271 // --------------------------------------------------------------------------
       
   272 // TInt GfxMath::svgScalarCos( TInt r1 )
       
   273 // ---------------------------------------------------------------------------
       
   274 TInt GfxMath::svgScalarCos( TInt r1 )
       
   275 {
       
   276 	TInt32 foo;
       
   277 	foo = hgLsl64h_0_31(hgMul64(r1,0x517CC1B7),15);
       
   278 	foo = hgMulu64h(foo,0x6487ED51);
       
   279 	if( foo >= 0x6487ED51>>1 )
       
   280 		foo -= 0x6487ED51>>0;
       
   281 	return svgiRCos(foo<<1) >> 13;
       
   282 }
       
   283 
       
   284 /*=======================================================================*/
       
   285 /*=======================================================================*/
       
   286 
       
   287 // --------------------------------------------------------------------------
       
   288 // TInt GfxMath::svgScalarTan( TInt r1 )
       
   289 // ---------------------------------------------------------------------------
       
   290 TInt GfxMath::svgScalarTan( TInt r1 )
       
   291 {
       
   292 	TInt lSin = svgScalarSin(r1);
       
   293 		if(!lSin)
       
   294 			return 0xffffffff; //highest value possible to indicate error
       
   295 	TInt lCos = svgScalarCos(r1);
       
   296 
       
   297 		if ( !lCos  )
       
   298 		{
       
   299 		return 0xffffffff;
       
   300 		}
       
   301 	return (((lSin << 15) / lCos)<<1);
       
   302 }