sl@0: // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Anim DLL to deal with handwriting sl@0: // sl@0: // sl@0: sl@0: #include "HANDANIM.H" sl@0: sl@0: #define DEFAUlT_LINE_WIDTH 4 sl@0: #define DEFAUlT_MASK_WIDTH_FACTOR 3 sl@0: #define DEFAUlT_END_POINT_FACTOR 2 sl@0: #define BLACK TRgb::Gray2(0) sl@0: #define WHITE TRgb::Gray2(1) sl@0: sl@0: #define leavescan_needs_to_see_some_brackets_here { } sl@0: EXPORT_C CAnimDll *CreateCAnimDllL() sl@0: { sl@0: return(new(ELeave) CHandWritingAnimDll()); sl@0: } sl@0: sl@0: sl@0: /*CHandWritingAnimDll*/ sl@0: sl@0: CAnim *CHandWritingAnimDll::CreateInstanceL(TInt /*aType*/) sl@0: { sl@0: return new(ELeave) CHandWritingAnim(); sl@0: } sl@0: sl@0: sl@0: /*CHandWritingAnim*/ sl@0: sl@0: CHandWritingAnim::~CHandWritingAnim() sl@0: { sl@0: iFunctions->GetRawEvents(EFalse); sl@0: delete iBitmapDevice; sl@0: delete iMaskBitmapDevice; sl@0: } sl@0: sl@0: void CHandWritingAnim::Activate() sl@0: { sl@0: if (iState==EHwStateDeactive) sl@0: { sl@0: iState=EHwStateInactive; sl@0: iFunctions->GetRawEvents(ETrue); sl@0: } sl@0: } sl@0: sl@0: void CHandWritingAnim::Deactivate() sl@0: { sl@0: if (iState!=EHwStateDeactive) sl@0: { sl@0: iState=EHwStateDeactive; sl@0: iFunctions->GetRawEvents(EFalse); sl@0: iSpriteFunctions->Activate(EFalse); sl@0: ClearSprite(); sl@0: } sl@0: } sl@0: sl@0: void CHandWritingAnim::SpriteChangeL(TBool aUsingSeparateMask) sl@0: { sl@0: if (aUsingSeparateMask) sl@0: { sl@0: TSpriteMember *spriteMember=iSpriteFunctions->GetSpriteMember(0); sl@0: iMaskBitmapDevice=CFbsBitmapDevice::NewL(spriteMember->iMaskBitmap); //If this leaves the error value will be returned to the client side sl@0: } sl@0: else sl@0: { sl@0: delete iMaskBitmapDevice; sl@0: iMaskBitmapDevice=NULL; sl@0: iDrawData.iLineColor=BLACK; //Must use black ink when there is no mask sl@0: iDrawData.iInitialBitmapColor=WHITE; //Must have white background when there is no mask sl@0: } sl@0: iIsMask=aUsingSeparateMask; sl@0: } sl@0: sl@0: void CHandWritingAnim::SetDrawData(THandwritingDrawData *aDrawData) sl@0: { sl@0: iDrawData=*aDrawData; sl@0: if (!iIsMask) sl@0: { sl@0: iDrawData.iLineColor=BLACK; //Must use black ink when there is no mask sl@0: iDrawData.iInitialBitmapColor=WHITE; //Must have white background when there is no mask sl@0: } sl@0: } sl@0: sl@0: TBool CHandWritingAnim::HandlePointerDown(TPoint aPoint) sl@0: { sl@0: if (iState==EHwStateWaitingMove) sl@0: return EFalse; sl@0: iCurrentDrawPoint=aPoint; sl@0: if (iState==EHwStateInactive) sl@0: { sl@0: iState=EHwStateWaitingMove; sl@0: StartTimer(); sl@0: return ETrue; sl@0: } sl@0: iState=EHwStateDrawing; sl@0: DrawPoint(); sl@0: UpdateSprite(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CHandWritingAnim::HandlePointerMove(TPoint aPoint) sl@0: { sl@0: switch (iState) sl@0: { sl@0: case EHwStateWaitingMove: sl@0: { sl@0: TPoint moved=aPoint-iCurrentDrawPoint; sl@0: if (Abs(moved.iX)<5 && Abs(moved.iY)<5) //Need to do something with these constants sl@0: return ETrue; sl@0: iSpriteFunctions->Activate(ETrue); sl@0: DrawPoint(); sl@0: iState=EHwStateDrawing; sl@0: } sl@0: case EHwStateDrawing: sl@0: break; sl@0: default: sl@0: return EFalse; sl@0: } sl@0: DrawLine(aPoint); sl@0: UpdateSprite(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CHandWritingAnim::HandlePointerUp(TPoint aPoint) sl@0: { sl@0: if (iState==EHwStateInactive) sl@0: return EFalse; sl@0: else if (iState==EHwStateWaitingMove) sl@0: { sl@0: TPoint moved=aPoint-iCurrentDrawPoint; sl@0: if (Abs(moved.iX)<5 && Abs(moved.iY)<5) //Need to do something with these constants sl@0: { sl@0: SendEatenDownEvent(); sl@0: return EFalse; sl@0: } sl@0: iSpriteFunctions->Activate(ETrue); sl@0: DrawPoint(); sl@0: } sl@0: DrawLine(aPoint); sl@0: DrawPoint(); sl@0: UpdateSprite(); sl@0: iState=EHwStateWaitingStroke; sl@0: StartTimer(); sl@0: return ETrue; sl@0: } sl@0: sl@0: void CHandWritingAnim::DrawPoint() sl@0: { sl@0: iSpriteGc->Activate(iBitmapDevice); sl@0: iSpriteGc->SetPenSize(TSize(iDrawData.iEndPontWidth,iDrawData.iEndPontWidth)); sl@0: iSpriteGc->SetPenColor(iDrawData.iLineColor); sl@0: iSpriteGc->Plot(iCurrentDrawPoint); sl@0: if (iMaskBitmapDevice) sl@0: { sl@0: iSpriteGc->Activate(iMaskBitmapDevice); sl@0: iSpriteGc->SetPenSize(TSize(iDrawData.iMaskLineWidth,iDrawData.iMaskLineWidth)); sl@0: iSpriteGc->SetPenColor(BLACK); //Mask must be drawn in black sl@0: iSpriteGc->Plot(iCurrentDrawPoint); sl@0: } sl@0: iPointStore->AddPoint(iCurrentDrawPoint); sl@0: } sl@0: sl@0: void CHandWritingAnim::DrawLine(TPoint aEndPoint) sl@0: { sl@0: iSpriteGc->Activate(iBitmapDevice); sl@0: iSpriteGc->SetPenSize(TSize(iDrawData.iLineWidth,iDrawData.iLineWidth)); sl@0: iSpriteGc->SetPenColor(iDrawData.iLineColor); sl@0: iSpriteGc->MoveTo(iCurrentDrawPoint); sl@0: iSpriteGc->DrawLineTo(aEndPoint); sl@0: if (iMaskBitmapDevice) sl@0: { sl@0: iSpriteGc->Activate(iMaskBitmapDevice); sl@0: iSpriteGc->SetPenSize(TSize(iDrawData.iMaskLineWidth,iDrawData.iMaskLineWidth)); sl@0: iSpriteGc->SetPenColor(BLACK); //Mask must be drawn in black sl@0: iSpriteGc->MoveTo(iCurrentDrawPoint); sl@0: iSpriteGc->DrawLineTo(aEndPoint); sl@0: } sl@0: iCurrentDrawPoint=aEndPoint; sl@0: iPointStore->AddPoint(aEndPoint); sl@0: } sl@0: sl@0: void CHandWritingAnim::UpdateSprite() sl@0: { sl@0: TRect drawTo; sl@0: iSpriteGc->RectDrawnTo(drawTo); sl@0: iSpriteFunctions->UpdateMember(0,drawTo,EFalse); sl@0: } sl@0: sl@0: void CHandWritingAnim::StartTimer() sl@0: { sl@0: iFunctions->SetNextInterval(2); sl@0: } sl@0: sl@0: void CHandWritingAnim::SendEatenDownEvent() sl@0: { sl@0: TRawEvent rawEvent; sl@0: rawEvent.Set(TRawEvent::EButton1Down,iCurrentDrawPoint.iX,iCurrentDrawPoint.iY); sl@0: iFunctions->PostRawEvent(rawEvent); sl@0: iState=EHwStateInactive; sl@0: } sl@0: sl@0: void CHandWritingAnim::CharacterFinished() sl@0: { sl@0: iState=EHwStateInactive; sl@0: iLastGeneratedCharacter=iPointStore->GetChar(); sl@0: /*TRawEvent rawEvent; sl@0: rawEvent.Set(TRawEvent::EKeyDown,iLastGeneratedCharacter); sl@0: iFunctions->PostKeyEvent(rawEvent);*/ sl@0: TKeyEvent keyEvent; sl@0: keyEvent.iCode=keyEvent.iScanCode=iLastGeneratedCharacter; sl@0: keyEvent.iModifiers=keyEvent.iRepeats=0; sl@0: iFunctions->PostKeyEvent(keyEvent); sl@0: iPointStore->ClearPoints(); sl@0: iSpriteFunctions->Activate(EFalse); sl@0: ClearSprite(); sl@0: } sl@0: sl@0: void CHandWritingAnim::ClearSprite() sl@0: { sl@0: iSpriteGc->Activate(iBitmapDevice); sl@0: iSpriteGc->SetBrushStyle(CGraphicsContext::ESolidBrush); sl@0: iSpriteGc->SetBrushColor(iDrawData.iInitialBitmapColor); sl@0: iSpriteGc->Clear(); sl@0: if (iMaskBitmapDevice) sl@0: { sl@0: iSpriteGc->Activate(iMaskBitmapDevice); sl@0: iSpriteGc->SetBrushColor(WHITE); //Mask must be cleared in white sl@0: iSpriteGc->Clear(); sl@0: } sl@0: TRect drawnTo; sl@0: iSpriteGc->RectDrawnTo(drawnTo); //Clear the drawnTo rect. sl@0: } sl@0: sl@0: TBool CHandWritingAnim::OfferRawEvent(const TRawEvent &aRawEvent) sl@0: { sl@0: if (iState==EHwStateDeactive) sl@0: return EFalse; sl@0: switch (aRawEvent.Type()) sl@0: { sl@0: case TRawEvent::EButton1Down: sl@0: { sl@0: iDownTime.HomeTime(); sl@0: return HandlePointerDown(aRawEvent.Pos()); sl@0: } sl@0: case TRawEvent::EPointerMove: sl@0: return HandlePointerMove(aRawEvent.Pos()); sl@0: case TRawEvent::EButton1Up: sl@0: return HandlePointerUp(aRawEvent.Pos()); sl@0: default: sl@0: return EFalse; sl@0: } sl@0: } sl@0: sl@0: void CHandWritingAnim::ConstructL(TAny *) sl@0: { sl@0: TSpriteMember *spriteMember=iSpriteFunctions->GetSpriteMember(0); sl@0: iIsMask=(spriteMember->iBitmap->Handle() != spriteMember->iMaskBitmap->Handle()); sl@0: iBitmapDevice=CFbsBitmapDevice::NewL(spriteMember->iBitmap); sl@0: if (iIsMask) sl@0: iMaskBitmapDevice=CFbsBitmapDevice::NewL(spriteMember->iMaskBitmap); sl@0: iState=EHwStateDeactive; sl@0: iSpriteGc=CFbsBitGc::NewL(); sl@0: iSpriteGc->Reset(); sl@0: iDrawData.iLineColor=BLACK; sl@0: iDrawData.iInitialBitmapColor=WHITE; sl@0: iDrawData.iLineWidth=DEFAUlT_LINE_WIDTH; sl@0: iDrawData.iMaskLineWidth=DEFAUlT_MASK_WIDTH_FACTOR*DEFAUlT_LINE_WIDTH; sl@0: iDrawData.iEndPontWidth=DEFAUlT_END_POINT_FACTOR*DEFAUlT_LINE_WIDTH; sl@0: iSpriteFunctions->SizeChangedL(); sl@0: iPointStore=new(ELeave) CPointStore(); sl@0: iPointStore->ConstructL(); sl@0: } sl@0: sl@0: void CHandWritingAnim::Animate(TDateTime* /*aDateTime*/) sl@0: { sl@0: iFunctions->SetInterval(0); sl@0: if (iState==EHwStateWaitingMove) sl@0: SendEatenDownEvent(); sl@0: else if (iState==EHwStateWaitingStroke) sl@0: CharacterFinished(); sl@0: } sl@0: sl@0: void CHandWritingAnim::Redraw() sl@0: { sl@0: } sl@0: sl@0: void CHandWritingAnim::Command(TInt aOpcode,TAny *aParams) sl@0: { sl@0: switch (aOpcode) sl@0: { sl@0: case EHwOpActivate: sl@0: Activate(); sl@0: break; sl@0: case EHwOpDeactivate: sl@0: Deactivate(); sl@0: break; sl@0: case EHwOpSetDrawData:; sl@0: SetDrawData(STATIC_CAST(THandwritingDrawData*,aParams)); sl@0: break; sl@0: default: sl@0: iFunctions->Panic(); sl@0: } sl@0: } sl@0: sl@0: void CHandWritingAnim::FocusChanged(TBool ) sl@0: { sl@0: } sl@0: sl@0: TInt CHandWritingAnim::CommandReplyL(TInt aOpcode,TAny *aParams) sl@0: { sl@0: switch (aOpcode) sl@0: { sl@0: case EHwOpSpriteMask: sl@0: SpriteChangeL(*STATIC_CAST(TBool*,aParams)); sl@0: break; sl@0: case EHwOpGetLastChar: sl@0: return iLastGeneratedCharacter; sl@0: default: sl@0: iFunctions->Panic(); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /*CPointStore*/ sl@0: sl@0: CPointStore::CPointStore() sl@0: {} sl@0: sl@0: void CPointStore::ConstructL() sl@0: { sl@0: iPoints=new(ELeave) CArrayFixFlat(16); sl@0: iPoints->ResizeL(256); sl@0: } sl@0: sl@0: void CPointStore::AddPoint(TPoint aPoint) sl@0: { sl@0: if (iNumPoints<256) sl@0: (*iPoints)[iNumPoints++]=aPoint; sl@0: } sl@0: sl@0: TInt CPointStore::GetChar() sl@0: { sl@0: TPoint oldPoint=(*iPoints)[0]; sl@0: TPoint newPoint; sl@0: TPoint totalPoint=oldPoint; sl@0: TInt xInc=0,xDec=0,yInc=0,yDec=0; sl@0: TInt yState=0,xState=0; sl@0: TInt ii; sl@0: for (ii=1;iioldPoint.iX) sl@0: ++xInc; sl@0: if (newPoint.iXoldPoint.iY) sl@0: ++yInc; sl@0: if (newPoint.iY10*yDec) sl@0: yState=1; sl@0: if (10*xInc10*xDec) sl@0: xState=1; sl@0: if (xState!=0 && yState!=0) sl@0: { sl@0: if (Abs(newPoint.iY)0 ? EKeyRightArrow:EKeyLeftArrow; sl@0: if (yState!=0) sl@0: return yState>0 ? EKeyDownArrow:EKeyUpArrow; sl@0: TInt firstChar='a'; sl@0: TInt numChars=26; sl@0: TInt type=(totalPoint.iY/10)%10; sl@0: if (type>5) sl@0: firstChar='A'; sl@0: else if (type==0) sl@0: { sl@0: firstChar='0'; sl@0: numChars=10; sl@0: } sl@0: return firstChar+((totalPoint.iX/10)%numChars); sl@0: } sl@0: sl@0: void CPointStore::ClearPoints() sl@0: { sl@0: iNumPoints=0; sl@0: }