⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphics.cpp

📁 在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己的开发
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// GRAPHICS.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//


#include "graphics.h"
#include <oplr.h>
#include <s32file.h> 			 	 
#include <f32file.h> 
#if !defined(__SERIES60__)
#include <fontids.h>
#endif
#include "oplutil.h"			 	 
#include <eiklabel.h>
#include <clock.h>
#include <gulutil.h>
#include <eikon.hrh>
#include <eikon.rsg>
#include "clckupdt.h"

// const TInt KSinglePixelGap = 0x100;  not supported by wserv
const TInt KSinglePixelShadow = 1;
const TInt KGapForSinglePixelShadow = 2;
const TInt KDoublePixelShadow = 3;
const TInt KGapForDoublePixelShadow = 4;
const TInt KFontIdOffset = 0x1000;

const TInt KNormalCornerSize = 4;
const TInt KMoreRoundedCornerSize = 6;


/*****************************
class CDrawablesCollection
*****************************/

CDrawablesCollection::CDrawablesCollection(RWsSession& aWsSession) 
: iFlushState(ETrue) ,iWsSession(aWsSession)
	{
	}

CDrawablesCollection::~CDrawablesCollection()
	{
	COplDrawable** drawablePtr = iDrawablesArray;
	for (TInt index=0; index < KMaxDrawables; index++,drawablePtr++)
		{
		delete (*drawablePtr);
		}
	}

void CDrawablesCollection::SetConsoleWinL(COplRuntime& aRuntime, COplConsole* aConsole)
	{
	COplDrawable* window = new(ELeave) COplWindow;
	CleanupStack::PushL(window);
	TInt color=0;
	TInt gray=0;
	TDisplayMode dMode=aRuntime.ConEnv()->WsSession().GetDefModeMaxNumColors(color,gray);
	((COplWindow*)window)->ConstructL(aRuntime,aConsole->Window(),dMode);
//	((COplWindow*)window)->ConstructL(aRuntime,aConsole->Window(),EGray4);
	AddDrawableL(window,1);	// first drawable
	iDrawableWithCursor = 0; // the console gets the cursor
	CleanupStack::Pop();
	}

TInt CDrawablesCollection::NextAvailableId()
	{
	TInt found = -1;
	for (TInt index=0; index<KMaxDrawables; index++)
		{
		if (iDrawablesArray[index] == NULL)
			{
			found = index;
			break;
			}
		}
	if (found < 0)
		User::Leave(KOplErrMaxDraw);
	return (found+KDiffBtnIdAndPos);
	}

void CDrawablesCollection::AddDrawableL(COplDrawable* aDrawable, TInt aDrawableId)
  // returns id of drawable in array
	{
	if (iNumOfDrawables == KMaxDrawables)
		User::Leave(KOplErrMaxDraw);
	iDrawablesArray[aDrawableId-KDiffBtnIdAndPos] = aDrawable;
	iNumOfDrawables++;
	iCurrentDrawable = aDrawable;
	}

void CDrawablesCollection::CloseDrawableL(TInt aId)
	// note the aId will never be 1 as it is already handled before this function call
	{
	COplDrawable* drawable = DrawableL(aId);
	if (DrawableWithCursor()==aId)
		SetDrawableWithCursor(-1);
	if (iCurrentDrawable == drawable)	// if drawable to close = current drawable
		iCurrentDrawable = iDrawablesArray[0];	// this implies the console becomes the current drawable
	delete (drawable);
	iDrawablesArray[aId - KDiffBtnIdAndPos]=NULL;
	iNumOfDrawables--;
	}												    

TInt CDrawablesCollection::DrawableId(COplDrawable* aDrawable)
 // returns position of drawable in array. Note that aDrawable will ALWAYS be in the array
	{		 
	TInt index = 0;
	for (; index < KMaxDrawables; index++)
		{
		if (aDrawable == iDrawablesArray[index])
			break;
		}
	return index + KDiffBtnIdAndPos;
	}

