svgtopt/gfx2d/src/GfxImage/GfxImageTransformer.cpp
author hgs
Wed, 03 Nov 2010 18:56:10 +0200
changeset 46 88edb906c587
permissions -rw-r--r--
201044
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description:  Graphics Extension Library source file
hgs
parents:
diff changeset
    15
*
hgs
parents:
diff changeset
    16
*/
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
hgs
parents:
diff changeset
    19
#include "GfxImageTransformer.h"
hgs
parents:
diff changeset
    20
#include "GfxColor.h"
hgs
parents:
diff changeset
    21
hgs
parents:
diff changeset
    22
#define RGB565toRGB888(rgb565) (0xff000000|((rgb565 << 8) & 0xf80000) | ((rgb565 << 5) & 0x00fc00) | ((rgb565 << 3) & 0x000f8))
hgs
parents:
diff changeset
    23
hgs
parents:
diff changeset
    24
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
    25
// Constructor
hgs
parents:
diff changeset
    26
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
    27
// --------------------------------------------------------------------------
hgs
parents:
diff changeset
    28
//  TGfxImageTransformer::TGfxImageTransformer( TGfxAffineTransform* aTransform )
hgs
parents:
diff changeset
    29
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
    30
 TGfxImageTransformer::TGfxImageTransformer( TGfxAffineTransform* aTransform, CVGRenderer * aRenderer )
hgs
parents:
diff changeset
    31
    {
hgs
parents:
diff changeset
    32
    iTransform = aTransform;
hgs
parents:
diff changeset
    33
    iVgRenderer = aRenderer;
hgs
parents:
diff changeset
    34
	}
hgs
parents:
diff changeset
    35
hgs
parents:
diff changeset
    36
hgs
parents:
diff changeset
    37
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
// --------------------------------------------------------------------------
hgs
parents:
diff changeset
    40
//  void TGfxImageTransformer::ImageBlend( CFbsBitmap* aSrc,
hgs
parents:
diff changeset
    41
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
    42
 void TGfxImageTransformer::ImageBlend( CFbsBitmap* aSrc,
hgs
parents:
diff changeset
    43
                                          const TGfxPoint2D& aP,
hgs
parents:
diff changeset
    44
										  TInt aDstWidth,
hgs
parents:
diff changeset
    45
										  TInt aDstHeight,
hgs
parents:
diff changeset
    46
                                          const TRect& aClipRect,
hgs
parents:
diff changeset
    47
										  TBool aReverse)
hgs
parents:
diff changeset
    48
{
hgs
parents:
diff changeset
    49
hgs
parents:
diff changeset
    50
    TRect srcrect( TPoint( aP.iX, aP.iY ), aSrc->SizeInPixels() );
hgs
parents:
diff changeset
    51
    TRect dstrect( TPoint( 0, 0 ), TSize(aDstWidth, aDstHeight) );
hgs
parents:
diff changeset
    52
	TInt srcWidth = aSrc->SizeInPixels().iWidth;
hgs
parents:
diff changeset
    53
	TInt srcHeight = aSrc->SizeInPixels().iHeight;
hgs
parents:
diff changeset
    54
hgs
parents:
diff changeset
    55
    TGfxRectangle2D rect2d = GetTransformedBound( aSrc, aP );
hgs
parents:
diff changeset
    56
    TRect rect (TPoint( rect2d.iX, rect2d.iY ), TSize( rect2d.iWidth, rect2d.iHeight ) );
hgs
parents:
diff changeset
    57
	rect.Intersection(aClipRect);	// Clipping
hgs
parents:
diff changeset
    58
hgs
parents:
diff changeset
    59
    if ( !rect.Intersects( dstrect ) )    // clip rect with dst image
hgs
parents:
diff changeset
    60
        return;
hgs
parents:
diff changeset
    61
hgs
parents:
diff changeset
    62
    aSrc->LockHeap();
hgs
parents:
diff changeset
    63
    rect.Intersection( dstrect );
hgs
parents:
diff changeset
    64
hgs
parents:
diff changeset
    65
	TUint32* bufsrc32 = (TUint32*) aSrc->DataAddress();
hgs
parents:
diff changeset
    66
    TUint bufLimit = aDstWidth * aDstHeight;
hgs
parents:
diff changeset
    67
hgs
parents:
diff changeset
    68
    TGfxAffineTransform inv = iTransform->CreateInverse();
hgs
parents:
diff changeset
    69
hgs
parents:
diff changeset
    70
    TInt xstart, xend, yend;
hgs
parents:
diff changeset
    71
	TGfxPoint2D horizDeriv;
hgs
parents:
diff changeset
    72
	TGfxPoint2D origin, top, right, corner, east, west, south, north;
hgs
parents:
diff changeset
    73
hgs
parents:
diff changeset
    74
	// sort four corners into appropriate order
hgs
parents:
diff changeset
    75
	SortCoordinates(origin, top, north, south, right, east, west,
hgs
parents:
diff changeset
    76
	    corner, aP, srcWidth, srcHeight);
hgs
parents:
diff changeset
    77
hgs
parents:
diff changeset
    78
	// compute derivitives for scanline in source.
hgs
parents:
diff changeset
    79
    TPoint pinv;
hgs
parents:
diff changeset
    80
    TGfxPoint2D p;
hgs
parents:
diff changeset
    81
	p.iX = 8;
hgs
parents:
diff changeset
    82
	p.iY = 0;
hgs
parents:
diff changeset
    83
	inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
    84
	horizDeriv.iX = p.iX;
hgs
parents:
diff changeset
    85
	horizDeriv.iY = p.iY;
hgs
parents:
diff changeset
    86
	p.iX = 0;
hgs
parents:
diff changeset
    87
	p.iY = 0;
hgs
parents:
diff changeset
    88
	inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
    89
	horizDeriv.iX -= p.iX;
hgs
parents:
diff changeset
    90
	horizDeriv.iY -= p.iY;
hgs
parents:
diff changeset
    91
	horizDeriv.iX = horizDeriv.iX >> 3;
hgs
parents:
diff changeset
    92
	horizDeriv.iY = horizDeriv.iY >> 3;
hgs
parents:
diff changeset
    93
hgs
parents:
diff changeset
    94
    yend = rect.iBr.iY;
hgs
parents:
diff changeset
    95
    TInt bufLength = rect.iTl.iX + ( rect.iTl.iY * aDstWidth );
hgs
parents:
diff changeset
    96
	TInt tempBufLength = bufLength;
hgs
parents:
diff changeset
    97
hgs
parents:
diff changeset
    98
    TInt x, y;
hgs
parents:
diff changeset
    99
    TInt sx, sy;
hgs
parents:
diff changeset
   100
    TUint32 pixel;
hgs
parents:
diff changeset
   101
    TInt offset;
hgs
parents:
diff changeset
   102
    VGint stride = CFbsBitmap::ScanLineLength( aDstWidth, aSrc->DisplayMode() );
hgs
parents:
diff changeset
   103
    for ( y = rect.iTl.iY; y <= yend; y++ )
hgs
parents:
diff changeset
   104
        {
hgs
parents:
diff changeset
   105
        p.iY = y;
hgs
parents:
diff changeset
   106
		// compute scanline starting position
hgs
parents:
diff changeset
   107
		ComputeXPositions((TFloatFixPt)y, rect, north, west, east, south, xstart, xend);
hgs
parents:
diff changeset
   108
hgs
parents:
diff changeset
   109
		p.iX = xstart;
hgs
parents:
diff changeset
   110
		// transform that starting position to the source image
hgs
parents:
diff changeset
   111
		inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
   112
		bufLength += xstart - rect.iTl.iX;
hgs
parents:
diff changeset
   113
hgs
parents:
diff changeset
   114
	#ifdef SVG_FLOAT_BUILD
hgs
parents:
diff changeset
   115
	p.iY -= TFloatFixPt( .5f );
hgs
parents:
diff changeset
   116
	#else
hgs
parents:
diff changeset
   117
	p.iY -= TFloatFixPt(0x8000, ETrue);
hgs
parents:
diff changeset
   118
	#endif
hgs
parents:
diff changeset
   119
		for ( x = xstart; x <= xend; x++ )
hgs
parents:
diff changeset
   120
			{
hgs
parents:
diff changeset
   121
			//increment the location of the position by one horizontal location
hgs
parents:
diff changeset
   122
			pinv.iX = p.iX;
hgs
parents:
diff changeset
   123
			pinv.iY = p.iY;
hgs
parents:
diff changeset
   124
hgs
parents:
diff changeset
   125
			if ( srcrect.Contains( pinv ) )
hgs
parents:
diff changeset
   126
				{
hgs
parents:
diff changeset
   127
				pinv.iX -= ( TInt32 ) aP.iX;
hgs
parents:
diff changeset
   128
				pinv.iY -= ( TInt32 ) aP.iY;
hgs
parents:
diff changeset
   129
                // find out cooresponding x & y in OpenVG
hgs
parents:
diff changeset
   130
                offset = bufLength;
hgs
parents:
diff changeset
   131
                sy = aDstHeight - (offset / aDstWidth);
hgs
parents:
diff changeset
   132
                sx = offset % aDstWidth;
hgs
parents:
diff changeset
   133
                if (aReverse)
hgs
parents:
diff changeset
   134
                    {
hgs
parents:
diff changeset
   135
                    iVgRenderer->vgReadPixels((void *)&pixel, stride, VG_sRGBA_8888_PRE, sx, sy, 1, 1);
hgs
parents:
diff changeset
   136
    				*(bufsrc32 + ( TInt32 ) pinv.iX + (srcWidth)*( TInt32 ) (pinv.iY)) =
hgs
parents:
diff changeset
   137
    				    (pixel >> 8) | (pixel << 24) ;
hgs
parents:
diff changeset
   138
    				}
hgs
parents:
diff changeset
   139
    			else
hgs
parents:
diff changeset
   140
    			    {
hgs
parents:
diff changeset
   141
    			    pixel = *(bufsrc32 + ( TInt32 ) pinv.iX + (srcWidth)*( TInt32 ) (pinv.iY));
hgs
parents:
diff changeset
   142
    			    pixel = (pixel << 8) | (pixel >> 24);
hgs
parents:
diff changeset
   143
    			    iVgRenderer->vgWritePixels((void *)&pixel, stride, VG_sRGBA_8888_PRE, sx, sy, 1, 1);
hgs
parents:
diff changeset
   144
    			    }
hgs
parents:
diff changeset
   145
				}
hgs
parents:
diff changeset
   146
			p.iX += horizDeriv.iX;
hgs
parents:
diff changeset
   147
			p.iY += horizDeriv.iY;
hgs
parents:
diff changeset
   148
			bufLength++;
hgs
parents:
diff changeset
   149
			}
hgs
parents:
diff changeset
   150
		tempBufLength += aDstWidth;
hgs
parents:
diff changeset
   151
		bufLength = tempBufLength;
hgs
parents:
diff changeset
   152
		if (tempBufLength + aDstWidth >= bufLimit)
hgs
parents:
diff changeset
   153
            {
hgs
parents:
diff changeset
   154
            aSrc->UnlockHeap();
hgs
parents:
diff changeset
   155
            return;
hgs
parents:
diff changeset
   156
            }
hgs
parents:
diff changeset
   157
        }
hgs
parents:
diff changeset
   158
    aSrc->UnlockHeap();
hgs
parents:
diff changeset
   159
hgs
parents:
diff changeset
   160
    }
