|
1 // Copyright (c) 1999-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 // Anim DLL to deal with handwriting |
|
15 // |
|
16 // |
|
17 |
|
18 #include "HANDANIM.H" |
|
19 |
|
20 #define DEFAUlT_LINE_WIDTH 4 |
|
21 #define DEFAUlT_MASK_WIDTH_FACTOR 3 |
|
22 #define DEFAUlT_END_POINT_FACTOR 2 |
|
23 #define BLACK TRgb::Gray2(0) |
|
24 #define WHITE TRgb::Gray2(1) |
|
25 |
|
26 #define leavescan_needs_to_see_some_brackets_here { } |
|
27 EXPORT_C CAnimDll *CreateCAnimDllL() |
|
28 { |
|
29 return(new(ELeave) CHandWritingAnimDll()); |
|
30 } |
|
31 |
|
32 |
|
33 /*CHandWritingAnimDll*/ |
|
34 |
|
35 CAnim *CHandWritingAnimDll::CreateInstanceL(TInt /*aType*/) |
|
36 { |
|
37 return new(ELeave) CHandWritingAnim(); |
|
38 } |
|
39 |
|
40 |
|
41 /*CHandWritingAnim*/ |
|
42 |
|
43 CHandWritingAnim::~CHandWritingAnim() |
|
44 { |
|
45 iFunctions->GetRawEvents(EFalse); |
|
46 delete iBitmapDevice; |
|
47 delete iMaskBitmapDevice; |
|
48 } |
|
49 |
|
50 void CHandWritingAnim::Activate() |
|
51 { |
|
52 if (iState==EHwStateDeactive) |
|
53 { |
|
54 iState=EHwStateInactive; |
|
55 iFunctions->GetRawEvents(ETrue); |
|
56 } |
|
57 } |
|
58 |
|
59 void CHandWritingAnim::Deactivate() |
|
60 { |
|
61 if (iState!=EHwStateDeactive) |
|
62 { |
|
63 iState=EHwStateDeactive; |
|
64 iFunctions->GetRawEvents(EFalse); |
|
65 iSpriteFunctions->Activate(EFalse); |
|
66 ClearSprite(); |
|
67 } |
|
68 } |
|
69 |
|
70 void CHandWritingAnim::SpriteChangeL(TBool aUsingSeparateMask) |
|
71 { |
|
72 if (aUsingSeparateMask) |
|
73 { |
|
74 TSpriteMember *spriteMember=iSpriteFunctions->GetSpriteMember(0); |
|
75 iMaskBitmapDevice=CFbsBitmapDevice::NewL(spriteMember->iMaskBitmap); //If this leaves the error value will be returned to the client side |
|
76 } |
|
77 else |
|
78 { |
|
79 delete iMaskBitmapDevice; |
|
80 iMaskBitmapDevice=NULL; |
|
81 iDrawData.iLineColor=BLACK; //Must use black ink when there is no mask |
|
82 iDrawData.iInitialBitmapColor=WHITE; //Must have white background when there is no mask |
|
83 } |
|
84 iIsMask=aUsingSeparateMask; |
|
85 } |
|
86 |
|
87 void CHandWritingAnim::SetDrawData(THandwritingDrawData *aDrawData) |
|
88 { |
|
89 iDrawData=*aDrawData; |
|
90 if (!iIsMask) |
|
91 { |
|
92 iDrawData.iLineColor=BLACK; //Must use black ink when there is no mask |
|
93 iDrawData.iInitialBitmapColor=WHITE; //Must have white background when there is no mask |
|
94 } |
|
95 } |
|
96 |
|
97 TBool CHandWritingAnim::HandlePointerDown(TPoint aPoint) |
|
98 { |
|
99 if (iState==EHwStateWaitingMove) |
|
100 return EFalse; |
|
101 iCurrentDrawPoint=aPoint; |
|
102 if (iState==EHwStateInactive) |
|
103 { |
|
104 iState=EHwStateWaitingMove; |
|
105 StartTimer(); |
|
106 return ETrue; |
|
107 } |
|
108 iState=EHwStateDrawing; |
|
109 DrawPoint(); |
|
110 UpdateSprite(); |
|
111 return ETrue; |
|
112 } |
|
113 |
|
114 TBool CHandWritingAnim::HandlePointerMove(TPoint aPoint) |
|
115 { |
|
116 switch (iState) |
|
117 { |
|
118 case EHwStateWaitingMove: |
|
119 { |
|
120 TPoint moved=aPoint-iCurrentDrawPoint; |
|
121 if (Abs(moved.iX)<5 && Abs(moved.iY)<5) //Need to do something with these constants |
|
122 return ETrue; |
|
123 iSpriteFunctions->Activate(ETrue); |
|
124 DrawPoint(); |
|
125 iState=EHwStateDrawing; |
|
126 } |
|
127 case EHwStateDrawing: |
|
128 break; |
|
129 default: |
|
130 return EFalse; |
|
131 } |
|
132 DrawLine(aPoint); |
|
133 UpdateSprite(); |
|
134 return ETrue; |
|
135 } |
|
136 |
|
137 TBool CHandWritingAnim::HandlePointerUp(TPoint aPoint) |
|
138 { |
|
139 if (iState==EHwStateInactive) |
|
140 return EFalse; |
|
141 else if (iState==EHwStateWaitingMove) |
|
142 { |
|
143 TPoint moved=aPoint-iCurrentDrawPoint; |
|
144 if (Abs(moved.iX)<5 && Abs(moved.iY)<5) //Need to do something with these constants |
|
145 { |
|
146 SendEatenDownEvent(); |
|
147 return EFalse; |
|
148 } |
|
149 iSpriteFunctions->Activate(ETrue); |
|
150 DrawPoint(); |
|
151 } |
|
152 DrawLine(aPoint); |
|
153 DrawPoint(); |
|
154 UpdateSprite(); |
|
155 iState=EHwStateWaitingStroke; |
|
156 StartTimer(); |
|
157 return ETrue; |
|
158 } |
|
159 |
|
160 void CHandWritingAnim::DrawPoint() |
|
161 { |
|
162 iSpriteGc->Activate(iBitmapDevice); |
|
163 iSpriteGc->SetPenSize(TSize(iDrawData.iEndPontWidth,iDrawData.iEndPontWidth)); |
|
164 iSpriteGc->SetPenColor(iDrawData.iLineColor); |
|
165 iSpriteGc->Plot(iCurrentDrawPoint); |
|
166 if (iMaskBitmapDevice) |
|
167 { |
|
168 iSpriteGc->Activate(iMaskBitmapDevice); |
|
169 iSpriteGc->SetPenSize(TSize(iDrawData.iMaskLineWidth,iDrawData.iMaskLineWidth)); |
|
170 iSpriteGc->SetPenColor(BLACK); //Mask must be drawn in black |
|
171 iSpriteGc->Plot(iCurrentDrawPoint); |
|
172 } |
|
173 iPointStore->AddPoint(iCurrentDrawPoint); |
|
174 } |
|
175 |
|
176 void CHandWritingAnim::DrawLine(TPoint aEndPoint) |
|
177 { |
|
178 iSpriteGc->Activate(iBitmapDevice); |
|
179 iSpriteGc->SetPenSize(TSize(iDrawData.iLineWidth,iDrawData.iLineWidth)); |
|
180 iSpriteGc->SetPenColor(iDrawData.iLineColor); |
|
181 iSpriteGc->MoveTo(iCurrentDrawPoint); |
|
182 iSpriteGc->DrawLineTo(aEndPoint); |
|
183 if (iMaskBitmapDevice) |
|
184 { |
|
185 iSpriteGc->Activate(iMaskBitmapDevice); |
|
186 iSpriteGc->SetPenSize(TSize(iDrawData.iMaskLineWidth,iDrawData.iMaskLineWidth)); |
|
187 iSpriteGc->SetPenColor(BLACK); //Mask must be drawn in black |
|
188 iSpriteGc->MoveTo(iCurrentDrawPoint); |
|
189 iSpriteGc->DrawLineTo(aEndPoint); |
|
190 } |
|
191 iCurrentDrawPoint=aEndPoint; |
|
192 iPointStore->AddPoint(aEndPoint); |
|
193 } |
|
194 |
|
195 void CHandWritingAnim::UpdateSprite() |
|
196 { |
|
197 TRect drawTo; |
|
198 iSpriteGc->RectDrawnTo(drawTo); |
|
199 iSpriteFunctions->UpdateMember(0,drawTo,EFalse); |
|
200 } |
|
201 |
|
202 void CHandWritingAnim::StartTimer() |
|
203 { |
|
204 iFunctions->SetNextInterval(2); |
|
205 } |
|
206 |
|
207 void CHandWritingAnim::SendEatenDownEvent() |
|
208 { |
|
209 TRawEvent rawEvent; |
|
210 rawEvent.Set(TRawEvent::EButton1Down,iCurrentDrawPoint.iX,iCurrentDrawPoint.iY); |
|
211 iFunctions->PostRawEvent(rawEvent); |
|
212 iState=EHwStateInactive; |
|
213 } |
|
214 |
|
215 void CHandWritingAnim::CharacterFinished() |
|
216 { |
|
217 iState=EHwStateInactive; |
|
218 iLastGeneratedCharacter=iPointStore->GetChar(); |
|
219 /*TRawEvent rawEvent; |
|
220 rawEvent.Set(TRawEvent::EKeyDown,iLastGeneratedCharacter); |
|
221 iFunctions->PostKeyEvent(rawEvent);*/ |
|
222 TKeyEvent keyEvent; |
|
223 keyEvent.iCode=keyEvent.iScanCode=iLastGeneratedCharacter; |
|
224 keyEvent.iModifiers=keyEvent.iRepeats=0; |
|
225 iFunctions->PostKeyEvent(keyEvent); |
|
226 iPointStore->ClearPoints(); |
|
227 iSpriteFunctions->Activate(EFalse); |
|
228 ClearSprite(); |
|
229 } |
|
230 |
|
231 void CHandWritingAnim::ClearSprite() |
|
232 { |
|
233 iSpriteGc->Activate(iBitmapDevice); |
|
234 iSpriteGc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
235 iSpriteGc->SetBrushColor(iDrawData.iInitialBitmapColor); |
|
236 iSpriteGc->Clear(); |
|
237 if (iMaskBitmapDevice) |
|
238 { |
|
239 iSpriteGc->Activate(iMaskBitmapDevice); |
|
240 iSpriteGc->SetBrushColor(WHITE); //Mask must be cleared in white |
|
241 iSpriteGc->Clear(); |
|
242 } |
|
243 TRect drawnTo; |
|
244 iSpriteGc->RectDrawnTo(drawnTo); //Clear the drawnTo rect. |
|
245 } |
|
246 |
|
247 TBool CHandWritingAnim::OfferRawEvent(const TRawEvent &aRawEvent) |
|
248 { |
|
249 if (iState==EHwStateDeactive) |
|
250 return EFalse; |
|
251 switch (aRawEvent.Type()) |
|
252 { |
|
253 case TRawEvent::EButton1Down: |
|
254 { |
|
255 iDownTime.HomeTime(); |
|
256 return HandlePointerDown(aRawEvent.Pos()); |
|
257 } |
|
258 case TRawEvent::EPointerMove: |
|
259 return HandlePointerMove(aRawEvent.Pos()); |
|
260 case TRawEvent::EButton1Up: |
|
261 return HandlePointerUp(aRawEvent.Pos()); |
|
262 default: |
|
263 return EFalse; |
|
264 } |
|
265 } |
|
266 |
|
267 void CHandWritingAnim::ConstructL(TAny *) |
|
268 { |
|
269 TSpriteMember *spriteMember=iSpriteFunctions->GetSpriteMember(0); |
|
270 iIsMask=(spriteMember->iBitmap->Handle() != spriteMember->iMaskBitmap->Handle()); |
|
271 iBitmapDevice=CFbsBitmapDevice::NewL(spriteMember->iBitmap); |
|
272 if (iIsMask) |
|
273 iMaskBitmapDevice=CFbsBitmapDevice::NewL(spriteMember->iMaskBitmap); |
|
274 iState=EHwStateDeactive; |
|
275 iSpriteGc=CFbsBitGc::NewL(); |
|
276 iSpriteGc->Reset(); |
|
277 iDrawData.iLineColor=BLACK; |
|
278 iDrawData.iInitialBitmapColor=WHITE; |
|
279 iDrawData.iLineWidth=DEFAUlT_LINE_WIDTH; |
|
280 iDrawData.iMaskLineWidth=DEFAUlT_MASK_WIDTH_FACTOR*DEFAUlT_LINE_WIDTH; |
|
281 iDrawData.iEndPontWidth=DEFAUlT_END_POINT_FACTOR*DEFAUlT_LINE_WIDTH; |
|
282 iSpriteFunctions->SizeChangedL(); |
|
283 iPointStore=new(ELeave) CPointStore(); |
|
284 iPointStore->ConstructL(); |
|
285 } |
|
286 |
|
287 void CHandWritingAnim::Animate(TDateTime* /*aDateTime*/) |
|
288 { |
|
289 iFunctions->SetInterval(0); |
|
290 if (iState==EHwStateWaitingMove) |
|
291 SendEatenDownEvent(); |
|
292 else if (iState==EHwStateWaitingStroke) |
|
293 CharacterFinished(); |
|
294 } |
|
295 |
|
296 void CHandWritingAnim::Redraw() |
|
297 { |
|
298 } |
|
299 |
|
300 void CHandWritingAnim::Command(TInt aOpcode,TAny *aParams) |
|
301 { |
|
302 switch (aOpcode) |
|
303 { |
|
304 case EHwOpActivate: |
|
305 Activate(); |
|
306 break; |
|
307 case EHwOpDeactivate: |
|
308 Deactivate(); |
|
309 break; |
|
310 case EHwOpSetDrawData:; |
|
311 SetDrawData(STATIC_CAST(THandwritingDrawData*,aParams)); |
|
312 break; |
|
313 default: |
|
314 iFunctions->Panic(); |
|
315 } |
|
316 } |
|
317 |
|
318 void CHandWritingAnim::FocusChanged(TBool ) |
|
319 { |
|
320 } |
|
321 |
|
322 TInt CHandWritingAnim::CommandReplyL(TInt aOpcode,TAny *aParams) |
|
323 { |
|
324 switch (aOpcode) |
|
325 { |
|
326 case EHwOpSpriteMask: |
|
327 SpriteChangeL(*STATIC_CAST(TBool*,aParams)); |
|
328 break; |
|
329 case EHwOpGetLastChar: |
|
330 return iLastGeneratedCharacter; |
|
331 default: |
|
332 iFunctions->Panic(); |
|
333 } |
|
334 return KErrNone; |
|
335 } |
|
336 |
|
337 |
|
338 /*CPointStore*/ |
|
339 |
|
340 CPointStore::CPointStore() |
|
341 {} |
|
342 |
|
343 void CPointStore::ConstructL() |
|
344 { |
|
345 iPoints=new(ELeave) CArrayFixFlat<TPoint>(16); |
|
346 iPoints->ResizeL(256); |
|
347 } |
|
348 |
|
349 void CPointStore::AddPoint(TPoint aPoint) |
|
350 { |
|
351 if (iNumPoints<256) |
|
352 (*iPoints)[iNumPoints++]=aPoint; |
|
353 } |
|
354 |
|
355 TInt CPointStore::GetChar() |
|
356 { |
|
357 TPoint oldPoint=(*iPoints)[0]; |
|
358 TPoint newPoint; |
|
359 TPoint totalPoint=oldPoint; |
|
360 TInt xInc=0,xDec=0,yInc=0,yDec=0; |
|
361 TInt yState=0,xState=0; |
|
362 TInt ii; |
|
363 for (ii=1;ii<iNumPoints;++ii) |
|
364 { |
|
365 newPoint=(*iPoints)[ii]; |
|
366 totalPoint+=newPoint; |
|
367 if (newPoint.iX>oldPoint.iX) |
|
368 ++xInc; |
|
369 if (newPoint.iX<oldPoint.iX) |
|
370 ++xDec; |
|
371 if (newPoint.iY>oldPoint.iY) |
|
372 ++yInc; |
|
373 if (newPoint.iY<oldPoint.iY) |
|
374 ++yDec; |
|
375 oldPoint=newPoint; |
|
376 } |
|
377 newPoint-=(*iPoints)[0]; |
|
378 if (10*yInc<yDec) |
|
379 yState=-1; |
|
380 else if (yInc>10*yDec) |
|
381 yState=1; |
|
382 if (10*xInc<xDec) |
|
383 xState=-1; |
|
384 else if (xInc>10*xDec) |
|
385 xState=1; |
|
386 if (xState!=0 && yState!=0) |
|
387 { |
|
388 if (Abs(newPoint.iY)<Abs(newPoint.iX)) |
|
389 yState=0; |
|
390 else |
|
391 xState=0; |
|
392 } |
|
393 if (xState!=0) |
|
394 return xState>0 ? EKeyRightArrow:EKeyLeftArrow; |
|
395 if (yState!=0) |
|
396 return yState>0 ? EKeyDownArrow:EKeyUpArrow; |
|
397 TInt firstChar='a'; |
|
398 TInt numChars=26; |
|
399 TInt type=(totalPoint.iY/10)%10; |
|
400 if (type>5) |
|
401 firstChar='A'; |
|
402 else if (type==0) |
|
403 { |
|
404 firstChar='0'; |
|
405 numChars=10; |
|
406 } |
|
407 return firstChar+((totalPoint.iX/10)%numChars); |
|
408 } |
|
409 |
|
410 void CPointStore::ClearPoints() |
|
411 { |
|
412 iNumPoints=0; |
|
413 } |