os/graphics/graphicsdeviceinterface/bitgdi/sbit/RECT.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) 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 <bitmap.h>
sl@0
    18
#include <bitstd.h>
sl@0
    19
#include <bitdev.h>
sl@0
    20
#include "BITPANIC.H"
sl@0
    21
#include <graphicsaccelerator.h>
sl@0
    22
#include <bitdraw.h>
sl@0
    23
#include <graphics/fbsrasterizer.h>
sl@0
    24
sl@0
    25
/**
sl@0
    26
Copies a rectangle.
sl@0
    27
sl@0
    28
The function provides a concrete implementation of the pure virtual
sl@0
    29
function <code>CBitmapContext::CopyRect()</code>. The function
sl@0
    30
behaviour is the same as documented in that class.
sl@0
    31
*/
sl@0
    32
EXPORT_C void CFbsBitGc::CopyRect(const TPoint& aOffset,const TRect& aRect)
sl@0
    33
	{
sl@0
    34
	if(CheckDevice(aRect) || aRect.IsEmpty() || aOffset == TPoint(0,0))
sl@0
    35
		return;
sl@0
    36
sl@0
    37
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
    38
sl@0
    39
	TRect deviceRect;
sl@0
    40
	drawDevice->GetDrawRect(deviceRect);
sl@0
    41
	const TPoint back(TPoint(0,0)-aOffset);
sl@0
    42
	TRect rcpy(aRect);
sl@0
    43
	rcpy.Move(iOrigin);
sl@0
    44
	rcpy.Intersection(deviceRect);
sl@0
    45
	((TRegion*)iDefaultRegionPtr)->Sort(aOffset);
sl@0
    46
sl@0
    47
	TRect clippedBoundingRect(rcpy);
sl@0
    48
	clippedBoundingRect.Move(aOffset);
sl@0
    49
	AddRect(clippedBoundingRect);
sl@0
    50
	clippedBoundingRect.BoundingRect(rcpy);
sl@0
    51
	if(!clippedBoundingRect.Intersects(iUserClipRect))
sl@0
    52
		return;
sl@0
    53
sl@0
    54
	SetupDevice();
sl@0
    55
	iDevice->DrawingBegin();
sl@0
    56
sl@0
    57
	const TInt limit=iDefaultRegionPtr->Count();
sl@0
    58
	for(TInt count=0;count<limit;count++)
sl@0
    59
		{
sl@0
    60
		iClipRect=(*iDefaultRegionPtr)[count];
sl@0
    61
		if(UserClipRect(iClipRect)) 
sl@0
    62
			continue;
sl@0
    63
		iClipRect.Move(back);
sl@0
    64
		if(!iClipRect.Intersects(rcpy))
sl@0
    65
			continue;
sl@0
    66
sl@0
    67
		iClipRect.Intersection(rcpy);
sl@0
    68
		TDrawMode drawMode = iDrawMode;
sl@0
    69
		iDrawMode = EDrawModeWriteAlpha;
sl@0
    70
		DoCopyRect(aOffset,iClipRect);
sl@0
    71
		iDrawMode = drawMode; // restore the previous draw mode
sl@0
    72
		iClipRect.Move(aOffset);
sl@0
    73
		drawDevice->UpdateRegion(iClipRect);
sl@0
    74
		}
sl@0
    75
sl@0
    76
	iDevice->DrawingEnd();
sl@0
    77
	}
sl@0
    78
sl@0
    79
