|
1 /******************************************************************************* |
|
2 * Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. This program and the accompanying materials |
|
4 * are made available under the terms of the Eclipse Public License v1.0 |
|
5 * which accompanies this distribution, and is available at |
|
6 * http://www.eclipse.org/legal/epl-v10.html |
|
7 * |
|
8 * Contributors: |
|
9 * Nokia Corporation - S60 implementation |
|
10 *******************************************************************************/ |
|
11 |
|
12 |
|
13 #include "swtimage.h" |
|
14 #include "swtgrimagedata.h" |
|
15 #include "swtgrpalettedata.h" |
|
16 #include "swtcontrolhelper.h" |
|
17 #include "swtdisplay.h" // needed for macro definitions |
|
18 |
|
19 |
|
20 // Look-up table for the bit-reversed value of a byte. |
|
21 static const TUint8 KBitReverseTable[256] = |
|
22 { |
|
23 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, |
|
24 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, |
|
25 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, |
|
26 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, |
|
27 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, |
|
28 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, |
|
29 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, |
|
30 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, |
|
31 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, |
|
32 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, |
|
33 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, |
|
34 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, |
|
35 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, |
|
36 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, |
|
37 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, |
|
38 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, |
|
39 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, |
|
40 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, |
|
41 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, |
|
42 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, |
|
43 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, |
|
44 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, |
|
45 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, |
|
46 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, |
|
47 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, |
|
48 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, |
|
49 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, |
|
50 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, |
|
51 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, |
|
52 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, |
|
53 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, |
|
54 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff |
|
55 }; |
|
56 |
|
57 |
|
58 // ======== MEMBER FUNCTIONS ======== |
|
59 |
|
60 |
|
61 // --------------------------------------------------------------------------- |
|
62 // CSwtImage::NewL |
|
63 // --------------------------------------------------------------------------- |
|
64 // |
|
65 CSwtImage* CSwtImage::NewL(MSwtDevice& aDevice, const TSize& aSize, |
|
66 MSwtDisplay& aDisplay, TDisplayMode aMode /*=ENone*/) |
|
67 { |
|
68 CSwtImage* self = new(ELeave) CSwtImage(&aDevice, &aDisplay); |
|
69 CleanupStack::PushL(self); |
|
70 self->ConstructL(aSize, aMode); |
|
71 CleanupStack::Pop(self); |
|
72 return self; |
|
73 } |
|
74 |
|
75 // --------------------------------------------------------------------------- |
|
76 // CSwtImage::NewL |
|
77 // --------------------------------------------------------------------------- |
|
78 // |
|
79 CSwtImage* CSwtImage::NewL(MSwtDevice* aDevice, const MSwtImageData& aData, |
|
80 MSwtDisplay* aDisplay) |
|
81 { |
|
82 CSwtImage* self = new(ELeave) CSwtImage(aDevice, aDisplay); |
|
83 CleanupStack::PushL(self); |
|
84 self->ConstructL(aData); |
|
85 CleanupStack::Pop(self); |
|
86 return self; |
|
87 } |
|
88 |
|
89 // --------------------------------------------------------------------------- |
|
90 // CSwtImage::NewL |
|
91 // --------------------------------------------------------------------------- |
|
92 // |
|
93 CSwtImage* CSwtImage::NewL(CFbsBitmap& aBitmap, CFbsBitmap* aMask, |
|
94 const TPoint& aTopLeft, TInt aDelayTime, TSwtGifDisposal aDisposalMethod) |
|
95 { |
|
96 CSwtImage* self = new(ELeave) CSwtImage(NULL, NULL); |
|
97 CleanupStack::PushL(self); |
|
98 self->ConstructL(aBitmap, aMask, aTopLeft, aDelayTime, aDisposalMethod, ETrue); |
|
99 CleanupStack::Pop(self); |
|
100 return self; |
|
101 } |
|
102 |
|
103 // --------------------------------------------------------------------------- |
|
104 // CSwtImage::NewL |
|
105 // --------------------------------------------------------------------------- |
|
106 // |
|
107 CSwtImage* CSwtImage::NewL(CFbsBitmap& aBitmap, CFbsBitmap* aMask) |
|
108 { |
|
109 CSwtImage* self = new(ELeave) CSwtImage(NULL, NULL); |
|
110 CleanupStack::PushL(self); |
|
111 self->ConstructL(aBitmap, aMask, TPoint(0, 0), 0, KSwtDisposalUnspecified, EFalse); |
|
112 CleanupStack::Pop(self); |
|
113 return self; |
|
114 } |
|
115 |
|
116 // --------------------------------------------------------------------------- |
|
117 // CSwtImage::CSwtImage |
|
118 // --------------------------------------------------------------------------- |
|
119 // |
|
120 inline CSwtImage::CSwtImage(MSwtDevice* aDevice, MSwtDisplay* aDisplay) |
|
121 : iDevice(aDevice) |
|
122 , iMaskType(ENoMask) |
|
123 , iDisplay(aDisplay) |
|
124 { |
|
125 } |
|
126 |
|
127 // --------------------------------------------------------------------------- |
|
128 // CSwtImage::~CSwtImage |
|
129 // --------------------------------------------------------------------------- |
|
130 // |
|
131 CSwtImage::~CSwtImage() |
|
132 { |
|
133 iScaledMasks.ResetAndDestroy(); |
|
134 iScaledMasksInverted.ResetAndDestroy(); |
|
135 iScaledBitmaps.ResetAndDestroy(); |
|
136 iScaledBitmapRefs.Close(); |
|
137 delete iColorKey; |
|
138 if (!iOwnExternally) |
|
139 { |
|
140 delete iMask; |
|
141 delete iBitmap; |
|
142 } |
|
143 delete iMaskInverted; |
|
144 delete iBitmapDevice; |
|
145 if (iDisplay) |
|
146 { |
|
147 iDisplay->RemoveResourceChangeObserver(this); |
|
148 } |
|
149 } |
|
150 |
|
151 // --------------------------------------------------------------------------- |
|
152 // CSwtImage::ConstructL |
|
153 // --------------------------------------------------------------------------- |
|
154 // |
|
155 void CSwtImage::ConstructL(const TSize& aSize, TDisplayMode aMode) |
|
156 { |
|
157 ASSERT(iDevice); |
|
158 ASSERT(iDisplay); |
|
159 |
|
160 // Create the bitmap |
|
161 iBitmap = new(ELeave) CFbsBitmap; |
|
162 |
|
163 // By default set the image color depth to that of the device. |
|
164 TDisplayMode mode = (aMode != ENone) ? aMode : |
|
165 iDisplay->CoeEnv()->ScreenDevice()->DisplayMode(); |
|
166 |
|
167 // 12-bit images aren't handled by SWT, neither will we |
|
168 if (mode == EColor4K) |
|
169 { |
|
170 mode = iDisplay->CoeEnv()->ScreenDevice()->DisplayMode(); |
|
171 } |
|
172 |
|
173 User::LeaveIfError(iBitmap->Create(aSize, mode)); |
|
174 |
|
175 // We have to set twips size of bitmap because this is used in order to get |
|
176 // best sized fonts if a GC is created on this bitmap ( if we don't then |
|
177 // HAL will be used and maybe this could return wrong values if device |
|
178 // resolution has changed ) |
|
179 iBitmap->SetSizeInTwips(&(iDevice->GraphicsDevice())); |
|
180 iDisplay->AddResourceChangeObserverL(this); |
|
181 |
|
182 // Create the bitmap device |
|
183 iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap); |
|
184 |
|
185 // Initialise the image information |
|
186 iInfo.iSize = aSize; |
|
187 iInfo.iDepth = BitDepth(mode); |
|
188 iInfo.iScanlinePad = ScanlinePadding(iInfo.iDepth); |
|
189 iInfo.iBytesPerLine = BytesPerLine(iInfo.iSize.iWidth, iInfo.iDepth, |
|
190 iInfo.iScanlinePad); |
|
191 iInfo.iTransparentPixel = -1; |
|
192 iInfo.iMaskPad = 0; |
|
193 iInfo.iAlpha = -1; |
|
194 iInfo.iType = ESwtImagePng; |
|
195 iInfo.iTopLeft = TPoint(0, 0); |
|
196 iInfo.iDisposalMethod = KSwtDisposalUnspecified; |
|
197 iInfo.iDelayTime = 0; |
|
198 } |
|
199 |
|
200 // --------------------------------------------------------------------------- |
|
201 // CSwtImage::ConstructL |
|
202 // --------------------------------------------------------------------------- |
|
203 // |
|
204 void CSwtImage::ConstructL(const MSwtImageData& aData) |
|
205 { |
|
206 TDisplayMode mode(DisplayMode(aData)); |
|
207 if (mode == ENone) |
|
208 { |
|
209 User::Leave(ESwtErrorUnsupportedDepth); |
|
210 } |
|
211 |
|
212 iInfo = aData.Info(); |
|
213 |
|
214 // Create the bitmap and its device |
|
215 iBitmap = new(ELeave) CFbsBitmap; |
|
216 User::LeaveIfError(iBitmap->Create(iInfo.iSize, mode)); |
|
217 iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap); |
|
218 |
|
219 // Fill the bitmap |
|
220 if (aData.PixelBuffer().Length() != 0) |
|
221 { |
|
222 CopyData(*iBitmap, aData.PixelBuffer(), iInfo.iSize.iHeight, |
|
223 iInfo.iDepth, iInfo.iBytesPerLine, &(aData.Palette())); |
|
224 } |
|
225 else |
|
226 { |
|
227 FillBitmapL(*iBitmapDevice, KRgbBlack, TRect(iInfo.iSize)); |
|
228 } |
|
229 |
|
230 if (iInfo.iAlpha != -1) |
|
231 { |
|
232 // Global alpha value, causes alphaData to be ignored. |
|
233 iMaskType = EAlphaMask; |
|
234 iMask = new(ELeave) CFbsBitmap; |
|
235 User::LeaveIfError(iMask->Create(iInfo.iSize, EGray256)); |
|
236 |
|
237 iMask->LockHeap(); |
|
238 Mem::Fill(iMask->DataAddress(), |
|
239 iInfo.iSize.iWidth * iInfo.iSize.iHeight, iInfo.iAlpha); |
|
240 iMask->UnlockHeap(); |
|
241 } |
|
242 else |
|
243 { |
|
244 // Binary mask |
|
245 if (aData.MaskBuffer()) |
|
246 { |
|
247 iMaskType = EBinaryMask; |
|
248 iMask = new(ELeave) CFbsBitmap; |
|
249 User::LeaveIfError(iMask->Create(iInfo.iSize, EGray2)); |
|
250 TInt bpl = BytesPerLine(iInfo.iSize.iWidth, 1, iInfo.iMaskPad); |
|
251 CopyData(*iMask, *aData.MaskBuffer(), iInfo.iSize.iHeight, 1, bpl, NULL); |
|
252 } |
|
253 // Colour key mask, binary mask |
|
254 else if (iInfo.iTransparentPixel != -1) |
|
255 { |
|
256 iMaskType = EDirtyColorKey; |
|
257 iMask = new(ELeave) CFbsBitmap; |
|
258 User::LeaveIfError(iMask->Create(iInfo.iSize, EGray2)); |
|
259 SetColorKeyL(aData); |
|
260 ComputeColorKeyMask(); |
|
261 } |
|
262 // Alpha mask |
|
263 else if (aData.AlphaBuffer()) |
|
264 { |
|
265 iMaskType = EAlphaMask; |
|
266 iMask = new(ELeave) CFbsBitmap; |
|
267 User::LeaveIfError(iMask->Create(iInfo.iSize, EGray256)); |
|
268 CopyData(*iMask, *aData.AlphaBuffer(), iInfo.iSize.iHeight, 8, |
|
269 iInfo.iSize.iWidth, NULL); |
|
270 } |
|
271 } |
|
272 } |
|
273 |
|
274 // --------------------------------------------------------------------------- |
|
275 // CSwtImage::ConstructL |
|
276 // --------------------------------------------------------------------------- |
|
277 // |
|
278 void CSwtImage::ConstructL(CFbsBitmap& aBitmap, CFbsBitmap* aMask, |
|
279 const TPoint& aTopLeft, TInt aDelayTime, |
|
280 TSwtGifDisposal aDisposalMethod, TBool aBmpOwnExternally) |
|
281 { |
|
282 // Caution: if true, the object depends on the external bitmap's lifetime |
|
283 iOwnExternally = aBmpOwnExternally; |
|
284 |
|
285 iBitmap = &aBitmap; |
|
286 iMask = aMask; |
|
287 |
|
288 TDisplayMode mode = iBitmap->DisplayMode(); |
|
289 if (mode == ENone || mode == EColor4K) |
|
290 { |
|
291 // 12-bit images aren't handled by SWT, neither will we |
|
292 User::Leave(ESwtErrorUnsupportedDepth); |
|
293 } |
|
294 |
|
295 iInfo.iSize = iBitmap->SizeInPixels(); |
|
296 iInfo.iDepth = BitDepth(mode); |
|
297 iInfo.iScanlinePad = ScanlinePadding(iInfo.iDepth); |
|
298 iInfo.iBytesPerLine = BytesPerLine(iInfo.iSize.iWidth, iInfo.iDepth, iInfo.iScanlinePad); |
|
299 iInfo.iTransparentPixel = -1; |
|
300 iInfo.iMaskPad = 0; |
|
301 iInfo.iAlpha = -1; |
|
302 iInfo.iType = ESwtImagePng; |
|
303 iInfo.iTopLeft = aTopLeft; |
|
304 iInfo.iDisposalMethod = aDisposalMethod; |
|
305 iInfo.iDelayTime = aDelayTime; |
|
306 |
|
307 if (iMask) |
|
308 { |
|
309 if (iMask->DisplayMode() == EGray2) |
|
310 { |
|
311 iMaskType = EBinaryMask; |
|
312 } |
|
313 else |
|
314 { |
|
315 iMaskType = EAlphaMask; |
|
316 } |
|
317 } |
|
318 } |
|
319 |
|
320 // --------------------------------------------------------------------------- |
|
321 // CSwtImage::SetColorKeyL |
|
322 // --------------------------------------------------------------------------- |
|
323 // |
|
324 void CSwtImage::SetColorKeyL(const MSwtImageData& aData) |
|
325 { |
|
326 ASSERT(!iColorKey); |
|
327 |
|
328 iColorKey = new(ELeave) TRgb; |
|
329 |
|
330 const MSwtPaletteData& palette = aData.Palette(); |
|
331 const MSwtImageData::TInfo& info = aData.Info(); |
|
332 |
|
333 if (palette.IsDirect()) |
|
334 { |
|
335 switch (info.iDepth) |
|
336 { |
|
337 // Monochrome, the transparent pixel is either black or white |
|
338 case 1: |
|
339 *iColorKey = (info.iTransparentPixel == 0) ? |
|
340 TRgb(0, 0, 0) : TRgb(255u, 255u, 255u); |
|
341 break; |
|
342 // Direct colour, extract components |
|
343 case 16: |
|
344 case 24: |
|
345 case 32: |
|
346 *iColorKey = GetRgb(info.iTransparentPixel, |
|
347 palette.DirectData()); |
|
348 break; |
|
349 default: |
|
350 User::Leave(KErrNotSupported); |
|
351 break; |
|
352 } |
|
353 } |
|
354 else |
|
355 { |
|
356 switch (aData.Info().iDepth) |
|
357 { |
|
358 // Look up the transparent pixel in the palette |
|
359 case 1: |
|
360 case 2: |
|
361 case 4: |
|
362 case 8: |
|
363 *iColorKey = palette.IndirectData()->GetEntry( |
|
364 info.iTransparentPixel); |
|
365 break; |
|
366 default: |
|
367 User::Leave(KErrNotSupported); |
|
368 break; |
|
369 } |
|
370 } |
|
371 } |
|
372 |
|
373 |
|
374 // --------------------------------------------------------------------------- |
|
375 // CSwtImage::EnsureMaskIsUpToDate |
|
376 // --------------------------------------------------------------------------- |
|
377 // |
|
378 void CSwtImage::EnsureMaskIsUpToDate() const |
|
379 { |
|
380 if (iMaskType == EDirtyColorKey) |
|
381 { |
|
382 const_cast<CSwtImage*>(this)->ComputeColorKeyMask(); |
|
383 } |
|
384 } |
|
385 |
|
386 // --------------------------------------------------------------------------- |
|
387 // CSwtImage::ComputeColorKeyMask |
|
388 // --------------------------------------------------------------------------- |
|
389 // |
|
390 void CSwtImage::ComputeColorKeyMask() |
|
391 { |
|
392 ASSERT(iBitmap); |
|
393 ASSERT(iMask && iMask->DisplayMode() == EGray2); |
|
394 ASSERT(iColorKey); |
|
395 ASSERT(iMaskType == EDirtyColorKey); |
|
396 |
|
397 iMask->LockHeap(EFalse); |
|
398 TUint32* maskPtr = iMask->DataAddress(); |
|
399 |
|
400 const TSize size(iBitmap->SizeInPixels()); |
|
401 const TInt wordsPerMaskLine = CFbsBitmap::ScanLineLength(size.iWidth, EGray2) / 4; |
|
402 |
|
403 TRgb pixel; |
|
404 for (TInt y = 0; y < size.iHeight; ++y) |
|
405 { |
|
406 TUint32 word32 = 0; |
|
407 TInt bitsInWord = 0; |
|
408 TInt wordsWritten = 0; |
|
409 |
|
410 for (TInt x = 0; x < size.iWidth; ++x) |
|
411 { |
|
412 iBitmap->GetPixel(pixel, TPoint(x, y)); |
|
413 word32 >>= 1; |
|
414 word32 |= (pixel == *iColorKey) ? 0 : 0x80000000; |
|
415 if (++bitsInWord == 32) |
|
416 { |
|
417 maskPtr[wordsWritten++] = word32; |
|
418 bitsInWord = 0; |
|
419 } |
|
420 } |
|
421 |
|
422 if (bitsInWord != 0) |
|
423 { |
|
424 maskPtr[wordsWritten] = word32 >> (32 - bitsInWord); |
|
425 } |
|
426 |
|
427 maskPtr += wordsPerMaskLine; |
|
428 } |
|
429 |
|
430 iMask->UnlockHeap(); |
|
431 iMaskType = EColorKey; |
|
432 } |
|
433 |
|
434 // --------------------------------------------------------------------------- |
|
435 // CSwtImage::IsGrayscale |
|
436 // --------------------------------------------------------------------------- |
|
437 // |
|
438 TBool CSwtImage::IsGrayscale() const |
|
439 { |
|
440 switch (iBitmap->DisplayMode()) |
|
441 { |
|
442 case EGray2: |
|
443 case EGray4: |
|
444 case EGray16: |
|
445 case EGray256: |
|
446 return ETrue; |
|
447 default: |
|
448 return EFalse; |
|
449 } |
|
450 } |
|
451 |
|
452 // --------------------------------------------------------------------------- |
|
453 // CSwtImage::GetPaletteDataL |
|
454 // --------------------------------------------------------------------------- |
|
455 // |
|
456 CSwtGrPaletteData* CSwtImage::GetPaletteDataL() const |
|
457 { |
|
458 TDisplayMode mode(iBitmap->DisplayMode()); |
|
459 |
|
460 // Decide whether the palette is direct or indirect |
|
461 TBool isDirect; |
|
462 switch (mode) |
|
463 { |
|
464 case EGray2: |
|
465 case EGray4: |
|
466 case EGray16: |
|
467 case EGray256: |
|
468 isDirect = EFalse; |
|
469 break; |
|
470 case EColor64K: |
|
471 case EColor16M: |
|
472 case EColor16MU: |
|
473 case EColor16MA: |
|
474 case EColor16MAP: |
|
475 isDirect = ETrue; |
|
476 break; |
|
477 default: |
|
478 ASSERT(EFalse); |
|
479 return NULL; |
|
480 } |
|
481 |
|
482 // Create and fill the palette data |
|
483 CSwtGrPaletteData* data = CSwtGrPaletteData::NewL(isDirect); |
|
484 if (isDirect) |
|
485 { |
|
486 CSwtGrPaletteData::TDirectData directData; |
|
487 if (mode == EColor64K) |
|
488 { |
|
489 // 16-bit Symbian bitmaps are stored as [rrrrrggg gggbbbbb] ( binary ) |
|
490 directData.iRedMask = 0xF800; // [11111000 00000000] binary |
|
491 directData.iGreenMask = 0x07E0; // [00000111 11100000] binary |
|
492 directData.iBlueMask = 0x001F; // [00000000 00011111] binary |
|
493 directData.iRedShift = -8; |
|
494 directData.iGreenShift = -3; |
|
495 directData.iBlueShift = 3; |
|
496 } |
|
497 else if (mode == EColor16M) |
|
498 { |
|
499 // 24-bit Symbian bitmaps are stored in BGR order; 24-bit SWT images |
|
500 // are stored in MSB first order, this yields a pixel format of 0xbbggrr |
|
501 directData.iRedMask = 0x0000FF; |
|
502 directData.iGreenMask = 0x00FF00; |
|
503 directData.iBlueMask = 0xFF0000; |
|
504 directData.iRedShift = 0; |
|
505 directData.iGreenShift = -8; |
|
506 directData.iBlueShift = -16; |
|
507 } |
|
508 else |
|
509 { |
|
510 // EColor16MU, EColor16MA or EColor16MAP |
|
511 // 32-bit Symbian bitmaps are stored in BGR order; 32-bit SWT images |
|
512 // are stored in MSB first order, this yields a pixel format of 0xbbggrraa |
|
513 directData.iRedMask = 0x0000FF00; |
|
514 directData.iGreenMask = 0x00FF0000; |
|
515 directData.iBlueMask = 0xFF000000; |
|
516 directData.iRedShift = -8; |
|
517 directData.iGreenShift = -16; |
|
518 directData.iBlueShift = -24; |
|
519 } |
|
520 data->SetDirectData(directData); |
|
521 } |
|
522 else |
|
523 { |
|
524 data->SetIndirectData(NewGrayPaletteL(mode)); |
|
525 } |
|
526 |
|
527 return data; |
|
528 } |
|
529 |
|
530 // --------------------------------------------------------------------------- |
|
531 // CSwtImage::PaletteGrayMode |
|
532 // --------------------------------------------------------------------------- |
|
533 // |
|
534 TDisplayMode CSwtImage::PaletteGrayMode(TInt aDepth, const CPalette& aPalette) |
|
535 { |
|
536 TDisplayMode mode; |
|
537 |
|
538 // Find the mode by looking at the bit depth |
|
539 switch (aDepth) |
|
540 { |
|
541 case 8: |
|
542 mode = EGray256; |
|
543 break; |
|
544 case 4: |
|
545 mode = EGray16; |
|
546 break; |
|
547 case 2: |
|
548 mode = EGray4; |
|
549 break; |
|
550 case 1: |
|
551 mode = EGray2; |
|
552 break; |
|
553 default: |
|
554 mode = ENone; |
|
555 break; |
|
556 } |
|
557 |
|
558 // Check the colours |
|
559 if (mode != ENone) |
|
560 { |
|
561 // Check the number of colours is 2^depth |
|
562 const TInt count = aPalette.Entries(); |
|
563 if (count != (1 << aDepth)) |
|
564 { |
|
565 return ENone; |
|
566 } |
|
567 |
|
568 // Check the colours are indeed gray and evenly scattered |
|
569 for (TInt i = 0; i<count; ++i) |
|
570 { |
|
571 TInt l = (i*255) / (count - 1); |
|
572 if (aPalette.GetEntry(i) != TRgb(l, l, l)) |
|
573 { |
|
574 return ENone; |
|
575 } |
|
576 } |
|
577 } |
|
578 |
|
579 return mode; |
|
580 } |
|
581 |
|
582 // --------------------------------------------------------------------------- |
|
583 // CSwtImage::DisplayMode |
|
584 // --------------------------------------------------------------------------- |
|
585 // |
|
586 TDisplayMode CSwtImage::DisplayMode(const MSwtImageData& aData) |
|
587 { |
|
588 TDisplayMode mode(ENone); |
|
589 |
|
590 const MSwtPaletteData& palette = aData.Palette(); |
|
591 const MSwtImageData::TInfo& info = aData.Info(); |
|
592 |
|
593 // Non paletted modes |
|
594 if (palette.IsDirect()) |
|
595 { |
|
596 switch (info.iDepth) |
|
597 { |
|
598 case 1: |
|
599 mode = EGray2; |
|
600 break; |
|
601 case 16: |
|
602 mode = EColor64K; |
|
603 break; |
|
604 case 8: |
|
605 case 24: |
|
606 mode = EColor16M; |
|
607 break; |
|
608 case 32: |
|
609 mode = EColor16MU; |
|
610 break; |
|
611 default: |
|
612 break; |
|
613 } |
|
614 } |
|
615 // Paletted modes |
|
616 else |
|
617 { |
|
618 // For some reason, CFbsBitmap::SetPalette() is implemented as empty. |
|
619 // The result is that paletted modes are not handled correctly. The |
|
620 // workaround is to convert all colour paletted modes to 24 bits, we |
|
621 // waste a lot of memory but at least it works. |
|
622 TDisplayMode grayMode(PaletteGrayMode(info.iDepth, |
|
623 *(palette.IndirectData()))); |
|
624 mode = (grayMode != ENone) ? grayMode : EColor16MU; |
|
625 } |
|
626 |
|
627 return mode; |
|
628 } |
|
629 |
|
630 // --------------------------------------------------------------------------- |
|
631 // CSwtImage::BitDepth |
|
632 // --------------------------------------------------------------------------- |
|
633 // |
|
634 TInt CSwtImage::BitDepth(TDisplayMode aMode) |
|
635 { |
|
636 return TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode); |
|
637 } |
|
638 |
|
639 // --------------------------------------------------------------------------- |
|
640 // CSwtImage::ImageDepth |
|
641 // --------------------------------------------------------------------------- |
|
642 // |
|
643 TInt CSwtImage::ImageDepth() const |
|
644 { |
|
645 switch (iBitmap->DisplayMode()) |
|
646 { |
|
647 case EGray2: |
|
648 return 1; |
|
649 case EGray4: |
|
650 return 2; |
|
651 case EGray16: |
|
652 return 4; |
|
653 case EGray256: |
|
654 return 8; |
|
655 case EColor16: |
|
656 return 4; |
|
657 case EColor256: |
|
658 return 8; |
|
659 case EColor64K: |
|
660 return 16; |
|
661 case EColor16M: |
|
662 return 24; |
|
663 case EColor16MU: |
|
664 return 32; |
|
665 case EColor16MA: |
|
666 return 32; |
|
667 case EColor16MAP: |
|
668 return 32; |
|
669 case ERgb: |
|
670 return 24; |
|
671 case EColor4K: |
|
672 return 12; |
|
673 |
|
674 default: |
|
675 case ENone: |
|
676 case EColorLast: |
|
677 ASSERT(EFalse); |
|
678 return 0; |
|
679 } |
|
680 } |
|
681 |
|
682 // --------------------------------------------------------------------------- |
|
683 // CSwtImage::ScanlinePadding |
|
684 // --------------------------------------------------------------------------- |
|
685 // |
|
686 TInt CSwtImage::ScanlinePadding(TInt aBitDepth) |
|
687 { |
|
688 switch (aBitDepth) |
|
689 { |
|
690 case 1: |
|
691 case 2: |
|
692 case 4: |
|
693 case 16: |
|
694 case 24: |
|
695 case 32: |
|
696 return 4; |
|
697 case 8: |
|
698 // This is because of alpha data which is not supposed to have padding |
|
699 return 1; |
|
700 default: |
|
701 ASSERT(EFalse); |
|
702 return 0; |
|
703 } |
|
704 } |
|
705 |
|
706 // --------------------------------------------------------------------------- |
|
707 // CSwtImage::BytesPerLine |
|
708 // --------------------------------------------------------------------------- |
|
709 // |
|
710 TInt CSwtImage::BytesPerLine(TInt aPixelsPerLine, TInt aBitsPerPixel, |
|
711 TInt aPadding) |
|
712 { |
|
713 TInt byteCount = (aPixelsPerLine * aBitsPerPixel + 7) / 8; |
|
714 TInt remainder = byteCount % aPadding; |
|
715 TInt extra = (remainder != 0) ? aPadding-remainder : 0; |
|
716 return byteCount + extra; |
|
717 } |
|
718 |
|
719 // --------------------------------------------------------------------------- |
|
720 // CSwtImage::FillBitmapL |
|
721 // --------------------------------------------------------------------------- |
|
722 // |
|
723 void CSwtImage::FillBitmapL(CFbsBitmapDevice& aDevice, const TRgb& aColor, |
|
724 const TRect& aRect) |
|
725 { |
|
726 CFbsBitGc* gc = CFbsBitGc::NewL(); |
|
727 gc->Activate(&aDevice); |
|
728 |
|
729 gc->SetPenStyle(CGraphicsContext::ENullPen); |
|
730 gc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
731 gc->SetBrushColor(aColor); |
|
732 gc->DrawRect(aRect); |
|
733 |
|
734 delete gc; |
|
735 } |
|
736 |
|
737 // --------------------------------------------------------------------------- |
|
738 // CSwtImage::BitBltBitmapL |
|
739 // --------------------------------------------------------------------------- |
|
740 // |
|
741 void CSwtImage::BitBltBitmapL(CFbsBitmapDevice& aDevice, const CFbsBitmap& aBitmap) |
|
742 { |
|
743 CFbsBitGc* gc = CFbsBitGc::NewL(); |
|
744 gc->Activate(&aDevice); |
|
745 gc->BitBlt(TPoint(0,0), &aBitmap); |
|
746 delete gc; |
|
747 } |
|
748 |
|
749 |
|
750 // --------------------------------------------------------------------------- |
|
751 // CSwtImage::FillBitmapL |
|
752 // --------------------------------------------------------------------------- |
|
753 // |
|
754 void CSwtImage::FillBitmapL(CFbsBitmap& aBitmap, const TRgb& aColor, |
|
755 const TRect& aRect) |
|
756 { |
|
757 CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(&aBitmap); |
|
758 CleanupStack::PushL(device); |
|
759 FillBitmapL(*device, aColor, aRect); |
|
760 CleanupStack::PopAndDestroy(device); |
|
761 } |
|
762 |
|
763 // --------------------------------------------------------------------------- |
|
764 // CSwtImage::NewGrayPaletteL |
|
765 // --------------------------------------------------------------------------- |
|
766 // |
|
767 CPalette* CSwtImage::NewGrayPaletteL(TDisplayMode aMode) |
|
768 { |
|
769 TInt count; |
|
770 |
|
771 switch (aMode) |
|
772 { |
|
773 case EGray2: |
|
774 count = 2; |
|
775 break; |
|
776 case EGray4: |
|
777 count = 4; |
|
778 break; |
|
779 case EGray16: |
|
780 count = 16; |
|
781 break; |
|
782 case EGray256: |
|
783 count = 256; |
|
784 break; |
|
785 default: |
|
786 ASSERT(EFalse); |
|
787 return NULL; |
|
788 } |
|
789 |
|
790 CPalette* palette = CPalette::NewL(count); |
|
791 for (TInt i = 0; i < count; ++i) |
|
792 { |
|
793 TInt shade = (i*255) / (count-1); |
|
794 palette->SetEntry(i, TRgb(shade, shade, shade)); |
|
795 } |
|
796 |
|
797 return palette; |
|
798 } |
|
799 |
|
800 // --------------------------------------------------------------------------- |
|
801 // CSwtImage::BitShift |
|
802 // --------------------------------------------------------------------------- |
|
803 // |
|
804 inline TUint CSwtImage::BitShift(TUint aValue, TInt aShift) |
|
805 { |
|
806 return (aShift >= 0) ? (aValue << aShift) : (aValue >> -aShift); |
|
807 } |
|
808 |
|
809 // --------------------------------------------------------------------------- |
|
810 // CSwtImage::GetRed |
|
811 // --------------------------------------------------------------------------- |
|
812 // |
|
813 inline TUint CSwtImage::GetRed(TUint aPixel, |
|
814 const MSwtPaletteData::TDirectData& aPalette) |
|
815 { |
|
816 return BitShift(aPixel & aPalette.iRedMask, aPalette.iRedShift); |
|
817 } |
|
818 |
|
819 // --------------------------------------------------------------------------- |
|
820 // CSwtImage::GetGreen |
|
821 // --------------------------------------------------------------------------- |
|
822 // |
|
823 inline TUint CSwtImage::GetGreen(TUint aPixel, |
|
824 const MSwtPaletteData::TDirectData& aPalette) |
|
825 { |
|
826 return BitShift(aPixel & aPalette.iGreenMask, aPalette.iGreenShift); |
|
827 } |
|
828 |
|
829 // --------------------------------------------------------------------------- |
|
830 // CSwtImage::GetBlue |
|
831 // --------------------------------------------------------------------------- |
|
832 // |
|
833 inline TUint CSwtImage::GetBlue(TUint aPixel, |
|
834 const MSwtPaletteData::TDirectData& aPalette) |
|
835 { |
|
836 return BitShift(aPixel & aPalette.iBlueMask, aPalette.iBlueShift); |
|
837 } |
|
838 |
|
839 // --------------------------------------------------------------------------- |
|
840 // CSwtImage::GetBlue |
|
841 // --------------------------------------------------------------------------- |
|
842 // |
|
843 inline TRgb CSwtImage::GetRgb(TUint aPixel, |
|
844 const MSwtPaletteData::TDirectData& aPalette) |
|
845 { |
|
846 return TRgb(GetRed(aPixel, aPalette), GetGreen(aPixel, aPalette), GetBlue(aPixel, aPalette)); |
|
847 } |
|
848 |
|
849 // --------------------------------------------------------------------------- |
|
850 // CSwtImage::WritePixel16 |
|
851 // --------------------------------------------------------------------------- |
|
852 // |
|
853 inline void CSwtImage::WritePixel16(TUint8*& aPtr, TUint aPixel, |
|
854 const MSwtPaletteData::TDirectData& aPalette) |
|
855 { |
|
856 TUint pixel16; |
|
857 pixel16 = (GetRed(aPixel, aPalette) & 0xF8) << 8; |
|
858 pixel16 |= (GetGreen(aPixel, aPalette) & 0xFC) << 3; |
|
859 pixel16 |= (GetBlue(aPixel, aPalette)) >> 3; |
|
860 |
|
861 *reinterpret_cast<TUint16*&>(aPtr)++ = static_cast<TUint16>(pixel16); |
|
862 } |
|
863 |
|
864 // --------------------------------------------------------------------------- |
|
865 // CSwtImage::WritePixelTrueColor |
|
866 // --------------------------------------------------------------------------- |
|
867 // |
|
868 inline void CSwtImage::WritePixelTrueColor(TUint8*& aPtr, const TRgb& aColor, TBool a24Bit) |
|
869 { |
|
870 *aPtr++ = static_cast<TUint8>(aColor.Blue()); |
|
871 *aPtr++ = static_cast<TUint8>(aColor.Green()); |
|
872 *aPtr++ = static_cast<TUint8>(aColor.Red()); |
|
873 |
|
874 if (!a24Bit) |
|
875 { |
|
876 // Since we don't get any alpha channel data for the 32-bit pixel, |
|
877 // set it opaque. |
|
878 *aPtr++ = 0xFF; |
|
879 } |
|
880 } |
|
881 |
|
882 |
|
883 // --------------------------------------------------------------------------- |
|
884 // CSwtImage::WritePixelTrueColor |
|
885 // --------------------------------------------------------------------------- |
|
886 // |
|
887 inline void CSwtImage::WritePixelTrueColor(TUint8*& aPtr, TUint aPixel, |
|
888 const MSwtPaletteData::TDirectData& aPalette, TBool a24Bit) |
|
889 { |
|
890 if (a24Bit) |
|
891 { |
|
892 *aPtr++ = static_cast<TUint8>(GetBlue(aPixel, aPalette)); |
|
893 *aPtr++ = static_cast<TUint8>(GetGreen(aPixel, aPalette)); |
|
894 *aPtr++ = static_cast<TUint8>(GetRed(aPixel, aPalette)); |
|
895 } |
|
896 else |
|
897 { |
|
898 *aPtr++ = static_cast<TUint8>(GetBlue(aPixel, aPalette)); |
|
899 *aPtr++ = static_cast<TUint8>(GetGreen(aPixel, aPalette)); |
|
900 *aPtr++ = static_cast<TUint8>(GetRed(aPixel, aPalette)); |
|
901 // Alpha value is the last byte of the pixel. |
|
902 *aPtr++ = static_cast<TUint8>(aPixel & 0xFF); |
|
903 } |
|
904 } |
|
905 |
|
906 |
|
907 // --------------------------------------------------------------------------- |
|
908 // CSwtImage::CopyData |
|
909 // --------------------------------------------------------------------------- |
|
910 // |
|
911 void CSwtImage::CopyData(const CFbsBitmap& aBitmap, const TDesC8& aData, |
|
912 TInt aLineCount, TInt aDepth, TInt aBytesPerLine, |
|
913 const MSwtPaletteData* aPalette) |
|
914 { |
|
915 aBitmap.LockHeap(EFalse); |
|
916 |
|
917 const TUint8* srce = aData.Ptr(); |
|
918 TUint8* dest = reinterpret_cast<TUint8*>(aBitmap.DataAddress()); |
|
919 |
|
920 TDisplayMode mode(aBitmap.DisplayMode()); |
|
921 TInt destBytesPerLine = CFbsBitmap::ScanLineLength( |
|
922 aBitmap.SizeInPixels().iWidth, mode); |
|
923 |
|
924 switch (mode) |
|
925 { |
|
926 case EGray2: |
|
927 Copy1(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount); |
|
928 break; |
|
929 case EGray4: |
|
930 Copy2(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount); |
|
931 break; |
|
932 case EGray16: |
|
933 Copy4(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount); |
|
934 break; |
|
935 case EGray256: |
|
936 Copy8(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount); |
|
937 break; |
|
938 case EColor64K: |
|
939 ASSERT(aPalette); |
|
940 Copy16(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount, |
|
941 aPalette->DirectData()); |
|
942 break; |
|
943 case EColor16M: |
|
944 case EColor16MU: |
|
945 case EColor16MA: |
|
946 case EColor16MAP: |
|
947 ASSERT(aPalette); |
|
948 switch (aDepth) |
|
949 { |
|
950 case 1: |
|
951 Copy1ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine, |
|
952 aLineCount, *aPalette->IndirectData(), mode == EColor16M); |
|
953 break; |
|
954 case 2: |
|
955 Copy2ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine, |
|
956 aLineCount, *aPalette->IndirectData(), mode == EColor16M); |
|
957 break; |
|
958 case 4: |
|
959 Copy4ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine, |
|
960 aLineCount, *aPalette->IndirectData(), mode == EColor16M); |
|
961 break; |
|
962 case 8: |
|
963 if (aPalette->IsDirect()) |
|
964 { |
|
965 Copy8ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine, |
|
966 aLineCount, aPalette->DirectData(), mode == EColor16M); |
|
967 } |
|
968 else |
|
969 { |
|
970 Copy8ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine, |
|
971 aLineCount, *aPalette->IndirectData(), mode == EColor16M); |
|
972 } |
|
973 break; |
|
974 case 24: |
|
975 Copy24(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount, |
|
976 aPalette->DirectData()); |
|
977 break; |
|
978 case 32: |
|
979 Copy32(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount, |
|
980 aPalette->DirectData()); |
|
981 break; |
|
982 default: |
|
983 ASSERT(EFalse); |
|
984 break; |
|
985 } |
|
986 break; |
|
987 default: |
|
988 ASSERT(EFalse); |
|
989 break; |
|
990 } |
|
991 |
|
992 aBitmap.UnlockHeap(); |
|
993 } |
|
994 |
|
995 |
|
996 // --------------------------------------------------------------------------- |
|
997 // CSwtImage::CopyDataWithAlpha |
|
998 // --------------------------------------------------------------------------- |
|
999 // |
|
1000 void CSwtImage::AddMaskToAlphaChannel(const CFbsBitmap& aBitmap, const CFbsBitmap& aMask) |
|
1001 { |
|
1002 |
|
1003 ASSERT(aBitmap.DisplayMode() == EColor16MA |
|
1004 || aBitmap.DisplayMode() == EColor16MAP); |
|
1005 ASSERT(aMask.DisplayMode() == EGray256); |
|
1006 |
|
1007 aBitmap.LockHeap(EFalse); |
|
1008 TUint8* dest = reinterpret_cast<TUint8*>(aBitmap.DataAddress()); |
|
1009 |
|
1010 TUint8* srce = reinterpret_cast<TUint8*>(aMask.DataAddress()); |
|
1011 |
|
1012 |
|
1013 |
|
1014 for (TInt i = 0; i < aMask.SizeInPixels().iHeight * aMask.SizeInPixels().iWidth; ++i) |
|
1015 { |
|
1016 // 1 byte = B; 2 byte = G; 3 byte = R; 4 byte = alpha |
|
1017 // skip rgb byte |
|
1018 dest++; // skip b |
|
1019 dest++; // skip g |
|
1020 dest++; // skip r |
|
1021 |
|
1022 // copy alpha vaule |
|
1023 *dest = *srce; |
|
1024 |
|
1025 // go next byte |
|
1026 srce++; |
|
1027 dest++; |
|
1028 } |
|
1029 |
|
1030 aBitmap.UnlockHeap(); |
|
1031 } |
|
1032 |
|
1033 // --------------------------------------------------------------------------- |
|
1034 // CSwtImage::Copy1 |
|
1035 // --------------------------------------------------------------------------- |
|
1036 // |
|
1037 void CSwtImage::Copy1(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1038 TInt aBytesPerSrceLine, TInt aLineCount) |
|
1039 { |
|
1040 ASSERT(aDest); |
|
1041 ASSERT(aSrce); |
|
1042 |
|
1043 const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine); |
|
1044 |
|
1045 for (TInt y = 0; y < aLineCount; ++y) |
|
1046 { |
|
1047 for (TInt x = 0; x < bytesToCopyPerLine; ++x) |
|
1048 { |
|
1049 aDest[x] = KBitReverseTable[aSrce[x]]; |
|
1050 } |
|
1051 aDest += aBytesPerDestLine; |
|
1052 aSrce += aBytesPerSrceLine; |
|
1053 } |
|
1054 } |
|
1055 |
|
1056 // --------------------------------------------------------------------------- |
|
1057 // CSwtImage::Copy2 |
|
1058 // --------------------------------------------------------------------------- |
|
1059 // |
|
1060 void CSwtImage::Copy2(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1061 TInt aBytesPerSrceLine, TInt aLineCount) |
|
1062 { |
|
1063 ASSERT(aDest); |
|
1064 ASSERT(aSrce); |
|
1065 |
|
1066 const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine); |
|
1067 |
|
1068 for (TInt y = 0; y < aLineCount; ++y) |
|
1069 { |
|
1070 for (TInt x = 0; x < bytesToCopyPerLine; ++x) |
|
1071 { |
|
1072 TUint byte = aSrce[x]; |
|
1073 aDest[x] = static_cast<TUint8> |
|
1074 ((byte >> 6) | |
|
1075 ((byte >> 2) & 0x0C) | |
|
1076 ((byte << 2) & 0x30) | |
|
1077 (byte << 6)); |
|
1078 } |
|
1079 aDest += aBytesPerDestLine; |
|
1080 aSrce += aBytesPerSrceLine; |
|
1081 } |
|
1082 } |
|
1083 |
|
1084 // --------------------------------------------------------------------------- |
|
1085 // CSwtImage::Copy4 |
|
1086 // --------------------------------------------------------------------------- |
|
1087 // |
|
1088 void CSwtImage::Copy4(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1089 TInt aBytesPerSrceLine, TInt aLineCount) |
|
1090 { |
|
1091 ASSERT(aDest); |
|
1092 ASSERT(aSrce); |
|
1093 |
|
1094 const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine); |
|
1095 |
|
1096 for (TInt y = 0; y < aLineCount; ++y) |
|
1097 { |
|
1098 for (TInt x = 0; x < bytesToCopyPerLine; ++x) |
|
1099 { |
|
1100 TUint byte = aSrce[x]; |
|
1101 aDest[x] = static_cast<TUint8>(byte >> 4 | byte << 4); |
|
1102 } |
|
1103 aDest += aBytesPerDestLine; |
|
1104 aSrce += aBytesPerSrceLine; |
|
1105 } |
|
1106 } |
|
1107 |
|
1108 // --------------------------------------------------------------------------- |
|
1109 // CSwtImage::Copy8 |
|
1110 // --------------------------------------------------------------------------- |
|
1111 // |
|
1112 void CSwtImage::Copy8(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1113 TInt aBytesPerSrceLine, TInt aLineCount) |
|
1114 { |
|
1115 ASSERT(aDest); |
|
1116 ASSERT(aSrce); |
|
1117 |
|
1118 const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine); |
|
1119 |
|
1120 for (TInt y = 0; y < aLineCount; ++y) |
|
1121 { |
|
1122 Mem::Copy(aDest, aSrce, bytesToCopyPerLine); |
|
1123 aDest += aBytesPerDestLine; |
|
1124 aSrce += aBytesPerSrceLine; |
|
1125 } |
|
1126 } |
|
1127 |
|
1128 // --------------------------------------------------------------------------- |
|
1129 // CSwtImage::Copy16 |
|
1130 // --------------------------------------------------------------------------- |
|
1131 // |
|
1132 void CSwtImage::Copy16(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1133 TInt aBytesPerSrceLine, TInt aLineCount, const MSwtPaletteData::TDirectData& aPalette) |
|
1134 { |
|
1135 ASSERT(aDest); |
|
1136 ASSERT(aSrce); |
|
1137 |
|
1138 const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine) & ~0x1; |
|
1139 |
|
1140 for (TInt y = 0; y < aLineCount; ++y) |
|
1141 { |
|
1142 TUint8* ptr = aDest; |
|
1143 |
|
1144 for (TInt x = 0; x < bytesToCopyPerLine; x+=2) |
|
1145 { |
|
1146 // Data in source buffer in stored LSB first |
|
1147 TUint pixel; |
|
1148 pixel = static_cast<TUint>(aSrce[x]); |
|
1149 pixel |= static_cast<TUint>(aSrce[x+1]) << 8; |
|
1150 |
|
1151 WritePixel16(ptr, pixel, aPalette); |
|
1152 } |
|
1153 |
|
1154 aDest += aBytesPerDestLine; |
|
1155 aSrce += aBytesPerSrceLine; |
|
1156 } |
|
1157 } |
|
1158 |
|
1159 // --------------------------------------------------------------------------- |
|
1160 // CSwtImage::Copy1To24 |
|
1161 // --------------------------------------------------------------------------- |
|
1162 // |
|
1163 void CSwtImage::Copy1ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1164 TInt aBytesPerSrceLine, TInt aLineCount, const CPalette& aPalette, TBool a24Bit) |
|
1165 { |
|
1166 ASSERT(aDest); |
|
1167 ASSERT(aSrce); |
|
1168 |
|
1169 const TInt bytesPerPixel = a24Bit ? 3 : 4; |
|
1170 const TInt pixelsToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel, |
|
1171 aBytesPerSrceLine * 8); |
|
1172 const TInt bytesToCopyPerLine = (pixelsToCopyPerLine + 7) / 8; |
|
1173 |
|
1174 for (TInt y = 0; y < aLineCount; ++y) |
|
1175 { |
|
1176 TUint8* ptr = aDest; |
|
1177 |
|
1178 TInt bitsLeftInLine = pixelsToCopyPerLine; |
|
1179 for (TInt x = 0; x < bytesToCopyPerLine; ++x) |
|
1180 { |
|
1181 TUint8 byte = aSrce[x]; |
|
1182 TInt bitsToCopy = Min(bitsLeftInLine, 8); |
|
1183 for (TInt i = 0; i < bitsToCopy; ++i) |
|
1184 { |
|
1185 WritePixelTrueColor(ptr, aPalette.GetEntry(byte >> 7), a24Bit); |
|
1186 byte <<= 1; |
|
1187 } |
|
1188 bitsLeftInLine -= 8; |
|
1189 } |
|
1190 |
|
1191 aDest += aBytesPerDestLine; |
|
1192 aSrce += aBytesPerSrceLine; |
|
1193 } |
|
1194 } |
|
1195 |
|
1196 // --------------------------------------------------------------------------- |
|
1197 // CSwtImage::Copy2To24 |
|
1198 // --------------------------------------------------------------------------- |
|
1199 // |
|
1200 void CSwtImage::Copy2ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1201 TInt aBytesPerSrceLine, TInt aLineCount, const CPalette& aPalette, TBool a24Bit) |
|
1202 { |
|
1203 ASSERT(aDest); |
|
1204 ASSERT(aSrce); |
|
1205 |
|
1206 const TInt bytesPerPixel = a24Bit ? 3 : 4; |
|
1207 const TInt pixelsToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel, |
|
1208 aBytesPerSrceLine*4); |
|
1209 const TInt bytesToCopyPerLine = (pixelsToCopyPerLine + bytesPerPixel) / 4; |
|
1210 |
|
1211 for (TInt y = 0; y < aLineCount; ++y) |
|
1212 { |
|
1213 TUint8* ptr = aDest; |
|
1214 |
|
1215 TInt bitsLeftInLine = pixelsToCopyPerLine * 2; |
|
1216 for (TInt x = 0; x < bytesToCopyPerLine; ++x) |
|
1217 { |
|
1218 TUint8 byte = aSrce[x]; |
|
1219 TInt bitsToCopy = Min(bitsLeftInLine, 8); |
|
1220 for (TInt i = 0; i < bitsToCopy; i += 2) |
|
1221 { |
|
1222 WritePixelTrueColor(ptr, aPalette.GetEntry(byte >> 6), a24Bit); |
|
1223 byte <<= 2; |
|
1224 } |
|
1225 bitsLeftInLine -= 8; |
|
1226 } |
|
1227 |
|
1228 aDest += aBytesPerDestLine; |
|
1229 aSrce += aBytesPerSrceLine; |
|
1230 } |
|
1231 } |
|
1232 |
|
1233 // --------------------------------------------------------------------------- |
|
1234 // CSwtImage::Copy4To24 |
|
1235 // --------------------------------------------------------------------------- |
|
1236 // |
|
1237 void CSwtImage::Copy4ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1238 TInt aBytesPerSrceLine, TInt aLineCount, const CPalette& aPalette, TBool a24Bit) |
|
1239 { |
|
1240 ASSERT(aDest); |
|
1241 ASSERT(aSrce); |
|
1242 |
|
1243 const TInt bytesPerPixel = a24Bit ? 3 : 4; |
|
1244 const TInt pixelsToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel, |
|
1245 aBytesPerSrceLine * 2); |
|
1246 const TInt bytesToCopyPerLine = pixelsToCopyPerLine / 2; |
|
1247 const TInt remainderPerLine = pixelsToCopyPerLine % 2; |
|
1248 |
|
1249 for (TInt y = 0; y < aLineCount; ++y) |
|
1250 { |
|
1251 TUint8* ptr = aDest; |
|
1252 TInt x; |
|
1253 for (x = 0; x < bytesToCopyPerLine; ++x) |
|
1254 { |
|
1255 TUint8 byte = aSrce[x]; |
|
1256 WritePixelTrueColor(ptr, aPalette.GetEntry(byte >> 4), a24Bit); |
|
1257 WritePixelTrueColor(ptr, aPalette.GetEntry(byte & 0x0F), a24Bit); |
|
1258 } |
|
1259 |
|
1260 if (remainderPerLine != 0) |
|
1261 { |
|
1262 WritePixelTrueColor(ptr, aPalette.GetEntry(aSrce[x] >> 4), a24Bit); |
|
1263 } |
|
1264 |
|
1265 aDest += aBytesPerDestLine; |
|
1266 aSrce += aBytesPerSrceLine; |
|
1267 } |
|
1268 } |
|
1269 |
|
1270 // --------------------------------------------------------------------------- |
|
1271 // CSwtImage::Copy8To24 |
|
1272 // --------------------------------------------------------------------------- |
|
1273 // |
|
1274 void CSwtImage::Copy8ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1275 TInt aBytesPerSrceLine, TInt aLineCount, const CPalette& aPalette, TBool a24Bit) |
|
1276 { |
|
1277 ASSERT(aDest); |
|
1278 ASSERT(aSrce); |
|
1279 |
|
1280 const TInt bytesPerPixel = a24Bit ? 3 : 4; |
|
1281 const TInt bytesToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel, |
|
1282 aBytesPerSrceLine); |
|
1283 |
|
1284 for (TInt y = 0; y < aLineCount; ++y) |
|
1285 { |
|
1286 TUint8* ptr = aDest; |
|
1287 |
|
1288 for (TInt x = 0; x < bytesToCopyPerLine; ++x) |
|
1289 { |
|
1290 WritePixelTrueColor(ptr, aPalette.GetEntry(aSrce[x]), a24Bit); |
|
1291 } |
|
1292 |
|
1293 aDest += aBytesPerDestLine; |
|
1294 aSrce += aBytesPerSrceLine; |
|
1295 } |
|
1296 } |
|
1297 |
|
1298 // --------------------------------------------------------------------------- |
|
1299 // CSwtImage::Copy8To24 |
|
1300 // --------------------------------------------------------------------------- |
|
1301 // |
|
1302 void CSwtImage::Copy8ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1303 TInt aBytesPerSrceLine, TInt aLineCount, const MSwtPaletteData::TDirectData& aPalette, |
|
1304 TBool a24Bit) |
|
1305 { |
|
1306 ASSERT(aDest); |
|
1307 ASSERT(aSrce); |
|
1308 |
|
1309 const TInt bytesPerPixel = a24Bit ? 3 : 4; |
|
1310 const TInt bytesToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel, |
|
1311 aBytesPerSrceLine); |
|
1312 |
|
1313 const TUint redMax = BitShift(aPalette.iRedMask, aPalette.iRedShift); |
|
1314 const TUint greenMax = BitShift(aPalette.iGreenMask, aPalette.iGreenShift); |
|
1315 const TUint blueMax = BitShift(aPalette.iBlueMask, aPalette.iBlueShift); |
|
1316 |
|
1317 for (TInt y = 0; y < aLineCount; ++y) |
|
1318 { |
|
1319 TUint8* ptr = aDest; |
|
1320 |
|
1321 for (TInt x = 0; x < bytesToCopyPerLine; ++x) |
|
1322 { |
|
1323 TUint red = (GetRed(aSrce[x], aPalette) * 255u) / redMax; |
|
1324 TUint green = (GetGreen(aSrce[x], aPalette) * 255u) / greenMax; |
|
1325 TUint blue = (GetBlue(aSrce[x], aPalette) * 255u) / blueMax; |
|
1326 |
|
1327 TRgb color(red, green, blue); |
|
1328 WritePixelTrueColor(ptr, color, a24Bit); |
|
1329 } |
|
1330 |
|
1331 aDest += aBytesPerDestLine; |
|
1332 aSrce += aBytesPerSrceLine; |
|
1333 } |
|
1334 } |
|
1335 |
|
1336 // --------------------------------------------------------------------------- |
|
1337 // CSwtImage::Copy24 |
|
1338 // --------------------------------------------------------------------------- |
|
1339 // |
|
1340 void CSwtImage::Copy24(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1341 TInt aBytesPerSrceLine, TInt aLineCount, const MSwtPaletteData::TDirectData& aPalette) |
|
1342 { |
|
1343 ASSERT(aDest); |
|
1344 ASSERT(aSrce); |
|
1345 |
|
1346 TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine); |
|
1347 bytesToCopyPerLine -= bytesToCopyPerLine % 3; // In order to have an integer number of pixels |
|
1348 |
|
1349 for (TInt y = 0; y < aLineCount; ++y) |
|
1350 { |
|
1351 TUint8* ptrDest = aDest; |
|
1352 |
|
1353 for (TInt x = 0; x < bytesToCopyPerLine; x += 3) |
|
1354 { |
|
1355 // Data in source buffer in stored MSB first |
|
1356 TUint pixel; |
|
1357 pixel = static_cast<TUint>(aSrce[x]) << 16; |
|
1358 pixel |= static_cast<TUint>(aSrce[x+1]) << 8; |
|
1359 pixel |= static_cast<TUint>(aSrce[x+2]); |
|
1360 |
|
1361 WritePixelTrueColor(ptrDest, pixel, aPalette, ETrue); |
|
1362 } |
|
1363 |
|
1364 aDest += aBytesPerDestLine; |
|
1365 aSrce += aBytesPerSrceLine; |
|
1366 } |
|
1367 } |
|
1368 |
|
1369 // --------------------------------------------------------------------------- |
|
1370 // CSwtImage::Copy32 |
|
1371 // --------------------------------------------------------------------------- |
|
1372 // |
|
1373 void CSwtImage::Copy32(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce, |
|
1374 TInt aBytesPerSrceLine, TInt aLineCount, const MSwtPaletteData::TDirectData& aPalette) |
|
1375 { |
|
1376 ASSERT(aDest); |
|
1377 ASSERT(aSrce); |
|
1378 |
|
1379 TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine); |
|
1380 bytesToCopyPerLine -= bytesToCopyPerLine % 4; // In order to have an integer number of pixels |
|
1381 |
|
1382 for (TInt y = 0; y < aLineCount; ++y) |
|
1383 { |
|
1384 TUint8* ptrDest = aDest; |
|
1385 |
|
1386 for (TInt x = 0; x < bytesToCopyPerLine; x += 4) |
|
1387 { |
|
1388 TUint pixel = 0; |
|
1389 |
|
1390 // Data in source buffer in stored MSB first |
|
1391 pixel = static_cast<TUint>(aSrce[x]) << 24; |
|
1392 pixel |= static_cast<TUint>(aSrce[x+1]) << 16; |
|
1393 pixel |= static_cast<TUint>(aSrce[x+2]) << 8; |
|
1394 pixel |= static_cast<TUint>(aSrce[x+3]); |
|
1395 |
|
1396 WritePixelTrueColor(ptrDest, pixel, aPalette, EFalse); |
|
1397 } |
|
1398 |
|
1399 aDest += aBytesPerDestLine; |
|
1400 aSrce += aBytesPerSrceLine; |
|
1401 } |
|
1402 } |
|
1403 |
|
1404 |
|
1405 // --------------------------------------------------------------------------- |
|
1406 // CSwtImage::GetPixelDataLC |
|
1407 // --------------------------------------------------------------------------- |
|
1408 // |
|
1409 HBufC8* CSwtImage::GetPixelDataLC(const CFbsBitmap& aBitmap) |
|
1410 { |
|
1411 TSize size(aBitmap.SizeInPixels()); |
|
1412 TDisplayMode mode(aBitmap.DisplayMode()); |
|
1413 TInt depth = BitDepth(mode); |
|
1414 TInt bplSrce = CFbsBitmap::ScanLineLength(size.iWidth, mode); |
|
1415 TInt bplDest = BytesPerLine(size.iWidth, depth, ScanlinePadding(depth)); |
|
1416 TInt bufLength = bplDest * size.iHeight; |
|
1417 |
|
1418 HBufC8* buffer = HBufC8::NewLC(bufLength); |
|
1419 TPtr8 des(buffer->Des()); |
|
1420 des.SetLength(bufLength); |
|
1421 TUint8* dest = const_cast<TUint8*>(des.Ptr()); |
|
1422 Mem::FillZ(dest, bufLength); |
|
1423 |
|
1424 aBitmap.LockHeapLC(ETrue); |
|
1425 const TUint8* srce = reinterpret_cast<TUint8*>(aBitmap.DataAddress()); |
|
1426 |
|
1427 switch (mode) |
|
1428 { |
|
1429 case EGray2: |
|
1430 Copy1(dest, bplDest, srce, bplSrce, size.iHeight); |
|
1431 break; |
|
1432 case EGray4: |
|
1433 Copy2(dest, bplDest, srce, bplSrce, size.iHeight); |
|
1434 break; |
|
1435 case EGray16: |
|
1436 Copy4(dest, bplDest, srce, bplSrce, size.iHeight); |
|
1437 break; |
|
1438 case EGray256: |
|
1439 /* This is workaround for case that the image width is not mutliple of four. |
|
1440 The symbian function CFbsBitmap::ScanLineLength() returns muplitple of |
|
1441 four and not the correct size. On the other hand BytesPerLine() returns |
|
1442 the correct size. When using the incorrect size the image is skewed. |
|
1443 Problem occured only on alpha bitmap with PNG images. This is the |
|
1444 reason, why this fix is present only in this switch. Also it does not |
|
1445 occur in 3.2 */ |
|
1446 #if defined( RD_SCALABLE_UI_V2 ) |
|
1447 bplSrce = bplDest; |
|
1448 #endif // RD_SCALABLE_UI_V2 |
|
1449 Copy8(dest, bplDest, srce, bplSrce, size.iHeight); |
|
1450 break; |
|
1451 case EColor64K: |
|
1452 GetPixels16(dest, bplDest, srce, bplSrce, size); |
|
1453 break; |
|
1454 case EColor16M: |
|
1455 Copy8(dest, bplDest, srce, bplSrce, size.iHeight); |
|
1456 break; |
|
1457 case EColor16MU: |
|
1458 Copy8(dest, bplDest, srce, bplSrce, size.iHeight); |
|
1459 break; |
|
1460 case EColor16MA: |
|
1461 Copy8(dest, bplDest, srce, bplSrce, size.iHeight); |
|
1462 break; |
|
1463 case EColor16MAP: |
|
1464 Copy8(dest, bplDest, srce, bplSrce, size.iHeight); |
|
1465 break; |
|
1466 default: |
|
1467 __DEBUGGER(); |
|
1468 User::Leave(KErrNotSupported); |
|
1469 break; |
|
1470 }; |
|
1471 |
|
1472 CleanupStack::PopAndDestroy(); // LockHeap |
|
1473 |
|
1474 return buffer; |
|
1475 } |
|
1476 |
|
1477 // --------------------------------------------------------------------------- |
|
1478 // CSwtImage::GetPixels16 |
|
1479 // --------------------------------------------------------------------------- |
|
1480 // |
|
1481 void CSwtImage::GetPixels16(TUint8* aDest, TInt aBytesPerDestLine, |
|
1482 const TUint8* aSrce, TInt aBytesPerSrceLine, const TSize& aSize) |
|
1483 { |
|
1484 ASSERT(aDest); |
|
1485 ASSERT(aSrce); |
|
1486 |
|
1487 for (TInt y = 0; y<aSize.iHeight; ++y) |
|
1488 { |
|
1489 const TUint16* ptrSrce = reinterpret_cast<const TUint16*>(aSrce); |
|
1490 TUint8* ptrDest = aDest; |
|
1491 |
|
1492 TInt x; |
|
1493 for (x = 0; x<aSize.iWidth; ++x) |
|
1494 { |
|
1495 TUint16 pixel = *ptrSrce++; |
|
1496 |
|
1497 // Data in dest buffer in stored LSB first |
|
1498 *ptrDest++ = static_cast<TUint8>(pixel & 0x00FF); |
|
1499 *ptrDest++ = static_cast<TUint8>(pixel >> 8); |
|
1500 } |
|
1501 |
|
1502 aDest += aBytesPerDestLine; |
|
1503 aSrce += aBytesPerSrceLine; |
|
1504 } |
|
1505 } |
|
1506 |
|
1507 // --------------------------------------------------------------------------- |
|
1508 // CSwtImage::NewGcL |
|
1509 // From MSwtBitmapDrawable |
|
1510 // --------------------------------------------------------------------------- |
|
1511 // |
|
1512 MSwtGc* CSwtImage::NewGcL() |
|
1513 { |
|
1514 ASSERT(iDevice); |
|
1515 ASSERT(iDisplay); |
|
1516 |
|
1517 CFbsBitGc* nativeGc = CFbsBitGc::NewL(); |
|
1518 nativeGc->Activate(iBitmapDevice); |
|
1519 |
|
1520 return iDisplay->Factory().NewBitmapGcL(*this, nativeGc, |
|
1521 DestroyNativeGc, KRgbBlack, KRgbWhite, *iDevice->GetSystemFont()); |
|
1522 } |
|
1523 |
|
1524 // --------------------------------------------------------------------------- |
|
1525 // CSwtImage::GraphicsDevice |
|
1526 // From MSwtBitmapDrawable |
|
1527 // --------------------------------------------------------------------------- |
|
1528 // |
|
1529 CBitmapDevice& CSwtImage::GraphicsDevice() |
|
1530 { |
|
1531 return *iBitmapDevice; |
|
1532 } |
|
1533 |
|
1534 // --------------------------------------------------------------------------- |
|
1535 // CSwtImage::GraphicsDevice |
|
1536 // From MSwtBitmapDrawable |
|
1537 // --------------------------------------------------------------------------- |
|
1538 // |
|
1539 void CSwtImage::HandleUpdate() |
|
1540 { |
|
1541 if (iMaskType == EColorKey) |
|
1542 { |
|
1543 iMaskType = EDirtyColorKey; |
|
1544 } |
|
1545 } |
|
1546 |
|
1547 // --------------------------------------------------------------------------- |
|
1548 // CSwtImage::DestroyNativeGc |
|
1549 // From MSwtBitmapDrawable |
|
1550 // --------------------------------------------------------------------------- |
|
1551 // |
|
1552 void CSwtImage::DestroyNativeGc(CBitmapContext* aGc) |
|
1553 { |
|
1554 delete aGc; |
|
1555 } |
|
1556 |
|
1557 // --------------------------------------------------------------------------- |
|
1558 // CSwtImage::GetBitmap |
|
1559 // From MSwtImage |
|
1560 // --------------------------------------------------------------------------- |
|
1561 // |
|
1562 CFbsBitmap& CSwtImage::GetBitmap() const |
|
1563 { |
|
1564 return *iBitmap; |
|
1565 } |
|
1566 |
|
1567 // --------------------------------------------------------------------------- |
|
1568 // CSwtImage::GetSubBitmap |
|
1569 // From MSwtImage |
|
1570 // --------------------------------------------------------------------------- |
|
1571 // |
|
1572 CFbsBitmap& CSwtImage::GetSubBitmap(const TSize& aSize) const |
|
1573 { |
|
1574 ASSERT(iBitmap); |
|
1575 |
|
1576 // For the original size return the main bitmap |
|
1577 if (iBitmap->SizeInPixels() == aSize) |
|
1578 { |
|
1579 return GetBitmap(); |
|
1580 } |
|
1581 |
|
1582 // Search scaled bitmap copy |
|
1583 CFbsBitmap* bmp = NULL; |
|
1584 TInt count = iScaledBitmaps.Count(); |
|
1585 for (TInt i = 0; i < count; i++) |
|
1586 { |
|
1587 bmp = iScaledBitmaps[i]; |
|
1588 if (bmp->SizeInPixels() == aSize) |
|
1589 { |
|
1590 return *bmp; |
|
1591 } |
|
1592 } |
|
1593 |
|
1594 // Scaled bitmap copy not found, create one for aSize |
|
1595 TRAP_IGNORE(bmp = SwtControlHelper::GetCopyOfBitmapL(iBitmap, aSize)); |
|
1596 if (bmp) |
|
1597 { |
|
1598 // Create also scaled mask copy for aSize |
|
1599 CFbsBitmap* mask = NULL; |
|
1600 CFbsBitmap* maski = NULL; |
|
1601 if (iMask) |
|
1602 { |
|
1603 TRAP_IGNORE(mask = SwtControlHelper::GetCopyOfBitmapL(iMask, aSize)); |
|
1604 if (iMask->IsMonochrome()) |
|
1605 { |
|
1606 TRAP_IGNORE(maski = SwtControlHelper::GetInvertedCopyOfMonoBitmapL(iMask, aSize)); |
|
1607 } |
|
1608 } |
|
1609 |
|
1610 // Update arrays |
|
1611 |
|
1612 // NOTE! iScaledBitmapRefs, iScaledBitmaps, iScaledMasks and |
|
1613 // iScaledMasksInverted must always have the same number of entries. |
|
1614 // NOTE! iScaledMasksInverted entries are valid only if |
|
1615 // the main mask is monochrome. Otherwise they are NULL |
|
1616 // and iScaledMasks entries should be used instead. |
|
1617 TInt err = KErrNone; |
|
1618 TInt appendCount = 0; |
|
1619 err = iScaledBitmapRefs.Append(0); |
|
1620 if (err == KErrNone) |
|
1621 { |
|
1622 ++appendCount; |
|
1623 err = iScaledBitmaps.Append(bmp); |
|
1624 } |
|
1625 if (err == KErrNone) |
|
1626 { |
|
1627 ++appendCount; |
|
1628 err = iScaledMasks.Append(mask); |
|
1629 } |
|
1630 if (err == KErrNone) |
|
1631 { |
|
1632 ++appendCount; |
|
1633 err = iScaledMasksInverted.Append(maski); |
|
1634 } |
|
1635 |
|
1636 if (err) |
|
1637 { |
|
1638 if (appendCount > 0) |
|
1639 { |
|
1640 iScaledBitmapRefs.Remove(iScaledBitmapRefs.Count() - 1); |
|
1641 } |
|
1642 if (appendCount > 1) |
|
1643 { |
|
1644 iScaledBitmaps.Remove(iScaledBitmaps.Count() - 1); |
|
1645 } |
|
1646 if (appendCount > 2) |
|
1647 { |
|
1648 iScaledMasks.Remove(iScaledMasks.Count() - 1); |
|
1649 } |
|
1650 |
|
1651 delete bmp; |
|
1652 bmp = NULL; |
|
1653 delete mask; |
|
1654 mask = NULL; |
|
1655 delete maski; |
|
1656 maski = NULL; |
|
1657 } |
|
1658 } |
|
1659 |
|
1660 if (!bmp) |
|
1661 { |
|
1662 // In the case of no memory or whatever |
|
1663 ASSERT(EFalse); |
|
1664 bmp = &GetBitmap(); |
|
1665 } |
|
1666 |
|
1667 return *bmp; |
|
1668 } |
|
1669 |
|
1670 // --------------------------------------------------------------------------- |
|
1671 // CSwtImage::Dispose |
|
1672 // From MSwtImage |
|
1673 // --------------------------------------------------------------------------- |
|
1674 // |
|
1675 void CSwtImage::Dispose() |
|
1676 { |
|
1677 // Likely reasons for this assertion to fail: |
|
1678 // - The SWT program disposing of its images before the objects that |
|
1679 // reference them; |
|
1680 // - Memory leak in one of the objects referencing the image ( AddRef() was |
|
1681 // called but not RemoveRef() ). |
|
1682 #ifdef ESWT_EARLY_DISPOSAL_CHECKING_ENABLED |
|
1683 ASSERT(RefCount() == 1); |
|
1684 #endif // ESWT_EARLY_DISPOSAL_CHECKING_ENABLED |
|
1685 RemoveRef(); |
|
1686 } |
|
1687 |
|
1688 // --------------------------------------------------------------------------- |
|
1689 // CSwtImage::MaskBitmap |
|
1690 // From MSwtImage |
|
1691 // --------------------------------------------------------------------------- |
|
1692 // |
|
1693 const CFbsBitmap* CSwtImage::MaskBitmap(TBool aInvertedIfMonochrome /*= EFalse*/) const |
|
1694 { |
|
1695 EnsureMaskIsUpToDate(); |
|
1696 CFbsBitmap* mask = iMask; |
|
1697 if (mask && aInvertedIfMonochrome && mask->IsMonochrome()) |
|
1698 { |
|
1699 if (!iMaskInverted) |
|
1700 { |
|
1701 TRAP_IGNORE(iMaskInverted = SwtControlHelper::GetInvertedCopyOfMonoBitmapL(mask)); |
|
1702 } |
|
1703 mask = iMaskInverted; |
|
1704 } |
|
1705 return mask; |
|
1706 } |
|
1707 |
|
1708 // --------------------------------------------------------------------------- |
|
1709 // CSwtImage::SubMaskBitmap |
|
1710 // From MSwtImage |
|
1711 // --------------------------------------------------------------------------- |
|
1712 // |
|
1713 const CFbsBitmap* CSwtImage::SubMaskBitmap(const TSize& aSize, |
|
1714 TBool aInvertedIfMonochrome /*= EFalse*/) const |
|
1715 { |
|
1716 ASSERT(iBitmap); |
|
1717 |
|
1718 // For the original size return the main mask |
|
1719 if (iBitmap->SizeInPixels() == aSize) |
|
1720 { |
|
1721 return MaskBitmap(aInvertedIfMonochrome); |
|
1722 } |
|
1723 |
|
1724 // Find scaled copy of the bitmap and return its scaled mask. |
|
1725 CFbsBitmap* bmp = NULL; |
|
1726 CFbsBitmap* mask = NULL; |
|
1727 TInt count = iScaledBitmaps.Count(); |
|
1728 for (TInt i = 0; i < count; i++) |
|
1729 { |
|
1730 bmp = iScaledBitmaps[i]; |
|
1731 if (bmp && bmp->SizeInPixels() == aSize) |
|
1732 { |
|
1733 mask = iScaledMasks[i]; |
|
1734 if (mask && aInvertedIfMonochrome && mask->IsMonochrome()) |
|
1735 { |
|
1736 // NOTE! iScaledMasksInverted entries are valid only if |
|
1737 // the main mask is monochrome. Otherwise they are NULL |
|
1738 // and iScaledMasks entries should be used instead. |
|
1739 mask = iScaledMasksInverted[i]; |
|
1740 } |
|
1741 return mask; |
|
1742 } |
|
1743 } |
|
1744 |
|
1745 return mask; |
|
1746 } |
|
1747 |
|
1748 // --------------------------------------------------------------------------- |
|
1749 // CSwtImage::GetBounds |
|
1750 // From MSwtImage |
|
1751 // --------------------------------------------------------------------------- |
|
1752 // |
|
1753 TRect CSwtImage::GetBounds() const |
|
1754 { |
|
1755 return TRect(iBitmap->SizeInPixels()); |
|
1756 } |
|
1757 |
|
1758 // --------------------------------------------------------------------------- |
|
1759 // CSwtImage::GetImageDataL |
|
1760 // From MSwtImage |
|
1761 // --------------------------------------------------------------------------- |
|
1762 // |
|
1763 MSwtImageData* CSwtImage::GetImageDataL() const |
|
1764 { |
|
1765 // Get the palette |
|
1766 CSwtGrPaletteData* paletteData = GetPaletteDataL(); |
|
1767 CleanupStack::PushL(paletteData); |
|
1768 |
|
1769 // Get the buffers |
|
1770 HBufC8* pixelData = GetPixelDataLC(*iBitmap); |
|
1771 HBufC8* maskData = NULL; |
|
1772 if (iMaskType == EBinaryMask) |
|
1773 { |
|
1774 ASSERT(iMask); |
|
1775 maskData = GetPixelDataLC(*iMask); |
|
1776 } |
|
1777 |
|
1778 HBufC8* alphaData = NULL; |
|
1779 if (iMaskType == EAlphaMask) |
|
1780 { |
|
1781 ASSERT(iMask); |
|
1782 alphaData = GetPixelDataLC(*iMask); |
|
1783 } |
|
1784 |
|
1785 // Prepare the information |
|
1786 MSwtImageData::TInfo info; |
|
1787 info.iSize = iInfo.iSize; |
|
1788 info.iDepth = BitDepth(iBitmap->DisplayMode()); |
|
1789 info.iScanlinePad = ScanlinePadding(info.iDepth); |
|
1790 info.iBytesPerLine = BytesPerLine(info.iSize.iWidth, info.iDepth, |
|
1791 info.iScanlinePad); |
|
1792 info.iMaskPad = (maskData) ? ScanlinePadding(1) : 0; |
|
1793 info.iAlpha = iInfo.iAlpha; |
|
1794 info.iType = iInfo.iType; |
|
1795 info.iTopLeft = iInfo.iTopLeft; |
|
1796 info.iDisposalMethod = iInfo.iDisposalMethod; |
|
1797 info.iDelayTime = iInfo.iDelayTime; |
|
1798 |
|
1799 if (!iColorKey) |
|
1800 { |
|
1801 info.iTransparentPixel = -1; |
|
1802 } |
|
1803 else |
|
1804 { |
|
1805 if (paletteData->IsDirect()) |
|
1806 { |
|
1807 const MSwtPaletteData::TDirectData& directData = |
|
1808 paletteData->DirectData(); |
|
1809 TUint r = BitShift(iColorKey->Red(), |
|
1810 - directData.iRedShift) & directData.iRedMask; |
|
1811 TUint g = BitShift(iColorKey->Green(), |
|
1812 - directData.iGreenShift) & directData.iGreenMask; |
|
1813 TUint b = BitShift(iColorKey->Blue(), |
|
1814 - directData.iBlueShift) & directData.iBlueMask; |
|
1815 info.iTransparentPixel = r | g | b; |
|
1816 } |
|
1817 else |
|
1818 { |
|
1819 info.iTransparentPixel = paletteData->IndirectData()-> |
|
1820 NearestIndex(*iColorKey); |
|
1821 } |
|
1822 } |
|
1823 |
|
1824 if (alphaData) |
|
1825 { |
|
1826 CleanupStack::Pop(alphaData); |
|
1827 } |
|
1828 if (maskData) |
|
1829 { |
|
1830 CleanupStack::Pop(maskData); |
|
1831 } |
|
1832 CleanupStack::Pop(pixelData); |
|
1833 CleanupStack::Pop(paletteData); |
|
1834 |
|
1835 return CSwtGrImageData::NewL(info, paletteData, pixelData, maskData, alphaData); |
|
1836 } |
|
1837 |
|
1838 // --------------------------------------------------------------------------- |
|
1839 // CSwtImage::AddSubRef |
|
1840 // From MSwtImage |
|
1841 // --------------------------------------------------------------------------- |
|
1842 // |
|
1843 TInt CSwtImage::AddSubRef(const TSize& aSize) const |
|
1844 { |
|
1845 ASSERT(iBitmap); |
|
1846 if (iBitmap->SizeInPixels() == aSize) |
|
1847 { |
|
1848 AddRef(); |
|
1849 return KErrNone; |
|
1850 } |
|
1851 |
|
1852 CFbsBitmap* bmp = NULL; |
|
1853 TInt count = iScaledBitmaps.Count(); |
|
1854 for (TInt i = 0; i < count; i++) |
|
1855 { |
|
1856 bmp = iScaledBitmaps[i]; |
|
1857 if (bmp && bmp->SizeInPixels() == aSize) |
|
1858 { |
|
1859 iScaledBitmapRefs[i]++; // mutable |
|
1860 return KErrNone; |
|
1861 } |
|
1862 } |
|
1863 return KErrNotFound; |
|
1864 } |
|
1865 |
|
1866 // --------------------------------------------------------------------------- |
|
1867 // CSwtImage::RemoveSubRef |
|
1868 // From MSwtImage |
|
1869 // --------------------------------------------------------------------------- |
|
1870 // |
|
1871 TInt CSwtImage::RemoveSubRef(const TSize& aSize) const |
|
1872 { |
|
1873 ASSERT(iBitmap); |
|
1874 if (iBitmap->SizeInPixels() == aSize) |
|
1875 { |
|
1876 RemoveRef(); |
|
1877 return KErrNone; |
|
1878 } |
|
1879 |
|
1880 CFbsBitmap* bmp = NULL; |
|
1881 CFbsBitmap* mask = NULL; |
|
1882 CFbsBitmap* maski = NULL; |
|
1883 TInt count = iScaledBitmaps.Count(); |
|
1884 for (TInt i = 0; i < count; i++) |
|
1885 { |
|
1886 // NOTE! iScaledBitmapRefs, iScaledBitmaps, iScaledMasks and |
|
1887 // iScaledMasksInverted must always have the same number of entries. |
|
1888 // NOTE! iScaledMasksInverted entries are valid only if |
|
1889 // the main mask is monochrome. Otherwise they are NULL |
|
1890 // and iScaledMasks entries should be used instead. |
|
1891 bmp = iScaledBitmaps[i]; |
|
1892 mask = iScaledMasks[i]; |
|
1893 maski = iScaledMasksInverted[i]; |
|
1894 if (bmp && bmp->SizeInPixels() == aSize) |
|
1895 { |
|
1896 iScaledBitmapRefs[i]--; // mutable |
|
1897 if (iScaledBitmapRefs[i] == 0) |
|
1898 { |
|
1899 delete bmp; |
|
1900 delete mask; |
|
1901 delete maski; |
|
1902 iScaledMasks.Remove(i); |
|
1903 iScaledMasksInverted.Remove(i); |
|
1904 iScaledBitmaps.Remove(i); |
|
1905 iScaledBitmapRefs.Remove(i); |
|
1906 } |
|
1907 return KErrNone; |
|
1908 } |
|
1909 } |
|
1910 return KErrNotFound; |
|
1911 } |
|
1912 |
|
1913 // --------------------------------------------------------------------------- |
|
1914 // CSwtImage::SubRefCount |
|
1915 // From MSwtImage |
|
1916 // --------------------------------------------------------------------------- |
|
1917 // |
|
1918 TInt CSwtImage::SubRefCount(const TSize& aSize) const |
|
1919 { |
|
1920 ASSERT(iBitmap); |
|
1921 if (iBitmap->SizeInPixels() == aSize) |
|
1922 { |
|
1923 return RefCount(); |
|
1924 } |
|
1925 |
|
1926 CFbsBitmap* bmp = NULL; |
|
1927 TInt count = iScaledBitmaps.Count(); |
|
1928 for (TInt i = 0; i < count; i++) |
|
1929 { |
|
1930 bmp = iScaledBitmaps[i]; |
|
1931 if (bmp && bmp->SizeInPixels() == aSize) |
|
1932 { |
|
1933 return iScaledBitmapRefs[i]; |
|
1934 } |
|
1935 } |
|
1936 return 0; |
|
1937 } |
|
1938 |
|
1939 |
|
1940 // --------------------------------------------------------------------------- |
|
1941 // CSwtImage::BitmapWithAlphaLC |
|
1942 // From MSwtImage |
|
1943 // --------------------------------------------------------------------------- |
|
1944 // |
|
1945 CFbsBitmap* CSwtImage::BitmapWithAlphaLC() |
|
1946 { |
|
1947 |
|
1948 ASSERT(iMask); |
|
1949 ASSERT(iBitmap); |
|
1950 |
|
1951 |
|
1952 // Create the bitmap |
|
1953 CFbsBitmap* bitmap = new(ELeave) CFbsBitmap; |
|
1954 CleanupStack::PushL(bitmap); |
|
1955 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
1956 User::LeaveIfError(bitmap->Create(iBitmap->SizeInPixels(), EColor16MAP)); |
|
1957 #else |
|
1958 User::LeaveIfError(bitmap->Create(iBitmap->SizeInPixels(), EColor16MA)); |
|
1959 #endif //RD_JAVA_S60_RELEASE_9_2 |
|
1960 |
|
1961 |
|
1962 // Create bitmap mask |
|
1963 CFbsBitmap* mask = new(ELeave) CFbsBitmap; |
|
1964 CleanupStack::PushL(mask); |
|
1965 User::LeaveIfError(mask->Create(iMask->SizeInPixels(), EGray256)); |
|
1966 |
|
1967 // copy bitmap |
|
1968 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap); |
|
1969 CleanupStack::PushL(bitmapDevice); |
|
1970 BitBltBitmapL(*bitmapDevice, *iBitmap); |
|
1971 CleanupStack::PopAndDestroy(bitmapDevice); |
|
1972 |
|
1973 // copy bitmap mask |
|
1974 CFbsBitmapDevice* maskDevice = CFbsBitmapDevice::NewL(mask); |
|
1975 CleanupStack::PushL(maskDevice); |
|
1976 BitBltBitmapL(*maskDevice, *iMask); |
|
1977 CleanupStack::PopAndDestroy(maskDevice); |
|
1978 |
|
1979 // add mask to alpha bitmap's alpha channel |
|
1980 AddMaskToAlphaChannel(*bitmap, *mask); |
|
1981 CleanupStack::PopAndDestroy(mask); |
|
1982 return bitmap; |
|
1983 } |
|
1984 |
|
1985 |
|
1986 // --------------------------------------------------------------------------- |
|
1987 // CSwtImage::OfferResourceChangeL |
|
1988 // From MSwtResourceChangeObserver |
|
1989 // --------------------------------------------------------------------------- |
|
1990 // |
|
1991 void CSwtImage::OfferResourceChangeL(TInt /*aType*/) |
|
1992 { |
|
1993 ASSERT(iDevice); |
|
1994 |
|
1995 // We set new twips size of bitmap in case device resolution has changed |
|
1996 iBitmap->SetSizeInTwips(&(iDevice->GraphicsDevice())); |
|
1997 } |