void CDrawablesCollection::SetCurrentDrawableL(TInt aId)
 // sets iCurrentDrawable to the drawable at aId-1
	{
	iCurrentDrawable = DrawableL(aId);
	}

 COplDrawable* CDrawablesCollection::DrawableL(TInt aId) 
 	{
	if ((aId<KDiffBtnIdAndPos) || (aId>=KMaxDrawables+KDiffBtnIdAndPos))
		User::Leave(KErrArgument);
 	COplDrawable* drawable=(iDrawablesArray[aId - KDiffBtnIdAndPos]);
	if (drawable==NULL)
		User::Leave(KOplErrDrawNotOpen);
	return drawable;
 	}

CFbsFont* CDrawablesCollection::GetFontByIdL(TUid aFontId, const TAlgStyle& aAlgStyle)
	{
	CBitmapDevice* device = NULL;
	CFont* font = NULL;
	TInt err=KErrNone;
	if (iCurrentDrawable->DrawableFlag() != EIsOplBitmap)
		{
		device = ((COplWindow*)iCurrentDrawable)->iScreenDevice;
		err=((CWsScreenDevice*)device)->GetFontById(font,aFontId,aAlgStyle);
		}
	else
		{
		device = ((COplBitmap*)iCurrentDrawable)->BitmapDevice();
		err=((CFbsBitmapDevice*)device)->GetFontById(font,aFontId,aAlgStyle);
		}
	if (err)
		{
		if (err==KErrNotFound)
			err=KOplErrFontNotLoaded;
		User::Leave(err);
		}
	return ((CFbsFont*)font);
	}
 
CFbsFont* CDrawablesCollection::GetFontByNameL(const TFontSpec& aFontSpec)
	{
	CBitmapDevice* device = NULL;
//	CFont* font = NULL;
//	TInt err=KErrNone;
	if (iCurrentDrawable->DrawableFlag() != EIsOplBitmap)
		{
		//device = ((COplWindow*)iCurrentDrawable)->iScreenDevice;
		CFbsFont* font=TheRuntime()->ConEnv()->CreateScreenFontL(aFontSpec);
		//err=((CWsScreenDevice*)device)->GetFontById(font,aFontId,aAlgStyle);
		return ((CFbsFont*)font);
		}
	else
		{
		device = ((COplBitmap*)iCurrentDrawable)->BitmapDevice();
		CFbsFont* font=TheRuntime()->ConEnv()->CreateDeviceFontL(device,aFontSpec);
//		err=((CFbsBitmapDevice*)device)->GetFontById(font,aFontId,aAlgStyle);
		return ((CFbsFont*)font);
		}
//	if (err)
//		{
//		if (err==KErrNotFound)
//			err=KOplErrFontNotLoaded;
//		User::Leave(err);
//		}
	}


TInt16 CDrawablesCollection::AddFontFileL(const TDesC& aFontFile)
	{
	TInt16 id=-1;
	TInt* fileIdPtr=iFontFileId;
    TInt ii;
	for (ii=0;ii<KMaxFontFiles;ii++,fileIdPtr++)
		{
		if (*fileIdPtr==0)
			{
			id=(TInt16)(ii+KFontIdOffset);
			break;
			}
		}
	if (ii==KMaxFontFiles)
		User::Leave(KErrGeneral);
	COplDrawable* drawable=DrawableL(1);
	// add to screen device via the console drawable
#if defined(_DEBUG)
	_LIT(KAddFontFile,"AddFontFile");
#endif
	__ASSERT_DEBUG(drawable->DrawableFlag()==EIsOplConsole,User::Panic(KAddFontFile,1));
	User::LeaveIfError(STATIC_CAST(COplWindow*,drawable)->iScreenDevice->AddFile(aFontFile,iFontFileId[ii]));
	return id;
	}


void CDrawablesCollection::RemoveFontFile(TInt aId)
	{
	if (aId==0)
		return;
	TInt index=aId-KFontIdOffset;
	if (index<0 || index >KMaxFontFiles)
		User::Leave(KErrArgument);
	COplDrawable* drawable=DrawableL(1);
	// remove from screen device via the console drawable
#if defined(_DEBUG)
	_LIT(KRemoveFontFile,"RemoveFontFile");
#endif
	__ASSERT_DEBUG(drawable->DrawableFlag()==EIsOplConsole,User::Panic(KRemoveFontFile,1));
	TInt& id=iFontFileId[index];
	if (id)
		STATIC_CAST(COplWindow*,drawable)->iScreenDevice->RemoveFile(id);
	else
		User::Leave(KErrArgument);
	id=0;
	}


