os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgditext.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2008-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 "swdirectgdiengine.h"
sl@0
    17
#include <bitdrawinterfaceid.h>
sl@0
    18
#include <bmalphablend.h>
sl@0
    19
sl@0
    20
/**
sl@0
    21
@see MDirectGdiEngine::SetFont()
sl@0
    22
*/
sl@0
    23
void CSwDirectGdiEngine::SetFont(TUint32 /*aFontId*/)
sl@0
    24
	{
sl@0
    25
	// Do nothing.
sl@0
    26
	// The SW adapter doesn't need the font ID to index a separate font cache because it uses the standard one.
sl@0
    27
	}
sl@0
    28
sl@0
    29
sl@0
    30
/**
sl@0
    31
@see MDirectGdiEngine::ResetFont()
sl@0
    32
*/
sl@0
    33
void CSwDirectGdiEngine::ResetFont()
sl@0
    34
	{
sl@0
    35
	}
sl@0
    36
sl@0
    37
sl@0
    38
/**
sl@0
    39
@see MDirectGdiEngine::SetTextShadowColor()
sl@0
    40
*/
sl@0
    41
void CSwDirectGdiEngine::SetTextShadowColor(const TRgb& aColor)
sl@0
    42
	{	
sl@0
    43
	iTextShadowColor = aColor;
sl@0
    44
	}
sl@0
    45
sl@0
    46
/**
sl@0
    47
@see MDirectGdiEngine::BeginDrawGlyph()
sl@0
    48
*/
sl@0
    49
void CSwDirectGdiEngine::BeginDrawGlyph()
sl@0
    50
	{
sl@0
    51
	}
sl@0
    52
sl@0
    53
/**
sl@0
    54
@see MDirectGdiEngine::DrawGlyph()
sl@0
    55
@panic DGDIAdapter 56, if an invalid glyph bitmap type is passed in.
sl@0
    56
*/
sl@0
    57
void CSwDirectGdiEngine::DrawGlyph(const TPoint& aScrPos, const TChar /*aChar*/, const TUint8* aGlyphImage,
sl@0
    58
								   const TGlyphBitmapType aGlyphBitmapType, const TSize& aGlyphImageSize,
sl@0
    59
								   const TRect& aScrClipRect, const DirectGdi::TGraphicsRotation aRotation)
sl@0
    60
	{
sl@0
    61
	TPoint pos=aScrPos;
sl@0
    62
	pos+=iDrawOrigin;
sl@0
    63
	TRect clipRect=aScrClipRect;
sl@0
    64
	clipRect.iTl+=iDrawOrigin;
sl@0
    65
	clipRect.iBr+=iDrawOrigin;
sl@0
    66
	TRect regionRect(0, 0, 0, 0);
sl@0
    67
	TInt numRects = iDefaultRegionPtr->Count();
sl@0
    68
	for (TInt count = 0; count < numRects; count++)
sl@0
    69
		{
sl@0
    70
		// Do the clip rects intersect?
sl@0
    71
		regionRect = (*iDefaultRegionPtr)[count];
sl@0
    72
		if (!regionRect.Intersects(clipRect))
sl@0
    73
			{
sl@0
    74
			// Nothing to draw
sl@0
    75
			continue;
sl@0
    76
			}
sl@0
    77
		// Clip to intersection of two clip rects
sl@0
    78
		regionRect.Intersection(clipRect);
sl@0
    79
		
sl@0
    80
		if (aRotation == DirectGdi::EGraphicsRotationNone)	// Horizontal text
sl@0
    81
			{
sl@0
    82
			// Do the glyph and the clip rect intersect?
sl@0
    83
			TRect glyphRect(pos, aGlyphImageSize);
sl@0
    84
			if (!regionRect.Intersects(glyphRect))
sl@0
    85
				{
sl@0
    86
				// Nothing to draw
sl@0
    87
				continue;
sl@0
    88
				}
sl@0
    89
			// Clip to intersection with glyph bitmap 
sl@0
    90
			regionRect.Intersection(glyphRect);
sl@0
    91
			
sl@0
    92
			switch (aGlyphBitmapType)
sl@0
    93
				{
sl@0
    94
				case EMonochromeGlyphBitmap:
sl@0
    95
					{
sl@0
    96
					DrawBitmapGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect);
sl@0
    97
					break;
sl@0
    98
					}
sl@0
    99
				case EAntiAliasedGlyphBitmap:
sl@0
   100
					{
sl@0
   101
					DrawAntiAliasedGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect);
sl@0
   102
					break;
sl@0
   103
					}
sl@0
   104
				case EFourColourBlendGlyphBitmap:
sl@0
   105
					{
sl@0
   106
					DrawFourColourGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect);
sl@0
   107
					break;
sl@0
   108
					}
sl@0
   109
				default:
sl@0
   110
					GRAPHICS_PANIC_ALWAYS(EDirectGdiPanicInvalidGlyphBitmapType);
sl@0
   111
				}
sl@0
   112
			}
sl@0
   113
		else	// Vertical text
sl@0
   114
			{
sl@0
   115
			/*
sl@0
   116
			// Do the glyph and the clip rect intersect?
sl@0
   117
			TRect glyphRect(aPos, aGlyphImageSize);
sl@0
   118
			if (!regionRect.Intersects(glyphRect))
sl@0
   119
				{
sl@0
   120
				// Nothing to draw
sl@0
   121
				continue;
sl@0
   122
				}
sl@0
   123
			// Clip to intersection with glyph bitmap 
sl@0
   124
			regionRect.Intersection(glyphRect);
sl@0
   125
			*/
sl@0
   126
			
sl@0
   127
			switch (aGlyphBitmapType)
sl@0
   128
				{
sl@0
   129
				case EMonochromeGlyphBitmap:
sl@0
   130
					{
sl@0
   131
					DrawRotatedBitmapGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect, aRotation);
sl@0
   132
					break;
sl@0
   133
					}
sl@0
   134
				case EAntiAliasedGlyphBitmap:
sl@0
   135
					{
sl@0
   136
					DrawRotatedAntiAliasedGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect, aRotation);
sl@0
   137
					break;
sl@0
   138
					}
