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