|
1 /* |
|
2 * Copyright (c) 2010 Ixonos Plc. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "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 * Ixonos Plc |
|
14 * |
|
15 * Description: |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 #include "VeiTitleClipGenerator.h" |
|
22 #include "VideoEditorCommon.h" |
|
23 #include "VideoEditorDebugUtils.h" |
|
24 |
|
25 #include <VedMovie.h> |
|
26 #include <fbs.h> |
|
27 #include <bitdev.h> |
|
28 #include <gdi.h> |
|
29 #include <aknutils.h> |
|
30 #include <ImageConversion.h> |
|
31 #include <BitmapTransforms.h> |
|
32 #include <aknbiditextutils.h> |
|
33 |
|
34 #include <AknFontAccess.h> |
|
35 #include <AknFontSpecification.h> |
|
36 #include <AknLayoutFont.h> |
|
37 |
|
38 #include "VideoEditorDebugUtils.h" |
|
39 |
|
40 const TInt KDefaultNumberOfLines = 15; |
|
41 const TInt KLineSpacing = 4; |
|
42 const TInt KMargin = 10; |
|
43 const TInt KVeiTitleClipDefaultDuration = 5000000; |
|
44 const TInt KVeiTitleClipFadeLimit = 2000000; |
|
45 // Restrict the maximum frame rate to 15fps regardless of the movie properties |
|
46 const TInt KMaxFrameRate = 15; |
|
47 |
|
48 |
|
49 EXPORT_C CVeiTitleClipGenerator* CVeiTitleClipGenerator::NewL(const TSize& aMaxResolution, |
|
50 TVeiTitleClipTransition aTransition, TVeiTitleClipHorizontalAlignment aHorizontalAlignment, |
|
51 TVeiTitleClipVerticalAlignment aVerticalAlignment) |
|
52 { |
|
53 LOGFMT2(KVideoEditorLogFile, "CVeiTitleClipGenerator::NewL: aMaxResolution: (%d,%d)", aMaxResolution.iWidth,aMaxResolution.iHeight); |
|
54 |
|
55 __ASSERT_ALWAYS(aMaxResolution.iHeight >= 0, TVedPanic::Panic(TVedPanic::ETitleClipGeneratorIllegalMaxResolution)); |
|
56 __ASSERT_ALWAYS(aMaxResolution.iWidth >= 0, TVedPanic::Panic(TVedPanic::ETitleClipGeneratorIllegalMaxResolution)); |
|
57 |
|
58 CVeiTitleClipGenerator* self = CVeiTitleClipGenerator::NewLC(aMaxResolution, aTransition, aHorizontalAlignment, aVerticalAlignment); |
|
59 CleanupStack::Pop(self); |
|
60 return self; |
|
61 } |
|
62 |
|
63 EXPORT_C CVeiTitleClipGenerator* CVeiTitleClipGenerator::NewLC(const TSize& aMaxResolution, |
|
64 TVeiTitleClipTransition aTransition, TVeiTitleClipHorizontalAlignment aHorizontalAlignment, |
|
65 TVeiTitleClipVerticalAlignment aVerticalAlignment) |
|
66 { |
|
67 LOGFMT2(KVideoEditorLogFile, "CVeiTitleClipGenerator::NewLC: In: aMaxResolution: (%d,%d)", aMaxResolution.iWidth,aMaxResolution.iHeight); |
|
68 |
|
69 __ASSERT_ALWAYS(aMaxResolution.iHeight >= 0, TVedPanic::Panic(TVedPanic::ETitleClipGeneratorIllegalMaxResolution)); |
|
70 __ASSERT_ALWAYS(aMaxResolution.iWidth >= 0, TVedPanic::Panic(TVedPanic::ETitleClipGeneratorIllegalMaxResolution)); |
|
71 |
|
72 CVeiTitleClipGenerator* self = new (ELeave) CVeiTitleClipGenerator(aMaxResolution, aTransition, aHorizontalAlignment, aVerticalAlignment); |
|
73 CleanupStack::PushL(self); |
|
74 self->ConstructL(); |
|
75 return self; |
|
76 } |
|
77 |
|
78 void CVeiTitleClipGenerator::ConstructL() |
|
79 { |
|
80 iDescriptiveName = HBufC::NewL(0); |
|
81 iWrappedArray = new (ELeave) CArrayFixFlat<TPtrC>(KDefaultNumberOfLines); |
|
82 iText = HBufC::NewL(0); |
|
83 GetTextFont(); |
|
84 } |
|
85 |
|
86 EXPORT_C CVeiTitleClipGenerator::~CVeiTitleClipGenerator() |
|
87 { |
|
88 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::~CVeiTitleClipGenerator(): In"); |
|
89 delete iDecodeOperation; |
|
90 delete iText; |
|
91 if (iWrappedArray) |
|
92 { |
|
93 iWrappedArray->Reset(); |
|
94 } |
|
95 delete iWrappedArray; |
|
96 delete iBackgroundImage; |
|
97 delete iScaledBackgroundImage; |
|
98 delete iDescriptiveName; |
|
99 |
|
100 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::~CVeiTitleClipGenerator(): Out"); |
|
101 } |
|
102 |
|
103 CVeiTitleClipGenerator::CVeiTitleClipGenerator(const TSize& aMaxResolution, |
|
104 TVeiTitleClipTransition aTransition, |
|
105 TVeiTitleClipHorizontalAlignment aHorizontalAlignment, |
|
106 TVeiTitleClipVerticalAlignment aVerticalAlignment) |
|
107 : iFirstFrameComplexityFactor(0), |
|
108 iGetFontResolution(aMaxResolution), |
|
109 iMaxResolution(aMaxResolution), |
|
110 iTransition(aTransition), |
|
111 iHorizontalAlignment(aHorizontalAlignment), |
|
112 iVerticalAlignment(aVerticalAlignment) |
|
113 { |
|
114 // Set some default values |
|
115 iDuration = TTimeIntervalMicroSeconds(KVeiTitleClipDefaultDuration); |
|
116 iBackgroundColor = KRgbBlack; |
|
117 iTextColor = KRgbWhite; |
|
118 } |
|
119 |
|
120 EXPORT_C TPtrC CVeiTitleClipGenerator::DescriptiveName() const |
|
121 { |
|
122 return *iDescriptiveName; |
|
123 } |
|
124 |
|
125 EXPORT_C TUid CVeiTitleClipGenerator::Uid() const |
|
126 { |
|
127 return KUidTitleClipGenerator; |
|
128 } |
|
129 |
|
130 EXPORT_C TTimeIntervalMicroSeconds CVeiTitleClipGenerator::Duration() const |
|
131 { |
|
132 return iDuration; |
|
133 } |
|
134 |
|
135 EXPORT_C TInt CVeiTitleClipGenerator::VideoFrameCount() const |
|
136 { |
|
137 TReal countReal((TReal)( (static_cast<TInt32>(iDuration.Int64())) / 1000000.0 ) * (TReal)(MaximumFramerate()) + 0.5); |
|
138 return (TInt) countReal; |
|
139 } |
|
140 |
|
141 EXPORT_C TTimeIntervalMicroSeconds CVeiTitleClipGenerator::VideoFrameStartTime(TInt aIndex) const |
|
142 { |
|
143 __ASSERT_ALWAYS(aIndex >= 0 && aIndex < VideoFrameCount(), |
|
144 TVedPanic::Panic(TVedPanic::EVideoClipGeneratorIllegalVideoFrameIndex)); |
|
145 |
|
146 TTimeIntervalMicroSeconds frameTime(1000000 / MaximumFramerate()); |
|
147 return TTimeIntervalMicroSeconds(TInt64(aIndex) * frameTime.Int64()); |
|
148 } |
|
149 |
|
150 EXPORT_C TTimeIntervalMicroSeconds CVeiTitleClipGenerator::VideoFrameEndTime(TInt aIndex) const |
|
151 { |
|
152 __ASSERT_ALWAYS(aIndex >= 0 && aIndex < VideoFrameCount(), |
|
153 TVedPanic::Panic(TVedPanic::EVideoClipGeneratorIllegalVideoFrameIndex)); |
|
154 |
|
155 TTimeIntervalMicroSeconds frameTime(1000000 / MaximumFramerate()); |
|
156 return TTimeIntervalMicroSeconds( (static_cast<TInt64>(aIndex) + 1) * frameTime.Int64() ); |
|
157 } |
|
158 |
|
159 EXPORT_C TTimeIntervalMicroSeconds CVeiTitleClipGenerator::VideoFrameDuration(TInt aIndex) const |
|
160 { |
|
161 __ASSERT_ALWAYS(aIndex >= 0 && aIndex < VideoFrameCount(), |
|
162 TVedPanic::Panic(TVedPanic::EVideoClipGeneratorIllegalVideoFrameIndex)); |
|
163 |
|
164 return TTimeIntervalMicroSeconds(VideoFrameEndTime(aIndex).Int64() - VideoFrameStartTime(aIndex).Int64()); |
|
165 } |
|
166 |
|
167 EXPORT_C TInt CVeiTitleClipGenerator::VideoFirstFrameComplexityFactor() const |
|
168 { |
|
169 return iFirstFrameComplexityFactor; |
|
170 } |
|
171 |
|
172 EXPORT_C TInt CVeiTitleClipGenerator::VideoFrameDifferenceFactor(TInt aIndex) const |
|
173 { |
|
174 __ASSERT_ALWAYS(aIndex > 0 && aIndex < VideoFrameCount(), |
|
175 TVedPanic::Panic(TVedPanic::EVideoClipGeneratorIllegalVideoFrameIndex)); |
|
176 |
|
177 TInt differenceFactor = 0; |
|
178 TInt pixels = iMaxResolution.iHeight * iMaxResolution.iWidth; |
|
179 TInt scale = 1000; |
|
180 TInt fontHeight = iTextFont->HeightInPixels(); |
|
181 |
|
182 switch(iTransition) |
|
183 { |
|
184 case EVeiTitleClipTransitionNone: |
|
185 { |
|
186 differenceFactor = 0; // if there is no transition, it's just a static text |
|
187 } |
|
188 break; |
|
189 case EVeiTitleClipTransitionFade: |
|
190 { |
|
191 TInt inEndFrame; |
|
192 TInt outStartFrame; |
|
193 CalculateTransitionFrameIndices(inEndFrame, outStartFrame); |
|
194 if ((aIndex < inEndFrame) || (aIndex > outStartFrame)) |
|
195 { |
|
196 for (TInt i = 0; i < iWrappedArray->Count(); i++) |
|
197 { |
|
198 TInt lineWidth = iTextFont->TextWidthInPixels(iWrappedArray->At(i)); |
|
199 differenceFactor += fontHeight * lineWidth; |
|
200 } |
|
201 differenceFactor *= scale; |
|
202 differenceFactor /= pixels; |
|
203 } |
|
204 else |
|
205 { |
|
206 differenceFactor = 0; |
|
207 } |
|
208 } |
|
209 break; |
|
210 case EVeiTitleClipTransitionScrollBottomToTop: |
|
211 case EVeiTitleClipTransitionScrollTopToBottom: |
|
212 { |
|
213 TInt yTravelPerFrame = (iMaxResolution.iHeight + iWrappedTextBoxHeight) / VideoFrameCount() + 1; |
|
214 |
|
215 TInt maxLineWidth = 0; |
|
216 for (TInt i = 0; i < iWrappedArray->Count(); i++) |
|
217 { |
|
218 TInt lineWidth = iTextFont->TextWidthInPixels(iWrappedArray->At(i)); |
|
219 if (lineWidth > maxLineWidth) |
|
220 { |
|
221 maxLineWidth = lineWidth; |
|
222 } |
|
223 } |
|
224 differenceFactor = scale * maxLineWidth * yTravelPerFrame / pixels; |
|
225 break; |
|
226 } |
|
227 case EVeiTitleClipTransitionScrollLeftToRight: |
|
228 case EVeiTitleClipTransitionScrollRightToLeft: |
|
229 { |
|
230 TInt xTravelPerFrame = (iMaxResolution.iWidth + iTextFont->TextWidthInPixels(*iText)) / VideoFrameCount() + 1; |
|
231 differenceFactor = scale * xTravelPerFrame * fontHeight / pixels; |
|
232 break; |
|
233 } |
|
234 default: |
|
235 TVedPanic::Panic(TVedPanic::EInternal); |
|
236 } |
|
237 |
|
238 return differenceFactor; |
|
239 } |
|
240 |
|
241 EXPORT_C TInt CVeiTitleClipGenerator::GetVideoFrameIndex(TTimeIntervalMicroSeconds aTime) const |
|
242 { |
|
243 __ASSERT_ALWAYS(aTime.Int64() >= 0 && aTime.Int64() <= iDuration.Int64(), |
|
244 TVedPanic::Panic(TVedPanic::EVideoClipGeneratorIllegalVideoFrameIndex)); |
|
245 |
|
246 TTimeIntervalMicroSeconds frameTime(1000000 / MaximumFramerate()); |
|
247 return (static_cast<TInt32>(aTime.Int64() / frameTime.Int64())); |
|
248 } |
|
249 |
|
250 EXPORT_C void CVeiTitleClipGenerator::GetFrameL(MVedVideoClipGeneratorFrameObserver& aObserver, |
|
251 TInt aIndex, TSize* const aResolution, |
|
252 TDisplayMode aDisplayMode, TBool aEnhance, |
|
253 TInt aPriority) |
|
254 { |
|
255 #ifdef VERBOSE |
|
256 LOGFMT3(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetFrameL(): In: aIndex:%d, aResolution:(%d,%d)",\ |
|
257 aIndex, aResolution->iWidth, aResolution->iHeight); |
|
258 #endif |
|
259 |
|
260 __ASSERT_ALWAYS(aIndex == KFrameIndexBestThumb || aIndex >= 0 |
|
261 && aIndex < VideoFrameCount(), |
|
262 TVedPanic::Panic(TVedPanic::EVideoClipGeneratorIllegalVideoFrameIndex)); |
|
263 |
|
264 TDisplayMode displayMode = aDisplayMode; |
|
265 |
|
266 // check validity of thumbnail and associated operation |
|
267 if(aEnhance) // for saving to file |
|
268 { |
|
269 if(displayMode == ENone) // if no preference |
|
270 { |
|
271 displayMode = EColor16M; // 24-bit color image for enhancement |
|
272 } |
|
273 else if(displayMode != EColor16M) // invalid combination |
|
274 { |
|
275 User::Leave(KErrNotSupported); |
|
276 } |
|
277 } |
|
278 else // for screen display |
|
279 { |
|
280 if(displayMode == ENone) // if no preference |
|
281 { |
|
282 displayMode = EColor64K; // 16-bit image |
|
283 } |
|
284 } |
|
285 |
|
286 |
|
287 iUseScaledImage = EFalse; |
|
288 iGetFrameObserver = &aObserver; |
|
289 iGetFrameIndex = aIndex; |
|
290 iGetFrameResolution = TSize(aResolution->iWidth, aResolution->iHeight); |
|
291 iGetFrameDisplayMode = displayMode; |
|
292 iGetFrameEnhance = aEnhance; |
|
293 iGetFramePriority = aPriority; |
|
294 |
|
295 if (!iBackgroundImage) |
|
296 { |
|
297 // No background image, just finish. |
|
298 FinishGetFrameL(); |
|
299 } |
|
300 else if ((aResolution->iHeight == iBackgroundImage->SizeInPixels().iHeight) || |
|
301 (aResolution->iWidth == iBackgroundImage->SizeInPixels().iWidth)) |
|
302 { |
|
303 // The background image does not need scaling - deleting scaled image |
|
304 // causes FinishGetFrameL() to use the original. |
|
305 iUseScaledImage = EFalse; |
|
306 FinishGetFrameL(); |
|
307 } |
|
308 else if (iScaledBackgroundImage && |
|
309 ((aResolution->iHeight == iScaledBackgroundImage->SizeInPixels().iHeight) || |
|
310 (aResolution->iWidth == iScaledBackgroundImage->SizeInPixels().iWidth))) |
|
311 { |
|
312 // Scaled image is in correct resolution |
|
313 iUseScaledImage = ETrue; |
|
314 FinishGetFrameL(); |
|
315 } |
|
316 else |
|
317 { |
|
318 // We need to scale the image. |
|
319 iUseScaledImage = ETrue; |
|
320 if (iScaledBackgroundImage) |
|
321 { |
|
322 delete iScaledBackgroundImage; |
|
323 iScaledBackgroundImage = 0; |
|
324 } |
|
325 |
|
326 if (iDecodeOperation) |
|
327 { |
|
328 delete iDecodeOperation; |
|
329 iDecodeOperation = 0; |
|
330 } |
|
331 |
|
332 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap; |
|
333 CleanupStack::PushL(bitmap); |
|
334 User::LeaveIfError(bitmap->Create(iBackgroundImage->SizeInPixels(), iBackgroundImage->DisplayMode())); |
|
335 CFbsDevice* device = CFbsBitmapDevice::NewL(bitmap); |
|
336 CFbsBitGc* gc = NULL; |
|
337 device->CreateContext(gc); |
|
338 gc->BitBlt(TPoint(0,0), iBackgroundImage); |
|
339 delete gc; |
|
340 delete device; |
|
341 iDecodeOperation = CVeiTitleClipImageDecodeOperation::NewL(*this, bitmap); |
|
342 CleanupStack::Pop(bitmap); |
|
343 iDecodeOperation->StartScalingOperationL(iGetFrameResolution); |
|
344 } |
|
345 |
|
346 #ifdef VERBOSE |
|
347 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetFrameL(): Out"); |
|
348 #endif |
|
349 } |
|
350 |
|
351 |
|
352 EXPORT_C CFbsBitmap* CVeiTitleClipGenerator::FinishGetFrameL(TInt aError) |
|
353 { |
|
354 #ifdef VERBOSE |
|
355 LOGFMT(KVideoEditorLogFile, "CVeiTitleClipGenerator::FinishGetFrameL(): In: aError:%d", aError); |
|
356 #endif |
|
357 |
|
358 ASSERT(iGetFrameResolution.iWidth > 0 && iGetFrameResolution.iHeight > 0); |
|
359 |
|
360 if (aError != KErrNone) |
|
361 { |
|
362 iGetFrameObserver->NotifyVideoClipGeneratorFrameCompleted(*this, aError, NULL); |
|
363 return NULL; |
|
364 } |
|
365 |
|
366 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap; |
|
367 CleanupStack::PushL(bitmap); |
|
368 TInt err = bitmap->Create(iGetFrameResolution, iGetFrameDisplayMode); |
|
369 if (err != KErrNone) |
|
370 { |
|
371 delete bitmap; |
|
372 bitmap = NULL; |
|
373 iGetFrameObserver->NotifyVideoClipGeneratorFrameCompleted(*this, err, NULL); |
|
374 } |
|
375 else |
|
376 { |
|
377 CFbsDevice* device = CFbsBitmapDevice::NewL(bitmap); |
|
378 CFbsBitGc* gc = NULL; |
|
379 device->CreateContext(gc); |
|
380 |
|
381 /* Draw the background. */ |
|
382 if (iUseScaledImage) |
|
383 { |
|
384 TSize bgImageSize(iScaledBackgroundImage->SizeInPixels()); |
|
385 TPoint bgPoint((iGetFrameResolution.iWidth - bgImageSize.iWidth) / 2, |
|
386 (iGetFrameResolution.iHeight - bgImageSize.iHeight) / 2); |
|
387 gc->BitBlt(bgPoint, iScaledBackgroundImage); |
|
388 } |
|
389 else if (iBackgroundImage) |
|
390 { |
|
391 TSize bgImageSize(iBackgroundImage->SizeInPixels()); |
|
392 TPoint bgPoint((iGetFrameResolution.iWidth - bgImageSize.iWidth) / 2, |
|
393 (iGetFrameResolution.iHeight - bgImageSize.iHeight) / 2); |
|
394 gc->BitBlt(bgPoint, iBackgroundImage); |
|
395 } |
|
396 else |
|
397 { |
|
398 gc->SetBrushColor(iBackgroundColor); |
|
399 gc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
400 gc->DrawRect(bitmap->SizeInPixels()); |
|
401 } |
|
402 |
|
403 delete gc; |
|
404 delete device; |
|
405 |
|
406 switch(iTransition) |
|
407 { |
|
408 case EVeiTitleClipTransitionNone: |
|
409 case EVeiTitleClipTransitionFade: |
|
410 { |
|
411 DrawMainTitleFrameL(*bitmap, iGetFrameIndex); |
|
412 break; |
|
413 } |
|
414 case EVeiTitleClipTransitionScrollBottomToTop: |
|
415 case EVeiTitleClipTransitionScrollTopToBottom: |
|
416 case EVeiTitleClipTransitionScrollLeftToRight: |
|
417 case EVeiTitleClipTransitionScrollRightToLeft: |
|
418 { |
|
419 DrawScrollTitleFrameL(*bitmap, iGetFrameIndex); |
|
420 break; |
|
421 } |
|
422 default: |
|
423 TVedPanic::Panic(TVedPanic::EInternal); |
|
424 } |
|
425 |
|
426 /* Notify the observer. */ |
|
427 if (iGetFrameObserver) |
|
428 { |
|
429 iGetFrameObserver->NotifyVideoClipGeneratorFrameCompleted(*this, KErrNone, bitmap); |
|
430 } |
|
431 |
|
432 iGetFrameObserver = 0; |
|
433 iGetFrameIndex = -5; |
|
434 |
|
435 CleanupStack::Pop(bitmap); |
|
436 } |
|
437 |
|
438 #ifdef VERBOSE |
|
439 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::FinishGetFrameL(): Out"); |
|
440 #endif |
|
441 |
|
442 return bitmap; |
|
443 } |
|
444 |
|
445 EXPORT_C void CVeiTitleClipGenerator::CancelFrame() |
|
446 { |
|
447 if (iDecodeOperation) |
|
448 { |
|
449 iDecodeOperation->Cancel(); |
|
450 } |
|
451 } |
|
452 |
|
453 EXPORT_C TVeiTitleClipTransition CVeiTitleClipGenerator::Transition() const |
|
454 { |
|
455 return iTransition; |
|
456 } |
|
457 |
|
458 EXPORT_C TVeiTitleClipHorizontalAlignment CVeiTitleClipGenerator::HorizontalAlignment() const |
|
459 { |
|
460 return iHorizontalAlignment; |
|
461 } |
|
462 |
|
463 EXPORT_C TVeiTitleClipVerticalAlignment CVeiTitleClipGenerator::VerticalAlignment() const |
|
464 { |
|
465 return iVerticalAlignment; |
|
466 } |
|
467 |
|
468 EXPORT_C void CVeiTitleClipGenerator::SetTransitionAndAlignmentsL( |
|
469 TVeiTitleClipTransition aTransition, |
|
470 TVeiTitleClipHorizontalAlignment aHorizontalAlignment, |
|
471 TVeiTitleClipVerticalAlignment aVerticalAlignment) |
|
472 { |
|
473 TBool updateNeeded = EFalse; |
|
474 if (iTransition != aTransition) |
|
475 { |
|
476 iTransition = aTransition; |
|
477 updateNeeded = ETrue; |
|
478 } |
|
479 |
|
480 if (iHorizontalAlignment != aHorizontalAlignment) |
|
481 { |
|
482 iHorizontalAlignment = aHorizontalAlignment; |
|
483 updateNeeded = ETrue; |
|
484 } |
|
485 |
|
486 if (iVerticalAlignment != aVerticalAlignment) |
|
487 { |
|
488 iVerticalAlignment = aVerticalAlignment; |
|
489 updateNeeded = ETrue; |
|
490 } |
|
491 |
|
492 if (updateNeeded) |
|
493 { |
|
494 UpdateFirstFrameComplexityFactorL(); |
|
495 ReportSettingsChanged(); |
|
496 } |
|
497 } |
|
498 |
|
499 EXPORT_C void CVeiTitleClipGenerator::SetTextL(const TDesC& aText) |
|
500 { |
|
501 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::SetTextL(): In"); |
|
502 |
|
503 /* Don't do anything if the texts are equal. */ |
|
504 if (iText && !iText->Compare(aText)) |
|
505 { |
|
506 return; |
|
507 } |
|
508 |
|
509 /* Delete old text. */ |
|
510 if (iText) |
|
511 { |
|
512 delete iText; |
|
513 iText = 0; |
|
514 } |
|
515 |
|
516 /* Wrap the string to lines. */ |
|
517 WrapTextToArrayL(aText); |
|
518 ReportSettingsChanged(); |
|
519 |
|
520 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::SetTextL(): Out"); |
|
521 } |
|
522 |
|
523 EXPORT_C void CVeiTitleClipGenerator::SetDescriptiveNameL(const TDesC& aDescriptiveName) |
|
524 { |
|
525 if (iDescriptiveName && !iDescriptiveName->Compare(aDescriptiveName)) |
|
526 { |
|
527 return; |
|
528 } |
|
529 |
|
530 if (iDescriptiveName) |
|
531 { |
|
532 delete iDescriptiveName; |
|
533 iDescriptiveName = 0; |
|
534 } |
|
535 iDescriptiveName = HBufC::NewL(aDescriptiveName.Length()); |
|
536 *iDescriptiveName = aDescriptiveName; |
|
537 ReportDescriptiveNameChanged(); |
|
538 } |
|
539 |
|
540 EXPORT_C TPtrC CVeiTitleClipGenerator::Text() const |
|
541 { |
|
542 return *iText; |
|
543 } |
|
544 |
|
545 |
|
546 EXPORT_C void CVeiTitleClipGenerator::SetBackgroundColorL(const TRgb& aBackgroundColor) |
|
547 { |
|
548 if (iBackgroundImage) |
|
549 { |
|
550 delete iBackgroundImage; |
|
551 iBackgroundImage = 0; |
|
552 delete iScaledBackgroundImage; |
|
553 iScaledBackgroundImage = 0; |
|
554 } |
|
555 else if (aBackgroundColor == iBackgroundColor) |
|
556 { |
|
557 return; |
|
558 } |
|
559 |
|
560 iBackgroundColor = aBackgroundColor; |
|
561 UpdateFirstFrameComplexityFactorL(); |
|
562 ReportSettingsChanged(); |
|
563 } |
|
564 |
|
565 EXPORT_C TRgb CVeiTitleClipGenerator::BackgroundColor() const |
|
566 { |
|
567 return iBackgroundColor; |
|
568 } |
|
569 |
|
570 EXPORT_C void CVeiTitleClipGenerator::SetTextColorL(const TRgb& aTextColor) |
|
571 { |
|
572 if (iTextColor != aTextColor) |
|
573 { |
|
574 iTextColor = aTextColor; |
|
575 ReportSettingsChanged(); |
|
576 UpdateFirstFrameComplexityFactorL(); |
|
577 } |
|
578 } |
|
579 |
|
580 EXPORT_C TRgb CVeiTitleClipGenerator::TextColor() const |
|
581 { |
|
582 return iTextColor; |
|
583 } |
|
584 |
|
585 EXPORT_C void CVeiTitleClipGenerator::SetBackgroundImageL(const CFbsBitmap* aBackgroundImage) |
|
586 { |
|
587 if (iBackgroundImage) |
|
588 { |
|
589 delete iBackgroundImage; |
|
590 iBackgroundImage = 0; |
|
591 delete iScaledBackgroundImage; |
|
592 iScaledBackgroundImage = 0; |
|
593 } |
|
594 |
|
595 iBackgroundImage = new (ELeave) CFbsBitmap; |
|
596 iBackgroundImage->Duplicate(aBackgroundImage->Handle()); |
|
597 UpdateFirstFrameComplexityFactorL(); |
|
598 ReportSettingsChanged(); |
|
599 } |
|
600 |
|
601 EXPORT_C void CVeiTitleClipGenerator::SetBackgroundImageL(const TDesC& aFilename, MVeiTitleClipGeneratorObserver& aObserver) |
|
602 { |
|
603 delete iDecodeOperation; |
|
604 iDecodeOperation = 0; |
|
605 delete iBackgroundImage; |
|
606 iBackgroundImage = 0; |
|
607 delete iScaledBackgroundImage; |
|
608 iScaledBackgroundImage = 0; |
|
609 |
|
610 iDecodeOperation = CVeiTitleClipImageDecodeOperation::NewL(*this, aObserver, aFilename); |
|
611 iDecodeOperation->StartLoadOperationL(iMaxResolution); |
|
612 } |
|
613 |
|
614 EXPORT_C CFbsBitmap* CVeiTitleClipGenerator::BackgroundImage() const |
|
615 { |
|
616 return iBackgroundImage; |
|
617 } |
|
618 |
|
619 EXPORT_C void CVeiTitleClipGenerator::SetDuration(const TTimeIntervalMicroSeconds& aDuration) |
|
620 { |
|
621 if (iDuration != aDuration) |
|
622 { |
|
623 iDuration = aDuration; |
|
624 ReportDurationChanged(); |
|
625 } |
|
626 } |
|
627 |
|
628 void CVeiTitleClipGenerator::WrapTextToArrayL(const TDesC& aText) |
|
629 { |
|
630 LOGFMT2(KVideoEditorLogFile, "CVeiTitleClipGenerator::WrapTextToArrayL(): In: iMaxResolution: (%d,%d)", iMaxResolution.iWidth, iMaxResolution.iHeight); |
|
631 |
|
632 TInt fontdivisor = 11; |
|
633 |
|
634 do |
|
635 { |
|
636 |
|
637 if (iText) |
|
638 { |
|
639 delete iText; |
|
640 iText = 0; |
|
641 } |
|
642 |
|
643 if (iWrappedArray) |
|
644 { |
|
645 iWrappedArray->Reset(); |
|
646 } |
|
647 |
|
648 TInt width = iMaxResolution.iWidth - KMargin * 2; |
|
649 GetTextFont(fontdivisor); |
|
650 iText = AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(aText, width, *iTextFont, *iWrappedArray); |
|
651 |
|
652 /* Recalculate text dependant values. */ |
|
653 TInt lineHeight = iTextFont->HeightInPixels() + KLineSpacing; |
|
654 iWrappedTextBoxHeight = iWrappedArray->Count() * lineHeight; |
|
655 LOGFMT2(KVideoEditorLogFile, "CVeiTitleClipGenerator::WrapTextToArrayL(): In: iWrappedArray->Count %d, iWrappedTextBoxHeight %d", iWrappedArray->Count(), iWrappedTextBoxHeight); |
|
656 |
|
657 fontdivisor++; |
|
658 } |
|
659 while(iWrappedTextBoxHeight > iMaxResolution.iHeight); |
|
660 |
|
661 UpdateFirstFrameComplexityFactorL(); |
|
662 |
|
663 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::WrapTextToArrayL(): Out"); |
|
664 } |
|
665 |
|
666 void CVeiTitleClipGenerator::UpdateFirstFrameComplexityFactorL() |
|
667 { |
|
668 CFbsBitmap* bitmap = GetFirstFrameL(); |
|
669 CleanupStack::PushL(bitmap); |
|
670 iFirstFrameComplexityFactor = CalculateFrameComplexityFactor(bitmap); |
|
671 CleanupStack::PopAndDestroy(bitmap); |
|
672 } |
|
673 |
|
674 void CVeiTitleClipGenerator::CalculateTransitionFrameIndices(TInt& aInEndFrame, TInt& aOutStartFrame) const |
|
675 { |
|
676 /* Calculate some values for timing the transitions */ |
|
677 TInt64 divider = 3; |
|
678 TInt64 durationInt = iDuration.Int64(); |
|
679 TTimeIntervalMicroSeconds inEndTime(durationInt / divider); |
|
680 TTimeIntervalMicroSeconds outStartTime(durationInt - durationInt / divider); |
|
681 |
|
682 /* Limit the fade in/out times to a reasonable value. */ |
|
683 if (inEndTime.Int64() > TInt64(KVeiTitleClipFadeLimit)) |
|
684 { |
|
685 inEndTime = TTimeIntervalMicroSeconds(KVeiTitleClipFadeLimit); |
|
686 outStartTime = TTimeIntervalMicroSeconds(durationInt - KVeiTitleClipFadeLimit); |
|
687 } |
|
688 |
|
689 if (IsInserted()) |
|
690 { |
|
691 aInEndFrame = GetVideoFrameIndex(inEndTime); |
|
692 aOutStartFrame = GetVideoFrameIndex(outStartTime); |
|
693 } |
|
694 else |
|
695 { |
|
696 aInEndFrame = 5; |
|
697 aOutStartFrame = 10; |
|
698 } |
|
699 } |
|
700 |
|
701 |
|
702 void CVeiTitleClipGenerator::GetTextFont(TInt aFontDivisor) |
|
703 { |
|
704 #ifdef VERBOSE |
|
705 LOGFMT4(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetTextFont(): iGetFrameResolution: (%d,%d), iMaxResolution: (%d,%d)",\ |
|
706 iGetFrameResolution.iWidth, iGetFrameResolution.iHeight, iMaxResolution.iWidth, iMaxResolution.iHeight); |
|
707 #endif |
|
708 |
|
709 if (!iTextFont || iGetFontResolution != iGetFrameResolution) |
|
710 { |
|
711 LOGFMT6(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetTextFont(): Getting new font. iGetFontResolution: (%d,%d), iGetFrameResolution: (%d,%d), iMaxResolution: (%d,%d)",\ |
|
712 iGetFontResolution.iWidth, iGetFontResolution.iHeight, iGetFrameResolution.iWidth, iGetFrameResolution.iHeight, iMaxResolution.iWidth, iMaxResolution.iHeight); |
|
713 |
|
714 TInt movieHeight = iGetFrameResolution.iHeight; |
|
715 iGetFontResolution = iGetFrameResolution; |
|
716 if (movieHeight <= 0) |
|
717 { |
|
718 movieHeight = iMaxResolution.iHeight; |
|
719 iGetFontResolution = iMaxResolution; |
|
720 } |
|
721 |
|
722 // If the generator is inserted, we can use the actual movie height |
|
723 // otherwise, we'll just assume max resolution. |
|
724 if (IsInserted()) |
|
725 { |
|
726 CVedMovie* movie = Movie(); |
|
727 movieHeight = movie->Resolution().iHeight; |
|
728 } |
|
729 TInt fontHeightInPixels; |
|
730 if(aFontDivisor) |
|
731 { |
|
732 fontHeightInPixels = movieHeight / (aFontDivisor -3); |
|
733 if (movieHeight >= 200) |
|
734 { |
|
735 fontHeightInPixels = movieHeight / aFontDivisor; |
|
736 } |
|
737 } |
|
738 else |
|
739 { |
|
740 fontHeightInPixels = movieHeight / 8; |
|
741 if (movieHeight >= 200) |
|
742 { |
|
743 fontHeightInPixels = movieHeight / 11; |
|
744 } |
|
745 } |
|
746 |
|
747 TAknFontSpecification spec( EAknFontCategoryPrimary ); |
|
748 spec.SetTextPaneHeight( fontHeightInPixels ); |
|
749 spec.SetWeight( EStrokeWeightBold ); |
|
750 spec.SetPosture( EPostureUpright ); |
|
751 |
|
752 CWsScreenDevice* dev = CCoeEnv::Static()->ScreenDevice(); |
|
753 CAknLayoutFont* layoutFont = NULL; |
|
754 TRAPD(err, layoutFont = AknFontAccess::CreateLayoutFontFromSpecificationL( *dev, spec ) ); |
|
755 if (err) |
|
756 { |
|
757 LOGFMT(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetTextFont(): Creating font from font spec failed (%d)", err); |
|
758 |
|
759 // In case of failure (should not happen...) make sure that some font is still available |
|
760 ASSERT(EFalse); |
|
761 TInt fontId = 0; |
|
762 if (movieHeight >= 200) |
|
763 { |
|
764 fontId =EAknLogicalFontPrimaryFont; |
|
765 } |
|
766 else |
|
767 { |
|
768 fontId = EAknLogicalFontSecondaryFont; |
|
769 } |
|
770 iTextFont = AknLayoutUtils::FontFromId( fontId ); |
|
771 } |
|
772 else |
|
773 { |
|
774 iTextFont = (const CFont*)layoutFont; |
|
775 } |
|
776 } |
|
777 |
|
778 #ifdef VERBOSE |
|
779 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetTextFont(): Out"); |
|
780 #endif |
|
781 } |
|
782 |
|
783 void CVeiTitleClipGenerator::DrawWrappedTextL(CFbsBitmap& aBitmap, |
|
784 const TPoint& aTextPoint, const TRgb& aTextColor, const TRgb& aBgColor, const TRgb& aShadowColor, |
|
785 TBool aDrawBackground) |
|
786 { |
|
787 #ifdef VERBOSE |
|
788 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::DrawWrappedTextL(): In"); |
|
789 #endif |
|
790 |
|
791 // Make sure the text is wrapped using the movie's frame resolution. |
|
792 // If the generator is not inserted, just use the maximum resolution. |
|
793 // - unfortunately this does not seem to work, if the text is re-wrapped |
|
794 // here, the program seems to get stuck. |
|
795 /* if (IsInserted()) |
|
796 { |
|
797 CVedMovie* movie = Movie(); |
|
798 TSize res = movie->Resolution(); |
|
799 if (iMaxResolution != res) |
|
800 { |
|
801 HBufC* oldText = iText->Des().AllocLC(); |
|
802 delete iText; |
|
803 iText = NULL; |
|
804 iMaxResolution = res; |
|
805 WrapTextToArrayL(oldText->Des()); |
|
806 CleanupStack::PopAndDestroy(oldText); |
|
807 } |
|
808 } |
|
809 */ |
|
810 CFbsDevice* device = CFbsBitmapDevice::NewL(&aBitmap); |
|
811 CleanupStack::PushL(device); |
|
812 CFbsBitGc* gc = NULL; |
|
813 device->CreateContext(gc); |
|
814 CleanupStack::PushL(gc); |
|
815 gc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
816 |
|
817 if (aDrawBackground) |
|
818 { |
|
819 gc->SetPenColor(aBgColor); |
|
820 gc->SetBrushColor(aBgColor); |
|
821 gc->DrawRect(TRect(aBitmap.SizeInPixels())); |
|
822 } |
|
823 |
|
824 gc->SetPenSize(TSize(1,1)); |
|
825 |
|
826 GetTextFont(); |
|
827 gc->UseFont(iTextFont); |
|
828 |
|
829 TPoint textPoint(aTextPoint); |
|
830 TRect rect(aBitmap.SizeInPixels()); |
|
831 |
|
832 /* Draw text and shadow. */ |
|
833 |
|
834 textPoint = aTextPoint; |
|
835 |
|
836 for (TInt i = 0; i < iWrappedArray->Count(); i++) |
|
837 { |
|
838 TInt textWidth = iTextFont->TextWidthInPixels(iWrappedArray->At(i)); |
|
839 TInt baseX = 0; |
|
840 switch(iHorizontalAlignment) |
|
841 { |
|
842 case EVeiTitleClipHorizontalAlignmentCenter: |
|
843 baseX = (rect.Width() - textWidth) / 2; |
|
844 break; |
|
845 case EVeiTitleClipHorizontalAlignmentLeft: |
|
846 baseX = KMargin; |
|
847 break; |
|
848 case EVeiTitleClipHorizontalAlignmentRight: |
|
849 baseX = (rect.iBr.iX - textWidth) - KMargin; |
|
850 break; |
|
851 default: |
|
852 TVedPanic::Panic(TVedPanic::EInternal); |
|
853 } |
|
854 textPoint.iX = baseX + 1; |
|
855 textPoint.iY += iTextFont->AscentInPixels() + KLineSpacing / 2 + 2; |
|
856 gc->SetBrushColor(aShadowColor); |
|
857 gc->SetPenColor(aShadowColor); |
|
858 gc->DrawText(iWrappedArray->At(i), textPoint); |
|
859 textPoint.iX -= 1; |
|
860 textPoint.iY -= 2; |
|
861 gc->SetBrushColor(aTextColor); |
|
862 gc->SetPenColor(aTextColor); |
|
863 gc->DrawText(iWrappedArray->At(i), textPoint); |
|
864 textPoint.iY += iTextFont->DescentInPixels() + KLineSpacing / 2; |
|
865 } |
|
866 |
|
867 gc->DiscardFont(); |
|
868 CleanupStack::PopAndDestroy(gc); |
|
869 CleanupStack::PopAndDestroy(device); |
|
870 |
|
871 #ifdef VERBOSE |
|
872 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::DrawWrappedTextL(): Out"); |
|
873 #endif |
|
874 } |
|
875 |
|
876 EXPORT_C CFbsBitmap* CVeiTitleClipGenerator::GetFirstFrameL() |
|
877 { |
|
878 LOG(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetFirstFrameL()"); |
|
879 |
|
880 iUseScaledImage = EFalse; |
|
881 iGetFrameObserver = 0; |
|
882 iGetFrameIndex = 0; |
|
883 |
|
884 if (iBackgroundImage) |
|
885 { |
|
886 iGetFrameResolution = iBackgroundImage->SizeInPixels(); |
|
887 |
|
888 LOGFMT2(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetFirstFrameL(): Using BG image resolution: (%d,%d)", \ |
|
889 iGetFrameResolution.iWidth, iGetFrameResolution.iHeight); |
|
890 } |
|
891 else |
|
892 { |
|
893 iGetFrameResolution = iMaxResolution; |
|
894 |
|
895 LOGFMT2(KVideoEditorLogFile, "CVeiTitleClipGenerator::GetFirstFrameL(): Using iMaxResolution: (%d,%d)", \ |
|
896 iGetFrameResolution.iWidth, iGetFrameResolution.iHeight); |
|
897 } |
|
898 |
|
899 iGetFrameDisplayMode = KVideoClipGenetatorDisplayMode; |
|
900 iGetFrameEnhance = EFalse; |
|
901 return FinishGetFrameL(); |
|
902 } |
|
903 |
|
904 void CVeiTitleClipGenerator::DrawMainTitleFrameL(CFbsBitmap& aBitmap, TInt aIndex) |
|
905 { |
|
906 ASSERT(iGetFrameResolution.iWidth > 0 && iGetFrameResolution.iHeight > 0); |
|
907 |
|
908 TInt inEndFrame; |
|
909 TInt outStartFrame; |
|
910 |
|
911 CalculateTransitionFrameIndices(inEndFrame, outStartFrame); |
|
912 |
|
913 TInt index = aIndex; |
|
914 |
|
915 /* Best thumbnail frame would be the one just after the transition. */ |
|
916 if (aIndex == KFrameIndexBestThumb) |
|
917 { |
|
918 if (iTransition == EVeiTitleClipTransitionFade) |
|
919 { |
|
920 /* Select a bit different looking frame for fading effects. */ |
|
921 index = inEndFrame / 2; |
|
922 } |
|
923 else |
|
924 { |
|
925 index = inEndFrame; |
|
926 } |
|
927 } |
|
928 |
|
929 TRect rect(aBitmap.SizeInPixels()); |
|
930 |
|
931 /* Calculate text points */ |
|
932 TInt yAdjust; |
|
933 if (iVerticalAlignment == EVeiTitleClipVerticalAlignmentBottom) |
|
934 { |
|
935 yAdjust = (rect.Height() - iWrappedTextBoxHeight) - KMargin; |
|
936 } |
|
937 else if (iVerticalAlignment == EVeiTitleClipVerticalAlignmentCenter) |
|
938 { |
|
939 yAdjust = (rect.Height() - iWrappedTextBoxHeight) / 2; |
|
940 } |
|
941 else |
|
942 { |
|
943 yAdjust = KMargin; |
|
944 } |
|
945 |
|
946 TPoint textPoint(rect.iTl.iX, rect.iTl.iY + yAdjust); |
|
947 |
|
948 /* Initializations for drawing the text. */ |
|
949 CFbsBitmap* textBitmap = new (ELeave) CFbsBitmap; |
|
950 CleanupStack::PushL(textBitmap); |
|
951 User::LeaveIfError(textBitmap->Create(aBitmap.SizeInPixels(), aBitmap.DisplayMode())); |
|
952 |
|
953 /* Determine shadow color. */ |
|
954 |
|
955 TRgb shadowColor; |
|
956 if (iTextColor.Gray2() > 0) |
|
957 { |
|
958 shadowColor = KRgbBlack; |
|
959 } |
|
960 else |
|
961 { |
|
962 shadowColor = KRgbWhite; |
|
963 } |
|
964 |
|
965 /* Draw the text. */ |
|
966 DrawWrappedTextL(*textBitmap, textPoint, iTextColor, iBackgroundColor, shadowColor, ETrue); |
|
967 |
|
968 /* Create mask. */ |
|
969 CFbsBitmap* maskBitmap = new (ELeave) CFbsBitmap; |
|
970 CleanupStack::PushL(maskBitmap); |
|
971 User::LeaveIfError(maskBitmap->Create(aBitmap.SizeInPixels(), EGray256)); |
|
972 |
|
973 /* Calculate fading if necessary. */ |
|
974 TInt colorIndex = 255; // default: obilque text |
|
975 if (iTransition == EVeiTitleClipTransitionFade) |
|
976 { |
|
977 if (index < inEndFrame) |
|
978 { |
|
979 // fade in |
|
980 colorIndex = index * 255 / inEndFrame; |
|
981 } |
|
982 else if (index > outStartFrame) |
|
983 { |
|
984 // fade out |
|
985 TInt endFrame = VideoFrameCount() - 1; |
|
986 colorIndex = (index - endFrame) * 255 / (outStartFrame - endFrame); |
|
987 } |
|
988 } |
|
989 |
|
990 textPoint = TPoint(rect.iTl.iX, rect.iTl.iY + yAdjust); |
|
991 DrawWrappedTextL(*maskBitmap, textPoint, TRgb::Gray256(colorIndex), TRgb::Gray256(0), TRgb::Gray256(colorIndex), ETrue); |
|
992 |
|
993 /* Combine aBitmap & mask. */ |
|
994 CFbsDevice* device = CFbsBitmapDevice::NewL(&aBitmap); |
|
995 CleanupStack::PushL(device); |
|
996 CFbsBitGc* gc = NULL; |
|
997 device->CreateContext(gc); |
|
998 CleanupStack::PushL(gc); |
|
999 |
|
1000 gc->BitBltMasked(TPoint(0,0), textBitmap, rect, maskBitmap, EFalse); |
|
1001 |
|
1002 CleanupStack::PopAndDestroy(gc); |
|
1003 CleanupStack::PopAndDestroy(device); |
|
1004 CleanupStack::PopAndDestroy(maskBitmap); |
|
1005 CleanupStack::PopAndDestroy(textBitmap); |
|
1006 } |
|
1007 |
|
1008 |
|
1009 void CVeiTitleClipGenerator::DrawScrollTitleFrameL(CFbsBitmap& aBitmap, TInt aIndex) |
|
1010 { |
|
1011 TInt index = aIndex; |
|
1012 |
|
1013 TInt numberOfFrames = VideoFrameCount(); |
|
1014 |
|
1015 /* Select thumbnail so that it's a bit different from the centered ones. */ |
|
1016 if (aIndex == KFrameIndexBestThumb) |
|
1017 { |
|
1018 index = numberOfFrames - numberOfFrames / 3; |
|
1019 } |
|
1020 |
|
1021 TRect rect(aBitmap.SizeInPixels()); |
|
1022 TPoint textPoint; |
|
1023 |
|
1024 /* Calculate amounts for vertical scrollers. */ |
|
1025 TInt yTravelPerFrame = (rect.Height() + iWrappedTextBoxHeight) / numberOfFrames + 1; |
|
1026 TInt yStartPoint = (rect.iTl.iY - iWrappedTextBoxHeight) - 10; |
|
1027 |
|
1028 TRgb shadowColor; |
|
1029 if (iTextColor.Gray2() > 0) |
|
1030 { |
|
1031 shadowColor = KRgbBlack; |
|
1032 } |
|
1033 else |
|
1034 { |
|
1035 shadowColor = KRgbWhite; |
|
1036 } |
|
1037 |
|
1038 if (iTransition == EVeiTitleClipTransitionScrollBottomToTop) |
|
1039 { |
|
1040 textPoint.iY = yStartPoint + yTravelPerFrame * (numberOfFrames - index); |
|
1041 DrawWrappedTextL(aBitmap, textPoint, iTextColor, iBackgroundColor, shadowColor, EFalse); |
|
1042 } |
|
1043 else |
|
1044 { |
|
1045 CFbsDevice* device = CFbsBitmapDevice::NewL(&aBitmap); |
|
1046 CFbsBitGc* gc = NULL; |
|
1047 device->CreateContext(gc); |
|
1048 |
|
1049 GetTextFont(); |
|
1050 gc->UseFont(iTextFont); |
|
1051 |
|
1052 gc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
1053 gc->SetPenSize(TSize(1,1)); |
|
1054 |
|
1055 /* Calculate scroll amounts for horizontal scrollers. */ |
|
1056 TInt xTravelPerFrame = (rect.Width() + iTextFont->TextWidthInPixels(*iText)) / numberOfFrames + 1; |
|
1057 TInt xStartPoint = ( rect.iTl.iX - iTextFont->TextWidthInPixels(*iText) ) - 10; |
|
1058 |
|
1059 if (iTransition == EVeiTitleClipTransitionScrollTopToBottom) |
|
1060 { |
|
1061 textPoint.iY = yStartPoint + yTravelPerFrame * index; |
|
1062 |
|
1063 /* Draw texts. */ |
|
1064 for (TInt i = iWrappedArray->Count(); i > 0; i--) |
|
1065 { |
|
1066 TInt textWidth = iTextFont->TextWidthInPixels(iWrappedArray->At(i - 1)); |
|
1067 TInt baseX = 0; |
|
1068 switch(HorizontalAlignment()) |
|
1069 { |
|
1070 case EVeiTitleClipHorizontalAlignmentCenter: |
|
1071 baseX = (rect.Width() - textWidth) / 2; |
|
1072 break; |
|
1073 case EVeiTitleClipHorizontalAlignmentLeft: |
|
1074 baseX = 0; |
|
1075 break; |
|
1076 case EVeiTitleClipHorizontalAlignmentRight: |
|
1077 baseX = rect.iBr.iX - textWidth; |
|
1078 break; |
|
1079 default: |
|
1080 TVedPanic::Panic(TVedPanic::EInternal); |
|
1081 } |
|
1082 textPoint.iX = baseX + 1; |
|
1083 textPoint.iY += iTextFont->AscentInPixels() + KLineSpacing / 2 + 2; |
|
1084 gc->SetBrushColor(shadowColor); |
|
1085 gc->SetPenColor(shadowColor); |
|
1086 gc->DrawText(iWrappedArray->At(i), textPoint); |
|
1087 textPoint.iX -= 1; |
|
1088 textPoint.iY -= 2; |
|
1089 gc->SetBrushColor(TextColor()); |
|
1090 gc->SetPenColor(TextColor()); |
|
1091 gc->DrawText(iWrappedArray->At(i), textPoint); |
|
1092 textPoint.iY += iTextFont->DescentInPixels() + KLineSpacing / 2; |
|
1093 } |
|
1094 } |
|
1095 else if (iTransition == EVeiTitleClipTransitionScrollRightToLeft) |
|
1096 { |
|
1097 textPoint.iY = rect.Height() / 2 + 2; |
|
1098 textPoint.iX = xStartPoint + xTravelPerFrame * (numberOfFrames - index) + 1; |
|
1099 gc->SetBrushColor(shadowColor); |
|
1100 gc->SetPenColor(shadowColor); |
|
1101 gc->DrawText(*iText, textPoint); |
|
1102 textPoint.iX -= 1; |
|
1103 textPoint.iY -= 2; |
|
1104 gc->SetBrushColor(TextColor()); |
|
1105 gc->SetPenColor(TextColor()); |
|
1106 gc->DrawText(*iText, textPoint); |
|
1107 } |
|
1108 else if (iTransition == EVeiTitleClipTransitionScrollLeftToRight) |
|
1109 { |
|
1110 textPoint.iX = xStartPoint + xTravelPerFrame * index + 1; |
|
1111 textPoint.iY = rect.Height() / 2 + 2; |
|
1112 gc->SetBrushColor(shadowColor); |
|
1113 gc->SetPenColor(shadowColor); |
|
1114 gc->DrawText(*iText, textPoint); |
|
1115 textPoint.iX -= 1; |
|
1116 textPoint.iY -= 2; |
|
1117 gc->SetBrushColor(TextColor()); |
|
1118 gc->SetPenColor(TextColor()); |
|
1119 gc->DrawText(*iText, textPoint); |
|
1120 } |
|
1121 |
|
1122 gc->DiscardFont(); |
|
1123 delete gc; |
|
1124 delete device; |
|
1125 } |
|
1126 } |
|
1127 |
|
1128 TInt CVeiTitleClipGenerator::MaximumFramerate() const |
|
1129 { |
|
1130 TInt maxFrameRate; |
|
1131 if (IsInserted()) |
|
1132 { |
|
1133 maxFrameRate = Movie()->MaximumFramerate(); |
|
1134 if (maxFrameRate > KMaxFrameRate) |
|
1135 { |
|
1136 maxFrameRate = KMaxFrameRate; |
|
1137 } |
|
1138 } |
|
1139 else |
|
1140 { |
|
1141 maxFrameRate = KMaxFrameRate; |
|
1142 } |
|
1143 |
|
1144 #ifdef VERBOSE |
|
1145 LOGFMT(KVideoEditorLogFile, "CVeiTitleClipGenerator::MaximumFramerate(): %d", maxFrameRate); |
|
1146 #endif |
|
1147 |
|
1148 return maxFrameRate; |
|
1149 } |
|
1150 |
|
1151 ////////////////////////////////////////////////////////////////////////// |
|
1152 // Decode operation |
|
1153 ////////////////////////////////////////////////////////////////////////// |
|
1154 |
|
1155 |
|
1156 CVeiTitleClipImageDecodeOperation* CVeiTitleClipImageDecodeOperation::NewL( |
|
1157 CVeiTitleClipGenerator& aGenerator, |
|
1158 MVeiTitleClipGeneratorObserver& aObserver, |
|
1159 const TDesC& aFilename, |
|
1160 TInt aPriority) |
|
1161 { |
|
1162 CVeiTitleClipImageDecodeOperation* self = |
|
1163 new (ELeave) CVeiTitleClipImageDecodeOperation(aGenerator, |
|
1164 aObserver, |
|
1165 aPriority); |
|
1166 CleanupStack::PushL(self); |
|
1167 self->ConstructL(aFilename); |
|
1168 CleanupStack::Pop(self); |
|
1169 return self; |
|
1170 } |
|
1171 |
|
1172 CVeiTitleClipImageDecodeOperation::CVeiTitleClipImageDecodeOperation(CVeiTitleClipGenerator& aGenerator, |
|
1173 MVeiTitleClipGeneratorObserver& aObserver, |
|
1174 TInt aPriority) |
|
1175 : CActive(aPriority), iGenerator(aGenerator), iObserver(&aObserver) |
|
1176 { |
|
1177 CActiveScheduler::Add(this); |
|
1178 } |
|
1179 |
|
1180 |
|
1181 CVeiTitleClipImageDecodeOperation* CVeiTitleClipImageDecodeOperation::NewL( |
|
1182 CVeiTitleClipGenerator& aGenerator, |
|
1183 CFbsBitmap* aSourceBitmap, |
|
1184 TInt aPriority) |
|
1185 { |
|
1186 CVeiTitleClipImageDecodeOperation* self = |
|
1187 new (ELeave) CVeiTitleClipImageDecodeOperation(aGenerator, |
|
1188 aSourceBitmap, |
|
1189 aPriority); |
|
1190 return self; |
|
1191 } |
|
1192 |
|
1193 |
|
1194 CVeiTitleClipImageDecodeOperation::CVeiTitleClipImageDecodeOperation( |
|
1195 CVeiTitleClipGenerator& aGenerator, |
|
1196 CFbsBitmap* aSourceBitmap, |
|
1197 TInt aPriority) |
|
1198 : CActive(aPriority), iGenerator(aGenerator), iObserver(0), iBitmap(aSourceBitmap), iNotifyObserver(EFalse) |
|
1199 { |
|
1200 CActiveScheduler::Add(this); |
|
1201 } |
|
1202 |
|
1203 |
|
1204 void CVeiTitleClipImageDecodeOperation::ConstructL(const TDesC& aFilename) |
|
1205 { |
|
1206 LOGFMT(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::constructL(): In: aFilename: %S", &aFilename); |
|
1207 |
|
1208 RFs& fs = CCoeEnv::Static()->FsSession(); |
|
1209 iDecoder = CImageDecoder::FileNewL(fs, aFilename); |
|
1210 iNotifyObserver = ETrue; |
|
1211 |
|
1212 LOG(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::ConstructL(): Out"); |
|
1213 } |
|
1214 |
|
1215 CVeiTitleClipImageDecodeOperation::~CVeiTitleClipImageDecodeOperation() |
|
1216 { |
|
1217 Cancel(); |
|
1218 |
|
1219 delete iDecoder; |
|
1220 iDecoder = 0; |
|
1221 delete iScaler; |
|
1222 iScaler = 0; |
|
1223 delete iBitmap; |
|
1224 iBitmap = 0; |
|
1225 iObserver = 0; |
|
1226 } |
|
1227 |
|
1228 void CVeiTitleClipImageDecodeOperation::DoCancel() |
|
1229 { |
|
1230 LOG(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::DoCancel(): In"); |
|
1231 |
|
1232 if (iDecoder) |
|
1233 { |
|
1234 iDecoder->Cancel(); |
|
1235 } |
|
1236 |
|
1237 delete iScaler; |
|
1238 iScaler = 0; |
|
1239 delete iDecoder; |
|
1240 iDecoder = 0; |
|
1241 delete iBitmap; |
|
1242 iBitmap = 0; |
|
1243 |
|
1244 if (iNotifyObserver) |
|
1245 { |
|
1246 iObserver->NotifyTitleClipBackgroundImageLoadComplete(iGenerator, KErrCancel); |
|
1247 } |
|
1248 else |
|
1249 { |
|
1250 TRAP_IGNORE( iGenerator.FinishGetFrameL() ); |
|
1251 } |
|
1252 |
|
1253 LOG(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::DoCancel(): Out"); |
|
1254 } |
|
1255 |
|
1256 void CVeiTitleClipImageDecodeOperation::RunL() |
|
1257 { |
|
1258 switch(iDecodePhase) |
|
1259 { |
|
1260 case EPhaseLoading: |
|
1261 { |
|
1262 StartScalingOperationL(iGenerator.iMaxResolution); |
|
1263 break; |
|
1264 } |
|
1265 case EPhaseScaling: |
|
1266 { |
|
1267 delete iDecoder; |
|
1268 iDecoder = 0; |
|
1269 delete iScaler; |
|
1270 iScaler = 0; |
|
1271 iDecodePhase = EPhaseComplete; |
|
1272 if (iNotifyObserver) |
|
1273 { |
|
1274 /* Notify observer. */ |
|
1275 iObserver->NotifyTitleClipBackgroundImageLoadComplete(iGenerator, KErrNone); |
|
1276 |
|
1277 /* Transfer ownership of iBitmap to generator. */ |
|
1278 iGenerator.iBackgroundImage = iBitmap; |
|
1279 iBitmap = 0; |
|
1280 iGenerator.UpdateFirstFrameComplexityFactorL(); |
|
1281 iGenerator.ReportSettingsChanged(); |
|
1282 } |
|
1283 else |
|
1284 { |
|
1285 iGenerator.iScaledBackgroundImage = iBitmap; |
|
1286 iBitmap = 0; |
|
1287 iGenerator.FinishGetFrameL(); |
|
1288 } |
|
1289 break; |
|
1290 } |
|
1291 default: |
|
1292 TVedPanic::Panic(TVedPanic::EInternal); |
|
1293 } |
|
1294 } |
|
1295 |
|
1296 TInt CVeiTitleClipImageDecodeOperation::RunError(TInt aError) |
|
1297 { |
|
1298 LOGFMT(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::RunError(): In: %d", aError); |
|
1299 if (iDecoder) |
|
1300 { |
|
1301 iDecoder->Cancel(); |
|
1302 } |
|
1303 |
|
1304 delete iScaler; |
|
1305 iScaler = 0; |
|
1306 delete iDecoder; |
|
1307 iDecoder = 0; |
|
1308 delete iBitmap; |
|
1309 iBitmap = 0; |
|
1310 |
|
1311 TInt err = KErrNone; |
|
1312 if (iNotifyObserver) |
|
1313 { |
|
1314 iObserver->NotifyTitleClipBackgroundImageLoadComplete(iGenerator, aError); |
|
1315 } |
|
1316 else |
|
1317 { |
|
1318 TRAP(err, iGenerator.FinishGetFrameL(aError) ); |
|
1319 } |
|
1320 |
|
1321 LOGFMT(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::RunError(): Out: %d", err); |
|
1322 return err; |
|
1323 } |
|
1324 |
|
1325 void CVeiTitleClipImageDecodeOperation::StartLoadOperationL(const TSize& aMaxResolution) |
|
1326 { |
|
1327 LOGFMT2(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::StartLoadOperationL(): In: aMaxResolution: (%d,%d)", aMaxResolution.iWidth, aMaxResolution.iHeight); |
|
1328 |
|
1329 __ASSERT_ALWAYS(!IsActive(), TVedPanic::Panic(TVedPanic::EInternal)); |
|
1330 |
|
1331 iDecodePhase = EPhaseLoading; |
|
1332 |
|
1333 const TFrameInfo& info = iDecoder->FrameInfo(); |
|
1334 TSize targetResolution(0, 0); |
|
1335 const TSize sourceResolution(info.iOverallSizeInPixels); |
|
1336 |
|
1337 /* Calculate resolution. */ |
|
1338 |
|
1339 if ((sourceResolution.iWidth <= aMaxResolution.iWidth) |
|
1340 && (sourceResolution.iHeight <= aMaxResolution.iHeight)) |
|
1341 { |
|
1342 targetResolution.iWidth = sourceResolution.iWidth; |
|
1343 targetResolution.iHeight = sourceResolution.iHeight; |
|
1344 } |
|
1345 else if (info.iFlags & TFrameInfo::EFullyScaleable) |
|
1346 { |
|
1347 if ((sourceResolution.iWidth * aMaxResolution.iWidth) > |
|
1348 (sourceResolution.iHeight * aMaxResolution.iHeight)) |
|
1349 { |
|
1350 targetResolution.iWidth = aMaxResolution.iWidth; |
|
1351 targetResolution.iHeight = |
|
1352 (targetResolution.iWidth * sourceResolution.iHeight) / sourceResolution.iWidth; |
|
1353 } |
|
1354 else |
|
1355 { |
|
1356 targetResolution.iHeight = aMaxResolution.iHeight; |
|
1357 targetResolution.iWidth = |
|
1358 (targetResolution.iHeight * sourceResolution.iWidth) / sourceResolution.iHeight; |
|
1359 } |
|
1360 } |
|
1361 else |
|
1362 { |
|
1363 targetResolution.iWidth = (sourceResolution.iWidth / 8) + 1; |
|
1364 targetResolution.iHeight = (sourceResolution.iHeight / 8) + 1; |
|
1365 |
|
1366 if ((targetResolution.iWidth < aMaxResolution.iWidth) |
|
1367 && (targetResolution.iHeight < aMaxResolution.iHeight)) |
|
1368 { |
|
1369 targetResolution.iWidth = (sourceResolution.iWidth / 4) + 1; |
|
1370 targetResolution.iHeight = (sourceResolution.iHeight / 4) + 1; |
|
1371 } |
|
1372 |
|
1373 if ((targetResolution.iWidth < aMaxResolution.iWidth) |
|
1374 && (targetResolution.iHeight < aMaxResolution.iHeight)) |
|
1375 { |
|
1376 targetResolution.iWidth = (sourceResolution.iWidth / 2) + 1; |
|
1377 targetResolution.iHeight = (sourceResolution.iHeight / 2) + 1; |
|
1378 } |
|
1379 |
|
1380 if ((targetResolution.iWidth < aMaxResolution.iWidth) |
|
1381 && (targetResolution.iHeight < aMaxResolution.iHeight)) |
|
1382 { |
|
1383 targetResolution.iWidth = (sourceResolution.iWidth); |
|
1384 targetResolution.iHeight = (sourceResolution.iHeight); |
|
1385 } |
|
1386 } |
|
1387 |
|
1388 iBitmap = new (ELeave) CFbsBitmap; |
|
1389 TInt err = iBitmap->Create(targetResolution, EColor64K); |
|
1390 |
|
1391 if (err != KErrNone) |
|
1392 { |
|
1393 delete iBitmap; |
|
1394 iBitmap = 0; |
|
1395 iObserver->NotifyTitleClipBackgroundImageLoadComplete(iGenerator, err); |
|
1396 return; |
|
1397 } |
|
1398 |
|
1399 iDecoder->Convert(&iStatus, *iBitmap); |
|
1400 SetActive(); |
|
1401 |
|
1402 LOG(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::StartLoadingOperationL(): Out"); |
|
1403 } |
|
1404 |
|
1405 |
|
1406 void CVeiTitleClipImageDecodeOperation::StartScalingOperationL(const TSize& aResolution) |
|
1407 { |
|
1408 LOGFMT2(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::StartScalingOperationL(): In: aResolution: (%d,%d)", aResolution.iWidth, aResolution.iHeight); |
|
1409 |
|
1410 __ASSERT_ALWAYS(!IsActive(), TVedPanic::Panic(TVedPanic::EInternal)); |
|
1411 |
|
1412 iDecodePhase = EPhaseScaling; |
|
1413 |
|
1414 TSize sourceRes = iBitmap->SizeInPixels(); |
|
1415 TSize destRes(aResolution); |
|
1416 TSize movieRes = iGenerator.Movie()->Resolution(); |
|
1417 |
|
1418 if (destRes.iHeight > movieRes.iHeight || destRes.iWidth > movieRes.iWidth) |
|
1419 { |
|
1420 movieRes = destRes; |
|
1421 } |
|
1422 |
|
1423 TSize imageResInMovie(0,0); |
|
1424 if ((sourceRes.iWidth > movieRes.iWidth) || (sourceRes.iHeight > movieRes.iHeight)) |
|
1425 { |
|
1426 LOG(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::StartScalingOperationL downscaling"); |
|
1427 // Downscaling |
|
1428 if ((sourceRes.iWidth * movieRes.iHeight) < |
|
1429 (sourceRes.iHeight * movieRes.iWidth)) |
|
1430 { |
|
1431 imageResInMovie.iWidth = movieRes.iWidth; |
|
1432 imageResInMovie.iHeight = |
|
1433 (movieRes.iWidth * sourceRes.iHeight) / sourceRes.iWidth; |
|
1434 } |
|
1435 else |
|
1436 { |
|
1437 imageResInMovie.iHeight = movieRes.iHeight; |
|
1438 imageResInMovie.iWidth = |
|
1439 (movieRes.iHeight * sourceRes.iWidth) / sourceRes.iHeight; |
|
1440 } |
|
1441 } |
|
1442 else if (iNotifyObserver) |
|
1443 { |
|
1444 imageResInMovie = sourceRes; |
|
1445 } |
|
1446 else |
|
1447 { |
|
1448 LOG(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::StartScalingOperationL upscaling"); |
|
1449 // Upscaling - limit to a factor of two |
|
1450 if ((sourceRes.iWidth * movieRes.iHeight) < |
|
1451 (sourceRes.iHeight * movieRes.iWidth)) |
|
1452 { |
|
1453 imageResInMovie.iWidth = Min(movieRes.iWidth, (sourceRes.iWidth * 2)); |
|
1454 imageResInMovie.iHeight = Min((sourceRes.iHeight * 2), |
|
1455 ((movieRes.iWidth * sourceRes.iHeight) / sourceRes.iWidth)); |
|
1456 } |
|
1457 else |
|
1458 { |
|
1459 imageResInMovie.iHeight = Min((sourceRes.iHeight * 2), movieRes.iHeight); |
|
1460 imageResInMovie.iWidth = Min((sourceRes.iWidth * 2), |
|
1461 ((movieRes.iHeight * sourceRes.iWidth) / sourceRes.iHeight)); |
|
1462 } |
|
1463 } |
|
1464 |
|
1465 TSize movieResInDestBitmap(-1,-1); |
|
1466 if ((movieRes.iWidth * destRes.iHeight) < |
|
1467 (movieRes.iHeight * destRes.iWidth)) |
|
1468 { |
|
1469 movieResInDestBitmap.iWidth = destRes.iWidth; |
|
1470 movieResInDestBitmap.iHeight = |
|
1471 (movieResInDestBitmap.iWidth * movieRes.iHeight) / movieRes.iWidth; |
|
1472 } |
|
1473 else |
|
1474 { |
|
1475 movieResInDestBitmap.iHeight = destRes.iHeight; |
|
1476 movieResInDestBitmap.iWidth = |
|
1477 (movieResInDestBitmap.iHeight * movieRes.iWidth) / movieRes.iHeight; |
|
1478 } |
|
1479 |
|
1480 |
|
1481 TSize targetRes(imageResInMovie); |
|
1482 targetRes.iWidth = imageResInMovie.iWidth * movieResInDestBitmap.iWidth / movieRes.iWidth; |
|
1483 targetRes.iHeight = imageResInMovie.iHeight * movieResInDestBitmap.iHeight / movieRes.iHeight; |
|
1484 |
|
1485 LOGFMT12(KVideoEditorLogFile,\ |
|
1486 "CVeiTitleClipOperation::StartOperation() sourceRes=(%d,%d) movieRes=(%d,%d) destRes=(%d,%d) targetRes=(%d,%d) imageResInMovie=(%d,%d) movieResInDestBitmap=(%d,%d)", \ |
|
1487 sourceRes.iWidth, sourceRes.iHeight, \ |
|
1488 movieRes.iWidth, movieRes.iHeight, \ |
|
1489 destRes.iWidth, destRes.iHeight, \ |
|
1490 targetRes.iWidth, targetRes.iHeight, \ |
|
1491 imageResInMovie.iWidth, imageResInMovie.iHeight, \ |
|
1492 movieResInDestBitmap.iWidth, movieResInDestBitmap.iHeight); |
|
1493 |
|
1494 |
|
1495 if (iGenerator.iScaledBackgroundImage) |
|
1496 { |
|
1497 TSize scaledRes = iGenerator.iScaledBackgroundImage->SizeInPixels(); |
|
1498 if ((scaledRes.iWidth == targetRes.iWidth) || (scaledRes.iHeight == targetRes.iHeight)) |
|
1499 { |
|
1500 LOG(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::StartScalingOperationL Using scaled"); |
|
1501 iGenerator.FinishGetFrameL(); |
|
1502 return; |
|
1503 } |
|
1504 } |
|
1505 |
|
1506 delete iScaler; |
|
1507 iScaler = NULL; |
|
1508 iScaler = CBitmapScaler::NewL(); |
|
1509 iScaler->Scale(&iStatus, *iBitmap, targetRes, EFalse); |
|
1510 SetActive(); |
|
1511 |
|
1512 LOG(KVideoEditorLogFile, "CVeiTitleClipImageDecodeOperation::StartScalingOperationL(): Out"); |
|
1513 } |
|
1514 |
|
1515 // End of File |