sl@0
   139
				case EFourColourBlendGlyphBitmap:
sl@0
   140
					{
sl@0
   141
					DrawRotatedFourColourGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect, aRotation);
sl@0
   142
					break;
sl@0
   143
					}
sl@0
   144
				default:
sl@0
   145
					GRAPHICS_PANIC_ALWAYS(EDirectGdiPanicInvalidGlyphBitmapType);
sl@0
   146
				}
sl@0
   147
			}
sl@0
   148
		// Now display it
sl@0
   149
		iDrawDevice->UpdateRegion(regionRect);
sl@0
   150
		}
sl@0
   151
	}
sl@0
   152
sl@0
   153
/**
sl@0
   154
@see MDirectGdiEngine::EndDrawGlyph()
sl@0
   155
*/
sl@0
   156
void CSwDirectGdiEngine::EndDrawGlyph()
sl@0
   157
	{
sl@0
   158
	}
sl@0
   159
sl@0
   160
/**
sl@0
   161
Draw a bitmap glyph.
sl@0
   162
	
sl@0
   163
@param	aPos			Position to start drawing gyph.
sl@0
   164
@param	aGlyphImage		Pointer to the glyph image data.
sl@0
   165
@param	aGlyphImageSize	Glyph image size.
sl@0
   166
@param	aClipRect		Clipping rect.
sl@0
   167
*/
sl@0
   168
void CSwDirectGdiEngine::DrawBitmapGlyph(const TPoint& aPos, const TUint8* aGlyphImage,
sl@0
   169
										 const TSize& aGlyphImageSize, const TRect& aClipRect)
sl@0
   170
	{
sl@0
   171
	// aChar parameter not needed because SW implementation uses the default glyph cache
sl@0
   172
	// therefore does not need aChar to index its own local cache
sl@0
   173
	
sl@0
   174
	/*
sl@0
   175
	Divert if the character is large.
sl@0
   176
	Large is defined as wider than 30 bits (a scan line won't fit in a TInt32)
sl@0
   177
	or greater than 32 bits high (because that's the current array size - could be changed).
sl@0
   178
	*/
sl@0
   179
	TInt dataHeight = aGlyphImageSize.iHeight;
sl@0
   180
	TInt dataLength = aGlyphImageSize.iWidth;
sl@0
   181
	if (dataLength > 30 || dataHeight > 32)
sl@0
   182
		{
sl@0
   183
		DrawLargeBitmapGlyph(aPos, aGlyphImage, aGlyphImageSize, aClipRect);
sl@0
   184
		return;
sl@0
   185
		}
sl@0
   186
	
sl@0
   187
	TInt bitIndex = 0;
sl@0
   188
	TInt16 repeatCount = 0;
sl@0
   189
	TUint32 binaryData[32];
sl@0
   190
	TUint32* binaryDataPtr = binaryData;
sl@0
   191
	TUint32* binaryDataPtrLimit;
sl@0
   192
	for (TInt glyphLine = 0; glyphLine < dataHeight; glyphLine += repeatCount) // for lines in the glyph bitmap
sl@0
   193
		{
sl@0
   194
		repeatCount = Load16(aGlyphImage + (bitIndex >> 3));
sl@0
   195
		repeatCount >>= bitIndex & 7;
sl@0
   196
		TInt multiLineFlag = repeatCount & 1;
sl@0
   197
		repeatCount >>= 1;
sl@0
   198
		repeatCount &= 0xf;
sl@0
   199
		bitIndex += 5;
sl@0
   200
		binaryDataPtrLimit = binaryData + glyphLine + repeatCount;
sl@0
   201
		if (multiLineFlag)
sl@0
   202
			{
sl@0
   203
			while (binaryDataPtr < binaryDataPtrLimit)
sl@0
   204
				{
sl@0
   205
				TInt glyphDataOffsetPtr = TInt(aGlyphImage) + (bitIndex >> 3);
sl@0
   206
				TUint32* glyphDataWord = (TUint32*)(glyphDataOffsetPtr & ~3);
sl@0
   207
				TInt bitShift = bitIndex & 7;
sl@0
   208
				bitShift += (glyphDataOffsetPtr & 3) << 3;
sl@0
   209
				*binaryDataPtr = (*glyphDataWord++) >> bitShift;
sl@0
   210
				if (bitShift)
sl@0
   211
					{
sl@0
   212
					*binaryDataPtr |= (*glyphDataWord << (32 - bitShift));
sl@0
   213
					}
sl@0
   214
				bitIndex += dataLength;
sl@0
   215
				binaryDataPtr++;
sl@0
   216
				}
sl@0
   217
			}
sl@0
   218
		else
sl@0
   219
			{
sl@0
   220
			TInt glyphDataOffsetPtr = TInt(aGlyphImage) + (bitIndex >> 3);
sl@0
   221
			TUint32* glyphDataWord = (TUint32*)(glyphDataOffsetPtr & ~3);
sl@0
   222
			TInt bitShift = bitIndex & 7;
sl@0
   223
			bitShift += (glyphDataOffsetPtr & 3) << 3;
sl@0
   224
			TUint32 data = (*glyphDataWord++) >> bitShift;
sl@0
   225
			if (bitShift)
sl@0
   226
				{
sl@0
   227
				data |= (*glyphDataWord << (32 - bitShift));
sl@0
   228
				}
sl@0
   229
			while (binaryDataPtr < binaryDataPtrLimit)
sl@0
   230
				{
sl@0
   231
				*binaryDataPtr++ = data;
sl@0
   232
				}
sl@0
   233
			bitIndex += dataLength;
sl@0
   234
			}
sl@0
   235
		}
sl@0
   236
	TPoint topLeft(aPos);
sl@0
   237
	binaryDataPtr = ClipBinaryArray(binaryData, binaryData + dataHeight, dataLength, dataHeight, topLeft, aClipRect);
sl@0
   238
	if ((dataLength > 0) && (dataHeight > 0))
sl@0
   239
		{
sl@0
   240
		iDrawDevice->WriteBinary(topLeft.iX, topLeft.iY, binaryDataPtr, dataLength, dataHeight, iPenColor, GcDrawMode(iDrawMode) );
sl@0
   241
		}
sl@0
   242
	}