hgs
parents:
diff changeset
   161
hgs
parents:
diff changeset
   162
hgs
parents:
diff changeset
   163
hgs
parents:
diff changeset
   164
hgs
parents:
diff changeset
   165
hgs
parents:
diff changeset
   166
hgs
parents:
diff changeset
   167
// --------------------------------------------------------------------------
hgs
parents:
diff changeset
   168
//  void TGfxImageTransformer::SortCoordinates
hgs
parents:
diff changeset
   169
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
   170
hgs
parents:
diff changeset
   171
void TGfxImageTransformer::SortCoordinates(
hgs
parents:
diff changeset
   172
    TGfxPoint2D& origin, TGfxPoint2D& top,
hgs
parents:
diff changeset
   173
    TGfxPoint2D& north, TGfxPoint2D& south, TGfxPoint2D& right,
hgs
parents:
diff changeset
   174
    TGfxPoint2D& east, TGfxPoint2D& west, TGfxPoint2D& corner,
hgs
parents:
diff changeset
   175
    const TGfxPoint2D aP, const TInt srcWidth, const TInt srcHeight)
hgs
parents:
diff changeset
   176
    {
hgs
parents:
diff changeset
   177
hgs
parents:
diff changeset
   178
	origin.iX = aP.iX;
hgs
parents:
diff changeset
   179
	origin.iY = aP.iY;
hgs
parents:
diff changeset
   180
	corner.iX = aP.iX + (TFloatFixPt)srcWidth;
hgs
parents:
diff changeset
   181
	corner.iY = aP.iY + (TFloatFixPt)srcHeight;
hgs
parents:
diff changeset
   182
	top.iX =	aP.iX;
hgs
parents:
diff changeset
   183
	top.iY =	aP.iY + (TFloatFixPt)srcHeight;
hgs
parents:
diff changeset
   184
	right.iX =	aP.iX + (TFloatFixPt)srcWidth;
hgs
parents:
diff changeset
   185
	right.iY =	aP.iY;
hgs
parents:
diff changeset
   186
hgs
parents:
diff changeset
   187
	// transform corners of the source rectangle.
hgs
parents:
diff changeset
   188
    iTransform->Transform(&origin, &origin, 1);
hgs
parents:
diff changeset
   189
    iTransform->Transform(&top, &top, 1);
hgs
parents:
diff changeset
   190
    iTransform->Transform(&right, &right, 1);
hgs
parents:
diff changeset
   191
	iTransform->Transform(&corner, &corner, 1);
hgs
parents:
diff changeset
   192
hgs
parents:
diff changeset
   193
	west = origin; east = corner; north = top; south = right;
hgs
parents:
diff changeset
   194
	if (top.iX < origin.iX)
hgs
parents:
diff changeset
   195
	    {
hgs
parents:
diff changeset
   196
	    west = top;
hgs
parents:
diff changeset
   197
	    east = right;
hgs
parents:
diff changeset
   198
	    north = corner;
hgs
parents:
diff changeset
   199
	    south = origin;
hgs
parents:
diff changeset
   200
	    }
hgs
parents:
diff changeset
   201
	else
hgs
parents:
diff changeset
   202
	    {
hgs
parents:
diff changeset
   203
	    west = origin;
hgs
parents:
diff changeset
   204
	    east = corner;
hgs
parents:
diff changeset
   205
	    north = top;
hgs
parents:
diff changeset
   206
	    south = right;
hgs
parents:
diff changeset
   207
	    }
hgs
parents:
diff changeset
   208
hgs
parents:
diff changeset
   209
	if (corner.iX < west.iX)
hgs
parents:
diff changeset
   210
	    {
hgs
parents:
diff changeset
   211
	    west = corner;
hgs
parents:
diff changeset
   212
	    east = origin;
hgs
parents:
diff changeset
   213
	    north = right;
hgs
parents:
diff changeset
   214
	    south = top;
hgs
parents:
diff changeset
   215
	    }
hgs
parents:
diff changeset
   216
hgs
parents:
diff changeset
   217
	if (right.iX < west.iX)
hgs
parents:
diff changeset
   218
	    {
hgs
parents:
diff changeset
   219
	    west = right;
hgs
parents:
diff changeset
   220
	    east = top;
hgs
parents:
diff changeset
   221
	    north = origin;
hgs
parents:
diff changeset
   222
	    south = corner;
hgs
parents:
diff changeset
   223
	    }
hgs
parents:
diff changeset
   224
    }
hgs
parents:
diff changeset
   225
hgs
parents:
diff changeset
   226
hgs
parents:
diff changeset
   227
hgs
parents:
diff changeset
   228
hgs
parents:
diff changeset
   229
hgs
parents:
diff changeset
   230
// --------------------------------------------------------------------------
hgs
parents:
diff changeset
   231
//  void TGfxImageTransformer::ComputeXPositions
hgs
parents:
diff changeset
   232
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
   233
hgs
parents:
diff changeset
   234
void TGfxImageTransformer::ComputeXPositions(TFloatFixPt y, TRect rect,
hgs
parents:
diff changeset
   235
    TGfxPoint2D north, TGfxPoint2D west, TGfxPoint2D east,
hgs
parents:
diff changeset
   236
    TGfxPoint2D south, TInt& xstart, TInt& xend)
