|
1 /** |
|
2 * Copyright (c) 2010 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: CUpnpSvgImageConverter class implementation. |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "upnpsvgimageconverter.h" |
|
19 #include "upnptmserverimpl.h" |
|
20 #include <f32file.h> |
|
21 #include "upnpiconconversionactive.h" |
|
22 #include "OstTraceDefinitions.h" |
|
23 #ifdef OST_TRACE_COMPILER_IN_USE |
|
24 #include "upnpsvgimageconverterTraces.h" |
|
25 #endif |
|
26 |
|
27 // Literals |
|
28 _LIT(KLatin, "LatinPlain12"); |
|
29 _LIT(KConvertedIconPath, "public\\TmServerDevice1\\"); |
|
30 _LIT(KCross, "x"); |
|
31 _LIT(KDotBmp, ".bmp"); |
|
32 _LIT(KThreadName, "ImageConverterThread"); |
|
33 _LIT(KSemaphoreName, "ImageConverterSemaphore"); |
|
34 |
|
35 // Constant |
|
36 const TUint KDot = '.'; |
|
37 |
|
38 // ============================ MEMBER FUNCTIONS =================================== |
|
39 |
|
40 // --------------------------------------------------------------------------------- |
|
41 // CUpnpSvgImageConverter::NewL |
|
42 // Two-phased constructor. |
|
43 // @param aIconWidth Desired width of the serving icon. |
|
44 // @param aIconHeight Desired height of the serving icon. |
|
45 // --------------------------------------------------------------------------------- |
|
46 // |
|
47 CUpnpSvgImageConverter* CUpnpSvgImageConverter::NewL( TInt aIconWidth, TInt aIconHeight ) |
|
48 { |
|
49 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_NEWL_ENTRY ); |
|
50 OstTraceExt2( TRACE_NORMAL, CUPNPSVGIMAGECONVERTER_NEWL, "CUpnpSvgImageConverter::NewL;aIconWidth=%d;aIconHeight=%d", aIconWidth, aIconHeight ); |
|
51 CUpnpSvgImageConverter* self = new (ELeave) CUpnpSvgImageConverter( ); |
|
52 CleanupStack::PushL(self); |
|
53 self->ConstructL( aIconWidth,aIconHeight ); |
|
54 CleanupStack::Pop(self); |
|
55 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_NEWL_EXIT ); |
|
56 return self; |
|
57 } |
|
58 |
|
59 // --------------------------------------------------------------------------------- |
|
60 // CUpnpSvgImageConverter::CUpnpSvgImageConverter |
|
61 // C++ default constructor can NOT contain any code, that might leave. |
|
62 // --------------------------------------------------------------------------------- |
|
63 // |
|
64 CUpnpSvgImageConverter::CUpnpSvgImageConverter( ) |
|
65 { |
|
66 |
|
67 } |
|
68 |
|
69 // --------------------------------------------------------------------------------- |
|
70 // CUpnpSvgImageConverter::ConstructL |
|
71 // Symbian 2nd phase constructor can leave. |
|
72 // --------------------------------------------------------------------------------- |
|
73 // |
|
74 void CUpnpSvgImageConverter::ConstructL( TInt aIconWidth, TInt aIconHeight ) |
|
75 { |
|
76 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CONSTRUCTL_ENTRY ); |
|
77 //Geometric rectangle. |
|
78 TRect lMainRect( 0,0,aIconWidth,aIconHeight ); |
|
79 /** |
|
80 * Specifies the font specification to use for text drawing. |
|
81 * Here "LatinPlain12" of height "10" is used. |
|
82 */ |
|
83 TFontSpec lFontSpec( KLatin,UpnpString::KMaxTUintLength ); |
|
84 // A bitmap managed by the font and bitmap server. |
|
85 User::LeaveIfError(iFbsSession.Connect()); |
|
86 iBitmap = new ( ELeave ) CFbsBitmap(); |
|
87 iMask = new ( ELeave ) CFbsBitmap(); |
|
88 //Creates bitmap file of the desired dimensions with desired display mode(64,000 colour) |
|
89 User::LeaveIfError( iBitmap->Create( TSize( lMainRect.Width(), |
|
90 lMainRect.Height() ),EColor64K ) ); |
|
91 User::LeaveIfError( iMask->Create( TSize( lMainRect.Width(), |
|
92 lMainRect.Height() ),EGray256 ) ); // 256 grayscales display mode as alpha values |
|
93 /** |
|
94 * Create a new Svg Engine interface. |
|
95 * @param iBitmap bitmap to draw resulting svg image. |
|
96 * @param aReqObserver(NULL) interface for callbacks to retrieve info |
|
97 * only client can provide, such as opening files. |
|
98 * @param lFontSpecFont spec to use for text drawing. |
|
99 */ |
|
100 iSvgModule = CSvgEngineInterfaceImpl::NewL( iBitmap,NULL,lFontSpec ); |
|
101 User::LeaveIfError( iFileSession.Connect() ); |
|
102 TBuf<UpnpString::KMaxFilenameLength> privatePath; |
|
103 User::LeaveIfError( iFileSession.PrivatePath(privatePath) ); |
|
104 |
|
105 privatePath.Append(KConvertedIconPath()); |
|
106 privatePath.AppendNum( aIconWidth ); |
|
107 privatePath.Append( KCross); |
|
108 privatePath.AppendNum( aIconHeight ); |
|
109 privatePath.Append( UpnpString::KDoubleBackSlash16() ); |
|
110 TInt err = iFileSession.MkDir(privatePath); |
|
111 if( ( err != KErrNone ) && ( err != KErrAlreadyExists ) ) |
|
112 { |
|
113 // Leaves if fails to create a directory |
|
114 User::Leave(err); |
|
115 } |
|
116 iBitMapFilePath.CreateL( UpnpString::KMaxFilenameLength ); |
|
117 iBitMapFilePath.Append( privatePath ); |
|
118 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CONSTRUCTL_EXIT ); |
|
119 } |
|
120 |
|
121 // --------------------------------------------------------------------------------- |
|
122 // CUpnpSvgImageConverter::~CUpnpSvgImageConverter |
|
123 // Destructor |
|
124 // --------------------------------------------------------------------------------- |
|
125 // |
|
126 CUpnpSvgImageConverter::~CUpnpSvgImageConverter() |
|
127 { |
|
128 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CUPNPSVGIMAGECONVERTER_ENTRY ); |
|
129 iBitMapFilePath.Close(); |
|
130 delete iMask; |
|
131 delete iBitmap; |
|
132 delete iSvgModule; |
|
133 iFbsSession.Disconnect(); |
|
134 iFileSession.Close(); |
|
135 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CUPNPSVGIMAGECONVERTER_EXIT ); |
|
136 } |
|
137 |
|
138 // ----------------------------------------------------------------------------------- |
|
139 // CUpnpSvgImageConverter::ConvertToBitmapL |
|
140 // Method invokes svg to bitmap conversion. |
|
141 // It takes svg file as an input and returns converted icon file( bmp ). |
|
142 // Also prepares DOM for given SVG file. |
|
143 // @param aSvgFile Input svg filepath |
|
144 // @param aBitmapFile[out] Bitmap filepath ( converted file ). |
|
145 // ----------------------------------------------------------------------------------- |
|
146 void CUpnpSvgImageConverter::ConvertToBitmapL( const TDesC& aSvgFile, RBuf& aBitmapFile ) |
|
147 { |
|
148 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL_ENTRY ); |
|
149 /** |
|
150 * Extracts the filename( without filename extension ) from the input svg filepath and |
|
151 * uses the same filename to create bitmap file ( eg: abc.bmp ) |
|
152 */ |
|
153 TPtrC iconFileNameWithExtension = aSvgFile.Mid((aSvgFile.LocateReverse(KDirectorySeparator))+1); |
|
154 iBitMapFilePath.Append( iconFileNameWithExtension.Left(iconFileNameWithExtension.LocateReverse(KDot)) ); |
|
155 iBitMapFilePath.Append( KDotBmp ); |
|
156 RFile iconFile; |
|
157 TInt err = iconFile.Create(iFileSession,iBitMapFilePath,EFileRead|EFileWrite|EFileShareAny); |
|
158 OstTrace1( TRACE_NORMAL, CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL, "CUpnpSvgImageConverter::ConvertToBitmapL;err=%d", err ); |
|
159 iconFile.Close(); |
|
160 aBitmapFile.Close(); |
|
161 if ( err == KErrAlreadyExists ) |
|
162 { |
|
163 //If the converted file pre-exists, just return the existing filepath. |
|
164 aBitmapFile.CreateL(iBitMapFilePath); |
|
165 } |
|
166 else if ( err == KErrNone ) |
|
167 { |
|
168 TInt domHandle; |
|
169 /** |
|
170 * Parses and Prepares DOM for given SVG file. |
|
171 * @param aSvgFile the name of the file to be parsed |
|
172 * @param domHandle Handle to the created DOM. |
|
173 * @return lsvgerr Error object specifying the error occured during operation |
|
174 */ |
|
175 MSvgError* lsvgerr = iSvgModule->PrepareDom( aSvgFile,domHandle ,NULL ); |
|
176 if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) ) |
|
177 { |
|
178 User::Leave( KErrCancel ); |
|
179 } |
|
180 /** |
|
181 *Initialization of the engine |
|
182 *@param domHandle Handle to DOM Tree. |
|
183 *@param iBitmap Buffer for drawing the DOM Tree. |
|
184 *@param iMask Buffer for mask (alpha values) of framebuffer result |
|
185 *@return lsvgerr Error object specifying the error occured. |
|
186 */ |
|
187 lsvgerr = iSvgModule->UseDom( domHandle ,iBitmap,iMask ); |
|
188 if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) ) |
|
189 { |
|
190 User::Leave( KErrCancel ); |
|
191 } |
|
192 /** |
|
193 * Request the SVG Engine to begin an animation. |
|
194 */ |
|
195 iSvgModule->Start( lsvgerr ); |
|
196 if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) ) |
|
197 { |
|
198 User::Leave( KErrCancel ); |
|
199 } |
|
200 /** |
|
201 * Deletes the DOM tree associated with the Handle. |
|
202 */ |
|
203 lsvgerr = iSvgModule->DeleteDom( domHandle ) ; |
|
204 if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) ) |
|
205 { |
|
206 User::Leave( KErrCancel ); |
|
207 } |
|
208 /** |
|
209 * Creates and starts a new thread to handle asynchronous icon conversion. |
|
210 * A new or separate thread is needed for this purpose since the conversion happens |
|
211 * in the same thread as of that of the one who invokes. |
|
212 */ |
|
213 StartThreadL(); |
|
214 // Sets the converted filepath |
|
215 aBitmapFile.CreateL(iBitMapFilePath); |
|
216 } |
|
217 else |
|
218 { |
|
219 User::Leave(err); |
|
220 } |
|
221 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL_EXIT ); |
|
222 } |
|
223 |
|
224 // --------------------------------------------------------------------------------- |
|
225 // CUpnpSvgImageConverter::StartThreadL |
|
226 // Creates a new thread where actual conversion occurs. |
|
227 // Also creates a sempahore and waits on it. |
|
228 // --------------------------------------------------------------------------------- |
|
229 // |
|
230 void CUpnpSvgImageConverter::StartThreadL( ) |
|
231 { |
|
232 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_STARTTHREADL_ENTRY ); |
|
233 // Creates and opens a semaphore |
|
234 RSemaphore semaphore; |
|
235 CleanupClosePushL(semaphore); |
|
236 TInt error = semaphore.CreateGlobal( KSemaphoreName, KErrNone ); |
|
237 if ( error == KErrAlreadyExists ) |
|
238 { |
|
239 User::LeaveIfError(semaphore.OpenGlobal( KSemaphoreName )); |
|
240 } |
|
241 else |
|
242 { |
|
243 User::LeaveIfError(error); |
|
244 } |
|
245 // Creates a new thread which will be in suspended state after creation |
|
246 RThread thread; |
|
247 CleanupClosePushL(thread); |
|
248 User::LeaveIfError( thread.Create( KThreadName, |
|
249 ImageConverter, |
|
250 KDefaultStackSize, |
|
251 NULL, |
|
252 this, |
|
253 EOwnerProcess)); |
|
254 thread.SetPriority(EPriorityRealTime); |
|
255 //Resumes the newly created thread |
|
256 thread.Resume(); |
|
257 semaphore.Wait(); |
|
258 CleanupStack::PopAndDestroy(2,&semaphore); |
|
259 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_STARTTHREADL_EXIT ); |
|
260 } |
|
261 |
|
262 // --------------------------------------------------------------------------------- |
|
263 // CUpnpSvgImageConverter::Filepath |
|
264 // Method to return the path of the icon file which needs to be converted. |
|
265 // @return Returns reference to Bitmap file path. |
|
266 // --------------------------------------------------------------------------------- |
|
267 // |
|
268 const TDesC& CUpnpSvgImageConverter::Filepath( )const |
|
269 { |
|
270 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_FILEPATH_ENTRY ); |
|
271 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_FILEPATH_EXIT ); |
|
272 return iBitMapFilePath; |
|
273 } |
|
274 |
|
275 // --------------------------------------------------------------------------------- |
|
276 // CUpnpSvgImageConverter::BitmapObject |
|
277 // Method to return the bitmap object. |
|
278 // @return Returns reference to Bitmap object. |
|
279 // --------------------------------------------------------------------------------- |
|
280 // |
|
281 CFbsBitmap& CUpnpSvgImageConverter::BitmapObject()const |
|
282 { |
|
283 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_BITMAPOBJECT_ENTRY ); |
|
284 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_BITMAPOBJECT_EXIT ); |
|
285 return *iBitmap; |
|
286 } |
|
287 |
|
288 // --------------------------------------------------------------------------------- |
|
289 // CUpnpSvgImageConverter::ImageConverter |
|
290 // Static method serving as thread's main function |
|
291 // @param aParam Pointer to any type object. |
|
292 // @return Returns error code |
|
293 // --------------------------------------------------------------------------------- |
|
294 // |
|
295 TInt CUpnpSvgImageConverter::ImageConverter( TAny* aParam ) |
|
296 { |
|
297 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTER_ENTRY ); |
|
298 TInt err( KErrNone ); |
|
299 CUpnpSvgImageConverter* svgConverter = static_cast <CUpnpSvgImageConverter*>( aParam ); |
|
300 // Create cleanupstack |
|
301 CTrapCleanup* cleanupStack = CTrapCleanup::New(); |
|
302 if ( !cleanupStack ) |
|
303 { |
|
304 err = KErrNoMemory; |
|
305 } |
|
306 else |
|
307 { |
|
308 TRAP( err, ImageConverterL(*svgConverter) ); |
|
309 } |
|
310 // Create a matching semaphore for signalling the waiting semaphore |
|
311 RSemaphore semaphoreStop; |
|
312 semaphoreStop.OpenGlobal(KSemaphoreName); |
|
313 semaphoreStop.Signal(); |
|
314 semaphoreStop.Close(); |
|
315 |
|
316 delete cleanupStack; |
|
317 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTER_EXIT ); |
|
318 return err; |
|
319 } |
|
320 |
|
321 // --------------------------------------------------------------------------------- |
|
322 // CUpnpSvgImageConverter::ImageConverterL |
|
323 // Called from thread's main function. |
|
324 // Contains the code which can leave. |
|
325 // @param aSvgConverter Reference to class object. |
|
326 // --------------------------------------------------------------------------------- |
|
327 // |
|
328 void CUpnpSvgImageConverter::ImageConverterL( CUpnpSvgImageConverter& aSvgConverter ) |
|
329 { |
|
330 OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTERL_ENTRY ); |
|
331 /** |
|
332 * Add support for active objects |
|
333 * Create and install active scheduler |
|
334 */ |
|
335 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler; |
|
336 CleanupStack::PushL(scheduler); |
|
337 CActiveScheduler::Install( scheduler ); |
|
338 // Opens the bitmap file and supplies it to the active object |
|
339 RFs fs; |
|
340 CleanupClosePushL( fs ); |
|
341 User::LeaveIfError(fs.Connect()); |
|
342 RFile bitmapFile; |
|
343 CleanupClosePushL( bitmapFile ); |
|
344 User::LeaveIfError( bitmapFile.Open( fs, aSvgConverter.Filepath(), EFileRead|EFileWrite|EFileShareAny )); |
|
345 |
|
346 // Create an active object that is executed in this thread |
|
347 CUpnpIconConversionActive* active = CUpnpIconConversionActive::NewL( bitmapFile ); |
|
348 CleanupStack::PushL(active); |
|
349 // Invoke the request to the active object |
|
350 active->Convert( aSvgConverter.BitmapObject() ); |
|
351 // Thread execution starts |
|
352 CActiveScheduler::Start(); |
|
353 User::LeaveIfError( active->FetchError() ); // Leaves if the status returned is not KErrNone |
|
354 |
|
355 /** |
|
356 * Thread execution ends (waiting for CActiveScheduler::Stop()) |
|
357 * Cleanup the active object and scheduler |
|
358 */ |
|
359 CleanupStack::PopAndDestroy(UpnpString::KDoubleLineFeedLength,scheduler); |
|
360 OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTERL_EXIT ); |
|
361 } |
|
362 |
|
363 // End of File |