sl@0
   243
	
sl@0
   244
	
sl@0
   245
/**
sl@0
   246
Draw a large bitmap glyph.
sl@0
   247
	
sl@0
   248
@param	aPos			Position to start drawing gyph.
sl@0
   249
@param	aGlyphImage		Pointer to the glyph image data.
sl@0
   250
@param	aGlyphImageSize	Glyph image size.
sl@0
   251
@param	aClipRect		Clipping rect.
sl@0
   252
*/
sl@0
   253
void CSwDirectGdiEngine::DrawLargeBitmapGlyph(const TPoint& aPos, const TUint8* aGlyphImage,
sl@0
   254
											 const TSize& aGlyphImageSize, const TRect& aClipRect)
sl@0
   255
	{
sl@0
   256
	TPoint printPos(aPos);
sl@0
   257
	const TInt dataLength = aGlyphImageSize.iWidth;
sl@0
   258
	const TInt dataHeight = aGlyphImageSize.iHeight;
sl@0
   259
	TInt bitIndex = 0;
sl@0
   260
	TInt16 repeatCount = 0;
sl@0
   261
	TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
sl@0
   262
	const TInt scanLineWords = (iDrawDevice->ScanLineBytes()) << 3;
sl@0
   263
	for (TInt glyphLine = 0; glyphLine < dataHeight; glyphLine += repeatCount) // for lines in the glyph bitmap
sl@0
   264
		{
sl@0
   265
		repeatCount = Load16(aGlyphImage + (bitIndex >> 3));
sl@0
   266
		repeatCount >>= bitIndex & 7;
sl@0
   267
		const TInt multiLineFlag = repeatCount & 1;
sl@0
   268
		repeatCount >>= 1;
sl@0
   269
		repeatCount &= 0xf;
sl@0
   270
		bitIndex += 5;
sl@0
   271
		if (multiLineFlag)
sl@0
   272
			{
sl@0
   273
			for (TInt currentLine = 0; currentLine < repeatCount; currentLine++)
sl@0
   274
				{
sl@0
   275
				CopyCharLine(scanLineBuffer, scanLineWords, aGlyphImage + (bitIndex >> 3), bitIndex & 7, dataLength);
sl@0
   276
				OutputCharLineMultiplied(printPos, scanLineBuffer, dataLength, 1, aClipRect);
sl@0
   277
				bitIndex += dataLength;
sl@0
   278
				printPos.iY++;
sl@0
   279
				}
sl@0
   280
			}
sl@0
   281
		else
sl@0
   282
			{
sl@0
   283
			CopyCharLine(scanLineBuffer, scanLineWords, aGlyphImage + (bitIndex >> 3), bitIndex & 7, dataLength);
sl@0
   284
			OutputCharLineMultiplied(printPos, scanLineBuffer, dataLength, repeatCount, aClipRect);
sl@0
   285
			printPos.iY += repeatCount;
sl@0
   286
			bitIndex += dataLength;
sl@0
   287
			}
sl@0
   288
		}
sl@0
   289
	}
sl@0
   290
sl@0
   291
sl@0
   292
/**
sl@0
   293
sl@0
   294
*/
sl@0
   295
void CSwDirectGdiEngine::CopyCharLine(TUint32* aBinaryDataPtr, TInt aBufferWords, const TUint8* aData, TInt aBitShift, TInt aCharWidth)
sl@0
   296
	{
sl@0
   297
	aBitShift &= 7;
sl@0
   298
	TInt wordsToCopy = (aCharWidth + 31) >> 5;
sl@0
   299
	if (wordsToCopy > aBufferWords)
sl@0
   300
		{
sl@0
   301
		wordsToCopy = aBufferWords;
sl@0
   302
		}
sl@0
   303
	TUint32* ptrLimit = aBinaryDataPtr + wordsToCopy;
sl@0
   304
	TUint32* dataWord = (TUint32*)(TInt(aData) & ~3);
sl@0
   305
	aBitShift += (TInt(aData) - TInt(dataWord)) << 3;
sl@0
   306
	while (aBinaryDataPtr < ptrLimit)
sl@0
   307
		{
sl@0
   308
		*aBinaryDataPtr = *dataWord++;
sl@0
   309
		*aBinaryDataPtr >>= aBitShift;
sl@0
   310
		if (aBitShift)
sl@0
   311
			{
sl@0
   312
			*aBinaryDataPtr |= (*dataWord << (32 - aBitShift));
sl@0
   313
			}
sl@0
   314
		aBinaryDataPtr++;
sl@0
   315
		}
sl@0
   316
	}
sl@0
   317
sl@0
   318
sl@0
   319
/**
sl@0
   320
sl@0
   321
*/
sl@0
   322
