os/graphics/graphicsdeviceinterface/bitgdi/sbit/TEXT.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <fntstore.h>
sl@0
    17
#include <bitdraw.h>
sl@0
    18
#include <bitstd.h>
sl@0
    19
#include <bitdev.h>
sl@0
    20
#include "BITPANIC.H"
sl@0
    21
#include <shapeinfo.h>
sl@0
    22
#include <bmalphablend.h>
sl@0
    23
#include <bitdrawinterfaceid.h>
sl@0
    24
#include <graphics/fbsrasterizer.h>
sl@0
    25
#include "bitgcextradata.h"
sl@0
    26
#include <graphics/gdi/gdiconsts.h>
sl@0
    27
#include <graphics/gdi/gdistructs.h>
sl@0
    28
sl@0
    29
sl@0
    30
/** Draws text at the last print position.
sl@0
    31
sl@0
    32
@param aText The text string to be drawn. */
sl@0
    33
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText)
sl@0
    34
	{
sl@0
    35
	TTextParameters* param = NULL;
sl@0
    36
	DrawText(aText,param,iLastPrintPosition,ELeft,CFont::EHorizontal);
sl@0
    37
	}
sl@0
    38
sl@0
    39
/** Draws text at the specified position and updates the print position.
sl@0
    40
sl@0
    41
@param  aText The text string to be drawn
sl@0
    42
@param aCoords Coordinates to draw the text at. */
sl@0
    43
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TPoint& aCoords)
sl@0
    44
	{
sl@0
    45
	TTextParameters* param = NULL;
sl@0
    46
	DrawText(aText,param,aCoords,ELeft,CFont::EHorizontal);
sl@0
    47
	}
sl@0
    48
sl@0
    49
sl@0
    50
/** Draws text clipped to the specified rectangle.
sl@0
    51
sl@0
    52
@param aText The text string to be drawn 
sl@0
    53
@param aBox The clipping rectangle. */
sl@0
    54
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TRect& aBox)
sl@0
    55
	{
sl@0
    56
	TTextParameters* param = NULL;
sl@0
    57
	DrawText(aText,param,aBox);
sl@0
    58
	}
sl@0
    59
sl@0
    60
sl@0
    61
/** Draws text clipped to the specified rectangle using a baseline offset,
sl@0
    62
horizontal alignment and a margin.
sl@0
    63
sl@0
    64
@param  aText The text string to be drawn
sl@0
    65
@param aBox The clipping rectangle.
sl@0
    66
@param  aBLOff An offset in pixels for the baseline from the normal position
sl@0
    67
        (bottom of the rectangle minus the descent of the font).
sl@0
    68
@param  aHrz Horizontal alignment option relative to the specified rectangle.
sl@0
    69
@param aMargin Offset to add to the position as calculated using specified 
sl@0
    70
		rectangle. */	
sl@0
    71
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TRect& aBox,TInt aBLOff,
sl@0
    72
								  TTextAlign aHrz,TInt aMargin)
sl@0
    73
    {
sl@0
    74
    TTextParameters* param = NULL;
sl@0
    75
	DrawText(aText,param,aBox,aBLOff,-1,aHrz,aMargin);
sl@0
    76
	}
sl@0
    77
sl@0
    78
/** Draws text clipped to the specified rectangle.
sl@0
    79
sl@0
    80
@param  aText The text string to be drawn
sl@0
    81
@param aBox The clipping rectangle. */	
sl@0
    82
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TRect& aBox,
sl@0
    83
								  TInt aBLOff,TInt /*aTextWidth*/,
sl@0
    84
								  TTextAlign aHrz,TInt aMargin)
sl@0
    85
    {
sl@0
    86
// aTextWidth is not used here - try to abolish this - I think it is unneeded
sl@0
    87
	TPoint p(aBox.iTl);
sl@0
    88
	p.iY += aBLOff;
sl@0
    89
	switch (aHrz)
sl@0
    90
		{
sl@0
    91
		case ELeft: p.iX += aMargin; break;
sl@0
    92
		case ERight: p.iX = aBox.iBr.iX - aMargin; break;
sl@0
    93
		case ECenter: p.iX += aBox.Width() / 2 + aMargin; break;
sl@0
    94
		}
sl@0
    95
	TTextParameters* param = NULL;
sl@0
    96
	DrawText(aText,param,p,aHrz,CFont::EHorizontal,&aBox);
sl@0
    97
	}
sl@0
    98
sl@0
    99
sl@0
   100
/** The general DrawText routine that implements all the others.
sl@0
   101
sl@0
   102
@param aText the text to be drawn
sl@0
   103
@param aPosition the origin of the text
sl@0
   104
@param aAlignment left, centred or right, around aPosition; not used if drawing vertically
sl@0
   105
@param aDirection direction: left to right, right to left, or top to bottom
sl@0
   106
@param aBox if non-null, filled before the text is drawn
sl@0
   107
@param aTextBounds if non-null returns the bounding box of the text
sl@0
   108
*/ 
sl@0
   109
void CFbsBitGc::DrawText(const TDesC& aText,const TTextParameters* aParam,const TPoint& aPosition,TTextAlign aAlignment,
sl@0
   110
						 CFont::TTextDirection aDirection,const TRect* aBox)