TBool CDrawablesCollection::SetFlushState(TBool aState)
	{
	TBool prev=iFlushState;
	iFlushState=aState;
	return prev;
	}

void CDrawablesCollection::DrawCursorIfOn()
	{
	if (iDrawableWithCursor>0) // not console text cursor
		{
		COplWindow* win=STATIC_CAST(COplWindow*,DrawableL(iDrawableWithCursor));
#if defined(_DEBUG)
		_LIT(KOplrName,"OPLR");
#endif
		__ASSERT_DEBUG(win->DrawableFlag()!=EIsOplBitmap,User::Panic(KOplrName,1)); // check the cast was OK
		win->DrawCursorIfOn(win->Cursor());
		}
	}

void CDrawablesCollection::DrawAllClocks()
	{
	COplDrawable** drawablePtr = iDrawablesArray;
	for (TInt index=0; index < KMaxDrawables; index++,drawablePtr++)
		{
		if (*drawablePtr && (*drawablePtr)->DrawableFlag()!=EIsOplBitmap)
			STATIC_CAST(COplWindow*,*drawablePtr)->DrawClock();
		}
	}

void CDrawablesCollection::UpdateAllClocks()
	{
	TLocale locale;
	COplDrawable** drawablePtr = iDrawablesArray;
	for (TInt index=0; index < KMaxDrawables; index++,drawablePtr++)
		{
		if (*drawablePtr && (*drawablePtr)->DrawableFlag()!=EIsOplBitmap)
			STATIC_CAST(COplWindow*,*drawablePtr)->UpdateClock(locale);
		}
	}

/*******************************
class COplDrawable
*******************************/


COplDrawable::COplDrawable()
	{
	}
		  

COplDrawable::~COplDrawable()
	{
	delete iDrawableGc;
	}

void COplDrawable::MoveCursorToEndOfBuffer(TDesC& aText)
	{
	TPoint newPos(iCursorPosition.iX+iFont->TextWidthInPixels(aText),iCursorPosition.iY);
	SetCursorPosition(newPos);
	}

/*
void COplDrawable::UpdatePoints(TPoint& aStartPoint, TPoint& aEndPoint)
	// note that startPoint and endPoint will never be the same as that will be handled before
	// note also that whenever either the x or y coordinates of the end point is greater than its
	// corresponding start point coordinates then no change is required as the wserv does not draw the
	// the last point on a line!
	{
	if (aStartPoint.iX == aEndPoint.iX) 
			// ie a vertical line
		{
		if (aStartPoint.iY > aEndPoint.iY)	  // vertical line drawn upwards
			SwapPoints(aStartPoint,aEndPoint); // swap over so that bottom point is not included
		return;
		}
	if (aStartPoint.iY == aEndPoint.iY)
			// ie is a horizontal line
		{
		if (aStartPoint.iX > aEndPoint.iX)	  // horizontal line drawn right to left
			SwapPoints(aStartPoint,aEndPoint); // swap over so that right-most point	is not included
		return;
		}

	TInt yDiff = aStartPoint.iY - aEndPoint.iY;
	TInt xDiff = aStartPoint.iX - aEndPoint.iX;
	TBool slope = xDiff^yDiff;
	
	TInt singlePixelOffset = 1;
	if (!slope)
		{
		if (aStartPoint.iX > aEndPoint.iX)	// if start point is below and to the right of the end point  
			SwapPoints(aStartPoint,aEndPoint);  // swap over so that the bottom-right point is not included
		}
	else
		{
		if (aStartPoint.iY > aEndPoint.iY)
			aStartPoint.iY -= singlePixelOffset;
		else
			aEndPoint.iY -= singlePixelOffset;
		if (aStartPoint.iX > aEndPoint.iX)
			{
			aStartPoint.iX -= singlePixelOffset;
			aEndPoint -= TPoint(singlePixelOffset,-singlePixelOffset);	 // make sure the *new* 
			}														// endpoint is drawn by the wserv
		else
			{
			aEndPoint.iX -= singlePixelOffset;
			aEndPoint += TPoint(singlePixelOffset,-singlePixelOffset);	 // as above!
			}
		}
	}
*/