void CSwDirectGdiEngine::OutputCharLineMultiplied(TPoint aPrintPos, TUint32* aBuffer, TInt aDataLength, TInt aNum, const TRect& aClipRect)
sl@0
   323
	{
sl@0
   324
	if (aDataLength <= 0)
sl@0
   325
		{
sl@0
   326
		return;
sl@0
   327
		}
sl@0
   328
	TInt bufferWords = (aDataLength + 31) >> 5;
sl@0
   329
	TUint32* bufferLimit = aBuffer + bufferWords;
sl@0
   330
	if (aPrintPos.iX < aClipRect.iTl.iX)
sl@0
   331
		{
sl@0
   332
		TInt pixelExcess = aClipRect.iTl.iX - aPrintPos.iX;
sl@0
   333
		while (pixelExcess >= 32)
sl@0
   334
			{
sl@0
   335
			aBuffer++;
sl@0
   336
			bufferWords--;
sl@0
   337
			aDataLength -= 32;
sl@0
   338
			pixelExcess -= 32;
sl@0
   339
			}
sl@0
   340
		if (aDataLength <= 0)
sl@0
   341
			{
sl@0
   342
			return;
sl@0
   343
			}
sl@0
   344
		if (pixelExcess > 0)
sl@0
   345
			{
sl@0
   346
			TInt shiftUp = 32 - pixelExcess;
sl@0
   347
			TUint32* bufferPtr = aBuffer;
sl@0
   348
			while (bufferPtr < bufferLimit)
sl@0
   349
				{
sl@0
   350
				*bufferPtr >>= pixelExcess;
sl@0
   351
				if (bufferPtr < bufferLimit - 1)
sl@0
   352
					{
sl@0
   353
					*bufferPtr |= (*(bufferPtr + 1) << shiftUp);
sl@0
   354
					}
sl@0
   355
				bufferPtr++;
sl@0
   356
				}
sl@0
   357
			aDataLength -= pixelExcess;
sl@0
   358
			if (aDataLength <= 0)
sl@0
   359
				{
sl@0
   360
				return;
sl@0
   361
				}
sl@0
   362
			}
sl@0
   363
		aPrintPos.iX = aClipRect.iTl.iX;
sl@0
   364
		}
sl@0
   365
	if (aPrintPos.iX + aDataLength > aClipRect.iBr.iX)
sl@0
   366
		{
sl@0
   367
		TInt pixelExcess = aPrintPos.iX + aDataLength - aClipRect.iBr.iX;
sl@0
   368
		aDataLength -= pixelExcess;
sl@0
   369
		if (aDataLength <= 0)
sl@0
   370
			{
sl@0
   371
			return;
sl@0
   372
			}
sl@0
   373
		}
sl@0
   374
	while (aNum > 0)
sl@0
   375
		{
sl@0
   376
		if ((aPrintPos.iY >= aClipRect.iTl.iY) && (aPrintPos.iY < aClipRect.iBr.iY))
sl@0
   377
			{
sl@0
   378
			iDrawDevice->WriteBinaryLine(aPrintPos.iX, aPrintPos.iY, aBuffer, aDataLength, iPenColor, GcDrawMode(iDrawMode));
sl@0
   379
			}
sl@0
   380
		aPrintPos.iY++;
sl@0
   381
		aNum--;
sl@0
   382
		}
sl@0
   383
	}
sl@0
   384
sl@0
   385
sl@0
   386
/**
sl@0
   387
Draw a rotated bitmap glyph.
sl@0
   388
	
sl@0
   389
@param	aPos			Position to start drawing glyph after rotation has been applied.
sl@0
   390
@param	aGlyphImage		Pointer to the glyph image data.
sl@0
   391
@param	aGlyphImageSize	Glyph image size.
sl@0
   392
@param	aClipRect		Clipping rect.
sl@0
   393
@param	aRotation		Rotation specifying how the glyph will be drawn.
sl@0
   394
*/
sl@0
   395
void CSwDirectGdiEngine::DrawRotatedBitmapGlyph(const TPoint& aPos, const TUint8* aGlyphImage,
sl@0
   396
												const TSize& aGlyphImageSize, const TRect& aClipRect, const DirectGdi::TGraphicsRotation aRotation)
sl@0
   397
	{
sl@0
   398
	TPoint printPos(aPos);
sl@0
   399
	TInt dataLength = aGlyphImageSize.iWidth;
sl@0
   400
	TInt dataHeight = aGlyphImageSize.iHeight;
sl@0
   401
	TInt bitIndex = 0;
sl@0
   402
	TInt16 repeatCount = 0;
sl@0
   403
	TInt direction = (aRotation == DirectGdi::EGraphicsRotation270) ? 1 : -1;
sl@0
   404
	TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
sl@0
   405
	TInt scanLineWords = (iDrawDevice->ScanLineBytes()) << 3;
sl@0
   406
	for (TInt glyphLine = 0; glyphLine < dataHeight; glyphLine += repeatCount) // for lines in the glyph bitmap...
sl@0
   407
		{
sl@0
   408
		repeatCount = Load16(aGlyphImage + (bitIndex >> 3));
sl@0
   409
		repeatCount >>= bitIndex & 7;
sl@0
   410
		TInt multiLineFlag = repeatCount & 1;
sl@0
   411
		repeatCount >>= 1;
sl@0
   412
		repeatCount &= 0xf;
sl@0
   413
		bitIndex += 5;
sl@0
   414
		TInt signedRepeatCount = repeatCount * direction;
sl@0
   415
		if (multiLineFlag)
sl@0
   416
			{
sl@0
   417
			for (TInt currentLine = 0; currentLine < repeatCount; currentLine++)
sl@0
   418
				{
sl@0
   419
				CopyCharLine(scanLineBuffer, scanLineWords, aGlyphImage + (bitIndex >> 3), bitIndex & 7, dataLength);
sl@0
   420
				OutputCharLineVertical(printPos, scanLineBuffer, dataLength, 1, direction, aClipRect);
sl@0
   421
				bitIndex += dataLength;
sl@0
   422
				printPos.iX += direction;
sl@0
   423
				}
sl@0
   424
			}
sl@0
   425
		else
sl@0
   426
			{
sl@0
   427
			CopyCharLine(scanLineBuffer,scanLineWords, aGlyphImage + (bitIndex >> 3), bitIndex & 7, dataLength);
sl@0
   428
			OutputCharLineVertical(printPos, scanLineBuffer, dataLength, repeatCount, direction, aClipRect);
sl@0
   429
			printPos.iX += signedRepeatCount;
sl@0
   430
			bitIndex += dataLength;
sl@0
   431
			}
sl@0
   432
		}
sl@0
   433
	}
sl@0
   434
sl@0
   435
sl@0
   436
/**
sl@0
   437
sl@0
   438
*/
sl@0
   439