sl@0
   111
   {
sl@0
   112
	// sanity checks
sl@0
   113
	BG_ASSERT_ALWAYS(iDevice,EBitgdiPanicNoDevicePresent);
sl@0
   114
	BG_ASSERT_ALWAYS(iFont.Handle() != 0,EBitgdiPanicNoFontSelected);
sl@0
   115
	const CBitmapFont* bitmap_font = iFont.Address();
sl@0
   116
	BG_ASSERT_ALWAYS(bitmap_font != 0,EBitgdiPanicNoFontSelected);
sl@0
   117
sl@0
   118
	// anything to do?
sl@0
   119
	if (!aBox && !aText.Length())
sl@0
   120
		return;
sl@0
   121
sl@0
   122
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   123
sl@0
   124
	TRect deviceRect;
sl@0
   125
	drawDevice->GetDrawRect(deviceRect);
sl@0
   126
sl@0
   127
	// measure the text
sl@0
   128
	CFont::TMeasureTextInput measure_text_input;
sl@0
   129
	measure_text_input.iCharJustNum = iCharJustNum;
sl@0
   130
	measure_text_input.iCharJustExcess = iCharJustExcess;
sl@0
   131
	measure_text_input.iWordJustNum = iWordJustNum;
sl@0
   132
	measure_text_input.iWordJustExcess = iWordJustExcess;
sl@0
   133
	measure_text_input.iFlags |= CFont::TMeasureTextInput::EFVisualOrder;
sl@0
   134
	if (aParam)
sl@0
   135
		{
sl@0
   136
		BG_ASSERT_ALWAYS(aParam->iStart < aParam->iEnd ,EBitgdiPanicInvalidParameter);
sl@0
   137
		measure_text_input.iStartInputChar = aParam->iStart;
sl@0
   138
		measure_text_input.iEndInputChar = Min(aText.Length(),aParam->iEnd);
sl@0
   139
		}
sl@0
   140
	CFont::TMeasureTextOutput measure_text_output;
sl@0
   141
	const int advance = iFont.MeasureText(aText,&measure_text_input,&measure_text_output);
sl@0
   142
	TRect text_bounds = measure_text_output.iBounds;
sl@0
   143
	TInt underlineStrikeoutOffset;
sl@0
   144
	
sl@0
   145
	//this call is only needed in the case of linked fonts
sl@0
   146
	//should this pass by one structure?
sl@0
   147
	underlineStrikeoutOffset= BaselineCorrection();
sl@0
   148
	
sl@0
   149
	if (iUnderline == EUnderlineOn)
sl@0
   150
		{
sl@0
   151
		TInt underline_top = 0, underline_bottom = 0;
sl@0
   152
		TInt err = GetUnderlineMetrics(underline_top,underline_bottom);
sl@0
   153
		underline_top+=underlineStrikeoutOffset;
sl@0
   154
		underline_bottom+=underlineStrikeoutOffset;
sl@0
   155
		BG_ASSERT_DEBUG(err == KErrNone, EBitgdiPanicInvalidArg);
sl@0
   156
		text_bounds.iTl.iY = Min(text_bounds.iTl.iY,underline_top);
sl@0
   157
		text_bounds.iBr.iY = Max(text_bounds.iBr.iY,underline_bottom);
sl@0
   158
		}
sl@0
   159
	if (iStrikethrough == EStrikethroughOn)
sl@0
   160
		{
sl@0
   161
		TInt strike_top = 0,strike_bottom = 0;
sl@0
   162
		GetStrikethroughMetrics(strike_top,strike_bottom);
sl@0
   163
		strike_top+=underlineStrikeoutOffset;
sl@0
   164
		strike_bottom+=underlineStrikeoutOffset;
sl@0
   165
		text_bounds.iTl.iY = Min(text_bounds.iTl.iY,strike_top);
sl@0
   166
		text_bounds.iBr.iY = Max(text_bounds.iBr.iY,strike_bottom);
sl@0
   167
		}
sl@0
   168
	if (iUnderline == EUnderlineOn || iStrikethrough == EStrikethroughOn)
sl@0
   169
		{
sl@0
   170
		if (aDirection == CFont::EHorizontal)
sl@0
   171
			{
sl@0
   172
			text_bounds.iTl.iX = Min(text_bounds.iTl.iX, 0);
sl@0
   173
			text_bounds.iBr.iX = Max(text_bounds.iBr.iX, advance);
sl@0
   174
			}
sl@0
   175
		else
sl@0
   176
			{
sl@0
   177
			text_bounds.iTl.iY = Min(text_bounds.iTl.iY, 0);
sl@0
   178
			text_bounds.iBr.iY = Max(text_bounds.iBr.iY, advance);
sl@0
   179
			}
sl@0
   180
		}
sl@0
   181
sl@0
   182
	// work out the text origin and new drawing position
sl@0
   183
 	TPoint text_origin = aPosition;
sl@0
   184
 	if (aDirection != CFont::EVertical)
sl@0
   185
 		{
sl@0
   186
 		const TInt leftSideBearing = Min(text_bounds.iTl.iX, 0);
sl@0
   187
 		const TInt rightSideBearing = Max(text_bounds.iBr.iX, advance);
sl@0
   188
 		switch (aAlignment)
sl@0
   189
 			{
sl@0
   190
			// We are forbidding side-bearings to leak over the sides here,
sl@0
   191
			// but still keeping the start and end pen positions within bounds.
sl@0
   192
			case ELeft:
sl@0
   193
				text_origin.iX -= leftSideBearing;
sl@0
   194
				break;
sl@0
   195
			case ERight:
sl@0
   196
				text_origin.iX -= rightSideBearing;
sl@0
   197
				break;
sl@0
   198
			case ECenter:
sl@0
   199
				// Centre is the average of left and right
sl@0
   200
				text_origin.iX -= (leftSideBearing + rightSideBearing) >> 1;
sl@0
   201
				break;
sl@0
   202
			default:
sl@0
   203
				break;
sl@0
   204
 			}
sl@0
   205
		}
sl@0
   206
	iLastPrintPosition = text_origin;
sl@0
   207
	if (aDirection == CFont::EHorizontal)
sl@0
   208
		iLastPrintPosition.iX += advance;
sl@0
   209
	else
sl@0
   210
		iLastPrintPosition.iY += advance;
sl@0
   211
	text_origin.iY += bitmap_font->iAlgStyle.iBaselineOffsetInPixels;
sl@0
   212
	text_bounds.Move(text_origin);
sl@0
   213
	text_origin += iOrigin;
sl@0
   214
sl@0
   215
	// determine clipping rectangle
sl@0
   216
	TRect clip_rect = aBox ? *aBox : text_bounds;
sl@0
   217
	AddRect(clip_rect);
sl@0
   218
	clip_rect.Move(iOrigin);
sl@0
   219
sl@0
   220
	if (UserClipRect(clip_rect))
sl@0
   221
		{
sl@0
   222
		if (iAutoUpdateJustification)
sl@0
   223
			UpdateJustification(aText,aParam);
sl@0
   224
		return; // nothing to do
sl@0
   225
		}
sl@0
   226
sl@0
   227
	SetupDevice();
sl@0
   228
	iDevice->DrawingBegin(&iBrushBitmap);
sl@0
   229
	CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
sl@0
   230
sl@0
   231
	// fill the box if necessary
sl@0
   232
	if (aBox)
sl@0
   233
		{
sl@0
   234
		TRect fill_box = *aBox;
sl@0
   235
		fill_box.Move(iOrigin);
sl@0
   236
		RectFill(fill_box);
sl@0
   237
		}
sl@0
   238
sl@0
   239
	// decide which drawing routine to call
sl@0
   240
	const TBool bold = bitmap_font->iAlgStyle.IsBold();
sl@0
   241
	const TBool italic = bitmap_font->iAlgStyle.IsItalic();
sl@0
   242
	const TBool multiw = bitmap_font->iAlgStyle.WidthFactor() > 1;
sl@0
   243
	const TBool multih = bitmap_font->iAlgStyle.HeightFactor() > 1;
sl@0
   244
sl@0
   245
	TOpenFontMetrics metrics;
sl@0
   246
	iFont.GetFontMetrics(metrics);
sl@0
   247
	const TInt maxwidth = metrics.MaxWidth();
sl@0
   248
	// extext will be TRUE, if font is bold/italic/underline/strikethrough/anti-aliased or it 
sl@0
   249
	// has shadow/outline effects ON. Depending on these properties it will call the proper draw routine.
sl@0
   250
	TBool extext = FALSE;
sl@0
   251
	TBool normaltext = FALSE;
sl@0
   252
	const TBool anti_aliased = (bitmap_font->GlyphBitmapType() == EAntiAliasedGlyphBitmap);
sl@0
   253
	const TBool outlineAndShadow = (bitmap_font->GlyphBitmapType() == EFourColourBlendGlyphBitmap);
sl@0
   254
	if (anti_aliased || outlineAndShadow)
sl@0
   255
		{
sl@0
   256
		if ((outlineAndShadow) && !(iBrushStyle == ENullBrush || iBrushStyle == ESolidBrush))
sl@0
   257
			{
sl@0
   258
			//For future compatibility it is better if brush style of ENullBrush or ESolidBrush is used 
sl@0
   259
			//when drawing outline and shadow fonts.
sl@0
   260
			BG_PANIC_ALWAYS(EBitgdiPanicInvalidBrushStyle);
sl@0
   261
			}
sl@0
   262
		extext = TRUE;
sl@0
   263
		}
sl@0
   264
	else if (maxwidth > 30 || text_bounds.Height() > 32 || multiw || multih)
sl@0
   265
		{
sl@0
   266
		}
sl@0
   267
	else if (iUnderline == EUnderlineOn || bold || italic || iStrikethrough == EStrikethroughOn || 
sl@0
   268
			 iCharJustNum > 0 || iWordJustNum > 0)
sl@0
   269
		extext = TRUE;
sl@0
   270
	else
sl@0
   271
		normaltext = TRUE;
sl@0
   272
sl@0
   273
	const TInt charjustexcess = iCharJustExcess;
sl@0
   274
	const TInt charjustnum = iCharJustNum;
sl@0
   275
	const TInt wordjustexcess = iWordJustExcess;
sl@0
   276
	const TInt wordjustnum = iWordJustNum;
sl@0
   277
sl@0
   278
	// draw the text to all clip rectangles in turn
sl@0
   279
	int clip_rects = iDefaultRegionPtr->Count();
sl@0
   280
	for (int i = 0; i < clip_rects; i++)
sl@0
   281
		{
sl@0
   282
		iClipRect = (*iDefaultRegionPtr)[i];
sl@0
   283
		if (!iClipRect.Intersects(clip_rect))
sl@0
   284
			continue;
sl@0
   285
sl@0
   286
#ifdef _DEBUG
sl@0
   287
		BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
   288
		BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
   289
		BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
   290
		BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
   291
#endif
sl@0
   292
sl@0
   293
		iClipRect.Intersection(clip_rect);
sl@0
   294
sl@0
   295
		// Set up the parameter block for character positioning.
sl@0
   296
		CFont::TPositionParam param;
sl@0
   297
		param.iDirection = static_cast<TInt16>(aDirection);
sl@0
   298
		param.iText.Set(aText);
sl@0
   299
		TInt endDraw = aText.Length();
sl@0
   300
		if (aParam)
sl@0
   301
			{
sl@0
   302
			param.iPosInText = aParam->iStart;
sl@0
   303
			endDraw = Min(aText.Length(),aParam->iEnd);
sl@0
   304
			}
sl@0
   305
		else
sl@0
   306
			param.iPosInText = 0;
sl@0
   307
		param.iPen = text_origin;
sl@0
   308
sl@0
   309
		// Draw the text.
sl@0
   310
		if (normaltext)
sl@0
   311
			DoDrawText(param,endDraw);
sl@0
   312
		else if (extext)
sl@0
   313
			DoDrawTextEx(param,bitmap_font,endDraw,underlineStrikeoutOffset);
sl@0
   314
		else
sl@0
   315
			DoDrawTextLarge(param,bitmap_font,endDraw);
sl@0
   316
		
sl@0
   317
		/*
sl@0
   318
		Reset the justification parameters to their original values.
sl@0
   319
		These will be updated as required later in code.
sl@0
   320
		*/
sl@0
   321
		iCharJustExcess = charjustexcess;
sl@0
   322
		iCharJustNum = charjustnum;
sl@0
   323
		iWordJustExcess = wordjustexcess;
sl@0
   324
		iWordJustNum = wordjustnum;
sl@0
   325
sl@0
   326
		drawDevice->UpdateRegion(iClipRect);
sl@0
   327
		}
sl@0
   328
sl@0
   329
	if (brushRasterizer)
sl@0
   330
		{
sl@0
   331
		brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
sl@0
   332
		}
sl@0
   333
	iDevice->DrawingEnd(&iBrushBitmap);
sl@0
   334
	if (iAutoUpdateJustification)
sl@0
   335
		UpdateJustification(aText,aParam);
sl@0
   336
	}
sl@0
   337
sl@0
   338
void CFbsBitGc::DoDrawText(CFont::TPositionParam& aParam, const TInt aEnd)
sl@0
   339
	{
sl@0
   340
	//const int n = aParam.iText.Length();
sl@0
   341
	RShapeInfo shapeInfo;
sl@0
   342
	while (aParam.iPosInText < /*n*/aEnd)
sl@0
   343
		{
sl@0
   344
		if (iFont.GetCharacterPosition2(aParam, shapeInfo))
sl@0
   345
			{
sl@0
   346
			const CFont::TPositionParam::TOutput* output = aParam.iOutput;
sl@0
   347
			for (int i = 0; i < aParam.iOutputGlyphs; i++, output++)
sl@0
   348
				DoDrawCharacter(output->iBounds.iTl,output->iBitmapSize,output->iBitmap);
sl@0
   349
			}
sl@0
   350
		}
sl@0
   351
	if (shapeInfo.IsOpen())
sl@0
   352
		shapeInfo.Close();
sl@0
   353
		
sl@0
   354
	}
sl@0
   355
sl@0
   356
void CFbsBitGc::DoDrawCharacter(const TPoint& aTopLeft,
sl@0
   357
								const TSize& aDataSize,
sl@0
   358
								const TUint8* aData)
