imageeditorengine/filters/FilterText/src/CFilterText.cpp
changeset 1 edfc90759b9f
equal deleted inserted replaced
0:57d4cdd99204 1:edfc90759b9f
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "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 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include "CFilterText.h"
       
    22 #include <txtetext.h>
       
    23 #include <fbs.h>
       
    24 #include <bitdev.h>
       
    25 #include <e32math.h>
       
    26 #include <AknBidiTextUtils.h>
       
    27 #include "CFbsBitmapHack.h"
       
    28 
       
    29 const TInt KScaleBits = 12;
       
    30 const TInt KCoordBits = 8;
       
    31 
       
    32 EXPORT_C TInt CFilterText::Create()
       
    33 	{
       
    34 	CFilterText* ptr = NULL;
       
    35 	TRAPD( error, ptr = NewL(); );
       
    36 	if( error != KErrNone )
       
    37 		{
       
    38 		ptr = NULL;
       
    39 		}
       
    40 	return (TInt)((MImageFilter*)ptr);
       
    41 	}
       
    42 
       
    43 
       
    44 
       
    45 CFilterText* CFilterText::NewL()
       
    46 	{
       
    47 	CFilterText* self = new( ELeave )CFilterText();
       
    48 	CleanupStack::PushL( self );
       
    49 	self->ConstructL();
       
    50 	CleanupStack::Pop( self );
       
    51 	return self;
       
    52 	}
       
    53 
       
    54 
       
    55 
       
    56 CFilterText::~CFilterText()
       
    57 	{
       
    58 	delete[] iData;
       
    59 	iFont = NULL;
       
    60 	}
       
    61 
       
    62 
       
    63 
       
    64 CFilterText::CFilterText()
       
    65 	{
       
    66 
       
    67 	}
       
    68 
       
    69 
       
    70 
       
    71 void CFilterText::ConstructL()
       
    72 	{
       
    73 	iScale.iX = 1 << 8;
       
    74 	iScale.iY = 0;
       
    75 	iZoom = 1000;
       
    76 	iAngle = 0;
       
    77 	iColor = 0xFFFFFF;
       
    78 	}
       
    79 
       
    80 
       
    81 
       
    82 TRect CFilterText::Rect()
       
    83 	{
       
    84 	return iChild->Rect();
       
    85 	}
       
    86 
       
    87 TReal CFilterText::Scale()
       
    88 	{
       
    89 	return iChild->Scale();
       
    90 	}
       
    91 
       
    92 TSize CFilterText::ViewPortSize()
       
    93 {
       
    94     return iChild->ViewPortSize();
       
    95 }
       
    96 
       
    97 
       
    98 TBlock * CFilterText::GetBlockL ( const TRect & aRect )
       
    99 {
       
   100     TBlock * pB = iChild->GetBlockL (aRect);
       
   101     if (!pB) return NULL;
       
   102     TUint32 * pD = pB->iData;
       
   103     for (TInt i = pB->iRect.iTl.iY; i < pB->iRect.iBr.iY; ++i)
       
   104     {
       
   105         for (TInt j = pB->iRect.iTl.iX; j < pB->iRect.iBr.iX; ++j, ++pD)
       
   106         {
       
   107 
       
   108 	        TUint32 c = *pD;
       
   109 	        
       
   110 	        TPoint pos = iCorrectPosition + TPoint (j << KCoordBits, i << KCoordBits);
       
   111 	        TInt x = (pos.iX * iScale.iX + pos.iY * iScale.iY) >> (KScaleBits + KCoordBits);
       
   112 	        TInt y = (pos.iY * iScale.iX - pos.iX * iScale.iY) >> (KScaleBits + KCoordBits);
       
   113 
       
   114 	        if ( (x >= 0) && (y >= 0) && (x < iSize.iWidth) && (y < iSize.iHeight) )
       
   115             {
       
   116 		        TUint32 c2 = iData [x + y * iSize.iWidth];
       
   117 		        TInt ca = c2 >> 24;
       
   118 		        c2 &= iColor;
       
   119 		        if( ca == 255 )
       
   120                 {
       
   121 			        *pD = c2 & 0xffffff;
       
   122 			    }
       
   123 		        else 
       
   124                 {
       
   125 		            TInt cc1 = ( c2 & 0xff00ff ) * ca + ( c & 0xff00ff ) * ( 255-ca );
       
   126 		            TInt cc2 = ( c2 & 0xff00 ) * ca + ( c & 0xff00 ) * ( 255-ca );
       
   127 		            *pD =  ( ( cc1 >> 8 ) & 0xff00ff ) + ( ( cc2 >> 8 ) & 0xff00 );
       
   128                 }
       
   129             }
       
   130         }
       
   131     }
       
   132     return pB;
       
   133 }
       
   134 
       
   135 
       
   136 void CFilterText::SetParent( MImageFilter* aParent )
       
   137 	{
       
   138 	iParent = aParent;
       
   139 	}
       
   140 
       
   141 
       
   142 
       
   143 
       
   144 void CFilterText::SetChild( MImageFilter* aChild )
       
   145 	{
       
   146 	iChild = aChild;
       
   147 	}
       
   148 
       
   149 
       
   150 
       
   151 TInt CFilterText::CmdL( const TDesC16& aCmd )
       
   152 	{
       
   153 	TLex lex( aCmd );
       
   154 
       
   155 	TInt red = iColor >> 16;
       
   156 	TInt green = ( iColor >> 8 ) & 255;
       
   157 	TInt blue = iColor & 255;
       
   158 
       
   159     while( ! lex.Eos() )
       
   160 		{
       
   161 		TPtrC token = lex.NextToken();
       
   162 		if( token.Compare( _L("x") ) == 0 )
       
   163 			{
       
   164             TReal relscale = iChild->Scale();
       
   165             TInt param = 0;
       
   166 			lex.Inc ();
       
   167 			lex.Val (param);
       
   168             iPosition.iX = (TInt)((param / relscale) + 0.5);
       
   169 			}
       
   170 		else if( token.Compare( _L("y") ) == 0 )
       
   171 			{
       
   172             TReal relscale = iChild->Scale();
       
   173             TInt param = 0;
       
   174 			lex.Inc ();
       
   175 			lex.Val (param);
       
   176             iPosition.iY = (TInt)((param / relscale) + 0.5);
       
   177 			}
       
   178 		else if( token.Compare( _L("zoom") ) == 0 )
       
   179 			{
       
   180 			lex.Inc();
       
   181 			lex.Val( iZoom );
       
   182 			}
       
   183 		else if( token.Compare( _L("angle") ) == 0 )
       
   184 			{
       
   185 			lex.Inc();
       
   186 			lex.Val( iAngle );
       
   187 			}
       
   188 		else if( token.Compare( _L("width") ) == 0 )
       
   189 			{
       
   190             TReal relscale = iChild->Scale();
       
   191             TInt param = 0;
       
   192 			lex.Inc ();
       
   193 			lex.Val (param);
       
   194             TInt width = (TInt)((param / relscale) + 0.5);
       
   195             iZoom = (width * 1000) / iSize.iWidth;
       
   196 			}
       
   197 		else if( token.Compare( _L("height") ) == 0 )
       
   198 			{
       
   199             TReal relscale = iChild->Scale();
       
   200             TInt param = 0;
       
   201 			lex.Inc ();
       
   202 			lex.Val (param);
       
   203             TInt height = (TInt)((param / relscale) + 0.5);
       
   204             iZoom = (height * 1000) / iSize.iHeight;
       
   205 			}
       
   206 		else if( token.Compare( _L("red") ) == 0 )
       
   207 			{
       
   208 			lex.Inc();
       
   209 			lex.Val( red );
       
   210 			}
       
   211 		else if( token.Compare( _L("green") ) == 0 )
       
   212 			{
       
   213 			lex.Inc();
       
   214 			lex.Val( green );
       
   215 			}
       
   216 		else if( token.Compare( _L("blue") ) == 0 )
       
   217 			{
       
   218 			lex.Inc();
       
   219 			lex.Val( blue );
       
   220 			}
       
   221 		else if( token.Compare( _L("textwidth") ) == 0 )
       
   222 			{
       
   223 			lex.Inc();
       
   224 			lex.Val( iTextSize.iWidth );
       
   225 			}
       
   226 		else if( token.Compare( _L("textheight") ) == 0 )
       
   227 			{
       
   228 			lex.Inc();
       
   229 			lex.Val( iTextSize.iHeight );
       
   230 			}
       
   231 		else if( token.Compare( _L("font") ) == 0 )
       
   232 			{
       
   233             TInt point = 0;
       
   234 			lex.Inc();
       
   235 			lex.Val( point );
       
   236             iFont = (const CFont *)point;
       
   237 			}
       
   238 
       
   239 		else if( token.Compare( _L("text") ) == 0 )
       
   240 		{
       
   241 			
       
   242 			//	Extract text data
       
   243 			HBufC * text = HBufC::NewLC(255);
       
   244 			TPtr txtptr = text->Des();
       
   245 			
       
   246 			//	Find the start of the string
       
   247 			while (!lex.Eos()) 
       
   248 			{
       
   249 				if (lex.Get() == '"') break;
       
   250 			}
       
   251 
       
   252 			//	Get the text data
       
   253 			while (!lex.Eos())
       
   254 			{
       
   255 				TChar c= lex.Get();
       
   256 				if (c == '"')
       
   257 				{
       
   258 					break;
       
   259 				}
       
   260 				else
       
   261 				{
       
   262 					txtptr.Append(c);
       
   263 				}
       
   264 			}
       
   265             if (iFont)
       
   266             	{
       
   267 				CreateTextL( txtptr );
       
   268 
       
   269             	}
       
   270 			CleanupStack::PopAndDestroy(); // text
       
   271 		}
       
   272 
       
   273 		iColor = ( red << 16 ) + ( green << 8 ) + blue;
       
   274 		}
       
   275 
       
   276     TReal relscale = iChild->Scale();
       
   277     TInt scaledx = (TInt)(iPosition.iX  * relscale + 0.5);
       
   278     TInt scaledy = (TInt)(iPosition.iY * relscale + 0.5);
       
   279     TInt scaledz = (TInt)(iZoom *  relscale + 0.5);
       
   280 
       
   281 	TReal zoom = 0.001 * scaledz;
       
   282 	TReal angle = 0.001 * iAngle;
       
   283 	TReal rad = KPi * angle / 180.0;
       
   284 	TReal r;
       
   285 	TReal res;
       
   286 
       
   287 
       
   288 	Math::Cos( r, rad );
       
   289 	r *= 1 << KScaleBits;
       
   290 	//r /= zoom;
       
   291 	Math::Round( res, r, 0 );
       
   292 	iScale.iX = (TInt)res;
       
   293 
       
   294 	Math::Sin( r, rad );
       
   295 	r *= 1 << KScaleBits;
       
   296 	Math::Round( res, r, 0 );
       
   297 	iScale.iY = (TInt)res;
       
   298 
       
   299 	// helpers
       
   300 	TPoint mid( iSize.iWidth/2, iSize.iHeight/2 );
       
   301 	TPoint sca( (TInt)(zoom * iScale.iX), (TInt)(zoom * iScale.iY) );
       
   302 	TInt xo = ( mid.iX * sca.iX - mid.iY * sca.iY ) >> ( KScaleBits - KCoordBits );
       
   303 	TInt yo = ( mid.iY * sca.iX + mid.iX * sca.iY ) >> ( KScaleBits - KCoordBits );
       
   304 
       
   305 	// iCorrectPosition is clipart mid position corrected with
       
   306 	// rotation ( otherwise rotation would be around topleft corner )
       
   307     iCorrectPosition = TPoint( xo,yo ) - TPoint( scaledx << KCoordBits, scaledy << KCoordBits );
       
   308 
       
   309 	// with iScale screen coordinates are translated to texture coordinates
       
   310 	iScale.iX = (TInt)(1.0 / zoom * iScale.iX);
       
   311 	iScale.iY = (TInt)(1.0 / zoom * iScale.iY);
       
   312 	return 0;
       
   313 	}
       
   314 
       
   315 
       
   316 
       
   317 const char* CFilterText::Type()
       
   318 	{
       
   319 	return "text";
       
   320 	}
       
   321 
       
   322 
       
   323 void CFilterText::CreateBitmapL( const TSize& aSize )
       
   324 	{
       
   325 	delete iData;
       
   326 	iData = NULL;
       
   327 	iData = new( ELeave )TUint32[ aSize.iWidth * aSize.iHeight ];
       
   328 	Mem::FillZ( iData, aSize.iWidth * aSize.iHeight * sizeof( TUint32 ) );
       
   329 	iRect = aSize;
       
   330 	iSize = aSize;
       
   331 	}
       
   332 
       
   333 
       
   334 
       
   335 
       
   336 void CFilterText::CreateTextL ( const TDesC16 & aText )
       
   337 	{
       
   338     CArrayFix<TPtrC>* lines = new(ELeave) CArrayFixFlat<TPtrC>(5);
       
   339     CleanupStack::PushL (lines);
       
   340  
       
   341 
       
   342     HBufC* visualText = AknBidiTextUtils::ConvertToVisualAndWrapToArrayL  
       
   343 	                        ( aText,
       
   344 	                          iTextSize.iWidth,
       
   345 	                          *iFont,
       
   346 	                          *lines ); 
       
   347     CleanupStack::PushL(visualText);
       
   348 
       
   349 
       
   350     TInt width = 0;	
       
   351     for (TInt i = 0; i < lines->Count(); ++i)
       
   352     {
       
   353         if (width < iFont->TextWidthInPixels ((*lines)[i]))
       
   354         {
       
   355             width = iFont->TextWidthInPixels ((*lines)[i]);    
       
   356         }
       
   357         
       
   358     }
       
   359     
       
   360 
       
   361 	TInt fh = iFont->HeightInPixels() + 4;
       
   362 	TInt height = fh * lines->Count(); 
       
   363 
       
   364     //  Create a bitmap big enough to hold the text
       
   365 	CFbsBitmap bitmap;
       
   366     iSize.SetSize ( width + 4, height + 4);
       
   367     User::LeaveIfError ( bitmap.Create ( iSize, EColor4K ) );
       
   368 
       
   369     //  Create bitmap device and context
       
   370     CFbsBitmapDevice * bitmapDevice = CFbsBitmapDevice::NewL (&bitmap); 
       
   371     CleanupStack::PushL (bitmapDevice);
       
   372 
       
   373 	//	Create bitmap graphics context
       
   374     CFbsBitGc * bitmapContext = 0;
       
   375     User::LeaveIfError (bitmapDevice->CreateContext (bitmapContext));
       
   376     CleanupStack::PushL (bitmapContext) ;
       
   377     
       
   378     //  Set parameters for the context
       
   379     bitmapContext->UseFont( iFont );
       
   380 	bitmapContext->SetBrushColor( 0 );
       
   381     bitmapContext->SetPenColor (KRgbWhite);
       
   382 	bitmapContext->Clear();
       
   383 
       
   384     //  Render lines
       
   385     for (TInt i = 0; i < lines->Count(); i++)
       
   386         {
       
   387         TInt xoffset = (bitmap.SizeInPixels().iWidth - iFont->TextWidthInPixels ((*lines)[i])) >> 1;
       
   388 		
       
   389 		TInt yoffset = iFont->HeightInPixels() * (i+1) + 2; 
       
   390 		bitmapContext->DrawText ((*lines)[i], TPoint (xoffset, yoffset));	
       
   391         }
       
   392 
       
   393 
       
   394 	//	Create memory buffer to hold rendered image data
       
   395     delete[] iData;
       
   396     iData = NULL;
       
   397     iData = new (ELeave) TUint32 [iSize.iWidth * iSize.iHeight];
       
   398     Mem::FillZ (iData, iSize.iWidth * iSize.iHeight * sizeof (TUint32));
       
   399     
       
   400     //  Copy data to buffer and create borders
       
   401 	CFbsBitmapHack bm2;
       
   402 	bm2.Duplicate( bitmap.Handle() );
       
   403 	bm2.DoLock();
       
   404 
       
   405 	TInt ws = bm2.ScanLineLength(iSize.iWidth, bm2.DisplayMode()) / 2;
       
   406 	TUint16 * spos = (TUint16*)(bm2.DataAddress()) + ws + 1;
       
   407     TUint32 * tp = iData + iSize.iWidth + 1;
       
   408 
       
   409     for (TInt y = 1; y < iSize.iHeight - 1; y++ )
       
   410     {
       
   411 
       
   412         TUint16 * sp = spos;
       
   413         spos += ws;       
       
   414  
       
   415 		for (TInt x = 1; x < iSize.iWidth - 1; x++ )
       
   416         {
       
   417 		
       
   418             TUint16 c0 = sp[ 0 ];
       
   419 			TUint16 c1 = sp[ -1 ];
       
   420 			TUint16 c2 = sp[ 1 ];
       
   421 			TUint16 c3 = sp[ -ws ];
       
   422 			TUint16 c4 = sp[ ws ];
       
   423 			TUint16 c5 = sp[ -1 - ws ];
       
   424 			TUint16 c6 = sp[ 1 - ws ];
       
   425 			TUint16 c7 = sp[ -1 + ws ];
       
   426 			TUint16 c8 = sp[ 1 + ws ];
       
   427 			sp++;
       
   428 
       
   429 			TUint32 c = 0;
       
   430 			if (c0)
       
   431             {
       
   432 				c = iColor;
       
   433 			}
       
   434 			TInt a = 0;
       
   435 			if (c0) a++;
       
   436 			if (c1) a++;
       
   437 			if (c2) a++;
       
   438 			if (c3) a++;
       
   439 			if (c4) a++;
       
   440 			a *= 2;
       
   441 			if (c5) a++;
       
   442 			if (c6) a++;
       
   443 			if (c7) a++;
       
   444 			if (c8) a++;
       
   445 			a *= 80;
       
   446 			if (a > 255) a = 255;
       
   447 			a <<= 24;
       
   448 			*tp++ = a + c;
       
   449         }
       
   450         tp += 2;
       
   451     }
       
   452 	bm2.DoUnlock();
       
   453 
       
   454     bitmapContext->DiscardFont();
       
   455     CleanupStack::PopAndDestroy(4); // bitmapContext, bitmapDevice, lines, visaul text
       
   456 	bitmap.Reset();
       
   457 
       
   458     }
       
   459 
       
   460 #if !defined(EKA2)
       
   461 GLDEF_C TInt E32Dll( TDllReason )
       
   462     {
       
   463     return KErrNone;
       
   464     }	
       
   465 #endif