|
1 /* |
|
2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Icon loading from MIF files. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <gdi.h> |
|
22 #include "AknIconLoader.h" |
|
23 #include "AknIconLocationInfo.h" |
|
24 #include <mifconvdefs.h> |
|
25 |
|
26 // CONSTANTS |
|
27 |
|
28 // ============================ GLOBAL FUNCTIONS =============================== |
|
29 |
|
30 GLDEF_C void CleanupFreeIcon( TAny* aObj ) |
|
31 { |
|
32 static_cast<CAknIconLoader*>( aObj )->FreeIcon(); |
|
33 } |
|
34 |
|
35 // ============================ MEMBER FUNCTIONS =============================== |
|
36 |
|
37 // ----------------------------------------------------------------------------- |
|
38 // CAknIconLoader::CAknIconLoader |
|
39 // C++ default constructor can NOT contain any code, that |
|
40 // might leave. |
|
41 // ----------------------------------------------------------------------------- |
|
42 // |
|
43 CAknIconLoader::CAknIconLoader() : iIconId( -1 ) |
|
44 { |
|
45 #ifdef _NGATESTING |
|
46 iConfigIconType = -1; |
|
47 #endif |
|
48 } |
|
49 |
|
50 CAknIconLoader* CAknIconLoader::NewL( RFs& aFs, const TDesC& aFileName ) |
|
51 { |
|
52 CAknIconLoader* self = new( ELeave ) CAknIconLoader; |
|
53 CleanupStack::PushL( self ); |
|
54 self->ConstructL( aFs, aFileName ); |
|
55 CleanupStack::Pop(); |
|
56 return self; |
|
57 } |
|
58 |
|
59 // Opened file handle as parameter. |
|
60 CAknIconLoader* CAknIconLoader::NewL( RFile& aFile ) |
|
61 { |
|
62 CAknIconLoader* self = new( ELeave ) CAknIconLoader; |
|
63 CleanupStack::PushL( self ); |
|
64 self->ConstructL( aFile ); |
|
65 CleanupStack::Pop(); |
|
66 return self; |
|
67 } |
|
68 |
|
69 void CAknIconLoader::ConstructL( RFs& aFs, const TDesC& aFileName ) |
|
70 { |
|
71 OpenFileL( aFs, aFileName ); |
|
72 } |
|
73 |
|
74 void CAknIconLoader::ConstructL( RFile& aFile ) |
|
75 { |
|
76 OpenFileL( aFile ); |
|
77 } |
|
78 |
|
79 // Destructor |
|
80 CAknIconLoader::~CAknIconLoader() |
|
81 { |
|
82 iFile.Close(); |
|
83 delete iOffsets; |
|
84 delete iSharedOffsets; |
|
85 delete iIcon; |
|
86 delete iCdlEngine; |
|
87 } |
|
88 |
|
89 // ----------------------------------------------------------------------------- |
|
90 // CAknIconLoader::OpenFileL |
|
91 // ----------------------------------------------------------------------------- |
|
92 // |
|
93 void CAknIconLoader::OpenFileL( RFs& aFs, const TDesC& aFileName ) |
|
94 { |
|
95 iFile.Close(); |
|
96 User::LeaveIfError( iFile.Open( aFs, aFileName, EFileRead|EFileShareReadersOnly ) ); |
|
97 } |
|
98 |
|
99 // ----------------------------------------------------------------------------- |
|
100 // CAknIconLoader::OpenFileL |
|
101 // ----------------------------------------------------------------------------- |
|
102 // |
|
103 void CAknIconLoader::OpenFileL( RFile& aFile ) |
|
104 { |
|
105 iFile.Close(); |
|
106 User::LeaveIfError( iFile.Duplicate( aFile ) ); |
|
107 } |
|
108 |
|
109 // ----------------------------------------------------------------------------- |
|
110 // CAknIconLoader::CloseFile |
|
111 // ----------------------------------------------------------------------------- |
|
112 // |
|
113 void CAknIconLoader::CloseFile() |
|
114 { |
|
115 iFile.Close(); |
|
116 } |
|
117 |
|
118 // ----------------------------------------------------------------------------- |
|
119 // CAknIconLoader::FileHeaderStructL |
|
120 // ----------------------------------------------------------------------------- |
|
121 // |
|
122 void CAknIconLoader::LoadFileHeaderStructL() |
|
123 { |
|
124 if ( !iHeader.iV1.iUid ) |
|
125 { |
|
126 TPckg<TMifFileHeaderV1> v1(iHeader.iV1); |
|
127 User::LeaveIfError( iFile.Read( 0, v1, sizeof( TMifFileHeaderV1 ) ) ); |
|
128 |
|
129 if (iHeader.iV1.iVersion >= 3) |
|
130 { |
|
131 TPckg<TMifFileHeaderV3> v3(iHeader.iV3); |
|
132 User::LeaveIfError( iFile.Read( v3, sizeof( TMifFileHeaderV3 ) ) ); |
|
133 } |
|
134 } |
|
135 } |
|
136 |
|
137 // ----------------------------------------------------------------------------- |
|
138 // CAknIconLoader::CheckFileL |
|
139 // ----------------------------------------------------------------------------- |
|
140 // |
|
141 void CAknIconLoader::CheckFileL() |
|
142 { |
|
143 LoadFileHeaderStructL(); |
|
144 |
|
145 if ( iHeader.iV1.iUid != KUidAvkonMultiIconFile || |
|
146 iHeader.iV1.iVersion < KMifFirstSupportedVersion || |
|
147 iHeader.iV1.iVersion > KMifLastSupportedVersion ) |
|
148 { |
|
149 #ifdef _DEBUG |
|
150 RDebug::Print(_L("AknIconLoader: Icon file corrupt; file format error!")); |
|
151 #endif |
|
152 |
|
153 User::Leave( KErrCorrupt ); |
|
154 } |
|
155 } |
|
156 |
|
157 |
|
158 // ----------------------------------------------------------------------------- |
|
159 // CAknIconLoader::LoadSharedOffsetsL |
|
160 // ----------------------------------------------------------------------------- |
|
161 // |
|
162 void CAknIconLoader::LoadSharedOffsetsL() |
|
163 { |
|
164 if (!CdlEngine::IsCdlEngineCreated()) |
|
165 iCdlEngine = CdlEngine::CreateCdlEngineL(); |
|
166 |
|
167 TBuf<12> dllName; |
|
168 _LIT(KDllNameFormat,"%08x.DLL"); |
|
169 dllName.Format(KDllNameFormat, iHeader.iV3.iIndexDllUid); |
|
170 iSharedOffsets = MifHeader::CInstance::NewL(dllName, 0); // MifHeader DLLs only ever have one instance, and that has id 0 |
|
171 } |
|
172 |
|
173 // ----------------------------------------------------------------------------- |
|
174 // CAknIconLoader::LoadOffsetsFromMifL |
|
175 // ----------------------------------------------------------------------------- |
|
176 // |
|
177 void CAknIconLoader::LoadOffsetsFromMifL() |
|
178 { |
|
179 TInt pos = iHeader.iV1.iArrayOffset; |
|
180 TInt length = iHeader.iV1.iArrayLength; |
|
181 HBufC8* offsets = HBufC8::NewL( sizeof( TMifBitmapOffsetElement ) * length ); |
|
182 CleanupStack::PushL( offsets ); |
|
183 TPtr8 ptr = offsets->Des(); |
|
184 |
|
185 User::LeaveIfError( iFile.Read( |
|
186 pos, ptr, sizeof( TMifBitmapOffsetElement ) * length ) ); |
|
187 |
|
188 if ( TUint( ptr.Length() ) != sizeof( TMifBitmapOffsetElement ) * length ) |
|
189 { |
|
190 #ifdef _DEBUG |
|
191 RDebug::Print(_L("AknIconLoader: Icon file corrupt; EOF at offsets!")); |
|
192 #endif |
|
193 |
|
194 User::Leave( KErrCorrupt ); |
|
195 } |
|
196 |
|
197 CleanupStack::Pop(); // offsets |
|
198 iOffsets = offsets; |
|
199 } |
|
200 |
|
201 // ----------------------------------------------------------------------------- |
|
202 // CAknIconLoader::BitmapOffsetsL |
|
203 // ----------------------------------------------------------------------------- |
|
204 // |
|
205 const TMifBitmapOffsetElement* CAknIconLoader::BitmapOffsetsL() |
|
206 { |
|
207 if ( !iOffsets && !iSharedOffsets ) |
|
208 { |
|
209 CheckFileL(); |
|
210 |
|
211 LoadFileHeaderStructL(); |
|
212 if (iHeader.iV1.iVersion == 3) |
|
213 LoadSharedOffsetsL(); |
|
214 else |
|
215 LoadOffsetsFromMifL(); |
|
216 } |
|
217 |
|
218 if (iOffsets) |
|
219 return (TMifBitmapOffsetElement*)iOffsets->Ptr(); |
|
220 else |
|
221 return &iSharedOffsets->indicies()[0]; |
|
222 } |
|
223 |
|
224 // ----------------------------------------------------------------------------- |
|
225 // CAknIconLoader::BitmapOffsetsArrayL |
|
226 // ----------------------------------------------------------------------------- |
|
227 // |
|
228 const TMifBitmapOffsetElement* CAknIconLoader::BitmapOffsetsArrayL() |
|
229 { |
|
230 return BitmapOffsetsL(); |
|
231 } |
|
232 |
|
233 // ----------------------------------------------------------------------------- |
|
234 // CAknIconLoader::IconWithHeaderL |
|
235 // ----------------------------------------------------------------------------- |
|
236 // |
|
237 TPtrC8 CAknIconLoader::IconWithHeaderL( TInt aId ) |
|
238 { |
|
239 if ( iIconId == aId ) |
|
240 { |
|
241 return iIcon->Des(); |
|
242 } |
|
243 |
|
244 LoadFileHeaderStructL(); |
|
245 |
|
246 TInt usedId = iHeader.iV1.iVersion == 1 ? aId / 2 : aId; |
|
247 |
|
248 if ( usedId < 0 || usedId >= iHeader.iV1.iArrayLength ) |
|
249 { |
|
250 #ifdef _DEBUG |
|
251 RDebug::Print(_L("AknIconLoader: Icon ID not found!")); |
|
252 #endif |
|
253 |
|
254 // Consistent error code with MBM loading. |
|
255 User::Leave( KErrEof ); |
|
256 } |
|
257 |
|
258 const TMifBitmapOffsetElement* ptr = BitmapOffsetsArrayL(); |
|
259 TUint32 offset = ptr[usedId].iOffset; |
|
260 if (((TInt32)offset) < 0) |
|
261 { |
|
262 #ifdef _DEBUG |
|
263 RDebug::Print(_L("AknIconLoader: Icon file corrupt; Negative offset!")); |
|
264 #endif |
|
265 User::Leave( KErrCorrupt ); |
|
266 } |
|
267 |
|
268 TUint32 length = ptr[usedId].iLength; |
|
269 |
|
270 delete iIcon; |
|
271 iIcon = NULL; |
|
272 iIcon = HBufC8::NewL( length ); |
|
273 |
|
274 TPtr8 ptr2 = iIcon->Des(); |
|
275 User::LeaveIfError( iFile.Read( offset, ptr2, length ) ); |
|
276 |
|
277 if ( TUint( ptr2.Length() ) != length ) |
|
278 { |
|
279 #ifdef _DEBUG |
|
280 RDebug::Print(_L("AknIconLoader: Icon file corrupt; EOF at icon!")); |
|
281 #endif |
|
282 |
|
283 User::Leave( KErrCorrupt ); |
|
284 } |
|
285 |
|
286 iIconId = aId; |
|
287 return iIcon->Des(); |
|
288 } |
|
289 |
|
290 // ----------------------------------------------------------------------------- |
|
291 // CAknIconLoader::CheckIconL |
|
292 // ----------------------------------------------------------------------------- |
|
293 // |
|
294 void CAknIconLoader::CheckIconL( TInt aId ) |
|
295 { |
|
296 TMifIconHeader* header = (TMifIconHeader*)IconWithHeaderL( aId ).Ptr(); |
|
297 |
|
298 if ( header->iUid != KUidAvkonMultiIcon || |
|
299 header->iVersion < KMifIconFirstSupportedVersion || |
|
300 header->iVersion > KMifIconLastSupportedVersion ) |
|
301 { |
|
302 #ifdef _DEBUG |
|
303 RDebug::Print(_L("AknIconLoader: Icon file corrupt; icon format error!")); |
|
304 #endif |
|
305 |
|
306 User::Leave( KErrCorrupt ); |
|
307 } |
|
308 } |
|
309 |
|
310 // ----------------------------------------------------------------------------- |
|
311 // CAknIconLoader::IconHeaderL |
|
312 // ----------------------------------------------------------------------------- |
|
313 // |
|
314 TMifIconHeader* CAknIconLoader::IconHeaderL( TInt aId ) |
|
315 { |
|
316 CheckIconL( aId ); |
|
317 |
|
318 TPtrC8 icon = IconWithHeaderL( aId ); |
|
319 return (TMifIconHeader*)icon.Ptr(); |
|
320 } |
|
321 |
|
322 // ----------------------------------------------------------------------------- |
|
323 // CAknIconLoader::IconL |
|
324 // ----------------------------------------------------------------------------- |
|
325 // |
|
326 TPtrC8 CAknIconLoader::IconL( TInt aId ) |
|
327 { |
|
328 CheckIconL( aId ); |
|
329 |
|
330 TPtrC8 icon = IconWithHeaderL( aId ); |
|
331 TMifIconHeader* header = IconHeaderL( aId ); |
|
332 icon.Set( icon.Mid( header->iDataOffset, header->iDataLength ) ); |
|
333 return icon; |
|
334 } |
|
335 #ifdef _NGATESTING |
|
336 void CAknIconLoader::SetIconTypeConfig(TInt32 aConfigIconType, const TDesC & aNGATestDirectory) |
|
337 { |
|
338 iConfigIconType = aConfigIconType; |
|
339 iNGADirectory.Copy(aNGATestDirectory); |
|
340 } |
|
341 |
|
342 TInt32 CAknIconLoader::GetDerivedIconTypeL(TInt32 aType, const TDesC & aMifFileName) |
|
343 { |
|
344 if (aType != EIconFormatBMP && |
|
345 aType != EIconFormatNVG) |
|
346 { |
|
347 if (iConfigIconType != -1) |
|
348 { |
|
349 aType = iConfigIconType; |
|
350 } |
|
351 |
|
352 if (aType != EIconFormatNGA) |
|
353 { |
|
354 TInt NGADirectoryLength = iNGADirectory.Length(); |
|
355 if ( NGADirectoryLength > 0 && |
|
356 NGADirectoryLength < aMifFileName.Length() && |
|
357 aMifFileName.Left(NGADirectoryLength).CompareF(iNGADirectory) == 0 ) |
|
358 { |
|
359 aType = EIconFormatNGA; |
|
360 } |
|
361 } |
|
362 } |
|
363 |
|
364 return aType; |
|
365 } |
|
366 #endif |
|
367 |
|
368 // ----------------------------------------------------------------------------- |
|
369 // CAknIconLoader::IconTypeL |
|
370 // ----------------------------------------------------------------------------- |
|
371 // |
|
372 TInt32 CAknIconLoader::IconTypeL( TInt aId ) |
|
373 { |
|
374 TMifIconHeader* header = IconHeaderL( aId ); |
|
375 return header->iType; |
|
376 } |
|
377 |
|
378 // ----------------------------------------------------------------------------- |
|
379 // CAknIconLoader::IconDepthL |
|
380 // ----------------------------------------------------------------------------- |
|
381 // |
|
382 TInt32 CAknIconLoader::IconDepthL( TInt aId ) |
|
383 { |
|
384 TMifIconHeader* header = IconHeaderL( aId ); |
|
385 return header->iDepth; |
|
386 } |
|
387 |
|
388 // ----------------------------------------------------------------------------- |
|
389 // CAknIconLoader::MaskDepthL |
|
390 // ----------------------------------------------------------------------------- |
|
391 // |
|
392 TInt32 CAknIconLoader::MaskDepthL( TInt aId ) |
|
393 { |
|
394 TMifIconHeader* header = IconHeaderL( aId ); |
|
395 return header->iMaskDepth; |
|
396 } |
|
397 |
|
398 // ----------------------------------------------------------------------------- |
|
399 // CAknIconLoader::IconAnimatedL |
|
400 // ----------------------------------------------------------------------------- |
|
401 // |
|
402 TInt32 CAknIconLoader::IconAnimatedL( TInt aId ) |
|
403 { |
|
404 TMifIconHeader* header = IconHeaderL( aId ); |
|
405 return header->iAnimated; |
|
406 } |
|
407 |
|
408 // ----------------------------------------------------------------------------- |
|
409 // CAknIconLoader::FreeIcon |
|
410 // ----------------------------------------------------------------------------- |
|
411 // |
|
412 void CAknIconLoader::FreeIcon() |
|
413 { |
|
414 iIconId = -1; |
|
415 delete iIcon; |
|
416 iIcon = NULL; |
|
417 } |
|
418 |
|
419 // ----------------------------------------------------------------------------- |
|
420 // CAknIconLoader::LoadIconLocationInfoL |
|
421 // ----------------------------------------------------------------------------- |
|
422 // |
|
423 CAknIconLocationInfo* CAknIconLoader::LoadIconLocationInfoL( |
|
424 const TDesC& aFileName ) |
|
425 { |
|
426 CheckFileL(); |
|
427 |
|
428 // First check whether this is v1 or v2 MIF file. |
|
429 LoadFileHeaderStructL(); |
|
430 |
|
431 if ( iHeader.iV1.iVersion == 1 ) |
|
432 { |
|
433 // V1, no location info array as parameter. |
|
434 return CAknIconLocationInfo::NewL( aFileName ); |
|
435 } |
|
436 |
|
437 // V2+ MIF file, load the location info array. |
|
438 BitmapOffsetsL(); |
|
439 if (iOffsets) |
|
440 return CAknIconLocationInfo::NewL( aFileName, *iOffsets ); |
|
441 else |
|
442 return CAknIconLocationInfo::NewL( aFileName, *iSharedOffsets ); |
|
443 } |
|
444 |
|
445 // End of File |