sl@0
   359
	{
sl@0
   360
	/*
sl@0
   361
	Divert if the character is larger than expected; the criterion
sl@0
   362
	for choosing this function is only a heuristic, because it's perfectly legal for
sl@0
   363
	a character's bitmap to be wider than its escapement.
sl@0
   364
sl@0
   365
	Use a dummy value (0) for semi-ascent because this character is not italic and so semi-ascent
sl@0
   366
	is irrelevant; it's used for pseudo-italic slanting.
sl@0
   367
	*/
sl@0
   368
	TInt dataheight = aDataSize.iHeight;
sl@0
   369
	TInt datalength = aDataSize.iWidth;
sl@0
   370
	if (datalength > 30 || dataheight > 32)
sl@0
   371
		{
sl@0
   372
		DoDrawCharacterExLarge(aTopLeft,aDataSize,aData,FALSE,FALSE,0,1,1);
sl@0
   373
		return;
sl@0
   374
		}
sl@0
   375
	
sl@0
   376
	TInt bitindex=0;
sl@0
   377
	TInt16 repeatcount=0;
sl@0
   378
	TUint32 binarydata[32];
sl@0
   379
	TUint32* binarydataptr=binarydata;
sl@0
   380
	TUint32* binarydataptrlimit;
sl@0
   381
	for(TInt charline=0;charline<dataheight;charline+=repeatcount) // for lines in the character...
sl@0
   382
		{
sl@0
   383
		repeatcount=Load16(aData+(bitindex>>3));
sl@0
   384
		repeatcount>>=bitindex&7;
sl@0
   385
		TInt multilineflag=repeatcount&1;
sl@0
   386
		repeatcount>>=1;
sl@0
   387
		repeatcount&=0xf;
sl@0
   388
		bitindex+=5;
sl@0
   389
		binarydataptrlimit=binarydata+charline+repeatcount;
sl@0
   390
		if(multilineflag)
sl@0
   391
			{
sl@0
   392
			while(binarydataptr<binarydataptrlimit)
sl@0
   393
				{
sl@0
   394
				TInt chardataoffsetptr=TInt(aData)+(bitindex>>3);
sl@0
   395
				TUint32* chardataword=(TUint32*)(chardataoffsetptr&~3);
sl@0
   396
				TInt bitshift=bitindex&7;
sl@0
   397
				bitshift+=(chardataoffsetptr&3)<<3;
sl@0
   398
				*binarydataptr=(*chardataword++)>>bitshift;
sl@0
   399
				if(bitshift) *binarydataptr|=(*chardataword<<(32-bitshift));
sl@0
   400
				bitindex+=datalength;
sl@0
   401
				binarydataptr++;
sl@0
   402
				}
sl@0
   403
			}
sl@0
   404
		else
sl@0
   405
			{
sl@0
   406
			TInt chardataoffsetptr=TInt(aData)+(bitindex>>3);
sl@0
   407
			TUint32* chardataword=(TUint32*)(chardataoffsetptr&~3);
sl@0
   408
			TInt bitshift=bitindex&7;
sl@0
   409
			bitshift+=(chardataoffsetptr&3)<<3;
sl@0
   410
			TUint32 data=(*chardataword++)>>bitshift;
sl@0
   411
			if(bitshift) data|=(*chardataword<<(32-bitshift));
sl@0
   412
			while(binarydataptr<binarydataptrlimit)
sl@0
   413
				*binarydataptr++=data;
sl@0
   414
			bitindex+=datalength;
sl@0
   415
			}
sl@0
   416
		}
sl@0
   417
	TPoint topleft(aTopLeft);
sl@0
   418
	binarydataptr=ClipBinaryArray(binarydata,binarydata+dataheight,1,datalength,dataheight,topleft);
sl@0
   419
	if(datalength>0 && dataheight>0)
sl@0
   420
		iDevice->iDrawDevice->WriteBinary(topleft.iX,topleft.iY,binarydataptr,datalength,dataheight,iPenColor,iDrawMode);
sl@0
   421
	}
sl@0
   422
sl@0
   423
/** 
sl@0
   424
@internalTechnology
sl@0
   425
sl@0
   426
This function retrieves the baseline offset from the metrics of the text currently being drawn.
sl@0
   427
This is used to alter the positioning of underline and strikethrough on a linked font
sl@0
   428
sl@0
   429
@return The baseline correction associated with the currently used font.
sl@0
   430
*/	
sl@0
   431
TInt CFbsBitGc::BaselineCorrection()
sl@0
   432
	{
sl@0
   433
	TOpenFontMetrics metrics;
sl@0
   434
	if (iFont.GetFontMetrics(metrics))
sl@0
   435
		return metrics.BaselineCorrection();
sl@0
   436
	else
sl@0
   437
		return 0;
sl@0
   438
	}
sl@0
   439
sl@0
   440
void CFbsBitGc::DoDrawTextEx(CFont::TPositionParam& aParam,const CBitmapFont* font, const TInt aEnd, const TInt aUnderlineStrikethroughOffset)
sl@0
   441
	{
sl@0
   442
	const TInt charclipping = iClipRect.iBr.iX;
sl@0
   443
	TPoint start_pen = aParam.iPen;
sl@0
   444
	const TBool bold = font->iAlgStyle.IsBold();
sl@0
   445
	const TBool italic = font->iAlgStyle.IsItalic();
sl@0
   446
	const TGlyphBitmapType glyphBitmapTypeForFont = font->GlyphBitmapType();
sl@0
   447
	const TBool outlineShadowOrAntialiased = ((glyphBitmapTypeForFont == EAntiAliasedGlyphBitmap) ||
sl@0
   448
												(glyphBitmapTypeForFont == EFourColourBlendGlyphBitmap));
sl@0
   449
sl@0
   450
	TInt underline_top = 0, underline_bottom = 0;
sl@0
   451
	if (iUnderline == EUnderlineOn)
sl@0
   452
		{
sl@0
   453
		TInt err = GetUnderlineMetrics(underline_top,underline_bottom);
sl@0
   454
		underline_top+=aUnderlineStrikethroughOffset;
sl@0
   455
		underline_bottom+=aUnderlineStrikethroughOffset;
sl@0
   456
		BG_ASSERT_DEBUG(err == KErrNone, EBitgdiPanicInvalidArg);
sl@0
   457
		}
sl@0
   458
	TInt strike_top = 0, strike_bottom = 0;
sl@0
   459
	if (italic || iStrikethrough == EStrikethroughOn)
sl@0
   460
		{
sl@0
   461
		GetStrikethroughMetrics(strike_top,strike_bottom);
sl@0
   462
		strike_top+=aUnderlineStrikethroughOffset;
sl@0
   463
		strike_bottom+=aUnderlineStrikethroughOffset;
sl@0
   464
		}
sl@0
   465
sl@0
   466
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   467
	RShapeInfo shapeInfo;
sl@0
   468
	while (aParam.iPosInText < aEnd)
sl@0
   469
		{
sl@0
   470
		if (!iFont.GetCharacterPosition2(aParam, shapeInfo))
sl@0
   471
			continue;
sl@0
   472
		TInt adjustment = 0;
sl@0
   473
		if(iCharJustExcess && iCharJustNum > 0) // character clipping/justification
sl@0
   474
			{
sl@0
   475
			adjustment = CGraphicsContext::JustificationInPixels(iCharJustExcess,iCharJustNum);
sl@0
   476
			if(adjustment < 0)
sl@0
   477
				iClipRect.iBr.iX = Min(aParam.iPen.iX + adjustment,iClipRect.iBr.iX);
sl@0
   478
			}
sl@0
   479
sl@0
   480
		const CFont::TPositionParam::TOutput* output = aParam.iOutput;
sl@0
   481
		int semi_ascent = start_pen.iY + strike_top;
sl@0
   482
sl@0
   483
		for (int i = 0; i < aParam.iOutputGlyphs; i++, output++)
sl@0
   484
			{
sl@0
   485
			//get the character metrics for the glyph type
sl@0
   486
			TOpenFontCharMetrics characterParams;
sl@0
   487
			const TUint8* bitmap;
sl@0
   488
			TSize size;
sl@0
   489
			//note may now be using a glyph code, and not a character
sl@0
   490
			iFont.GetCharacterData(aParam.iOutput[i].iCode,characterParams,bitmap,size);
sl@0
   491
			TGlyphBitmapType glyphType = characterParams.GlyphType();
sl@0
   492
			
sl@0
   493
			switch (glyphType)
sl@0
   494
				{
sl@0
   495
				case EAntiAliasedGlyphBitmap:
sl@0
   496
				case EFourColourBlendGlyphBitmap:
sl@0
   497
					DoDrawCharacterAntiAliased(output->iBounds.iTl,output->iBitmapSize,output->iBitmap,glyphType);
sl@0
   498
					break;
sl@0
   499
sl@0
   500
				case EDefaultGlyphBitmap:
sl@0
   501
				case EMonochromeGlyphBitmap:
sl@0
   502
					DoDrawCharacterEx(output->iBounds.iTl,output->iBitmapSize,output->iBitmap,bold,italic,semi_ascent);
sl@0
   503
					break;
sl@0
   504
sl@0
   505
				default:
sl@0
   506
					//if the outline or shadow is not specified for the character, then use the font setting
sl@0
   507
					if (outlineShadowOrAntialiased)
sl@0
   508
						{
sl@0
   509
						DoDrawCharacterAntiAliased(output->iBounds.iTl,output->iBitmapSize,output->iBitmap,glyphBitmapTypeForFont);			
sl@0
   510
						}
sl@0
   511
					else
sl@0
   512
						{
sl@0
   513
						DoDrawCharacterEx(output->iBounds.iTl,output->iBitmapSize,output->iBitmap,bold,italic,semi_ascent);
sl@0
   514
						}			 
sl@0
   515
					break;
sl@0
   516
				}
sl@0
   517
			}
sl@0
   518
sl@0
   519
		iClipRect.iBr.iX = charclipping;
sl@0
   520
		if (adjustment)
sl@0
   521
			aParam.iPen.iX += adjustment;
sl@0
   522
		if (iWordJustExcess > 0 && iWordJustNum > 0 && aParam.iOutput[0].iCode == 0x0020) // word justification
sl@0
   523
			{
sl@0
   524
			adjustment = CGraphicsContext::JustificationInPixels(iWordJustExcess,iWordJustNum);
sl@0
   525
			aParam.iPen.iX += adjustment;
sl@0
   526
			}
sl@0
   527
		}
sl@0
   528
	if (shapeInfo.IsOpen())
sl@0
   529
		shapeInfo.Close();
sl@0
   530
sl@0
   531
	if (iUnderline == EUnderlineOn)
sl@0
   532
		{
sl@0
   533
		TRect ul(start_pen.iX,start_pen.iY + underline_top,aParam.iPen.iX,start_pen.iY + underline_bottom);
sl@0
   534
		if(ul.Intersects(iClipRect)) // checks for empty aRect as well
sl@0
   535
			{
sl@0
   536
			ul.Intersection(iClipRect);
sl@0
   537
			drawDevice->WriteRgbMulti(ul.iTl.iX,ul.iTl.iY,ul.iBr.iX-ul.iTl.iX,ul.iBr.iY-ul.iTl.iY,iPenColor,iDrawMode);
sl@0
   538
			}
sl@0
   539
		}
sl@0
   540
sl@0
   541
	if (iStrikethrough == EStrikethroughOn)
sl@0
   542
		{
sl@0
   543
		TRect st(start_pen.iX,start_pen.iY + strike_top,aParam.iPen.iX,start_pen.iY + strike_bottom);
sl@0
   544
		if(st.Intersects(iClipRect)) // checks for empty aRect as well
sl@0
   545
			{
sl@0
   546
			st.Intersection(iClipRect);
sl@0
   547
			drawDevice->WriteRgbMulti(st.iTl.iX,st.iTl.iY,st.iBr.iX-st.iTl.iX,st.iBr.iY-st.iTl.iY,iPenColor,iDrawMode);
sl@0
   548
			}
sl@0
   549
		}
sl@0
   550
	}