void COplDrawable::CalcMsgPosition(TInt aCorner, TGulAlignment& aAlignment)
	{
	switch(aCorner)
		{
	case 0 :
		aAlignment=EHLeftVTop;
		break;
	case 1 :
		aAlignment=EHLeftVBottom;
		break;
	case 2 :
		aAlignment=EHRightVTop;
		break;
	case 3 :
		aAlignment=EHRightVBottom;
		break;
	default:
		User::Leave(KErrArgument);
		break;
		}
	}

TOplDrawMode COplDrawable::GetOplDrawMode(TInt aMode)
	{
	if ((aMode<0) || (aMode>3))
		User::Leave(KOplErrInvalidArgs);
	switch(aMode)
		{
	case 1 :
		return EModeClear;	
	case 2 :
		return EModeInvert;
	case 3 :
		return EModeReplace;
	default :
		return EModeSet;
		}
	}

void COplDrawable::SetInverseStyle(TBool aStyle)
	{
	if (aStyle && (iStyle&KStyleInverse))
		return;
	if (aStyle)
		iStyle += KStyleInverse;
	else
		iStyle -= KStyleInverse;
	}

void COplDrawable::PrintAndMoveCursor(TDesC& aText)
	{
	Print(aText);
	MoveCursorToEndOfBuffer(aText);
	}

void COplDrawable::Print(TDesC& aText)
	{
	if ((InverseStyle()) && (iCurrentDrawMode!=EModeGXPrint))
		{
		TRect rect = FontRect(aText);
		SetGcMode(EModeInverseStyle);
		iDrawableGc->DrawText(aText,rect,iFont->AscentInPixels());
		}
	else
		{
		SetGcMode(iCurrentTextMode);
		if (iCurrentTextMode == EModeReplace)
			{
			TRect rect = FontRect(aText);
			iDrawableGc->DrawText(aText,rect,iFont->AscentInPixels());
			}
		else
			iDrawableGc->DrawText(aText,iCursorPosition);
		}
	}
	
TRect COplDrawable::FontRect(TDesC& aText, TInt aWidth)
	{
	TPoint topLeft(iCursorPosition.iX,iCursorPosition.iY-iFont->AscentInPixels());
	TSize size(0,0);
	if (aWidth == 0)
		aWidth = iFont->TextWidthInPixels(aText);
	size.SetSize(aWidth,iFont->HeightInPixels());
	return (TRect(topLeft,size));
	}

TPoint COplDrawable::PopPoint(CStack& aStack)
	{
	TInt yPos = aStack.PopInt16();
	return (TPoint(aStack.PopInt16(),yPos));
	}

TSize COplDrawable::PopSize(CStack& aStack)
	{
	TInt height = aStack.PopInt16();
	return (TSize(aStack.PopInt16(),height));
	}

TRect COplDrawable::PopRect(CStack& aStack)
	{
	TSize size = PopSize(aStack);
	return (TRect(PopPoint(aStack),size));
	}

#if defined(__SERIES60__)
void COplDrawable::SetFont(CFbsFont* aFont,const TBool aStandardFont)
	{
	if (iFont)
		ReleaseFont();
	iFont = aFont;
	iDrawableGc->UseFont(aFont); //pukka
	iIsFontToBeReleased=(aStandardFont)?EFalse:ETrue;
	}
#else
void COplDrawable::SetFont(CFbsFont* aFont)
	{
	if (iFont)
		ReleaseFont();
	iFont = aFont;
	iDrawableGc->UseFont(aFont);
	}
#endif

void COplDrawable::SetDrawMode(TOplDrawMode aDrawMode)
	{
//	SetGcMode(aDrawMode);
	iCurrentDrawMode = aDrawMode;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -