Exemple #1
0
BOOL IsHighlighted(SESSION_INFO *si, GCEVENT *gce)
{
	if (!g_Settings->bHighlightEnabled || !g_Settings->pszHighlightWords || !gce || !si || !si->pMe)
		return FALSE;

	if (gce->ptszText == NULL)
		return FALSE;

	TCHAR *buf = RemoveFormatting(NEWTSTR_ALLOCA(gce->ptszText));

	int iStart = 0;
	CMString tszHighlightWords(g_Settings->pszHighlightWords);

	while (true) {
		CMString tszToken = tszHighlightWords.Tokenize(_T("\t "), iStart);
		if (iStart == -1)
			break;

		// replace %m with the users nickname
		if (tszToken == _T("%m"))
			tszToken = si->pMe->pszNick;

		if (tszToken.Find('*') == -1)
			tszToken = '*' + tszToken + '*';

		// time to get the next/first word in the incoming text string
		for (const TCHAR *p = buf; *p != '\0'; p += _tcscspn(p, _T(" "))) {
			p += _tcsspn(p, _T(" "));

			// compare the words, using wildcards
			if (wildcmpit(p, tszToken))
				return TRUE;
		}
	}

	return FALSE;
}
static INT_PTR Service_AddEvent(WPARAM wParam, LPARAM lParam)
{
	GCEVENT *gce = (GCEVENT*)lParam, save_gce;
	GCDEST *gcd = NULL, save_gcd;
	TCHAR* pWnd = NULL;
	char* pMod = NULL;
	BOOL bIsHighlighted = FALSE;
	BOOL bRemoveFlag = FALSE;
	int iRetVal = GC_EVENT_ERROR;

	if ( gce == NULL )
		return GC_EVENT_ERROR;

	gcd = gce->pDest;
	if ( gcd == NULL )
		return GC_EVENT_ERROR;

	if ( gce->cbSize != SIZEOF_STRUCT_GCEVENT_V1 && gce->cbSize != SIZEOF_STRUCT_GCEVENT_V2 )
		return GC_EVENT_WRONGVER;

	if ( !IsEventSupported( gcd->iType ) )
		return GC_EVENT_ERROR;

	EnterCriticalSection(&cs);

	#if defined( _UNICODE )
		if ( !( gce->dwFlags & GC_UNICODE )) {
			save_gce = *gce;
			save_gcd = *gce->pDest;
			gce->pDest->ptszID = a2tf( gce->pDest->ptszID, gce->dwFlags );
			gce->ptszUID       = a2tf( gce->ptszUID,       gce->dwFlags );
			gce->ptszNick      = a2tf( gce->ptszNick,      gce->dwFlags );
			gce->ptszStatus    = a2tf( gce->ptszStatus,    gce->dwFlags );
			gce->ptszText      = a2tf( gce->ptszText,      gce->dwFlags );
			gce->ptszUserInfo  = a2tf( gce->ptszUserInfo,  gce->dwFlags );
		}
	#endif

	// Do different things according to type of event
	switch(gcd->iType) {
	case GC_EVENT_ADDGROUP:
		{
			STATUSINFO* si = SM_AddStatus( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszStatus);
			if ( si && gce->dwItemData)
				si->hIcon = CopyIcon((HICON)gce->dwItemData);
		}
		iRetVal = 0;
		goto LBL_Exit;

	case GC_EVENT_CHUID:
	case GC_EVENT_CHANGESESSIONAME:
	case GC_EVENT_SETITEMDATA:
	case GC_EVENT_GETITEMDATA:
	case GC_EVENT_CONTROL:
	case GC_EVENT_SETSBTEXT:
	case GC_EVENT_ACK:
	case GC_EVENT_SENDMESSAGE :
	case GC_EVENT_SETSTATUSEX :
		iRetVal = DoControl(gce, wParam);
		goto LBL_Exit;

	case GC_EVENT_SETCONTACTSTATUS:
		iRetVal = SM_SetContactStatus( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, (WORD)gce->dwItemData );
		goto LBL_Exit;

	case GC_EVENT_TOPIC:
	{
		SESSION_INFO* si = SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
		if ( si ) {
			if ( gce->pszText ) {
				replaceStr( &si->ptszTopic, gce->ptszText);
				DBWriteContactSettingTString( si->windowData.hContact, si->pszModule , "Topic", RemoveFormatting( si->ptszTopic ));
				if ( DBGetContactSettingByte( NULL, "Chat", "TopicOnClist", 0 ))
					DBWriteContactSettingTString( si->windowData.hContact, "CList" , "StatusMsg", RemoveFormatting( si->ptszTopic ));
		}	}
		break;
	}
	case GC_EVENT_ADDSTATUS:
		SM_GiveStatus( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, gce->ptszStatus );
		break;

	case GC_EVENT_REMOVESTATUS:
		SM_TakeStatus( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, gce->ptszStatus);
		break;

	case GC_EVENT_MESSAGE:
	case GC_EVENT_ACTION:
		if ( !gce->bIsMe && gce->pDest->pszID && gce->pszText ) {
			SESSION_INFO* si = SM_FindSession( gce->pDest->ptszID, gce->pDest->pszModule );
			if ( si )
				if ( IsHighlighted( si, gce->ptszText ))
					bIsHighlighted = TRUE;
		}
		break;

	case GC_EVENT_NICK:
		SM_ChangeNick( gce->pDest->ptszID, gce->pDest->pszModule, gce);
		break;

	case GC_EVENT_JOIN:
		AddUser(gce);
		break;

	case GC_EVENT_PART:
	case GC_EVENT_QUIT:
	case GC_EVENT_KICK:
		bRemoveFlag = TRUE;
		break;
	}

	// Decide which window (log) should have the event
	if ( gcd->pszID ) {
		pWnd = gcd->ptszID;
		pMod = gcd->pszModule;
	}
	else if ( gcd->iType == GC_EVENT_NOTICE || gcd->iType == GC_EVENT_INFORMATION ) {
		SESSION_INFO* si = GetActiveSession();
		if ( si && !lstrcmpA( si->pszModule, gcd->pszModule )) {
			pWnd = si->ptszID;
			pMod = si->pszModule;
		}
		else {
			iRetVal = 0;
			goto LBL_Exit;
		}
	}
	else {
		// Send the event to all windows with a user pszUID. Used for broadcasting QUIT etc
		SM_AddEventToAllMatchingUID( gce );
		if ( !bRemoveFlag ) {
			iRetVal = 0;
			goto LBL_Exit;
	}	}

	// add to log
	if ( pWnd ) {
		SESSION_INFO* si = SM_FindSession(pWnd, pMod);

		// fix for IRC's old stuyle mode notifications. Should not affect any other protocol
		if ((gce->pDest->iType == GC_EVENT_ADDSTATUS || gce->pDest->iType == GC_EVENT_REMOVESTATUS) && !( gce->dwFlags & GCEF_ADDTOLOG )) {
			iRetVal = 0;
			goto LBL_Exit;
		}

		if (gce && gce->pDest->iType == GC_EVENT_JOIN && gce->time == 0) {
			iRetVal = 0;
			goto LBL_Exit;
		}

		if (si && (si->bInitDone || gce->pDest->iType == GC_EVENT_TOPIC || (gce->pDest->iType == GC_EVENT_JOIN && gce->bIsMe))) {
			if (SM_AddEvent(pWnd, pMod, gce, bIsHighlighted) && si->hWnd) {
				SendMessage(si->hWnd, GC_ADDLOG, 0, 0);
			}
			else if (si->hWnd) {
				SendMessage(si->hWnd, GC_REDRAWLOG2, 0, 0);
			}
			DoSoundsFlashPopupTrayStuff(si, gce, bIsHighlighted, 0);
			if ((gce->dwFlags & GCEF_ADDTOLOG) && g_Settings.LoggingEnabled)
				LogToFile(si, gce);
		}

		if ( !bRemoveFlag ) {
			iRetVal = 0;
			goto LBL_Exit;
	}	}

	if ( bRemoveFlag )
		iRetVal = ( SM_RemoveUser( gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID ) == 0 ) ? 1 : 0;

LBL_Exit:
	LeaveCriticalSection(&cs);

	#if defined( _UNICODE )
		if ( !( gce->dwFlags & GC_UNICODE )) {
			mir_free((void*)gce->ptszText );
			mir_free((void*)gce->ptszNick );
			mir_free((void*)gce->ptszUID );
			mir_free((void*)gce->ptszStatus );
			mir_free((void*)gce->ptszUserInfo );
			mir_free((void*)gce->pDest->ptszID );
			*gce = save_gce;
			*gce->pDest = save_gcd;
		}
	#endif

	return iRetVal;
}
Exemple #3
0
static INT_PTR Service_AddEvent(WPARAM wParam, LPARAM lParam)
{
	GCEVENT *gce = (GCEVENT*)lParam;
	BOOL bIsHighlighted = FALSE;
	BOOL bRemoveFlag = FALSE;

	if (gce == NULL)
		return GC_EVENT_ERROR;

	GCDEST *gcd = gce->pDest;
	if (gcd == NULL)
		return GC_EVENT_ERROR;

	if (gce->cbSize != sizeof(GCEVENT))
		return GC_EVENT_WRONGVER;

	if (!IsEventSupported(gcd->iType))
		return GC_EVENT_ERROR;

	NotifyEventHooks(hHookEvent, wParam, lParam);

	SESSION_INFO *si;
	mir_cslock lck(cs);

	// Do different things according to type of event
	switch (gcd->iType) {
	case GC_EVENT_ADDGROUP:
	{
		STATUSINFO *si = ci.SM_AddStatus(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszStatus);
		if (si && gce->dwItemData)
			si->hIcon = CopyIcon((HICON)gce->dwItemData);
	}
		return 0;

	case GC_EVENT_CHUID:
	case GC_EVENT_CHANGESESSIONAME:
	case GC_EVENT_SETITEMDATA:
	case GC_EVENT_GETITEMDATA:
	case GC_EVENT_CONTROL:
	case GC_EVENT_SETSBTEXT:
	case GC_EVENT_ACK:
	case GC_EVENT_SENDMESSAGE:
	case GC_EVENT_SETSTATUSEX:
		return DoControl(gce, wParam);

	case GC_EVENT_SETCONTACTSTATUS:
		return ci.SM_SetContactStatus(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, (WORD)gce->dwItemData);

	case GC_EVENT_TOPIC:
		if (si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule)) {
			if (gce->ptszText) {
				replaceStrT(si->ptszTopic, RemoveFormatting(gce->ptszText));
				db_set_ts(si->hContact, si->pszModule, "Topic", si->ptszTopic);
				if (ci.OnSetTopic)
					ci.OnSetTopic(si);
				if (db_get_b(NULL, CHAT_MODULE, "TopicOnClist", 0))
					db_set_ts(si->hContact, "CList", "StatusMsg", si->ptszTopic);
			}
		}
		break;

	case GC_EVENT_ADDSTATUS:
		ci.SM_GiveStatus(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, gce->ptszStatus);
		bIsHighlighted = ci.IsHighlighted(NULL, gce);
		break;

	case GC_EVENT_REMOVESTATUS:
		ci.SM_TakeStatus(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, gce->ptszStatus);
		bIsHighlighted = ci.IsHighlighted(NULL, gce);
		break;

	case GC_EVENT_MESSAGE:
	case GC_EVENT_ACTION:
		if (!gce->bIsMe && gce->pDest->ptszID && gce->ptszText) {
			si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule);
			bIsHighlighted = ci.IsHighlighted(si, gce);
		}
		break;

	case GC_EVENT_NICK:
		ci.SM_ChangeNick(gce->pDest->ptszID, gce->pDest->pszModule, gce);
		bIsHighlighted = ci.IsHighlighted(NULL, gce);
		break;

	case GC_EVENT_JOIN:
		AddUser(gce);
		bIsHighlighted = ci.IsHighlighted(NULL, gce);
		break;

	case GC_EVENT_PART:
	case GC_EVENT_QUIT:
	case GC_EVENT_KICK:
		bRemoveFlag = TRUE;
		bIsHighlighted = ci.IsHighlighted(NULL, gce);
		break;
	}

	// Decide which window (log) should have the event
	LPCTSTR pWnd = NULL;
	LPCSTR pMod = NULL;
	if (gcd->ptszID) {
		pWnd = gcd->ptszID;
		pMod = gcd->pszModule;
	}
	else if (gcd->iType == GC_EVENT_NOTICE || gcd->iType == GC_EVENT_INFORMATION) {
		si = ci.GetActiveSession();
		if (si && !lstrcmpA(si->pszModule, gcd->pszModule)) {
			pWnd = si->ptszID;
			pMod = si->pszModule;
		}
		else return 0;
	}
	else {
		// Send the event to all windows with a user pszUID. Used for broadcasting QUIT etc
		ci.SM_AddEventToAllMatchingUID(gce);
		if (!bRemoveFlag)
			return 0;
	}

	// add to log
	if (pWnd) {
		si = ci.SM_FindSession(pWnd, pMod);

		// fix for IRC's old stuyle mode notifications. Should not affect any other protocol
		if ((gce->pDest->iType == GC_EVENT_ADDSTATUS || gce->pDest->iType == GC_EVENT_REMOVESTATUS) && !(gce->dwFlags & GCEF_ADDTOLOG))
			return 0;

		if (gce && gce->pDest->iType == GC_EVENT_JOIN && gce->time == 0)
			return 0;

		if (si && (si->bInitDone || gce->pDest->iType == GC_EVENT_TOPIC || (gce->pDest->iType == GC_EVENT_JOIN && gce->bIsMe))) {
			int isOk = ci.SM_AddEvent(pWnd, pMod, gce, bIsHighlighted);
			if (ci.OnAddLog)
				ci.OnAddLog(si, isOk);
			if (!(gce->dwFlags & GCEF_NOTNOTIFY))
				ci.DoSoundsFlashPopupTrayStuff(si, gce, bIsHighlighted, 0);
			if ((gce->dwFlags & GCEF_ADDTOLOG) && g_Settings->bLoggingEnabled)
				ci.LogToFile(si, gce);
		}

		if (!bRemoveFlag)
			return 0;
	}

	if (bRemoveFlag)
		return ci.SM_RemoveUser(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID) == 0;

	return GC_EVENT_ERROR;
}
Exemple #4
0
BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce)
{
	switch (gce->pDest->iType) {
	case GC_EVENT_MESSAGE | GC_EVENT_HIGHLIGHT:
		chatApi.ShowPopup(si->hContact, si, Skin_LoadIcon(SKINICON_EVENT_MESSAGE), si->pszModule, si->ptszName, chatApi.aFonts[16].color, TranslateT("%s says: %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_ACTION | GC_EVENT_HIGHLIGHT:
		chatApi.ShowPopup(si->hContact, si, Skin_LoadIcon(SKINICON_EVENT_MESSAGE), si->pszModule, si->ptszName, chatApi.aFonts[16].color, _T("%s %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_MESSAGE:
		chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_MESSAGE], si->pszModule, si->ptszName, chatApi.aFonts[9].color, TranslateT("%s says: %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_ACTION:
		chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_ACTION], si->pszModule, si->ptszName, chatApi.aFonts[15].color, _T("%s %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_JOIN:
		chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_JOIN], si->pszModule, si->ptszName, chatApi.aFonts[3].color, TranslateT("%s has joined"), gce->ptszNick);
		break;
	case GC_EVENT_PART:
		if (!gce->ptszText)
			chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_PART], si->pszModule, si->ptszName, chatApi.aFonts[4].color, TranslateT("%s has left"), gce->ptszNick);
		else
			chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_PART], si->pszModule, si->ptszName, chatApi.aFonts[4].color, TranslateT("%s has left (%s)"), gce->ptszNick, RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_QUIT:
		if (!gce->ptszText)
			chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_QUIT], si->pszModule, si->ptszName, chatApi.aFonts[5].color, TranslateT("%s has disconnected"), gce->ptszNick);
		else
			chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_QUIT], si->pszModule, si->ptszName, chatApi.aFonts[5].color, TranslateT("%s has disconnected (%s)"), gce->ptszNick, RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_NICK:
		chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_NICK], si->pszModule, si->ptszName, chatApi.aFonts[7].color, TranslateT("%s is now known as %s"), gce->ptszNick, gce->ptszText);
		break;
	case GC_EVENT_KICK:
		if (!gce->ptszText)
			chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_KICK], si->pszModule, si->ptszName, chatApi.aFonts[6].color, TranslateT("%s kicked %s"), (char *)gce->ptszStatus, gce->ptszNick);
		else
			chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_KICK], si->pszModule, si->ptszName, chatApi.aFonts[6].color, TranslateT("%s kicked %s (%s)"), (char *)gce->ptszStatus, gce->ptszNick, RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_NOTICE:
		chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_NOTICE], si->pszModule, si->ptszName, chatApi.aFonts[8].color, TranslateT("Notice from %s: %s"), gce->ptszNick, RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_TOPIC:
		if (!gce->ptszNick)
			chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_TOPIC], si->pszModule, si->ptszName, chatApi.aFonts[11].color, TranslateT("The topic is '%s'"), RemoveFormatting(gce->ptszText));
		else
			chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_TOPIC], si->pszModule, si->ptszName, chatApi.aFonts[11].color, TranslateT("The topic is '%s' (set by %s)"), RemoveFormatting(gce->ptszText), gce->ptszNick);
		break;
	case GC_EVENT_INFORMATION:
		chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_INFO], si->pszModule, si->ptszName, chatApi.aFonts[12].color, _T("%s"), RemoveFormatting(gce->ptszText));
		break;
	case GC_EVENT_ADDSTATUS:
		chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_ADDSTATUS], si->pszModule, si->ptszName, chatApi.aFonts[13].color, TranslateT("%s enables '%s' status for %s"), gce->ptszText, (char *)gce->ptszStatus, gce->ptszNick);
		break;
	case GC_EVENT_REMOVESTATUS:
		chatApi.ShowPopup(si->hContact, si, chatApi.hIcons[ICON_REMSTATUS], si->pszModule, si->ptszName, chatApi.aFonts[14].color, TranslateT("%s disables '%s' status for %s"), gce->ptszText, (char *)gce->ptszStatus, gce->ptszNick);
		break;
	}

	return TRUE;
}
bool CGUIInstance::Update()
{
	// reset render info
	m_VertexInfo.clear();
	if (m_ItemRef)
	{
		m_ItemRef->Update();
		m_ItemRef->GetRenderParams(m_VertexInfo, GetPosX(), GetPosY(), GetWidth(), GetHeight(), m_State, m_fAngle, m_iColor);
		vector<GUIFONTINFO> newFontData;
		m_ItemRef->GetFontParams(newFontData, GetPosX(), GetPosY(), GetWidth(), GetHeight(), m_State);

		for (UINT i=0; i<newFontData.size(); i++)
		{
			DWORD dwNewPrimaryFont = newFontData[i].dwPrimaryFontName;
			DWORD dwNewSecondaryFont = newFontData[i].dwSecondaryFontName;
			DWORD dwNewText = newFontData[i].dwText;

			if (i >= m_pFont.size())
			{
				// create new fonts!
				CREATEFONTINTERFACE cfi;
				static DWORD msgHash_CreateFont = CHashString(_T("CreateFont")).GetUniqueID();
				EngineGetToolBox()->SendMessage(msgHash_CreateFont, sizeof(CREATEFONTINTERFACE), &cfi);
				if (cfi.m_FontInterface == NULL)
				{
					EngineGetToolBox()->Log(LOGERROR, _T("Instance could not create a new font!\n"));
					assert(cfi.m_FontInterface);
					return false;
				}
				m_pFont.push_back(cfi.m_FontInterface);
				m_pFont[i]->UseKerning(false);
				m_pFont[i]->SetKerningScale( 1.0f );
				m_pFont[i]->SetVisible( true );
				m_pFont[i]->SetLeadingScale( 1.0f );					
			}

			if (i >= m_FontInfo.size())
			{
				m_pFont[i]->SetFont(m_ToolBox->GetHashString(dwNewPrimaryFont), newFontData[i].iFontSize);
				m_pFont[i]->SetFontBold(m_ToolBox->GetHashString(dwNewSecondaryFont), newFontData[i].iFontSize);
				m_pFont[i]->SetRenderRect(newFontData[i].renderRect.left, newFontData[i].renderRect.top, 
					newFontData[i].renderRect.right, newFontData[i].renderRect.bottom);				
				
				StdString colorAdjust = MultiplyTextColor(m_ToolBox->GetHashString(dwNewText));
				m_pFont[i]->SetText(colorAdjust);
				if (newFontData[i].bCentered)
				{
					float centerX = GetWidth() / 2.f;
					float centerY = GetHeight() / 2.f;
                    StdString cleanStr = RemoveFormatting(m_ToolBox->GetHashString(dwNewText));
					int textWidth = m_pFont[i]->GetFontPixWidth(cleanStr);
					int textHeight = newFontData[i].iFontSize * m_pFont[i]->GetNumLines();
					float textPosX = centerX - ((float)textWidth / 2.f) + newFontData[i].iXOffset;
					float textPosY = centerY - ((float)textHeight / 2.f) + newFontData[i].iYOffset;
					m_pFont[i]->SetOffset(textPosX, textPosY);
				}
				else
				{
					m_pFont[i]->SetOffset((float)newFontData[i].iXOffset, (float)newFontData[i].iYOffset);
				}

				m_pFont[i]->SetPageOffset(m_iPageOffsetX, m_iPageOffsetY);					
				m_pFont[i]->SetWidthRatio(m_fWidthRatio);
				m_pFont[i]->SetHeightRatio(m_fHeightRatio);
				m_pFont[i]->SetZoomFactor(m_fZoomFactor);

				if (newFontData[i].bUseShadow)
				{
					m_pFont[i]->EnableDropShadow(true);
					m_pFont[i]->SetShadowVals(newFontData[i].iShadowColor, newFontData[i].iShadowXScale, newFontData[i].iShadowYScale, newFontData[i].iShadowXOffset, newFontData[i].iShadowYOffset);
				}

				GUIFONTINFO entry;
				entry.dwPrimaryFontName = newFontData[i].dwPrimaryFontName;
				entry.dwSecondaryFontName = newFontData[i].dwSecondaryFontName;
				entry.dwText = newFontData[i].dwText;
				entry.iFontSize = newFontData[i].iFontSize;
				entry.bCentered = newFontData[i].bCentered;
				entry.iXOffset = newFontData[i].iXOffset;
				entry.iYOffset = newFontData[i].iYOffset;
				entry.renderRect = newFontData[i].renderRect;
				entry.clippingRect = newFontData[i].clippingRect;
				entry.bUseClippingRect = newFontData[i].bUseClippingRect;
				entry.bRender = true;
				entry.bUseShadow = newFontData[i].bUseShadow;
				entry.iShadowColor = newFontData[i].iShadowColor;
				entry.iShadowXScale = newFontData[i].iShadowXScale;
				entry.iShadowYScale = newFontData[i].iShadowYScale;
				entry.iShadowXOffset = newFontData[i].iShadowXOffset;
				entry.iShadowYOffset = newFontData[i].iShadowYOffset;
				
				m_FontInfo.push_back(entry);
			}
			// compare elements
			else
			{	
				if (m_FontInfo[i].dwPrimaryFontName != newFontData[i].dwPrimaryFontName)
				{
					m_pFont[i]->SetFont(m_ToolBox->GetHashString(dwNewPrimaryFont), newFontData[i].iFontSize);
					m_FontInfo[i].dwPrimaryFontName = newFontData[i].dwPrimaryFontName;
					m_FontInfo[i].iFontSize = newFontData[i].iFontSize;
				}
				if (m_FontInfo[i].dwSecondaryFontName != newFontData[i].dwSecondaryFontName)
				{
					m_pFont[i]->SetFontBold(m_ToolBox->GetHashString(dwNewSecondaryFont), newFontData[i].iFontSize);
					m_FontInfo[i].dwSecondaryFontName = newFontData[i].dwSecondaryFontName;
					m_FontInfo[i].iFontSize = newFontData[i].iFontSize;
				}
				if (m_FontInfo[i].iFontSize != newFontData[i].iFontSize)
				{
					m_pFont[i]->SetFont(m_ToolBox->GetHashString(dwNewPrimaryFont), newFontData[i].iFontSize);
					m_pFont[i]->SetFontBold(m_ToolBox->GetHashString(dwNewSecondaryFont), newFontData[i].iFontSize);
					m_FontInfo[i].iFontSize = newFontData[i].iFontSize;
				}
				if (m_FontInfo[i].dwText != newFontData[i].dwText)
				{
					StdString colorAdjust = MultiplyTextColor(m_ToolBox->GetHashString(dwNewText));
					m_pFont[i]->SetText(colorAdjust);
					m_FontInfo[i].dwText = newFontData[i].dwText;
					if (newFontData[i].bCentered)
					{
						float centerX = GetWidth() / 2.f;
						float centerY = GetHeight() / 2.f;
						StdString cleanStr = RemoveFormatting(m_ToolBox->GetHashString(dwNewText));
						int textWidth = m_pFont[i]->GetFontPixWidth(cleanStr);
						int textHeight = m_FontInfo[i].iFontSize * m_pFont[i]->GetNumLines();
						float textPosX = centerX - ((float)textWidth / 2.f) + m_FontInfo[i].iXOffset;
						float textPosY = centerY - ((float)textHeight / 2.f) + m_FontInfo[i].iYOffset;
						m_pFont[i]->SetOffset(textPosX, textPosY);
					}
				}
				if (m_FontInfo[i].bCentered != newFontData[i].bCentered)
				{
					m_FontInfo[i].bCentered = newFontData[i].bCentered;
					if (newFontData[i].bCentered)
					{
						float centerX = GetWidth() / 2.f;
						float centerY = GetHeight() / 2.f;
						StdString cleanStr = RemoveFormatting(m_ToolBox->GetHashString(dwNewText));
						int textWidth = m_pFont[i]->GetFontPixWidth(cleanStr);
						int textHeight = m_FontInfo[i].iFontSize * m_pFont[i]->GetNumLines();
						float textPosX = centerX - ((float)textWidth / 2.f) + newFontData[i].iXOffset;
						float textPosY = centerY - ((float)textHeight / 2.f) + newFontData[i].iYOffset;
						m_pFont[i]->SetOffset(textPosX, textPosY);
					}
					else
					{
						m_pFont[i]->SetOffset((float)newFontData[i].iXOffset, (float)newFontData[i].iYOffset);
					}
				}
				if ((m_FontInfo[i].iXOffset != newFontData[i].iXOffset) || (m_FontInfo[i].iYOffset != newFontData[i].iYOffset))
				{
					if (!m_FontInfo[i].bCentered)
					{
						m_pFont[i]->SetOffset((float)newFontData[i].iXOffset, (float)newFontData[i].iYOffset);
					}
					m_FontInfo[i].iXOffset = newFontData[i].iXOffset;
					m_FontInfo[i].iYOffset = newFontData[i].iYOffset;
				}
				if ((m_FontInfo[i].renderRect.bottom != newFontData[i].renderRect.bottom) ||
					(m_FontInfo[i].renderRect.top != newFontData[i].renderRect.top) ||
					(m_FontInfo[i].renderRect.left != newFontData[i].renderRect.left) ||
					(m_FontInfo[i].renderRect.right != newFontData[i].renderRect.right))
				{
					m_pFont[i]->SetRenderRect(newFontData[i].renderRect.left, newFontData[i].renderRect.top, 
						newFontData[i].renderRect.right, newFontData[i].renderRect.bottom);
					m_FontInfo[i].renderRect = newFontData[i].renderRect;
					if (newFontData[i].bCentered)
					{
						float centerX = GetWidth() / 2.f;
						float centerY = GetHeight() / 2.f;
						StdString cleanStr = RemoveFormatting(m_ToolBox->GetHashString(dwNewText));
						int textWidth = m_pFont[i]->GetFontPixWidth(cleanStr);
						int textHeight = m_FontInfo[i].iFontSize * m_pFont[i]->GetNumLines();
						float textPosX = centerX - ((float)textWidth / 2.f) + newFontData[i].iXOffset;
						float textPosY = centerY - ((float)textHeight / 2.f) + newFontData[i].iYOffset;
						m_pFont[i]->SetOffset(textPosX, textPosY);
					}
					else
					{
						m_pFont[i]->SetOffset((float)newFontData[i].iXOffset, (float)newFontData[i].iYOffset);
					}
				}

				if (m_FontInfo[i].bUseShadow != newFontData[i].bUseShadow)
				{
					m_FontInfo[i].bUseShadow = newFontData[i].bUseShadow;
					m_FontInfo[i].iShadowColor = newFontData[i].iShadowColor;
					m_FontInfo[i].iShadowXScale = newFontData[i].iShadowXScale;
					m_FontInfo[i].iShadowYScale = newFontData[i].iShadowYScale;
					m_FontInfo[i].iShadowXOffset = newFontData[i].iShadowXOffset;
					m_FontInfo[i].iShadowYOffset = newFontData[i].iShadowYOffset;

					if (m_FontInfo[i].bUseShadow)
					{
						m_pFont[i]->EnableDropShadow(true);
						m_pFont[i]->SetShadowVals(m_FontInfo[i].iShadowColor, m_FontInfo[i].iShadowXScale, m_FontInfo[i].iShadowYScale, m_FontInfo[i].iShadowXOffset, m_FontInfo[i].iShadowYOffset);
					}
					else
					{
						m_pFont[i]->EnableDropShadow(false);
					}
				}
				else if(m_FontInfo[i].bUseShadow)					
				{
					m_FontInfo[i].iShadowColor = newFontData[i].iShadowColor;
					m_FontInfo[i].iShadowXScale = newFontData[i].iShadowXScale;
					m_FontInfo[i].iShadowYScale = newFontData[i].iShadowYScale;
					m_FontInfo[i].iShadowXOffset = newFontData[i].iShadowXOffset;
					m_FontInfo[i].iShadowYOffset = newFontData[i].iShadowYOffset;
					m_pFont[i]->SetShadowVals(m_FontInfo[i].iShadowColor, m_FontInfo[i].iShadowXScale, m_FontInfo[i].iShadowYScale, m_FontInfo[i].iShadowXOffset, m_FontInfo[i].iShadowYOffset);
				}
				
				m_FontInfo[i].clippingRect = newFontData[i].clippingRect;
				m_FontInfo[i].bUseClippingRect = newFontData[i].bUseClippingRect;					

				m_FontInfo[i].bRender = true;
			}
			if (m_bColorChanged)
			{
				StdString colorChanged = MultiplyTextColor(m_ToolBox->GetHashString(dwNewText));
				m_pFont[i]->SetText(colorChanged);				
			}
		}

		// disable any fonts that haven't been updated
		for (UINT j=newFontData.size(); j<m_FontInfo.size(); j++)
		{
			m_FontInfo[j].bRender = false;
		}
	}

	return true;
}