sl@0
   551
sl@0
   552
void CFbsBitGc::DoDrawCharacterEx(const TPoint& aTopLeft,
sl@0
   553
								  const TSize& aDataSize,
sl@0
   554
								  const TUint8* aData,
sl@0
   555
								  TBool aBold,TBool aItalic,TInt aSemiAscent)
sl@0
   556
	{
sl@0
   557
	/*
sl@0
   558
	Divert if the character is larger than expected; the criterion
sl@0
   559
	for choosing this function is only a heuristic, because it's perfectly legal for
sl@0
   560
	a character's bitmap to be wider than its escapement.
sl@0
   561
	*/
sl@0
   562
	TInt datalength = aDataSize.iWidth;
sl@0
   563
	TInt dataheight = aDataSize.iHeight;
sl@0
   564
	if (datalength > 30 || dataheight > 32)
sl@0
   565
		{
sl@0
   566
		DoDrawCharacterExLarge(aTopLeft,aDataSize,aData,aBold,aItalic,aSemiAscent,1,1);
sl@0
   567
		return;
sl@0
   568
		}
sl@0
   569
sl@0
   570
	TInt bitindex=0;
sl@0
   571
	TInt16 repeatcount=0;
sl@0
   572
	TUint32 binarydata[32];
sl@0
   573
	TUint32* binarydataptr=binarydata;
sl@0
   574
	TUint32* binarydataptrlimit;
sl@0
   575
	for(TInt charline=0;charline<dataheight;charline+=repeatcount) // for lines in the character...
sl@0
   576
		{
sl@0
   577
		repeatcount=Load16(aData+(bitindex>>3));
sl@0
   578
		repeatcount>>=bitindex&7;
sl@0
   579
		TInt multilineflag=repeatcount&1;
sl@0
   580
		repeatcount>>=1;
sl@0
   581
		repeatcount&=0xf;
sl@0
   582
		bitindex+=5;
sl@0
   583
		binarydataptrlimit=binarydata+charline+repeatcount;
sl@0
   584
		if(multilineflag)
sl@0
   585
			{
sl@0
   586
			while(binarydataptr<binarydataptrlimit)
sl@0
   587
				{
sl@0
   588
				CopyCharWord(binarydataptr,aData+(bitindex>>3),bitindex&7);
sl@0
   589
				bitindex+=datalength;
sl@0
   590
				binarydataptr++;
sl@0
   591
				}
sl@0
   592
			}
sl@0
   593
		else
sl@0
   594
			{
sl@0
   595
			TUint32 data=0;
sl@0
   596
			CopyCharWord(&data,aData+(bitindex>>3),bitindex&7);
sl@0
   597
			while(binarydataptr<binarydataptrlimit)
sl@0
   598
				*binarydataptr++=data;
sl@0
   599
			bitindex+=datalength;
sl@0
   600
			}
sl@0
   601
		}
sl@0
   602
	binarydataptr=binarydata;
sl@0
   603
	binarydataptrlimit=binarydata+dataheight;
sl@0
   604
	if(aBold)
sl@0
   605
		{
sl@0
   606
		TInt sparemask=(0xffffffff>>(32-datalength));
sl@0
   607
		while(binarydataptr<binarydataptrlimit)
sl@0
   608
			{
sl@0
   609
			*binarydataptr&=sparemask;
sl@0
   610
			*binarydataptr|=(*binarydataptr<<1);
sl@0
   611
			++binarydataptr;
sl@0
   612
			}
sl@0
   613
		binarydataptr=binarydata;
sl@0
   614
		datalength++;
sl@0
   615
		}
sl@0
   616
	if(aItalic)
sl@0
   617
		{
sl@0
   618
		TInt skewlevel=aSemiAscent-aTopLeft.iY;
sl@0
   619
		TUint32 sparemask=(0xffffffff>>(32-datalength));
sl@0
   620
		binarydataptrlimit=binarydata+skewlevel;
sl@0
   621
		while(binarydataptr<binarydataptrlimit)
sl@0
   622
			*binarydataptr++<<=1;
sl@0
   623
		binarydataptrlimit=binarydata+dataheight;
sl@0
   624
		while(binarydataptr<binarydataptrlimit)
sl@0
   625
			*binarydataptr++&=sparemask;
sl@0
   626
		binarydataptr=binarydata;
sl@0
   627
		datalength++;
sl@0
   628
		}
sl@0
   629
	TPoint topleft(aTopLeft);
sl@0
   630
	binarydataptr=ClipBinaryArray(binarydata,binarydata+dataheight,1,datalength,dataheight,topleft);
sl@0
   631
	if(datalength>0 && dataheight>0)
sl@0
   632
		iDevice->iDrawDevice->WriteBinary(topleft.iX,topleft.iY,binarydataptr,datalength,dataheight,iPenColor,iDrawMode);
sl@0
   633
	}
sl@0
   634
sl@0
   635
/** 
sl@0
   636
@internalTechnology
sl@0
   637
sl@0
   638
This function draws an anti-aliased character.
sl@0
   639
sl@0
   640
@param aTopLeft The position to output the character
sl@0
   641
@param aDataSize The size of the bitmap
sl@0
   642
@param aData the bitmap for outputt in their TOpenFontCharMetrics
sl@0
   643
@param aGlyphType the glyph type for the character
sl@0
   644
*/
sl@0
   645
void CFbsBitGc::DoDrawCharacterAntiAliased(const TPoint& aTopLeft,
sl@0
   646
										   const TSize& aDataSize,
sl@0
   647
										   const TUint8* aData,
sl@0
   648
										   const TGlyphBitmapType aGlyphType)
sl@0
   649
	{
sl@0
   650
	const int top_row = Max(0,iClipRect.iTl.iY - aTopLeft.iY);
sl@0
   651
	const int bottom_row = Min(aDataSize.iHeight,iClipRect.iBr.iY - aTopLeft.iY);
sl@0
   652
	const int left_col = Max(0,iClipRect.iTl.iX - aTopLeft.iX);
sl@0
   653
	const int right_col = Min(aDataSize.iWidth,iClipRect.iBr.iX - aTopLeft.iX);
sl@0
   654
	const TUint8* p = aData + top_row * aDataSize.iWidth + left_col;
sl@0
   655
	const int x = aTopLeft.iX + left_col;
sl@0
   656
	int y = aTopLeft.iY + top_row;
sl@0
   657
	const int cols = right_col - left_col;
sl@0
   658
	const TUint32 penColor = iPenColor.Internal();
sl@0
   659
	const TUint32 shadowColor = iFbsBitGcExtraData->ShadowColor().Internal();
sl@0
   660
	const TUint32 brushColor = iBrushColor.Internal();
sl@0
   661
sl@0
   662
	if (EFourColourBlendGlyphBitmap == aGlyphType)
sl@0
   663
		{
sl@0
   664
		MOutlineAndShadowBlend* outlineAndShadow = NULL;
sl@0
   665
		const TInt err = iDevice->iDrawDevice->GetInterface(KOutlineAndShadowInterfaceID, reinterpret_cast <TAny*&> (outlineAndShadow));
sl@0
   666
		if(err == KErrNone) 
sl@0
   667
			{
sl@0
   668
			//There is a support for the interface with KOutlineAndShadowInterface id.
sl@0
   669
			for (int row = top_row; row < bottom_row; row++, p += aDataSize.iWidth, y++)
sl@0
   670
				outlineAndShadow->WriteRgbOutlineAndShadow(x, y, cols, penColor, shadowColor, brushColor, p);
sl@0
   671
			}
sl@0
   672
		else
sl@0
   673
			{
sl@0
   674
			// Assert if MOutlineAndShadowBlend interface is not implemented
sl@0
   675
			BG_ASSERT_DEBUG(outlineAndShadow, EBitgdiPanicInvalidInterfaceHandle);
sl@0
   676
			}
sl@0
   677
		}
sl@0
   678
	else
sl@0
   679
		{
sl@0
   680
		for (int row = top_row; row < bottom_row; row++, p += aDataSize.iWidth, y++)
sl@0
   681
			iDevice->iDrawDevice->WriteRgbAlphaMulti(x,y,cols,iPenColor,p);
sl@0
   682
		}
sl@0
   683
	}
sl@0
   684
sl@0
   685
void CFbsBitGc::DoDrawTextLarge(CFont::TPositionParam& aParam,const CBitmapFont* font,const TInt aEnd)
sl@0
   686
	{
sl@0
   687
	const TInt charclipping = iClipRect.iBr.iX;
sl@0
   688
	TPoint start_pen = aParam.iPen;
sl@0
   689
	const TInt strikeheight = start_pen.iY - (font->CBitmapFont::DoAscentInPixels() * 5/12) - 1;
sl@0
   690
	const TBool bold = font->iAlgStyle.IsBold();
sl@0
   691
	const TBool italic = font->iAlgStyle.IsItalic();
sl@0
   692
	const TInt widthfactor=font->iAlgStyle.WidthFactor();
sl@0
   693
	const TInt heightfactor=font->iAlgStyle.HeightFactor();
sl@0
   694
sl@0
   695
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   696
sl@0
   697
	RShapeInfo shapeInfo;
sl@0
   698
	while (aParam.iPosInText < aEnd)
sl@0
   699
		{
sl@0
   700
		if (!iFont.GetCharacterPosition2(aParam, shapeInfo))
sl@0
   701
			continue;
sl@0
   702
		TInt adjustment = 0;
sl@0
   703
		if(iCharJustExcess && iCharJustNum > 0) // character clipping/justification
sl@0
   704
			{
sl@0
   705
			adjustment = CGraphicsContext::JustificationInPixels(iCharJustExcess,iCharJustNum);
sl@0
   706
			if(adjustment < 0)
sl@0
   707
				iClipRect.iBr.iX = Min(aParam.iPen.iX + adjustment,iClipRect.iBr.iX);
sl@0
   708
			}
sl@0
   709
sl@0
   710
		const CFont::TPositionParam::TOutput* output = aParam.iOutput;
sl@0
   711
		for (int i = 0; i < aParam.iOutputGlyphs; i++, output++)
sl@0
   712
			DoDrawCharacterLarge(output->iBounds.iTl,output->iBitmapSize,output->iBitmap,bold,italic,strikeheight,
sl@0
   713
								 widthfactor,heightfactor);
sl@0
   714
sl@0
   715
		iClipRect.iBr.iX = charclipping;
sl@0
   716
		if (adjustment)
sl@0
   717
			aParam.iPen.iX += adjustment;
sl@0
   718
		if (iWordJustExcess > 0 && iWordJustNum > 0 && aParam.iOutput[0].iCode == 0x0020) // word justification
sl@0
   719
			{
sl@0
   720
			adjustment = CGraphicsContext::JustificationInPixels(iWordJustExcess,iWordJustNum);
sl@0
   721
			aParam.iPen.iX += adjustment;
sl@0
   722
			}
sl@0
   723
		}
sl@0
   724
	if (shapeInfo.IsOpen())
sl@0
   725
		shapeInfo.Close();
sl@0
   726
	const TInt ulwidth = Max(font->CBitmapFont::DoHeightInPixels() / 10, 1);
sl@0
   727
	if (iUnderline == EUnderlineOn)
sl@0
   728
		{
sl@0
   729
		TInt ulstart = start_pen.iY + 1 + ulwidth / 2;
sl@0
   730
		TRect ul(start_pen.iX,ulstart,aParam.iPen.iX,ulstart + ulwidth);
sl@0
   731
		if(ul.Intersects(iClipRect)) // checks for empty aRect as well
sl@0
   732
			{
sl@0
   733
			ul.Intersection(iClipRect);
sl@0
   734
			drawDevice->WriteRgbMulti(ul.iTl.iX,ul.iTl.iY,ul.iBr.iX-ul.iTl.iX,ul.iBr.iY-ul.iTl.iY,iPenColor,iDrawMode);
sl@0
   735
			}
sl@0
   736
		}
sl@0
   737
sl@0
   738
	if (iStrikethrough == EStrikethroughOn)
sl@0
   739
		{
sl@0
   740
		TRect st(start_pen.iX,strikeheight,aParam.iPen.iX,strikeheight + ulwidth);
sl@0
   741
		if(st.Intersects(iClipRect)) // checks for empty aRect as well
sl@0
   742
			{
sl@0
   743
			st.Intersection(iClipRect);
sl@0
   744
			drawDevice->WriteRgbMulti(st.iTl.iX,st.iTl.iY,st.iBr.iX-st.iTl.iX,st.iBr.iY-st.iTl.iY,iPenColor,iDrawMode);
sl@0
   745
			}
sl@0
   746
		}
sl@0
   747
	}
sl@0
   748
sl@0
   749
void CFbsBitGc::DoDrawCharacterLarge(const TPoint& aTopLeft,const TSize& aDataSize,const TUint8* aData,
sl@0
   750
									 TBool aBold,TBool aItalic,TInt aSemiAscent,TInt aWidthFactor,TInt aHeightFactor)
sl@0
   751
	{
sl@0
   752
	TInt datalength = aDataSize.iWidth;
sl@0
   753
	TInt dataheight = aDataSize.iHeight;
sl@0
   754
	
sl@0
   755
	if (aWidthFactor > 2 || aHeightFactor > 2)
sl@0
   756
		{
sl@0
   757
		DoDrawCharacterMultiplied(aTopLeft,aDataSize,aData,aBold,aItalic,aSemiAscent,aWidthFactor,aHeightFactor);
sl@0
   758
		return;
sl@0
   759
		}
sl@0
   760
	
sl@0
   761
	if (datalength > 30 || dataheight > 32 || (aWidthFactor == 2 && datalength > 14))
sl@0
   762
		{
sl@0
   763
		DoDrawCharacterExLarge(aTopLeft,aDataSize,aData,aBold,aItalic,aSemiAscent,aWidthFactor,aHeightFactor);
sl@0
   764
		return;
sl@0
   765
		}
sl@0
   766
	
sl@0
   767
	TInt italicheight=aSemiAscent-aTopLeft.iY;
sl@0
   768
	if(aHeightFactor==2) italicheight>>=1;
sl@0
   769
	TInt bitindex=0;
sl@0
   770
	TInt16 repeatcount=0;
sl@0
   771
	TUint32 binarydata[64];
sl@0
   772
	TUint32* binarydataptr=binarydata;
sl@0
   773
	TUint32* binarydataptrlimit;
sl@0
   774
sl@0
   775
	for(TInt charline=0;charline<dataheight;charline+=repeatcount) // for lines in the character...
sl@0
   776
		{
sl@0
   777
		repeatcount=Load16(aData+(bitindex>>3));
sl@0
   778
		repeatcount>>=bitindex&7;
sl@0
   779
		TInt multilineflag=repeatcount&1;
sl@0
   780
		repeatcount>>=1;
sl@0
   781
		repeatcount&=0xf;
sl@0
   782
		bitindex+=5;
sl@0
   783
		binarydataptrlimit=binarydata+charline+repeatcount;
sl@0
   784
		if(multilineflag)
sl@0
   785
			{
sl@0
   786
			while(binarydataptr<binarydataptrlimit)
sl@0
   787
				{
sl@0
   788
				CopyCharWord(binarydataptr,aData+(bitindex>>3),bitindex&7);
sl@0
   789
				bitindex+=datalength;
sl@0
   790
				binarydataptr++;
sl@0
   791
				}
sl@0
   792
			}
sl@0
   793
		else
sl@0
   794
			{
sl@0
   795
			TUint32 data=0;
sl@0
   796
			CopyCharWord(&data,aData+(bitindex>>3),bitindex&7);
sl@0
   797
			while(binarydataptr<binarydataptrlimit)
sl@0
   798
				*binarydataptr++=data;
sl@0
   799
			bitindex+=datalength;
sl@0
   800
			}
sl@0
   801
		}
sl@0
   802
	binarydataptr=binarydata;
sl@0
   803
	binarydataptrlimit=binarydata+dataheight;
sl@0
   804
	if(aBold)
sl@0
   805
		{
sl@0
   806
		TInt sparemask=(0xffffffff>>(32-datalength));
sl@0
   807
		while(binarydataptr<binarydataptrlimit)
sl@0
   808
			{
sl@0
   809
			*binarydataptr&=sparemask;
sl@0
   810
			*binarydataptr|=(*binarydataptr<<1);
sl@0
   811
			++binarydataptr;
sl@0
   812
			}
sl@0
   813
		binarydataptr=binarydata;
sl@0
   814
		datalength++;
sl@0
   815
		}
sl@0
   816
	if(aItalic)
sl@0
   817
		{
sl@0
   818
		TUint32 sparemask=(0xffffffff>>(32-datalength));
sl@0
   819
		binarydataptrlimit=Min(binarydataptrlimit,binarydata+italicheight);
sl@0
   820
		while(binarydataptr<binarydataptrlimit)
sl@0
   821
			{
sl@0
   822
			*binarydataptr<<=1;
sl@0
   823
			*binarydataptr++&=0xfffffffe;
sl@0
   824
			}
sl@0
   825
		binarydataptrlimit=binarydata+dataheight;
sl@0
   826
		while(binarydataptr<binarydataptrlimit)
sl@0
   827
			*binarydataptr++&=sparemask;
sl@0
   828
		binarydataptr=binarydata;
sl@0
   829
		datalength++;
sl@0
   830
		}
sl@0
   831
	if(aWidthFactor==2)
sl@0
   832
		{
sl@0
   833
		BG_ASSERT_DEBUG(datalength<=16,EBitgdiPanicCharacterTooBig);
sl@0
   834
		while(binarydataptr<binarydataptrlimit)
sl@0
   835
			{
sl@0
   836
			TUint32 singlemask=0x8000;
sl@0
   837
			TUint32 doublemask=0xc0000000;
sl@0
   838
			TUint32 newdata=0;
sl@0
   839
			while(singlemask)
sl@0
   840
				{
sl@0
   841
				if(*binarydataptr&singlemask)
sl@0
   842
					newdata|=doublemask;
sl@0
   843
				singlemask>>=1;
sl@0
   844
				doublemask>>=2;
sl@0
   845
				}
sl@0
   846
			*binarydataptr++=newdata;
sl@0
   847
			}
sl@0
   848
		datalength<<=1;
sl@0
   849
		binarydataptr=binarydata;
sl@0
   850
		}
sl@0
   851
	if(aHeightFactor==2)
sl@0
   852
		{
sl@0
   853
		binarydataptr=binarydata+dataheight-1;
sl@0
   854
		TUint32* tempptr=binarydataptr+dataheight;
sl@0
   855
		while(binarydataptr>=binarydata)
sl@0
   856
			{
sl@0
   857
			*tempptr--=*binarydataptr;
sl@0
   858
			*tempptr--=*binarydataptr--;
sl@0
   859
			}
sl@0
   860
		dataheight<<=1;
sl@0
   861
		binarydataptr=binarydata;
sl@0
   862
		}
sl@0
   863
	TPoint startpos=aTopLeft;
sl@0
   864
	binarydataptr=ClipBinaryArray(binarydata,binarydata+dataheight,1,datalength,dataheight,startpos);
sl@0
   865
	if(datalength>0 && dataheight>0)
sl@0
   866
		iDevice->iDrawDevice->WriteBinary(startpos.iX,startpos.iY,binarydataptr,datalength,dataheight,iPenColor,iDrawMode);
sl@0
   867
	}