void CFbsBitGc::DoCopyRect(const TPoint& aOffset,const TRect& rect)
sl@0
    80
	{
sl@0
    81
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
    82
#ifdef _DEBUG
sl@0
    83
	TRect deviceRect;
sl@0
    84
	drawDevice->GetDrawRect(deviceRect);
sl@0
    85
#endif
sl@0
    86
	BG_ASSERT_DEBUG(rect.iTl.iX >= deviceRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
    87
	BG_ASSERT_DEBUG(rect.iTl.iY >= deviceRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
    88
	BG_ASSERT_DEBUG(rect.iBr.iX <= deviceRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
    89
	BG_ASSERT_DEBUG(rect.iBr.iY <= deviceRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
    90
sl@0
    91
	TRect offrect(rect);
sl@0
    92
	offrect.Move(aOffset);
sl@0
    93
sl@0
    94
	BG_ASSERT_DEBUG(offrect.iTl.iX >= deviceRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
    95
	BG_ASSERT_DEBUG(offrect.iTl.iY >= deviceRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
    96
	BG_ASSERT_DEBUG(offrect.iBr.iX <= deviceRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
    97
	BG_ASSERT_DEBUG(offrect.iBr.iY <= deviceRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
    98
sl@0
    99
	TInt y1 = rect.iTl.iY,y2 = rect.iBr.iY,yinc = 1; // default y2>y1
sl@0
   100
	if (aOffset.iY > 0)	// y1>y2
sl@0
   101
		{
sl@0
   102
		y1 = rect.iBr.iY - 1;
sl@0
   103
		y2 = rect.iTl.iY - 1;
sl@0
   104
		yinc = -1;
sl@0
   105
		}
sl@0
   106
sl@0
   107
	const TInt width = rect.Width();
sl@0
   108
	const TInt xoffset = rect.iTl.iX + aOffset.iX;
sl@0
   109
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
   110
	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
   111
sl@0
   112
	for (TInt row = y1; row != y2; row += yinc)
sl@0
   113
		{
sl@0
   114
		drawDevice->ReadLine(rect.iTl.iX,row,width,scanLineBuffer,dispMode);
sl@0
   115
		drawDevice->WriteLine(xoffset,row + aOffset.iY,width, scanLineBuffer,iDrawMode);
sl@0
   116
		}
sl@0
   117
	}
sl@0
   118
sl@0
   119
/**
sl@0
   120
Draws and fills a rectangle.
sl@0
   121
sl@0
   122
The function provides a concrete implementation of the pure virtual
sl@0
   123
function <code>CGraphicsContext::DrawRect()</code>. The function
sl@0
   124
behaviour is the same as documented in that class.
sl@0
   125
*/
sl@0
   126
EXPORT_C void CFbsBitGc::DrawRect(const TRect& aRect)
sl@0
   127
	{
sl@0
   128
	if (CheckDevice(aRect))
sl@0
   129
		return;
sl@0
   130
sl@0
   131
	TRect rcpy(aRect);
sl@0
   132
	TRect clippedBoundingRect(rcpy);
sl@0
   133
	clippedBoundingRect.Move(iOrigin);
sl@0
   134
	clippedBoundingRect.Grow((iPenSize.iWidth >> 1) + 1,(iPenSize.iHeight >> 1) + 1);
sl@0
   135
	if(!clippedBoundingRect.Intersects(iUserClipRect))
sl@0
   136
		return;
sl@0
   137
sl@0
   138
	CGraphicsAccelerator* ga = GraphicsAccelerator();
sl@0
   139
sl@0
   140
	SetupDevice();
sl@0
   141
	iDevice->DrawingBegin();
sl@0
   142
	iBrushBitmap.BeginDataAccess();
sl@0
   143
	CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
sl@0
   144
sl@0
   145
	if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1 && iPenStyle != ENullPen)
sl@0
   146
		{
sl@0
   147
		const TInt width = rcpy.Width();
sl@0
   148
		const TInt height = rcpy.Height();
sl@0
   149
		const TPoint currentLinePosition = iLinePosition;
sl@0
   150
sl@0
   151
		if (iPenStyle != ESolidPen)
sl@0
   152
			iDotParam = 0;
sl@0
   153
sl@0
   154
		if (width)
sl@0
   155
			DoDrawLine(rcpy.iTl,TPoint(rcpy.iBr.iX,rcpy.iTl.iY),ETrue); // top
sl@0
   156
sl@0
   157
		if (height > 2 && width > 1)
sl@0
   158
			DoDrawLine(TPoint(rcpy.iBr.iX-1,rcpy.iTl.iY+1),TPoint(rcpy.iBr.iX-1,rcpy.iBr.iY-1),ETrue); // right
sl@0
   159
sl@0
   160
		if (width && height > 1)
sl@0
   161
			DoDrawLine(TPoint(rcpy.iBr.iX-1,rcpy.iBr.iY-1),TPoint(rcpy.iTl.iX-1,rcpy.iBr.iY-1),ETrue); // bottom
sl@0
   162
sl@0
   163
		if (height > 2)
sl@0
   164
			DoDrawLine(TPoint(rcpy.iTl.iX,rcpy.iBr.iY-2),rcpy.iTl,ETrue); // left
sl@0
   165
		
sl@0
   166
		// Restore internal line position in case it has been modified by DoDrawLine().
sl@0
   167
		// DrawRect() should not be modifying it.
sl@0
   168
		iLinePosition = currentLinePosition;
sl@0
   169
sl@0
   170
		if (width < 3 || height < 3)
sl@0
   171
			goto nofill;
sl@0
   172
sl@0
   173
		rcpy.Shrink(1,1);
sl@0
   174
		rcpy.Move(iOrigin);
sl@0
   175
		}
sl@0
   176
	else if (iPenStyle != ENullPen && (iPenSize.iWidth >= 1 && iPenSize.iHeight >= 1))
sl@0
   177
		{
sl@0
   178
		rcpy.Move(iOrigin);
sl@0
   179
sl@0
   180
		const TBrushStyle tempbrushstyle = iBrushStyle;
sl@0
   181
		iBrushStyle = ESolidBrush;
sl@0
   182
		const TRgb tempbrushColor = iBrushColor;
sl@0
   183
		iBrushColor = iPenColor;
sl@0
   184
		const CGraphicsContext::TDrawMode tempdrawmode = iDrawMode;
sl@0
   185
sl@0
   186
		if(iDrawMode != CGraphicsContext::EDrawModeWriteAlpha)
sl@0
   187
			{			
sl@0
   188
			iDrawMode = CGraphicsContext::EDrawModePEN;
sl@0
   189
			}
sl@0
   190
sl@0
   191
		const TInt halfpenwidth = (iPenSize.iWidth - 1) >> 1;
sl@0
   192
		const TInt halfpenheight = (iPenSize.iHeight - 1) >> 1;
sl@0
   193
		const TInt otherhalfwidth = (iPenSize.iWidth >> 1) + 1;
sl@0
   194
		const TInt otherhalfheight = (iPenSize.iHeight >> 1) + 1;
sl@0
   195
sl@0
   196
		rcpy.iBr.iX--;
sl@0
   197
		rcpy.iBr.iY--;
sl@0
   198
sl@0
   199
		if (rcpy.iBr.iY - rcpy.iTl.iY <= iPenSize.iHeight + 1 || rcpy.iBr.iX - rcpy.iTl.iX <= iPenSize.iWidth + 1)
sl@0
   200
			{
sl@0
   201
			rcpy.iTl.iX -= halfpenwidth;
sl@0
   202
			rcpy.iTl.iY -= halfpenheight;
sl@0
   203
			rcpy.iBr.iX += otherhalfwidth;
sl@0
   204
			rcpy.iBr.iY += otherhalfheight;
sl@0
   205
sl@0
   206
			RectFill(rcpy);
sl@0
   207
sl@0
   208
			iBrushStyle = tempbrushstyle;
sl@0
   209
			iBrushColor = tempbrushColor;
sl@0
   210
			iDrawMode = tempdrawmode;
sl@0
   211
sl@0
   212
			goto nofill;
sl@0
   213
			}
sl@0
   214
		else
sl@0
   215
			{
sl@0
   216
			RectFill(TRect(rcpy.iTl.iX - halfpenwidth,rcpy.iTl.iY - halfpenheight,rcpy.iBr.iX + otherhalfwidth,rcpy.iTl.iY + otherhalfheight)); // top
sl@0
   217
			RectFill(TRect(rcpy.iTl.iX - halfpenwidth,rcpy.iTl.iY + otherhalfheight,rcpy.iTl.iX + otherhalfwidth,rcpy.iBr.iY - halfpenheight)); // left
sl@0
   218
			RectFill(TRect(rcpy.iBr.iX - halfpenwidth,rcpy.iTl.iY + otherhalfheight,rcpy.iBr.iX + otherhalfwidth,rcpy.iBr.iY - halfpenheight)); // right
sl@0
   219
			RectFill(TRect(rcpy.iTl.iX - halfpenwidth,rcpy.iBr.iY - halfpenheight,rcpy.iBr.iX + otherhalfwidth,rcpy.iBr.iY + otherhalfheight)); // bottom
sl@0
   220
sl@0
   221
			rcpy.iTl.iX += otherhalfwidth;
sl@0
   222
			rcpy.iTl.iY += otherhalfheight;
sl@0
   223
			rcpy.iBr.iX -= halfpenwidth;
sl@0
   224
			rcpy.iBr.iY -= halfpenheight;
sl@0
   225
sl@0
   226
			iBrushStyle = tempbrushstyle;
sl@0
   227
			iBrushColor = tempbrushColor;
sl@0
   228
			iDrawMode = tempdrawmode;
sl@0
   229
			}
sl@0
   230
		}
sl@0
   231
	else
sl@0
   232
		rcpy.Move(iOrigin);
sl@0
   233
sl@0
   234
	//use Graphics accelerator if available
sl@0
   235
	if(ga)
sl@0
   236
		{
sl@0
   237
		TInt i = -1;
sl@0
   238
		//Draw rect
sl@0
   239
		if(iPenStyle == ENullPen && iShadowMode == CFbsDrawDevice::ENoShadow)
sl@0
   240
			{
sl@0
   241
			if(iBrushStyle == ESolidBrush )
sl@0
   242
				{
sl@0
   243
				// EDrawModePEN and EDrawModeWriteAlpha mode should use the same method when
sl@0
   244
				// (1) solid brush with opaque color is used. Or
sl@0
   245
				// (2) solid brush with transparent color is used but display mode is
sl@0
   246
				//     other than EColor64K, EColor16MU, EColor16MA, EColor16MAP.
sl@0
   247
				//  in the same way as the software implemantation does and calls WriteRgbMulti method.
sl@0
   248
				if(iDrawMode == EDrawModeWriteAlpha)
sl@0
   249
					{
sl@0
   250
					i = 0;
sl@0
   251
					}
sl@0
   252
				else if(iDrawMode == EDrawModePEN)
sl@0
   253
					{
sl@0
   254
					if(iBrushColor.Alpha() == 255)
sl@0
   255
						{
sl@0
   256
						i = 0;
sl@0
   257
						}
sl@0
   258
					else
sl@0
   259
						{
sl@0
   260
						TDisplayMode dispMode = iDevice->DisplayMode();
sl@0
   261
						if(dispMode != EColor64K && dispMode != EColor16MU && dispMode != EColor16MA && dispMode != EColor16MAP)
sl@0
   262
							{
sl@0
   263
							i = 0;
sl@0
   264
							}
sl@0
   265
						}
sl@0
   266
					}
sl@0
   267
				//Invert color
sl@0
   268
				else if(iDrawMode == EDrawModeNOTSCREEN)
sl@0
   269
					{
sl@0
   270
					i = 1;
sl@0
   271
					}
sl@0
   272
				}
sl@0
   273
			//use a patter brush
sl@0
   274
			else if(iBrushStyle == EPatternedBrush)
sl@0
   275
				{
sl@0
   276
				i = 2;
sl@0
   277
				}
sl@0
   278
			}
sl@0
   279
sl@0
   280
		if(i != -1)
sl@0
   281
			{
sl@0
   282
	        TInt gaOperationResult = KErrUnknown;
sl@0
   283
            iDevice->DrawingEnd();
sl@0
   284
sl@0
   285
			const TInt limit=iDefaultRegionPtr->Count();
sl@0
   286
			for (TInt count = 0; count < limit; count++)
sl@0
   287
				{
sl@0
   288
				iClipRect = (*iDefaultRegionPtr)[count];
sl@0
   289
				if (!iClipRect.Intersects(rcpy))
sl@0
   290
					continue;
sl@0
   291
sl@0
   292
				iClipRect.Intersection(rcpy);
sl@0
   293
				if (UserClipRect(iClipRect))
sl@0
   294
					continue;
sl@0
   295
sl@0
   296
				switch(i)
sl@0
   297
					{
sl@0
   298
				case 0:
sl@0
   299
					gaOperationResult = ga->Operation(TGopFilledRect(iClipRect,iBrushColor));
sl@0
   300
					break;
sl@0
   301
				case 1:
sl@0
   302
					gaOperationResult = ga->Operation(TGopInvertRect(iClipRect));
sl@0
   303
					break;
sl@0
   304
				case 2:
sl@0
   305
					CFbsBitmap* brushbitmap = (CFbsBitmap*)&iBrushBitmap;
sl@0
   306
					BG_ASSERT_ALWAYS(iBrushUsed,EBitgdiPanicInvalidBitmap);
sl@0
   307
					BG_ASSERT_ALWAYS(brushbitmap != NULL,EBitgdiPanicInvalidBitmap);
sl@0
   308
sl@0
   309
					TAcceleratedBitmapSpec brushBitmapSpec(brushbitmap);
sl@0
   310
					TGopFillPattern gopFillPattern;
sl@0
   311
					gopFillPattern.iBitmap = brushBitmapSpec;
sl@0
   312
					gopFillPattern.iOrigin = iBrushOrigin;
sl@0
   313
					gaOperationResult = ga->Operation(TGopFilledRectWithPattern(iClipRect,gopFillPattern));
sl@0
   314
					break;
sl@0
   315
					}			
sl@0
   316
				if(gaOperationResult != KErrNone)
sl@0
   317
					break;
sl@0
   318
				}
sl@0
   319
			if(gaOperationResult == KErrNone)
sl@0
   320
				goto finish;
sl@0
   321
			iDevice->DrawingBegin();
sl@0
   322
			}
sl@0
   323
		}
sl@0
   324
sl@0
   325
	RectFill(rcpy);
sl@0
   326
sl@0
   327
nofill:
sl@0
   328
	iDevice->DrawingEnd();
sl@0
   329
finish:
sl@0
   330
	if (brushRasterizer)
sl@0
   331
		{
sl@0
   332
		brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
sl@0
   333
		}
sl@0
   334
	iBrushBitmap.EndDataAccess(ETrue);
sl@0
   335
	}
sl@0
   336
sl@0
   337
// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method
sl@0
   338
void CFbsBitGc::RectFill(const TRect& aRect)
sl@0
   339
	{
sl@0
   340
	if (aRect.IsEmpty() || iBrushStyle == ENullBrush)
sl@0
   341
		return;
sl@0
   342
sl@0
   343
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   344
sl@0
   345
	AddRect(aRect);
sl@0
   346
sl@0
   347
	const TPoint origin = iOrigin + iBrushOrigin;
sl@0
   348
sl@0
   349
	const TInt limit=iDefaultRegionPtr->Count();
sl@0
   350
	for (TInt count = 0; count < limit; count++)
sl@0
   351
		{
sl@0
   352
		iClipRect = (*iDefaultRegionPtr)[count];
sl@0
   353
		if (!iClipRect.Intersects(aRect))
sl@0
   354
			continue;
sl@0
   355
sl@0
   356
		iClipRect.Intersection(aRect);
sl@0
   357
		if (UserClipRect(iClipRect))
sl@0
   358
			continue;
sl@0
   359
sl@0
   360
#ifdef _DEBUG
sl@0
   361
		TRect deviceRect;
sl@0
   362
		drawDevice->GetDrawRect(deviceRect);
sl@0
   363
#endif
sl@0
   364
		BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
   365
		BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
   366
		BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
   367
		BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
   368
sl@0
   369
		TInt xcoord = iClipRect.iTl.iX;
sl@0
   370
		TInt ycoord = iClipRect.iTl.iY;
sl@0
   371
sl@0
   372
sl@0
   373
		switch(iBrushStyle)
sl@0
   374
			{
sl@0
   375
		case ESolidBrush:
sl@0
   376
			drawDevice->WriteRgbMulti(iClipRect.iTl.iX,iClipRect.iTl.iY,
sl@0
   377
					iClipRect.Width(),iClipRect.Height(),iBrushColor,iDrawMode);
sl@0
   378
			break;
sl@0
   379
		case EPatternedBrush:
sl@0
   380
			{
sl@0
   381
			CBitwiseBitmap* brushbitmap = iBrushBitmap.Address();
sl@0
   382
			BG_ASSERT_ALWAYS(iBrushUsed,EBitgdiPanicInvalidBitmap);
sl@0
   383
			BG_ASSERT_ALWAYS(brushbitmap != NULL,EBitgdiPanicInvalidBitmap);
sl@0
   384
sl@0
   385
			TRect sourcerect(iClipRect);
sl@0
   386
			sourcerect.Move(-origin);
sl@0
   387
			DoBitBlt(iClipRect.iTl,brushbitmap,iBrushBitmap.DataAddress(),iBrushBitmap.DataStride(),sourcerect);
sl@0
   388
			break;
sl@0
   389
			}
sl@0
   390
		case EHorizontalHatchBrush:
sl@0
   391
			drawDevice->WriteRgbMulti(iClipRect.iTl.iX,iClipRect.iTl.iY,
sl@0
   392
					iClipRect.Width(),iClipRect.Height(),iBrushColor,iDrawMode);
sl@0
   393
			while (Abs((ycoord - origin.iY) % 3) != 2)
sl@0
   394
				ycoord++;
sl@0
   395
			for (; ycoord < iClipRect.iBr.iY; ycoord += 3)
sl@0
   396
				drawDevice->WriteRgbMulti(iClipRect.iTl.iX,ycoord,iClipRect.Width(),1,iPenColor,iDrawMode);
sl@0
   397
			break;
sl@0
   398
		case EVerticalHatchBrush:
sl@0
   399
			drawDevice->WriteRgbMulti(iClipRect.iTl.iX,iClipRect.iTl.iY,
sl@0
   400
					iClipRect.Width(),iClipRect.Height(),iBrushColor,iDrawMode);
sl@0
   401
			while (Abs((xcoord - origin.iX) % 3) != 2)
sl@0
   402
				xcoord++;
sl@0
   403
			for (; xcoord < iClipRect.iBr.iX; xcoord += 3)
sl@0
   404
				drawDevice->WriteRgbMulti(xcoord,iClipRect.iTl.iY,1,iClipRect.Height(),iPenColor,iDrawMode);
sl@0
   405
			break;
sl@0
   406
		case ESquareCrossHatchBrush:
sl@0
   407
			drawDevice->WriteRgbMulti(iClipRect.iTl.iX,iClipRect.iTl.iY,
sl@0
   408
					iClipRect.Width(),iClipRect.Height(),iBrushColor,iDrawMode);
sl@0
   409
			while (Abs((ycoord - origin.iY) % 3) != 2)
sl@0
   410
				ycoord++;
sl@0
   411
			for (; ycoord < iClipRect.iBr.iY; ycoord += 3) // horizontal lines
sl@0
   412
				drawDevice->WriteRgbMulti(iClipRect.iTl.iX,ycoord,iClipRect.Width(),1,iPenColor,iDrawMode);
sl@0
   413
sl@0
   414
			ycoord = iClipRect.iTl.iY;
sl@0
   415
			while (Abs((ycoord - origin.iY) % 3) != 2 && ycoord < iClipRect.iBr.iY) // above the top horizontal line
sl@0
   416
				{
sl@0
   417
				xcoord = iClipRect.iTl.iX;
sl@0
   418
				while (Abs((xcoord - origin.iX) % 3) != 2)
sl@0
   419
					xcoord++;
sl@0
   420
				for (; xcoord < iClipRect.iBr.iX; xcoord += 3)
sl@0
   421
					drawDevice->WriteRgb(xcoord,ycoord,iPenColor,iDrawMode);
sl@0
   422
				ycoord++;
sl@0
   423
				}
sl@0
   424
sl@0
   425
			ycoord += 3;
sl@0
   426
			for (; ycoord < iClipRect.iBr.iY; ycoord += 3) // between the top and bottom horizontals
sl@0
   427
				{
sl@0
   428
				xcoord = iClipRect.iTl.iX;
sl@0
   429
				while (Abs((xcoord - origin.iX) % 3) != 2)
sl@0
   430
					xcoord++;
sl@0
   431
				for (; xcoord < iClipRect.iBr.iX; xcoord += 3)
sl@0
   432
					drawDevice->WriteRgbMulti(xcoord,ycoord - 2,1,2,iPenColor,iDrawMode);
sl@0
   433
				}
sl@0
   434
sl@0
   435
			ycoord -= 3;
sl@0
   436
			while (ycoord < iClipRect.iBr.iY) // below the bottom horizontal
sl@0
   437
				{
sl@0
   438
				xcoord = iClipRect.iTl.iX;
sl@0
   439
				while (Abs((xcoord - origin.iX) % 3) != 2)
sl@0
   440
					xcoord++;
sl@0
   441
				for (; xcoord < iClipRect.iBr.iX; xcoord += 3)
sl@0
   442
					drawDevice->WriteRgb(xcoord,ycoord,iPenColor,iDrawMode);
sl@0
   443
				ycoord++;
sl@0
   444
				}
sl@0
   445
			break;
sl@0
   446
		case EForwardDiagonalHatchBrush:
sl@0
   447
			drawDevice->WriteRgbMulti(iClipRect.iTl.iX,iClipRect.iTl.iY,
sl@0
   448
					iClipRect.Width(),iClipRect.Height(),iBrushColor,iDrawMode);
sl@0
   449
			for (; ycoord < iClipRect.iBr.iY; ycoord++)
sl@0
   450
				{
sl@0
   451
				xcoord = iClipRect.iTl.iX;
sl@0
   452
				TInt diff = (origin.iX + origin.iY - xcoord - ycoord) % 3;
sl@0
   453
				if (diff < 0)
sl@0
   454
					diff += 3;
sl@0
   455
				xcoord += diff;
sl@0
   456
				for (; xcoord < iClipRect.iBr.iX; xcoord += 3)
sl@0
   457
					drawDevice->WriteRgb(xcoord,ycoord,iPenColor,iDrawMode);
sl@0
   458
				}
sl@0
   459
			break;
sl@0
   460
		case ERearwardDiagonalHatchBrush:
sl@0
   461
			drawDevice->WriteRgbMulti(iClipRect.iTl.iX,iClipRect.iTl.iY,
sl@0
   462
					iClipRect.Width(),iClipRect.Height(),iBrushColor,iDrawMode);
sl@0
   463
			for (; ycoord < iClipRect.iBr.iY; ycoord++)
sl@0
   464
				{
sl@0
   465
				xcoord = iClipRect.iTl.iX;
sl@0
   466
				TInt diff = (origin.iX - origin.iY - xcoord + ycoord) % 3;
sl@0
   467
				if (diff < 0)
sl@0
   468
					diff += 3;
sl@0
   469
				xcoord += diff;
sl@0
   470
				for (; xcoord < iClipRect.iBr.iX; xcoord += 3)
sl@0
   471
					drawDevice->WriteRgb(xcoord,ycoord,iPenColor,iDrawMode);
sl@0
   472
				}
sl@0
   473
			break;
sl@0
   474
		case EDiamondCrossHatchBrush:
sl@0
   475
			{
sl@0
   476
			drawDevice->WriteRgbMulti(iClipRect.iTl.iX,iClipRect.iTl.iY,
sl@0
   477
					iClipRect.Width(),iClipRect.Height(),iBrushColor,iDrawMode);
sl@0
   478
			TInt sum = xcoord + ycoord - origin.iX - origin.iY;
sl@0
   479
			for (; ycoord < iClipRect.iBr.iY; ycoord++,sum++)
sl@0
   480
				{
sl@0
   481
				TInt currentsum = sum;
sl@0
   482
				for (xcoord = iClipRect.iTl.iX; xcoord < iClipRect.iBr.iX; xcoord++,currentsum++)
sl@0
   483
					{
sl@0
   484
					if((currentsum & 1) == 0 && ((currentsum & 3) != 0 || ((xcoord-origin.iX) & 1) == 1))
sl@0
   485
						drawDevice->WriteRgb(xcoord,ycoord,iPenColor,iDrawMode);
sl@0
   486
					}
sl@0
   487
				}
sl@0
   488
			break;
sl@0
   489
			}
sl@0
   490
		default:
sl@0
   491
			return;
sl@0
   492
			}
sl@0
   493
sl@0
   494
		drawDevice->UpdateRegion(iClipRect);
sl@0
   495
		}
sl@0
   496
	}
sl@0
   497