|
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalComponent |
|
19 */ |
|
20 |
|
21 #include <e32std.h> |
|
22 #include <e32base.h> |
|
23 #include <e32math.h> |
|
24 #include <e32svr.h> |
|
25 #include <bitstd.h> |
|
26 #include <bitdev.h> |
|
27 #include <fbs.h> |
|
28 #include <w32adll.h> |
|
29 |
|
30 #include "tfep2be.h" |
|
31 #include "tfep2com.h" |
|
32 |
|
33 #define DEBUGGING_MESSAGES |
|
34 |
|
35 // numeric constants |
|
36 |
|
37 const TInt KPanicClientFromServer=1; // must be greater than zero (CTstHandWritingRecognizer::OfferRawEvent assumes this to be true) |
|
38 |
|
39 // literal constant text |
|
40 |
|
41 #if defined(_DEBUG) |
|
42 _LIT(KLitTFEP2BE, "TFEP2BE"); |
|
43 #endif |
|
44 |
|
45 // local and global functions |
|
46 |
|
47 #if defined(_DEBUG) |
|
48 |
|
49 enum TPanic |
|
50 { |
|
51 EPanicUnexpectedError=1, |
|
52 EPanicBadDataInDllTls, |
|
53 EPanicUnexpectedRawEvent, |
|
54 EPanicTimerActive1, |
|
55 EPanicTimerActive2, |
|
56 EPanicNoPendingCharactersToMove, |
|
57 EPanicUnexpectedNullPointer1, |
|
58 EPanicUnexpectedNullPointer2, |
|
59 EPanicBadGranularity, |
|
60 EPanicAlreadyConstructed, |
|
61 EPanicNonAlignedDescriptorLength1, |
|
62 EPanicNonAlignedDescriptorLength2, |
|
63 EPanicNonAlignedDescriptorMaximumLength, |
|
64 EPanicBadDescriptorLength, |
|
65 EPanicBadNumberOfCharacters1, |
|
66 EPanicBadNumberOfCharacters2 |
|
67 }; |
|
68 |
|
69 LOCAL_C void Panic(TPanic aPanic) |
|
70 { |
|
71 User::Panic(KLitTFEP2BE, aPanic); |
|
72 } |
|
73 |
|
74 #endif |
|
75 |
|
76 LOCAL_C void PanicClientFromServer() |
|
77 { |
|
78 User::Leave(KPanicClientFromServer); |
|
79 } |
|
80 |
|
81 LOCAL_C void HandleErrorIfErrorL(MAnimGeneralFunctions& aFunctions, TInt aError) |
|
82 { |
|
83 switch (aError) |
|
84 { |
|
85 case KErrNone: |
|
86 break; |
|
87 case KPanicClientFromServer: |
|
88 aFunctions.Panic(); |
|
89 break; |
|
90 default: |
|
91 User::Leave(aError); |
|
92 break; |
|
93 } |
|
94 } |
|
95 |
|
96 LOCAL_C void HandleErrorIfError(MAnimGeneralFunctions& aFunctions, TInt aError) |
|
97 { |
|
98 switch (aError) |
|
99 { |
|
100 case KErrNone: |
|
101 break; |
|
102 case KPanicClientFromServer: |
|
103 aFunctions.Panic(); |
|
104 break; |
|
105 default: |
|
106 #if defined(_DEBUG) |
|
107 Panic(EPanicUnexpectedError); |
|
108 #endif |
|
109 break; |
|
110 } |
|
111 } |
|
112 |
|
113 GLDEF_C TInt E32Dll( |
|
114 ) |
|
115 { |
|
116 return KErrNone; |
|
117 } |
|
118 |
|
119 // CTstHandWritingRecognizer |
|
120 |
|
121 CTstHandWritingRecognizer::CTstHandWritingRecognizer() |
|
122 :iFlags(0), |
|
123 iArrayOfPolyLines(12), |
|
124 iArrayOfCharactersPending(10), |
|
125 iTimeOutTimer(NULL), |
|
126 iMessage_RequestForNotificationOfStartOfTransaction(), |
|
127 iMessage_RequestForCharacters(), |
|
128 iMaximumLengthOfClientSideCharacterBuffer(0), |
|
129 iMainBitmap(NULL), |
|
130 iMaskBitmap(NULL), |
|
131 iGraphicsContext(NULL) |
|
132 { |
|
133 } |
|
134 |
|
135 CTstHandWritingRecognizer::~CTstHandWritingRecognizer() |
|
136 { |
|
137 iFunctions->GetRawEvents(EFalse); |
|
138 iSpriteFunctions->Activate(EFalse); |
|
139 if (iFlags&EFlagReferenceCountIncremented) |
|
140 { |
|
141 SBitmapHandlesWithReferenceCount* const bitmapHandlesWithReferenceCount=STATIC_CAST(SBitmapHandlesWithReferenceCount*, Dll::Tls()); |
|
142 __ASSERT_DEBUG((bitmapHandlesWithReferenceCount!=NULL) && (bitmapHandlesWithReferenceCount->iReferenceCount>0), Panic(EPanicBadDataInDllTls)); |
|
143 --bitmapHandlesWithReferenceCount->iReferenceCount; |
|
144 if (bitmapHandlesWithReferenceCount->iReferenceCount==0) |
|
145 { |
|
146 delete bitmapHandlesWithReferenceCount; |
|
147 Dll::SetTls(NULL); |
|
148 } |
|
149 } |
|
150 iArrayOfPolyLines.ResetAndDestroy(); |
|
151 iArrayOfPolyLines.Close(); |
|
152 iArrayOfCharactersPending.Close(); |
|
153 delete iTimeOutTimer; |
|
154 delete iGraphicsContext; |
|
155 delete iMainBitmap; |
|
156 delete iMaskBitmap; |
|
157 } |
|
158 |
|
159 void CTstHandWritingRecognizer::HandleTimeOut() |
|
160 { |
|
161 TRAPD(error, DoRecognitionL()); |
|
162 CompleteRequestForCharacters(error); |
|
163 } |
|
164 |
|
165 void CTstHandWritingRecognizer::ConstructLP(TAny* /*aParameters*/) |
|
166 { |
|
167 // this functions does not actually construct anything, but simply writes the bitmap handles stored in Dll::Tls() (if any) to the client's descriptor |
|
168 STstBitmapHandles bitmapHandles(0, 0); |
|
169 const SBitmapHandlesWithReferenceCount* const bitmapHandlesWithReferenceCount=REINTERPRET_CAST(const SBitmapHandlesWithReferenceCount*, Dll::Tls()); |
|
170 if (bitmapHandlesWithReferenceCount!=NULL) |
|
171 { |
|
172 bitmapHandles=bitmapHandlesWithReferenceCount->iBitmapHandles; |
|
173 } |
|
174 iFunctions->Message()->WriteL(EIpcSlot, TPckgC<STstBitmapHandles>(bitmapHandles)); |
|
175 } |
|
176 |
|
177 TInt CTstHandWritingRecognizer::CommandReplyLP(TInt aOpcode, TAny* aParameters) |
|
178 { |
|
179 switch (aOpcode) |
|
180 { |
|
181 case EHandWritingRecognizerCommandFinishConstructionL: |
|
182 { |
|
183 __ASSERT_ALWAYS(iFlags==0, PanicClientFromServer()); |
|
184 iFunctions->SetSync(MAnimGeneralFunctions::ESyncNone); |
|
185 iSpriteFunctions->SizeChangedL(); |
|
186 iArrayOfCharactersPending.ConstructL(); |
|
187 iTimeOutTimer=CTimeOutTimer::NewL(*this); |
|
188 const TSpriteMember* const spriteMember=iSpriteFunctions->GetSpriteMember(0); |
|
189 __ASSERT_ALWAYS((spriteMember!=NULL) && (spriteMember->iBitmap!=NULL) && (spriteMember->iMaskBitmap!=NULL), PanicClientFromServer()); |
|
190 const STstBitmapHandles bitmapHandles(spriteMember->iBitmap->Handle(), spriteMember->iMaskBitmap->Handle()); |
|
191 SBitmapHandlesWithReferenceCount* bitmapHandlesWithReferenceCount=STATIC_CAST(SBitmapHandlesWithReferenceCount*, Dll::Tls()); |
|
192 if (bitmapHandlesWithReferenceCount!=NULL) |
|
193 { |
|
194 __ASSERT_ALWAYS((bitmapHandlesWithReferenceCount->iBitmapHandles.iMain==bitmapHandles.iMain) && (bitmapHandlesWithReferenceCount->iBitmapHandles.iMask==bitmapHandles.iMask), PanicClientFromServer()); |
|
195 ++bitmapHandlesWithReferenceCount->iReferenceCount; |
|
196 } |
|
197 else |
|
198 { |
|
199 bitmapHandlesWithReferenceCount=new(ELeave) SBitmapHandlesWithReferenceCount; |
|
200 CleanupStack::PushL(bitmapHandlesWithReferenceCount); |
|
201 bitmapHandlesWithReferenceCount->iBitmapHandles=bitmapHandles; |
|
202 bitmapHandlesWithReferenceCount->iReferenceCount=1; |
|
203 User::LeaveIfError(Dll::SetTls(bitmapHandlesWithReferenceCount)); |
|
204 CleanupStack::Pop(); // bitmapHandlesWithReferenceCount |
|
205 } |
|
206 iFlags|=EFlagReferenceCountIncremented; |
|
207 #if defined(DEBUGGING_MESSAGES) |
|
208 RDebug::Print(_L("reference-count of the bitmap handles: %d"), bitmapHandlesWithReferenceCount->iReferenceCount); |
|
209 #endif |
|
210 iMainBitmap=CFbsBitmapDevice::NewL(spriteMember->iBitmap); |
|
211 iMaskBitmap=CFbsBitmapDevice::NewL(spriteMember->iMaskBitmap); |
|
212 iGraphicsContext=CFbsBitGc::NewL(); |
|
213 iGraphicsContext->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
214 iGraphicsContext->SetBrushColor(KRgbWhite); |
|
215 iGraphicsContext->SetPenStyle(CGraphicsContext::ESolidPen); |
|
216 iGraphicsContext->SetPenColor(KRgbBlack); |
|
217 } |
|
218 break; |
|
219 case EHandWritingRecognizerCommandRequestNotificationOfStartOfTransaction: |
|
220 __ASSERT_ALWAYS(iMessage_RequestForNotificationOfStartOfTransaction.IsNull(), PanicClientFromServer()); |
|
221 iMessage_RequestForNotificationOfStartOfTransaction=*iFunctions->Message(); |
|
222 __ASSERT_ALWAYS(!iMessage_RequestForNotificationOfStartOfTransaction.IsNull(), PanicClientFromServer()); |
|
223 break; |
|
224 case EHandWritingRecognizerCommandCancelRequestForNotificationOfStartOfTransaction: |
|
225 if (!iMessage_RequestForNotificationOfStartOfTransaction.IsNull()) |
|
226 { |
|
227 iMessage_RequestForNotificationOfStartOfTransaction.Complete(KErrCancel); |
|
228 } |
|
229 break; |
|
230 case EHandWritingRecognizerCommandRequestCharacters: |
|
231 __ASSERT_ALWAYS(iMessage_RequestForCharacters.IsNull() && (iMaximumLengthOfClientSideCharacterBuffer==0), PanicClientFromServer()); |
|
232 iMessage_RequestForCharacters=*iFunctions->Message(); |
|
233 iMaximumLengthOfClientSideCharacterBuffer=iFunctions->Message()->GetDesMaxLength(EAsyncIpcSlot); |
|
234 __ASSERT_ALWAYS((!iMessage_RequestForCharacters.IsNull()) && (iMaximumLengthOfClientSideCharacterBuffer>=STATIC_CAST(TInt, sizeof(TUint))), PanicClientFromServer()); |
|
235 if (iArrayOfCharactersPending.Count()>0) |
|
236 { |
|
237 TRAPD(error, MovePendingCharactersToClientBufferL()); |
|
238 CompleteRequestForCharacters(error); |
|
239 } |
|
240 else |
|
241 { |
|
242 iFunctions->GetRawEvents(ETrue); |
|
243 iSpriteFunctions->Activate(ETrue); |
|
244 } |
|
245 break; |
|
246 case EHandWritingRecognizerCommandCancelRequestForCharacters: |
|
247 if (!iMessage_RequestForCharacters.IsNull()) |
|
248 { |
|
249 CompleteRequestForCharacters(KErrCancel); |
|
250 } |
|
251 break; |
|
252 case EHandWritingRecognizerCommandSetUpperCase: |
|
253 { |
|
254 STstParametersForHandWritingRecognizerCommandSetUpperCase* const parameters=REINTERPRET_CAST(STstParametersForHandWritingRecognizerCommandSetUpperCase*, aParameters); |
|
255 if (parameters->iUpperCase) |
|
256 { |
|
257 iFlags|=EFlagUpperCase; |
|
258 } |
|
259 else |
|
260 { |
|
261 iFlags&=~EFlagUpperCase; |
|
262 } |
|
263 } |
|
264 break; |
|
265 default: |
|
266 PanicClientFromServer(); |
|
267 break; |
|
268 } |
|
269 return KErrNone; // dummy return to prevent compiler error |
|
270 } |
|
271 |
|
272 TBool CTstHandWritingRecognizer::OfferRawEventLP(const TRawEvent& aRawEvent) |
|
273 { |
|
274 __ASSERT_DEBUG(!iMessage_RequestForCharacters.IsNull(), Panic(EPanicUnexpectedRawEvent)); |
|
275 switch (aRawEvent.Type()) |
|
276 { |
|
277 case TRawEvent::EPointerMove: |
|
278 { |
|
279 if (iFlags&EFlagPointerIsDown) // this test is needed in the cases where (i) the TRawEvent::EPointerMove event occurs when the pointer is not "down" (this is possible for some pointing devices, e.g. a mouse), and (ii) there was a "leave" when handling the TRawEvent::EButton1Down event |
|
280 { |
|
281 __ASSERT_DEBUG(!iTimeOutTimer->IsActive(), Panic(EPanicTimerActive1)); |
|
282 const TPoint thisPoint=aRawEvent.Pos(); |
|
283 CArrayFix<TPoint>& polyLine=*iArrayOfPolyLines[iArrayOfPolyLines.Count()-1]; |
|
284 polyLine.AppendL(thisPoint); |
|
285 const TPoint previousPoint=polyLine[polyLine.Count()-2]; |
|
286 TRect rectangleDrawnTo; |
|
287 DrawLine(*iMainBitmap, rectangleDrawnTo, EPenWidthForMainBitmap, previousPoint, thisPoint); |
|
288 TRect temp; |
|
289 DrawLine(*iMaskBitmap, temp, EPenWidthForMaskBitmap, previousPoint, thisPoint); |
|
290 rectangleDrawnTo.BoundingRect(temp); |
|
291 Plot(*iMainBitmap, temp, EPenWidthForMainBitmap, thisPoint); |
|
292 rectangleDrawnTo.BoundingRect(temp); |
|
293 Plot(*iMaskBitmap, temp, EPenWidthForMaskBitmap, thisPoint); |
|
294 rectangleDrawnTo.BoundingRect(temp); |
|
295 iSpriteFunctions->UpdateMember(0, rectangleDrawnTo, EFalse); |
|
296 } |
|
297 } |
|
298 return ETrue; |
|
299 case TRawEvent::EButton1Down: |
|
300 { |
|
301 iTimeOutTimer->Cancel(); |
|
302 const TPoint thisPoint=aRawEvent.Pos(); |
|
303 CArrayFix<TPoint>* const polyLine=new(ELeave) CArrayFixSeg<TPoint>(50); |
|
304 CleanupStack::PushL(polyLine); |
|
305 polyLine->AppendL(thisPoint); |
|
306 User::LeaveIfError(iArrayOfPolyLines.Append(polyLine)); |
|
307 CleanupStack::Pop(); // polyLine |
|
308 TRect rectangleDrawnTo; |
|
309 Plot(*iMainBitmap, rectangleDrawnTo, EPenWidthForMainBitmap, thisPoint); |
|
310 TRect temp; |
|
311 Plot(*iMaskBitmap, temp, EPenWidthForMaskBitmap, thisPoint); |
|
312 rectangleDrawnTo.BoundingRect(temp); |
|
313 iSpriteFunctions->UpdateMember(0, rectangleDrawnTo, EFalse); |
|
314 iFlags|=EFlagPointerIsDown; |
|
315 if ((iArrayOfPolyLines.Count()==1) && (!iMessage_RequestForNotificationOfStartOfTransaction.IsNull())) |
|
316 { |
|
317 iMessage_RequestForNotificationOfStartOfTransaction.Complete(KErrNone); |
|
318 } |
|
319 } |
|
320 return ETrue; |
|
321 case TRawEvent::EButton1Up: |
|
322 if (iFlags&EFlagPointerIsDown) // this test is needed in the case where there was a "leave" when handling the TRawEvent::EButton1Down event |
|
323 { |
|
324 __ASSERT_DEBUG(!iTimeOutTimer->IsActive(), Panic(EPanicTimerActive2)); |
|
325 iTimeOutTimer->After(ETimeOutInMicroSeconds); |
|
326 iFlags&=~EFlagPointerIsDown; |
|
327 } |
|
328 return ETrue; |
|
329 default: |
|
330 return EFalse; |
|
331 } |
|
332 } |
|
333 |
|
334 void CTstHandWritingRecognizer::DoRecognitionL() |
|
335 { |
|
336 TInt i; |
|
337 TInt minimumX=KMaxTInt; |
|
338 TInt maximumX=KMinTInt; |
|
339 for (i=iArrayOfPolyLines.Count()-1; i>=0; --i) |
|
340 { |
|
341 const CArrayFix<TPoint>& polyLine=*iArrayOfPolyLines[i]; |
|
342 for (TInt j=polyLine.Count()-1; j>=0; --j) |
|
343 { |
|
344 const TInt x=polyLine[j].iX; |
|
345 if (minimumX>x) |
|
346 { |
|
347 minimumX=x; |
|
348 } |
|
349 if (maximumX<x) |
|
350 { |
|
351 maximumX=x; |
|
352 } |
|
353 } |
|
354 } |
|
355 const TInt numberOfCharacters=((maximumX-minimumX)/80)+1; |
|
356 TTime homeTime; |
|
357 homeTime.HomeTime(); |
|
358 TInt64 seedForRandomNumber=homeTime.Int64(); |
|
359 const TUint baseCharacter=(iFlags&EFlagUpperCase)? 'A': 'a'; |
|
360 for (i=0; i<numberOfCharacters; ++i) |
|
361 { |
|
362 iArrayOfCharactersPending.AppendL(baseCharacter+(Math::Rand(seedForRandomNumber)%26)); |
|
363 } |
|
364 MovePendingCharactersToClientBufferL(); |
|
365 } |
|
366 |
|
367 void CTstHandWritingRecognizer::MovePendingCharactersToClientBufferL() |
|
368 { |
|
369 __ASSERT_DEBUG(iArrayOfCharactersPending.Count()>0, Panic(EPanicNoPendingCharactersToMove)); |
|
370 __ASSERT_DEBUG((!iMessage_RequestForCharacters.IsNull()) && (iMaximumLengthOfClientSideCharacterBuffer>=STATIC_CAST(TInt, sizeof(TUint))), Panic(EPanicUnexpectedNullPointer1)); |
|
371 const TInt numberOfCharactersToMove=Min(iArrayOfCharactersPending.Count(), iMaximumLengthOfClientSideCharacterBuffer/sizeof(TUint)); |
|
372 iMessage_RequestForCharacters.WriteL(EAsyncIpcSlot, iArrayOfCharactersPending.DescriptorFromStart(numberOfCharactersToMove), 0); |
|
373 iArrayOfCharactersPending.RemoveFromStart(numberOfCharactersToMove); |
|
374 } |
|
375 |
|
376 void CTstHandWritingRecognizer::CompleteRequestForCharacters(TInt aErrorCode) |
|
377 { |
|
378 __ASSERT_DEBUG((!iMessage_RequestForCharacters.IsNull()) && (iMaximumLengthOfClientSideCharacterBuffer>=STATIC_CAST(TInt, sizeof(TUint))), Panic(EPanicUnexpectedNullPointer2)); |
|
379 iArrayOfPolyLines.ResetAndDestroy(); |
|
380 iArrayOfCharactersPending.Reset(); |
|
381 iTimeOutTimer->Cancel(); |
|
382 iMessage_RequestForCharacters.Complete(aErrorCode); |
|
383 iMaximumLengthOfClientSideCharacterBuffer=NULL; |
|
384 iFunctions->GetRawEvents(EFalse); |
|
385 iSpriteFunctions->Activate(EFalse); |
|
386 ClearBitmap(*iMainBitmap); |
|
387 ClearBitmap(*iMaskBitmap); |
|
388 // there is no need to call iSpriteFunctions->UpdateMember as the sprite has just been de-activated (3 lines above) |
|
389 } |
|
390 |
|
391 void CTstHandWritingRecognizer::ClearBitmap(CFbsBitmapDevice& aBitmap) |
|
392 { |
|
393 iGraphicsContext->Activate(&aBitmap); |
|
394 iGraphicsContext->Clear(); |
|
395 } |
|
396 |
|
397 void CTstHandWritingRecognizer::DrawLine(CFbsBitmapDevice& aBitmap, TRect& aRectangleDrawnTo, TInt aPenSize, const TPoint& aPoint1, const TPoint& aPoint2) |
|
398 { |
|
399 iGraphicsContext->Activate(&aBitmap); |
|
400 iGraphicsContext->SetPenSize(TSize(aPenSize, aPenSize)); |
|
401 iGraphicsContext->DrawLine(aPoint1, aPoint2); |
|
402 iGraphicsContext->RectDrawnTo(aRectangleDrawnTo); |
|
403 } |
|
404 |
|
405 void CTstHandWritingRecognizer::Plot(CFbsBitmapDevice& aBitmap, TRect& aRectangleDrawnTo, TInt aPenSize, const TPoint& aPoint) |
|
406 { |
|
407 iGraphicsContext->Activate(&aBitmap); |
|
408 iGraphicsContext->SetPenSize(TSize(aPenSize, aPenSize)); |
|
409 iGraphicsContext->Plot(aPoint); |
|
410 iGraphicsContext->RectDrawnTo(aRectangleDrawnTo); |
|
411 } |
|
412 |
|
413 void CTstHandWritingRecognizer::ConstructL(TAny* aParameters) |
|
414 { |
|
415 TRAPD(error, ConstructLP(aParameters)); |
|
416 HandleErrorIfErrorL(*iFunctions, error); |
|
417 } |
|
418 |
|
419 TInt CTstHandWritingRecognizer::CommandReplyL(TInt aOpcode, TAny* aParameters) |
|
420 { |
|
421 TInt returnVal=0; // dummy initialization to prevent compiler warning |
|
422 TRAPD(error, returnVal=CommandReplyLP(aOpcode, aParameters)); |
|
423 HandleErrorIfErrorL(*iFunctions, error); |
|
424 return returnVal; |
|
425 } |
|
426 |
|
427 void CTstHandWritingRecognizer::Command(TInt, TAny*) |
|
428 { |
|
429 iFunctions->Panic(); |
|
430 } |
|
431 |
|
432 void CTstHandWritingRecognizer::Animate(TDateTime*) |
|
433 { |
|
434 } |
|
435 |
|
436 TBool CTstHandWritingRecognizer::OfferRawEvent(const TRawEvent& aRawEvent) |
|
437 { |
|
438 TBool returnVal=0; // dummy initialization to prevent compiler warning |
|
439 TRAPD(error, returnVal=OfferRawEventLP(aRawEvent)); |
|
440 if (error>=0) // if error is a KErrXxxxx, ignore it (as OfferRawEvent cannot leave) |
|
441 { |
|
442 HandleErrorIfError(*iFunctions, error); |
|
443 } |
|
444 return returnVal; |
|
445 } |
|
446 |
|
447 // CTstHandWritingRecognizer::RFlatArrayOfCharacters |
|
448 |
|
449 CTstHandWritingRecognizer::RFlatArrayOfCharacters::RFlatArrayOfCharacters(TInt aGranularity) |
|
450 :iGranularity(aGranularity), |
|
451 iDescriptor(NULL) |
|
452 { |
|
453 __ASSERT_DEBUG(aGranularity>0, Panic(EPanicBadGranularity)); |
|
454 } |
|
455 |
|
456 void CTstHandWritingRecognizer::RFlatArrayOfCharacters::ConstructL() |
|
457 { |
|
458 __ASSERT_DEBUG(iDescriptor==NULL, Panic(EPanicAlreadyConstructed)); |
|
459 iDescriptor=HBufC8::NewL(iGranularity*sizeof(TUint)); |
|
460 } |
|
461 |
|
462 void CTstHandWritingRecognizer::RFlatArrayOfCharacters::Close() |
|
463 { |
|
464 delete iDescriptor; |
|
465 iDescriptor=NULL; |
|
466 } |
|
467 |
|
468 void CTstHandWritingRecognizer::RFlatArrayOfCharacters::AppendL(TUint aCharacter) |
|
469 { |
|
470 const TInt oldDescriptorLength=iDescriptor->Length(); |
|
471 __ASSERT_DEBUG(oldDescriptorLength%sizeof(TUint)==0, Panic(EPanicNonAlignedDescriptorLength1)); |
|
472 const TInt oldDescriptorMaximumLength=iDescriptor->Des().MaxLength(); |
|
473 __ASSERT_DEBUG(oldDescriptorMaximumLength%sizeof(TUint)==0, Panic(EPanicNonAlignedDescriptorMaximumLength)); |
|
474 if (oldDescriptorLength>=oldDescriptorMaximumLength) |
|
475 { |
|
476 iDescriptor=iDescriptor->ReAllocL(oldDescriptorLength+(iGranularity*sizeof(TUint))); |
|
477 } |
|
478 TPtr8 descriptor(iDescriptor->Des()); |
|
479 __ASSERT_DEBUG(oldDescriptorLength==descriptor.Length(), Panic(EPanicBadDescriptorLength)); |
|
480 descriptor.SetLength(oldDescriptorLength+sizeof(TUint)); |
|
481 *REINTERPRET_CAST(TUint*, CONST_CAST(TUint8*, descriptor.Ptr()+oldDescriptorLength))=aCharacter; |
|
482 } |
|
483 |
|
484 TInt CTstHandWritingRecognizer::RFlatArrayOfCharacters::Count() const |
|
485 { |
|
486 const TInt descriptorLength=iDescriptor->Length(); |
|
487 __ASSERT_DEBUG(descriptorLength%sizeof(TUint)==0, Panic(EPanicNonAlignedDescriptorLength2)); |
|
488 return descriptorLength/sizeof(TUint); |
|
489 } |
|
490 |
|
491 TPtrC8 CTstHandWritingRecognizer::RFlatArrayOfCharacters::DescriptorFromStart(TInt aNumberOfCharacters) const |
|
492 { |
|
493 __ASSERT_DEBUG((aNumberOfCharacters>0) && (aNumberOfCharacters<=Count()), Panic(EPanicBadNumberOfCharacters1)); |
|
494 return iDescriptor->Left(aNumberOfCharacters*sizeof(TUint)); |
|
495 } |
|
496 |
|
497 void CTstHandWritingRecognizer::RFlatArrayOfCharacters::RemoveFromStart(TInt aNumberOfCharacters) |
|
498 { |
|
499 __ASSERT_DEBUG((aNumberOfCharacters>0) && (aNumberOfCharacters<=Count()), Panic(EPanicBadNumberOfCharacters2)); |
|
500 TPtr8 descriptor(iDescriptor->Des()); |
|
501 descriptor.Delete(0, aNumberOfCharacters*sizeof(TUint)); |
|
502 // we could "iDescriptor=iDescriptor->ReAllocL" here to free up unused memory, but it's probably not worth it as iDescriptor will never grow very large |
|
503 } |
|
504 |
|
505 void CTstHandWritingRecognizer::RFlatArrayOfCharacters::Reset() |
|
506 { |
|
507 TPtr8 descriptor(iDescriptor->Des()); |
|
508 descriptor.SetLength(0); |
|
509 // we could "iDescriptor=iDescriptor->ReAllocL" here to free up unused memory, but it's probably not worth it as iDescriptor will never grow very large |
|
510 } |
|
511 |
|
512 // CTstHandWritingRecognizer::CTimeOutTimer |
|
513 |
|
514 CTstHandWritingRecognizer::CTimeOutTimer* CTstHandWritingRecognizer::CTimeOutTimer::NewL(CTstHandWritingRecognizer& aHandWritingRecognizer) |
|
515 { |
|
516 CTimeOutTimer* const timeOutTimer=new(ELeave) CTimeOutTimer(aHandWritingRecognizer); |
|
517 CleanupStack::PushL(timeOutTimer); |
|
518 CActiveScheduler::Add(timeOutTimer); |
|
519 timeOutTimer->ConstructL(); |
|
520 CleanupStack::Pop(); // timeOutTimer |
|
521 return timeOutTimer; |
|
522 } |
|
523 |
|
524 CTstHandWritingRecognizer::CTimeOutTimer::~CTimeOutTimer() |
|
525 { |
|
526 Cancel(); |
|
527 } |
|
528 |
|
529 CTstHandWritingRecognizer::CTimeOutTimer::CTimeOutTimer(CTstHandWritingRecognizer& aHandWritingRecognizer) |
|
530 :CTimer(EPriorityLow), |
|
531 iHandWritingRecognizer(aHandWritingRecognizer) |
|
532 { |
|
533 } |
|
534 |
|
535 void CTstHandWritingRecognizer::CTimeOutTimer::RunL() |
|
536 { |
|
537 iHandWritingRecognizer.HandleTimeOut(); |
|
538 } |
|
539 |
|
540 // CTstDll |
|
541 |
|
542 CAnim* CTstDll::CreateInstanceL(TInt aType) |
|
543 { |
|
544 switch (aType) |
|
545 { |
|
546 case EAnimTypeHandWritingRecognizer: |
|
547 return new(ELeave) CTstHandWritingRecognizer; |
|
548 default: |
|
549 User::Leave(KErrArgument); |
|
550 return NULL; // dummy return to prevent compiler error |
|
551 } |
|
552 } |
|
553 |
|
554 // the exported function |
|
555 |
|
556 EXPORT_C CAnimDll* CreateCAnimDllL() |
|
557 { |
|
558 return new(ELeave) CTstDll; |
|
559 } |
|
560 |