void CSwDirectGdiEngine::OutputCharLineVertical(TPoint aPrintPos, TUint32* aBuffer, TInt aDataLength,
sl@0
   440
												TInt aNum, TInt aDirection, const TRect& aClipRect)
sl@0
   441
	{
sl@0
   442
//	const DirectGdi::TGraphicsRotation rotation = aUp ? DirectGdi::EGraphicsRotation270 : DirectGdi::EGraphicsRotation90;
sl@0
   443
//	TInt direction = (aRotation == DirectGdi::EGraphicsRotation270) ? 1 : -1;
sl@0
   444
	if (aDataLength <= 0)
sl@0
   445
		{
sl@0
   446
		return;
sl@0
   447
		}
sl@0
   448
	TInt bufferWords = (aDataLength + 31) >> 5;
sl@0
   449
	TUint32* bufferLimit = aBuffer + bufferWords;
sl@0
   450
	if (aDirection == 1)
sl@0
   451
		{
sl@0
   452
		if (aPrintPos.iY >= aClipRect.iBr.iY)
sl@0
   453
			{
sl@0
   454
			TInt pixelExcess = aPrintPos.iY - aClipRect.iBr.iY + 1;
sl@0
   455
			while (pixelExcess >= 32)
sl@0
   456
				{
sl@0
   457
				aBuffer++;
sl@0
   458
				aDataLength -= 32;
sl@0
   459
				pixelExcess -= 32;
sl@0
   460
				}
sl@0
   461
			if (aDataLength <= 0)
sl@0
   462
				{
sl@0
   463
				return;
sl@0
   464
				}
sl@0
   465
			if (pixelExcess > 0)
sl@0
   466
				{
sl@0
   467
				TInt shiftUp = 32 - pixelExcess;
sl@0
   468
				TUint32* bufferPtr = aBuffer;
sl@0
   469
				while (bufferPtr < bufferLimit)
sl@0
   470
					{
sl@0
   471
					*bufferPtr >>= pixelExcess;
sl@0
   472
					if (bufferPtr < bufferLimit - 1)
sl@0
   473
						*bufferPtr |= (*(bufferPtr + 1) << shiftUp);
sl@0
   474
					bufferPtr++;
sl@0
   475
					}
sl@0
   476
				aDataLength -= pixelExcess;
sl@0
   477
				if (aDataLength <= 0)
sl@0
   478
					{
sl@0
   479
					return;
sl@0
   480
					}
sl@0
   481
				}
sl@0
   482
			aPrintPos.iY = aClipRect.iBr.iY - 1;
sl@0
   483
			}
sl@0
   484
		if ((aPrintPos.iY - aDataLength) < (aClipRect.iTl.iY - 1))
sl@0
   485
			{
sl@0
   486
			TInt pixelExcess = aClipRect.iTl.iY - 1 - aPrintPos.iY + aDataLength;
sl@0
   487
			aDataLength -= pixelExcess;
sl@0
   488
			if (aDataLength <= 0)
sl@0
   489
				{
sl@0
   490
				return;
sl@0
   491
				}
sl@0
   492
			}
sl@0
   493
		}
sl@0
   494
	else
sl@0
   495
		{
sl@0
   496
		if (aPrintPos.iY < aClipRect.iTl.iY)
sl@0
   497
			{
sl@0
   498
			TInt pixelExcess = aClipRect.iTl.iY - aPrintPos.iY;
sl@0
   499
			while (pixelExcess >= 32)
sl@0
   500
				{
sl@0
   501
				aBuffer++;
sl@0
   502
				aDataLength -= 32;
sl@0
   503
				pixelExcess -= 32;
sl@0
   504
				}
sl@0
   505
			if (aDataLength <= 0)
sl@0
   506
				{
sl@0
   507
				return;
sl@0
   508
				}
sl@0
   509
			if (pixelExcess > 0)
sl@0
   510
				{
sl@0
   511
				TInt shiftup = 32 - pixelExcess;
sl@0
   512
				TUint32* bufferptr = aBuffer;
sl@0
   513
				while (bufferptr < bufferLimit)
sl@0
   514
					{
sl@0
   515
					*bufferptr >>= pixelExcess;
sl@0
   516
					if (bufferptr < bufferLimit - 1)
sl@0
   517
						*bufferptr |= (*(bufferptr + 1) << shiftup);
sl@0
   518
					bufferptr++;
sl@0
   519
					}
sl@0
   520
				aDataLength -= pixelExcess;
sl@0
   521
				if (aDataLength <= 0)
sl@0
   522
					{
sl@0
   523
					return;
sl@0
   524
					}
sl@0
   525
				}
sl@0
   526
			aPrintPos.iY = aClipRect.iTl.iY;
sl@0
   527
			}
sl@0
   528
		if (aPrintPos.iY + aDataLength > aClipRect.iBr.iY)
sl@0
   529
			{
sl@0
   530
			TInt pixelExcess = aPrintPos.iY + aDataLength - aClipRect.iBr.iY;
sl@0
   531
			aDataLength -= pixelExcess;
sl@0
   532
			if (aDataLength <= 0)
sl@0
   533
				{
sl@0
   534
				return;
sl@0
   535
				}
sl@0
   536
			}
sl@0
   537
		}
sl@0
   538
	CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
sl@0
   539
	while (aNum > 0)
sl@0
   540
		{
sl@0
   541
		if ((aPrintPos.iX >= aClipRect.iTl.iX) && (aPrintPos.iX < aClipRect.iBr.iX))
sl@0
   542
			iDrawDevice->WriteBinaryLineVertical(aPrintPos.iX, aPrintPos.iY, aBuffer, aDataLength, iPenColor, drawMode, (aDirection == 1));
sl@0
   543
		aPrintPos.iX += aDirection;
sl@0
   544
		aNum--;
sl@0
   545
		}
sl@0
   546
	}
sl@0
   547
sl@0
   548
sl@0
   549
