|
1 /* |
|
2 * Copyright (c) 2005 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: This file implements the read codec for the SVG presentation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "SVGCodec.h" |
|
20 |
|
21 // INCLUDE FILES |
|
22 #include <uri16.h> |
|
23 #include <coeutils.h> |
|
24 #include <SVGEngineInterfaceImpl.h> |
|
25 #include <gdi.h> |
|
26 #include <pathconfiguration.hrh> |
|
27 // User Includes |
|
28 #include <SVGTUIControlDbgFlags.hrh> |
|
29 #include <imcvcodc.h> |
|
30 #include <utf.h> |
|
31 |
|
32 #ifdef RD_MULTIPLE_DRIVE |
|
33 #include <pathinfo.h> |
|
34 #include <driveinfo.h> |
|
35 #endif |
|
36 |
|
37 // General Constants |
|
38 const TInt KSccConstZero = 0; |
|
39 const TUint KSccBackground = 0xffffffff; |
|
40 // SMIL Fit Value |
|
41 _LIT( KSccSmilFitValue,"meet" ); |
|
42 |
|
43 // |
|
44 _LIT( KWww, "www" ); |
|
45 _LIT( KHttp, "http://"); |
|
46 _LIT( KDotDot, ".." ); |
|
47 _LIT( KBSlashStr, "/" ); |
|
48 _LIT( KSlashStr, "\\" ); |
|
49 _LIT( KDotSlashStr, ".\\" ); |
|
50 _LIT( KColonStr, ":" ); |
|
51 |
|
52 _LIT(KJpg, ".jpg" ); |
|
53 _LIT(KJpeg, ".jpeg" ); |
|
54 _LIT(KPng, ".png" ); |
|
55 _LIT(KBmp, ".bmp" ); |
|
56 _LIT(KSvg, ".svg" ); |
|
57 _LIT(KSvgz, ".svgz" ); |
|
58 // |
|
59 |
|
60 enum TSVGCodecPanic |
|
61 { |
|
62 ECouldNotGenerateThumbnail |
|
63 }; |
|
64 |
|
65 // ============================ MEMBER FUNCTIONS =============================== |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // CSvgReadCodec::CSvgReadCodec |
|
69 // Default constructor. |
|
70 // ----------------------------------------------------------------------------- |
|
71 // |
|
72 CSvgReadCodec::CSvgReadCodec( const TSize& aSize ): iImagesPresent(EFalse), |
|
73 iImagesLoaded (EFalse), |
|
74 iOriginalSize(aSize) |
|
75 |
|
76 { |
|
77 } |
|
78 |
|
79 // ----------------------------------------------------------------------------- |
|
80 // CSvgReadCodec::NewL |
|
81 // Static constructor. Returns the pointer to the CSvgReadCodec |
|
82 // ----------------------------------------------------------------------------- |
|
83 // |
|
84 CSvgReadCodec* CSvgReadCodec::NewL( const TSize& aSize ) |
|
85 { |
|
86 CSvgReadCodec* self = new(ELeave) CSvgReadCodec( aSize ); |
|
87 CleanupStack::PushL(self); |
|
88 self->ConstructL(); |
|
89 CleanupStack::Pop(self); |
|
90 return self; |
|
91 } |
|
92 |
|
93 void CSvgReadCodec::ConstructL() |
|
94 { |
|
95 iSvgModule = NULL; |
|
96 iSVGTBitMapDummy = NULL; |
|
97 InitializeEngineL(); |
|
98 } |
|
99 |
|
100 void CSvgReadCodec::InitializeEngineL() |
|
101 { |
|
102 if ( !iSvgModule ) |
|
103 { |
|
104 TFontSpec spec; |
|
105 |
|
106 if ( !iSVGTBitMapDummy ) |
|
107 { |
|
108 // For thumbnails, the user provided bitmap is used, |
|
109 // Have to give some dummy bitmap to the engine in the constructor. |
|
110 iSVGTBitMapDummy = new( ELeave ) CFbsBitmap; |
|
111 User::LeaveIfError( |
|
112 iSVGTBitMapDummy->Create( |
|
113 TSize( KSccConstZero, KSccConstZero ), |
|
114 EGray2 ) ); |
|
115 } |
|
116 |
|
117 iSvgModule = CSvgEngineInterfaceImpl::NewL( iSVGTBitMapDummy, this, spec ); |
|
118 // 0xffffffff is the default color. |
|
119 iSvgModule->SetBackgroundColor( KSccBackground ); |
|
120 iSvgModule->AddListener(static_cast<MSvgLoadingListener*>(this), |
|
121 ESvgLoadingListener); |
|
122 |
|
123 } |
|
124 } |
|
125 |
|
126 // ----------------------------------------------------------------------------- |
|
127 // CSvgReadCodec::~CSvgReadCodec |
|
128 // Destructor |
|
129 // ----------------------------------------------------------------------------- |
|
130 // |
|
131 CSvgReadCodec::~CSvgReadCodec() |
|
132 { |
|
133 DeleteEngine(); |
|
134 |
|
135 // Dummy bitmap |
|
136 delete iSVGTBitMapDummy; |
|
137 |
|
138 // SVG file data |
|
139 delete iFileData; |
|
140 } |
|
141 |
|
142 // ----------------------------------------------------------------------------- |
|
143 // CSvgReadCodec::SetFileDataL |
|
144 // Sets the SVG presentation data |
|
145 // ----------------------------------------------------------------------------- |
|
146 // |
|
147 void CSvgReadCodec::SetFileDataL( const TDesC8& aFileData ) |
|
148 { |
|
149 delete iFileData; |
|
150 iFileData = NULL; |
|
151 |
|
152 // For files which are in UTF-16 or unicode format the first 2 bytes |
|
153 // will be FF and FE. In UTF-16 and unicode format every single character |
|
154 // is represented by two bytes. |
|
155 |
|
156 HBufC8* binaryBuffer=NULL; |
|
157 binaryBuffer = HBufC8::NewL( aFileData.Length() ); |
|
158 |
|
159 TPtr8 binaryBufferPtr = binaryBuffer->Des(); |
|
160 binaryBufferPtr = aFileData; |
|
161 |
|
162 TInt hichar = (CEditableText::EReversedByteOrderMark & 0xFF00)>>8; |
|
163 TInt lochar = CEditableText::EReversedByteOrderMark & 0x00FF; |
|
164 TInt bytesPerChar = 1; |
|
165 |
|
166 if(binaryBufferPtr[0] == hichar && binaryBufferPtr[1] == lochar) |
|
167 { |
|
168 bytesPerChar = 2; |
|
169 |
|
170 HBufC* dataBuffer=NULL; |
|
171 TInt fileSize = aFileData.Length(); |
|
172 dataBuffer = HBufC::New(aFileData.Length()/bytesPerChar); |
|
173 if ( !dataBuffer) |
|
174 { |
|
175 //_LIT( KErrorMsg, "Failed to Load Svg Content: Out of memory"); |
|
176 delete binaryBuffer; |
|
177 return; |
|
178 } |
|
179 |
|
180 TPtr dataBufferPtr = dataBuffer->Des(); |
|
181 |
|
182 // Skip two bytes and set the pointer to the next location |
|
183 // from where the actual data starts. |
|
184 dataBufferPtr.Set((TUint16*)binaryBufferPtr.Ptr()+1, |
|
185 fileSize/bytesPerChar-1, |
|
186 fileSize/bytesPerChar-1); |
|
187 |
|
188 HBufC8* outputBuffer= NULL; |
|
189 outputBuffer=HBufC8::New(fileSize); |
|
190 if(!outputBuffer) |
|
191 { |
|
192 //_LIT( KErrorMsg, "Failed to Load Svg Content: Out of memory"); |
|
193 delete dataBuffer; |
|
194 delete binaryBuffer; |
|
195 return ; |
|
196 } |
|
197 TPtr8 outputBufferptr=outputBuffer->Des(); |
|
198 CnvUtfConverter::ConvertFromUnicodeToUtf8( |
|
199 outputBufferptr, // Destination |
|
200 dataBufferPtr ); |
|
201 |
|
202 iFileData = HBufC8::NewL(fileSize); |
|
203 iFileData->Des().Copy(outputBufferptr); |
|
204 |
|
205 delete dataBuffer; |
|
206 delete outputBuffer; |
|
207 |
|
208 } |
|
209 else |
|
210 { |
|
211 iFileData = HBufC8::NewL(aFileData.Length()); |
|
212 iFileData->Des().Copy( aFileData ); |
|
213 } |
|
214 delete binaryBuffer; |
|
215 } |
|
216 |
|
217 // ----------------------------------------------------------------------------- |
|
218 // CSvgReadCodec::ProcessFrameL |
|
219 // Processes the frame data contained in aSrc. |
|
220 // ----------------------------------------------------------------------------- |
|
221 // |
|
222 TFrameState CSvgReadCodec::ProcessFrameL(TBufPtr8& aSrc ) |
|
223 { |
|
224 aSrc.Shift( 1 ); |
|
225 TFrameState lRetVal = EFrameComplete; |
|
226 DoProcessL(); |
|
227 |
|
228 if(iImagesPresent && !iImagesLoaded) |
|
229 { |
|
230 lRetVal = EFrameIncompleteRepositionRequest; |
|
231 } |
|
232 |
|
233 return lRetVal; |
|
234 } |
|
235 |
|
236 // ----------------------------------------------------------------------------- |
|
237 // CSvgReadCodec::DoProcessL |
|
238 // Processes the SVG presentation file data. Called by ProcessFrameL() |
|
239 // ----------------------------------------------------------------------------- |
|
240 // |
|
241 void CSvgReadCodec::DoProcessL() |
|
242 { |
|
243 } |
|
244 |
|
245 // ----------------------------------------------------------------------------- |
|
246 // CSvgReadCodec::InitFrameL |
|
247 // Processes the SVG presentation file data. Called by ProcessFrameL() |
|
248 // ----------------------------------------------------------------------------- |
|
249 // |
|
250 void CSvgReadCodec::InitFrameL(TFrameInfo& /* aFrameInfo*/, |
|
251 CFrameImageData& /*aFrameImageData*/, |
|
252 TBool /*aDisableErrorDiffusion */, |
|
253 CFbsBitmap& aFrame, |
|
254 CFbsBitmap* /* aDestinationMask */ ) |
|
255 { |
|
256 GenerateThumbnailL(&aFrame, NULL); |
|
257 } |
|
258 |
|
259 void CSvgReadCodec::UpdateScreen() |
|
260 { |
|
261 } |
|
262 |
|
263 TBool CSvgReadCodec::ScriptCall( const TDesC& /*aScript*/, CSvgElementImpl* /*aCallerElement*/ ) |
|
264 { |
|
265 return EFalse; |
|
266 } |
|
267 |
|
268 TInt CSvgReadCodec::FetchImage( const TDesC& aUri, RFs& aSession, RFile& aFileHandle ) |
|
269 { |
|
270 TInt errorCode = KErrNotFound; |
|
271 TInt ret = 0; |
|
272 TRAPD(err, ret = IsDownloadNeededL(aUri)); |
|
273 if(err==KErrNone) |
|
274 { |
|
275 if( ret == ELocalImageFile) |
|
276 { |
|
277 TFileName fileName; |
|
278 |
|
279 #ifdef RD_MULTIPLE_DRIVE |
|
280 |
|
281 // RFs fsSession; |
|
282 HBufC* fullImagesPathBuf = HBufC::New( KMaxPath ); |
|
283 if (fullImagesPathBuf) |
|
284 { |
|
285 TPtr fullImagesPathPtr = fullImagesPathBuf->Des(); |
|
286 TInt intDrive; |
|
287 DriveInfo::TDriveArray driveArray; |
|
288 |
|
289 // fsSession.Connect(); |
|
290 |
|
291 TInt err1=DriveInfo::GetUserVisibleDrives( aSession, driveArray ); |
|
292 if(err1==KErrNone) |
|
293 { |
|
294 for(TInt i=0; i < driveArray.Count(); i++) |
|
295 { |
|
296 TChar driveLetter = driveArray.LetterAt(i); |
|
297 TInt err2=RFs::CharToDrive(driveLetter, intDrive); |
|
298 if(err2==KErrNone) |
|
299 { |
|
300 TInt err3=PathInfo::GetRootPath(fullImagesPathPtr, intDrive); |
|
301 if(err3==KErrNone) |
|
302 { |
|
303 fullImagesPathPtr.Append( PathInfo::ImagesPath() ); |
|
304 if(GetLocalFile( aUri, fileName, fullImagesPathPtr)) |
|
305 { |
|
306 errorCode = aFileHandle.Open( aSession, fileName, EFileShareAny ); |
|
307 break; |
|
308 } |
|
309 } |
|
310 } |
|
311 } |
|
312 } |
|
313 } |
|
314 delete fullImagesPathBuf; |
|
315 fullImagesPathBuf=NULL; |
|
316 |
|
317 // fsSession.Close(); |
|
318 |
|
319 #else |
|
320 |
|
321 HBufC* phoneMemImagesPath = GetImagesPath(EPhoneMemory); |
|
322 TPtr ptrphoneMemImagesPath(phoneMemImagesPath->Des()); |
|
323 HBufC* memCardImagesPath = GetImagesPath(EMemoryCard); |
|
324 TPtr ptrMemCardImagesPath(memCardImagesPath->Des()); |
|
325 |
|
326 if(GetLocalFile( aUri, fileName, ptrphoneMemImagesPath)) |
|
327 errorCode = aFileHandle.Open( aSession, fileName, EFileShareAny ); |
|
328 else if(GetLocalFile( aUri, fileName, ptrMemCardImagesPath)) |
|
329 errorCode = aFileHandle.Open( aSession, fileName, EFileShareAny ); |
|
330 |
|
331 delete memCardImagesPath; |
|
332 delete phoneMemImagesPath; |
|
333 #endif |
|
334 } |
|
335 } |
|
336 return errorCode; |
|
337 } |
|
338 |
|
339 TInt CSvgReadCodec::FetchFont( const TDesC& /* aUri */, |
|
340 RFs& /* aSession */, RFile& /* aFileHandle */ ) |
|
341 { |
|
342 return KErrNotSupported; |
|
343 } |
|
344 |
|
345 |
|
346 void CSvgReadCodec::GetSmilFitValue( TDes& aSmilValue ) |
|
347 { |
|
348 aSmilValue.Copy( KSccSmilFitValue ); |
|
349 } |
|
350 |
|
351 void CSvgReadCodec::UpdatePresentation( const TInt32& /* aNoOfAnimation */ ) |
|
352 { |
|
353 } |
|
354 |
|
355 void CSvgReadCodec::PrepareEngine() |
|
356 { |
|
357 iPrepareDomResult = iSvgModule->PrepareDom( *iFileData, iThumbnailHandle ); |
|
358 TInt err = iPrepareDomResult->HasError(); |
|
359 iSvgModule->UseDom( iThumbnailHandle, NULL); |
|
360 iContentSize = iSvgModule->GetSvgBoundingBox().Size(); |
|
361 if(iContentSize.iHeight < 1) |
|
362 { |
|
363 iContentSize.iHeight = 1; |
|
364 } |
|
365 if(iContentSize.iWidth < 1) |
|
366 { |
|
367 iContentSize.iWidth = 1; |
|
368 } |
|
369 } |
|
370 |
|
371 TSize CSvgReadCodec::ContentSize() const |
|
372 { |
|
373 return iContentSize; |
|
374 } |
|
375 |
|
376 void CSvgReadCodec::GenerateThumbnailL(CFbsBitmap* aFrame, CFbsBitmap* /*aFrameMask*/) |
|
377 { |
|
378 if ( iSvgModule ) |
|
379 { |
|
380 // NULL is returned, possible out of memory when create error object. |
|
381 User::LeaveIfNull( iPrepareDomResult ); |
|
382 User::LeaveIfError(iPrepareDomResult->HasError()); |
|
383 #ifdef SVGTUICONTROL_DBG_DRM_THUMBNAIL_API_ENABLE |
|
384 iSvgModule->SetThumbNailMode( ETrue ); // Set thumbnail mode On |
|
385 #endif // SVGTUICONTROL_DBG_DRM_THUMBNAIL_API_ENABLE |
|
386 |
|
387 // Setup the engine to use the DOM |
|
388 MSvgError* pResult = iSvgModule->UseDom( iThumbnailHandle, aFrame ); |
|
389 if ( pResult->HasError() && !pResult->IsWarning() ) |
|
390 { |
|
391 User::Leave( KErrGeneral ); |
|
392 } |
|
393 |
|
394 // View Box define for Dom associated frame |
|
395 iSvgModule->ChooseViewBoxIfNotSet(iThumbnailHandle); |
|
396 |
|
397 // Setup the frame size as the one obtained from |
|
398 // creator of codec. |
|
399 const TSize frameSize = aFrame->SizeInPixels(); |
|
400 // Get the Display mode for bitmap |
|
401 TDisplayMode lFrameDispMode = aFrame->DisplayMode(); |
|
402 // Get the Displaymode for mask |
|
403 iSvgModule->InitializeEngine(); |
|
404 iSvgModule->RenderFrame( NULL, 0); |
|
405 // render static content as well |
|
406 if ( iFrameList.Count() ) |
|
407 { |
|
408 CFbsBitGc* bitmapContext=NULL; |
|
409 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( aFrame ); |
|
410 CleanupStack::PushL( bitmapDevice ); |
|
411 User::LeaveIfError( bitmapDevice->CreateContext( bitmapContext ) ); |
|
412 CleanupStack::PushL( bitmapContext ); |
|
413 bitmapContext->BitBlt( TPoint(0,0),iFrameList[ 0 ] ); |
|
414 CleanupStack::PopAndDestroy(2); |
|
415 } |
|
416 |
|
417 #ifdef SVGTUICONTROL_DBG_DRM_THUMBNAIL_API_ENABLE |
|
418 iSvgModule->SetThumbNailMode( EFalse ); // Set thumbnail mode Off |
|
419 #endif // SVGTUICONTROL_DBG_DRM_THUMBNAIL_API_ENABLE |
|
420 } |
|
421 } |
|
422 |
|
423 // ----------------------------------------------------------------------------- |
|
424 // CSvgReadCodec::DeleteEngine |
|
425 // Deletes the structures associated with the engine |
|
426 // viz. The Frame List, Mask List, Delay Interval List, |
|
427 // The DOM for the content and the Engine Implementation itself |
|
428 // ----------------------------------------------------------------------------- |
|
429 // |
|
430 void CSvgReadCodec::DeleteEngine() |
|
431 { |
|
432 // Cleanup elements in the frame list |
|
433 for ( TInt i = 0; i < iFrameList.Count(); i++ ) |
|
434 { |
|
435 delete iFrameList[i]; |
|
436 } |
|
437 |
|
438 // Cleanup elements in the mask list |
|
439 for ( TInt i = 0; i < iMaskList.Count(); i++ ) |
|
440 { |
|
441 delete iMaskList[i]; |
|
442 } |
|
443 |
|
444 // Cleanup the memory used for storing the pointers/values |
|
445 iFrameList.Reset(); |
|
446 iMaskList.Reset(); |
|
447 iDelayList.Reset(); |
|
448 |
|
449 // Close the resources |
|
450 iFrameList.Close(); |
|
451 iMaskList.Close(); |
|
452 iDelayList.Close(); |
|
453 |
|
454 // Delete the DOM created for the content |
|
455 //if ( iThumbnailHandle ) |
|
456 // { |
|
457 // iSvgModule->DeleteDom( iThumbnailHandle ); |
|
458 // iThumbnailHandle = 0; |
|
459 // } |
|
460 |
|
461 // Delete the Engine module |
|
462 delete iSvgModule; |
|
463 iSvgModule = NULL; |
|
464 } |
|
465 |
|
466 CSvgReadCodec::TDownloadNeeded CSvgReadCodec::IsDownloadNeededL( const TDesC& aUri ) const |
|
467 { |
|
468 |
|
469 TUriParser UriParser; |
|
470 |
|
471 TBuf<KMaxFileName> localUri; |
|
472 // url starts with www so append http:// |
|
473 if ( !aUri.Left( 4 ).Compare( KWww ) ) |
|
474 { |
|
475 localUri.Append( KHttp ); |
|
476 localUri.Append( aUri ); |
|
477 User::LeaveIfError( UriParser.Parse( localUri ) ); |
|
478 } |
|
479 else |
|
480 { |
|
481 User::LeaveIfError( UriParser.Parse( aUri ) ); |
|
482 } |
|
483 |
|
484 if ( UriParser.IsPresent( EUriHost ) ) |
|
485 { |
|
486 // Extract the Path, filename and extension from the uri |
|
487 TFileName filename = UriParser.Extract( EUriPath ); |
|
488 TParsePtrC fileParser( filename ); |
|
489 |
|
490 if ( fileParser.NamePresent() && fileParser.ExtPresent() ) |
|
491 { |
|
492 if ( fileParser.Ext().Compare( KJpg ) == 0 || |
|
493 fileParser.Ext().Compare( KJpeg ) == 0 || |
|
494 fileParser.Ext().Compare( KBmp ) == 0 || |
|
495 fileParser.Ext().Compare( KPng ) == 0 || |
|
496 fileParser.Ext().Compare( KSvg ) == 0 || |
|
497 fileParser.Ext().Compare( KSvgz ) == 0 ) |
|
498 { |
|
499 // file name and ext present and |
|
500 // it is amy of the supported image types |
|
501 return ERemoteImageFile; |
|
502 } |
|
503 else |
|
504 { |
|
505 //file Extension present but not a supported image ext, |
|
506 //may be some html file |
|
507 return ENotAnImageFile; |
|
508 } |
|
509 } |
|
510 else |
|
511 { |
|
512 //Should be a domain name so return ENotAnImageFile |
|
513 return ENotAnImageFile; |
|
514 } |
|
515 } |
|
516 else |
|
517 { |
|
518 return ELocalImageFile; |
|
519 } |
|
520 } |
|
521 |
|
522 TBool CSvgReadCodec::GetLocalFile( const TDesC& aUri, |
|
523 TDes& aFileName , |
|
524 const TDesC& aRefPath ) const |
|
525 { |
|
526 aFileName.Zero(); |
|
527 TBuf<KMaxFileName> copyUri = aUri; |
|
528 // Before giving the uri to the file parser, |
|
529 // convert '/' to '\'. |
|
530 TInt pos; |
|
531 while( KErrNotFound != ( pos = copyUri.FindF( KBSlashStr ) ) ) |
|
532 { |
|
533 copyUri.Replace(pos,1,KSlashStr ); |
|
534 } |
|
535 |
|
536 // if the uri starts with ".\" remove ".\" |
|
537 if ( copyUri.Left( 2 ).Compare( KDotSlashStr ) == 0 ) |
|
538 { |
|
539 copyUri = copyUri.Right( copyUri.Length() - KDotSlashStr().Length() ); |
|
540 } |
|
541 |
|
542 // If the second letter is not ':' |
|
543 // and if it is not starting with '\', |
|
544 // and if the path has '/', |
|
545 // then prepend slash to it. |
|
546 if ( copyUri.Length() >= 2 && |
|
547 copyUri.Mid( 1, 1 ).Compare( KColonStr ) != 0 && |
|
548 copyUri.Mid( 0, 1 ).Compare( KSlashStr ) != 0 && |
|
549 ( copyUri.Find( KSlashStr ) != KErrNotFound ) ) |
|
550 { |
|
551 copyUri.Insert( 0, KSlashStr ); |
|
552 } |
|
553 |
|
554 TParse fileParser; |
|
555 if( fileParser.Set( copyUri, NULL, NULL ) != KErrNone ) |
|
556 { |
|
557 return EFalse; |
|
558 } |
|
559 |
|
560 if ( fileParser.DrivePresent() ) |
|
561 { |
|
562 // The uri is an absolute path |
|
563 aFileName.Append( fileParser.Drive() ); |
|
564 // Append path, file name and extension from the uri. |
|
565 if ( fileParser.PathPresent() ) |
|
566 { |
|
567 aFileName.Append( fileParser.Path() ); |
|
568 } |
|
569 if ( fileParser.NamePresent() ) |
|
570 { |
|
571 aFileName.Append( fileParser.Name() ); |
|
572 } |
|
573 if ( fileParser.ExtPresent() ) |
|
574 { |
|
575 aFileName.Append( fileParser.Ext() ); |
|
576 } |
|
577 |
|
578 if ( !ConeUtils::FileExists( aFileName ) ) |
|
579 { |
|
580 return EFalse; |
|
581 } |
|
582 return ETrue; |
|
583 } |
|
584 else |
|
585 { |
|
586 |
|
587 TParse svgFilenameParser; |
|
588 if ( svgFilenameParser.Set( aRefPath,NULL,NULL ) != KErrNone ) |
|
589 { |
|
590 return EFalse; |
|
591 } |
|
592 |
|
593 if ( svgFilenameParser.DrivePresent() ) |
|
594 { |
|
595 aFileName.Append( svgFilenameParser.Drive() ); |
|
596 } |
|
597 |
|
598 TInt dotdotPos = copyUri.Find( KDotDot ); |
|
599 TInt rightPos = 0; |
|
600 |
|
601 if ( dotdotPos != KErrNotFound ) |
|
602 { |
|
603 // If ".." is present collapse it with the parent path |
|
604 if ( svgFilenameParser.PathPresent() ) |
|
605 { |
|
606 do |
|
607 { |
|
608 if ( dotdotPos > 1 ) |
|
609 { |
|
610 svgFilenameParser.AddDir( copyUri.Left(dotdotPos - 1) ); |
|
611 } |
|
612 |
|
613 if ( svgFilenameParser.PopDir() != KErrNone ) |
|
614 { |
|
615 return EFalse; |
|
616 } |
|
617 |
|
618 rightPos = (copyUri.Length()) - (dotdotPos + 3); |
|
619 |
|
620 if ( rightPos > 0 ) |
|
621 { |
|
622 copyUri = copyUri.Right( rightPos ); |
|
623 } |
|
624 |
|
625 }while ( (dotdotPos = copyUri.Find( KDotDot ) ) |
|
626 != KErrNotFound ); |
|
627 |
|
628 aFileName.Append( svgFilenameParser.Path() ); |
|
629 aFileName.Append( copyUri ); |
|
630 } |
|
631 else |
|
632 { |
|
633 return EFalse; |
|
634 } |
|
635 } |
|
636 else |
|
637 { |
|
638 if ( svgFilenameParser.PathPresent() ) |
|
639 { |
|
640 aFileName.Append( svgFilenameParser.Path() ); |
|
641 } |
|
642 |
|
643 // Append path, file name and extension from the uri. |
|
644 if ( fileParser.PathPresent() ) |
|
645 { |
|
646 TFileName path(fileParser.Path() ); |
|
647 path.Copy(path.Right(path.Length()-1)); |
|
648 aFileName.Append( path ); |
|
649 |
|
650 } |
|
651 |
|
652 if ( fileParser.NamePresent() ) |
|
653 { |
|
654 aFileName.Append( fileParser.Name() ); |
|
655 } |
|
656 if ( fileParser.ExtPresent() ) |
|
657 { |
|
658 aFileName.Append( fileParser.Ext() ); |
|
659 } |
|
660 } |
|
661 if ( !ConeUtils::FileExists( aFileName ) ) |
|
662 { |
|
663 return EFalse; |
|
664 } |
|
665 return ETrue; |
|
666 } |
|
667 } |
|
668 |
|
669 HBufC* CSvgReadCodec::GetImagesPath( |
|
670 CSvgReadCodec::TImagesLocation aImagesLocation) const |
|
671 { |
|
672 HBufC* fullImagesPath = HBufC::New( KMaxPath ); |
|
673 if(fullImagesPath) |
|
674 { |
|
675 TPtr ptrFullImagesPath(fullImagesPath->Des()); |
|
676 |
|
677 TPtrC8 ptrImagesPath((TText8*)text_images_path); |
|
678 TFileName imagesPath16; |
|
679 imagesPath16.Copy(ptrImagesPath); |
|
680 |
|
681 switch( aImagesLocation ) |
|
682 { |
|
683 case EPhoneMemory: |
|
684 { |
|
685 TPtrC8 ptrRootPhoneMemPath((TText8*)text_phone_memory_root_path); |
|
686 ptrFullImagesPath.Copy(ptrRootPhoneMemPath); |
|
687 } |
|
688 break; |
|
689 case EMemoryCard: |
|
690 { |
|
691 TPtrC8 ptrRootMemCardPath((TText8*)text_memory_card_root_path); |
|
692 ptrFullImagesPath.Copy(ptrRootMemCardPath); |
|
693 } |
|
694 break; |
|
695 default: |
|
696 break; |
|
697 } |
|
698 ptrFullImagesPath.Append(imagesPath16); |
|
699 } |
|
700 return fullImagesPath; |
|
701 } |
|
702 |
|
703 //------------------------------------------------------------------------ |
|
704 //From MsvgLoadingListener |
|
705 /** |
|
706 * Query the listener if every element is to be reported or only |
|
707 * the children of <svg> tag. |
|
708 * |
|
709 * @since 1.0 |
|
710 * @return : ETrue if every element is to be reported, otherwise |
|
711 * only the children of <svg> are reported. |
|
712 */ |
|
713 TBool CSvgReadCodec::ReportAllElements() |
|
714 { |
|
715 return ETrue; |
|
716 } |
|
717 |
|
718 /** |
|
719 * Query the listener if client will call 'AssignImageData' to decode images |
|
720 * separately from parsing. This is used to avoid non-thread-safe calls in |
|
721 * creating bitmap and decoding images, which must be executed in the main thread. |
|
722 * |
|
723 * @since 1.0 |
|
724 * @return : ETrue to use 'ImageDataReference' instead of 'FetchImage'. |
|
725 */ |
|
726 TBool CSvgReadCodec::WillAssignImageData() |
|
727 { |
|
728 return ETrue; |
|
729 } |
|
730 |
|
731 /** |
|
732 * Callback when the href:xlink attribute is encountered for the <image> |
|
733 * element. This method is used to notify clients of image data references |
|
734 * needed by <image> element. This method is called only when 'WillAssignImageData' |
|
735 * returns ETrue. |
|
736 * |
|
737 * @since 1.0 |
|
738 * @return : none. |
|
739 */ |
|
740 void CSvgReadCodec::ImageDataReference( const TDesC& aUri ) |
|
741 { |
|
742 iImagesPresent = ETrue; |
|
743 |
|
744 HBufC8* lImageData = NULL; |
|
745 |
|
746 TInt errorCode = KErrNotFound; |
|
747 TInt ret = 0; |
|
748 TRAPD(err, ret = IsDownloadNeededL(aUri)); |
|
749 if(err==KErrNone) |
|
750 { |
|
751 if( ret != ELocalImageFile) |
|
752 { |
|
753 lImageData = HBufC8::New(0); |
|
754 if(lImageData) |
|
755 { |
|
756 iSvgModule->AssignImageData(aUri , lImageData ); |
|
757 } |
|
758 |
|
759 return; |
|
760 } |
|
761 |
|
762 _LIT(KEncodedImage,"data:image"); |
|
763 |
|
764 if( ! ( aUri.Left(10).Compare(KEncodedImage) )) |
|
765 { |
|
766 _LIT(KBase,"Base64"); |
|
767 if(aUri.FindF(KBase) != KErrNotFound) |
|
768 { |
|
769 TInt startIndex = aUri.Locate( ';' ); |
|
770 TInt endIndex = aUri.Locate( ',' ); |
|
771 // find index of first character after white-space |
|
772 TInt index = endIndex + 1; |
|
773 while ( index < aUri.Length() && TChar( aUri[index] ).IsSpace() ) |
|
774 index++; |
|
775 // must be 8-bit |
|
776 TInt length = aUri.Length() - index; |
|
777 HBufC8* encoded = HBufC8::New( length ); |
|
778 if(encoded) |
|
779 { |
|
780 encoded->Des().Copy( aUri.Right( length ) ); |
|
781 // Assign to member variable to destroy after image is process. |
|
782 lImageData = HBufC8::New( length ); |
|
783 if(lImageData) |
|
784 { |
|
785 TPtr8 decodedDes = lImageData->Des(); |
|
786 // decode |
|
787 TImCodecB64 encodingBase64; |
|
788 TInt decodeError = encodingBase64.Decode( *encoded, decodedDes ); |
|
789 delete encoded; |
|
790 encoded = NULL; |
|
791 } |
|
792 } |
|
793 } |
|
794 else |
|
795 { |
|
796 //lImageData = HBufC8::NewL(0); |
|
797 } |
|
798 } |
|
799 else |
|
800 { |
|
801 RFile lSvgFile; |
|
802 TFileName lFileName; |
|
803 RFs session; |
|
804 |
|
805 TInt Connecterror = session.Connect(); |
|
806 |
|
807 HBufC* phoneMemImagesPath = GetImagesPath(EPhoneMemory); |
|
808 TPtr ptrphoneMemImagesPath(phoneMemImagesPath->Des()); |
|
809 HBufC* memCardImagesPath = GetImagesPath(EMemoryCard); |
|
810 TPtr ptrMemCardImagesPath(memCardImagesPath->Des()); |
|
811 |
|
812 if(GetLocalFile( aUri, lFileName, ptrphoneMemImagesPath)) |
|
813 errorCode = lSvgFile.Open( session, lFileName, EFileShareAny ); |
|
814 else if(GetLocalFile( aUri, lFileName, ptrMemCardImagesPath)) |
|
815 errorCode = lSvgFile.Open( session, lFileName, EFileShareAny ); |
|
816 |
|
817 delete memCardImagesPath; |
|
818 delete phoneMemImagesPath; |
|
819 |
|
820 if(errorCode == KErrNone) |
|
821 { |
|
822 // Get the size of the data to create read buffer |
|
823 TInt lFileSize = 0; |
|
824 TInt sizeError = lSvgFile.Size(lFileSize) ; |
|
825 // Create buffer that will contain the file data |
|
826 lImageData = HBufC8::New(lFileSize); |
|
827 if(lImageData) |
|
828 { |
|
829 TPtr8 lFileDataPtr(lImageData->Des()); |
|
830 |
|
831 // Read from the file |
|
832 TInt ReadError = lSvgFile.Read(lFileDataPtr); |
|
833 } |
|
834 } |
|
835 else |
|
836 { |
|
837 lImageData = HBufC8::New(0); |
|
838 } |
|
839 lSvgFile.Close(); |
|
840 session.Close(); |
|
841 } |
|
842 if(lImageData) |
|
843 { |
|
844 iSvgModule->AssignImageData(aUri , lImageData ); |
|
845 } |
|
846 } |
|
847 } |
|
848 |
|
849 /** |
|
850 * Notified when the start of a svg document(<svg> tag) is encountered. |
|
851 * |
|
852 * @since 1.0 |
|
853 * @return : For future use. Value is ignored. |
|
854 */ |
|
855 TBool CSvgReadCodec::DocumentStart() |
|
856 { |
|
857 return EFalse; |
|
858 } |
|
859 |
|
860 /** |
|
861 * Notified when the end of a svg document(</svg> tag) is encountered. |
|
862 * |
|
863 * @since 1.0 |
|
864 * @return : For future use. Value is ignored. |
|
865 */ |
|
866 TBool CSvgReadCodec::DocumentEnd() |
|
867 { |
|
868 return ETrue; |
|
869 } |
|
870 |
|
871 /** |
|
872 * Notified when the start of a svg element is encountered. |
|
873 * |
|
874 * @since 1.0 |
|
875 * @param : aTagName -- name of svg tag |
|
876 * @param : aAttributeList -- attribute list. |
|
877 * @return : For future use. Value is ignored. |
|
878 */ |
|
879 TBool CSvgReadCodec::ElementStart( const TDesC& /*aTagName*/, |
|
880 MSvgAttributeList& /*aAttributeList*/) |
|
881 { |
|
882 return ETrue; |
|
883 } |
|
884 |
|
885 /** |
|
886 * Notified when the end of a svg element is encountered. |
|
887 * activated. |
|
888 * |
|
889 * @since 1.0 |
|
890 * @param : aTagName -- name of svg tag |
|
891 * @return : For future use. Value is ignored. |
|
892 */ |
|
893 TBool CSvgReadCodec::ElementEnd( const TDesC& /*aTagName*/ ) |
|
894 { |
|
895 return ETrue; |
|
896 } |
|
897 |
|
898 /** |
|
899 * Notified when an external data is needed by the svg document, |
|
900 * such as a image-file or an embedded svg-file. |
|
901 * |
|
902 * @since 1.0 |
|
903 * @param : aUri -- URI string of external data |
|
904 * @return : For future use. Value is ignored. |
|
905 */ |
|
906 TBool CSvgReadCodec::ExternalDataRequested( const TDesC& /*aUri*/ ) |
|
907 { |
|
908 return EFalse; |
|
909 } |
|
910 |
|
911 /** |
|
912 * Notified when an external data has been retrieved, |
|
913 * such as a image-file or an embedded svg-file. |
|
914 * |
|
915 * @since 1.0 |
|
916 * @param : aUri -- URI string of external data |
|
917 * @return : For future use. Value is ignored. |
|
918 */ |
|
919 TBool CSvgReadCodec::ExternalDataReceived( const TDesC& /*aUri*/ ) |
|
920 { |
|
921 return EFalse; |
|
922 } |
|
923 |
|
924 /** |
|
925 * Notified when an external data request has failed. |
|
926 * |
|
927 * @since 1.0 |
|
928 * @param : aUri -- URI string of external data |
|
929 * @return : For future use. Value is ignored. |
|
930 */ |
|
931 TBool CSvgReadCodec::ExternalDataRequestFailed( const TDesC& /*aUri*/ ) |
|
932 { |
|
933 return EFalse; |
|
934 } |
|
935 |
|
936 /** |
|
937 * Notified when an unsupported element is encountered. |
|
938 * |
|
939 * @since 1.0 |
|
940 * @param : aTagName -- tag name of element |
|
941 * @param : aAttributeList -- attribute list. |
|
942 * @return : For future use. Value is ignored. |
|
943 */ |
|
944 TBool CSvgReadCodec::UnsupportedElement( const TDesC& /*aTagName*/, |
|
945 MSvgAttributeList& /*aAttributeList*/ ) |
|
946 { |
|
947 return EFalse; |
|
948 } |
|
949 |
|
950 |
|
951 void CSvgReadCodec::ImagesLoaded(TInt /*aError*/) |
|
952 { |
|
953 iImagesLoaded = ETrue; |
|
954 iImagesPresent = EFalse; |
|
955 } |
|
956 |
|
957 void CSvgReadCodec::GetNewDataPosition(TInt& aPosition, TInt& /*aLength*/) |
|
958 { |
|
959 // Reset position to force seek to beginning |
|
960 aPosition =0; |
|
961 } |
|
962 |
|
963 |
|
964 |
|
965 |
|
966 |
|
967 //End of file |