hgs
parents:
diff changeset
   237
    {
hgs
parents:
diff changeset
   238
hgs
parents:
diff changeset
   239
	if ( y > west.iY )
hgs
parents:
diff changeset
   240
	    {
hgs
parents:
diff changeset
   241
		if (north.iY - west.iY == (TFloatFixPt)0)
hgs
parents:
diff changeset
   242
			xstart = (TInt32) west.iX;
hgs
parents:
diff changeset
   243
		else
hgs
parents:
diff changeset
   244
			xstart = (TInt32) (west.iX + (north.iX - west.iX) *
hgs
parents:
diff changeset
   245
			    ( (y - west.iY) / (north.iY - west.iY) ));
hgs
parents:
diff changeset
   246
	    }
hgs
parents:
diff changeset
   247
	else
hgs
parents:
diff changeset
   248
	    {
hgs
parents:
diff changeset
   249
		if (west.iY - south.iY == (TFloatFixPt)0)
hgs
parents:
diff changeset
   250
			xstart = (TInt32) south.iX;
hgs
parents:
diff changeset
   251
		else
hgs
parents:
diff changeset
   252
			xstart = (TInt32) (south.iX + (west.iX - south.iX) *
hgs
parents:
diff changeset
   253
			    ( (y - south.iY) / (west.iY - south.iY) ));
hgs
parents:
diff changeset
   254
	    }
hgs
parents:
diff changeset
   255
hgs
parents:
diff changeset
   256
	// compute scanline edges end position
hgs
parents:
diff changeset
   257
	if ( y > east.iY )
hgs
parents:
diff changeset
   258
	    {
hgs
parents:
diff changeset
   259
		if ( north.iY - east.iY == (TFloatFixPt)0 )
hgs
parents:
diff changeset
   260
			xend = (TInt32) north.iX;
hgs
parents:
diff changeset
   261
		else
hgs
parents:
diff changeset
   262
			xend = (TInt32) (east.iX + (north.iX - east.iX) *
hgs
parents:
diff changeset
   263
			    ( (((TFloatFixPt)y) - east.iY) / (north.iY - east.iY) ));
hgs
parents:
diff changeset
   264
	    }
hgs
parents:
diff changeset
   265
	else
hgs
parents:
diff changeset
   266
	    {
hgs
parents:
diff changeset
   267
		if ( (east.iY - south.iY) == (TFloatFixPt)0 )
hgs
parents:
diff changeset
   268
			xend = (TInt32) east.iX;
hgs
parents:
diff changeset
   269
		else
hgs
parents:
diff changeset
   270
			xend = (TInt32) (south.iX + (east.iX - south.iX) *
hgs
parents:
diff changeset
   271
			    ( (((TFloatFixPt)y) - south.iY) / (east.iY - south.iY) ));
hgs
parents:
diff changeset
   272
	    }
hgs
parents:
diff changeset
   273
hgs
parents:
diff changeset
   274
    // does span clip against edges
hgs
parents:
diff changeset
   275
	if(xstart < rect.iTl.iX)
hgs
parents:
diff changeset
   276
		xstart = rect.iTl.iX;
hgs
parents:
diff changeset
   277
hgs
parents:
diff changeset
   278
	if(xend >= rect.iBr.iX)  // iX-1 seems to be the limit, using iX rolls over to next line
hgs
parents:
diff changeset
   279
		xend = rect.iBr.iX-1;
hgs
parents:
diff changeset
   280
    }
hgs
parents:
diff changeset
   281
hgs
parents:
diff changeset
   282
// --------------------------------------------------------------------------
hgs
parents:
diff changeset
   283
//  void TGfxImageTransformer::Draw( CFbsBitmap* aSrc,
hgs
parents:
diff changeset
   284
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
   285
 void TGfxImageTransformer::Draw( CFbsBitmap* aSrc,
hgs
parents:
diff changeset
   286
                                          const TGfxPoint2D& aP,
hgs
parents:
diff changeset
   287
										  TUint32* aDst,
hgs
parents:
diff changeset
   288
										  TInt aDstWidth,
hgs
parents:
diff changeset
   289
										  TInt aDstHeight,
hgs
parents:
diff changeset
   290
                                          TUint8 /*aAlpha*/,
hgs
parents:
diff changeset
   291
                                          TGfxColor aTransparentColor,
hgs
parents:
diff changeset
   292
										  const TRect& aClipRect,
hgs
parents:
diff changeset
   293
										  TBool aReverse
hgs
parents:
diff changeset
   294
										  )
