Ejemplo n.º 1
0
static void CalcInternalMessage( LPTCHAR result, UINT32 Line, const TCHAR* Filename )
{
	const TCHAR* Slash    = camStrrchr( Filename, TEXT('\\') );
	const TCHAR* Dot      = camStrrchr( Filename, TEXT('.')  );
	TCHAR CodedFile[20];

	if (Slash && Dot)
	{
		TCHAR* p = CodedFile;

		*p++ = Filename[0];					// 1st char is first letter of dirname
		*p++ = TEXT('.');					// seperators
		*p++ = Slash[1];					// 1st 2 chars of filename
		*p++ = Slash[2];
		*p++ = TEXT('.');
		*p++ = Dot[-2];						// last 2 chars of filename
		*p++ = Dot[-1];
		*p = 0;

		Filename = CodedFile; 
	}

	// this message should not be translated
	String_256 jcf(_R(IDS_INTERNAL_ERROR_MSG));
	camSnprintf(result, 256, jcf, (UINT32) Line, (LPCTSTR) Filename);
}
Ejemplo n.º 2
0
String_32::String_32(UINT32 resID, UINT32 hinst)
{
	*(text = fixedbuf) = 0;
	length = FIX_LEN_BUFSIZE;
	if (!Load(resID, hinst))
	{	
		ERROR3("String resource failed to load");
		TCHAR buf[128];
		camSnprintf(buf, 128, TEXT("<%X:%X>"), (INT32) resID, (INT32) hinst);
		camStrcpy(text, (camStrlen(buf) <= 32) ? buf : TEXT("!"));
	}
}
Ejemplo n.º 3
0
void CDECL Error::XSetError( UINT32 errID, ...)
{


	if ( (errID==FALSE) || (errID==TRUE) )
	{
		// someone probably used the wrong macro parameters e.g. TRUE and FALSE instead of ID
		// This call will set an _R(IDE_INTERNAL_ERROR) for us
		ERROR2RAW( "ERROR1 macro used with invalid parameters" );
		return;
	}

	TCHAR				buf[256];

	va_list marker;

	va_start( marker, errID );

	String_256 result;

	// load the format string as a resoure (note no module ID yet)
	if (!SmartLoadString(0, errID, buf, sizeof(buf)))
	{
		camSnprintf( buf, 256, wxT("Error<%u>"), errID ); // keep inline
	}

	// now do _MakeMsg type formatting
	result.CCvsprintf(buf, marker);

#if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX)
	// Set the help context.
	SetNextMsgHelpContext(errID);
#endif
	// ralph needs this so that he can map the ID to a HRESULT before passing it
	// back to a harness
	TRACEUSER( "Chris", wxT("oOoOo Ralph Set Error %d \n"), RalphErrorID );

	RalphErrorID =errID;

	// and copy result into ErrorString
	SetErrorSerious( result );

	// trace output because SetErrorSerious doesn't bother
	TRACE( wxT("Setting error: ID = %d: \"%s\"\n"), errID, ErrorString);

	// then tidy up	
	va_end( marker );

	ResetWhere();
}
Ejemplo n.º 4
0
void Error::SetError(UINT32 number, UINT32 module)
{
	static TCHAR BASED_CODE LastResort[] = _T("Cannot perform SetError (2)");
	// We now check for a real recursive call. Should only happen if we can't get translate
	// an ID to an error string. Perhaps if we're really low on memory. We must then set the
	// minimum acceptable error string...
	if (InSetError)
	{
		TRACE(_T("SetError really has been called recursively (2)\n"));
		ErrorID = _R(IDE_EX_BADOP); // should have it's own, but...
		ErrStatus = ERRORSTAT_TEXT;
		ErrorHasBeenReported=FALSE;
		ModuleID = module;
		camStrcpy( ErrorString, LastResort );
		return;
	}
	InSetError++;
	if (!ErrorHasBeenReported)
	{
		// ENSURE(FALSE, "Recursive SetError call"); IMHO this is pointless - Alex
		TRACE( _T("SetError called twice: ID = %u  Module = %u\n"), number, module);
		InSetError--;
		return;
	}
	RalphErrorID = ErrorID = number;
	ModuleID = module;
	ErrorString[0] = 0;
	ErrStatus = ERRORSTAT_ID;
	ErrorHasBeenReported = FALSE;
	if (!SmartLoadString(module, ErrorID, ErrorString, 256 * sizeof(TCHAR)) )
	{
		camSnprintf( ErrorString, 256, _T("Error Number %u from module ID %u"), ErrorID, ModuleID );
	}
	
	TRACE( _T("Setting error: ID = %d: \"%s\"\n"), ErrorID, ErrorString);
	InSetError--;
}
Ejemplo n.º 5
0
/**************************************************************************************
>	INT32 StringBase::CCvsprintf(const TCHAR* layout, va_list va)

	Author:		Justin_Flude (Xara Group Ltd) <*****@*****.**>
	Created:	22nd April 1993
	Inputs:		A pointer to the format string, a variable-parameter pointer to the
				arguments to be formatted.
	Returns:	The length of the StringBase once the arguments have been substituted into
				it.
	Purpose:	This private helper function takes the list generated by
				StringBase::BuildList and scans through it, formatting stack-frame
				parameters according to their list entry.  This produces another list,
				this time of formatted parameters, which is then concatenated to
				produce the final output.
	Scope:		Private
***************************************************************************************/
INT32 StringBase::CCvsprintf(const TCHAR* layout, va_list va)
{
/*	if (IsUserName("JustinF"))
		TRACE( _T("CCvsprintf called with format string %s\n"), layout);
*/
	INT32 n = BuildList(layout);
	for (INT32 i = 1; i <= n; i++)
	{
		for (Item* p = Item::head; p; p = p->next)
			if (p->pos != i)
				continue;
			else
			{  	// Found specifier i in the list, so grab from the stack
				// and call wsprintf() to convert to text.  The converted
				// text is put in the temp[] buffer - note the enormous
				// size of this, in accordance with the C standard.
				TCHAR temp[512];
				switch (p->type)
				{
					// type 'c' - single character
					case CHAR_ARG:
#if defined(__WXMSW__)
						camSnprintf( temp, 512, p->str, va_arg(va, TCHAR) );
#else					// TCHARs are promoted to INT32 when passed via ... under GCC
						camSnprintf( temp, 512, p->str, va_arg(va, INT32) );
#endif
						break;
					// type 'd' / 'i' - signed decimal integer
					case SIGNED_INT_ARG:
						camSnprintf(temp, 512, p->str, va_arg(va, INT32));
						break;
					// type 'ld' / 'li' - signed decimal INT32
					case SIGNED_INT32_ARG:
						camSnprintf(temp, 512, p->str, va_arg(va, INT32));
						break;
					// type 'u' - unsigned decimal integer
					case UNSIGNED_INT_ARG:
						camSnprintf(temp, 512, p->str, va_arg(va, UINT32));
						break;
					// type 'lu' / 'lx' / 'lX' - unsigned decimal INT32
					case UNSIGNED_INT32_ARG:
						camSnprintf(temp, 512, p->str, va_arg(va, UINT32));
						break;
					// type 's' - long pointer to array of (constant) char
					case CHAR_POINTER_ARG:
						camSnprintf(temp, 512, p->str, va_arg(va, LPCTSTR));
						break;
					// type 'p' a pointer
					case UINT_PTR_ARG:
						camSnprintf(temp, 512, p->str, va_arg(va, UINT_PTR));
						break;
					// type 'S' - a pointer to a StringBase.  First change the
					// %S format specifier, which is our own, into a sprintf()
					// compatible %s.  Note that the 'S' is always the last
					// character of the format specifier.
					case STRING_POINTER_ARG:
						(p->str)[camStrlen(p->str) - 1] = TEXT('s');
						camSnprintf(temp, 512, p->str, LPCTSTR(va_arg(va, const StringBase*)->text));
						break;
					default:
						break;
				}
				// Replace the format specifier with the formatted text
				delete[] p->str;
				camStrcpy(p->str = new TCHAR[camStrlen(temp) + 1], temp);
				break;
			}
	}
	
	// Concatenate every string in the list, tidy up, and return in "this" string
	*text = 0;
	UINT32 NextChar = 0;
	INT32 Index = 0;
	for (Item* p = Item::head; (p != NULL && NextChar < length) ; p = p->next)
	{
/*		if (camStrlen(text) + camStrlen(p->str) < length)
			camStrcat(text, p->str);
		else
		{
			ENSURE(FALSE, "Call to String::MakeMsg will overflow - text has been truncated");
		}
*/
		for (Index = 0; p->str[Index] != 0 && NextChar < length; Index++)
			text[NextChar++] = p->str[Index];
	}

	if (NextChar > length)
		NextChar = length;
	text[NextChar] = TCHAR('\0');

	delete Item::head;
	return camStrlen(text);
}
Ejemplo n.º 6
0
static void InternalAssert(const TCHAR * AssertDescription, const char * lpszFileName, INT32 nLine, BOOL UseMFC)
{
	if (!UseMFC)
#if defined(__WXMSW__)
		MessageBeep(MB_ICONASTERISK);
#else
		::wxBell();
#endif


#ifdef _ENSURES

	TCHAR				sz[256];
	static TCHAR BASED_CODE szTitle[] = wxT("Ensure Failed!");

	// In Unicode we need to convert the filename to TCHAR
#if 0 != wxUSE_UNICODE
	TCHAR szRealFile[256];
	size_t count = camMbstowcs(szRealFile, lpszFileName, 255);
	if (count == (size_t)-1)
		count = 0;
	szRealFile[count] = (TCHAR)0;
	const TCHAR* lpszRealFile = szRealFile;
#else
	const TCHAR* lpszRealFile = lpszFileName;
#endif

	static TCHAR BASED_CODE szMessage[] = wxT("%s, File %s, Line %d");
	static TCHAR BASED_CODE szMessageNoReason[] = wxT("Error %d@%s");			// note number first

	// get app name or NULL if unknown (don't call assert)
//	const TCHAR		   *pszAppName = wxGetApp().GetAppName();

	if (AssertDescription != NULL)
	{
		camSnprintf(sz, 255,
			szMessage,                       
			AssertDescription, 
			lpszRealFile, 
			nLine);    
	}
	else   
	{
		camSnprintf(sz, 255,
			szMessageNoReason,
			nLine,
			lpszRealFile);
	}
	
#ifdef _DEBUG
//PORTNOTE("other","Remove afxTraceEnabled")
//#ifndef EXCLUDE_FROM_XARALX
//	if (afxTraceEnabled)
#if defined(__WXMSW__)
	{
		// assume the debugger or auxiliary port
		#ifndef _MAC
		::OutputDebugString(sz);
		::OutputDebugString(_T(", "));
		::OutputDebugString(szTitle);
		::OutputDebugString(_T("\n\r"));
		#else
		// Mac version needs them all together
		camStrcat(sz, _T(", "));
		camStrcat(sz,szTitle);
		camStrcat(sz,_T("\n\r"));
		::OutputDebugString(sz);
		#endif
	}
#endif
#endif


	if (AssertBusy > 0)
	{
		// getting assertion while inside an assertion
		//  - it has already been traced, but 
		// break into the debugger (or Dr Watson log)
		DEBUGBREAK;									// else Win32s might die (just beeps)
		return;
	}

	AssertBusy++;

	if ( Error::IsInRenderThread() )
	{
		TRACE( wxT("In RenderThread so clearing up system") );
		Error::RenderThreadReset();
													// Commented out - no problem using wx for render errors
//		UseMFC = FALSE;								// mustn't use MFC for render errors 
	}

	INT32					result;

	TCHAR				RealErrorMsg[256];

	if (UseMFC)
	{
		// use our error handler to report ensures as it is more robust instead of MessageBox
		// The arrangement of buttons is the same as the exception handler dialog, not the same
		// as the original Ensure dialog (which was Abort/Retry/Ignore)
		ErrorInfo Info;

		// try to preserve original error message
		camStrcpy( RealErrorMsg, Error::GetErrorString() );

		Error::SetErrorSerious( sz );			// set error msg (vaping any previous one)
		Info.ErrorMsg = 0;
		Info.Button[0] = _R(IDS_CONTINUE);
		Info.Button[1] = _R(IDS_QUIT);
#ifndef EXCLUDE_FROM_XARALX
		if (IsWin32NT())
		{
#endif
			// only NT can cope with an Abort button
			Info.Button[2] = _R(IDS_ABORT);
			Info.Button[3] = _R(IDS_DEBUG);
#ifndef EXCLUDE_FROM_XARALX
		}
		else
		{
			Info.Button[2] = _R(IDS_DEBUG);
		}
#endif
													// no default button (or Help)
		Info.Cancel = 1;							// Esc = Continue

		result = InformGeneral( ERRORTYPE_ENSURE, &Info );
	}
	else

	{
		CamResource::DoneInit();
		CCamApp::DisableSystem();

		// e.g. if this an MFC assert, don't use our lovely error handler becuase that itself
		// uses MFC. Instead we use good old MessageBox

#if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX)
		wxWindow	   *pParent = AfxGetApp().GetTopWindow(); 
PORTNOTE("other","Use CInformErrorDialog::GetSafeParent() when implemented")
#ifndef EXCLUDE_FROM_XARALX
		CInformErrorDialog::GetSafeParent();
#endif
#else
		wxWindow	   *pParent = NULL;
#endif

		wxMessageDialog	Dialog( pParent, sz, szTitle, wxICON_HAND | wxYES_NO | wxCANCEL );
		INT32 nCode = Dialog.ShowModal();

		CCamApp::EnableSystem();

		// convert MessageBox return value into a sane button ID
		switch (nCode)
		{
			case wxID_NO:
				result = _R(IDS_ABORT);
				break;
			case wxID_YES:
				result = _R(IDS_DEBUG);
				break;
			case wxID_CANCEL:
			default:
				result = _R(IDS_CONTINUE);
				break;
		}
	}

	AssertBusy--;

	if ((ResourceID)result == _R(IDS_DEBUG))
	{
		DEBUGBREAK;
	}
	// no action on _R(IDS_CONTINUE))
	else if ((ResourceID)result == _R(IDS_QUIT))
	{
		// quit in a slightly nice way
		wxWindow *MainWnd = AfxGetApp().GetTopWindow();
		if( MainWnd && MainWnd->IsShown() )
		{
			MainWnd->Destroy();
		}
	} // drop through
	if (((ResourceID)result == _R(IDS_ABORT)) || ((ResourceID)result == _R(IDS_QUIT)))
	{
		// if no window, try nasty exit
		AfxAbort();
		return; // how did we get here?
	}

	// if we ever get here we just carry on as if nothing happened

PORTNOTE("other","We can never use MFC again")
#ifndef EXCLUDE_FROM_XARALX
	if (UseMFC)
	{
		if (RealErrorMsg[0])
			Error::SetErrorSerious( RealErrorMsg );		// restore previous error msg
		else
			Error::ClearError();
	} 
#endif
#else
	// parameters not used if non-debug
	(void)lpszFileName;
	(void)nLine;
#endif // _ENSURES

}
Ejemplo n.º 7
0
void CCPanose::GetDebugDetails(StringBase *pStr)
{
	TCHAR				s[256], t[256];

	camSnprintf( s, 256, _T("\r\nPANOSE information\r\n\r\n") );
	(*pStr) += s;
	
	switch (mFamilyType)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_FAMILY_TEXT_DISPLAY		: camSnprintf( t, 256, _T("Text and display") ); break;
		case PAN_FAMILY_SCRIPT				: camSnprintf( t, 256, _T("Script") ); break;
		case PAN_FAMILY_DECORATIVE			: camSnprintf( t, 256, _T("Decorative") ); break;
		case PAN_FAMILY_PICTORIAL			: camSnprintf( t, 256, _T("Pictorial") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Family Type\t= (%d) %s\r\n") , mFamilyType, t);
	(*pStr) += s;

	switch (mSerifStyle)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_SERIF_COVE					: camSnprintf( t, 256, _T("Cove") ); break;
		case PAN_SERIF_OBTUSE_COVE			: camSnprintf( t, 256, _T("Obtuse cove") ); break;
		case PAN_SERIF_SQUARE_COVE			: camSnprintf( t, 256, _T("Square cove") ); break;
		case PAN_SERIF_OBTUSE_SQUARE_COVE	: camSnprintf( t, 256, _T("Obtuse square cove") ); break;
		case PAN_SERIF_SQUARE				: camSnprintf( t, 256, _T("Square	") ); break;
		case PAN_SERIF_THIN					: camSnprintf( t, 256, _T("Thin") ); break;
		case PAN_SERIF_BONE					: camSnprintf( t, 256, _T("Bone") ); break;
		case PAN_SERIF_EXAGGERATED			: camSnprintf( t, 256, _T("Exaggerated") ); break;
		case PAN_SERIF_TRIANGLE				: camSnprintf( t, 256, _T("Triangle") ); break;
		case PAN_SERIF_NORMAL_SANS			: camSnprintf( t, 256, _T("Normal sans serif") ); break;
		case PAN_SERIF_OBTUSE_SANS			: camSnprintf( t, 256, _T("Obtuse sans serif") ); break;
		case PAN_SERIF_PERP_SANS			: camSnprintf( t, 256, _T("Perp sans serif") ); break;
		case PAN_SERIF_FLARED				: camSnprintf( t, 256, _T("Flared") ); break;
		case PAN_SERIF_ROUNDED				: camSnprintf( t, 256, _T("Rounded") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Serif Style\t\t= (%d) %s\r\n") , mSerifStyle, t);
	(*pStr) += s;
	
	switch (mWeight)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_WEIGHT_VERY_LIGHT			: camSnprintf( t, 256, _T("Very light") ); break;
		case PAN_WEIGHT_LIGHT				: camSnprintf( t, 256, _T("Light") ); break;
		case PAN_WEIGHT_THIN				: camSnprintf( t, 256, _T("Thin") ); break;
		case PAN_WEIGHT_BOOK				: camSnprintf( t, 256, _T("Book") ); break;
		case PAN_WEIGHT_MEDIUM				: camSnprintf( t, 256, _T("Medium") ); break;
		case PAN_WEIGHT_DEMI				: camSnprintf( t, 256, _T("Demibold") ); break;
		case PAN_WEIGHT_BOLD				: camSnprintf( t, 256, _T("Bold") ); break;
		case PAN_WEIGHT_HEAVY				: camSnprintf( t, 256, _T("Heavy") ); break;
		case PAN_WEIGHT_BLACK				: camSnprintf( t, 256, _T("Black") ); break;
		case PAN_WEIGHT_NORD				: camSnprintf( t, 256, _T("Nord") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Weight\t\t= (%d) %s\r\n") , mWeight, t);
	(*pStr) += s;

	switch (mProportion)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_PROP_OLD_STYLE				: camSnprintf( t, 256, _T("Old style") ); break;
		case PAN_PROP_MODERN				: camSnprintf( t, 256, _T("Modern") ); break;
		case PAN_PROP_EVEN_WIDTH			: camSnprintf( t, 256, _T("Even width") ); break;
		case PAN_PROP_EXPANDED				: camSnprintf( t, 256, _T("Expanded") ); break;
		case PAN_PROP_CONDENSED				: camSnprintf( t, 256, _T("Condensed") ); break;
		case PAN_PROP_VERY_EXPANDED			: camSnprintf( t, 256, _T("Very expanded") ); break;
		case PAN_PROP_VERY_CONDENSED		: camSnprintf( t, 256, _T("Very condensed") ); break;
		case PAN_PROP_MONOSPACED			: camSnprintf( t, 256, _T("Monospaced") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Proportion\t= (%d) %s\r\n") , mProportion, t);
	(*pStr) += s;
	
	switch (mContrast)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_CONTRAST_NONE				: camSnprintf( t, 256, _T("None") ); break;
		case PAN_CONTRAST_VERY_LOW			: camSnprintf( t, 256, _T("Very low") ); break;
		case PAN_CONTRAST_LOW				: camSnprintf( t, 256, _T("Low") ); break;
		case PAN_CONTRAST_MEDIUM_LOW		: camSnprintf( t, 256, _T("Medium low") ); break;
		case PAN_CONTRAST_MEDIUM			: camSnprintf( t, 256, _T("Medium") ); break;
		case PAN_CONTRAST_MEDIUM_HIGH		: camSnprintf( t, 256, _T("Medium high") ); break;
		case PAN_CONTRAST_HIGH				: camSnprintf( t, 256, _T("High") ); break;
		case PAN_CONTRAST_VERY_HIGH			: camSnprintf( t, 256, _T("Very high") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Contrast\t\t= (%d) %s\r\n") , mContrast, t);
	(*pStr) += s;
	
	switch (mStrokeVariation)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_STROKE_GRADUAL_DIAG		: camSnprintf( t, 256, _T("Gradual/diagonal") ); break;
		case PAN_STROKE_GRADUAL_TRAN		: camSnprintf( t, 256, _T("Gradual/transitional") ); break;
		case PAN_STROKE_GRADUAL_VERT		: camSnprintf( t, 256, _T("Gradual/vertical") ); break;
		case PAN_STROKE_GRADUAL_HORZ		: camSnprintf( t, 256, _T("Gradual/horizontal") ); break;
		case PAN_STROKE_RAPID_VERT			: camSnprintf( t, 256, _T("Rapid/vertical") ); break;
		case PAN_STROKE_RAPID_HORZ			: camSnprintf( t, 256, _T("Rapid/horizontal") ); break;
		case PAN_STROKE_INSTANT_VERT		: camSnprintf( t, 256, _T("Instant/vertical") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Stroke Variation\t= (%d) %s\r\n") , mStrokeVariation, t);
	(*pStr) += s;
	
	switch (mArmStyle)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_STRAIGHT_ARMS_HORZ			: camSnprintf( t, 256, _T("Straight arms/horizontal") ); break;
		case PAN_STRAIGHT_ARMS_WEDGE		: camSnprintf( t, 256, _T("Straight arms/wedge") ); break;
		case PAN_STRAIGHT_ARMS_VERT			: camSnprintf( t, 256, _T("traight arms/vertical") ); break;
		case PAN_STRAIGHT_ARMS_SINGLE_SERIF	: camSnprintf( t, 256, _T("Straight arms/single-serif") ); break;
		case PAN_STRAIGHT_ARMS_DOUBLE_SERIF	: camSnprintf( t, 256, _T("Straight arms/double-serif") ); break;
		case PAN_BENT_ARMS_HORZ				: camSnprintf( t, 256, _T("Non-straight arms/horizontal") ); break;
		case PAN_BENT_ARMS_WEDGE			: camSnprintf( t, 256, _T("Non-straight arms/wedge") ); break;
		case PAN_BENT_ARMS_VERT				: camSnprintf( t, 256, _T("Non-straight arms/vertical") ); break;
		case PAN_BENT_ARMS_SINGLE_SERIF		: camSnprintf( t, 256, _T("Non-straight arms/single-serif") ); break;
		case PAN_BENT_ARMS_DOUBLE_SERIF		: camSnprintf( t, 256, _T("Non-straight arms/double-serif") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Arm Style\t\t= (%d) %s\r\n") , mArmStyle, t);
	(*pStr) += s;
	
	switch (mLetterform)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_LETT_NORMAL_CONTACT		: camSnprintf( t, 256, _T("Normal/contact") ); break;
		case PAN_LETT_NORMAL_WEIGHTED		: camSnprintf( t, 256, _T("Normal/weighted") ); break;
		case PAN_LETT_NORMAL_BOXED			: camSnprintf( t, 256, _T("Normal/boxed") ); break;
		case PAN_LETT_NORMAL_FLATTENED		: camSnprintf( t, 256, _T("Normal/flattened") ); break;
		case PAN_LETT_NORMAL_ROUNDED		: camSnprintf( t, 256, _T("Normal/rounded") ); break;
		case PAN_LETT_NORMAL_OFF_CENTER		: camSnprintf( t, 256, _T("Normal/off center") ); break;
		case PAN_LETT_NORMAL_SQUARE			: camSnprintf( t, 256, _T("Normal/square") ); break;
		case PAN_LETT_OBLIQUE_CONTACT		: camSnprintf( t, 256, _T("Oblique/contact") ); break;
		case PAN_LETT_OBLIQUE_WEIGHTED		: camSnprintf( t, 256, _T("Oblique/weighted") ); break;
		case PAN_LETT_OBLIQUE_BOXED			: camSnprintf( t, 256, _T("Oblique/boxed") ); break;
		case PAN_LETT_OBLIQUE_FLATTENED		: camSnprintf( t, 256, _T("Oblique/flattened") ); break;
		case PAN_LETT_OBLIQUE_ROUNDED		: camSnprintf( t, 256, _T("Oblique/rounded") ); break;
		case PAN_LETT_OBLIQUE_OFF_CENTER	: camSnprintf( t, 256, _T("Oblique/off center") ); break;
		case PAN_LETT_OBLIQUE_SQUARE		: camSnprintf( t, 256, _T("Oblique/square") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Letter Form\t= (%d) %s\r\n") , mLetterform, t);
	(*pStr) += s;

	switch (mMidline)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_MIDLINE_STANDARD_TRIMMED	: camSnprintf( t, 256, _T("Standard/trimmed") ); break;
		case PAN_MIDLINE_STANDARD_POINTED	: camSnprintf( t, 256, _T("Standard/pointed") ); break;
		case PAN_MIDLINE_STANDARD_SERIFED	: camSnprintf( t, 256, _T("Standard/serifed") ); break;
		case PAN_MIDLINE_HIGH_TRIMMED		: camSnprintf( t, 256, _T("High/trimmed") ); break;
		case PAN_MIDLINE_HIGH_POINTED		: camSnprintf( t, 256, _T("High/pointed") ); break;
		case PAN_MIDLINE_HIGH_SERIFED		: camSnprintf( t, 256, _T("High/serifed") ); break;
		case PAN_MIDLINE_CONSTANT_TRIMMED	: camSnprintf( t, 256, _T("Constant/trimmed") ); break;
		case PAN_MIDLINE_CONSTANT_POINTED	: camSnprintf( t, 256, _T("Constant/pointed") ); break;
		case PAN_MIDLINE_CONSTANT_SERIFED	: camSnprintf( t, 256, _T("Constant/serifed") ); break;
		case PAN_MIDLINE_LOW_TRIMMED		: camSnprintf( t, 256, _T("Low/trimmed") ); break;
		case PAN_MIDLINE_LOW_POINTED		: camSnprintf( t, 256, _T("Low/pointed") ); break;
		case PAN_MIDLINE_LOW_SERIFED		: camSnprintf( t, 256, _T("Low/serifed") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("Midline\t\t= (%d) %s\r\n") , mMidline, t);
	(*pStr) += s;

	switch (mXHeight)
	{
		case PAN_ANY						: camSnprintf( t, 256, _T("Any") ); break;
		case PAN_NO_FIT						: camSnprintf( t, 256, _T("No fit") ); break;
		case PAN_XHEIGHT_CONSTANT_SMALL		: camSnprintf( t, 256, _T("Constant/small") ); break;
		case PAN_XHEIGHT_CONSTANT_STD		: camSnprintf( t, 256, _T("Constant/standard") ); break;
		case PAN_XHEIGHT_CONSTANT_LARGE		: camSnprintf( t, 256, _T("Constant/large") ); break;
		case PAN_XHEIGHT_DUCKING_SMALL		: camSnprintf( t, 256, _T("Ducking/small") ); break;
		case PAN_XHEIGHT_DUCKING_STD		: camSnprintf( t, 256, _T("Ducking/standard") ); break;
		case PAN_XHEIGHT_DUCKING_LARGE		: camSnprintf( t, 256, _T("Ducking/large") ); break;
		default 							: camSnprintf( t, 256, _T("!! Unknown !! (tell Andy)") ); break;
	}

	camSnprintf( s, 256, _T("XHeight\t\t= (%d) %s\r\n") , mXHeight, t);
	(*pStr) += s;
}