/**
sl@0
   550
Draw an antialiased glyph.
sl@0
   551
	
sl@0
   552
@param	aPos			Position to start drawing gyph.
sl@0
   553
@param	aGlyphImage		Pointer to the glyph image data.
sl@0
   554
@param	aGlyphImageSize	Glyph image size.
sl@0
   555
@param	aClipRect		Clipping rect.
sl@0
   556
*/
sl@0
   557
void CSwDirectGdiEngine::DrawAntiAliasedGlyph(const TPoint& aPos, const TUint8* aGlyphImage,
sl@0
   558
											  const TSize& aGlyphImageSize, const TRect& aClipRect)
sl@0
   559
	{
sl@0
   560
	const TInt topRow = Max(0, aClipRect.iTl.iY - aPos.iY);
sl@0
   561
	const TInt bottomRow = Min(aGlyphImageSize.iHeight, aClipRect.iBr.iY - aPos.iY);
sl@0
   562
	const TInt leftCol = Max(0, aClipRect.iTl.iX - aPos.iX);
sl@0
   563
	const TInt rightCol = Min(aGlyphImageSize.iWidth, aClipRect.iBr.iX - aPos.iX);
sl@0
   564
	const TUint8* p = aGlyphImage + (topRow * aGlyphImageSize.iWidth) + leftCol;
sl@0
   565
	const TInt x = aPos.iX + leftCol;
sl@0
   566
	TInt y = aPos.iY + topRow;
sl@0
   567
	const TInt cols = rightCol - leftCol;
sl@0
   568
sl@0
   569
	for (TInt row = topRow; row < bottomRow; row++, p += aGlyphImageSize.iWidth, y++)
sl@0
   570
		{
sl@0
   571
		iDrawDevice->WriteRgbAlphaMulti(x, y, cols, iPenColor, p);
sl@0
   572
		}
sl@0
   573
	}
sl@0
   574
sl@0
   575
sl@0
   576
/**
sl@0
   577
Draw a rotated antialiased glyph.
sl@0
   578
	
sl@0
   579
@param	aPos			Position to start drawing gyph after rotation has been applied.
sl@0
   580
@param	aGlyphImage		Pointer to the glyph image data.
sl@0
   581
@param	aGlyphImageSize	Glyph image size.
sl@0
   582
@param	aClipRect		Clipping rect.
sl@0
   583
@param	aRotation		Rotation specifying how the glyph will be drawn.
sl@0
   584
*/
sl@0
   585
void CSwDirectGdiEngine::DrawRotatedAntiAliasedGlyph(const TPoint& aPos, const TUint8* aGlyphImage,
sl@0
   586
													 const TSize& aGlyphImageSize, const TRect& aClipRect, const DirectGdi::TGraphicsRotation aRotation)
sl@0
   587
	{
sl@0
   588
	const int KBufferSize = 32;
sl@0
   589
	TUint8 maskBuffer[KBufferSize];
sl@0
   590
	int topRow = 0;
sl@0
   591
	int bottomRow = 0;
sl@0
   592
	int leftCol = 0;
sl@0
   593
	int rightCol = 0;
sl@0
   594
	const TUint32 penColor = iPenColor.Internal();
sl@0
   595
	const TUint32 brushColor = iBrushColor.Internal();
sl@0
   596
	
sl@0
   597
	if (aRotation == DirectGdi::EGraphicsRotation270)
sl@0
   598
		{
sl@0
   599
		topRow = Max(0, aClipRect.iTl.iX - aPos.iX);
sl@0
   600
		bottomRow = Min(aGlyphImageSize.iHeight, aClipRect.iBr.iX - aPos.iX);
sl@0
   601
		leftCol = Max(0, aPos.iY - aClipRect.iBr.iY + 1);
sl@0
   602
		rightCol = Min(aGlyphImageSize.iWidth, aPos.iY - aClipRect.iTl.iY + 1);
sl@0
   603
		TInt y = aPos.iY - (rightCol - 1);
sl@0
   604
		for (TInt col = rightCol - 1; col >= leftCol; col--, y++)
sl@0
   605
			{
sl@0
   606
			TInt x = aPos.iX + topRow;
sl@0
   607
			for (TInt row = topRow; row < bottomRow; row += KBufferSize, x += KBufferSize)
sl@0
   608
				{
sl@0
   609
				TInt length = KBufferSize;
sl@0
   610
				if (length > bottomRow - row)
sl@0
   611
					{
sl@0
   612
					length = bottomRow - row;
sl@0
   613
					}
sl@0
   614
				const TUint8* p = aGlyphImage + row * aGlyphImageSize.iWidth + col;
sl@0
   615
				for (TInt i = 0; i < length; i++, p += aGlyphImageSize.iWidth)
sl@0
   616
					{
sl@0
   617
					maskBuffer[i] = *p;
sl@0
   618
					}
sl@0
   619
				iDrawDevice->WriteRgbAlphaMulti(x, y, length, iPenColor, maskBuffer);
sl@0
   620
				}
sl@0
   621
			}
sl@0
   622
		}
sl@0
   623
	else
sl@0
   624
		{
sl@0
   625
		topRow = Max(0, aPos.iX - aClipRect.iBr.iX + 1);
sl@0
   626
		bottomRow = Min(aGlyphImageSize.iHeight, aPos.iX - aClipRect.iTl.iX + 1);
sl@0
   627
		leftCol = Max(0, aClipRect.iTl.iY - aPos.iY);
sl@0
   628
		rightCol = Min(aGlyphImageSize.iWidth, aClipRect.iBr.iY - aPos.iY);
sl@0
   629
		int y = aPos.iY + leftCol;
sl@0
   630
		for (TInt col = leftCol; col < rightCol; col++, y++)
sl@0
   631
			{
sl@0
   632
			TInt x = aPos.iX - (bottomRow - 1);
sl@0
   633
			for (TInt row = bottomRow; row > topRow; row -= KBufferSize, x += KBufferSize)
sl@0
   634
				{
sl@0
   635
				int length = KBufferSize;
sl@0
   636
				if (length > row - topRow)
sl@0
   637
					length = row - topRow;
sl@0
   638
				const TUint8* p = aGlyphImage + (row - 1) * aGlyphImageSize.iWidth + col;
sl@0
   639
				for (TInt i = 0; i < length; i++, p -= aGlyphImageSize.iWidth)
sl@0
   640
					{
sl@0
   641
					maskBuffer[i] = *p;
sl@0
   642
					}
sl@0
   643
				iDrawDevice->WriteRgbAlphaMulti(x, y, length, iPenColor, maskBuffer);
sl@0
   644
				}
sl@0
   645
			}
sl@0
   646
		}
sl@0
   647
	}