hgs
parents:
diff changeset
   295
    {
hgs
parents:
diff changeset
   296
    TRect rect;
hgs
parents:
diff changeset
   297
    TInt32 x, y;
hgs
parents:
diff changeset
   298
hgs
parents:
diff changeset
   299
	TFloatFixPt currentScale = iTransform->ScalingFactor();
hgs
parents:
diff changeset
   300
		TSize bitmapSize = aSrc->SizeInPixels();
hgs
parents:
diff changeset
   301
    TRect srcrect( TPoint( aP.iX, aP.iY ),
hgs
parents:
diff changeset
   302
                   TSize( bitmapSize.iWidth-1, bitmapSize.iHeight-1 ) );
hgs
parents:
diff changeset
   303
    TRect dstrect( TPoint( 0, 0 ), TSize(aDstWidth-1, aDstHeight-1) );
hgs
parents:
diff changeset
   304
	  TInt32 srcWidth = bitmapSize.iWidth;
hgs
parents:
diff changeset
   305
	  TInt32 srcHeight = bitmapSize.iHeight;
hgs
parents:
diff changeset
   306
    TInt32 pad = (srcWidth & 1);
hgs
parents:
diff changeset
   307
hgs
parents:
diff changeset
   308
    TGfxRectangle2D rect2d = GetTransformedBound( aSrc, aP );
hgs
parents:
diff changeset
   309
    rect.SetRect( TPoint( rect2d.iX, rect2d.iY ), TSize( rect2d.iWidth, rect2d.iHeight ) );
hgs
parents:
diff changeset
   310
	rect.Intersection(aClipRect);	// Clipping
hgs
parents:
diff changeset
   311
hgs
parents:
diff changeset
   312
    if ( !rect.Intersects( dstrect ) )    // clip rect with dst image
hgs
parents:
diff changeset
   313
        return;
hgs
parents:
diff changeset
   314
hgs
parents:
diff changeset
   315
    aSrc->LockHeap();
hgs
parents:
diff changeset
   316
    rect.Intersection( dstrect );
hgs
parents:
diff changeset
   317
    TDisplayMode dispmode = aSrc->DisplayMode();
hgs
parents:
diff changeset
   318
hgs
parents:
diff changeset
   319
	TUint16* bufsrc16 = NULL;
hgs
parents:
diff changeset
   320
	TUint32* bufsrc32 = NULL;
hgs
parents:
diff changeset
   321
	if ( dispmode ==  EColor16MU)
hgs
parents:
diff changeset
   322
	    {
hgs
parents:
diff changeset
   323
	    bufsrc32 = (TUint32*) aSrc->DataAddress();
hgs
parents:
diff changeset
   324
	    }
hgs
parents:
diff changeset
   325
	else
hgs
parents:
diff changeset
   326
	    {
hgs
parents:
diff changeset
   327
	    bufsrc16 = (TUint16*) aSrc->DataAddress();
hgs
parents:
diff changeset
   328
	    }
hgs
parents:
diff changeset
   329
    TUint32* buf = aDst + rect.iTl.iX + ( rect.iTl.iY * aDstWidth );
hgs
parents:
diff changeset
   330
    TUint32* bufLimit = aDst + aDstWidth * aDstHeight;
hgs
parents:
diff changeset
   331
	TUint32 pix = 0;
hgs
parents:
diff changeset
   332
        TInt dstStride = aDstWidth;
hgs
parents:
diff changeset
   333
hgs
parents:
diff changeset
   334
    TGfxAffineTransform inv = iTransform->CreateInverse();
hgs
parents:
diff changeset
   335
hgs
parents:
diff changeset
   336
    if ( aTransparentColor.GetARGB() == KGfxColorNull /* && aAlpha == 0xff */ &&
hgs
parents:
diff changeset
   337
        (int)inv.TransformType() == KTransformIdentity && aReverse == EFalse)
hgs
parents:
diff changeset
   338
        {
hgs
parents:
diff changeset
   339
        // Fast case; no alpha or transform (cdm).
hgs
parents:
diff changeset
   340
        TPoint p;
hgs
parents:
diff changeset
   341
		TInt lScrPp = (srcWidth+pad);
hgs
parents:
diff changeset
   342
        for ( y = rect.iTl.iY; y <= rect.iBr.iY; y++ )
hgs
parents:
diff changeset
   343
            {
hgs
parents:
diff changeset
   344
            for ( x = rect.iTl.iX; x <= rect.iBr.iX; x++ )
hgs
parents:
diff changeset
   345
                {
hgs
parents:
diff changeset
   346
                p.iX = x;
hgs
parents:
diff changeset
   347
                p.iY = y;
hgs
parents:
diff changeset
   348
hgs
parents:
diff changeset
   349
                if ( srcrect.Contains( p ) )
hgs
parents:
diff changeset
   350
                    {
hgs
parents:
diff changeset
   351
                    p.iX -= ( TInt32 ) aP.iX;
hgs
parents:
diff changeset
   352
                    p.iY -= ( TInt32 ) aP.iY;
hgs
parents:
diff changeset
   353
					if ( dispmode ==  EColor16MU)
hgs
parents:
diff changeset
   354
					    {
hgs
parents:
diff changeset
   355
    					buf[x] = (TUint32) *(bufsrc32 + ( TInt32 ) p.iX + (lScrPp)*( TInt32 ) p.iY);
hgs
parents:
diff changeset
   356
    					*buf = pix;
hgs
parents:
diff changeset
   357
					    }
hgs
parents:
diff changeset
   358
					else
hgs
parents:
diff changeset
   359
					    {
hgs
parents:
diff changeset
   360
    					// src:RGB565 -> dst:ARGB8888
hgs
parents:
diff changeset
   361
    					pix = (TUint32) *(bufsrc16 + ( TInt32 ) p.iX + (lScrPp)*( TInt32 ) p.iY);
hgs
parents:
diff changeset
   362
    					buf[x] = RGB565toRGB888(pix);
hgs
parents:
diff changeset
   363
					    }
hgs
parents:
diff changeset
   364
                    }
hgs
parents:
diff changeset
   365
                }
hgs
parents:
diff changeset
   366
			buf += dstStride;
hgs
parents:
diff changeset
   367
			if (buf + dstStride >= bufLimit)
hgs
parents:
diff changeset
   368
                {
hgs
parents:
diff changeset
   369
                    aSrc->UnlockHeap();
hgs
parents:
diff changeset
   370
                    return;
hgs
parents:
diff changeset
   371
                }
hgs
parents:
diff changeset
   372
            }
hgs
parents:
diff changeset
   373
        }
hgs
parents:
diff changeset
   374
    else    // Alpha blending and/or transform is required.
hgs
parents:
diff changeset
   375
        {
hgs
parents:
diff changeset
   376
        TPoint pinv;
hgs
parents:
diff changeset
   377
        TGfxPoint2D p;
hgs
parents:
diff changeset
   378
hgs
parents:
diff changeset
   379
		TUint32* obuf = buf;
hgs
parents:
diff changeset
   380
		TInt32 xstart, xend, yend;
hgs
parents:
diff changeset
   381
		TGfxPoint2D horizDeriv;
hgs
parents:
diff changeset
   382
		TGfxPoint2D origin, top, right, corner;
hgs
parents:
diff changeset
   383
		TGfxPoint2D east, west, south, north;
hgs
parents:
diff changeset
   384
hgs
parents:
diff changeset
   385
		origin.iX = aP.iX;
hgs
parents:
diff changeset
   386
		origin.iY = aP.iY;
hgs
parents:
diff changeset
   387
		corner.iX = aP.iX + (TFloatFixPt)srcWidth;
hgs
parents:
diff changeset
   388
		corner.iY = aP.iY + (TFloatFixPt)srcHeight;
hgs
parents:
diff changeset
   389
		top.iX =	aP.iX;
hgs
parents:
diff changeset
   390
		top.iY =	aP.iY + (TFloatFixPt)srcHeight;
hgs
parents:
diff changeset
   391
		right.iX =	aP.iX + (TFloatFixPt)srcWidth;
hgs
parents:
diff changeset
   392
		right.iY =	aP.iY;
hgs
parents:
diff changeset
   393
hgs
parents:
diff changeset
   394
		// transform corners of the source rectangle.
hgs
parents:
diff changeset
   395
        iTransform->Transform(&origin, &origin, 1);
hgs
parents:
diff changeset
   396
        iTransform->Transform(&top, &top, 1);
hgs
parents:
diff changeset
   397
        iTransform->Transform(&right, &right, 1);
hgs
parents:
diff changeset
   398
		iTransform->Transform(&corner, &corner, 1);
hgs
parents:
diff changeset
   399
hgs
parents:
diff changeset
   400
		// sort four corners into appropriate order
hgs
parents:
diff changeset
   401
		west = origin; east = corner; north = top; south = right;
hgs
parents:
diff changeset
   402
		if (top.iX < origin.iX)
hgs
parents:
diff changeset
   403
		    {
hgs
parents:
diff changeset
   404
		    west = top;
hgs
parents:
diff changeset
   405
		    east = right;
hgs
parents:
diff changeset
   406
		    north = corner;
hgs
parents:
diff changeset
   407
		    south = origin;
hgs
parents:
diff changeset
   408
		    }
hgs
parents:
diff changeset
   409
		else
hgs
parents:
diff changeset
   410
		    {
hgs
parents:
diff changeset
   411
		    west = origin;
hgs
parents:
diff changeset
   412
		    east = corner;
hgs
parents:
diff changeset
   413
		    north = top;
hgs
parents:
diff changeset
   414
		    south = right;
hgs
parents:
diff changeset
   415
		    }
hgs
parents:
diff changeset
   416
hgs
parents:
diff changeset
   417
		if (corner.iX < west.iX)
hgs
parents:
diff changeset
   418
		    {
hgs
parents:
diff changeset
   419
		    west = corner;
hgs
parents:
diff changeset
   420
		    east = origin;
hgs
parents:
diff changeset
   421
		    north = right;
hgs
parents:
diff changeset
   422
		    south = top;
hgs
parents:
diff changeset
   423
		    }
hgs
parents:
diff changeset
   424
hgs
parents:
diff changeset
   425
		if (right.iX < west.iX)
hgs
parents:
diff changeset
   426
		    {
hgs
parents:
diff changeset
   427
		    west = right;
hgs
parents:
diff changeset
   428
		    east = top;
hgs
parents:
diff changeset
   429
		    north = origin;
hgs
parents:
diff changeset
   430
		    south = corner;
hgs
parents:
diff changeset
   431
		    }
hgs
parents:
diff changeset
   432
hgs
parents:
diff changeset
   433
		// compute derivitives for scanline in source.
hgs
parents:
diff changeset
   434
		p.iX = 1;
hgs
parents:
diff changeset
   435
		p.iY = 0;
hgs
parents:
diff changeset
   436
		inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
   437
		horizDeriv.iX = p.iX;
hgs
parents:
diff changeset
   438
		horizDeriv.iY = p.iY;
hgs
parents:
diff changeset
   439
		p.iX = 0;
hgs
parents:
diff changeset
   440
		p.iY = 0;
hgs
parents:
diff changeset
   441
		inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
   442
		horizDeriv.iX -= p.iX;
hgs
parents:
diff changeset
   443
		horizDeriv.iY -= p.iY;
hgs
parents:
diff changeset
   444
hgs
parents:
diff changeset
   445
        yend = rect.iBr.iY;
hgs
parents:
diff changeset
   446
        TInt lScrPp = 0;
hgs
parents:
diff changeset
   447
		if ( dispmode ==  EColor16MU)
hgs
parents:
diff changeset
   448
		    {
hgs
parents:
diff changeset
   449
			lScrPp = srcWidth;
hgs
parents:
diff changeset
   450
		    }
hgs
parents:
diff changeset
   451
		else
hgs
parents:
diff changeset
   452
			{
hgs
parents:
diff changeset
   453
			lScrPp = srcWidth+pad;
hgs
parents:
diff changeset
   454
			}
hgs
parents:
diff changeset
   455
hgs
parents:
diff changeset
   456
		TUint32 transparentColorRgb565 = aTransparentColor.ColorRgb565();
hgs
parents:
diff changeset
   457
hgs
parents:
diff changeset
   458
        for ( y = rect.iTl.iY; y <= yend; y++ )
hgs
parents:
diff changeset
   459
            {
hgs
parents:
diff changeset
   460
            p.iY = y;
hgs
parents:
diff changeset
   461
hgs
parents:
diff changeset
   462
			// compute scanline starting position
hgs
parents:
diff changeset
   463
hgs
parents:
diff changeset
   464
			if ( ((TFloatFixPt)y) > west.iY )
hgs
parents:
diff changeset
   465
			    {
hgs
parents:
diff changeset
   466
				if(north.iY - west.iY == (TFloatFixPt)0)
hgs
parents:
diff changeset
   467
					xstart = (TInt32) west.iX;
hgs
parents:
diff changeset
   468
				else
hgs
parents:
diff changeset
   469
					xstart = (TInt32) (west.iX + (north.iX - west.iX) * ( (((TFloatFixPt)y) - west.iY) / (north.iY - west.iY) ));
hgs
parents:
diff changeset
   470
			    }
hgs
parents:
diff changeset
   471
			else
hgs
parents:
diff changeset
   472
			    {
hgs
parents:
diff changeset
   473
				if(west.iY - south.iY == (TFloatFixPt)0)
hgs
parents:
diff changeset
   474
					xstart = (TInt32) south.iX;
hgs
parents:
diff changeset
   475
				else
hgs
parents:
diff changeset
   476
					xstart = (TInt32) (south.iX + (west.iX - south.iX) * ( (((TFloatFixPt)y) - south.iY) / (west.iY - south.iY) ));
hgs
parents:
diff changeset
   477
			    }
hgs
parents:
diff changeset
   478
hgs
parents:
diff changeset
   479
			// compute scanline edges end position
hgs
parents:
diff changeset
   480
			if ( (TFloatFixPt)y > east.iY )
hgs
parents:
diff changeset
   481
			    {
hgs
parents:
diff changeset
   482
				if(north.iY - east.iY == (TFloatFixPt)0)
hgs
parents:
diff changeset
   483
					xend = (TInt32) north.iX;
hgs
parents:
diff changeset
   484
				else
hgs
parents:
diff changeset
   485
					xend = (TInt32) (east.iX + (north.iX - east.iX) * ( (((TFloatFixPt)y) - east.iY) / (north.iY - east.iY) ));
hgs
parents:
diff changeset
   486
			    }
hgs
parents:
diff changeset
   487
			else
hgs
parents:
diff changeset
   488
			    {
hgs
parents:
diff changeset
   489
				if ( (east.iY - south.iY) == (TFloatFixPt)0 )
hgs
parents:
diff changeset
   490
					xend = (TInt32) east.iX;
hgs
parents:
diff changeset
   491
				else
hgs
parents:
diff changeset
   492
					xend = (TInt32) (south.iX + (east.iX - south.iX) * ( (((TFloatFixPt)y) - south.iY) / (east.iY - south.iY) ));
hgs
parents:
diff changeset
   493
			    }
hgs
parents:
diff changeset
   494
hgs
parents:
diff changeset
   495
		    // does span clip against edges
hgs
parents:
diff changeset
   496
			if(xstart < rect.iTl.iX)
hgs
parents:
diff changeset
   497
				xstart = rect.iTl.iX;
hgs
parents:
diff changeset
   498
hgs
parents:
diff changeset
   499
			if(xend >= rect.iBr.iX)  // iX-1 seems to be the limit, using iX rolls over to next line
hgs
parents:
diff changeset
   500
				xend = rect.iBr.iX-1;
hgs
parents:
diff changeset
   501
hgs
parents:
diff changeset
   502
			p.iX = xstart;
hgs
parents:
diff changeset
   503
			// transform that starting position to the source image
hgs
parents:
diff changeset
   504
			inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
   505
			buf += xstart-rect.iTl.iX;
hgs
parents:
diff changeset
   506
hgs
parents:
diff changeset
   507
			p.iY -= TFloatFixPt(.5f) * currentScale;
hgs
parents:
diff changeset
   508
hgs
parents:
diff changeset
   509
			if (aTransparentColor.GetARGB() == KGfxColorNull)
hgs
parents:
diff changeset
   510
				{
hgs
parents:
diff changeset
   511
					for ( x = xstart; x <= xend; x++ )
hgs
parents:
diff changeset
   512
    					{
hgs
parents:
diff changeset
   513
						//increment the location of the position by one horizontal location
hgs
parents:
diff changeset
   514
						pinv.iX = p.iX;
hgs
parents:
diff changeset
   515
						pinv.iY = p.iY;
hgs
parents:
diff changeset
   516
						if ( srcrect.Contains( pinv ) )
hgs
parents:
diff changeset
   517
						    {
hgs
parents:
diff changeset
   518
							pinv.iX -= ( TInt32 ) aP.iX;
hgs
parents:
diff changeset
   519
							pinv.iY -= ( TInt32 ) aP.iY;
hgs
parents:
diff changeset
   520
        					if ( dispmode == EColor16MU )
hgs
parents:
diff changeset
   521
        					    {
hgs
parents:
diff changeset
   522
                                *buf = (TUint32)*(bufsrc32 + ( TInt32 ) pinv.iX + (lScrPp)*( TInt32 ) (pinv.iY));
hgs
parents:
diff changeset
   523
        					    }
hgs
parents:
diff changeset
   524
        					else
hgs
parents:
diff changeset
   525
        					    {
hgs
parents:
diff changeset
   526
    							// src:RGB565 -> dst:ARGB8888
hgs
parents:
diff changeset
   527
    							pix = (TUint32)*(bufsrc16 + ( TInt32 ) pinv.iX + (lScrPp)*( TInt32 ) (pinv.iY));
hgs
parents:
diff changeset
   528
    							*buf = RGB565toRGB888(pix);
hgs
parents:
diff changeset
   529
    						    }
hgs
parents:
diff changeset
   530
						    }
hgs
parents:
diff changeset
   531
						p.iX += horizDeriv.iX;
hgs
parents:
diff changeset
   532
						p.iY += horizDeriv.iY;
hgs
parents:
diff changeset
   533
						buf++;
hgs
parents:
diff changeset
   534
					}
hgs
parents:
diff changeset
   535
				}
hgs
parents:
diff changeset
   536
			else
hgs
parents:
diff changeset
   537
				{
hgs
parents:
diff changeset
   538
				for ( x = xstart; x <= xend; x++ )
hgs
parents:
diff changeset
   539
					{
hgs
parents:
diff changeset
   540
					//increment the location of the position by one horizontal location
hgs
parents:
diff changeset
   541
					pinv.iX = p.iX;
hgs
parents:
diff changeset
   542
					pinv.iY = p.iY;
hgs
parents:
diff changeset
   543
hgs
parents:
diff changeset
   544
					if ( srcrect.Contains( pinv ) )
hgs
parents:
diff changeset
   545
						{
hgs
parents:
diff changeset
   546
						pinv.iX -= ( TInt32 ) aP.iX;
hgs
parents:
diff changeset
   547
						pinv.iY -= ( TInt32 ) aP.iY;
hgs
parents:
diff changeset
   548
hgs
parents:
diff changeset
   549
						if ( aReverse ) // copy source to destination. Used for Text blending with final framebufer.
hgs
parents:
diff changeset
   550
						    { // this used for text only
hgs
parents:
diff changeset
   551
        					if ( dispmode == EColor16MU )
hgs
parents:
diff changeset
   552
        					    {
hgs
parents:
diff changeset
   553
    							*(bufsrc32 + ( TInt32 ) pinv.iX + (lScrPp)*( TInt32 ) (pinv.iY)) = *buf ;
hgs
parents:
diff changeset
   554
    						    }
hgs
parents:
diff changeset
   555
    						else
hgs
parents:
diff changeset
   556
        					    {
hgs
parents:
diff changeset
   557
    							*(bufsrc16 + ( TInt32 ) pinv.iX + (lScrPp)*( TInt32 ) (pinv.iY)) = *buf ;
hgs
parents:
diff changeset
   558
    						    }
hgs
parents:
diff changeset
   559
						    }
hgs
parents:
diff changeset
   560
						else
hgs
parents:
diff changeset
   561
						    {
hgs
parents:
diff changeset
   562
        					if ( dispmode == EColor16MU )
hgs
parents:
diff changeset
   563
        					    {
hgs
parents:
diff changeset
   564
    							pix = (TUint32)*(bufsrc32 + ( TInt32 ) pinv.iX + (lScrPp)*( TInt32 ) (pinv.iY));
hgs
parents:
diff changeset
   565
						        if (pix != transparentColorRgb565)
hgs
parents:
diff changeset
   566
							        {
hgs
parents:
diff changeset
   567
							        *buf = pix;
hgs
parents:
diff changeset
   568
	                        	    }
hgs
parents:
diff changeset
   569
							    }
hgs
parents:
diff changeset
   570
							else
hgs
parents:
diff changeset
   571
        					    {
hgs
parents:
diff changeset
   572
    							pix = (TUint32) *(bufsrc16 + ( TInt32 ) pinv.iX + (lScrPp)*( TInt32 ) (pinv.iY));
hgs
parents:
diff changeset
   573
                                if (pix != transparentColorRgb565)
hgs
parents:
diff changeset
   574
                                    {
hgs
parents:
diff changeset
   575
								    *buf = RGB565toRGB888(pix);
hgs
parents:
diff changeset
   576
                                    }
hgs
parents:
diff changeset
   577
							    }
hgs
parents:
diff changeset
   578
							}
hgs
parents:
diff changeset
   579
						}
hgs
parents:
diff changeset
   580
					p.iX += horizDeriv.iX;
hgs
parents:
diff changeset
   581
					p.iY += horizDeriv.iY;
hgs
parents:
diff changeset
   582
					buf++;
hgs
parents:
diff changeset
   583
					}
hgs
parents:
diff changeset
   584
				}
hgs
parents:
diff changeset
   585
			buf = obuf+aDstWidth;
hgs
parents:
diff changeset
   586
			obuf += aDstWidth;
hgs
parents:
diff changeset
   587
			if (obuf + aDstWidth >= bufLimit)
hgs
parents:
diff changeset
   588
                {
hgs
parents:
diff changeset
   589
                aSrc->UnlockHeap();
hgs
parents:
diff changeset
   590
                return;
hgs
parents:
diff changeset
   591
                }
hgs
parents:
diff changeset
   592
            }
hgs
parents:
diff changeset
   593
        }
hgs
parents:
diff changeset
   594
hgs
parents:
diff changeset
   595
    aSrc->UnlockHeap();
hgs
parents:
diff changeset
   596
    }
hgs
parents:
diff changeset
   597
hgs
parents:
diff changeset
   598
// --------------------------------------------------------------------------
hgs
parents:
diff changeset
   599
//  void TGfxImageTransformer::Draw( CFbsBitmap* aSrc,
hgs
parents:
diff changeset
   600
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
   601
 void TGfxImageTransformer::Draw( CFbsBitmap* aSrc,
hgs
parents:
diff changeset
   602
                                          const TGfxPoint2D& aP,
hgs
parents:
diff changeset
   603
                                          TUint32* aDst,
hgs
parents:
diff changeset
   604
                                          TInt aDstWidth,
hgs
parents:
diff changeset
   605
                                          TInt aDstHeight,
hgs
parents:
diff changeset
   606
                                          const TRect& aClipRect
hgs
parents:
diff changeset
   607
                                          )
hgs
parents:
diff changeset
   608
    {
hgs
parents:
diff changeset
   609
    TDisplayMode dispmode = aSrc->DisplayMode();
hgs
parents:
diff changeset
   610
    if ( dispmode != EColor16MU )
hgs
parents:
diff changeset
   611
        {
hgs
parents:
diff changeset
   612
        return;
hgs
parents:
diff changeset
   613
        }
hgs
parents:
diff changeset
   614
hgs
parents:
diff changeset
   615
    TRect rect;
hgs
parents:
diff changeset
   616
    TInt32 x, y;
hgs
parents:
diff changeset
   617
hgs
parents:
diff changeset
   618
    TFloatFixPt currentScale = iTransform->ScalingFactor();
hgs
parents:
diff changeset
   619
hgs
parents:
diff changeset
   620
    TRect srcrect( TPoint( aP.iX, aP.iY ), aSrc->SizeInPixels() );
hgs
parents:
diff changeset
   621
    TRect dstrect( TPoint( 0, 0 ), TSize(aDstWidth, aDstHeight) );
hgs
parents:
diff changeset
   622
    TInt32 srcWidth = aSrc->SizeInPixels().iWidth;
hgs
parents:
diff changeset
   623
    TInt32 srcHeight = aSrc->SizeInPixels().iHeight;
hgs
parents:
diff changeset
   624
hgs
parents:
diff changeset
   625
    TGfxRectangle2D rect2d = GetTransformedBound( aSrc, aP );
hgs
parents:
diff changeset
   626
    rect.SetRect( TPoint( rect2d.iX, rect2d.iY ), TSize( rect2d.iWidth, rect2d.iHeight ) );
hgs
parents:
diff changeset
   627
    rect.Intersection(aClipRect);   // Clipping
hgs
parents:
diff changeset
   628
hgs
parents:
diff changeset
   629
    if ( !rect.Intersects( dstrect ) )    // clip rect with dst image
hgs
parents:
diff changeset
   630
        return;
hgs
parents:
diff changeset
   631
hgs
parents:
diff changeset
   632
    aSrc->LockHeap();
hgs
parents:
diff changeset
   633
    rect.Intersection( dstrect );
hgs
parents:
diff changeset
   634
hgs
parents:
diff changeset
   635
    TUint32* bufsrc32 = (TUint32*) aSrc->DataAddress();
hgs
parents:
diff changeset
   636
hgs
parents:
diff changeset
   637
    TUint32* buf = aDst + rect.iTl.iX + ( rect.iTl.iY * aDstWidth );
hgs
parents:
diff changeset
   638
    TUint32* bufLimit = aDst + aDstWidth * aDstHeight;
hgs
parents:
diff changeset
   639
    TUint32 pix = 0;
hgs
parents:
diff changeset
   640
hgs
parents:
diff changeset
   641
    TGfxAffineTransform inv = iTransform->CreateInverse();
hgs
parents:
diff changeset
   642
hgs
parents:
diff changeset
   643
        {
hgs
parents:
diff changeset
   644
        TPoint pinv;
hgs
parents:
diff changeset
   645
        TGfxPoint2D p;
hgs
parents:
diff changeset
   646
hgs
parents:
diff changeset
   647
        TUint32* obuf = buf;
hgs
parents:
diff changeset
   648
        TInt32 xstart, xend, yend;
hgs
parents:
diff changeset
   649
        TGfxPoint2D horizDeriv;
hgs
parents:
diff changeset
   650
        TGfxPoint2D origin, top, right, corner;
hgs
parents:
diff changeset
   651
        TGfxPoint2D east, west, south, north;
hgs
parents:
diff changeset
   652
hgs
parents:
diff changeset
   653
        origin.iX = aP.iX;
hgs
parents:
diff changeset
   654
        origin.iY = aP.iY;
hgs
parents:
diff changeset
   655
        corner.iX = aP.iX + (TFloatFixPt)srcWidth;
hgs
parents:
diff changeset
   656
        corner.iY = aP.iY + (TFloatFixPt)srcHeight;
hgs
parents:
diff changeset
   657
        top.iX =    aP.iX;
hgs
parents:
diff changeset
   658
        top.iY =    aP.iY + (TFloatFixPt)srcHeight;
hgs
parents:
diff changeset
   659
        right.iX =  aP.iX + (TFloatFixPt)srcWidth;
hgs
parents:
diff changeset
   660
        right.iY =  aP.iY;
hgs
parents:
diff changeset
   661
hgs
parents:
diff changeset
   662
        // transform corners of the source rectangle.
hgs
parents:
diff changeset
   663
        iTransform->Transform(&origin, &origin, 1);
hgs
parents:
diff changeset
   664
        iTransform->Transform(&top, &top, 1);
hgs
parents:
diff changeset
   665
        iTransform->Transform(&right, &right, 1);
hgs
parents:
diff changeset
   666
        iTransform->Transform(&corner, &corner, 1);
hgs
parents:
diff changeset
   667
hgs
parents:
diff changeset
   668
        // sort four corners into appropriate order
hgs
parents:
diff changeset
   669
        west = origin; east = corner; north = top; south = right;
hgs
parents:
diff changeset
   670
        if (top.iX < origin.iX)
hgs
parents:
diff changeset
   671
            {
hgs
parents:
diff changeset
   672
            west = top;
hgs
parents:
diff changeset
   673
            east = right;
hgs
parents:
diff changeset
   674
            north = corner;
hgs
parents:
diff changeset
   675
            south = origin;
hgs
parents:
diff changeset
   676
            }
hgs
parents:
diff changeset
   677
        else
hgs
parents:
diff changeset
   678
            {
hgs
parents:
diff changeset
   679
            west = origin;
hgs
parents:
diff changeset
   680
            east = corner;
hgs
parents:
diff changeset
   681
            north = top;
hgs
parents:
diff changeset
   682
            south = right;
hgs
parents:
diff changeset
   683
            }
hgs
parents:
diff changeset
   684
hgs
parents:
diff changeset
   685
        if (corner.iX < west.iX)
hgs
parents:
diff changeset
   686
            {
hgs
parents:
diff changeset
   687
            west = corner;
hgs
parents:
diff changeset
   688
            east = origin;
hgs
parents:
diff changeset
   689
            north = right;
hgs
parents:
diff changeset
   690
            south = top;
hgs
parents:
diff changeset
   691
            }
hgs
parents:
diff changeset
   692
hgs
parents:
diff changeset
   693
        if (right.iX < west.iX)
hgs
parents:
diff changeset
   694
            {
hgs
parents:
diff changeset
   695
            west = right;
hgs
parents:
diff changeset
   696
            east = top;
hgs
parents:
diff changeset
   697
            north = origin;
hgs
parents:
diff changeset
   698
            south = corner;
hgs
parents:
diff changeset
   699
            }
hgs
parents:
diff changeset
   700
hgs
parents:
diff changeset
   701
        // compute derivitives for scanline in source.
hgs
parents:
diff changeset
   702
        p.iX = 8;
hgs
parents:
diff changeset
   703
        p.iY = 0;
hgs
parents:
diff changeset
   704
        inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
   705
        horizDeriv.iX = p.iX;
hgs
parents:
diff changeset
   706
        horizDeriv.iY = p.iY;
hgs
parents:
diff changeset
   707
        p.iX = 0;
hgs
parents:
diff changeset
   708
        p.iY = 0;
hgs
parents:
diff changeset
   709
        inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
   710
        horizDeriv.iX -= p.iX;
hgs
parents:
diff changeset
   711
        horizDeriv.iY -= p.iY;
hgs
parents:
diff changeset
   712
        horizDeriv.iX = horizDeriv.iX >> 3;
hgs
parents:
diff changeset
   713
        horizDeriv.iY = horizDeriv.iY >> 3;
hgs
parents:
diff changeset
   714
hgs
parents:
diff changeset
   715
        yend = rect.iBr.iY;
hgs
parents:
diff changeset
   716
        TInt lScrPp = 0;
hgs
parents:
diff changeset
   717
        lScrPp = srcWidth;
hgs
parents:
diff changeset
   718
hgs
parents:
diff changeset
   719
hgs
parents:
diff changeset
   720
        for ( y = rect.iTl.iY; y <= yend; y++ )
hgs
parents:
diff changeset
   721
            {
hgs
parents:
diff changeset
   722
            p.iY = y;
hgs
parents:
diff changeset
   723
hgs
parents:
diff changeset
   724
            // compute scanline starting position
hgs
parents:
diff changeset
   725
hgs
parents:
diff changeset
   726
            if ( ((TFloatFixPt)y) > west.iY )
hgs
parents:
diff changeset
   727
                {
hgs
parents:
diff changeset
   728
                if(north.iY - west.iY == (TFloatFixPt)0)
hgs
parents:
diff changeset
   729
                    xstart = (TInt32) west.iX;
hgs
parents:
diff changeset
   730
                else
hgs
parents:
diff changeset
   731
                    xstart = (TInt32) (west.iX + (north.iX - west.iX) * ( (((TFloatFixPt)y) - west.iY) / (north.iY - west.iY) ));
hgs
parents:
diff changeset
   732
                }
hgs
parents:
diff changeset
   733
            else
hgs
parents:
diff changeset
   734
                {
hgs
parents:
diff changeset
   735
                if(west.iY - south.iY == (TFloatFixPt)0)
hgs
parents:
diff changeset
   736
                    xstart = (TInt32) south.iX;
hgs
parents:
diff changeset
   737
                else
hgs
parents:
diff changeset
   738
                    xstart = (TInt32) (south.iX + (west.iX - south.iX) * ( (((TFloatFixPt)y) - south.iY) / (west.iY - south.iY) ));
hgs
parents:
diff changeset
   739
                }
hgs
parents:
diff changeset
   740
hgs
parents:
diff changeset
   741
            // compute scanline edges end position
hgs
parents:
diff changeset
   742
            if ( (TFloatFixPt)y > east.iY )
hgs
parents:
diff changeset
   743
                {
hgs
parents:
diff changeset
   744
                if(north.iY - east.iY == (TFloatFixPt)0)
hgs
parents:
diff changeset
   745
                    xend = (TInt32) north.iX;
hgs
parents:
diff changeset
   746
                else
hgs
parents:
diff changeset
   747
                    xend = (TInt32) (east.iX + (north.iX - east.iX) * ( (((TFloatFixPt)y) - east.iY) / (north.iY - east.iY) ));
hgs
parents:
diff changeset
   748
                }
hgs
parents:
diff changeset
   749
            else
hgs
parents:
diff changeset
   750
                {
hgs
parents:
diff changeset
   751
                if ( (east.iY - south.iY) == (TFloatFixPt)0 )
hgs
parents:
diff changeset
   752
                    xend = (TInt32) east.iX;
hgs
parents:
diff changeset
   753
                else
hgs
parents:
diff changeset
   754
                    xend = (TInt32) (south.iX + (east.iX - south.iX) * ( (((TFloatFixPt)y) - south.iY) / (east.iY - south.iY) ));
hgs
parents:
diff changeset
   755
                }
hgs
parents:
diff changeset
   756
hgs
parents:
diff changeset
   757
            // does span clip against edges
hgs
parents:
diff changeset
   758
            if(xstart < rect.iTl.iX)
hgs
parents:
diff changeset
   759
                xstart = rect.iTl.iX;
hgs
parents:
diff changeset
   760
hgs
parents:
diff changeset
   761
            if(xend >= rect.iBr.iX)  // iX-1 seems to be the limit, using iX rolls over to next line
hgs
parents:
diff changeset
   762
                xend = rect.iBr.iX-1;
hgs
parents:
diff changeset
   763
hgs
parents:
diff changeset
   764
            p.iX = xstart;
hgs
parents:
diff changeset
   765
            // transform that starting position to the source image
hgs
parents:
diff changeset
   766
            inv.Transform( &p, & p, 1 );
hgs
parents:
diff changeset
   767
            buf += xstart-rect.iTl.iX;
hgs
parents:
diff changeset
   768
            // Change here
hgs
parents:
diff changeset
   769
            p.iY -= TFloatFixPt(0.5f) * currentScale;
hgs
parents:
diff changeset
   770
hgs
parents:
diff changeset
   771
                {
hgs
parents:
diff changeset
   772
                    for ( x = xstart; x <= xend; x++ )
hgs
parents:
diff changeset
   773
                        {
hgs
parents:
diff changeset
   774
                        //increment the location of the position by one horizontal location
hgs
parents:
diff changeset
   775
                        pinv.iX = p.iX;
hgs
parents:
diff changeset
   776
                        pinv.iY = p.iY;
hgs
parents:
diff changeset
   777
                        if ( srcrect.Contains( pinv ) )
hgs
parents:
diff changeset
   778
                            {
hgs
parents:
diff changeset
   779
                            pinv.iX -= ( TInt32 ) aP.iX;
hgs
parents:
diff changeset
   780
                            pinv.iY -= ( TInt32 ) aP.iY;
hgs
parents:
diff changeset
   781
hgs
parents:
diff changeset
   782
                            pix = (TUint32)*(bufsrc32 + ( TInt32 ) pinv.iX + (lScrPp)*( TInt32 ) (pinv.iY));
hgs
parents:
diff changeset
   783
                            TUint srcAlpha = ( pix & 0xFF000000 ) >> 24;
hgs
parents:
diff changeset
   784
                            if ( srcAlpha == 0xFF )
hgs
parents:
diff changeset
   785
                                {
hgs
parents:
diff changeset
   786
                                *buf = pix;
hgs
parents:
diff changeset
   787
                                }
hgs
parents:
diff changeset
   788
                            else if ( srcAlpha > 0 )
hgs
parents:
diff changeset
   789
                                {
hgs
parents:
diff changeset
   790
                                TUint destPix = *buf;
hgs
parents:
diff changeset
   791
                                TUint destAlpha = ( destPix & 0xFF000000 ) >> 24;
hgs
parents:
diff changeset
   792
                                // Blending needed: blend with background as opaque
hgs
parents:
diff changeset
   793
                                if ( destAlpha == 0xFF )
hgs
parents:
diff changeset
   794
                                    {
hgs
parents:
diff changeset
   795
                                    TReal32 alpha = 0.0039215686 * srcAlpha; // 0.0039.. = 1/255
hgs
parents:
diff changeset
   796
                                    TReal32 inverseAlpha = 1.0f - alpha;
hgs
parents:
diff changeset
   797
                                    *buf = ((((TUint)((pix     >> 16 & 0xff) * alpha) +
hgs
parents:
diff changeset
   798
                                              (TUint)((destPix >> 16 & 0xff) * inverseAlpha))) << 16) | // red
hgs
parents:
diff changeset
   799
                                           ((((TUint)((pix     >> 8  & 0xff) * alpha) +
hgs
parents:
diff changeset
   800
                                              (TUint)((destPix >> 8  & 0xff) * inverseAlpha))) << 8 ) | // green
hgs
parents:
diff changeset
   801
                                           ((((TUint)((pix           & 0xff) * alpha) +
hgs
parents:
diff changeset
   802
                                              (TUint)((destPix       & 0xff) * inverseAlpha)))      ) | // blue
hgs
parents:
diff changeset
   803
                                              (0xFF000000);                                             // full alpha (already blended)
hgs
parents:
diff changeset
   804
                                    }
hgs
parents:
diff changeset
   805
                                // Apply alpha to each color channel of source only
hgs
parents:
diff changeset
   806
                                // Important: use original alpha
hgs
parents:
diff changeset
   807
                                else
hgs
parents:
diff changeset
   808
                                    {
hgs
parents:
diff changeset
   809
                                    TReal32 alpha = 0.0039215686 * srcAlpha;
hgs
parents:
diff changeset
   810
                                    *buf = (srcAlpha << 24)|
hgs
parents:
diff changeset
   811
                                           ((TUint)((pix >> 16 & 0xff) * alpha) << 16) |
hgs
parents:
diff changeset
   812
                                           ((TUint)((pix     >> 8 & 0xff) * alpha) << 8) |
hgs
parents:
diff changeset
   813
                                           ((TUint)((pix & 0xff) * alpha));
hgs
parents:
diff changeset
   814
                                    }
hgs
parents:
diff changeset
   815
                                }
hgs
parents:
diff changeset
   816
                            }
hgs
parents:
diff changeset
   817
                        p.iX += horizDeriv.iX;
hgs
parents:
diff changeset
   818
                        p.iY += horizDeriv.iY;
hgs
parents:
diff changeset
   819
                        buf++;
hgs
parents:
diff changeset
   820
                    }
hgs
parents:
diff changeset
   821
                }
hgs
parents:
diff changeset
   822
hgs
parents:
diff changeset
   823
            buf = obuf+aDstWidth;
hgs
parents:
diff changeset
   824
            obuf += aDstWidth;
hgs
parents:
diff changeset
   825
            if (obuf + aDstWidth >= bufLimit)
hgs
parents:
diff changeset
   826
                {
hgs
parents:
diff changeset
   827
                aSrc->UnlockHeap();
hgs
parents:
diff changeset
   828
                return;
hgs
parents:
diff changeset
   829
                }
hgs
parents:
diff changeset
   830
            }
hgs
parents:
diff changeset
   831
        }
hgs
parents:
diff changeset
   832
hgs
parents:
diff changeset
   833
    aSrc->UnlockHeap();
hgs
parents:
diff changeset
   834
    }
hgs
parents:
diff changeset
   835
hgs
parents:
diff changeset
   836
//  TGfxRectangle2D TGfxImageTransformer::GetTransformedBound( CFbsBitmap* aSrc,
hgs
parents:
diff changeset
   837
// ---------------------------------------------------------------------------
hgs
parents:
diff changeset
   838
 TGfxRectangle2D TGfxImageTransformer::GetTransformedBound( CFbsBitmap* aSrc,
hgs
parents:
diff changeset
   839
                                                                    const TGfxPoint2D& aOffset )
hgs
parents:
diff changeset
   840
    {
hgs
parents:
diff changeset
   841
    TGfxRectangle2D rect;
hgs
parents:
diff changeset
   842
    TGfxPoint2D rectp[4];
hgs
parents:
diff changeset
   843
hgs
parents:
diff changeset
   844
    rectp[0].iX = aOffset.iX;
hgs
parents:
diff changeset
   845
    rectp[0].iY = aOffset.iY;
hgs
parents:
diff changeset
   846
    rectp[1].iX = aOffset.iX + ( TFloatFixPt ) aSrc->SizeInPixels().iWidth;
hgs
parents:
diff changeset
   847
    rectp[1].iY = aOffset.iY;
hgs
parents:
diff changeset
   848
    rectp[2].iX = aOffset.iX + ( TFloatFixPt ) aSrc->SizeInPixels().iWidth;
hgs
parents:
diff changeset
   849
    rectp[2].iY = aOffset.iY + ( TFloatFixPt ) aSrc->SizeInPixels().iHeight;
hgs
parents:
diff changeset
   850
    rectp[3].iX = aOffset.iX;
hgs
parents:
diff changeset
   851
    rectp[3].iY = aOffset.iY + ( TFloatFixPt ) aSrc->SizeInPixels().iHeight;
hgs
parents:
diff changeset
   852
    iTransform->Transform( rectp, rectp, 4 );
hgs
parents:
diff changeset
   853
hgs
parents:
diff changeset
   854
    TInt32 i;
hgs
parents:
diff changeset
   855
    //MinX
hgs
parents:
diff changeset
   856
    rect.iX = rectp[0].iX;
hgs
parents:
diff changeset
   857
    rect.iY = rectp[0].iY;
hgs
parents:
diff changeset
   858
    rect.iWidth = rectp[0].iX;
hgs
parents:
diff changeset
   859
    rect.iHeight = rectp[0].iY;
hgs
parents:
diff changeset
   860
hgs
parents:
diff changeset
   861
    for ( i = 1; i < 4; i++ )
hgs
parents:
diff changeset
   862
	    {
hgs
parents:
diff changeset
   863
        if ( rectp[i].iX < rect.iX )
hgs
parents:
diff changeset
   864
            rect.iX = rectp[i].iX;
hgs
parents:
diff changeset
   865
    //MinY
hgs
parents:
diff changeset
   866
        if ( rectp[i].iY < rect.iY )
hgs
parents:
diff changeset
   867
            rect.iY = rectp[i].iY;
hgs
parents:
diff changeset
   868
    //MaxX -> width
hgs
parents:
diff changeset
   869
        if ( rectp[i].iX > rect.iWidth )
hgs
parents:
diff changeset
   870
            rect.iWidth = rectp[i].iX;
hgs
parents:
diff changeset
   871
    //MaxY -> height
hgs
parents:
diff changeset
   872
        if ( rectp[i].iY > rect.iHeight )
hgs
parents:
diff changeset
   873
            rect.iHeight = rectp[i].iY;
hgs
parents:
diff changeset
   874
    	}
hgs
parents:
diff changeset
   875
    rect.iWidth -= rect.iX;
hgs
parents:
diff changeset
   876
    rect.iHeight -= rect.iY;
hgs
parents:
diff changeset
   877
hgs
parents:
diff changeset
   878
    return rect;
hgs
parents:
diff changeset
   879
    }
hgs
parents:
diff changeset
   880