sl@0
   868
sl@0
   869
void CFbsBitGc::DoDrawCharacterExLarge(const TPoint& aTopLeft,const TSize& aDataSize,const TUint8* aData,
sl@0
   870
									   TBool aBold,TBool aItalic,TInt aSemiAscent,TInt aWidthFactor,TInt aHeightFactor)
sl@0
   871
	{
sl@0
   872
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   873
	TPoint printpos(aTopLeft);
sl@0
   874
	const TInt datalength = aDataSize.iWidth;
sl@0
   875
	const TInt dataheight = aDataSize.iHeight;
sl@0
   876
	TInt bitindex=0;
sl@0
   877
	TInt16 repeatcount=0;
sl@0
   878
	TUint32* slbuffer=drawDevice->ScanLineBuffer();
sl@0
   879
	const TInt slwords=(drawDevice->ScanLineBytes())<<3;
sl@0
   880
	if(aItalic && aTopLeft.iY<aSemiAscent)
sl@0
   881
		printpos.iX++;
sl@0
   882
	for(TInt charline=0;charline<dataheight;charline+=repeatcount) // for lines in the character...
sl@0
   883
		{
sl@0
   884
		repeatcount=Load16(aData+(bitindex>>3));
sl@0
   885
		repeatcount>>=bitindex&7;
sl@0
   886
		const TInt multilineflag=repeatcount&1;
sl@0
   887
		repeatcount>>=1;
sl@0
   888
		repeatcount&=0xf;
sl@0
   889
		bitindex+=5;
sl@0
   890
		if(multilineflag)
sl@0
   891
			{
sl@0
   892
			for(TInt currentline=0;currentline<repeatcount;currentline++)
sl@0
   893
				{
sl@0
   894
				CopyCharLine(slbuffer,slwords,aData+(bitindex>>3),bitindex&7,datalength);
sl@0
   895
				OutputCharLineMultiplied(printpos,slbuffer,datalength,1,aBold,aWidthFactor,aHeightFactor);
sl@0
   896
				bitindex+=datalength;
sl@0
   897
				printpos.iY++;
sl@0
   898
				if(printpos.iY==aSemiAscent && aItalic) printpos.iX--;
sl@0
   899
				if(aHeightFactor==2)
sl@0
   900
					{
sl@0
   901
					printpos.iY++;
sl@0
   902
					if(printpos.iY==aSemiAscent && aItalic) printpos.iX--;
sl@0
   903
					}
sl@0
   904
				}
sl@0
   905
			}
sl@0
   906
		else
sl@0
   907
			{
sl@0
   908
			if(aItalic)
sl@0
   909
				{
sl@0
   910
				for(TInt currentline=0;currentline<repeatcount;currentline++)
sl@0
   911
					{
sl@0
   912
					CopyCharLine(slbuffer,slwords,aData+(bitindex>>3),bitindex&7,datalength);
sl@0
   913
					OutputCharLineMultiplied(printpos,slbuffer,datalength,1,aBold,aWidthFactor,aHeightFactor);
sl@0
   914
					printpos.iY++;
sl@0
   915
					if(printpos.iY==aSemiAscent && aItalic) printpos.iX--;
sl@0
   916
					if(aHeightFactor==2)
sl@0
   917
						{
sl@0
   918
						printpos.iY++;
sl@0
   919
						if(printpos.iY==aSemiAscent && aItalic) printpos.iX--;
sl@0
   920
						}
sl@0
   921
					}
sl@0
   922
				}
sl@0
   923
			else
sl@0
   924
				{
sl@0
   925
				CopyCharLine(slbuffer,slwords,aData+(bitindex>>3),bitindex&7,datalength);
sl@0
   926
				OutputCharLineMultiplied(printpos,slbuffer,datalength,repeatcount,aBold,aWidthFactor,aHeightFactor);
sl@0
   927
				printpos.iY+=repeatcount;
sl@0
   928
				if(aHeightFactor==2) printpos.iY+=repeatcount;
sl@0
   929
				}
sl@0
   930
			bitindex+=datalength;
sl@0
   931
			}
sl@0
   932
		}
sl@0
   933
	}
sl@0
   934
sl@0
   935
void CFbsBitGc::DoDrawCharacterMultiplied(const TPoint& aTopLeft,const TSize& aDataSize,const TUint8* aData,
sl@0
   936
										  TBool aBold,TBool aItalic,TInt aSemiAscent,TInt aWidthFactor,TInt aHeightFactor)
sl@0
   937
	{
sl@0
   938
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   939
	TPoint printpos(aTopLeft);
sl@0
   940
	const TInt datalength = aDataSize.iWidth;
sl@0
   941
	const TInt dataheight = aDataSize.iHeight;
sl@0
   942
	TInt bitindex=0;
sl@0
   943
	TInt16 repeatcount=0;
sl@0
   944
	TUint32* slbuffer=drawDevice->ScanLineBuffer();
sl@0
   945
	const TInt slwords=(drawDevice->ScanLineBytes())<<3;
sl@0
   946
	if(aItalic && aTopLeft.iY<aSemiAscent)
sl@0
   947
		printpos.iX++;
sl@0
   948
	for(TInt charline=0;charline<dataheight;charline+=repeatcount) // for lines in the character...
sl@0
   949
		{
sl@0
   950
		repeatcount=Load16(aData+(bitindex>>3));
sl@0
   951
		repeatcount>>=bitindex&7;
sl@0
   952
		const TInt multilineflag=repeatcount&1;
sl@0
   953
		repeatcount>>=1;
sl@0
   954
		repeatcount&=0xf;
sl@0
   955
		bitindex+=5;
sl@0
   956
		if(multilineflag)
sl@0
   957
			{
sl@0
   958
			for(TInt currentline=0;currentline<repeatcount;currentline++)
sl@0
   959
				{
sl@0
   960
				CopyCharLine(slbuffer,slwords,aData+(bitindex>>3),bitindex&7,datalength);
sl@0
   961
				OutputCharLineMultiplied(printpos,slbuffer,datalength,1,aBold,aWidthFactor,aHeightFactor);
sl@0
   962
				bitindex+=datalength;
sl@0
   963
				TBool aboveitalicjump=EFalse;
sl@0
   964
				if(aItalic && printpos.iY<aSemiAscent) aboveitalicjump=ETrue;
sl@0
   965
				printpos.iY+=aHeightFactor;
sl@0
   966
				if(aboveitalicjump && printpos.iY>=aSemiAscent) printpos.iX-=aWidthFactor;
sl@0
   967
				}
sl@0
   968
			}
sl@0
   969
		else
sl@0
   970
			{
sl@0
   971
			if(aItalic)
sl@0
   972
				{
sl@0
   973
				for(TInt currentline=0;currentline<repeatcount;currentline++)
sl@0
   974
					{
sl@0
   975
					CopyCharLine(slbuffer,slwords,aData+(bitindex>>3),bitindex&7,datalength);
sl@0
   976
					OutputCharLineMultiplied(printpos,slbuffer,datalength,1,aBold,aWidthFactor,aHeightFactor);
sl@0
   977
					TBool aboveitalicjump=EFalse;
sl@0
   978
					if(printpos.iY<aSemiAscent) aboveitalicjump=ETrue;
sl@0
   979
					printpos.iY+=aHeightFactor;
sl@0
   980
					if(aboveitalicjump && printpos.iY>=aSemiAscent) printpos.iX-=aWidthFactor;
sl@0
   981
					}
sl@0
   982
				}
sl@0
   983
			else
sl@0
   984
				{
sl@0
   985
				CopyCharLine(slbuffer,slwords,aData+(bitindex>>3),bitindex&7,datalength);
sl@0
   986
				OutputCharLineMultiplied(printpos,slbuffer,datalength,repeatcount,aBold,aWidthFactor,aHeightFactor);
sl@0
   987
				printpos.iY+=repeatcount*aHeightFactor;
sl@0
   988
				}
sl@0
   989
			bitindex+=datalength;
sl@0
   990
			}
sl@0
   991
		}
sl@0
   992
	}