sl@0
   648
sl@0
   649
sl@0
   650
/**
sl@0
   651
Draw a four colour glyph.
sl@0
   652
	
sl@0
   653
@param	aPos			Position to start drawing gyph.
sl@0
   654
@param	aGlyphImage		Pointer to the glyph image data.
sl@0
   655
@param	aGlyphImageSize	Glyph image size.
sl@0
   656
@param	aClipRect		Clipping rect.
sl@0
   657
*/
sl@0
   658
void CSwDirectGdiEngine::DrawFourColourGlyph(const TPoint& aPos, const TUint8* aGlyphImage,
sl@0
   659
											 const TSize& aGlyphImageSize, const TRect& aClipRect)
sl@0
   660
	{
sl@0
   661
	const TInt topRow = Max(0, aClipRect.iTl.iY - aPos.iY);
sl@0
   662
	const TInt bottomRow = Min(aGlyphImageSize.iHeight, aClipRect.iBr.iY - aPos.iY);
sl@0
   663
	const TInt leftCol = Max(0, aClipRect.iTl.iX - aPos.iX);
sl@0
   664
	const TInt rightCol = Min(aGlyphImageSize.iWidth, aClipRect.iBr.iX - aPos.iX);
sl@0
   665
	const TUint8* p = aGlyphImage + (topRow * aGlyphImageSize.iWidth) + leftCol;
sl@0
   666
	const TInt x = aPos.iX + leftCol;
sl@0
   667
	TInt y = aPos.iY + topRow;
sl@0
   668
	const TInt cols = rightCol - leftCol;
sl@0
   669
	const TUint32 penColor = iPenColor.Internal();
sl@0
   670
	const TUint32 shadowColor = iTextShadowColor.Internal();
sl@0
   671
	const TUint32 brushColor = iBrushColor.Internal();
sl@0
   672
sl@0
   673
	MOutlineAndShadowBlend* outlineAndShadow = NULL;
sl@0
   674
	const TInt err = iDrawDevice->GetInterface(KOutlineAndShadowInterfaceID, reinterpret_cast <TAny*&> (outlineAndShadow));
sl@0
   675
	if (err == KErrNone) 
sl@0
   676
		{
sl@0
   677
		//There is a support for the interface with KOutlineAndShadowInterface id.
sl@0
   678
		for (TInt row = topRow; row < bottomRow; row++, p += aGlyphImageSize.iWidth, y++)
sl@0
   679
			{
sl@0
   680
			outlineAndShadow->WriteRgbOutlineAndShadow(x, y, cols, penColor, shadowColor, brushColor, p);
sl@0
   681
			}
sl@0
   682
		}
sl@0
   683
	else
sl@0
   684
		{
sl@0
   685
		// Assert if MOutlineAndShadowBlend interface is not implemented
sl@0
   686
		GRAPHICS_ASSERT_DEBUG(outlineAndShadow, EDirectGdiPanicInvalidInterfaceHandle);
sl@0
   687
		}
sl@0
   688
	}
sl@0
   689
sl@0
   690
sl@0
   691
/**
sl@0
   692
Draw a rotated four colour glyph.
sl@0
   693
	
sl@0
   694
@param	aPos			Position to start drawing gyph after rotation has been applied.
sl@0
   695
@param	aGlyphImage		Pointer to the glyph image data.
sl@0
   696
@param	aGlyphImageSize	Glyph image size.
sl@0
   697
@param	aClipRect		Clipping rect.
sl@0
   698
@param	aRotation		Rotation specifying how the glyph will be drawn.
sl@0
   699
*/
sl@0
   700
void CSwDirectGdiEngine::DrawRotatedFourColourGlyph(const TPoint& aPos, const TUint8* aGlyphImage, const TSize& aGlyphImageSize,
sl@0
   701
													const TRect& aClipRect, const DirectGdi::TGraphicsRotation aRotation)
