|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "BMDRAW.H" |
|
17 #include "BitDrawInterfaceId.h" |
|
18 |
|
19 GLDEF_C void Panic(TScreenDriverPanic aPanicCode) |
|
20 { |
|
21 _LIT(KSCDVPanicCategory,"SCDV"); |
|
22 User::Panic(KSCDVPanicCategory,aPanicCode); |
|
23 } |
|
24 |
|
25 |
|
26 /** |
|
27 Alphablends a pixel. |
|
28 The formula used for that, is: |
|
29 (aPrimary * aAlphaValue + aSecondary * (255 - aAlphaValue)) / 255 - for each color (R,G,B). |
|
30 @param aPrimary RGB color 1. |
|
31 @param aSecondary RGB color 2. |
|
32 @param aAlphaValue Mask. |
|
33 @return Alpha blended value. |
|
34 @internalComponent |
|
35 */ |
|
36 TRgb AlphaBlend(TRgb aPrimary, TRgb aSecondary, TInt aAlphaValue) |
|
37 { |
|
38 return ::AlphaBlend(aPrimary.Red(), aPrimary.Green(), aPrimary.Blue(), aSecondary, aAlphaValue); |
|
39 } |
|
40 |
|
41 GLREF_D const TUint8 ditherlutab[16][4]; |
|
42 |
|
43 const TInt8 xIncArray[4] = { 1, 0, -1, 0 }; |
|
44 const TInt8 yIncArray[4] = { 0, 1, 0, -1 }; |
|
45 |
|
46 static CFbsDrawDevice* CreateBitmapDeviceL(const TSize& aSize, TDisplayMode aDispMode, TInt aDataStride) |
|
47 { |
|
48 CFbsDrawDevice* drawDevice = NULL; |
|
49 |
|
50 switch(aDispMode) |
|
51 { |
|
52 case EGray2: |
|
53 drawDevice = new(ELeave) CDrawOneBppBitmap; |
|
54 CleanupStack::PushL(drawDevice); |
|
55 User::LeaveIfError(((CDrawOneBppBitmap*)drawDevice)->Construct(aSize, aDataStride)); |
|
56 break; |
|
57 case EGray4: |
|
58 drawDevice = new(ELeave) CDrawTwoBppBitmap; |
|
59 CleanupStack::PushL(drawDevice); |
|
60 User::LeaveIfError(((CDrawTwoBppBitmap*)drawDevice)->Construct(aSize, aDataStride)); |
|
61 break; |
|
62 case EGray16: |
|
63 drawDevice = new(ELeave) CDrawFourBppBitmapGray; |
|
64 CleanupStack::PushL(drawDevice); |
|
65 User::LeaveIfError(((CDrawFourBppBitmapGray*)drawDevice)->Construct(aSize, aDataStride)); |
|
66 break; |
|
67 case EGray256: |
|
68 drawDevice = new(ELeave) CDrawEightBppBitmapGray; |
|
69 CleanupStack::PushL(drawDevice); |
|
70 User::LeaveIfError(((CDrawEightBppBitmapGray*)drawDevice)->Construct(aSize, aDataStride)); |
|
71 break; |
|
72 case EColor16: |
|
73 drawDevice = new(ELeave) CDrawFourBppBitmapColor; |
|
74 CleanupStack::PushL(drawDevice); |
|
75 User::LeaveIfError(((CDrawFourBppBitmapColor*)drawDevice)->Construct(aSize, aDataStride)); |
|
76 break; |
|
77 case EColor256: |
|
78 drawDevice = new(ELeave) CDrawEightBppBitmapColor; |
|
79 CleanupStack::PushL(drawDevice); |
|
80 User::LeaveIfError(((CDrawEightBppBitmapColor*)drawDevice)->Construct(aSize, aDataStride)); |
|
81 break; |
|
82 case EColor4K: |
|
83 drawDevice = new(ELeave) CDrawTwelveBppBitmap; |
|
84 CleanupStack::PushL(drawDevice); |
|
85 User::LeaveIfError(((CDrawTwelveBppBitmap*)drawDevice)->Construct(aSize, aDataStride)); |
|
86 break; |
|
87 case EColor64K: |
|
88 drawDevice = new(ELeave) CDrawSixteenBppBitmap; |
|
89 CleanupStack::PushL(drawDevice); |
|
90 User::LeaveIfError(((CDrawSixteenBppBitmap*)drawDevice)->Construct(aSize, aDataStride)); |
|
91 break; |
|
92 case EColor16M: |
|
93 drawDevice = new(ELeave) CDrawTwentyFourBppBitmap; |
|
94 CleanupStack::PushL(drawDevice); |
|
95 User::LeaveIfError(((CDrawTwentyFourBppBitmap*)drawDevice)->Construct(aSize, aDataStride)); |
|
96 break; |
|
97 case EColor16MU: |
|
98 drawDevice = new(ELeave) CDrawUTwentyFourBppBitmap; |
|
99 CleanupStack::PushL(drawDevice); |
|
100 User::LeaveIfError(((CDrawUTwentyFourBppBitmap*)drawDevice)->Construct(aSize, aDataStride)); |
|
101 break; |
|
102 case EColor16MA: |
|
103 drawDevice = new(ELeave) CDrawThirtyTwoBppBitmapAlpha; |
|
104 CleanupStack::PushL(drawDevice); |
|
105 User::LeaveIfError(((CDrawThirtyTwoBppBitmapAlpha*)drawDevice)->Construct(aSize, aDataStride)); |
|
106 break; |
|
107 case EColor16MAP: |
|
108 drawDevice = new(ELeave) CDrawThirtyTwoBppBitmapAlphaPM; |
|
109 CleanupStack::PushL(drawDevice); |
|
110 User::LeaveIfError(((CDrawThirtyTwoBppBitmapAlphaPM*)drawDevice)->Construct(aSize, aDataStride)); |
|
111 break; |
|
112 default: |
|
113 Panic(EScreenDriverPanicInvalidDisplayMode); |
|
114 } |
|
115 CleanupStack::Pop(drawDevice); // drawDevice |
|
116 return drawDevice; |
|
117 } |
|
118 |
|
119 /** |
|
120 @deprecated Use NewBitmapDeviceL(const TSize& aSize, TDisplayMode aDispMode, TInt aDataStride) |
|
121 */ |
|
122 EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewBitmapDeviceL(TScreenInfoV01 aInfo, |
|
123 TDisplayMode aDispMode, |
|
124 TInt aDataStride) |
|
125 { |
|
126 return ::CreateBitmapDeviceL(aInfo.iScreenSize, aDispMode, aDataStride); |
|
127 } |
|
128 |
|
129 /** |
|
130 Creates a new bitmap device instance, which implements CFbsDrawDevice interface. |
|
131 @param aSize Bitmap device size |
|
132 @param aDispMode Requested display mode |
|
133 @return A pointer to just created bitmap device, which implements CFbsDrawDevice interface |
|
134 @leave KErrNoMemory Not enough memory |
|
135 KErrArgument Invalid aSize value |
|
136 */ |
|
137 EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewBitmapDeviceL(const TSize& aSize, |
|
138 TDisplayMode aDispMode, |
|
139 TInt aDataStride) |
|
140 { |
|
141 return ::CreateBitmapDeviceL(aSize, aDispMode, aDataStride); |
|
142 } |
|
143 |
|
144 //Logical coordinates will be initialized with the right values, when SetSize() is called. |
|
145 CDrawBitmap::CDrawBitmap() |
|
146 { |
|
147 SetDefaults(); |
|
148 TInt err = GetInterface(KAlphaBlendInterfaceID, reinterpret_cast <TAny*&> (iAlphaBlend)); |
|
149 //There must be a support for an interface with KAlphaBlendInterfaceID id. |
|
150 __ASSERT_ALWAYS(iAlphaBlend && err == KErrNone, User::Invariant()); |
|
151 } |
|
152 |
|
153 //Scanline width in pixels. |
|
154 //The return value can be greater or equal than iSize.iWidth, because |
|
155 //the scan line memory is allocated in 32-bit words and can be rounded up, if |
|
156 //the display mode allows more than 1 pixel to be stored in a single byte. |
|
157 TInt CDrawBitmap::LongWidth() const |
|
158 { |
|
159 //0 or 180 dgrees |
|
160 if(!(iOrientation & 1)) |
|
161 { |
|
162 return iLongWidth; |
|
163 } |
|
164 //90 or 270 degrees |
|
165 return iSize.iWidth == 0 ? 0 : iLongWidth * iSize.iHeight / iSize.iWidth; |
|
166 } |
|
167 |
|
168 TUint32* CDrawBitmap::ScanLineBuffer() const |
|
169 { |
|
170 return iScanLineBuffer; |
|
171 } |
|
172 |
|
173 //Scanline width in bytes |
|
174 TInt CDrawBitmap::ScanLineBytes() const |
|
175 { |
|
176 register TInt scanLineBytes = iScanLineWords << 2; |
|
177 //90 or 270 degrees |
|
178 if(iOrientation & 1) |
|
179 { |
|
180 return iSize.iWidth == 0 ? 0 : scanLineBytes * iSize.iHeight / iSize.iWidth; |
|
181 } |
|
182 //0 or 180 degrees |
|
183 return scanLineBytes; |
|
184 } |
|
185 |
|
186 /** |
|
187 The method returns screen size in pixels. The orientation is taken into account. |
|
188 Always prefer GetDrawRect() to SizeInPixels() call. |
|
189 GetDrawRect() will take into account possible non-[0,0] top-left corner of the drawing |
|
190 rectangle if the device is scaled. |
|
191 @return TSize Screen size in pixels |
|
192 */ |
|
193 TSize CDrawBitmap::SizeInPixels() const |
|
194 { |
|
195 //90 or 270 degrees |
|
196 if(iOrientation & 1) |
|
197 { |
|
198 return TSize(iDrawRect.Height(), iDrawRect.Width()); |
|
199 } |
|
200 //0 or 180 degrees |
|
201 return iDrawRect.Size(); |
|
202 } |
|
203 |
|
204 //aPoint - logical coordinates |
|
205 void CDrawBitmap::SetDitherOrigin(const TPoint& aPoint) |
|
206 { |
|
207 if (iOrientation&1) |
|
208 { |
|
209 iDitherOrigin.iX = ::Log2Phys(aPoint.iX,iOrigin.iX,iScalingSettings.iFactorY,iSize.iHeight); |
|
210 iDitherOrigin.iY = ::Log2Phys(aPoint.iY,iOrigin.iY,iScalingSettings.iFactorX,iSize.iWidth); |
|
211 } |
|
212 else |
|
213 { |
|
214 iDitherOrigin.iX = ::Log2Phys(aPoint.iX,iOrigin.iX,iScalingSettings.iFactorX,iSize.iWidth); |
|
215 iDitherOrigin.iY = ::Log2Phys(aPoint.iY,iOrigin.iY,iScalingSettings.iFactorY,iSize.iHeight); |
|
216 } |
|
217 } |
|
218 |
|
219 TInt CDrawBitmap::BitsPerPixel(TDisplayMode aDispMode) |
|
220 { |
|
221 switch(aDispMode) |
|
222 { |
|
223 case EGray2: |
|
224 return 1; |
|
225 case EGray4: |
|
226 return 2; |
|
227 case EGray16: |
|
228 case EColor16: |
|
229 return 4; |
|
230 case EGray256: |
|
231 case EColor256: |
|
232 return 8; |
|
233 case EColor4K: |
|
234 case EColor64K: |
|
235 return 16; |
|
236 case EColor16M: |
|
237 return 24; |
|
238 case EColor16MU: |
|
239 case EColor16MA: |
|
240 case EColor16MAP: |
|
241 return 32; |
|
242 default: |
|
243 return 0; |
|
244 } |
|
245 } |
|
246 |
|
247 void CDrawBitmap::OrientationsAvailable(TBool aOrientation[4]) |
|
248 { |
|
249 aOrientation[EOrientationNormal] = ETrue; |
|
250 aOrientation[EOrientationRotated90] = EFalse; |
|
251 aOrientation[EOrientationRotated180] = EFalse; |
|
252 aOrientation[EOrientationRotated270] = EFalse; |
|
253 } |
|
254 |
|
255 //Works with logical coordinates |
|
256 void CDrawBitmap::Clear() |
|
257 { |
|
258 if(iBits) |
|
259 { |
|
260 if(iScalingOff && iOriginIsZero) |
|
261 { |
|
262 Mem::Fill(iBits, iScanLineWords * 4 * iSize.iHeight, 0xFF); |
|
263 } |
|
264 else |
|
265 { |
|
266 TShadowMode storedShadowMode = iShadowMode; |
|
267 iShadowMode = ENoShadow; |
|
268 TRect drawRect; |
|
269 GetDrawRect(drawRect); |
|
270 WriteRgbMulti(drawRect.iTl.iX, drawRect.iTl.iY, drawRect.Width(), drawRect.Height(), KRgbWhite, CGraphicsContext::EDrawModeWriteAlpha); |
|
271 iShadowMode = storedShadowMode; |
|
272 } |
|
273 } |
|
274 } |
|
275 |
|
276 CDrawBitmap::~CDrawBitmap() |
|
277 { |
|
278 if(iScanLineBuffer) |
|
279 { |
|
280 User::Free(iScanLineBuffer); |
|
281 } |
|
282 } |
|
283 |
|
284 //Works with logical sizes |
|
285 //The new device will accept old device scalling&scaling settings |
|
286 //All graphics contexts, already created by the scaled device, should be |
|
287 //re-activated calling CFbsBitGc::Activate(). |
|
288 void CDrawBitmap::CopyOldSettings(CFbsDrawDevice* aDrawDevice) |
|
289 { |
|
290 __ASSERT_DEBUG(aDrawDevice, User::Invariant()); |
|
291 //Scaling&Origin settings - their values when scaling&origin are off. |
|
292 const TPoint KDefaultOrigin(0, 0); |
|
293 const TInt KDefaultFactorX = 1, KDefaultFactorY = 1; |
|
294 const TInt KDefaultDivisorX = 1, KDefaultDivisorY = 1; |
|
295 TPoint origin = KDefaultOrigin;//old device origin |
|
296 TInt factorX = KDefaultFactorX, factorY = KDefaultFactorY;//old device - X and Y scaling factors |
|
297 TInt divisorX = KDefaultDivisorX, divisorY = KDefaultDivisorY;//old device - X and Y scaling divisors |
|
298 //Old device - set default scaling setings. |
|
299 MScalingSettings* scalingSettings = NULL; |
|
300 TInt err = aDrawDevice->GetInterface(KScalingSettingsInterfaceID, reinterpret_cast <TAny*&> (scalingSettings)); |
|
301 if(err == KErrNone) |
|
302 {//There is a support for the interface with KScalingSettingsInterfaceID id. |
|
303 __ASSERT_DEBUG(scalingSettings, User::Invariant()); |
|
304 scalingSettings->Get(factorX, factorY, divisorX, divisorY); |
|
305 (void)scalingSettings->Set(KDefaultFactorX, KDefaultFactorY, KDefaultDivisorX, KDefaultDivisorY); |
|
306 } |
|
307 //Current device - set default scaling setings. |
|
308 if(CanBeScaled()) |
|
309 { |
|
310 (void)Set(KDefaultFactorX, KDefaultFactorY, KDefaultDivisorX, KDefaultDivisorY); |
|
311 } |
|
312 //Old device - set default origin. |
|
313 MDrawDeviceOrigin* originInterface = NULL; |
|
314 err = aDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, reinterpret_cast <TAny*&> (originInterface)); |
|
315 if(err == KErrNone) |
|
316 {//There is a support for the interface with KDrawDeviceOriginInterfaceID id. |
|
317 __ASSERT_DEBUG(originInterface, User::Invariant()); |
|
318 originInterface->Get(origin); |
|
319 (void)originInterface->Set(KDefaultOrigin); |
|
320 } |
|
321 //Current device - set default origin. |
|
322 if(CanOriginBeMoved()) |
|
323 { |
|
324 (void)Set(KDefaultOrigin); |
|
325 } |
|
326 //Copy setigns |
|
327 DoCopyOldSettings(aDrawDevice); |
|
328 //Old device - restore scaling setings. |
|
329 if(scalingSettings) |
|
330 { |
|
331 (void)scalingSettings->Set(factorX, factorY, divisorX, divisorY); |
|
332 } |
|
333 //Old device - restore origin. |
|
334 if(originInterface) |
|
335 { |
|
336 (void)originInterface->Set(origin); |
|
337 } |
|
338 //Set current device scaling&origin settings to be the same as |
|
339 //scaling&origin settings of the old device. |
|
340 if(CanBeScaled()) |
|
341 { |
|
342 (void)Set(factorX, factorY, divisorX, divisorY); |
|
343 } |
|
344 if(CanOriginBeMoved()) |
|
345 { |
|
346 (void)Set(origin); |
|
347 } |
|
348 } |
|
349 |
|
350 void CDrawBitmap::DoCopyOldSettings(CFbsDrawDevice* aDrawDevice) |
|
351 { |
|
352 CDrawBitmap* oldDevice = (CDrawBitmap*)aDrawDevice; |
|
353 iDitherOrigin = oldDevice->iDitherOrigin; |
|
354 iShadowMode = oldDevice->iShadowMode; |
|
355 SetOrientation(oldDevice->iOrientation); |
|
356 iFadeMapFactor = oldDevice->iFadeMapFactor; |
|
357 iFadeMapOffset = oldDevice->iFadeMapOffset; |
|
358 |
|
359 TUint32* destRowPtr = iBits; |
|
360 TUint32* destRowPtrLimit = iBits; |
|
361 TInt destRowPtrInc = iScanLineWords; |
|
362 |
|
363 TInt row = 0; |
|
364 TInt rowInc = 1; |
|
365 |
|
366 if (BitsPerPixel(oldDevice->iDispMode) < BitsPerPixel(iDispMode)) |
|
367 { |
|
368 destRowPtr += (iSize.iHeight - 1) * iScanLineWords; |
|
369 destRowPtrInc = -destRowPtrInc; |
|
370 destRowPtrLimit -= iScanLineWords; |
|
371 row = iSize.iHeight - 1; |
|
372 rowInc = -1; |
|
373 } |
|
374 else |
|
375 destRowPtrLimit += iSize.iHeight * iScanLineWords; |
|
376 |
|
377 TOrientation oldOrientation=oldDevice->iOrientation; |
|
378 oldDevice->SetOrientation(CFbsDrawDevice::EOrientationNormal); |
|
379 while (destRowPtr != destRowPtrLimit) |
|
380 { |
|
381 aDrawDevice->ReadLine(0,row,iSize.iWidth,iScanLineBuffer,iDispMode); |
|
382 Mem::Copy(destRowPtr,iScanLineBuffer,iScanLineWords << 2); |
|
383 destRowPtr += destRowPtrInc; |
|
384 row += rowInc; |
|
385 } |
|
386 |
|
387 oldDevice->SetOrientation(oldOrientation); |
|
388 UpdateRegion(TRect(SizeInPixels())); |
|
389 Update(); |
|
390 } |
|
391 |
|
392 TUint32 CDrawBitmap::Hash(TUint32 aGray16,TInt aX,TInt aY) const |
|
393 { |
|
394 if (iDitherOrigin.iX & 1) |
|
395 aX++; |
|
396 if (iDitherOrigin.iY & 1) |
|
397 aY++; |
|
398 aX &= 1; |
|
399 aY &= 1; |
|
400 return ditherlutab[aGray16][aX + (aY << 1)]; |
|
401 } |
|
402 |
|
403 //aRect - logical coordinates |
|
404 void CDrawBitmap::MapColors(const TRect& aRect, const TRgb* aColors, |
|
405 TInt aNumPairs, TBool aMapForwards) |
|
406 { |
|
407 const TRect rect = DeOrientate(aRect);//deorientation and transformation of coordinates. |
|
408 //rect - physical coordinates |
|
409 __ASSERT_DEBUG(rect.iTl.iX >= 0 && rect.iBr.iX <= iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds)); |
|
410 __ASSERT_DEBUG(rect.iTl.iY >= 0 && rect.iBr.iY <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds)); |
|
411 __ASSERT_DEBUG(aColors,Panic(EScreenDriverPanicNullPointer)); |
|
412 __ASSERT_DEBUG(aNumPairs > 0,Panic(EScreenDriverPanicZeroLength)); |
|
413 |
|
414 TRgb color; |
|
415 |
|
416 TInt offset = aMapForwards ? 0 : 1; |
|
417 TInt scaleX; |
|
418 TInt scaleY; |
|
419 if (iOrientation&1) |
|
420 { |
|
421 scaleX=iScalingSettings.iFactorY; |
|
422 scaleY=iScalingSettings.iFactorX; |
|
423 } |
|
424 else |
|
425 { |
|
426 scaleX=iScalingSettings.iFactorX; |
|
427 scaleY=iScalingSettings.iFactorY; |
|
428 } |
|
429 for(TInt ycoord = rect.iTl.iY; ycoord < rect.iBr.iY; ycoord+=scaleY) |
|
430 { |
|
431 for(TInt xcoord = rect.iTl.iX; xcoord < rect.iBr.iX; xcoord+=scaleX) |
|
432 { |
|
433 color = ReadRgbNormal(xcoord,ycoord); |
|
434 for (TInt rgbcount = 0; rgbcount < aNumPairs; rgbcount++) |
|
435 { |
|
436 if (color == aColors[(rgbcount << 1) + offset]) |
|
437 { |
|
438 WriteRgb(xcoord,ycoord,aColors[(rgbcount << 1) + 1 - offset]); |
|
439 break; |
|
440 } |
|
441 } |
|
442 } |
|
443 } |
|
444 } |
|
445 |
|
446 //form an int from the end portion of one and the start portion of another |
|
447 TUint32 CDrawBitmap::PasteInt(TUint32 aFirst,TUint32 aSecond,TInt aOffset) const |
|
448 { |
|
449 TUint32 mask=0; |
|
450 if(aOffset<32) mask=0xffffffff>>aOffset; |
|
451 aFirst&=mask; |
|
452 aSecond&=~mask; |
|
453 return(aFirst|aSecond); |
|
454 } |
|
455 |
|
456 //returns the address of the start of scanline aY |
|
457 //aY- physical coordinate |
|
458 TUint32* CDrawBitmap::ScanLine(TInt aY) const |
|
459 { |
|
460 return iBits + (aY * iScanLineWords); |
|
461 } |
|
462 |
|
463 void CDrawBitmap::SetBits(TAny* aBits) |
|
464 { |
|
465 iBits = STATIC_CAST(TUint32*,aBits); |
|
466 } |
|
467 |
|
468 TBool CDrawBitmap::SetOrientation(TOrientation aOrientation) |
|
469 { |
|
470 if (iOrientation == aOrientation) |
|
471 return ETrue; |
|
472 |
|
473 return EFalse; |
|
474 } |
|
475 |
|
476 void CDrawBitmap::SetFadingParameters(TUint8 aBlackMap,TUint8 aWhiteMap) |
|
477 { |
|
478 iFadeMapFactor = aWhiteMap - aBlackMap + 1; |
|
479 iFadeMapOffset = aBlackMap; |
|
480 } |
|
481 |
|
482 TRgb CDrawBitmap::FadeRgb(TRgb aColor) |
|
483 { |
|
484 TInt value = aColor.Internal(); |
|
485 TInt b = (((value & 0x000000ff) * iFadeMapFactor) >> 8) + iFadeMapOffset; |
|
486 TInt g = (((value & 0x0000ff00) * iFadeMapFactor) >> 16) + iFadeMapOffset; |
|
487 //the multiplication by iFadeMapFactor can overflow into the sign bit, so we shift down in two steps |
|
488 TInt r = ((((value & 0x00ff0000) >> 16) * iFadeMapFactor) >> 8) + iFadeMapOffset; |
|
489 TInt a = aColor.Alpha(); |
|
490 return TRgb(r,g,b,a); |
|
491 } |
|
492 |
|
493 TUint32 CDrawBitmap::FadeRgb(TUint32 aColor) |
|
494 { |
|
495 TInt value = aColor; |
|
496 |
|
497 TInt b = (((value & 0x000000ff) * iFadeMapFactor) >> 8) + iFadeMapOffset; |
|
498 TInt g = (((value & 0x0000ff00) * iFadeMapFactor) >> 16) + iFadeMapOffset; |
|
499 //the multiplication by iFadeMapFactor can overflow into the sign bit, so we shift down in two steps |
|
500 TInt r = ((((value & 0x00ff0000) >> 16) * iFadeMapFactor) >> 8) + iFadeMapOffset; |
|
501 TInt a = aColor >> 24; |
|
502 return (a<<24) | ((r&0xff)<<16) | ((g&0xff)<<8) | (b&0xff); |
|
503 } |
|
504 |
|
505 /** |
|
506 The overloaded function for FadeRgb(TRgb) which works directly with |
|
507 the Red, Green and Blue colour components to increase the performance. |
|
508 @param aRed Red component of colour. |
|
509 @param aGreen Green component of colour. |
|
510 @param aBlue Blue component of colour. |
|
511 */ |
|
512 void CDrawBitmap::FadeRgb(TInt& aRed, TInt& aGreen, TInt& aBlue) |
|
513 { |
|
514 aRed = ((aRed * iFadeMapFactor) >> 8) + iFadeMapOffset; |
|
515 aGreen = ((aGreen * iFadeMapFactor) >> 8) + iFadeMapOffset; |
|
516 aBlue = ((aBlue * iFadeMapFactor) >> 8) + iFadeMapOffset; |
|
517 } |
|
518 |
|
519 TUint8 CDrawBitmap::FadeGray(TInt aGray256) |
|
520 { |
|
521 return STATIC_CAST(TUint8,((aGray256 * iFadeMapFactor) >> 8) + iFadeMapOffset); |
|
522 } |
|
523 |
|
524 //aX and aY - logical coordinates |
|
525 //aX and aY - deorientated and transformed to physical coordinates after the call |
|
526 void CDrawBitmap::DeOrientate(TInt& aX,TInt& aY) const |
|
527 { |
|
528 register TInt physWidth = iSize.iWidth; |
|
529 register TInt physHeight = iSize.iHeight; |
|
530 register TInt originX = iOrigin.iX; |
|
531 register TInt originY = iOrigin.iY; |
|
532 register TInt scalingFactorX = iScalingSettings.iFactorX; |
|
533 register TInt scalingFactorY = iScalingSettings.iFactorY; |
|
534 if(iOrientation & 0x1) |
|
535 { |
|
536 aX = ::Log2Phys(aX, originX, scalingFactorY, physHeight); |
|
537 aY = ::Log2Phys(aY, originY, scalingFactorX, physWidth); |
|
538 } |
|
539 else |
|
540 { |
|
541 aX = ::Log2Phys(aX, originX, scalingFactorX, physWidth); |
|
542 aY = ::Log2Phys(aY, originY, scalingFactorY, physHeight); |
|
543 } |
|
544 |
|
545 //aX and aY - descaled. |
|
546 switch(iOrientation) |
|
547 { |
|
548 case EOrientationNormal: |
|
549 { |
|
550 return; |
|
551 } |
|
552 case EOrientationRotated180: |
|
553 { |
|
554 aX = physWidth - aX - 1; |
|
555 aY = physHeight - aY - 1; |
|
556 break; |
|
557 } |
|
558 case EOrientationRotated90: |
|
559 { |
|
560 TInt temp = physWidth - aY - 1; |
|
561 aY = aX; |
|
562 aX = temp; |
|
563 break; |
|
564 } |
|
565 default: // EOrientationRotated270 |
|
566 { |
|
567 TInt temp = aY; |
|
568 aY = physHeight - aX - 1; |
|
569 aX = temp; |
|
570 } |
|
571 } |
|
572 } |
|
573 |
|
574 //aPoint - logical coordinates |
|
575 //The method returns TPoint object with deorientated and transformed to physical coordinates. |
|
576 TPoint CDrawBitmap::DeOrientate(const TPoint& aPoint) const |
|
577 { |
|
578 register TInt physWidth = iSize.iWidth; |
|
579 register TInt physHeight = iSize.iHeight; |
|
580 register TInt originX = iOrigin.iX; |
|
581 register TInt originY = iOrigin.iY; |
|
582 register TInt scalingFactorX = iScalingSettings.iFactorX; |
|
583 register TInt scalingFactorY = iScalingSettings.iFactorY; |
|
584 TPoint physPt; |
|
585 if(iOrientation & 0x1) |
|
586 { |
|
587 physPt.iX = ::Log2Phys(aPoint.iX, originX, scalingFactorY, physHeight); |
|
588 physPt.iY = ::Log2Phys(aPoint.iY, originY, scalingFactorX, physWidth); |
|
589 } |
|
590 else |
|
591 { |
|
592 physPt.iX = ::Log2Phys(aPoint.iX, originX, scalingFactorX, physWidth); |
|
593 physPt.iY = ::Log2Phys(aPoint.iY, originY, scalingFactorY, physHeight); |
|
594 } |
|
595 |
|
596 //physPt - descaled |
|
597 switch(iOrientation) |
|
598 { |
|
599 case EOrientationNormal: |
|
600 { |
|
601 return physPt; |
|
602 } |
|
603 case EOrientationRotated180: |
|
604 { |
|
605 return TPoint(physWidth - physPt.iX - 1, physHeight - physPt.iY - 1); |
|
606 } |
|
607 case EOrientationRotated90: |
|
608 { |
|
609 return TPoint(physWidth - physPt.iY - 1, physPt.iX); |
|
610 } |
|
611 // EOrientationRotated270 |
|
612 default: |
|
613 return TPoint(physPt.iY, physHeight - physPt.iX - 1); |
|
614 } |
|
615 } |
|
616 |
|
617 //aRect - logical coordinates |
|
618 //The method returns TRect object with deorientated and transformed to physical coordinates. |
|
619 TRect CDrawBitmap::DeOrientate(const TRect& aRect) const |
|
620 { |
|
621 register TInt originX = iOrigin.iX; |
|
622 register TInt originY = iOrigin.iY; |
|
623 register TInt scalingFactorX = iScalingSettings.iFactorX; |
|
624 register TInt scalingFactorY = iScalingSettings.iFactorY; |
|
625 register TInt physWidth = iSize.iWidth; |
|
626 register TInt physHeight = iSize.iHeight; |
|
627 TRect physRect; |
|
628 if(iOrientation & 0x1) |
|
629 { |
|
630 physRect.iTl.iX = ::Log2Phys(aRect.iTl.iX, originX, scalingFactorY, physHeight); |
|
631 physRect.iTl.iY = ::Log2Phys(aRect.iTl.iY, originY, scalingFactorX, physWidth); |
|
632 physRect.iBr.iX = ::RBtmLog2Phys(aRect.iBr.iX, originX, scalingFactorY, physHeight); |
|
633 physRect.iBr.iY = ::RBtmLog2Phys(aRect.iBr.iY, originY, scalingFactorX, physWidth); |
|
634 } |
|
635 else |
|
636 { |
|
637 physRect.iTl.iX = ::Log2Phys(aRect.iTl.iX, originX, scalingFactorX, physWidth); |
|
638 physRect.iTl.iY = ::Log2Phys(aRect.iTl.iY, originY, scalingFactorY, physHeight); |
|
639 physRect.iBr.iX = ::RBtmLog2Phys(aRect.iBr.iX, originX, scalingFactorX, physWidth); |
|
640 physRect.iBr.iY = ::RBtmLog2Phys(aRect.iBr.iY, originY, scalingFactorY, physHeight); |
|
641 } |
|
642 |
|
643 //physRect - descaled |
|
644 if(iOrientation == EOrientationNormal) |
|
645 { |
|
646 return physRect; |
|
647 } |
|
648 if (iOrientation == EOrientationRotated180) |
|
649 { |
|
650 return TRect(TPoint(physWidth - physRect.iBr.iX, physHeight - physRect.iBr.iY), physRect.Size()); |
|
651 } |
|
652 TSize altSize(physRect.Height(), physRect.Width()); |
|
653 TPoint altPoint; |
|
654 if (iOrientation == EOrientationRotated90) |
|
655 { |
|
656 altPoint.SetXY(physWidth - physRect.iBr.iY, physRect.iTl.iX); |
|
657 } |
|
658 else // EOrientationRotated270 |
|
659 { |
|
660 altPoint.SetXY(physRect.iTl.iY, physHeight - physRect.iBr.iX); |
|
661 } |
|
662 return TRect(altPoint, altSize); |
|
663 } |
|
664 |
|
665 //aX and aY - logical coordinates |
|
666 TRgb CDrawBitmap::ReadPixel(TInt aX,TInt aY) const |
|
667 { |
|
668 DeOrientate(aX, aY);//aX and aY - physical coordinates |
|
669 |
|
670 __ASSERT_DEBUG(aX >= 0 && aX < iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds)); |
|
671 __ASSERT_DEBUG(aY >= 0 && aY < iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds)); |
|
672 |
|
673 return ReadRgbNormal(aX, aY); |
|
674 } |
|
675 |
|
676 //aX and aY - logical coordinates |
|
677 void CDrawBitmap::ReadLine(TInt aX,TInt aY,TInt aLength, |
|
678 TAny* aBuffer,TDisplayMode aDispMode) const |
|
679 { |
|
680 DeOrientate(aX,aY);//aX and aY - physical coordinates |
|
681 |
|
682 __ASSERT_DEBUG(aX >= 0 && aX < iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds)); |
|
683 __ASSERT_DEBUG(aY >= 0 && aY < iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds)); |
|
684 #if defined(_DEBUG) |
|
685 switch (iOrientation) |
|
686 { |
|
687 case EOrientationNormal: |
|
688 __ASSERT_DEBUG(aX + aLength <= iLongWidth,Panic(EScreenDriverPanicOutOfBounds)); |
|
689 break; |
|
690 case EOrientationRotated90: |
|
691 __ASSERT_DEBUG(aY + aLength <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds)); |
|
692 break; |
|
693 case EOrientationRotated180: |
|
694 __ASSERT_DEBUG(aX - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds)); |
|
695 break; |
|
696 default: // EOrientationRotated270 |
|
697 __ASSERT_DEBUG(aY - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds)); |
|
698 break; |
|
699 } |
|
700 #endif |
|
701 __ASSERT_DEBUG(aLength > 0,Panic(EScreenDriverPanicZeroLength)); |
|
702 __ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer)); |
|
703 |
|
704 if (aDispMode == iDispMode) |
|
705 { |
|
706 ReadLine(aX,aY,aLength,aBuffer); |
|
707 return; |
|
708 } |
|
709 |
|
710 TInt xInc = xIncArray[iOrientation]; |
|
711 TInt yInc = yIncArray[iOrientation]; |
|
712 if(iOrientation & 0x1) |
|
713 { |
|
714 xInc*=iScalingSettings.iFactorY; |
|
715 yInc*=iScalingSettings.iFactorX; |
|
716 } |
|
717 else |
|
718 { |
|
719 xInc*=iScalingSettings.iFactorX; |
|
720 yInc*=iScalingSettings.iFactorY; |
|
721 } |
|
722 |
|
723 switch (aDispMode) |
|
724 { |
|
725 case EGray2: |
|
726 { |
|
727 TUint8* bufferPtr = (TUint8*)aBuffer; |
|
728 |
|
729 while (aLength >= 8) |
|
730 { |
|
731 bufferPtr[0] = TUint8(ReadRgbNormal(aX,aY)._Gray2()); |
|
732 aX += xInc; aY += yInc; |
|
733 bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 1); |
|
734 aX += xInc; aY += yInc; |
|
735 bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 2); |
|
736 aX += xInc; aY += yInc; |
|
737 bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 3); |
|
738 aX += xInc; aY += yInc; |
|
739 bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 4); |
|
740 aX += xInc; aY += yInc; |
|
741 bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 5); |
|
742 aX += xInc; aY += yInc; |
|
743 bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 6); |
|
744 aX += xInc; aY += yInc; |
|
745 bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 7); |
|
746 aX += xInc; aY += yInc; |
|
747 bufferPtr++; |
|
748 aLength -= 8; |
|
749 } |
|
750 TInt bitShift = 0; |
|
751 TInt bitLimit = aLength; |
|
752 if (bitShift < bitLimit) |
|
753 bufferPtr[0] = 0; |
|
754 while (bitShift < bitLimit) |
|
755 { |
|
756 bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << bitShift); |
|
757 aX += xInc; aY += yInc; |
|
758 bitShift++; |
|
759 } |
|
760 } |
|
761 break; |
|
762 case EGray4: |
|
763 { |
|
764 TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer); |
|
765 |
|
766 while (aLength > 3) |
|
767 { |
|
768 *bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray4()); |
|
769 aX += xInc; aY += yInc; |
|
770 *bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 2); |
|
771 aX += xInc; aY += yInc; |
|
772 *bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 4); |
|
773 aX += xInc; aY += yInc; |
|
774 *bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 6); |
|
775 aX += xInc; aY += yInc; |
|
776 aLength -= 4; |
|
777 } |
|
778 if (aLength > 0) |
|
779 { |
|
780 *bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray4()); |
|
781 aX += xInc; aY += yInc; |
|
782 aLength--; |
|
783 } |
|
784 if (aLength > 0) |
|
785 { |
|
786 *bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 2); |
|
787 aX += xInc; aY += yInc; |
|
788 aLength--; |
|
789 } |
|
790 if (aLength > 0) |
|
791 *bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 4); |
|
792 } |
|
793 break; |
|
794 case EGray16: |
|
795 { |
|
796 TUint8* bufferPtr = (TUint8*)aBuffer; |
|
797 |
|
798 while (aLength > 1) |
|
799 { |
|
800 *bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray16()); |
|
801 aX += xInc; aY += yInc; |
|
802 *bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY)._Gray16() << 4); |
|
803 aX += xInc; aY += yInc; |
|
804 aLength -= 2; |
|
805 } |
|
806 if (aLength > 0) |
|
807 *bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray16()); |
|
808 } |
|
809 break; |
|
810 case EGray256: |
|
811 { |
|
812 TUint8* bufferPtr = (TUint8*)aBuffer; |
|
813 const TUint8* bufferPtrLimit = bufferPtr + aLength; |
|
814 |
|
815 while (bufferPtr < bufferPtrLimit) |
|
816 { |
|
817 *bufferPtr++ = TUint8(ReadRgbNormal(aX,aY)._Gray256()); |
|
818 aX += xInc; aY += yInc; |
|
819 } |
|
820 } |
|
821 break; |
|
822 case EColor16: |
|
823 { |
|
824 TUint8* bufferPtr = (TUint8*)aBuffer; |
|
825 |
|
826 while (aLength > 1) |
|
827 { |
|
828 *bufferPtr = TUint8(ReadRgbNormal(aX,aY).Color16()); |
|
829 aX += xInc; aY += yInc; |
|
830 *bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY).Color16() << 4); |
|
831 aX += xInc; aY += yInc; |
|
832 aLength -= 2; |
|
833 } |
|
834 if (aLength > 0) |
|
835 *bufferPtr = TUint8(ReadRgbNormal(aX,aY).Color16()); |
|
836 } |
|
837 break; |
|
838 case EColor256: |
|
839 { |
|
840 TUint8* bufferPtr = (TUint8*)aBuffer; |
|
841 const TUint8* bufferPtrLimit = bufferPtr + aLength; |
|
842 |
|
843 while (bufferPtr < bufferPtrLimit) |
|
844 { |
|
845 *bufferPtr++ = TUint8(ReadRgbNormal(aX,aY).Color256()); |
|
846 aX += xInc; aY += yInc; |
|
847 } |
|
848 } |
|
849 break; |
|
850 case EColor4K: |
|
851 { |
|
852 TUint16* bufferPtr = (TUint16*)aBuffer; |
|
853 const TUint16* bufferPtrLimit = bufferPtr + aLength; |
|
854 |
|
855 while (bufferPtr < bufferPtrLimit) |
|
856 { |
|
857 *bufferPtr++ = TUint16(ReadRgbNormal(aX,aY)._Color4K()); |
|
858 aX += xInc; aY += yInc; |
|
859 } |
|
860 } |
|
861 break; |
|
862 case EColor64K: |
|
863 { |
|
864 TUint16* bufferPtr = (TUint16*)aBuffer; |
|
865 const TUint16* bufferPtrLimit = bufferPtr + aLength; |
|
866 |
|
867 while (bufferPtr < bufferPtrLimit) |
|
868 { |
|
869 *bufferPtr++ = TUint16(ReadRgbNormal(aX,aY)._Color64K()); |
|
870 aX += xInc; aY += yInc; |
|
871 } |
|
872 } |
|
873 break; |
|
874 case EColor16M: |
|
875 { |
|
876 TUint8* bufferPtr = (TUint8*)aBuffer; |
|
877 const TUint8* bufferPtrLimit = bufferPtr + (aLength * 3); |
|
878 |
|
879 while (bufferPtr < bufferPtrLimit) |
|
880 { |
|
881 TUint32 pixelColorValue = ReadRgbNormal(aX,aY).Internal(); |
|
882 aX += xInc; aY += yInc; |
|
883 bufferPtr[0] = TUint8(pixelColorValue); |
|
884 bufferPtr[1] = TUint8(pixelColorValue >> 8); |
|
885 bufferPtr[2] = TUint8(pixelColorValue >> 16); |
|
886 bufferPtr += 3; |
|
887 } |
|
888 } |
|
889 break; |
|
890 case ERgb: |
|
891 { |
|
892 TRgb* bufferPtr = (TRgb*)aBuffer; |
|
893 const TRgb* bufferPtrLimit = bufferPtr + aLength; |
|
894 |
|
895 while (bufferPtr < bufferPtrLimit) |
|
896 { |
|
897 *bufferPtr++ = ReadRgbNormal(aX,aY); |
|
898 aX += xInc; aY += yInc; |
|
899 } |
|
900 } |
|
901 break; |
|
902 case EColor16MU: |
|
903 { |
|
904 TUint32* bufferPtr = (TUint32*)aBuffer; |
|
905 const TUint32* bufferPtrLimit = bufferPtr + aLength; |
|
906 |
|
907 while (bufferPtr < bufferPtrLimit) |
|
908 { |
|
909 *bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MU();//BGRA (Blue/Green/Red/Alpha) as little endian bite order |
|
910 aX += xInc; aY += yInc; |
|
911 } |
|
912 } |
|
913 break; |
|
914 case EColor16MA: |
|
915 { |
|
916 TUint32* bufferPtr = (TUint32*)aBuffer; |
|
917 const TUint32* bufferPtrLimit = bufferPtr + aLength; |
|
918 |
|
919 while (bufferPtr < bufferPtrLimit) |
|
920 { |
|
921 *bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MA();//BGRA (Blue/Green/Red/Alpha) as little endian bite order |
|
922 aX += xInc; aY += yInc; |
|
923 } |
|
924 } |
|
925 break; |
|
926 case EColor16MAP: |
|
927 { |
|
928 TUint32* bufferPtr = (TUint32*)aBuffer; |
|
929 const TUint32* bufferPtrLimit = bufferPtr + aLength; |
|
930 |
|
931 while (bufferPtr < bufferPtrLimit) |
|
932 { |
|
933 *bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MAP();; |
|
934 aX += xInc; aY += yInc; |
|
935 } |
|
936 } |
|
937 break; |
|
938 default: |
|
939 Panic(EScreenDriverPanicInvalidDisplayMode); |
|
940 } |
|
941 } |
|
942 |
|
943 //aX, aY - logical coordinates |
|
944 void CDrawBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode) |
|
945 { |
|
946 register TInt width = -1; |
|
947 register TInt height = -1; |
|
948 PreWriteRgb(width, height, aX, aY, aDrawMode); |
|
949 WriteRgb(width, height, aX, aY, aColor, aDrawMode); |
|
950 } |
|
951 |
|
952 //aX, aY - logical coordinates |
|
953 void CDrawBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight, |
|
954 TRgb aColor,CGraphicsContext::TDrawMode aDrawMode) |
|
955 { |
|
956 const TRect rect = DeOrientate(TRect(aX,aY,aX + aLength,aY + aHeight));//rect - physical coordinates |
|
957 aX = rect.iTl.iX; |
|
958 aY = rect.iTl.iY; |
|
959 aLength = rect.Width(); |
|
960 aHeight = rect.Height(); |
|
961 |
|
962 __ASSERT_DEBUG(aX>=0 && aX+aLength<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds)); |
|
963 __ASSERT_DEBUG(aY>=0 && aY+aHeight<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds)); |
|
964 |
|
965 MapColorToUserDisplayMode(aColor); |
|
966 if(iShadowMode) |
|
967 { |
|
968 Shadow(aColor); |
|
969 } |
|
970 if(aDrawMode&CGraphicsContext::EInvertPen) |
|
971 { |
|
972 aColor=~aColor; |
|
973 } |
|
974 if(aDrawMode&CGraphicsContext::EPenmode) |
|
975 { |
|
976 BlendRgbMulti(aX,aY,aLength,aHeight,aColor); |
|
977 return; |
|
978 } |
|
979 if(aDrawMode&CGraphicsContext::EWriteAlpha) |
|
980 { |
|
981 WriteRgbMulti(aX,aY,aLength,aHeight,aColor); |
|
982 return; |
|
983 } |
|
984 if(aDrawMode&CGraphicsContext::EInvertScreen) |
|
985 { |
|
986 WriteRgbMultiXOR(aX,aY,aLength,aHeight,KRgbWhite); |
|
987 } |
|
988 if(aDrawMode&CGraphicsContext::EXor) |
|
989 { |
|
990 WriteRgbMultiXOR(aX,aY,aLength,aHeight,aColor); |
|
991 } |
|
992 else if(aDrawMode&CGraphicsContext::EAnd) |
|
993 { |
|
994 WriteRgbMultiAND(aX,aY,aLength,aHeight,aColor); |
|
995 } |
|
996 else if(aDrawMode&CGraphicsContext::EOr) |
|
997 { |
|
998 WriteRgbMultiOR(aX,aY,aLength,aHeight,aColor); |
|
999 } |
|
1000 } |
|
1001 |
|
1002 //aX, aY - logical coordinates |
|
1003 void CDrawBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength, |
|
1004 TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode) |
|
1005 { |
|
1006 TRect drawRect; |
|
1007 GetDrawRect(drawRect); |
|
1008 __ASSERT_DEBUG(aX >= drawRect.iTl.iX && (aX + aLength) <= drawRect.iBr.iX, Panic(EScreenDriverPanicOutOfBounds)); |
|
1009 __ASSERT_DEBUG(aY >= drawRect.iTl.iY && (aY + aHeight) <= drawRect.iBr.iY, Panic(EScreenDriverPanicOutOfBounds)); |
|
1010 __ASSERT_DEBUG(aBuffer, Panic(EScreenDriverPanicNullPointer)); |
|
1011 __ASSERT_DEBUG(aLength > 0, Panic(EScreenDriverPanicZeroLength)); |
|
1012 __ASSERT_DEBUG(aLength <= 32, Panic(EScreenDriverPanicOutOfBounds)); |
|
1013 |
|
1014 MapColorToUserDisplayMode(aColor); |
|
1015 if(iShadowMode) |
|
1016 Shadow(aColor); |
|
1017 if(aDrawMode&CGraphicsContext::EInvertPen) |
|
1018 aColor=~aColor; |
|
1019 if(aDrawMode&CGraphicsContext::EPenmode) |
|
1020 { |
|
1021 WriteBinary(aX,aY,aBuffer,aLength,aHeight,aColor); |
|
1022 return; |
|
1023 } |
|
1024 if(aDrawMode&CGraphicsContext::EInvertScreen) |
|
1025 WriteBinaryOp(aX,aY,aBuffer,aLength,aHeight,KRgbWhite,CGraphicsContext::EDrawModeXOR); |
|
1026 if(aDrawMode&CGraphicsContext::ELogicalOp) |
|
1027 WriteBinaryOp(aX,aY,aBuffer,aLength,aHeight,aColor,(CGraphicsContext::TDrawMode)(aDrawMode&CGraphicsContext::ELogicalOp)); |
|
1028 } |
|
1029 |
|
1030 //aX, aY - logical coordinates |
|
1031 void CDrawBitmap::WriteBinaryLine(TInt aX,TInt aY,TUint32* aBuffer, |
|
1032 TInt aLength,TRgb aColor, |
|
1033 CGraphicsContext::TDrawMode aDrawMode) |
|
1034 { |
|
1035 MapColorToUserDisplayMode(aColor); |
|
1036 while(aLength>32) |
|
1037 { |
|
1038 WriteBinary(aX,aY,aBuffer,32,1,aColor,aDrawMode); |
|
1039 aX+=32; |
|
1040 aBuffer++; |
|
1041 aLength-=32; |
|
1042 } |
|
1043 WriteBinary(aX,aY,aBuffer,aLength,1,aColor,aDrawMode); |
|
1044 } |
|
1045 |
|
1046 //aX, aY - logical coordinates |
|
1047 void CDrawBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aBuffer, |
|
1048 TInt aHeight,TRgb aColor, |
|
1049 CGraphicsContext::TDrawMode aDrawMode,TBool aUp) |
|
1050 { |
|
1051 TRect drawRect; |
|
1052 GetDrawRect(drawRect); |
|
1053 __ASSERT_DEBUG(aX >= drawRect.iTl.iX && aX < drawRect.iBr.iX, Panic(EScreenDriverPanicOutOfBounds)); |
|
1054 __ASSERT_DEBUG(aY >= drawRect.iTl.iY, Panic(EScreenDriverPanicOutOfBounds)); |
|
1055 __ASSERT_DEBUG(aUp || (aY + aHeight) <= drawRect.iBr.iY, Panic(EScreenDriverPanicOutOfBounds)); |
|
1056 __ASSERT_DEBUG(!aUp || (aY - aHeight + 1) >= drawRect.iTl.iY, Panic(EScreenDriverPanicOutOfBounds)); |
|
1057 __ASSERT_DEBUG(aBuffer, Panic(EScreenDriverPanicNullPointer)); |
|
1058 __ASSERT_DEBUG(aHeight > 0, Panic(EScreenDriverPanicZeroLength)); |
|
1059 |
|
1060 MapColorToUserDisplayMode(aColor); |
|
1061 if((aDrawMode & CGraphicsContext::EPenmode) && iScalingOff) |
|
1062 { |
|
1063 if(iShadowMode) |
|
1064 Shadow(aColor); |
|
1065 if(aDrawMode&CGraphicsContext::EInvertPen) |
|
1066 aColor=~aColor; |
|
1067 WriteBinaryLineVertical(aX,aY,aBuffer,aHeight,aColor,aUp); |
|
1068 return; |
|
1069 } |
|
1070 |
|
1071 TUint32 mask = 1; |
|
1072 TUint32 data = *aBuffer++; |
|
1073 TInt endrow = aY + (aUp ? -aHeight : aHeight); |
|
1074 TInt rowInc = aUp ? -1 : 1; |
|
1075 |
|
1076 while (aY != endrow) |
|
1077 { |
|
1078 if (!mask) |
|
1079 { |
|
1080 data = *aBuffer++; |
|
1081 mask = 1; |
|
1082 } |
|
1083 |
|
1084 if (data & mask) |
|
1085 { |
|
1086 WriteRgb(aX, aY, aColor, aDrawMode); |
|
1087 } |
|
1088 |
|
1089 aY += rowInc; |
|
1090 mask <<= 1; |
|
1091 } |
|
1092 } |
|
1093 |
|
1094 //aX, aY - logical coordinates |
|
1095 void CDrawBitmap::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer, |
|
1096 CGraphicsContext::TDrawMode aDrawMode) |
|
1097 { |
|
1098 const TPoint originalPoint(aX,aY); |
|
1099 DeOrientate(aX,aY);//aX and aY - physical coordinates |
|
1100 |
|
1101 __ASSERT_DEBUG(aX >= 0,Panic(EScreenDriverPanicOutOfBounds)); |
|
1102 __ASSERT_DEBUG(aY >= 0,Panic(EScreenDriverPanicOutOfBounds)); |
|
1103 #if defined(_DEBUG) |
|
1104 switch (iOrientation) |
|
1105 { |
|
1106 case EOrientationNormal: |
|
1107 __ASSERT_DEBUG(aX + aLength <= iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds)); |
|
1108 break; |
|
1109 case EOrientationRotated90: |
|
1110 __ASSERT_DEBUG(aY + aLength <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds)); |
|
1111 break; |
|
1112 case EOrientationRotated180: |
|
1113 __ASSERT_DEBUG(aX - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds)); |
|
1114 break; |
|
1115 default: // EOrientationRotated270 |
|
1116 __ASSERT_DEBUG(aY - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds)); |
|
1117 break; |
|
1118 } |
|
1119 #endif |
|
1120 __ASSERT_DEBUG(aLength > 0,Panic(EScreenDriverPanicZeroLength)); |
|
1121 __ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer)); |
|
1122 |
|
1123 MapBufferToUserDisplayMode(aLength,aBuffer); |
|
1124 if(iShadowMode) |
|
1125 { |
|
1126 ShadowBuffer(aLength,aBuffer); |
|
1127 } |
|
1128 if(aDrawMode&CGraphicsContext::EInvertPen) |
|
1129 { |
|
1130 InvertBuffer(aLength,aBuffer); |
|
1131 } |
|
1132 if(aDrawMode&CGraphicsContext::EPenmode) |
|
1133 { |
|
1134 BlendLine(aX,aY,aLength,aBuffer); |
|
1135 return; |
|
1136 } |
|
1137 if(aDrawMode&CGraphicsContext::EWriteAlpha) |
|
1138 { |
|
1139 WriteLine(aX,aY,aLength,aBuffer); |
|
1140 return; |
|
1141 } |
|
1142 if(aDrawMode&CGraphicsContext::EInvertScreen) |
|
1143 { |
|
1144 const TRect rect = DeOrientate(TRect(originalPoint,TSize(aLength,1)));//"rect" - deorientated and scaled |
|
1145 WriteRgbMultiXOR(rect.iTl.iX,rect.iTl.iY,rect.Width(),rect.Height(),KRgbWhite); |
|
1146 } |
|
1147 if(aDrawMode&CGraphicsContext::EXor) |
|
1148 { |
|
1149 WriteLineXOR(aX,aY,aLength,aBuffer); |
|
1150 } |
|
1151 else if(aDrawMode&CGraphicsContext::EAnd) |
|
1152 { |
|
1153 WriteLineAND(aX,aY,aLength,aBuffer); |
|
1154 } |
|
1155 else if(aDrawMode&CGraphicsContext::EOr) |
|
1156 { |
|
1157 WriteLineOR(aX,aY,aLength,aBuffer); |
|
1158 } |
|
1159 } |
|
1160 |
|
1161 TAny* CDrawBitmap::CopyOffset(TAny* aDestination,const TAny* aSource,TInt aWordsToCopy,TInt aSourceBitOffset) |
|
1162 { |
|
1163 ASSERT(aSourceBitOffset > 0 && aSourceBitOffset < 32); |
|
1164 |
|
1165 const TUint32* srcPtr = REINTERPRET_CAST(const TUint32*,aSource); |
|
1166 TUint32* destPtr = REINTERPRET_CAST(TUint32*,aDestination); |
|
1167 const TUint32* destPtrLimit = destPtr + aWordsToCopy; |
|
1168 const TInt sourceBitOffsetComplement = 32 - aSourceBitOffset; |
|
1169 |
|
1170 TUint32 sourceValue = *srcPtr++; |
|
1171 |
|
1172 while (destPtr < destPtrLimit) |
|
1173 { |
|
1174 TUint32 destValue = sourceValue >> aSourceBitOffset; |
|
1175 sourceValue = *srcPtr++; |
|
1176 destValue |= sourceValue << sourceBitOffsetComplement; |
|
1177 *destPtr++ = destValue; |
|
1178 } |
|
1179 return destPtr; |
|
1180 } |
|
1181 /** Common code to read a line of pixels where there are >1 pixels per byte. |
|
1182 The source words must be shifted to fit the target buffer. |
|
1183 @param aPixelPtr Source location to start copying from (word aligned, last word is safe) |
|
1184 @param aBufferPtr Target location to write to (word aligned - may or may not own all last word) |
|
1185 @param aWordsCnt Number of source words that can be safely copied |
|
1186 @param aRestPixels Number of pixels that must be read from the next word for the final byte copy |
|
1187 @param aBytesCount Number of bytes to write from final input word |
|
1188 @param aShiftBits Number of bits shifted between input and output words. |
|
1189 **/ |
|
1190 void CDrawBitmap::ReadLineCommon(TUint32* aPixelPtr,TUint32* aBufferPtr,TInt aWordsCount,TInt aRestPixels,TInt aBytesCount,TInt aShiftBits) |
|
1191 { |
|
1192 // As many pixels as possible are copied by shifting whole words. |
|
1193 // This involves reading two source words, shifting them, |
|
1194 // and merging the result to one target word. |
|
1195 // However, two cases mean the last few pixels need to be treated carefully: |
|
1196 // 1) The target buffer may be a number of bytes, not whole words. |
|
1197 // The number of pixels to copy defines the number of bytes to copy. |
|
1198 // 2) The number of pixels to read may mean the last read does not need |
|
1199 // to read a second word in order to satisfy the number of pixels requested. |
|
1200 // This next word may not be mapped, so must not be read! |
|
1201 |
|
1202 //Are we willing to pay for these asserts for every scanline copy, even in debug? |
|
1203 __ASSERT_DEBUG(aPixelPtr, User::Invariant()); |
|
1204 __ASSERT_DEBUG(aBufferPtr, User::Invariant()); |
|
1205 __ASSERT_DEBUG(aWordsCount>=0, User::Invariant()); |
|
1206 __ASSERT_DEBUG(aBytesCount<5, User::Invariant()); |
|
1207 __ASSERT_DEBUG(aShiftBits>=0 && aShiftBits<33, User::Invariant()); |
|
1208 |
|
1209 TUint32 nextpixel; |
|
1210 if(aWordsCount>0) |
|
1211 { |
|
1212 if (aShiftBits==0) |
|
1213 { |
|
1214 while (aWordsCount--) |
|
1215 { |
|
1216 *aBufferPtr++ = *aPixelPtr++; |
|
1217 } |
|
1218 if (aBytesCount>0) //I hope the optimiser can concatenate these two tests? |
|
1219 { |
|
1220 nextpixel=aPixelPtr[0]; |
|
1221 } |
|
1222 } |
|
1223 else |
|
1224 { |
|
1225 const TInt shiftBitsExtra = 32 - aShiftBits; |
|
1226 nextpixel=aPixelPtr[0]; |
|
1227 while (aWordsCount--) |
|
1228 { |
|
1229 TUint32 prevpixel=nextpixel; |
|
1230 nextpixel=aPixelPtr[1]; //this must not read forward when it doesn't need to |
|
1231 aBufferPtr[0] = (prevpixel >> aShiftBits) | (nextpixel << shiftBitsExtra); |
|
1232 |
|
1233 aPixelPtr++; |
|
1234 aBufferPtr++; |
|
1235 } |
|
1236 } |
|
1237 } |
|
1238 else |
|
1239 { |
|
1240 nextpixel=aPixelPtr[0]; |
|
1241 } |
|
1242 |
|
1243 //deal with the trailing bytes |
|
1244 if (aBytesCount>0) |
|
1245 { |
|
1246 if (aBytesCount==4) |
|
1247 { |
|
1248 //The client only requests 4 bytes rather than 1 more word when the requested pixels |
|
1249 //mean the second word should not be read from. |
|
1250 //Can also write the result in a single operation! |
|
1251 aBufferPtr[0]=nextpixel>> aShiftBits; |
|
1252 } |
|
1253 else |
|
1254 { |
|
1255 if (aRestPixels>0) |
|
1256 { |
|
1257 //do need to read from next word to fill all the requested pixels. |
|
1258 aWordsCount=(nextpixel >> aShiftBits) | (aPixelPtr[1] << (32 - aShiftBits)); |
|
1259 } |
|
1260 else |
|
1261 { |
|
1262 //Don't read second word, otherwise might read past end of picture data! |
|
1263 aWordsCount=(nextpixel >> aShiftBits); |
|
1264 } |
|
1265 TUint8* bufferPtrChar=reinterpret_cast <TUint8*> (aBufferPtr); |
|
1266 |
|
1267 //max 3 bytes to store |
|
1268 if (aBytesCount&2) |
|
1269 { |
|
1270 bufferPtrChar[0]=aWordsCount; |
|
1271 bufferPtrChar[1]=aWordsCount>>8; |
|
1272 bufferPtrChar+=2; |
|
1273 aWordsCount>>=16; |
|
1274 } |
|
1275 if (aBytesCount&1) |
|
1276 { |
|
1277 bufferPtrChar[0]=aWordsCount; |
|
1278 } |
|
1279 } |
|
1280 } |
|
1281 } |
|
1282 |
|
1283 /** |
|
1284 The method performs an alpha blending of the source data - aRgbBuffer and screen pixels, using |
|
1285 the data from aMaskBuffer buffer as an alpha blending factor. |
|
1286 If the shadowing/fading flag is set, a shadow/fade copy of the source bitmap will be used. |
|
1287 The formula used for that, is: |
|
1288 (C1 * A + C2 * (255 - A)) / 255, where: |
|
1289 - C1 - a pixel from aRgbBuffer; |
|
1290 - C2 - a pixel from the sceen; |
|
1291 - A - a pixel from aMaskBuffer; |
|
1292 The content of source and mask buffers is preserved. |
|
1293 The calculated alpha blended pixel is written to the destination - the screen or a bitmap. |
|
1294 @param aX Logical X coordinate of the position in the target the result should be drawn to. |
|
1295 @param aY Logical Y coordinate of the position in the target the result should be drawn to. |
|
1296 @param aLength Source data - length in pixels. |
|
1297 @param aRgbBuffer A pointer to a line of the source bitmap data. |
|
1298 @param aMaskBuffer Buffer containing the data which should be used as an |
|
1299 alpha blending factor. |
|
1300 */ |
|
1301 void CDrawBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength, |
|
1302 TUint8* aRgbBuffer, TUint8* aMaskBuffer, |
|
1303 CGraphicsContext::TDrawMode aDrawMode) |
|
1304 { |
|
1305 iAlphaBlend->WriteRgbAlphaLine(aX, aY, aLength, aRgbBuffer, aMaskBuffer, |
|
1306 MAlphaBlend::EShdwBefore, |
|
1307 aDrawMode); |
|
1308 } |
|
1309 |
|
1310 /** |
|
1311 The method performs an alpha blending of the source data - aRgbBuffer1 and aBuffer2, using |
|
1312 the data from aMaskBuffer buffer as an alpha blending factor. |
|
1313 If the shadowing/fading flag is set, the resulting pixels will be shadowed/faded. |
|
1314 The formula used for that, is: |
|
1315 (C1 * A + C2 * (255 - A)) / 255, where: |
|
1316 - C1 - a pixel from aRgbBuffer1; |
|
1317 - C2 - a pixel from aBuffer2; |
|
1318 - A - a pixel from aMaskBuffer; |
|
1319 The content of source and mask buffers is preserved. |
|
1320 The calculated alpha blended pixel is written to the destination - the screen or a bitmap. |
|
1321 @param aX Logical X coordinate of the position in the target the result should be drawn to. |
|
1322 @param aY Logical Y coordinate of the position in the target the result should be drawn to. |
|
1323 @param aLength Source data - length in pixels. |
|
1324 @param aRgbBuffer1 A pointer to a line of the source bitmap data 1. |
|
1325 @param aBuffer2 A pointer to a line of the source bitmap data 2. |
|
1326 Source bitmap data 2 should be mapped to current display mode |
|
1327 before the method call. |
|
1328 @param aMaskBuffer Buffer containing the data which should be used as an |
|
1329 alpha blending factor. |
|
1330 @param aDrawMode Drawing mode |
|
1331 */ |
|
1332 void CDrawBitmap::WriteRgbAlphaLine(TInt aX,TInt aY,TInt aLength, |
|
1333 const TUint8* aRgbBuffer1, |
|
1334 const TUint8* aBuffer2, |
|
1335 const TUint8* aMaskBuffer, |
|
1336 CGraphicsContext::TDrawMode aDrawMode) |
|
1337 { |
|
1338 // Save current shadow mode |
|
1339 TShadowMode temp_mode = iShadowMode; |
|
1340 iShadowMode = ENoShadow; |
|
1341 // copy the source data 2 to the screen/bitmap target buffer |
|
1342 WriteLine(aX, aY, aLength, (TUint32*)aBuffer2, aDrawMode); |
|
1343 // restore current shadow mode |
|
1344 iShadowMode = temp_mode; |
|
1345 // DrawModePen is the only supported operation for blending masks. |
|
1346 iAlphaBlend->WriteRgbAlphaLine(aX, aY, aLength, aRgbBuffer1, aMaskBuffer, |
|
1347 MAlphaBlend::EShdwAfter, CGraphicsContext::EDrawModePEN); |
|
1348 } |
|
1349 |
|
1350 //Initializes iSize and iDrawRect data members. |
|
1351 //It should be called every time when iSize is going to be changed - Construct() implementations |
|
1352 //in derived classes. |
|
1353 //The method does not use iOrientation data member. |
|
1354 //@param aSize Physical screen size in pixels. |
|
1355 //@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the |
|
1356 //device is scaled and the scaling origin goes outside physical drawing rectangle. |
|
1357 void CDrawBitmap::SetSize(const TSize& aSize) |
|
1358 { |
|
1359 iSize = aSize; |
|
1360 InitLogicalCoordinates(); |
|
1361 } |
|
1362 |
|
1363 /** |
|
1364 The method swaps bitmap device's width and height. |
|
1365 For example: if the size is (40, 20), the swapped size will be (20, 40). |
|
1366 The device's content is not preserved. |
|
1367 The method leaves CDrawBitmap object in a consistent state - |
|
1368 scaling settings will be set with their default values (the scaling is switched off), |
|
1369 iDitherOrigin will be set to (0,0), iOrigin to (0,0). |
|
1370 |
|
1371 Note: This method is used internally by BITGDI component. Do not call it! |
|
1372 */ |
|
1373 void CDrawBitmap::SwapWidthAndHeight() |
|
1374 { |
|
1375 SetDefaults(); |
|
1376 //Swap width and height |
|
1377 TSize swappedSize(iSize.iHeight, iSize.iWidth); |
|
1378 //Initialize iSize, iScanLineWords, iLongWidth data members. |
|
1379 SetSize(swappedSize); |
|
1380 } |
|
1381 |
|
1382 //This method initializes some of the data members. |
|
1383 //Espetially it switches scaling off, sets iDitherOrigin to (0,0), |
|
1384 //iOrigin to (0,0), iDrawRect to (0,0,0,0). iSize value is preserved. |
|
1385 //Do not forget to update it if adding new data members! |
|
1386 void CDrawBitmap::SetDefaults() |
|
1387 { |
|
1388 iLongWidth = 0; |
|
1389 iDitherOrigin.SetXY(0, 0); |
|
1390 iFadeMapFactor = 128; |
|
1391 iFadeMapOffset = 128; |
|
1392 iScalingSettings = TScalingSettings(); |
|
1393 iOrigin.SetXY(0, 0); |
|
1394 iScalingOff = ETrue; |
|
1395 iOriginIsZero = ETrue; |
|
1396 iDrawRect.SetRect(0, 0, 0, 0); |
|
1397 } |
|
1398 |
|
1399 /** |
|
1400 Implementation for CFbsDrawDevice::GetInterface(). |
|
1401 Retrieves a pointer to a specified interface of CFbsDrawDevice implementation. |
|
1402 @param aInterfaceId Interface identifier of the interface to be retrieved. |
|
1403 @param aInterface Address of variable that retrieves the specified interface. |
|
1404 @return KErrNone If the interface is supported, KErrNotSupported otherwise. |
|
1405 */ |
|
1406 TInt CDrawBitmap::GetInterface(TInt aInterfaceId, TAny*& aInterface) |
|
1407 { |
|
1408 aInterface = NULL; |
|
1409 TInt err = KErrNotSupported; |
|
1410 |
|
1411 switch (aInterfaceId) |
|
1412 { |
|
1413 case KScalingSettingsInterfaceID: |
|
1414 { |
|
1415 if(CanBeScaled()) |
|
1416 { |
|
1417 aInterface = static_cast <MScalingSettings*> (this); |
|
1418 err = KErrNone; |
|
1419 } |
|
1420 break; |
|
1421 } |
|
1422 case KDrawDeviceOriginInterfaceID: |
|
1423 { |
|
1424 if(CanOriginBeMoved()) |
|
1425 { |
|
1426 aInterface = static_cast <MDrawDeviceOrigin*> (this); |
|
1427 err = KErrNone; |
|
1428 } |
|
1429 break; |
|
1430 } |
|
1431 case KAlphaBlendInterfaceID: |
|
1432 { |
|
1433 aInterface = static_cast <MAlphaBlend*> (this); |
|
1434 err = KErrNone; |
|
1435 break; |
|
1436 } |
|
1437 case KOrientationInterfaceID: |
|
1438 { |
|
1439 aInterface = static_cast <MDrawDeviceOrientation*> (this); |
|
1440 err = KErrNone; |
|
1441 break; |
|
1442 } |
|
1443 case KOutlineAndShadowInterfaceID: |
|
1444 { |
|
1445 aInterface = static_cast <MOutlineAndShadowBlend*> (this); |
|
1446 err = KErrNone; |
|
1447 break; |
|
1448 } |
|
1449 case KFastBlendInterfaceID: |
|
1450 { |
|
1451 aInterface = static_cast <MFastBlend*> (this); |
|
1452 err = KErrNone; |
|
1453 break; |
|
1454 } |
|
1455 } |
|
1456 |
|
1457 return err; |
|
1458 } |
|
1459 |
|
1460 void CDrawBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor) |
|
1461 { |
|
1462 WriteRgbMulti(aX,aY,aLength,aHeight,aColor); |
|
1463 } |
|
1464 |
|
1465 void CDrawBitmap::BlendLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) |
|
1466 { |
|
1467 WriteLine(aX, aY,aLength, aBuffer); |
|
1468 } |
|
1469 |
|
1470 /** |
|
1471 Convert a RGB pixel into the color associated to the user display mode. |
|
1472 @param aRed red color |
|
1473 @param aGreen green color |
|
1474 @param aBlue blue color |
|
1475 @internalComponent |
|
1476 */ |
|
1477 void CDrawBitmap::MapColorToUserDisplayMode(TInt& aRed,TInt& aGreen,TInt& aBlue) |
|
1478 { |
|
1479 TUint32 tmpValue; |
|
1480 |
|
1481 switch (iUserDispMode) |
|
1482 { |
|
1483 case EGray2: |
|
1484 tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 10; |
|
1485 if (tmpValue) { aRed = 0xff; aBlue = 0xff; aGreen = 0xff; } |
|
1486 else { aRed = 0x00; aBlue = 0x00; aGreen = 0x00; } |
|
1487 break; |
|
1488 case EGray4: |
|
1489 tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 9; |
|
1490 tmpValue = tmpValue | (tmpValue << 2) | (tmpValue << 4) | (tmpValue << 6); |
|
1491 aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue; |
|
1492 break; |
|
1493 case EGray16: |
|
1494 tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 7; |
|
1495 tmpValue = tmpValue | (tmpValue << 4); |
|
1496 aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue; |
|
1497 break; |
|
1498 case EGray256: |
|
1499 tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 3; |
|
1500 aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue; |
|
1501 break; |
|
1502 case EColor16: |
|
1503 { |
|
1504 TRgb aColor(aRed,aGreen,aBlue); |
|
1505 aColor = TRgb::Color16(aColor.Color16()); |
|
1506 aRed = aColor.Red(); aGreen = aColor.Green(); aBlue = aColor.Blue(); |
|
1507 break; |
|
1508 } |
|
1509 case EColor256: |
|
1510 { |
|
1511 TRgb aColor2(aRed,aGreen,aBlue); |
|
1512 aColor2 = TRgb::Color256(aColor2.Color256()); |
|
1513 aRed = aColor2.Red(); aGreen = aColor2.Green(); aBlue = aColor2.Blue(); |
|
1514 break; |
|
1515 } |
|
1516 case EColor4K: |
|
1517 aBlue = aBlue & 0xf0; aBlue |= (aBlue >> 4); |
|
1518 aGreen = aGreen & 0xf0; aGreen |= (aGreen >> 4); |
|
1519 aRed = aRed & 0xf0; aRed |= (aRed >> 4); |
|
1520 break; |
|
1521 case EColor64K: |
|
1522 aBlue = aBlue & 0xf8; aBlue += (aBlue >> 5); |
|
1523 aGreen = aGreen & 0xfc; aGreen += (aGreen >> 6); |
|
1524 aRed = aRed & 0xf8; aRed += (aRed >> 5); |
|
1525 break; |
|
1526 default: |
|
1527 break; |
|
1528 } |
|
1529 } |
|
1530 |
|
1531 /** |
|
1532 CDrawBitmap::Orientation() implementation. |
|
1533 @internalTechnology |
|
1534 @see MDrawDeviceOrientation::Orientation() |
|
1535 */ |
|
1536 CFbsDrawDevice::TOrientation CDrawBitmap::Orientation() |
|
1537 { |
|
1538 return iOrientation; |
|
1539 } |
|
1540 |
|
1541 #ifdef __ARMCC__ |
|
1542 #ifndef __MARM_THUMB__ |
|
1543 #define USE_SCREENDRIVER_ARM_ASM |
|
1544 #endif //__MARM_THUMB__ |
|
1545 #endif //__ARMCC__ |
|
1546 |
|
1547 #ifdef USE_SCREENDRIVER_ARM_ASM |
|
1548 /** |
|
1549 MemFill - using an unrolled loop to perform the following: |
|
1550 for (TUint32* tempWordPtr = wordPtr; tempWordPtr < wordPtrLimit; tempWordPtr++) |
|
1551 { |
|
1552 *tempWordPtr = colorWord; |
|
1553 } |
|
1554 */ |
|
1555 __asm void MemFillTUint32(TUint32* /*aTrg*/, TInt /*aLength*/, const TUint32 /*aValue*/) |
|
1556 { |
|
1557 //r0 - aTrg, r1 - aLength, r2 - aValue |
|
1558 push {r1,r3,lr} |
|
1559 and r3,r1,#7 |
|
1560 cmp r3,#7 |
|
1561 addls pc,pc,r3,LSL #2 |
|
1562 b mf_switch0 |
|
1563 b mf_switch0 |
|
1564 b mf_switch1 |
|
1565 b mf_switch2 |
|
1566 b mf_switch3 |
|
1567 b mf_switch4 |
|
1568 b mf_switch5 |
|
1569 b mf_switch6 |
|
1570 b mf_switch7 |
|
1571 mf_switch7 |
|
1572 str r2,[r0],#4 |
|
1573 mf_switch6 |
|
1574 str r2,[r0],#4 |
|
1575 mf_switch5 |
|
1576 str r2,[r0],#4 |
|
1577 mf_switch4 |
|
1578 str r2,[r0],#4 |
|
1579 mf_switch3 |
|
1580 str r2,[r0],#4 |
|
1581 mf_switch2 |
|
1582 str r2,[r0],#4 |
|
1583 mf_switch1 |
|
1584 str r2,[r0],#4 |
|
1585 mf_switch0 |
|
1586 |
|
1587 asr r1,r1,#3 |
|
1588 cmp r1,#0 |
|
1589 beq mf_complete |
|
1590 |
|
1591 push {r0,r2,r4-r8} |
|
1592 mov r3,r2 |
|
1593 mov r4,r2 |
|
1594 mov r5,r2 |
|
1595 mov r6,r2 |
|
1596 mov r7,r2 |
|
1597 mov r8,r2 |
|
1598 mov lr,r2 |
|
1599 |
|
1600 mf_more |
|
1601 stmia r0!,{r2-r8,lr} |
|
1602 subs r1,r1,#1 |
|
1603 bgt mf_more |
|
1604 pop {r0,r2,r4-r8} |
|
1605 |
|
1606 mf_complete |
|
1607 pop {r1,r3,pc} |
|
1608 } |
|
1609 |
|
1610 #else //USE_SCREENDRIVER_ARM_ASM |
|
1611 |
|
1612 const TInt KDevideByEightShift = 3; |
|
1613 const TInt KModulusByEightFlag = 7; |
|
1614 |
|
1615 void MemFillTUint32(TUint32* tempWordPtr, TInt aCount, const TUint32 aValue) |
|
1616 { |
|
1617 TInt remainder = aCount & KModulusByEightFlag; |
|
1618 switch (remainder) |
|
1619 { |
|
1620 case 7: |
|
1621 *tempWordPtr++ = aValue; |
|
1622 case 6: |
|
1623 *tempWordPtr++ = aValue; |
|
1624 case 5: |
|
1625 *tempWordPtr++ = aValue; |
|
1626 case 4: |
|
1627 *tempWordPtr++ = aValue; |
|
1628 case 3: |
|
1629 *tempWordPtr++ = aValue; |
|
1630 case 2: |
|
1631 *tempWordPtr++ = aValue; |
|
1632 case 1: |
|
1633 *tempWordPtr++ = aValue; |
|
1634 } |
|
1635 register TUint32 value0 = aValue; |
|
1636 register TUint32 value1 = aValue; |
|
1637 register TUint32 value2 = aValue; |
|
1638 for(TInt times = (aCount >> KDevideByEightShift); times > 0; --times) |
|
1639 { |
|
1640 *tempWordPtr++ = value0; |
|
1641 *tempWordPtr++ = value1; |
|
1642 *tempWordPtr++ = value2; |
|
1643 *tempWordPtr++ = aValue; |
|
1644 *tempWordPtr++ = value0; |
|
1645 *tempWordPtr++ = value1; |
|
1646 *tempWordPtr++ = value2; |
|
1647 *tempWordPtr++ = aValue; |
|
1648 } |
|
1649 } |
|
1650 |
|
1651 #endif //USE_SCREENDRIVER_ARM_ASM |
|
1652 |