sl@0
   993
sl@0
   994
void CFbsBitGc::OutputCharLineMultiplied(TPoint aPrintPos,TUint32* aBuffer,TInt aDataLength,TInt aNum,TBool aBold,TInt aWidthFactor,TInt aHeightFactor)
sl@0
   995
	{
sl@0
   996
	if(aDataLength<=0) return;
sl@0
   997
	TInt bufferwords=(aDataLength+31)>>5;
sl@0
   998
	TUint32* bufferlimit=aBuffer+bufferwords;
sl@0
   999
	if(aBold)
sl@0
  1000
		{
sl@0
  1001
		TInt sparemask=(0xffffffff>>(32-(aDataLength&0x1f)));
sl@0
  1002
		if((aDataLength&0x1f)==0) sparemask=0xffffffff;
sl@0
  1003
		*(bufferlimit-1)&=sparemask;
sl@0
  1004
		TUint32* bufferptr=aBuffer;
sl@0
  1005
		TUint32 extrabit=0;
sl@0
  1006
		while(bufferptr<bufferlimit)
sl@0
  1007
			{
sl@0
  1008
			extrabit=*bufferptr>>31;
sl@0
  1009
			*bufferptr|=(*bufferptr<<1);
sl@0
  1010
			++bufferptr;
sl@0
  1011
			if(bufferptr<bufferlimit)
sl@0
  1012
				*bufferptr|=extrabit;
sl@0
  1013
			}
sl@0
  1014
		aDataLength++;
sl@0
  1015
		if((aDataLength&0x1f)==1)
sl@0
  1016
			{
sl@0
  1017
			bufferwords++;
sl@0
  1018
			*bufferlimit=extrabit;
sl@0
  1019
			bufferlimit++;
sl@0
  1020
			}
sl@0
  1021
		}
sl@0
  1022
	if(aWidthFactor>1)
sl@0
  1023
		{
sl@0
  1024
		BitMultiply(aBuffer,aDataLength,aWidthFactor);
sl@0
  1025
		aDataLength*=aWidthFactor;
sl@0
  1026
		bufferwords=(aDataLength+31)>>5;
sl@0
  1027
		bufferlimit=aBuffer+bufferwords;
sl@0
  1028
		}
sl@0
  1029
	if(aPrintPos.iX<iClipRect.iTl.iX)
sl@0
  1030
		{
sl@0
  1031
		TInt pixelexcess=iClipRect.iTl.iX-aPrintPos.iX;
sl@0
  1032
		while(pixelexcess>=32)
sl@0
  1033
			{
sl@0
  1034
			aBuffer++;
sl@0
  1035
			bufferwords--;
sl@0
  1036
			aDataLength-=32;
sl@0
  1037
			pixelexcess-=32;
sl@0
  1038
			}
sl@0
  1039
		if(aDataLength<=0) return;
sl@0
  1040
		if(pixelexcess>0)
sl@0
  1041
			{
sl@0
  1042
			TInt shiftup=32-pixelexcess;
sl@0
  1043
			TUint32* bufferptr=aBuffer;
sl@0
  1044
			while(bufferptr<bufferlimit)
sl@0
  1045
				{
sl@0
  1046
				*bufferptr>>=pixelexcess;
sl@0
  1047
				if(bufferptr<bufferlimit-1)
sl@0
  1048
					*bufferptr|=(*(bufferptr+1)<<shiftup);
sl@0
  1049
				bufferptr++;
sl@0
  1050
				}
sl@0
  1051
			aDataLength-=pixelexcess;
sl@0
  1052
			if(aDataLength<=0) return;
sl@0
  1053
			}
sl@0
  1054
		aPrintPos.iX=iClipRect.iTl.iX;
sl@0
  1055
		}
sl@0
  1056
	if(aPrintPos.iX+aDataLength>iClipRect.iBr.iX)
sl@0
  1057
		{
sl@0
  1058
		TInt pixelexcess=aPrintPos.iX+aDataLength-iClipRect.iBr.iX;
sl@0
  1059
		aDataLength-=pixelexcess;
sl@0
  1060
		if(aDataLength<=0) return;
sl@0
  1061
		}
sl@0
  1062
	aNum*=aHeightFactor;
sl@0
  1063
	while(aNum>0)
sl@0
  1064
		{
sl@0
  1065
		if(aPrintPos.iY>=iClipRect.iTl.iY && aPrintPos.iY<iClipRect.iBr.iY)
sl@0
  1066
			iDevice->iDrawDevice->WriteBinaryLine(aPrintPos.iX,aPrintPos.iY,aBuffer,aDataLength,iPenColor,iDrawMode);
sl@0
  1067
		aPrintPos.iY++;
sl@0
  1068
		aNum--;
sl@0
  1069
		}
sl@0
  1070
	}
sl@0
  1071
sl@0
  1072
void CFbsBitGc::CopyCharWord(TUint32* aBinaryDataPtr,const TUint8* aData,TInt aBitShift)
sl@0
  1073
	{
sl@0
  1074
	const TUint32* dataword=(TUint32*)(TInt(aData)&~3);
sl@0
  1075
	aBitShift+=(TInt(aData)-TInt(dataword))<<3;
sl@0
  1076
	*aBinaryDataPtr=*dataword++;
sl@0
  1077
	if(aBitShift<32) *aBinaryDataPtr>>=aBitShift;
sl@0
  1078
	if(aBitShift) *aBinaryDataPtr|=(*dataword<<(32-aBitShift));
sl@0
  1079
	}
sl@0
  1080
	
sl@0
  1081
void CFbsBitGc::CopyCharLine(TUint32* aBinaryDataPtr,TInt aBufferWords,const TUint8* aData,TInt aBitShift,TInt aCharWidth)
sl@0
  1082
	{
sl@0
  1083
	aBitShift&=7;
sl@0
  1084
	TInt wordstocopy=(aCharWidth+31)>>5;
sl@0
  1085
	if(wordstocopy>aBufferWords) wordstocopy=aBufferWords;
sl@0
  1086
	TUint32* ptrlimit=aBinaryDataPtr+wordstocopy;
sl@0
  1087
	TUint32* dataword=(TUint32*)(TInt(aData)&~3);
sl@0
  1088
	aBitShift+=(TInt(aData)-TInt(dataword))<<3;
sl@0
  1089
	while(aBinaryDataPtr<ptrlimit)
sl@0
  1090
		{
sl@0
  1091
		*aBinaryDataPtr=*dataword++;
sl@0
  1092
		*aBinaryDataPtr>>=aBitShift;
sl@0
  1093
		if(aBitShift) *aBinaryDataPtr|=(*dataword<<(32-aBitShift));
sl@0
  1094
		aBinaryDataPtr++;
sl@0
  1095
		}
sl@0
  1096
	}
sl@0
  1097
	
sl@0
  1098
TUint32* CFbsBitGc::ClipBinaryArray(TUint32* aArray,TUint32* aArrayLimit,TInt aArrayWordWd,TInt& aDataWd,TInt& aDataHt,TPoint& aPos)
sl@0
  1099
	{
sl@0
  1100
	TUint32* arrayptr=aArray;
sl@0
  1101
	TInt clipdiff=iClipRect.iTl.iX-aPos.iX;
sl@0
  1102
	if(aArrayWordWd==1)
sl@0
  1103
		{
sl@0
  1104
		if(clipdiff>0)
sl@0
  1105
			{
sl@0
  1106
			while(arrayptr<aArrayLimit)
sl@0
  1107
				*arrayptr++>>=clipdiff;
sl@0
  1108
			aDataWd-=clipdiff;
sl@0
  1109
			aPos.iX=iClipRect.iTl.iX;
sl@0
  1110
			arrayptr=aArray;
sl@0
  1111
			}
sl@0
  1112
		if(aPos.iX+aDataWd>iClipRect.iBr.iX && aDataWd>0)
sl@0
  1113
			aDataWd=iClipRect.iBr.iX-aPos.iX;
sl@0
  1114
		clipdiff=iClipRect.iTl.iY-aPos.iY;
sl@0
  1115
		if(clipdiff>0)
sl@0
  1116
			{
sl@0
  1117
			aDataHt-=clipdiff;
sl@0
  1118
			arrayptr+=clipdiff;
sl@0
  1119
			aPos.iY=iClipRect.iTl.iY;
sl@0
  1120
			}
sl@0
  1121
		if(aPos.iY+aDataHt>iClipRect.iBr.iY && aDataHt>0)
sl@0
  1122
			aDataHt=iClipRect.iBr.iY-aPos.iY;
sl@0
  1123
		}
sl@0
  1124
	return(arrayptr);
sl@0
  1125
	}
sl@0
  1126
sl@0
  1127
void CFbsBitGc::BitMultiply(TUint32* aBinaryDataPtr,TInt aBitLength,TInt aFactor)
sl@0
  1128
	{
sl@0
  1129
	TInt bitpos=aBitLength-1;
sl@0
  1130
	TUint32* wordpos=aBinaryDataPtr+(bitpos>>5);
sl@0
  1131
	TInt bitoffset=bitpos&0x1f;
sl@0
  1132
	TInt multbitpos=(aBitLength*aFactor)-1;
sl@0
  1133
	TUint32* multwordpos=aBinaryDataPtr+(multbitpos>>5);
sl@0
  1134
	TInt multbitoffset=multbitpos&0x1f;
sl@0
  1135
	while(bitpos>=0)
sl@0
  1136
		{
sl@0
  1137
		TUint32 bit=((*wordpos)>>bitoffset)&1;
sl@0
  1138
		TInt next=multbitpos-aFactor;
sl@0
  1139
		while(multbitpos>next)
sl@0
  1140
			{
sl@0
  1141
			if(bit) *multwordpos|=(1<<multbitoffset);
sl@0
  1142
			else *multwordpos&=~(1<<multbitoffset);
sl@0
  1143
			multbitpos--;
sl@0
  1144
			multbitoffset--;
sl@0
  1145
			if(multbitoffset<0)
sl@0
  1146
				{
sl@0
  1147
				multbitoffset=31;
sl@0
  1148
				multwordpos--;
sl@0
  1149
				}
sl@0
  1150
			}
sl@0
  1151
		bitpos--;
sl@0
  1152
		bitoffset--;
sl@0
  1153
		if(bitoffset<0)
sl@0
  1154
			{
sl@0
  1155
			bitoffset=31;
sl@0
  1156
			wordpos--;
sl@0
  1157
			}
sl@0
  1158
		}
sl@0
  1159
	}