sl@0
   702
	{
sl@0
   703
	const int KBufferSize = 32;
sl@0
   704
	TUint8 maskBuffer[KBufferSize];
sl@0
   705
	int topRow = 0;
sl@0
   706
	int bottomRow = 0;
sl@0
   707
	int leftCol = 0;
sl@0
   708
	int rightCol = 0;
sl@0
   709
	const TUint32 penColor = iPenColor.Internal();
sl@0
   710
	const TUint32 shadowColor = iTextShadowColor.Internal();
sl@0
   711
	const TUint32 brushColor = iBrushColor.Internal();
sl@0
   712
	
sl@0
   713
	MOutlineAndShadowBlend* outlineAndShadow = NULL;
sl@0
   714
	TInt err = iDrawDevice->GetInterface(KOutlineAndShadowInterfaceID, reinterpret_cast <TAny*&> (outlineAndShadow));
sl@0
   715
	if(err != KErrNone)
sl@0
   716
		{
sl@0
   717
		// Assert if MOutlineAndShadowBlend interface is not implemented
sl@0
   718
		GRAPHICS_ASSERT_DEBUG(outlineAndShadow, EDirectGdiPanicInvalidInterfaceHandle);
sl@0
   719
		}
sl@0
   720
	
sl@0
   721
	if (aRotation == DirectGdi::EGraphicsRotation270)
sl@0
   722
		{
sl@0
   723
		topRow = Max(0, aClipRect.iTl.iX - aPos.iX);
sl@0
   724
		bottomRow = Min(aGlyphImageSize.iHeight, aClipRect.iBr.iX - aPos.iX);
sl@0
   725
		leftCol = Max(0, aPos.iY - aClipRect.iBr.iY + 1);
sl@0
   726
		rightCol = Min(aGlyphImageSize.iWidth, aPos.iY - aClipRect.iTl.iY + 1);
sl@0
   727
		TInt y = aPos.iY - (rightCol - 1);
sl@0
   728
		for (TInt col = rightCol - 1; col >= leftCol; col--, y++)
sl@0
   729
			{
sl@0
   730
			TInt x = aPos.iX + topRow;
sl@0
   731
			for (TInt row = topRow; row < bottomRow; row += KBufferSize, x += KBufferSize)
sl@0
   732
				{
sl@0
   733
				TInt length = KBufferSize;
sl@0
   734
				if (length > bottomRow - row)
sl@0
   735
					{
sl@0
   736
					length = bottomRow - row;
sl@0
   737
					}
sl@0
   738
				const TUint8* p = aGlyphImage + row * aGlyphImageSize.iWidth + col;
sl@0
   739
				for (TInt i = 0; i < length; i++, p += aGlyphImageSize.iWidth)
sl@0
   740
					{
sl@0
   741
					maskBuffer[i] = *p;
sl@0
   742
					}
sl@0
   743
				//There is a support for the interface with KOutlineAndShadowInterface id.
sl@0
   744
				outlineAndShadow->WriteRgbOutlineAndShadow(x, y, length, penColor, shadowColor,	brushColor, maskBuffer);
sl@0
   745
				}
sl@0
   746
			}
sl@0
   747
		}
sl@0
   748
	else
sl@0
   749
		{
sl@0
   750
		topRow = Max(0, aPos.iX - aClipRect.iBr.iX + 1);
sl@0
   751
		bottomRow = Min(aGlyphImageSize.iHeight, aPos.iX - aClipRect.iTl.iX + 1);
sl@0
   752
		leftCol = Max(0, aClipRect.iTl.iY - aPos.iY);
sl@0
   753
		rightCol = Min(aGlyphImageSize.iWidth, aClipRect.iBr.iY - aPos.iY);
sl@0
   754
		int y = aPos.iY + leftCol;
sl@0
   755
		for (TInt col = leftCol; col < rightCol; col++, y++)
sl@0
   756
			{
sl@0
   757
			TInt x = aPos.iX - (bottomRow - 1);
sl@0
   758
			for (TInt row = bottomRow; row > topRow; row -= KBufferSize, x += KBufferSize)
sl@0
   759
				{
sl@0
   760
				int length = KBufferSize;
sl@0
   761
				if (length > row - topRow)
sl@0
   762
					length = row - topRow;
sl@0
   763
				const TUint8* p = aGlyphImage + (row - 1) * aGlyphImageSize.iWidth + col;
sl@0
   764
				for (TInt i = 0; i < length; i++, p -= aGlyphImageSize.iWidth)
sl@0
   765
					{
sl@0
   766
					maskBuffer[i] = *p;
sl@0
   767
					}
sl@0
   768
				//There is a support for the interface with KOutlineAndShadowInterface id.
sl@0
   769
				outlineAndShadow->WriteRgbOutlineAndShadow(x, y, length, penColor, shadowColor,	brushColor, maskBuffer);
sl@0
   770
				}
sl@0
   771
			}
sl@0
   772
		}
sl@0
   773
	}
sl@0
   774
sl@0
   775
sl@0
   776
/**
sl@0
   777
Helper function to clip the array to the clip rect.
sl@0
   778
sl@0
   779
@param	aArray		Start of array of data to be clipped.
sl@0
   780
@param	aArrayLimit	End of array of data to be clipped.
sl@0
   781
@param	aDataWd 	Length of data.
sl@0
   782
@param	aDataHt		Height of data.
sl@0
   783
@param	aPos		Position to start drawing from.
sl@0
   784
@param	aClipRect	Rectangle to clip data array to.
sl@0
   785
sl@0
   786
@return Pointer to array of clipped data.
sl@0
   787
*/
sl@0
   788
TUint32* CSwDirectGdiEngine::ClipBinaryArray(TUint32* aArray, TUint32* aArrayLimit, TInt& aDataWd, TInt& aDataHt, TPoint& aPos, const TRect& aClipRect)
sl@0
   789
	{
sl@0
   790
	TUint32* arrayPtr = aArray;
sl@0
   791
	TInt clipDiff = aClipRect.iTl.iX - aPos.iX;
sl@0
   792
	if (clipDiff > 0)
sl@0
   793
		{
sl@0
   794
		while (arrayPtr < aArrayLimit)
sl@0
   795
			{
sl@0
   796
			*arrayPtr++ >>= clipDiff;
sl@0
   797
			}
sl@0
   798
		aDataWd -= clipDiff;
sl@0
   799
		aPos.iX = aClipRect.iTl.iX;
sl@0
   800
		arrayPtr = aArray;
sl@0
   801
		}
sl@0
   802
	if ((aPos.iX + aDataWd > aClipRect.iBr.iX) && (aDataWd > 0))
sl@0
   803
		{
sl@0
   804
		aDataWd = aClipRect.iBr.iX - aPos.iX;
sl@0
   805
		}
sl@0
   806
	clipDiff = aClipRect.iTl.iY - aPos.iY;
sl@0
   807
	if (clipDiff > 0)
sl@0
   808
		{
sl@0
   809
		aDataHt -= clipDiff;
sl@0
   810
		arrayPtr += clipDiff;
sl@0
   811
		aPos.iY = aClipRect.iTl.iY;
sl@0
   812
		}
sl@0
   813
	if (((aPos.iY + aDataHt) > (aClipRect.iBr.iY)) && (aDataHt > 0))
sl@0
   814
		{
sl@0
   815
		aDataHt = aClipRect.iBr.iY - aPos.iY;
sl@0
   816
		}
sl@0
   817
	return arrayPtr;
sl@0
   818
	}