sl@0
  1160
sl@0
  1161
void CFbsBitGc::GetStrikethroughMetrics(TInt& aTop,TInt& aBottom)
sl@0
  1162
/** Get the top and bottom of a strikethrough line for the current font, relative to the baseline.*/
sl@0
  1163
	{
sl@0
  1164
	aTop = -(iFont.AscentInPixels() * 5/12) - 1;
sl@0
  1165
	aBottom = aTop + Max(iFont.HeightInPixels() / 10,1);
sl@0
  1166
	}
sl@0
  1167
sl@0
  1168
/** APIExtension can contain as many additional methods as is required by 
sl@0
  1169
CGraphicsContext after its original conception. It takes 3 parameters.
sl@0
  1170
Function is exported due to constrains of retaining BC with earlier versions.
sl@0
  1171
This is not used directly by external methods, instead it is called by a named 
sl@0
  1172
method in CGraphicsContext which passes the relivant arguements including an 
sl@0
  1173
unique identifier for the required action.
sl@0
  1174
@param aUid The unique identifier for the method that is required. Selected 
sl@0
  1175
internally by a series of "if" statements. 
sl@0
  1176
@see Valid Uid identifiers are listed in header gdi.h
sl@0
  1177
@see CGraphicsContext
sl@0
  1178
@param aOutput is a TAny pointer to a reference. Used to output data as the structure
sl@0
  1179
does not need to be instantiated before the function call this adds greater 
sl@0
  1180
flexibility.
sl@0
  1181
@param aInput is a TAny pointer used to input data.
sl@0
  1182
*/	
sl@0
  1183
EXPORT_C TInt CFbsBitGc::APIExtension(TUid aUid, TAny*& aOutput, TAny* aInput)
sl@0
  1184
	{
sl@0
  1185
	if (aUid == KGetUnderlineMetrics)
sl@0
  1186
		{		
sl@0
  1187
		APIExGetUnderlineMetrics(aOutput);
sl@0
  1188
		return KErrNone;	
sl@0
  1189
		}
sl@0
  1190
	else if (aUid == KSetShadowColor)
sl@0
  1191
		{
sl@0
  1192
		return APIExSetShadowColor(aInput);
sl@0
  1193
		}
sl@0
  1194
	else if (aUid == KGetShadowColor)
sl@0
  1195
		{
sl@0
  1196
		return APIExGetShadowColor(aOutput);
sl@0
  1197
		}
sl@0
  1198
	else if (aUid == KDrawTextInContextUid)
sl@0
  1199
		{
sl@0
  1200
		TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput;
sl@0
  1201
		DrawText(contextParam->iText, &contextParam->iParam, contextParam->iPosition);
sl@0
  1202
		return KErrNone;
sl@0
  1203
		}
sl@0
  1204
	else if (aUid == KDrawBoxTextInContextUid)
sl@0
  1205
		{
sl@0
  1206
		TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput;
sl@0
  1207
		DrawText(contextParam->iText,&contextParam->iParam,contextParam->iBox,contextParam->iBaselineOffset,contextParam->iAlign,contextParam->iMargin);
sl@0
  1208
		return KErrNone;
sl@0
  1209
		}
sl@0
  1210
	else if (aUid == KDrawTextInContextVerticalUid)
sl@0
  1211
		{
sl@0
  1212
		TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput;
sl@0
  1213
		DrawTextVertical(contextParam->iText, &contextParam->iParam, contextParam->iPosition,contextParam->iUp);
sl@0
  1214
		return KErrNone;
sl@0
  1215
		}
sl@0
  1216
	else if (aUid == KDrawBoxTextInContextVerticalUid)
sl@0
  1217
		{
sl@0
  1218
		TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput;
sl@0
  1219
		DrawTextVertical(contextParam->iText,&contextParam->iParam,contextParam->iBox,contextParam->iBaselineOffset,contextParam->iUp,contextParam->iAlign,contextParam->iMargin);
sl@0
  1220
		return KErrNone;
sl@0
  1221
		}
sl@0
  1222
	else if (aUid == KUidIsFbsBitmapGc)
sl@0
  1223
		{
sl@0
  1224
		return APIExIsFbsBitGc(aOutput);
sl@0
  1225
		}
sl@0
  1226
	/* Future cases may be placed here later.*/
sl@0
  1227
	else
sl@0
  1228
		return CBitmapContext::APIExtension(aUid, aOutput, aInput);
sl@0
  1229
	}
sl@0
  1230
	
sl@0
  1231
	
sl@0
  1232
	
sl@0
  1233
	
sl@0
  1234
		
sl@0
  1235
	
sl@0
  1236
	
sl@0
  1237
	
sl@0
  1238
	
sl@0
  1239
//The methods listed above in APIExtension follow here with the prefix APIEx.
sl@0
  1240
void CFbsBitGc::APIExGetUnderlineMetrics(TAny*& aOutput)
sl@0
  1241
	{
sl@0
  1242
	const TInt width = Max(iFont.HeightInPixels() / 10,1);
sl@0
  1243
	TTwoTInt* ptr = (TTwoTInt*)aOutput;
sl@0
  1244
	ptr->iTop = 1 + width / 2;
sl@0
  1245
	ptr->iBottom = (ptr->iTop) + width;
sl@0
  1246
	}
sl@0
  1247
sl@0
  1248
TInt CFbsBitGc::APIExSetShadowColor(TAny* aShadowColor)
sl@0
  1249
	{
sl@0
  1250
	iFbsBitGcExtraData->SetShadowColor(*(reinterpret_cast<TRgb*>(aShadowColor)));
sl@0
  1251
	return KErrNone;
sl@0
  1252
	}
sl@0
  1253
sl@0
  1254
TInt CFbsBitGc::APIExGetShadowColor(TAny*& aShadowColor)
sl@0
  1255
	{
sl@0
  1256
	TRgb* output = reinterpret_cast<TRgb*>(aShadowColor);
sl@0
  1257
	*output = iFbsBitGcExtraData->ShadowColor();
sl@0
  1258
	return KErrNone;
sl@0
  1259
	}
sl@0
  1260
	
sl@0
  1261
TInt CFbsBitGc::APIExIsFbsBitGc(TAny*& aIsCFbsBitGc)
sl@0
  1262
	{
sl@0
  1263
	TBool *output = reinterpret_cast<TBool*>(aIsCFbsBitGc);
sl@0
  1264
	*output = ETrue;
sl@0
  1265
	return KErrNone;
sl@0
  1266
	}
sl@0
  1267
sl@0
  1268
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TTextParameters* aParam)
sl@0
  1269
	{
sl@0
  1270
	DrawText(aText,aParam,iLastPrintPosition,ELeft,CFont::EHorizontal);
sl@0
  1271
	}
sl@0
  1272
sl@0
  1273
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TTextParameters* aParam,const TPoint& aPosition)
sl@0
  1274
	{
sl@0
  1275
	DrawText(aText,aParam,aPosition,ELeft,CFont::EHorizontal);
sl@0
  1276
	}
sl@0
  1277
	
sl@0
  1278
	
sl@0
  1279
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TTextParameters* aParam,const TRect& aBox)
sl@0
  1280
	{
sl@0
  1281
	TRect boxcpy(aBox);
sl@0
  1282
	boxcpy.Move(iOrigin);
sl@0
  1283
	if(!iUserClipRect.Intersects(boxcpy)) return;
sl@0
  1284
	TRect oldcliprect(iUserClipRect);
sl@0
  1285
	iUserClipRect.Intersection(boxcpy);
sl@0
  1286
	DrawText(aText,aParam);
sl@0
  1287
	iUserClipRect=oldcliprect;
sl@0
  1288
	}
sl@0
  1289
	
sl@0
  1290
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TTextParameters* aParam,const TRect& aBox,TInt aBaselineOffset,TTextAlign aHrz,TInt aMargin)
sl@0
  1291
	{
sl@0
  1292
	DrawText(aText,aParam,aBox,aBaselineOffset,-1,aHrz,aMargin);
sl@0
  1293
	}
sl@0
  1294
	
sl@0
  1295
EXPORT_C void CFbsBitGc::DrawText(const TDesC& aText,const TTextParameters* aParam,const TRect& aBox,TInt aBaselineOffset,TInt /*aTextWidth*/,TTextAlign aHrz,TInt aMargin)
sl@0
  1296
	{
sl@0
  1297
	// aTextWidth is not used here - try to abolish this - I think it is unneeded
sl@0
  1298
	TPoint p(aBox.iTl);
sl@0
  1299
	p.iY += aBaselineOffset;
sl@0
  1300
	switch (aHrz)
sl@0
  1301
		{
sl@0
  1302
		case ELeft: p.iX += aMargin; break;
sl@0
  1303
		case ERight: p.iX = aBox.iBr.iX - aMargin; break;
sl@0
  1304
		case ECenter: p.iX += aBox.Width() / 2 + aMargin; break;
sl@0
  1305
		}
sl@0
  1306
	DrawText(aText,aParam,p,aHrz,CFont::EHorizontal,&aBox);
sl@0
  1307
	}