summaryrefslogtreecommitdiff
path: root/utils/xbox/FontMaker
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/xbox/FontMaker
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/xbox/FontMaker')
-rw-r--r--utils/xbox/FontMaker/fontmaker.cpp1119
-rw-r--r--utils/xbox/FontMaker/fontmaker.docbin0 -> 5120 bytes
-rw-r--r--utils/xbox/FontMaker/fontmaker.h145
-rw-r--r--utils/xbox/FontMaker/fontmaker.icobin0 -> 1078 bytes
-rw-r--r--utils/xbox/FontMaker/fontmaker.rc314
-rw-r--r--utils/xbox/FontMaker/fontmaker.vpc68
-rw-r--r--utils/xbox/FontMaker/fontmakerwnd.cpp396
-rw-r--r--utils/xbox/FontMaker/glyphs.cpp1484
-rw-r--r--utils/xbox/FontMaker/glyphs.h104
-rw-r--r--utils/xbox/FontMaker/resource.h80
-rw-r--r--utils/xbox/FontMaker/stdafx.cpp8
-rw-r--r--utils/xbox/FontMaker/stdafx.h27
12 files changed, 3745 insertions, 0 deletions
diff --git a/utils/xbox/FontMaker/fontmaker.cpp b/utils/xbox/FontMaker/fontmaker.cpp
new file mode 100644
index 0000000..a2552af
--- /dev/null
+++ b/utils/xbox/FontMaker/fontmaker.cpp
@@ -0,0 +1,1119 @@
+//-----------------------------------------------------------------------------
+// Name: FontMaker.cpp
+//
+// Desc: Defines the class behaviors for the application.
+//
+// Hist: 09.06.02 - Revised Fontmaker sample
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+#include "FontMaker.h"
+#include "Glyphs.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+CTextureFont g_Font;
+extern BOOL g_bIsGlyphSelected;
+extern int g_iSelectedGlyphNum;
+extern GLYPH_ATTR* g_pSelectedGylph;
+extern WCHAR g_cSelectedGlyph;
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// CFontMakerApp
+//-----------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP(CFontMakerApp, CWinApp)
+ //{{AFX_MSG_MAP(CFontMakerApp)
+ ON_COMMAND(IDM_FILE_NEWFONT, OnNewFontButton)
+ ON_BN_CLICKED(IDC_EFFECTSOUTLINED_CHECK, OnEffectsCheck)
+ ON_BN_CLICKED(IDC_EFFECTSSHADOWED_CHECK, OnEffectsCheck)
+ ON_BN_CLICKED(IDC_EFFECTSBLURRED_CHECK, OnEffectsCheck)
+ ON_BN_CLICKED(IDC_EFFECTSSCANLINES_CHECK, OnEffectsCheck)
+ ON_BN_CLICKED(IDC_EFFECTSANTIALIAS_CHECK, OnEffectsCheck)
+ ON_BN_CLICKED(IDC_GLYPHSFROMRANGE_RADIO, OnGlyphsFromRangeRadio)
+ ON_EN_CHANGE(IDC_GLYPHSRANGEFROM_EDIT, OnChangeGlpyhsRangeEdit)
+ ON_BN_CLICKED(IDC_GLYPHSFROMFILE_RADIO, OnGlyphsFromFileRadio)
+ ON_EN_KILLFOCUS(IDC_GLYPHSFILE_EDIT, OnChangeGlyphsFileEdit)
+ ON_BN_CLICKED(IDC_GLYPHSFILESELECTOR_BUTTON, OnGlyphsFileSelectorButton)
+ ON_BN_CLICKED(IDC_GLYPHSCUSTOM_RADIO, OnGlyphsCustom)
+ ON_BN_CLICKED(IDC_TEXTURESIZE_BUTTON, OnTextureSizeButton)
+ ON_BN_CLICKED(IDC_MAGNIFY_BUTTON, OnMagnifyButton)
+ ON_BN_CLICKED(IDC_GLYPH_SPECIAL, OnGlyphSpecial)
+ ON_UPDATE_COMMAND_UI(IDC_MAGNIFY_BUTTON, OnUpdateButton)
+ ON_COMMAND(IDM_FILE_LOADFONTFILE, OnLoadButton)
+ ON_COMMAND(IDM_FILE_SAVEFONTFILES, OnSaveButton)
+ ON_COMMAND(IDM_FILE_LOADFONTLAYOUT, OnLoadCustomFontButton)
+ ON_COMMAND(IDM_FILE_EXIT, OnExit)
+ ON_COMMAND(ID_APP_ABOUT, OnAbout)
+ ON_COMMAND(ID_HELP, OnHelp)
+ ON_EN_CHANGE(IDC_GLYPHSRANGETO_EDIT, OnChangeGlpyhsRangeEdit)
+ ON_UPDATE_COMMAND_UI(IDC_TEXTURESIZE_BUTTON, OnUpdateButton)
+ ON_UPDATE_COMMAND_UI(IDC_GLYPHSFILESELECTOR_BUTTON, OnUpdateButton)
+ ON_UPDATE_COMMAND_UI(IDM_FILE_NEWFONT, OnUpdateButton)
+ ON_UPDATE_COMMAND_UI(IDM_FILE_LOADFONTFILE, OnUpdateButton)
+ ON_UPDATE_COMMAND_UI(IDM_FILE_LOADFONTLAYOUT, OnUpdateButton)
+ ON_UPDATE_COMMAND_UI(IDM_FILE_SAVEFONTFILES, OnUpdateButton)
+ ON_UPDATE_COMMAND_UI(IDM_FILE_EXIT, OnUpdateButton)
+ ON_UPDATE_COMMAND_UI(ID_APP_ABOUT, OnUpdateButton)
+ ON_UPDATE_COMMAND_UI(ID_HELP, OnUpdateButton)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+
+
+//-----------------------------------------------------------------------------
+// The one and only CFontMakerApp object
+//-----------------------------------------------------------------------------
+CFontMakerApp theApp;
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: InitInstance()
+// Desc: App initialization
+//-----------------------------------------------------------------------------
+BOOL CFontMakerApp::InitInstance()
+{
+ // Create the main frame window for the app
+ CFontMakerFrameWnd* pFrameWnd = new CFontMakerFrameWnd;
+ m_pMainWnd = pFrameWnd;
+
+ // Associate the view with the frame
+ CCreateContext context;
+ context.m_pCurrentFrame = NULL;
+ context.m_pCurrentDoc = NULL;
+ context.m_pNewViewClass = RUNTIME_CLASS(CFontMakerView);
+ context.m_pNewDocTemplate = NULL;
+
+ // Create the frame and load resources (menu, accelerator, etc.)
+ pFrameWnd->LoadFrame( IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
+ NULL, &context );
+
+ // Call OnInitialUpdate() to be called for the view
+ pFrameWnd->InitialUpdateFrame( NULL, TRUE );
+
+ // The one and only window has been initialized, so show and update it.
+ m_pMainWnd->ShowWindow( SW_SHOW );
+ m_pMainWnd->UpdateWindow();
+
+ // Load the hourglass cursor
+ m_hWaitCursor = LoadCursor( IDC_WAIT );
+
+ // Get access the the dialog controls and the view
+ m_pDialogBar = pFrameWnd->GetDialogBar();
+ m_pView = (CFontMakerView*)pFrameWnd->GetActiveView();
+
+ // Initially, no font is selected
+ m_pDialogBar->GetDlgItem( IDC_FONTNAME_STATIC )->SetWindowText( _T("<Choose font>") );
+ m_pDialogBar->GetDlgItem( IDC_FONTSTYLE_STATIC )->SetWindowText( _T("") );
+ m_pDialogBar->GetDlgItem( IDC_FONTSIZE_STATIC )->SetWindowText( _T("") );
+
+ return TRUE;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnUpdateButton()
+// Desc: This function is needed to override some internal mucking with button
+// states. Without it, button and menu enabling will make you crazy.
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnUpdateButton( CCmdUI* pCmdUI )
+{
+ BOOL bEnable;
+
+ switch( pCmdUI->m_nID )
+ {
+ // Controls which are active all the time
+ case IDM_FILE_NEWFONT:
+ case IDM_FILE_LOADFONTLAYOUT:
+ case IDM_FILE_LOADFONTFILE:
+ case IDM_FILE_EXIT:
+ case ID_APP_ABOUT:
+ case ID_HELP:
+ bEnable = TRUE;
+ break;
+
+ case IDC_TEXTURESIZE_BUTTON:
+ case IDM_FILE_SAVEFONTFILES:
+ case IDC_MAGNIFY_BUTTON:
+ bEnable = g_Font.m_hFont ? TRUE : FALSE;
+ if ( !bEnable )
+ bEnable = g_Font.m_pCustomFilename ? TRUE : FALSE;
+ break;
+
+ // Controls which are active only when a font is available
+ default:
+ bEnable = g_Font.m_hFont ? TRUE : FALSE;
+ break;
+ }
+
+ pCmdUI->Enable( bEnable );
+}
+
+BOOL g_bFirstTime = TRUE;
+
+//-----------------------------------------------------------------------------
+// Name: OnNewFontButton()
+// Desc: Called when the user hits the "New Font" button, this loads the font
+// and enables all the other windows controls.
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnNewFontButton()
+{
+ // Initialize the LOGFONT structure. It's static so it's state is remembered
+ if ( g_Font.m_LogFont.lfHeight == 0 )
+ {
+ // first time init
+ strcpy( g_Font.m_LogFont.lfFaceName, "Arial" ); // Arial font for a default
+ g_Font.m_LogFont.lfHeight = 16; // 16 height font for a default
+ g_Font.m_LogFont.lfWeight = 400; // 400 = normal, 700 = bold, etc.
+ g_Font.m_LogFont.lfItalic = 0; // 0 = normal, 255 = italic
+ g_Font.m_LogFont.lfQuality = ANTIALIASED_QUALITY;
+ }
+
+ // convert to point size for dialog purposes
+ HDC hDC = GetDC( m_pMainWnd->m_hWnd );
+ // Current point size unit=1/10 pts
+ INT iPointSize = g_Font.m_LogFont.lfHeight * 10;
+ g_Font.m_LogFont.lfHeight= -MulDiv( iPointSize, GetDeviceCaps( hDC, LOGPIXELSY ), 720 );
+ ReleaseDC( m_pMainWnd->m_hWnd, hDC );
+
+ // Create the CHOOSEFONT structure
+ static CHOOSEFONT cf = {0};
+ cf.lStructSize = sizeof(CHOOSEFONT);
+ cf.lpLogFont = &g_Font.m_LogFont;
+ cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
+ cf.nFontType = SCREEN_FONTTYPE;
+
+ if ( 0 == ChooseFont( &cf ) )
+ return;
+
+ g_Font.m_pCustomFilename = NULL;
+
+ // NOT using point sizes, but cell heights
+ g_Font.m_LogFont.lfHeight = cf.iPointSize/10;
+
+ // Reset the selected glpyh
+ UpdateSelectedGlyph( FALSE );
+
+ if( FAILED( CalculateAndRenderGlyphs() ) )
+ {
+ // Could not create new font
+ MessageBox( m_pMainWnd->m_hWnd, "Could not create the requested font!", "Error", MB_ICONERROR|MB_OK );
+ return;
+ }
+
+ char tempName[256];
+ sprintf( tempName, "%s_%d", g_Font.m_LogFont.lfFaceName, cf.iPointSize/10 );
+
+ // remove any spaces in the font name
+ for (unsigned int i=0,j=0; i<strlen( tempName )+1; i++)
+ {
+ if ( tempName[i] != ' ' )
+ {
+ g_Font.m_strFontName[j++] = tempName[i];
+ }
+ }
+
+ if ( g_bFirstTime )
+ {
+ CString str;
+
+ // Set font properties
+ m_pDialogBar->GetDlgItem( IDC_FONT_GROUPBOX )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTNAME_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTSTYLE_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTSIZE_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTNAME_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTSTYLE_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTSIZE_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSOUTLINED_CHECK )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSSHADOWED_CHECK )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSBLURRED_CHECK )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSSCANLINES_CHECK )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSANTIALIAS_CHECK )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_BLUR_EDIT )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_SCANLINES_EDIT )->EnableWindow( TRUE );
+
+ if ( g_Font.m_bAntialiasEffect )
+ {
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSANTIALIAS_CHECK ))->SetCheck( TRUE );
+ }
+ else
+ {
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSANTIALIAS_CHECK ))->SetCheck( FALSE );
+ }
+
+ str.Format( "%d", g_Font.m_nBlur );
+ m_pDialogBar->GetDlgItem( IDC_BLUR_EDIT )->SetWindowText( str );
+
+ str.Format( "%d", g_Font.m_nScanlines );
+ m_pDialogBar->GetDlgItem( IDC_SCANLINES_EDIT )->SetWindowText( str );
+
+ str.Format( "%s", g_Font.m_LogFont.lfFaceName );
+ m_pDialogBar->GetDlgItem( IDC_FONTNAME_STATIC )->SetWindowText( str );
+ if( g_Font.m_LogFont.lfItalic )
+ str.Format( "Italic", g_Font.m_LogFont.lfWeight < 550 ? "" : "Bold " );
+ else
+ str.Format( "%s", g_Font.m_LogFont.lfWeight < 550 ? "Regular" : "Bold" );
+ m_pDialogBar->GetDlgItem( IDC_FONTSTYLE_STATIC )->SetWindowText( str );
+ str.Format( "%ld", cf.iPointSize/10 );
+ m_pDialogBar->GetDlgItem( IDC_FONTSIZE_STATIC )->SetWindowText( str );
+
+ // Set texture properties
+ m_pDialogBar->GetDlgItem( IDC_TEXTURE_GROUPBOX )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREWIDTH_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREHEIGHT_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREWIDTH_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREHEIGHT_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTURESIZE_BUTTON )->EnableWindow( TRUE );
+
+ SetTextureSize( g_Font.m_dwTextureWidth, g_Font.m_dwTextureHeight );
+
+ // Set glyph range properties
+ m_pDialogBar->GetDlgItem( IDC_GLYPHS_GROUPBOX )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMRANGE_RADIO )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMFILE_RADIO )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_EDIT )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_EDIT )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILE_EDIT )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILESELECTOR_BUTTON )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSCUSTOM_RADIO )->EnableWindow( TRUE );
+
+ // Set a default range of glyphs to use
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMRANGE_RADIO ))->SetCheck( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_EDIT )->SetWindowText( "32" );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_EDIT )->SetWindowText( "127" );
+ g_Font.ExtractValidGlyphsFromRange( 32, 127 );
+
+ m_pDialogBar->GetDlgItem( IDC_INSERTGLYPH_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_INSERTGLYPH_EDIT )->EnableWindow( TRUE );
+ }
+ else
+ {
+ CString str;
+
+ str.Format( "%s", g_Font.m_LogFont.lfFaceName );
+ m_pDialogBar->GetDlgItem( IDC_FONTNAME_STATIC )->SetWindowText( str );
+ if ( g_Font.m_LogFont.lfItalic )
+ str.Format( "Italic", g_Font.m_LogFont.lfWeight < 550 ? "" : "Bold " );
+ else
+ str.Format( "%s", g_Font.m_LogFont.lfWeight < 550 ? "Regular" : "Bold" );
+ m_pDialogBar->GetDlgItem( IDC_FONTSTYLE_STATIC )->SetWindowText( str );
+ str.Format( "%ld", cf.iPointSize/10 );
+ m_pDialogBar->GetDlgItem( IDC_FONTSIZE_STATIC )->SetWindowText( str );
+ }
+
+ g_bFirstTime = FALSE;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnGlyphsFromRangeRadio()
+// Desc: User will be specifying a glyph range manually
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnGlyphsFromRangeRadio()
+{
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_EDIT )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_EDIT )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILE_EDIT )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILESELECTOR_BUTTON )->EnableWindow( FALSE );
+
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMFILE_RADIO ))->SetCheck( false );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMRANGE_RADIO ))->SetCheck( true );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSCUSTOM_RADIO ))->SetCheck( false );
+
+ OnChangeGlpyhsRangeEdit();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnChangeGlpyhsRangeEdit()
+// Desc: User changed the range of glpyhs
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnChangeGlpyhsRangeEdit()
+{
+ if( NULL == g_Font.m_hFont )
+ return;
+
+ CEdit* pGlyphRangeFromEdit = (CEdit*)m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_EDIT );
+ CEdit* pGlyphRangeToEdit = (CEdit*)m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_EDIT );
+
+ CString strFrom;
+ CString strTo;
+ pGlyphRangeFromEdit->GetWindowText( strFrom );
+ pGlyphRangeToEdit->GetWindowText( strTo );
+
+ WORD wFrom = (WORD)max( 0, atoi( strFrom ) );
+ WORD wTo = (WORD)min( 65535, atoi( strTo ) );
+ g_Font.ExtractValidGlyphsFromRange( wFrom, wTo );
+
+ // Draw the new font glyphs
+ CalculateAndRenderGlyphs();
+}
+
+
+void CFontMakerApp::OnGlyphsCustom()
+{
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMFILE_RADIO ))->SetCheck( false );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMRANGE_RADIO ))->SetCheck( false );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSCUSTOM_RADIO ))->SetCheck( true );
+}
+
+
+//-----------------------------------------------------------------------------
+// Name: OnGlyphsFromFileRadio()
+// Desc: User want to extract glyphs that are used in a text file
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnGlyphsFromFileRadio()
+{
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_LABEL )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_LABEL )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_EDIT )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_EDIT )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILE_EDIT )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILESELECTOR_BUTTON )->EnableWindow( TRUE );
+
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMFILE_RADIO ))->SetCheck( true );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMRANGE_RADIO ))->SetCheck( false );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSCUSTOM_RADIO ))->SetCheck( false );
+
+ OnChangeGlyphsFileEdit();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnChangeGlyphsFileEdit()
+// Desc: Handle change in name of file to extract glyphs from
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnChangeGlyphsFileEdit()
+{
+ CEdit* pGlyphFileNameEdit = (CEdit*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFILE_EDIT );
+
+ CString strFileName;
+ pGlyphFileNameEdit->GetWindowText( strFileName );
+
+ if( strFileName.IsEmpty() )
+ return;
+
+ g_Font.ExtractValidGlyphsFromFile( (const TCHAR*)strFileName );
+
+ // Draw the new font glyphs
+ CalculateAndRenderGlyphs();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnGlyphsFileSelectorButton()
+// Desc: Handle change in name of file to extract glyphs from
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnGlyphsFileSelectorButton()
+{
+ static TCHAR strFileName[MAX_PATH] = _T("");
+ static TCHAR strFileName2[MAX_PATH] = _T("");
+ static TCHAR strInitialDir[MAX_PATH] = _T("c:\\");
+
+ // Display the OpenFileName dialog. Then, try to load the specified file
+ OPENFILENAME ofn = { sizeof(OPENFILENAME), NULL, NULL,
+ _T("Text files (.txt)\0*.txt\0\0"),
+ NULL, 0, 1, strFileName, MAX_PATH, strFileName2, MAX_PATH,
+ strInitialDir, _T("Open Text File"),
+ OFN_FILEMUSTEXIST, 0, 1, NULL, 0, NULL, NULL };
+
+ if( TRUE == GetOpenFileName( &ofn ) )
+ {
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILE_EDIT )->SetWindowText( ofn.lpstrFile);
+ OnChangeGlyphsFileEdit();
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnEffectsCheck()
+// Desc: User changed font rendering options
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnEffectsCheck()
+{
+ g_Font.m_bOutlineEffect = ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSOUTLINED_CHECK ))->GetCheck();
+ g_Font.m_bShadowEffect = ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSSHADOWED_CHECK ))->GetCheck();
+ g_Font.m_bAntialiasEffect = ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSANTIALIAS_CHECK ))->GetCheck();
+
+ bool bValveEffects = false;
+ if ( g_Font.m_bOutlineEffect || g_Font.m_bShadowEffect )
+ {
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSBLURRED_CHECK )->EnableWindow( false );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSSCANLINES_CHECK )->EnableWindow( false );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSBLURRED_CHECK ))->SetCheck( false );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSSCANLINES_CHECK ))->SetCheck( false );
+ }
+ else
+ {
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSBLURRED_CHECK )->EnableWindow( true );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSSCANLINES_CHECK )->EnableWindow( true );
+ bValveEffects = true;
+ }
+
+ if ( bValveEffects && ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSBLURRED_CHECK ))->GetCheck() )
+ {
+ CEdit* pBlurEdit = (CEdit*)m_pDialogBar->GetDlgItem( IDC_BLUR_EDIT );
+
+ CString strBlur;
+ pBlurEdit->GetWindowText( strBlur );
+
+ g_Font.m_nBlur = max( 2, atoi( strBlur ) );
+
+ strBlur.Format( "%d", g_Font.m_nBlur );
+ pBlurEdit->SetWindowText( strBlur );
+ }
+ else
+ {
+ g_Font.m_nBlur = 0;
+ }
+
+ if ( bValveEffects && ((CButton*)m_pDialogBar->GetDlgItem( IDC_EFFECTSSCANLINES_CHECK ))->GetCheck() )
+ {
+ CEdit* pScanlineEdit = (CEdit*)m_pDialogBar->GetDlgItem( IDC_SCANLINES_EDIT );
+
+ CString strScanlines;
+ pScanlineEdit->GetWindowText( strScanlines );
+
+ g_Font.m_nScanlines = max( 2, atoi( strScanlines ) );
+
+ strScanlines.Format( "%d", g_Font.m_nScanlines );
+ pScanlineEdit->SetWindowText( strScanlines );
+ }
+ else
+ {
+ g_Font.m_nScanlines = 0;
+ }
+
+ // Draw the new font glyphs
+ CalculateAndRenderGlyphs();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnMagnifyButton()
+// Desc: User wants to run the Windows "magnify" tool
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnMagnifyButton()
+{
+ // Run the Windows "magnify" tool
+ WinExec( "magnify.exe", TRUE );
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: class CTextureSizeDlg
+// Desc: Simple dialog to change the font texture size
+//-----------------------------------------------------------------------------
+class CTextureSizeDlg : public CDialog
+{
+public:
+ CTextureSizeDlg();
+
+// Dialog Data
+ //{{AFX_DATA(CTextureSizeDlg)
+ enum { IDD = IDD_TEXTURESIZE };
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CTextureSizeDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ //{{AFX_MSG(CTextureSizeDlg)
+ // No message handlers
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+CTextureSizeDlg::CTextureSizeDlg() : CDialog(CTextureSizeDlg::IDD)
+{
+ //{{AFX_DATA_INIT(CTextureSizeDlg)
+ //}}AFX_DATA_INIT
+}
+
+void CTextureSizeDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+
+ //{{AFX_DATA_MAP(CTextureSizeDlg)
+ DDX_Text( pDX, IDC_WIDTH, g_Font.m_dwTextureWidth );
+ DDV_MinMaxInt( pDX, g_Font.m_dwTextureWidth, 16, 2048 );
+
+ DDX_Text( pDX, IDC_HEIGHT, g_Font.m_dwTextureHeight );
+ DDV_MinMaxInt( pDX, g_Font.m_dwTextureHeight, 16, 2048 );
+ //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CTextureSizeDlg, CDialog)
+ //{{AFX_MSG_MAP(CTextureSizeDlg)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+void CFontMakerApp::SetTextureSize( int width, int height )
+{
+ g_Font.m_dwTextureWidth = width;
+ g_Font.m_dwTextureHeight = height;
+
+ CString str;
+ str.Format( "%ld", g_Font.m_dwTextureWidth );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREWIDTH_STATIC )->SetWindowText( str );
+ str.Format( "%ld", g_Font.m_dwTextureHeight );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREHEIGHT_STATIC )->SetWindowText( str );
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnTextureSizeButton()
+// Desc: User wants to change the font texture size
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnTextureSizeButton()
+{
+ if ( !g_Font.m_hFont && !g_Font.m_pCustomFilename )
+ return;
+
+ CTextureSizeDlg dlgTextureSize;
+ dlgTextureSize.DoModal();
+
+ SetTextureSize( g_Font.m_dwTextureWidth, g_Font.m_dwTextureHeight );
+
+ // Draw the new font glyphs
+ CalculateAndRenderGlyphs();
+}
+
+void CFontMakerApp::InsertGlyph()
+{
+ CEdit* pGlyphInsert = (CEdit*)m_pDialogBar->GetDlgItem( IDC_INSERTGLYPH_EDIT );
+
+ CString strInsert;
+ pGlyphInsert->GetWindowText( strInsert );
+
+ WORD wGlyph = atoi( strInsert );
+ if ( wGlyph < 0 )
+ wGlyph = 0;
+ else if ( wGlyph > 65535 )
+ wGlyph = 65535;
+
+ g_Font.InsertGlyph( wGlyph );
+}
+
+//-----------------------------------------------------------------------------
+// Name: UpdateSelectedGlyph()
+// Desc: User changed (via mouse or keyboard) which glyph is selected
+//-----------------------------------------------------------------------------
+void CFontMakerApp::UpdateSelectedGlyph( BOOL bGlyphSelected, int iSelectedGlyph )
+{
+ // Handle case where no glyph is selected
+ g_bIsGlyphSelected = FALSE;
+ g_iSelectedGlyphNum = 0;
+ g_pSelectedGylph = NULL;
+ g_cSelectedGlyph = L'\0';
+
+ if ( bGlyphSelected )
+ {
+ for ( DWORD i=0; i<=g_Font.m_cMaxGlyph; i++ )
+ {
+ if ( g_Font.m_TranslatorTable[i] == iSelectedGlyph )
+ {
+ g_bIsGlyphSelected = TRUE;
+ g_iSelectedGlyphNum = iSelectedGlyph;
+ g_pSelectedGylph = &g_Font.m_pGlyphs[iSelectedGlyph];
+ g_cSelectedGlyph = (WCHAR)i;
+ break;
+ }
+ }
+ }
+
+ // Enable/disable/set-text-of the appropriate controls
+ if ( g_bIsGlyphSelected )
+ {
+ CString str;
+ str.Format( "%d", g_cSelectedGlyph ); m_pDialogBar->GetDlgItem( IDC_GLYPH_VALUE_STATIC )->SetWindowText( str );
+ str.Format( "%d", g_pSelectedGylph->x ); m_pDialogBar->GetDlgItem( IDC_GLYPH_X_STATIC )->SetWindowText( str );
+ str.Format( "%d", g_pSelectedGylph->y ); m_pDialogBar->GetDlgItem( IDC_GLYPH_Y_STATIC )->SetWindowText( str );
+ str.Format( "%d", g_pSelectedGylph->w ); m_pDialogBar->GetDlgItem( IDC_GLYPH_W_STATIC )->SetWindowText( str );
+ str.Format( "%d", g_pSelectedGylph->h ); m_pDialogBar->GetDlgItem( IDC_GLYPH_H_STATIC )->SetWindowText( str );
+ str.Format( "%d", g_pSelectedGylph->a ); m_pDialogBar->GetDlgItem( IDC_GLYPH_A_STATIC )->SetWindowText( str );
+ str.Format( "%d", g_pSelectedGylph->b ); m_pDialogBar->GetDlgItem( IDC_GLYPH_B_STATIC )->SetWindowText( str );
+ str.Format( "%d", g_pSelectedGylph->c ); m_pDialogBar->GetDlgItem( IDC_GLYPH_C_STATIC )->SetWindowText( str );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPH_SPECIAL ))->SetCheck( g_Font.m_ValidGlyphs[g_cSelectedGlyph] == 2 );
+ }
+ else
+ {
+ CString str("");
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_VALUE_STATIC )->SetWindowText( str );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_X_STATIC )->SetWindowText( str );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_Y_STATIC )->SetWindowText( str );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_W_STATIC )->SetWindowText( str );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_H_STATIC )->SetWindowText( str );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_A_STATIC )->SetWindowText( str );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_B_STATIC )->SetWindowText( str );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_C_STATIC )->SetWindowText( str );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPH_SPECIAL ))->SetCheck( FALSE );
+ }
+
+ m_pDialogBar->GetDlgItem( IDC_SELECTEDGLYPH_GROUPBOX )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_VALUE_LABEL )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_X_LABEL )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_Y_LABEL )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_W_LABEL )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_H_LABEL )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_A_LABEL )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_B_LABEL )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_C_LABEL )->EnableWindow( g_bIsGlyphSelected );
+
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_VALUE_STATIC )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_X_STATIC )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_Y_STATIC )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_W_STATIC )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_H_STATIC )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_A_STATIC )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_B_STATIC )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_C_STATIC )->EnableWindow( g_bIsGlyphSelected );
+ m_pDialogBar->GetDlgItem( IDC_GLYPH_SPECIAL )->EnableWindow( g_bIsGlyphSelected );
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnGlyphSpecial()
+// Desc: User changed the status of the selected glyph
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnGlyphSpecial()
+{
+ if( g_bIsGlyphSelected )
+ {
+ if( ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPH_SPECIAL ))->GetCheck() )
+ g_Font.m_ValidGlyphs[g_cSelectedGlyph] = 2;
+ else
+ g_Font.m_ValidGlyphs[g_cSelectedGlyph] = 1;
+
+ // Draw the font glyphs, which may have changed layout
+ CalculateAndRenderGlyphs();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnLoadButton()
+// Desc: User wants to load a font file
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnLoadButton()
+{
+ CHAR strVBFFileName[MAX_PATH];
+ sprintf( strVBFFileName, "%s.vbf", g_Font.m_strFontName );
+
+ OPENFILENAME ofnVBF; // common dialog box structure
+ ZeroMemory( &ofnVBF, sizeof(OPENFILENAME) );
+ ofnVBF.lStructSize = sizeof(OPENFILENAME);
+ ofnVBF.hwndOwner = m_pMainWnd->m_hWnd;
+ ofnVBF.lpstrFilter = "Font files (*.vbf)\0*.vbf\0\0";
+ ofnVBF.nFilterIndex = 1;
+ ofnVBF.lpstrFile = strVBFFileName;
+ ofnVBF.nMaxFile = sizeof(strVBFFileName);
+ ofnVBF.lpstrFileTitle = NULL;
+ ofnVBF.nMaxFileTitle = 0;
+ ofnVBF.lpstrInitialDir = NULL;
+ ofnVBF.lpstrTitle = "Load Font (VBF) File...";
+ ofnVBF.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_READONLY;
+
+ // Display the Load dialog box for the VBF file
+ if ( FALSE == GetOpenFileName( &ofnVBF ) )
+ return;
+
+ if ( FAILED( g_Font.ReadFontInfoFile( strVBFFileName ) ) )
+ {
+ m_pMainWnd->MessageBox( "Could not load the Valve bitmap font info file.",
+ "Error", MB_ICONERROR|MB_OK );
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// OnLoadCustomFontButton
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnLoadCustomFontButton()
+{
+ CHAR strVCFFileName[MAX_PATH];
+ strVCFFileName[0] = '\0';
+
+ OPENFILENAME ofnVCF; // common dialog box structure
+ ZeroMemory( &ofnVCF, sizeof(OPENFILENAME) );
+ ofnVCF.lStructSize = sizeof(OPENFILENAME);
+ ofnVCF.hwndOwner = m_pMainWnd->m_hWnd;
+ ofnVCF.lpstrFilter = "Custom Font files (*.vcf)\0*.vcf\0\0";
+ ofnVCF.nFilterIndex = 1;
+ ofnVCF.lpstrFile = strVCFFileName;
+ ofnVCF.nMaxFile = sizeof(strVCFFileName);
+ ofnVCF.lpstrFileTitle = NULL;
+ ofnVCF.nMaxFileTitle = 0;
+ ofnVCF.lpstrInitialDir = NULL;
+ ofnVCF.lpstrTitle = "Load Custom Font (VCF) File...";
+ ofnVCF.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_READONLY;
+
+ // Display the Load dialog box for the VBF file
+ if ( FALSE == GetOpenFileName( &ofnVCF ) )
+ return;
+
+ if ( FAILED( g_Font.ReadCustomFontFile( strVCFFileName ) ) )
+ {
+ m_pMainWnd->MessageBox( "Could not load the Valve bitmap custom font file.",
+ "Error", MB_ICONERROR|MB_OK );
+ return;
+ }
+
+ // Reset the selected glpyh
+ UpdateSelectedGlyph( FALSE );
+
+ if ( FAILED( CalculateAndRenderGlyphs() ) )
+ {
+ // Could not create new font
+ MessageBox( m_pMainWnd->m_hWnd, "Could not create the requested font!", "Error", MB_ICONERROR|MB_OK );
+ return;
+ }
+
+ m_pDialogBar->GetDlgItem( IDC_FONT_GROUPBOX )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_FONTNAME_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTSTYLE_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTSIZE_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTNAME_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_FONTSTYLE_STATIC )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_FONTSIZE_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSOUTLINED_CHECK )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSSHADOWED_CHECK )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSBLURRED_CHECK )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSSCANLINES_CHECK )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_EFFECTSANTIALIAS_CHECK )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_BLUR_EDIT )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_SCANLINES_EDIT )->EnableWindow( FALSE );
+
+ CString str;
+ str.Format( "%s", g_Font.m_strFontName );
+ m_pDialogBar->GetDlgItem( IDC_FONTNAME_STATIC )->SetWindowText( str );
+
+ str.Format( "%d", g_Font.m_maxCustomCharHeight );
+ m_pDialogBar->GetDlgItem( IDC_FONTSIZE_STATIC )->SetWindowText( str );
+
+ // Set texture properties
+ m_pDialogBar->GetDlgItem( IDC_TEXTURE_GROUPBOX )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREWIDTH_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREHEIGHT_LABEL )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREWIDTH_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTUREHEIGHT_STATIC )->EnableWindow( TRUE );
+ m_pDialogBar->GetDlgItem( IDC_TEXTURESIZE_BUTTON )->EnableWindow( TRUE );
+
+ SetTextureSize( g_Font.m_dwTextureWidth, g_Font.m_dwTextureHeight );
+
+ // Set glyph range properties
+ m_pDialogBar->GetDlgItem( IDC_GLYPHS_GROUPBOX )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMRANGE_RADIO )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMFILE_RADIO )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_EDIT )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_EDIT )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGEFROM_LABEL )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSRANGETO_LABEL )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILE_EDIT )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSFILESELECTOR_BUTTON )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_GLYPHSCUSTOM_RADIO )->EnableWindow( TRUE );
+
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMRANGE_RADIO ))->SetCheck( FALSE );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSFROMFILE_RADIO ))->SetCheck( FALSE );
+ ((CButton*)m_pDialogBar->GetDlgItem( IDC_GLYPHSCUSTOM_RADIO ))->SetCheck( TRUE );
+
+ m_pDialogBar->GetDlgItem( IDC_INSERTGLYPH_LABEL )->EnableWindow( FALSE );
+ m_pDialogBar->GetDlgItem( IDC_INSERTGLYPH_EDIT )->EnableWindow( FALSE );
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnSaveButton()
+// Desc: User wants to save the font files
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnSaveButton()
+{
+ CHAR strTGAFileName[MAX_PATH];
+ CHAR strVBFFileName[MAX_PATH];
+
+ if ( !g_Font.m_hFont && !g_Font.m_pCustomFilename )
+ return;
+
+ sprintf( strTGAFileName, "%s.tga", g_Font.m_strFontName );
+
+ OPENFILENAME ofnTGA; // common dialog box structure
+ ZeroMemory( &ofnTGA, sizeof(OPENFILENAME) );
+ ofnTGA.lStructSize = sizeof(OPENFILENAME);
+ ofnTGA.hwndOwner = m_pMainWnd->m_hWnd;
+ ofnTGA.lpstrFilter = "Targa files (*.tga)\0*.tga\0\0";
+ ofnTGA.nFilterIndex = 1;
+ ofnTGA.lpstrFile = strTGAFileName;
+ ofnTGA.nMaxFile = sizeof(strTGAFileName);
+ ofnTGA.lpstrFileTitle = NULL;
+ ofnTGA.nMaxFileTitle = 0;
+ ofnTGA.lpstrInitialDir = NULL;
+ ofnTGA.lpstrTitle = "Save Font Texture Image (TGA) File...";
+ ofnTGA.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_EXPLORER;
+
+ // Display the Save As dialog box for the TGA file
+ if ( FALSE == GetSaveFileName( &ofnTGA ) )
+ return;
+
+ // use the tga name, but replace the extension
+ CHAR *ptr;
+ CHAR temp[MAX_PATH];
+ int len;
+ strcpy( temp, strTGAFileName );
+ len = strlen( temp );
+ if ( len > 4 && temp[len-4] == '.' )
+ {
+ temp[len-3] = 'v';
+ temp[len-2] = 'b';
+ temp[len-1] = 'f';
+
+ // strip the path
+ ptr = strrchr( temp, '\\' );
+ if ( ptr )
+ {
+ strcpy( strVBFFileName, ptr+1 );
+ }
+ else
+ {
+ strcpy( strVBFFileName, temp );
+ }
+ }
+ else
+ {
+ sprintf( strVBFFileName, "%s.vbf", g_Font.m_strFontName );
+ }
+
+ // place the VBF files in the materials directory
+ CHAR materialsDir[MAX_PATH];
+ strcpy( materialsDir, strTGAFileName );
+ strlwr( materialsDir );
+ ptr = strstr( materialsDir, "\\content\\hl2x\\materialsrc\\" );
+ if ( ptr )
+ {
+ // need the final dirs, skip past
+ CHAR *ptr2 = ptr + strlen( "\\content\\hl2x\\materialsrc\\" );
+ strcpy( temp, ptr2 );
+
+ *ptr = '\0';
+ strcat( materialsDir, "\\game\\hl2x\\materials\\" );
+ strcat( materialsDir, temp );
+
+ // strip terminal filename
+ ptr = materialsDir + strlen( materialsDir ) - 1;
+ while ( ptr > materialsDir )
+ {
+ if ( *ptr == '\\' )
+ {
+ *ptr = '\0';
+ break;
+ }
+ ptr--;
+ }
+ }
+ else
+ {
+ materialsDir[0] = '\0';
+ }
+
+ // Initialize OPENFILENAME
+ OPENFILENAME ofnVBF; // common dialog box structure
+ ZeroMemory( &ofnVBF, sizeof(OPENFILENAME) );
+ ofnVBF.lStructSize = sizeof(OPENFILENAME);
+ ofnVBF.hwndOwner = m_pMainWnd->m_hWnd;
+ ofnVBF.lpstrFilter = "Font files (*.vbf)\0*.vbf\0\0";
+ ofnVBF.nFilterIndex = 1;
+ ofnVBF.lpstrFile = strVBFFileName;
+ ofnVBF.nMaxFile = sizeof(strVBFFileName);
+ ofnVBF.lpstrFileTitle = NULL;
+ ofnVBF.nMaxFileTitle = 0;
+ ofnVBF.lpstrInitialDir = materialsDir[0] ? materialsDir : NULL;
+ ofnVBF.lpstrTitle = "Save Valve Bitmap Font (VBF) File...";
+ ofnVBF.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_EXPLORER;
+
+ // Display the Save As dialog box for the ABC file
+ if ( FALSE == GetSaveFileName( &ofnVBF ) )
+ return;
+
+ // Make sure the names are valid
+ if ( !lstrcmp( strVBFFileName, strTGAFileName ) )
+ {
+ m_pMainWnd->MessageBox( "Cannot have VBF and TGA filenames be the same!\nFiles not saved.",
+ "Error", MB_ICONERROR|MB_OK );
+ return;
+ }
+
+ // Add an extension, if there was not one
+ if ( 0 == ofnVBF.nFileExtension )
+ lstrcat( strVBFFileName, ".vbf" );
+ if ( 0 == ofnTGA.nFileExtension )
+ lstrcat( strTGAFileName, ".tga" );
+
+ // Save the valve bitmap font info file (.vbf)
+ if ( FAILED( g_Font.WriteFontInfoFile( strVBFFileName ) ) )
+ {
+ m_pMainWnd->MessageBox( "Could not write the Valve bitmap font info file.",
+ "Error", MB_ICONERROR|MB_OK );
+ return;
+ }
+
+ // blur or scanline effects require special processing to ensure
+ // they can be used in additive mode
+ bool bAdditiveMode = ( g_Font.m_nBlur || g_Font.m_nScanlines );
+
+ // a custom font requires special processing
+ bool bCustomFont = g_Font.m_pCustomFilename != NULL;
+
+ // Save the font image file (.tga)
+ if ( FAILED( g_Font.WriteFontImageFile( strTGAFileName, bAdditiveMode, bCustomFont ) ) )
+ {
+ m_pMainWnd->MessageBox( "Could not write the font texture image file.",
+ "Error", MB_ICONERROR|MB_OK );
+ }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnAbout()
+// Desc: Display about box
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnAbout()
+{
+ CDialog dlg(IDD_ABOUT);
+ dlg.DoModal();
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnHelp()
+// Desc: Display app help
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnHelp()
+{
+ HKEY hRegKey;
+
+ if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ _T("SOFTWARE\\Microsoft\\XboxSDK"),
+ 0, KEY_QUERY_VALUE, &hRegKey ) )
+ {
+ DWORD dwSize = MAX_PATH;
+ CHAR InstallPath[MAX_PATH];
+
+ if( ERROR_SUCCESS == RegQueryValueEx( hRegKey, _T("InstallPath"), NULL,
+ NULL, (unsigned char *)InstallPath, &dwSize ) )
+ {
+ CString path = InstallPath;
+ path += _T("\\doc\\xboxsdk.chm::/xbox_jbh_tool_fontmaker.htm");
+
+ ::HtmlHelp( m_pMainWnd->GetSafeHwnd(), path, HH_DISPLAY_TOPIC, NULL );
+ RegCloseKey( hRegKey );
+ return;
+ }
+ RegCloseKey( hRegKey );
+ }
+
+ MessageBox( m_pMainWnd->GetSafeHwnd(),
+ "Unable to find the Xbox SDK Help file xboxsdk.chm.",
+ "Help file error", MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL );
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: OnExit()
+// Desc: User chose to exit the app
+//-----------------------------------------------------------------------------
+void CFontMakerApp::OnExit()
+{
+ // Send a close message to the main window
+ m_pMainWnd->SendMessage( WM_CLOSE );
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: ExitInstance()
+// Desc: Do some cleanup before exitting the app
+//-----------------------------------------------------------------------------
+int CFontMakerApp::ExitInstance()
+{
+ DestroyCursor( m_hWaitCursor );
+
+ return CWinApp::ExitInstance();
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Name: CalculateAndRenderGlyphs()
+// Desc: User changed the status of the selected glyph
+//-----------------------------------------------------------------------------
+HRESULT CFontMakerApp::CalculateAndRenderGlyphs()
+{
+ HRESULT hr;
+
+ // This may take some time, so display a wait cursor
+ HCURSOR hOldCursor = GetCursor();
+ SetCursor( m_hWaitCursor );
+
+ // Draw the font glyphs, which may have changed layout
+ if( FAILED( hr = g_Font.CalculateAndRenderGlyphs() ) )
+ return hr;
+
+ // Re-select the current glyph since the font data may have changed
+ theApp.UpdateSelectedGlyph( g_bIsGlyphSelected, g_iSelectedGlyphNum );
+
+ // Inform the view of the new font glyphs
+ m_pView->OnNewFontGlyphs();
+
+ // Restore the cursor
+ SetCursor( hOldCursor );
+
+ return S_OK;
+}
+
+
+
+
diff --git a/utils/xbox/FontMaker/fontmaker.doc b/utils/xbox/FontMaker/fontmaker.doc
new file mode 100644
index 0000000..f739de0
--- /dev/null
+++ b/utils/xbox/FontMaker/fontmaker.doc
Binary files differ
diff --git a/utils/xbox/FontMaker/fontmaker.h b/utils/xbox/FontMaker/fontmaker.h
new file mode 100644
index 0000000..43526ad
--- /dev/null
+++ b/utils/xbox/FontMaker/fontmaker.h
@@ -0,0 +1,145 @@
+//-----------------------------------------------------------------------------
+// Name: FontMaker.h
+//
+// Desc: Defines the class behaviors for the application.
+//
+// Hist: 09.06.02 - Revised Fontmaker sample
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#ifndef FONTMAKER_H
+#define FONTMAKER_H
+
+#include "resource.h"
+#include "BitmapFontFile.h"
+#include <math.h>
+#include "..\toollib\toollib.h"
+#include "..\toollib\scriplib.h"
+#include "..\toollib\piclib.h"
+
+//-----------------------------------------------------------------------------
+// Name: class CFontMakerView
+// Desc: The scroll view class for viewing the font texture image
+//-----------------------------------------------------------------------------
+class CFontMakerView : public CScrollView
+{
+protected:
+ CFontMakerView() {}
+ DECLARE_DYNCREATE(CFontMakerView)
+
+ CDC m_memDC;
+
+public:
+ VOID OnNewFontGlyphs();
+
+ virtual ~CFontMakerView();
+
+public:
+
+ // Overridden functions
+ //{{AFX_VIRTUAL(CFontMakerView)
+ public:
+ virtual void OnDraw(CDC* pDC);
+ virtual void OnInitialUpdate();
+ protected:
+ //}}AFX_VIRTUAL
+
+protected:
+ // Message map functions
+ //{{AFX_MSG(CFontMakerView)
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: class CFontMakerFrameWnd
+// Desc: The main frame window class for the app, which contains the dialog bar
+// full of controls and the scroll view to view the font texture image.
+//-----------------------------------------------------------------------------
+class CFontMakerFrameWnd : public CFrameWnd
+{
+public:
+ CFontMakerFrameWnd() {}
+ virtual ~CFontMakerFrameWnd() {}
+
+ CDialogBar m_wndDialogBar;
+ CDialogBar* GetDialogBar() { return &m_wndDialogBar; }
+
+protected:
+ DECLARE_DYNCREATE(CFontMakerFrameWnd)
+
+ // Message map functions
+ //{{AFX_MSG(CFontMakerFrameWnd)
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: class CFontMakerApp
+// Desc: The main app class
+//-----------------------------------------------------------------------------
+class CFontMakerApp : public CWinApp
+{
+ CDialogBar* m_pDialogBar;
+ CFontMakerView* m_pView;
+ HCURSOR m_hWaitCursor;
+
+public:
+ CFontMakerApp() {}
+ ~CFontMakerApp() {}
+
+ VOID UpdateSelectedGlyph( BOOL bGlyphSelected, int iSelectedGlyph = 0 );
+ HRESULT CalculateAndRenderGlyphs();
+ VOID InsertGlyph();
+
+ void SetTextureSize( int width, int height );
+
+ // Overrides
+ //{{AFX_VIRTUAL(CFontMakerApp)
+ public:
+ virtual BOOL InitInstance();
+ virtual int ExitInstance();
+ //}}AFX_VIRTUAL
+
+ // Implementation
+ //{{AFX_MSG(CFontMakerApp)
+ afx_msg void OnNewFontButton();
+ afx_msg void OnEffectsCheck();
+ afx_msg void OnGlyphsFromRangeRadio();
+ afx_msg void OnChangeGlpyhsRangeEdit();
+ afx_msg void OnGlyphsFromFileRadio();
+ afx_msg void OnChangeGlyphsFileEdit();
+ afx_msg void OnGlyphsFileSelectorButton();
+ afx_msg void OnTextureSizeButton();
+ afx_msg void OnMagnifyButton();
+ afx_msg void OnGlyphSpecial();
+ afx_msg void OnUpdateButton( CCmdUI* pCmdUI );
+ afx_msg void OnSaveButton();
+ afx_msg void OnExit();
+ afx_msg void OnAbout();
+ afx_msg void OnHelp();
+ afx_msg void OnGlyphsCustom();
+ afx_msg void OnLoadButton();
+ afx_msg void OnLoadCustomFontButton();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+
+
+// External reference to the unique application instance
+extern CFontMakerApp theApp;
+
+
+
+#endif // FONTMAKER_H
diff --git a/utils/xbox/FontMaker/fontmaker.ico b/utils/xbox/FontMaker/fontmaker.ico
new file mode 100644
index 0000000..8046b8c
--- /dev/null
+++ b/utils/xbox/FontMaker/fontmaker.ico
Binary files differ
diff --git a/utils/xbox/FontMaker/fontmaker.rc b/utils/xbox/FontMaker/fontmaker.rc
new file mode 100644
index 0000000..9f95362
--- /dev/null
+++ b/utils/xbox/FontMaker/fontmaker.rc
@@ -0,0 +1,314 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "#ifdef _WIN32\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#endif //_WIN32\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "FontMaker.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOGBAR DIALOGEX 0, 0, 142, 418
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Font",IDC_FONT_GROUPBOX,5,5,130,142,WS_DISABLED
+ LTEXT "Name",IDC_FONTNAME_LABEL,10,15,24,15,SS_CENTERIMAGE |
+ WS_DISABLED
+ LTEXT "",IDC_FONTNAME_STATIC,35,15,90,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ LTEXT "Style",IDC_FONTSTYLE_LABEL,10,30,20,15,SS_CENTERIMAGE |
+ WS_DISABLED
+ LTEXT "",IDC_FONTSTYLE_STATIC,35,30,90,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ LTEXT "Size",IDC_FONTSIZE_LABEL,10,45,20,15,SS_CENTERIMAGE |
+ WS_DISABLED
+ LTEXT "",IDC_FONTSIZE_STATIC,35,45,30,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CONTROL "Outlined",IDC_EFFECTSOUTLINED_CHECK,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,10,65,42,10
+ CONTROL "Shadowed",IDC_EFFECTSSHADOWED_CHECK,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,10,80,50,10
+ PUSHBUTTON "Magnify...",IDC_MAGNIFY_BUTTON,75,70,50,14,WS_DISABLED
+ GROUPBOX "Texture properties",IDC_TEXTURE_GROUPBOX,5,149,130,40,
+ WS_DISABLED
+ LTEXT "Insert Glyph:",IDC_INSERTGLYPH_LABEL,10,375,63,10,
+ SS_CENTERIMAGE | WS_DISABLED
+ CTEXT "",IDC_TEXTUREWIDTH_STATIC,9,170,30,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CTEXT "Height",IDC_TEXTUREHEIGHT_LABEL,45,159,30,10,
+ SS_CENTERIMAGE | WS_DISABLED
+ CTEXT "",IDC_TEXTUREHEIGHT_STATIC,45,170,30,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ PUSHBUTTON "Size...",IDC_TEXTURESIZE_BUTTON,80,165,50,14,
+ WS_DISABLED
+ GROUPBOX "Glyphs",IDC_GLYPHS_GROUPBOX,5,189,130,95,WS_DISABLED
+ CONTROL "From range:",IDC_GLYPHSFROMRANGE_RADIO,"Button",
+ BS_AUTORADIOBUTTON | WS_DISABLED | WS_GROUP,10,199,53,10
+ RTEXT "From:",IDC_GLYPHSRANGEFROM_LABEL,25,215,20,15,
+ SS_CENTERIMAGE | WS_DISABLED
+ EDITTEXT IDC_GLYPHSRANGEFROM_EDIT,50,215,25,12,ES_CENTER |
+ ES_AUTOHSCROLL | WS_DISABLED
+ RTEXT "To:",IDC_GLYPHSRANGETO_LABEL,85,215,15,15,
+ SS_CENTERIMAGE | WS_DISABLED
+ EDITTEXT IDC_GLYPHSRANGETO_EDIT,105,215,25,12,ES_CENTER |
+ ES_AUTOHSCROLL | WS_DISABLED
+ CONTROL "From file:",IDC_GLYPHSFROMFILE_RADIO,"Button",
+ BS_AUTORADIOBUTTON | WS_DISABLED,10,233,44,10
+ EDITTEXT IDC_GLYPHSFILE_EDIT,23,245,90,12,ES_AUTOHSCROLL |
+ WS_DISABLED
+ PUSHBUTTON "...",IDC_GLYPHSFILESELECTOR_BUTTON,117,245,15,12,
+ WS_DISABLED
+ GROUPBOX "Selected Glyph",IDC_SELECTEDGLYPH_GROUPBOX,5,289,130,
+ 121,WS_DISABLED
+ CTEXT "Value",IDC_GLYPH_VALUE_LABEL,10,300,35,10,
+ SS_CENTERIMAGE | WS_DISABLED
+ CTEXT "",IDC_GLYPH_VALUE_STATIC,10,310,35,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CTEXT "A",IDC_GLYPH_A_LABEL,60,300,20,10,SS_CENTERIMAGE |
+ WS_DISABLED
+ CTEXT "x",IDC_GLYPH_X_LABEL,9,324,20,10,SS_CENTERIMAGE |
+ WS_DISABLED
+ CTEXT "y",IDC_GLYPH_Y_LABEL,35,324,20,10,SS_CENTERIMAGE |
+ WS_DISABLED
+ CTEXT "w",IDC_GLYPH_W_LABEL,65,324,20,10,SS_CENTERIMAGE |
+ WS_DISABLED
+ CTEXT "h",IDC_GLYPH_H_LABEL,89,324,20,10,SS_CENTERIMAGE |
+ WS_DISABLED
+ CTEXT "B",IDC_GLYPH_B_LABEL,85,300,20,10,SS_CENTERIMAGE |
+ WS_DISABLED
+ CTEXT "C",IDC_GLYPH_C_LABEL,110,300,20,10,SS_CENTERIMAGE |
+ WS_DISABLED
+ CONTROL "Reserved for custom bitmap",IDC_GLYPH_SPECIAL,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,10,356,104,10
+ CTEXT "",IDC_GLYPH_X_STATIC,10,334,20,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CTEXT "",IDC_GLYPH_Y_STATIC,35,334,20,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CTEXT "",IDC_GLYPH_W_STATIC,65,334,20,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CTEXT "",IDC_GLYPH_H_STATIC,90,334,20,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CTEXT "",IDC_GLYPH_A_STATIC,60,310,20,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CTEXT "",IDC_GLYPH_B_STATIC,85,310,20,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CTEXT "",IDC_GLYPH_C_STATIC,110,310,20,12,SS_CENTERIMAGE |
+ WS_DISABLED,WS_EX_CLIENTEDGE
+ CONTROL "Blurred",IDC_EFFECTSBLURRED_CHECK,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,10,97,50,10
+ CONTROL "ScanLines",IDC_EFFECTSSCANLINES_CHECK,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,10,114,50,10
+ EDITTEXT IDC_BLUR_EDIT,65,95,25,12,ES_CENTER | ES_AUTOHSCROLL |
+ WS_DISABLED
+ EDITTEXT IDC_SCANLINES_EDIT,65,114,25,12,ES_CENTER |
+ ES_AUTOHSCROLL | WS_DISABLED
+ CONTROL "Antialias",IDC_EFFECTSANTIALIAS_CHECK,"Button",
+ BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,10,130,50,10
+ CONTROL "Custom",IDC_GLYPHSCUSTOM_RADIO,"Button",
+ BS_AUTORADIOBUTTON | WS_DISABLED | WS_GROUP,10,265,53,10
+ EDITTEXT IDC_INSERTGLYPH_EDIT,10,387,35,12,ES_CENTER |
+ ES_AUTOHSCROLL | WS_DISABLED
+ CTEXT "Width",IDC_TEXTUREWIDTH_LABEL,9,159,30,10,
+ SS_CENTERIMAGE | WS_DISABLED
+END
+
+IDD_TEXTURESIZE DIALOG 0, 0, 167, 49
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Texture Size"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Width",IDC_STATIC,5,5,19,15,SS_CENTERIMAGE
+ EDITTEXT IDC_WIDTH,35,5,40,15,ES_AUTOHSCROLL
+ LTEXT "Height",IDC_STATIC,5,25,25,15,SS_CENTERIMAGE
+ EDITTEXT IDC_HEIGHT,35,25,40,15,ES_AUTOHSCROLL
+ DEFPUSHBUTTON "OK",IDOK,115,5,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,115,25,50,14
+END
+
+IDD_ABOUT DIALOGEX 0, 0, 262, 123
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "About FontMaker"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ ICON IDR_MAINFRAME,IDC_STATIC,5,20,21,20
+ LTEXT "Xbox Font Maker tool - Modified for Valve Software",
+ IDC_STATIC,36,10,222,8
+ LTEXT "Version 2.0.0000.1 - Valve",IDC_STATIC,36,25,222,8
+ LTEXT "Copyright(c) 2000-2003 Microsoft Corporation. All rights reserved.",
+ IDC_STATIC,36,40,222,8
+ LTEXT "Warning: This computer program is protected by copyright law and",
+ IDC_STATIC,36,55,222,8
+ LTEXT "international treaties. Unauthorized reproduction or distribution of",
+ IDC_STATIC,36,65,222,8
+ LTEXT "this program, or any portion of it, may result in severe civil and",
+ IDC_STATIC,36,75,222,8
+ LTEXT "criminal penalties, and will be prosecuted to the maximum extent",
+ IDC_STATIC,36,85,222,8
+ LTEXT "possible under the law.",IDC_STATIC,36,95,222,8
+ DEFPUSHBUTTON "OK",IDOK,204,102,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DIALOGBAR, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 135
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 411
+ END
+
+ IDD_TEXTURESIZE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 160
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 42
+ END
+
+ IDD_ABOUT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 255
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 68
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "Load TTF Font...", IDM_FILE_NEWFONT
+ MENUITEM "Load Custom Font...", IDM_FILE_LOADFONTLAYOUT
+ MENUITEM "Load Compiled Font File...", IDM_FILE_LOADFONTFILE
+ MENUITEM SEPARATOR
+ MENUITEM "&Save Compiled Font...", IDM_FILE_SAVEFONTFILES
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", IDM_FILE_EXIT
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "FontMaker &Help\tF1", ID_HELP
+ MENUITEM SEPARATOR
+ MENUITEM "&About FontMaker...", ID_APP_ABOUT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDR_MAINFRAME "FontMaker\n\nFontMa\n\n\nFontMaker.Document\nFontMa Document"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif //_WIN32
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/utils/xbox/FontMaker/fontmaker.vpc b/utils/xbox/FontMaker/fontmaker.vpc
new file mode 100644
index 0000000..8774386
--- /dev/null
+++ b/utils/xbox/FontMaker/fontmaker.vpc
@@ -0,0 +1,68 @@
+//-----------------------------------------------------------------------------
+// FONTMAKER.VPC
+//
+// Project Script
+//-----------------------------------------------------------------------------
+
+$Macro SRCDIR "..\..\.."
+$Macro OUTBINDIR "$SRCDIR\devtools\bin"
+
+$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
+
+$Configuration
+{
+ $Compiler
+ {
+ $EnableC++Exceptions "Yes (/EHsc)"
+ }
+
+ $Linker
+ {
+ $AdditionalDependencies "htmlhelp.lib"
+ }
+}
+
+
+$Project "FontMaker"
+{
+ $Folder "Source Files"
+ {
+ -$File "$SRCDIR\public\tier0\memoverride.cpp"
+
+ $File "FontMaker.cpp"
+ $File "FontMakerWnd.cpp"
+ $File "Glyphs.cpp"
+ $File "..\toollib\piclib.cpp"
+ $File "..\toollib\scriplib.cpp"
+ $File "Stdafx.cpp"
+ {
+ $Configuration
+ {
+ $Compiler
+ {
+ $Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)"
+ }
+ }
+ }
+
+ $File "..\toollib\toollib.cpp"
+ }
+
+ $Folder "Resource Files"
+ {
+ $File "FontMaker.ico"
+ $File "FontMaker.rc"
+ $File "resource.h"
+ }
+
+ $Folder "Header Files"
+ {
+ $File "..\..\..\public\BitmapFontFile.h"
+ $File "FontMaker.h"
+ $File "Glyphs.h"
+ $File "..\toollib\piclib.h"
+ $File "..\toollib\scriplib.h"
+ $File "Stdafx.h"
+ $File "..\toollib\toollib.h"
+ }
+}
diff --git a/utils/xbox/FontMaker/fontmakerwnd.cpp b/utils/xbox/FontMaker/fontmakerwnd.cpp
new file mode 100644
index 0000000..a81a24e
--- /dev/null
+++ b/utils/xbox/FontMaker/fontmakerwnd.cpp
@@ -0,0 +1,396 @@
+//-----------------------------------------------------------------------------
+// Name: FontMakerWnd.cpp
+//
+// Desc: The window and scroll view class for the fontmaker app
+//
+// Hist: 09.06.02 - Revised Fontmaker sample
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+#include "FontMaker.h"
+#include "Glyphs.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+extern CTextureFont g_Font;
+BOOL g_bIsGlyphSelected = FALSE;
+int g_iSelectedGlyphNum = 0;
+WCHAR g_cSelectedGlyph = '\0';
+GLYPH_ATTR* g_pSelectedGylph = NULL;
+
+// Colors
+#define COLOR_WHITE ( RGB(255,255,255) )
+#define COLOR_BLACK ( RGB( 0, 0, 0) )
+#define COLOR_BLUE ( RGB( 0, 0,255) )
+#define COLOR_RED ( RGB(255, 0, 0) )
+#define COLOR_DARKRED ( RGB(128, 0, 0) )
+
+//-----------------------------------------------------------------------------
+// CFontMakerFrameWnd
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNCREATE(CFontMakerFrameWnd, CFrameWnd)
+
+BEGIN_MESSAGE_MAP(CFontMakerFrameWnd, CFrameWnd)
+ //{{AFX_MSG_MAP(CFontMakerFrameWnd)
+ ON_WM_CREATE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+int CFontMakerFrameWnd::OnCreate( LPCREATESTRUCT pCreateStruct )
+{
+ if( CFrameWnd::OnCreate( pCreateStruct ) == -1 )
+ return -1;
+
+ // Create a docked dialog bar
+ EnableDocking( CBRS_ALIGN_ANY );
+ if( !m_wndDialogBar.Create( this, IDD_DIALOGBAR,
+ CBRS_LEFT, IDD_DIALOGBAR ) )
+ {
+ TRACE0("Failed to create DlgBar\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// CFontMakerView
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNCREATE(CFontMakerView, CScrollView)
+
+BEGIN_MESSAGE_MAP(CFontMakerView, CScrollView)
+ //{{AFX_MSG_MAP(CFontMakerView)
+ ON_WM_LBUTTONDOWN()
+ ON_WM_ERASEBKGND()
+ ON_WM_KEYDOWN()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+//-----------------------------------------------------------------------------
+// Name: ~CFontMakerView()
+// Desc: Destructor with special cleanup
+//-----------------------------------------------------------------------------
+CFontMakerView::~CFontMakerView()
+{
+ // Cleanup before exitting
+ m_memDC.DeleteDC();
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnInitialUpdate()
+// Desc: Called when the view is created.
+//-----------------------------------------------------------------------------
+void CFontMakerView::OnInitialUpdate()
+{
+ // Set the scroll bars
+ CScrollView::OnInitialUpdate();
+ CSize szTotal( g_Font.m_dwTextureWidth, g_Font.m_dwTextureHeight );
+ SetScrollSizes( MM_TEXT, szTotal );
+ CPoint ptCenter( 0, 0 );
+ CenterOnPoint( ptCenter );
+
+ // Create a secondary DC, used for drawing
+ m_memDC.CreateCompatibleDC( GetDC() );
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnEraseBkgnd()
+// Desc: Overridden function to prevent the view from flickering during resizes
+// and redraws
+//-----------------------------------------------------------------------------
+BOOL CFontMakerView::OnEraseBkgnd( CDC* pDC )
+{
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// Name: RenderSelectedGlyph()
+// Desc: Highlight the selected glyph
+//-----------------------------------------------------------------------------
+VOID RenderSelectedGlyph( CDC* pDC )
+{
+ // If no glyph is selected, return
+ if( FALSE == g_bIsGlyphSelected )
+ return;
+
+ HRGN rgn = CreateRectRgn( 0, 0, g_Font.m_dwTextureWidth, g_Font.m_dwTextureHeight );
+ SelectClipRgn( pDC->m_hDC, rgn );
+
+ // Draw a higlighted background for the selected glyph
+ {
+ int x = g_pSelectedGylph->x;
+ int y = g_pSelectedGylph->y;
+ int w = g_pSelectedGylph->w;
+ int h = g_pSelectedGylph->h;
+ pDC->FillSolidRect( x, y, w, h, COLOR_DARKRED );
+ }
+
+ // Setup the DC for drawing text
+ pDC->SetTextColor( COLOR_WHITE );
+ pDC->SelectObject( g_Font.m_hFont );
+ pDC->SetTextAlign( TA_LEFT|TA_TOP );
+ pDC->SetMapMode( MM_TEXT );
+ pDC->SetBkMode( TRANSPARENT );
+ pDC->SetBkColor( COLOR_BLUE );
+
+ CPen pen( PS_SOLID, 1, COLOR_RED );
+ pDC->SelectObject( &pen );
+
+ // Render the selected glyph
+ GLYPH_ATTR* pGlyph = g_pSelectedGylph;
+ {
+ WCHAR c = g_cSelectedGlyph;
+ WCHAR str[2] = L"A";
+ str[0] = c ? c : 0xffff;
+
+ if ( g_Font.m_ValidGlyphs[c] == 2 )
+ {
+ // Draw a square box for a placeholder for custom glyph graphics
+ pDC->FillSolidRect( pGlyph->x, pGlyph->y, pGlyph->w, pGlyph->h, COLOR_BLACK );
+ }
+ else
+ {
+ int sx = pGlyph->x;
+ int sy = pGlyph->y;
+
+ // Adjust ccordinates to account for the leading edge
+ if ( str[0] > 0x1000 )
+ {
+ }
+ else
+ {
+ sx -= pGlyph->a;
+
+ if ( g_Font.m_bOutlineEffect )
+ sx -= 1;
+ }
+
+ if ( g_Font.m_bOutlineEffect )
+ {
+ sx++;
+ sy++;
+
+ pDC->SetTextColor( COLOR_BLACK );
+ ExtTextOutW( pDC->m_hDC, sx-1, sy-1, ETO_OPAQUE, NULL, str, 1, NULL );
+ ExtTextOutW( pDC->m_hDC, sx+0, sy-1, ETO_OPAQUE, NULL, str, 1, NULL );
+ ExtTextOutW( pDC->m_hDC, sx+1, sy-1, ETO_OPAQUE, NULL, str, 1, NULL );
+ ExtTextOutW( pDC->m_hDC, sx-1, sy+0, ETO_OPAQUE, NULL, str, 1, NULL );
+ ExtTextOutW( pDC->m_hDC, sx+1, sy+0, ETO_OPAQUE, NULL, str, 1, NULL );
+ ExtTextOutW( pDC->m_hDC, sx-1, sy+1, ETO_OPAQUE, NULL, str, 1, NULL );
+ ExtTextOutW( pDC->m_hDC, sx+0, sy+1, ETO_OPAQUE, NULL, str, 1, NULL );
+ ExtTextOutW( pDC->m_hDC, sx+1, sy+1, ETO_OPAQUE, NULL, str, 1, NULL );
+ }
+
+ if ( g_Font.m_bShadowEffect )
+ {
+ pDC->SetTextColor( COLOR_BLACK );
+ ExtTextOutW( pDC->m_hDC, sx+2, sy+2, ETO_OPAQUE, NULL, str, 1, NULL );
+ }
+
+ // Output the letter
+ pDC->SetTextColor( COLOR_WHITE );
+ ExtTextOutW( pDC->m_hDC, sx, sy, ETO_OPAQUE, NULL, str, 1, NULL );
+ }
+ }
+
+ // Draw a red outline around the selected glyph
+ {
+ // Create a red pen
+ CPen pen( PS_SOLID, 1, COLOR_RED );
+ pDC->SelectObject( &pen );
+
+ // Draw the outline
+ int x1 = pGlyph->x - 1;
+ int y1 = pGlyph->y - 1;
+ int x2 = pGlyph->x + pGlyph->w;
+ int y2 = pGlyph->y + pGlyph->h;
+
+ pDC->MoveTo( x1, y1 );
+ pDC->LineTo( x2, y1 );
+ pDC->LineTo( x2, y2 );
+ pDC->LineTo( x1, y2 );
+ pDC->LineTo( x1, y1 );
+ }
+
+ SelectClipRgn( pDC->m_hDC, NULL );
+ DeleteObject( rgn );
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnDraw()
+// Desc: Overridden draw function. Draws the font glyphs if a font is loaded,
+// else just a black background.
+//-----------------------------------------------------------------------------
+VOID CFontMakerView::OnNewFontGlyphs()
+{
+ // Select the resulting bits into our memory DC
+ static CBitmap Bitmap;
+ Bitmap.DeleteObject();
+ Bitmap.CreateBitmap( g_Font.m_dwTextureWidth, g_Font.m_dwTextureHeight, 1, 32, g_Font.m_pBits );
+ m_memDC.SelectObject( &Bitmap );
+
+ // Trigger the view to be re-drawn
+ OnUpdate(0,0,0);
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnDraw()
+// Desc: Overridden draw function. Draws the font glyphs if a font is loaded,
+// else just a black background.
+//-----------------------------------------------------------------------------
+VOID CFontMakerView::OnDraw( CDC* pDC )
+{
+ RECT rc;
+ GetClientRect( &rc );
+
+ // Draw the view
+ if ( g_Font.m_hFont == NULL && !g_Font.m_pCustomFilename )
+ {
+ // Don't display any scroll bars
+ CSize sizeTotal( 0, 0 );
+ SetScrollSizes( MM_TEXT, sizeTotal );
+
+ // Draw a black background
+ pDC->FillSolidRect( 0, 0, rc.right, rc.bottom, COLOR_BLACK );
+ }
+ else
+ {
+ // Set the scroll sizes for the view
+ CSize sizeTotal( g_Font.m_dwTextureWidth, g_Font.m_dwTextureHeight );
+ SetScrollSizes( MM_TEXT, sizeTotal );
+
+ // Draw the view's black areas
+ pDC->FillSolidRect( g_Font.m_dwTextureWidth, 0, max( (int)g_Font.m_dwTextureWidth, rc.right), g_Font.m_dwTextureHeight, COLOR_BLACK );
+ pDC->FillSolidRect( 0, g_Font.m_dwTextureHeight, max( (int)g_Font.m_dwTextureWidth, rc.right), max( (int)g_Font.m_dwTextureHeight, rc.bottom), COLOR_BLACK );
+
+ // Display the bitmap of all the rendered glyphs
+ pDC->BitBlt( 0, 0, g_Font.m_dwTextureWidth, g_Font.m_dwTextureHeight, &m_memDC, 0, 0, SRCCOPY );
+
+ // Draw the selected glyph, if any
+ RenderSelectedGlyph( pDC );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnLButtonDown()
+// Desc: Overridden function to select a glyph when the user clicks the mouse.
+//-----------------------------------------------------------------------------
+void CFontMakerView::OnLButtonDown( UINT nFlags, CPoint point )
+{
+ if ( !g_Font.m_hFont )
+ return;
+
+ // Correct the mouseclick point to account for the scroll position
+ point += GetScrollPosition();
+
+ // Find out which glyph, if any, is selected by the mouse click
+ theApp.UpdateSelectedGlyph( FALSE );
+
+ for( DWORD i=0; i<g_Font.m_dwNumGlyphs && g_Font.m_pGlyphs; i++ )
+ {
+ GLYPH_ATTR* pGlyph = &g_Font.m_pGlyphs[i];
+
+ if ( point.x >= pGlyph->x-2 && point.x <= pGlyph->x + pGlyph->w )
+ {
+ if ( point.y >= pGlyph->y-2 && point.y <= pGlyph->y + pGlyph->h )
+ {
+ theApp.UpdateSelectedGlyph( TRUE, i );
+ break;
+ }
+ }
+ }
+
+ // Redraw the view to show the newly selected glyph
+ Invalidate( TRUE );
+
+ // Call the base class' handler
+ CScrollView::OnLButtonDown( nFlags, point );
+}
+
+//-----------------------------------------------------------------------------
+// Name: OnKeyDown()
+// Desc: Overridden function to select a glyph with the keyboard.
+//-----------------------------------------------------------------------------
+void CFontMakerView::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
+{
+ if ( !g_Font.m_hFont )
+ return;
+
+ if( g_Font.m_dwNumGlyphs > 0 )
+ {
+ if( FALSE == g_bIsGlyphSelected )
+ {
+ if( nChar == 37 || nChar == 38 || nChar == 39 || nChar == 40 ) // Left, right, up or down
+ {
+ // Select the first glyph
+ theApp.UpdateSelectedGlyph( TRUE, 0 );
+ }
+ }
+ else
+ {
+ if( nChar == 37 ) // Left
+ theApp.UpdateSelectedGlyph( TRUE, max( 0, g_iSelectedGlyphNum-1 ) );
+ else if( nChar == 39 ) // Right
+ theApp.UpdateSelectedGlyph( TRUE, min( (int)g_Font.m_dwNumGlyphs-1, g_iSelectedGlyphNum+1 ) );
+ else if( nChar == 38 || nChar == 40 ) // Up or down
+ {
+ // Find the closest glyph above or below to move to
+ int x = g_pSelectedGylph->x + g_pSelectedGylph->w/2;
+ int y = g_pSelectedGylph->y + g_pSelectedGylph->h/2;
+
+ if( nChar == 38 ) y -= g_pSelectedGylph->h;
+ if( nChar == 40 ) y += g_pSelectedGylph->h;
+
+ for( DWORD i=0; i<g_Font.m_dwNumGlyphs; i++ )
+ {
+ GLYPH_ATTR* pGlyph = &g_Font.m_pGlyphs[i];
+
+ if( x >= pGlyph->x-2 && x <= pGlyph->x + pGlyph->w )
+ {
+ if( y >= pGlyph->y-2 && y <= pGlyph->y + pGlyph->h )
+ {
+ theApp.UpdateSelectedGlyph( TRUE, i );
+ break;
+ }
+ }
+ }
+ }
+ else if ( nChar == 46 )
+ {
+ // delete a glyph
+ theApp.OnGlyphsCustom();
+
+ // mark glyph as invalid
+ g_Font.DeleteGlyph( g_cSelectedGlyph );
+
+ // reset to the first glyph
+ theApp.UpdateSelectedGlyph( FALSE );
+ }
+ else if ( nChar == 45 )
+ {
+ // insert a glyph
+ theApp.OnGlyphsCustom();
+
+ // reset to the first glyph
+ theApp.UpdateSelectedGlyph( FALSE );
+
+ theApp.InsertGlyph();
+ }
+ }
+
+ // Redraw the view to show the newly selected glyph
+ Invalidate( TRUE );
+ }
+
+ CScrollView::OnKeyDown( nChar, nRepCnt, nFlags );
+}
+
+
+
diff --git a/utils/xbox/FontMaker/glyphs.cpp b/utils/xbox/FontMaker/glyphs.cpp
new file mode 100644
index 0000000..c2328ac
--- /dev/null
+++ b/utils/xbox/FontMaker/glyphs.cpp
@@ -0,0 +1,1484 @@
+//-----------------------------------------------------------------------------
+// Name: Glyphs.cpp
+//
+// Desc: Functions and global variables for keeping track of font glyphs
+//
+// Hist: 09.06.02 - Revised Fontmaker sample
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#include "stdafx.h"
+#include "Glyphs.h"
+#include "FontMaker.h"
+
+const COLORREF COLOR_WHITE = RGB(255,255,255);
+const COLORREF COLOR_BLACK = RGB( 0, 0, 0);
+const COLORREF COLOR_BLUE = RGB( 0, 0,255);
+
+//-----------------------------------------------------------------------------
+// Name: CTextureFont()
+// Desc: Constructor
+//-----------------------------------------------------------------------------
+CTextureFont::CTextureFont()
+{
+ ZeroMemory( this, sizeof( *this ) );
+
+ m_bIncludeNullCharacter = TRUE;
+ m_bAntialiasEffect = TRUE;
+
+ // Texture info
+ m_dwTextureWidth = 256;
+ m_dwTextureHeight = 256;
+
+ // Default glyph range
+ WORD wStartGlyph = 32;
+ WORD wEndGlyph = 255;
+ ExtractValidGlyphsFromRange( wStartGlyph, wEndGlyph );
+}
+
+//-----------------------------------------------------------------------------
+// Name: ~CTextureFont()
+// Desc: Destructor
+//-----------------------------------------------------------------------------
+CTextureFont::~CTextureFont()
+{
+ DestroyObjects();
+
+ if ( m_hFont )
+ DeleteObject( m_hFont );
+
+ if ( m_pBits )
+ delete[] m_pBits;
+
+ m_pBits = NULL;
+ m_hFont = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// ClearFont
+//-----------------------------------------------------------------------------
+void CTextureFont::ClearFont()
+{
+ DestroyObjects();
+
+ ZeroMemory( &m_LogFont, sizeof(LOGFONT) );
+
+ m_strFontName[0] = '\0';
+
+ m_hFont = NULL;
+
+ m_dwTextureWidth = 256;
+ m_dwTextureHeight = 256;
+
+ m_bAntialiasEffect = FALSE;
+ m_bShadowEffect = FALSE;
+ m_bOutlineEffect = FALSE;
+ m_nBlur = 0;
+ m_nScanlines = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Name: DestroyObjects()
+// Desc: Cleans up all allocated resources for the class
+//-----------------------------------------------------------------------------
+VOID CTextureFont::DestroyObjects()
+{
+ if ( m_pGlyphs )
+ delete[] m_pGlyphs;
+ if ( m_ValidGlyphs )
+ delete[] m_ValidGlyphs;
+ if ( m_TranslatorTable )
+ delete[] m_TranslatorTable;
+
+ if ( m_pCustomFilename )
+ {
+ TL_Free( (void*)m_pCustomFilename );
+ m_pCustomFilename = NULL;
+
+ for (DWORD i=0; i<m_dwNumGlyphs; i++)
+ {
+ if ( m_pCustomGlyphFiles[i] )
+ {
+ TL_Free( m_pCustomGlyphFiles[i] );
+ m_pCustomGlyphFiles[i] = NULL;
+ }
+ }
+ }
+
+ m_cMaxGlyph = 0;
+ m_dwNumGlyphs = 0;
+ m_pGlyphs = NULL;
+ m_ValidGlyphs = NULL;
+ m_TranslatorTable = NULL;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::InsertGlyph( WORD wGlyph )
+{
+ m_cMaxGlyph = 0;
+ m_dwNumGlyphs = 0;
+
+ m_ValidGlyphs[wGlyph] = 1;
+
+ for ( DWORD c=0; c<=65535; c++ )
+ {
+ if ( m_ValidGlyphs[c] )
+ {
+ m_dwNumGlyphs++;
+ m_cMaxGlyph = (WCHAR)c;
+ }
+ }
+
+ BuildTranslatorTable();
+ theApp.CalculateAndRenderGlyphs();
+
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::DeleteGlyph( WORD wGlyph )
+{
+ m_cMaxGlyph = 0;
+ m_dwNumGlyphs = 0;
+
+ m_ValidGlyphs[wGlyph] = 0;
+
+ for ( DWORD c=0; c<=65535; c++ )
+ {
+ if ( m_ValidGlyphs[c] )
+ {
+ m_dwNumGlyphs++;
+ m_cMaxGlyph = (WCHAR)c;
+ }
+ }
+
+ BuildTranslatorTable();
+ theApp.CalculateAndRenderGlyphs();
+
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// Name: ExtractValidGlyphsFromRange()
+// Desc: Set global variables to indicate we will be drawing all glyphs in the
+// range specified.
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::ExtractValidGlyphsFromRange( WORD wStartGlyph, WORD wEndGlyph )
+{
+ // Cleanup any previous entries
+ if( m_ValidGlyphs )
+ delete[] m_ValidGlyphs;
+
+ m_cMaxGlyph = 0;
+ m_dwNumGlyphs = 0;
+ m_ValidGlyphs = NULL;
+
+ // Allocate memory for the array of vaild glyphs
+ m_ValidGlyphs = new BYTE[65536];
+ ZeroMemory( m_ValidGlyphs, 65536 );
+
+ for( DWORD c=(DWORD)wStartGlyph; c<=(DWORD)wEndGlyph; c++ )
+ {
+ m_ValidGlyphs[c] = 1;
+ m_dwNumGlyphs++;
+ }
+
+ m_cMaxGlyph = wEndGlyph;
+
+ BuildTranslatorTable();
+
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// Name: ExtractValidGlyphsFromRange()
+// Desc: Set global variables to indicate we will be drawing all glyphs that
+// are present in the specified text file.
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::ExtractValidGlyphsFromFile( const CHAR* strFileName )
+{
+ // Open the file
+ FILE* file = fopen( strFileName, "rb" );
+ if( NULL == file )
+ return E_FAIL;
+
+ // Cleanup any previous entries
+ if( m_ValidGlyphs )
+ delete[] m_ValidGlyphs;
+
+ m_cMaxGlyph = 0;
+ m_dwNumGlyphs = 0;
+ m_ValidGlyphs = NULL;
+
+ // Allocate memory for the array of vaild glyphs
+ m_ValidGlyphs = new BYTE[65536];
+ ZeroMemory( m_ValidGlyphs, 65536 );
+
+ // Skip the unicode marker
+ BOOL bIsUnicode = (fgetwc(file) == 0xfeff) ? TRUE : FALSE;
+
+ if( bIsUnicode == FALSE )
+ rewind( file );
+
+ // Record which glyphs are valid
+ WCHAR c;
+ while( (WCHAR)EOF != ( c = bIsUnicode ? fgetwc(file) : fgetc(file) ) )
+ {
+ while( c == L'\\' )
+ {
+ c = bIsUnicode ? fgetwc(file) : fgetc(file);
+
+ // Handle octal-coded characters
+ if( isdigit(c) )
+ {
+ int code = (c - L'0');
+ c = bIsUnicode ? fgetwc(file) : fgetc(file);
+
+ if( isdigit(c) )
+ {
+ code = code*8 + (c - L'0');
+ c = bIsUnicode ? fgetwc(file) : fgetc(file);
+
+ if( isdigit(c) )
+ {
+ code = code*8 + (c - L'0');
+ c = bIsUnicode ? fgetwc(file) : fgetc(file);
+ }
+ }
+
+ if( m_ValidGlyphs[code] == 0 )
+ {
+ if( code > m_cMaxGlyph )
+ m_cMaxGlyph = (WCHAR)code;
+
+ m_dwNumGlyphs++;
+ m_ValidGlyphs[code] = 2;
+ }
+ }
+ else
+ {
+ // Add the backslash character
+ if( L'\\' > m_cMaxGlyph )
+ m_cMaxGlyph = L'\\';
+
+ if( m_ValidGlyphs[L'\\'] == 0 )
+ {
+ m_dwNumGlyphs++;
+ m_ValidGlyphs[L'\\'] = 1;
+ }
+ }
+ }
+
+ if( m_ValidGlyphs[c] == 0 )
+ {
+ // If the character is a printable one, add it
+ if( c != L'\n' && c != L'\r' && c != 0xffff )
+ {
+ m_dwNumGlyphs++;
+ m_ValidGlyphs[c] = 1;
+
+ if( c > m_cMaxGlyph )
+ m_cMaxGlyph = c;
+ }
+ }
+ }
+
+ // Done with the file
+ fclose( file );
+
+ BuildTranslatorTable();
+
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// Name: BuildTranslatorTable()
+// Desc: Builds a table to translate from a WCHAR to a glyph index.
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::BuildTranslatorTable()
+{
+ if ( m_TranslatorTable )
+ delete[] m_TranslatorTable;
+
+ // Insure the \0 is there
+ if ( m_bIncludeNullCharacter && 0 == m_ValidGlyphs[0] )
+ {
+ m_dwNumGlyphs++;
+ m_ValidGlyphs[0] = 1;
+ }
+
+ // Fill the string of all valid glyphs and build the translator table
+ m_TranslatorTable = new WORD[m_cMaxGlyph+1];
+ ZeroMemory( m_TranslatorTable, sizeof(WORD)*(m_cMaxGlyph+1) );
+
+ if ( !m_pCustomFilename )
+ {
+ // ttf has glyphs that are sequential
+ DWORD dwGlyph = 0;
+ for ( DWORD i=0; i<65536; i++ )
+ {
+ if ( m_ValidGlyphs[i] )
+ {
+ m_TranslatorTable[i] = (WORD)dwGlyph;
+ dwGlyph++;
+ }
+ }
+ }
+ else
+ {
+ // custom font has glyphs that are scattered
+ DWORD dwGlyph = 0;
+ for ( DWORD i=0; i<m_dwNumGlyphs; i++ )
+ {
+ if ( !i && m_bIncludeNullCharacter )
+ {
+ m_TranslatorTable[0] = 0;
+ dwGlyph++;
+ continue;
+ }
+
+ m_TranslatorTable[m_customGlyphs[i-1]] = (WORD)dwGlyph;
+ dwGlyph++;
+ }
+ }
+
+ return S_OK;
+}
+
+void StripQuotedToken( char *pToken )
+{
+ int len = strlen( pToken );
+ if ( !len )
+ return;
+
+ if ( pToken[0] == '\"' && pToken[len-1] == '\"' )
+ {
+ memcpy( pToken, pToken+1, len-1 );
+ pToken[len-2] = '\0';
+ }
+}
+
+
+
+//-----------------------------------------------------------------------------
+// ReadCustomFontFile
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::ReadCustomFontFile( CHAR* strFileName )
+{
+ char *pToken;
+ char fontName[128];
+ bool bSuccess;
+ unsigned char glyphs[256];
+ char *glyphFiles[512];
+ char basePath[MAX_PATH];
+ int numGlyphs;
+ char filename[MAX_PATH];
+
+ bSuccess = false;
+ numGlyphs = 0;
+
+ ClearFont();
+
+ TL_LoadScriptFile( strFileName );
+
+ strcpy( basePath, strFileName );
+ TL_StripFilename( basePath );
+ TL_AddSeperatorToPath( basePath, basePath );
+
+ fontName[0] = '\0';
+ while ( 1 )
+ {
+ pToken = TL_GetToken( true );
+ if ( !pToken || !pToken[0] )
+ break;
+ StripQuotedToken( pToken );
+
+ // get font name
+ if ( !stricmp( pToken, "fontName" ) )
+ {
+ pToken = TL_GetToken( true );
+ if ( !pToken || !pToken[0] )
+ goto cleanUp;
+ StripQuotedToken( pToken );
+ strcpy( fontName, pToken );
+ continue;
+ }
+
+ // get glyph
+ if ( strlen( pToken ) != 1 )
+ goto cleanUp;
+ glyphs[numGlyphs] = pToken[0];
+
+ // get glyph file
+ pToken = TL_GetToken( true );
+ if ( !pToken || !pToken[0] )
+ goto cleanUp;
+ StripQuotedToken( pToken );
+ sprintf( filename, "%s%s", basePath, pToken );
+ glyphFiles[numGlyphs] = TL_CopyString( filename );
+
+ numGlyphs++;
+ if ( numGlyphs >= 256 )
+ break;
+ }
+
+ if ( numGlyphs == 0 )
+ goto cleanUp;
+
+ m_pCustomFilename = TL_CopyString( strFileName );
+ strcpy ( m_strFontName, fontName );
+
+ m_dwTextureWidth = 256;
+ m_dwTextureHeight = 256;
+
+ m_ValidGlyphs = new BYTE[65536];
+ ZeroMemory( m_ValidGlyphs, 65536 );
+
+ m_dwNumGlyphs = numGlyphs;
+ m_cMaxGlyph = 0;
+ for (int i=0; i<numGlyphs; i++)
+ {
+ m_ValidGlyphs[glyphs[i]] = 1;
+
+ if ( m_cMaxGlyph < glyphs[i] )
+ m_cMaxGlyph = glyphs[i];
+
+ m_customGlyphs[i] = glyphs[i];
+ m_pCustomGlyphFiles[i] = glyphFiles[i];
+ }
+
+ BuildTranslatorTable();
+
+ bSuccess = true;
+
+cleanUp:
+ TL_FreeScriptFile();
+ return bSuccess ? S_OK : E_FAIL;
+}
+
+//-----------------------------------------------------------------------------
+// Name: ReadFontInfoFile()
+// Desc: Loads the font's glyph info from a file
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::ReadFontInfoFile( CHAR* strFileName )
+{
+ BitmapFont_t bitmapFont;
+
+ // open the info file
+ FILE* file = fopen( strFileName, "rb" );
+ if ( NULL == file )
+ return E_FAIL;
+
+ memset( &bitmapFont, 0, sizeof( BitmapFont_t ) );
+ fread( &bitmapFont, 1, sizeof( BitmapFont_t ), file );
+
+ if ( bitmapFont.m_id != BITMAPFONT_ID || bitmapFont.m_Version != BITMAPFONT_VERSION )
+ {
+ return E_FAIL;
+ }
+
+ theApp.SetTextureSize( bitmapFont.m_PageWidth, bitmapFont.m_PageHeight );
+
+ ZeroMemory( m_ValidGlyphs, 65536 );
+
+ m_dwNumGlyphs = 0;
+ m_cMaxGlyph = 0;
+ for (int i=0; i<256; i++)
+ {
+ if ( bitmapFont.m_TranslateTable[i] )
+ {
+ m_ValidGlyphs[i] = 1;
+ m_cMaxGlyph = i;
+ m_dwNumGlyphs++;
+ }
+ }
+ BuildTranslatorTable();
+
+ // success
+ fclose( file );
+
+ theApp.OnGlyphsCustom();
+ theApp.CalculateAndRenderGlyphs();
+
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// Name: WriteFontInfoFile()
+// Desc: Writes the font's glyph info to a file
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::WriteFontInfoFile( CHAR* strFileName )
+{
+ BitmapFont_t bitmapFont;
+ BitmapGlyph_t bitmapGlyph;
+
+ // Create the info file
+ FILE* file = fopen( strFileName, "wb" );
+ if ( NULL == file )
+ return E_FAIL;
+
+ bitmapFont.m_id = BITMAPFONT_ID;
+ bitmapFont.m_Version = BITMAPFONT_VERSION;
+ bitmapFont.m_PageWidth = (short)m_dwTextureWidth;
+ bitmapFont.m_PageHeight = (short)m_dwTextureHeight;
+ bitmapFont.m_Ascent = 0;
+ bitmapFont.m_NumGlyphs = (short)m_dwNumGlyphs;
+
+ // generate flags
+ bitmapFont.m_Flags = 0;
+ if ( m_bAntialiasEffect )
+ {
+ bitmapFont.m_Flags |= BF_ANTIALIASED;
+ }
+ if ( m_bShadowEffect )
+ {
+ bitmapFont.m_Flags |= BF_DROPSHADOW;
+ }
+ if ( m_bOutlineEffect )
+ {
+ bitmapFont.m_Flags |= BF_OUTLINED;
+ }
+ if ( m_nBlur )
+ {
+ bitmapFont.m_Flags |= BF_BLURRED;
+ }
+ if ( m_nScanlines )
+ {
+ bitmapFont.m_Flags |= BF_SCANLINES;
+ }
+ if ( m_LogFont.lfItalic )
+ {
+ bitmapFont.m_Flags |= BF_ITALIC;
+ }
+ if ( m_LogFont.lfWeight > 400 )
+ {
+ bitmapFont.m_Flags |= BF_BOLD;
+ }
+ if ( m_pCustomFilename )
+ {
+ bitmapFont.m_Flags |= BF_CUSTOM;
+ }
+
+ // determine max char width from all glyphs
+ bitmapFont.m_MaxCharWidth = 0;
+ for (unsigned int i=0; i<m_dwNumGlyphs; i++ )
+ {
+ if ( bitmapFont.m_MaxCharWidth < m_pGlyphs[i].w )
+ {
+ bitmapFont.m_MaxCharWidth = m_pGlyphs[i].w;
+ }
+ }
+
+ bitmapFont.m_MaxCharHeight = 0;
+ for (unsigned int i=0; i<m_dwNumGlyphs; i++ )
+ {
+ if ( bitmapFont.m_MaxCharHeight < m_pGlyphs[i].h )
+ {
+ bitmapFont.m_MaxCharHeight = m_pGlyphs[i].h;
+ }
+ }
+
+ // maps a char index to its actual glyph
+ for (int i=0; i<256; i++)
+ {
+ if ( i <= m_cMaxGlyph )
+ {
+ bitmapFont.m_TranslateTable[i] = (unsigned char)m_TranslatorTable[i];
+ }
+ else
+ {
+ bitmapFont.m_TranslateTable[i] = 0;
+ }
+ }
+
+ // write out the header
+ fwrite( &bitmapFont, sizeof( BitmapFont_t ), 1, file );
+
+ // Write out the vertical padding caused by effects
+// FLOAT fTopPadding = ( m_bOutlineEffect ? 1.0f : 0.0f );
+// FLOAT fBottomPadding = ( m_bOutlineEffect ? ( m_bShadowEffect ? 2.0f : 1.0f ) : ( m_bShadowEffect ? 2.0f : 0.0f ) );
+// FLOAT fFontYAdvance = fFontHeight - fTopPadding - fBottomPadding;
+
+ // Write the glyph attributes to the file
+ for (unsigned int i=0; i<m_dwNumGlyphs; i++ )
+ {
+ bitmapGlyph.x = m_pGlyphs[i].x;
+ bitmapGlyph.y = m_pGlyphs[i].y;
+ bitmapGlyph.w = m_pGlyphs[i].w;
+ bitmapGlyph.h = m_pGlyphs[i].h;
+ bitmapGlyph.a = m_pGlyphs[i].a;
+ bitmapGlyph.b = m_pGlyphs[i].b;
+ bitmapGlyph.c = m_pGlyphs[i].c;
+
+ fwrite( &bitmapGlyph, sizeof( BitmapGlyph_t ), 1, file );
+ }
+
+ // success
+ fclose( file );
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// Name: WriteTargaFile()
+// Desc: Writes 32-bit RGBA data to a .tga file
+//-----------------------------------------------------------------------------
+HRESULT WriteTargaFile( CHAR* strFileName, DWORD dwWidth, DWORD dwHeight,
+ DWORD* pRGBAData )
+{
+ struct TargaHeader
+ {
+ BYTE IDLength;
+ BYTE ColormapType;
+ BYTE ImageType;
+ BYTE ColormapSpecification[5];
+ WORD XOrigin;
+ WORD YOrigin;
+ WORD ImageWidth;
+ WORD ImageHeight;
+ BYTE PixelDepth;
+ BYTE ImageDescriptor;
+ } tga;
+
+ // Create the file
+ FILE* file = fopen( strFileName, "wb" );
+ if( NULL == file )
+ return E_FAIL;
+
+ // Write the TGA header
+ ZeroMemory( &tga, sizeof(tga) );
+ tga.IDLength = 0;
+ tga.ImageType = 2;
+ tga.ImageWidth = (WORD)dwWidth;
+ tga.ImageHeight = (WORD)dwHeight;
+ tga.PixelDepth = 32;
+ tga.ImageDescriptor = 0x28;
+ fwrite( &tga, sizeof(TargaHeader), 1, file );
+
+ // Write the pixels
+ fwrite( pRGBAData, sizeof(DWORD), dwHeight*dwWidth, file );
+
+ // Close the file and return okay
+ fclose( file );
+
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// Name: WriteFontImageFile()
+// Desc: Writes 32-bit RGBA data to a .tga file
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::WriteFontImageFile( CHAR* strFileName, bool bAdditiveMode, bool bCustomFont )
+{
+ // Convert the bits to have an alpha channel
+ DWORD* pRGBAData = new DWORD[m_dwTextureWidth*m_dwTextureHeight];
+
+ FLOAT l;
+ for ( DWORD i=0; i<m_dwTextureWidth*m_dwTextureHeight; i++ )
+ {
+ FLOAT a = ( ( 0xff000000 & m_pBits[i] ) >> 24L ) / 255.0f;
+ FLOAT r = ( ( 0x00ff0000 & m_pBits[i] ) >> 16L ) / 255.0f;
+ FLOAT g = ( ( 0x0000ff00 & m_pBits[i] ) >> 8L ) / 255.0f;
+ FLOAT b = ( ( 0x000000ff & m_pBits[i] ) >> 0L ) / 255.0f;
+
+ if ( bCustomFont )
+ {
+ if ( a == 0.0f && b == 1.0f )
+ {
+ // pure transluscent
+ a = 0;
+ r = g = b = 0.0f;
+ }
+
+ int red = (int)(r * 255.0f);
+ int green = (int)(g * 255.0f);
+ int blue = (int)(b * 255.0f);
+ int alpha = (int)(a * 255.0f);
+
+ pRGBAData[i] = (alpha<<24L) | (red<<16L) | (green<<8L) | (blue<<0L);
+ }
+ else
+ {
+ if ( bAdditiveMode )
+ {
+ // all channels should be same
+ if (( r != g ) || ( r != b ))
+ {
+ }
+
+ l = r;
+ a = 1.0f;
+ }
+ else
+ {
+ a = r + (1-b);
+ if ( a )
+ l = r / a;
+ else
+ l = 1;
+ }
+
+ DWORD alpha = (DWORD)( a * 255.0f );
+ DWORD lum = (DWORD)( l * 255.0f );
+
+ pRGBAData[i] = (alpha<<24L) | (lum<<16L) | (lum<<8L) | (lum<<0L);
+ }
+ }
+
+ // Write the file
+ HRESULT hr = WriteTargaFile( strFileName, m_dwTextureWidth,
+ m_dwTextureHeight, pRGBAData );
+
+ // Cleanup and return
+ delete[] pRGBAData;
+ return hr;
+}
+
+void GetBitmapBits2( HBITMAP hBitmap, int width, int height, void *pBits )
+{
+ memset( pBits, 0, width*height*4 );
+
+ HDC hDC = CreateCompatibleDC( NULL );
+ BITMAPINFO bitmapInfo = {0};
+ bitmapInfo.bmiHeader.biSize = sizeof( bitmapInfo.bmiHeader );
+ bitmapInfo.bmiHeader.biWidth = width;
+ bitmapInfo.bmiHeader.biHeight = -height;
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+ GetDIBits( hDC, hBitmap, 0, height, pBits, &bitmapInfo ,DIB_RGB_COLORS );
+ DeleteDC( hDC );
+}
+
+void SetBitmapBits2( HBITMAP hBitmap, int width, int height, void *pBits )
+{
+ HDC hDC = CreateCompatibleDC( NULL );
+ BITMAPINFO bitmapInfo = {0};
+ bitmapInfo.bmiHeader.biSize = sizeof( bitmapInfo.bmiHeader );
+ bitmapInfo.bmiHeader.biWidth = width;
+ bitmapInfo.bmiHeader.biHeight = -height;
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+ SetDIBits( hDC, hBitmap, 0, height, pBits, &bitmapInfo ,DIB_RGB_COLORS );
+ DeleteDC( hDC );
+}
+
+//-----------------------------------------------------------------------------
+// SetTextureBits
+//
+// Blit the rect back into the bitmap
+//-----------------------------------------------------------------------------
+void SetTextureBits( HBITMAP hBitmap, int bitmapWidth, int bitmapHeight, int x, int y, int w, int h, unsigned char *pRGBA )
+{
+ // get the enitre bitmap
+ unsigned char *pBitmapBits = (unsigned char *)malloc( bitmapWidth * bitmapHeight * 4);
+ GetBitmapBits2( hBitmap, bitmapWidth, bitmapHeight, pBitmapBits );
+
+ // copy into bitmap bits
+ unsigned char *pSrc = pRGBA;
+ for (int yy=y; yy<y+h; yy++)
+ {
+ if ( yy >= bitmapHeight )
+ {
+ // past end of bitmap
+ break;
+ }
+
+ unsigned char *pDst = pBitmapBits + (yy*bitmapWidth + x)*4;
+ for (int xx=0; xx<w; xx++)
+ {
+ if ( xx+x < bitmapWidth )
+ {
+ pDst[0] = pSrc[0];
+ pDst[1] = pSrc[1];
+ pDst[2] = pSrc[2];
+ pDst[3] = pSrc[3];
+ }
+ pSrc += 4;
+ pDst += 4;
+ }
+ }
+
+ SetBitmapBits2( hBitmap, bitmapWidth, bitmapHeight, pBitmapBits );
+
+ free( pBitmapBits );
+}
+
+//-----------------------------------------------------------------------------
+// GetTextureBits
+//
+// Blit the rect out of the bitmap
+//-----------------------------------------------------------------------------
+unsigned char *GetTextureBits( HBITMAP hBitmap, int bitmapWidth, int bitmapHeight, int x, int y, int w, int h )
+{
+ // get the enitre bitmap
+ unsigned char *pBitmapBits = new unsigned char[bitmapWidth * bitmapHeight * 4];
+ GetBitmapBits2( hBitmap, bitmapWidth, bitmapHeight, pBitmapBits );
+
+ unsigned char *pRGBA = new unsigned char[w * h * 4];
+ memset( pRGBA, 0, w*h*4 );
+
+ // copy out bits
+ unsigned char *pDst = pRGBA;
+ for (int yy=y; yy<y+h; yy++)
+ {
+ if ( yy >= bitmapHeight )
+ {
+ // past last row of bitmap
+ break;
+ }
+
+ unsigned char *pSrc = pBitmapBits + (yy*bitmapWidth + x)*4;
+ for (int xx=0; xx<w; xx++)
+ {
+ if ( xx + x < bitmapWidth )
+ {
+ pDst[0] = pSrc[0];
+ pDst[1] = pSrc[1];
+ pDst[2] = pSrc[2];
+ pDst[3] = pSrc[3];
+ }
+ pSrc += 4;
+ pDst += 4;
+ }
+ }
+
+ delete [] pBitmapBits;
+ return pRGBA;
+}
+
+
+int g_blur;
+float *g_pGaussianDistribution;
+
+//-----------------------------------------------------------------------------
+// Purpose: Gets the blur value for a single pixel
+//-----------------------------------------------------------------------------
+void GetBlurValueForPixel(unsigned char *src, int blur, float *gaussianDistribution, int srcX, int srcY, int srcWide, int srcTall, unsigned char *dest)
+{
+ int r = 0, g = 0, b = 0, a = 0;
+
+ float accum = 0.0f;
+
+ // scan the positive x direction
+ int maxX = min(srcX + blur, srcWide);
+ int minX = max(srcX - blur, 0);
+ for (int x = minX; x <= maxX; x++)
+ {
+ int maxY = min(srcY + blur, srcTall - 1);
+ int minY = max(srcY - blur, 0);
+ for (int y = minY; y <= maxY; y++)
+ {
+ unsigned char *srcPos = src + ((x + (y * srcWide)) * 4);
+
+ unsigned char red = srcPos[2];
+ unsigned char green = srcPos[1];
+ unsigned char blue = srcPos[0];
+
+ // muliply by the value matrix
+ float weight = gaussianDistribution[x - srcX + blur];
+ float weight2 = gaussianDistribution[y - srcY + blur];
+ accum += (red * (weight * weight2));
+ }
+ }
+
+ // blurring decreased the range, for xbox kick some back
+ accum *= 1.30f;
+
+ // all the values are the same for fonts, just use the calculated alpha
+ r = g = b = (int)accum;
+
+ dest[0] = min(b, 255);
+ dest[1] = min(g, 255);
+ dest[2] = min(r, 255);
+}
+
+//-----------------------------------------------------------------------------
+// ApplyGaussianBlurToTexture
+//-----------------------------------------------------------------------------
+void ApplyGaussianBlurToTexture( int blur, int rgbaX, int rgbaY, int rgbaWide, int rgbaTall, unsigned char *rgba)
+{
+ // calculate our gaussian distribution for if we're blurred
+ if ( blur > 1 && blur != g_blur )
+ {
+ g_blur = blur;
+ g_pGaussianDistribution = new float[blur * 2 + 1];
+ double sigma = 0.683f * blur;
+ for (int x = 0; x <= (blur * 2); x++)
+ {
+ int val = x - blur;
+ g_pGaussianDistribution[x] = (float)((1.0 / sqrt(2.0 * 3.14 * sigma * sigma)) * pow(2.7, -1.0 * (val * val) / (2.0 * sigma * sigma)));
+
+ // brightening factor
+ g_pGaussianDistribution[x] *= 1;
+ }
+ }
+
+ // alloc a new buffer
+ unsigned char *src = (unsigned char *)_alloca(rgbaWide * rgbaTall * 4);
+ memcpy(src, rgba, rgbaWide * rgbaTall * 4);
+
+ unsigned char *dest = rgba;
+ for (int y = 0; y < rgbaTall; y++)
+ {
+ for (int x = 0; x < rgbaWide; x++)
+ {
+ // scan the source pixel
+ GetBlurValueForPixel(src, blur, g_pGaussianDistribution, x, y, rgbaWide, rgbaTall, dest);
+
+ // move to the next
+ dest += 4;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// ApplyScanlineEffectToTexture
+//-----------------------------------------------------------------------------
+void ApplyScanlineEffectToTexture( int scanLines, int rgbaX, int rgbaY, int rgbaWide, int rgbaTall, unsigned char *rgba)
+{
+ if (scanLines < 2)
+ return;
+
+ float scale;
+ scale = 0;
+
+ // darken all the areas except the scanlines
+ for (int y = 0; y < rgbaTall; y++)
+ {
+ // skip the scan lines
+ if (y % scanLines == 0)
+ continue;
+
+ DWORD *pBits = (DWORD*)&rgba[(rgbaX + ((y + rgbaY) * rgbaWide)) * 4];
+
+ // darken the other lines
+ for (int x = 0; x < rgbaWide; x++, pBits++)
+ {
+ FLOAT r = ( ( 0x00ff0000 & pBits[0] ) >> 16L ) / 255.0f;
+ FLOAT g = ( ( 0x0000ff00 & pBits[0] ) >> 8L ) / 255.0f;
+ FLOAT b = ( ( 0x000000ff & pBits[0] ) >> 0L ) / 255.0f;
+
+ r *= scale;
+ g *= scale;
+ b *= scale;
+
+ pBits[0] = (((int)(r * 255.0f))<<16) | (((int)(g * 255.0f))<<8) | ((int)(b * 255.0f));
+ pBits[0] |= 0xFF000000;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Name: RenderTTFGlyphs()
+// Desc: Draws the list of font glyphs in the scroll view
+//-----------------------------------------------------------------------------
+GLYPH_ATTR* CTextureFont::RenderTTFGlyphs( HFONT hFont, HBITMAP hBitmap,
+ DWORD dwTextureWidth, DWORD dwTextureHeight,
+ BOOL bOutlineEffect, BOOL bShadowEffect,
+ int nScanlineEffect, int nBlurEffect,
+ BOOL bAntialias,
+ BYTE* ValidGlyphs, DWORD dwNumGlyphs )
+{
+ // Create a DC
+ HDC hDC = CreateCompatibleDC( NULL );
+
+ // Associate the drawing surface
+ SelectObject( hDC, hBitmap );
+
+ // Create a clip region
+ HRGN rgn = CreateRectRgn( 0, 0, dwTextureWidth, dwTextureHeight );
+ SelectClipRgn( hDC, rgn );
+
+ // Setup the DC for the font
+ SetTextColor( hDC, COLOR_WHITE );
+ SelectObject( hDC, hFont );
+ SetTextAlign( hDC, TA_LEFT|TA_TOP|TA_UPDATECP );
+ SetMapMode( hDC, MM_TEXT );
+ SetBkMode( hDC, TRANSPARENT );
+
+ if ( nScanlineEffect || nBlurEffect )
+ {
+ SetBkColor( hDC, COLOR_BLACK );
+
+ if ( nBlurEffect < 2 )
+ nBlurEffect = 2;
+ if ( nScanlineEffect < 2 )
+ nScanlineEffect = 2;
+ }
+ else
+ {
+ SetBkColor( hDC, COLOR_BLUE );
+ }
+
+ // Fill the background in blue
+ RECT rect;
+ SetRect( &rect, 0, 0, dwTextureWidth, dwTextureHeight );
+ ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL );
+
+ // Get the effective font height
+ WCHAR str[2] = L"A";
+ SIZE size;
+ GetTextExtentPoint32W( hDC, str, 1, &size );
+
+ DWORD dwLeftOrigin = 1;
+ DWORD dwTopOrigin = 1;
+
+ GLYPH_ATTR* pGlyphs = new GLYPH_ATTR[dwNumGlyphs];
+ memset( pGlyphs, 0, dwNumGlyphs*sizeof( GLYPH_ATTR ) );
+
+ // Loop through all printable character and output them to the bitmap..
+ // Meanwhile, keep track of the corresponding tex coords for each character.
+ DWORD x = dwLeftOrigin;
+ DWORD y = dwTopOrigin;
+ int sx;
+ int sy;
+
+ int numGlyphs = 0;
+
+ for( DWORD i=0; i<65536; i++ )
+ {
+ if ( 0 == ValidGlyphs[i])
+ continue;
+
+ str[0] = (WCHAR)i;
+
+ if ( i==0 && ValidGlyphs[i] == 1 )
+ {
+ // account for unprintable, but don't render it
+ numGlyphs++;
+ continue;
+ }
+
+ GetTextExtentPoint32W( hDC, str, 1, &size );
+
+ // Get char width a different way
+ int charwidth;
+ GetCharWidth32( hDC, str[0], str[0], &charwidth );
+
+ // Get the ABC widths for the letter
+ ABC abc;
+ if ( FALSE == GetCharABCWidthsW( hDC, str[0], str[0], &abc ) )
+ {
+ abc.abcA = 0;
+ abc.abcB = size.cx;
+ abc.abcC = 0;
+ }
+
+ int w = abc.abcB;
+ int h = size.cy;
+
+ // Determine padding for effects
+ int left_padding = 0;
+ int right_padding = 0;
+ int top_padding = 0;
+ int bottom_padding = 0;
+ if ( bOutlineEffect || bShadowEffect )
+ {
+ if ( bOutlineEffect )
+ left_padding = 1;
+
+ if ( bOutlineEffect )
+ {
+ if ( bShadowEffect )
+ right_padding = 2;
+ else
+ right_padding = 1;
+ }
+ else
+ {
+ if ( bShadowEffect )
+ right_padding = 2;
+ else
+ right_padding = 0;
+ }
+
+ if ( bOutlineEffect )
+ top_padding = 1;
+
+ if ( bOutlineEffect )
+ {
+ if ( bShadowEffect )
+ bottom_padding = 2;
+ else
+ bottom_padding = 1;
+ }
+ else
+ {
+ if ( bShadowEffect )
+ bottom_padding = 2;
+ else
+ bottom_padding = 0;
+ }
+ }
+ else if ( nBlurEffect )
+ {
+ left_padding = nBlurEffect;
+ right_padding = nBlurEffect;
+ }
+
+ if ( ValidGlyphs[i] == 2 )
+ {
+ // Handle special characters
+ // Advance to the next line, if necessary
+ if ( x + h + left_padding + right_padding >= (int)dwTextureWidth )
+ {
+ x = dwLeftOrigin;
+ y += h + top_padding + bottom_padding + 1;
+ }
+
+ sx = x;
+ sy = y;
+
+ // Draw a square box for a placeholder for custom glyph graphics
+ w = h + left_padding + right_padding;
+ h = h + top_padding + bottom_padding;
+
+ abc.abcA = 0;
+ abc.abcB = w;
+ abc.abcC = 0;
+
+ RECT rect;
+ SetRect( &rect, x, y, x+w, y+h );
+ SetBkColor( hDC, COLOR_BLACK );
+ ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL );
+ }
+ else
+ {
+ // Hack to adjust for Kanji
+ if ( str[0] > 0x1000 )
+ {
+ w = h;
+ }
+
+ // Advance to the next line, if necessary
+ if ( x + w + left_padding + right_padding + 1 >= (int)dwTextureWidth )
+ {
+ x = dwLeftOrigin;
+ y += h + top_padding + bottom_padding + 1;
+ }
+
+ sx = x;
+ sy = y;
+
+ // Adjust ccordinates to account for the leading edge
+ if ( abc.abcA >= 0 )
+ x += abc.abcA;
+ else
+ sx -= abc.abcA;
+
+ // Hack to adjust for Kanji
+ if ( str[0] > 0x1000 )
+ {
+ sx += abc.abcA;
+ }
+
+ // Add padding to the width and height
+ w += left_padding + right_padding;
+ h += top_padding + bottom_padding;
+ abc.abcA -= left_padding;
+ abc.abcB += left_padding + right_padding;
+ abc.abcC -= right_padding;
+
+ if ( bOutlineEffect || bShadowEffect )
+ {
+ if ( bOutlineEffect )
+ {
+ SetTextColor( hDC, COLOR_BLACK );
+ MoveToEx( hDC, sx+0, sy+0, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ MoveToEx( hDC, sx+1, sy+0, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ MoveToEx( hDC, sx+2, sy+0, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ MoveToEx( hDC, sx+0, sy+1, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ MoveToEx( hDC, sx+2, sy+1, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ MoveToEx( hDC, sx+0, sy+2, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ MoveToEx( hDC, sx+1, sy+2, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ MoveToEx( hDC, sx+2, sy+2, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+
+ if ( bShadowEffect )
+ {
+ MoveToEx( hDC, sx+3, sy+3, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ }
+
+ // Output the letter
+ SetTextColor( hDC, COLOR_WHITE );
+ MoveToEx( hDC, sx+1, sy+1, NULL ); ExtTextOutW( hDC, sx, sy, ETO_OPAQUE, NULL, str, 1, NULL );
+ }
+ else
+ {
+ if ( bShadowEffect )
+ {
+ SetTextColor( hDC, COLOR_BLACK );
+ MoveToEx( hDC, sx+2, sy+2, NULL ); ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, NULL, str, 1, NULL );
+ }
+
+ // Output the letter
+ SetTextColor( hDC, COLOR_WHITE );
+ MoveToEx( hDC, sx, sy, NULL ); ExtTextOutW( hDC, sx, sy, ETO_OPAQUE, NULL, str, 1, NULL );
+ }
+ }
+ else if ( nBlurEffect )
+ {
+ // blur effect
+ SetTextColor( hDC, COLOR_WHITE );
+ MoveToEx( hDC, sx + nBlurEffect, sy, NULL );
+ ExtTextOutW( hDC, sx, sy, ETO_OPAQUE, NULL, str, 1, NULL );
+
+ // apply blur effect
+ unsigned char *pBGRA = GetTextureBits( hBitmap, dwTextureWidth, dwTextureHeight, x, y, w, h );
+ if ( pBGRA )
+ {
+ ApplyGaussianBlurToTexture( nBlurEffect, 0, 0, w, h, pBGRA );
+ SetTextureBits( hBitmap, dwTextureWidth, dwTextureHeight, x, y, w, h, pBGRA );
+ delete [] pBGRA;
+ }
+ }
+ else
+ {
+ // normal, no effect
+ // Output the letter
+ SetTextColor( hDC, COLOR_WHITE );
+ MoveToEx( hDC, sx, sy, NULL );
+ ExtTextOutW( hDC, sx, sy, ETO_OPAQUE, NULL, str, 1, NULL );
+ }
+
+ // apply scanline effect
+ if ( nScanlineEffect )
+ {
+ unsigned char *pBGRA = GetTextureBits( hBitmap, dwTextureWidth, dwTextureHeight, x, y, w, h );
+ if ( pBGRA )
+ {
+ ApplyScanlineEffectToTexture( nScanlineEffect, 0, 0, w, h, pBGRA );
+ SetTextureBits( hBitmap, dwTextureWidth, dwTextureHeight, x, y, w, h, pBGRA );
+ delete [] pBGRA;
+ }
+ }
+
+ // Hack for extended characters (like Kanji) that don't seem to report
+ // correct ABC widths. In this case, use the width calculated from
+ // drawing the glyph.
+ if( str[0] > 0x1000 )
+ {
+ POINT pos;
+ GetCurrentPositionEx( hDC, &pos );
+ abc.abcB = pos.x - sx;
+
+ if( abc.abcC < 0 )
+ abc.abcB -= abc.abcC;
+
+ w = abc.abcB;
+ }
+ }
+
+ // Store the glyph attributes
+ pGlyphs[numGlyphs].x = x;
+ pGlyphs[numGlyphs].y = y;
+ pGlyphs[numGlyphs].w = w;
+ pGlyphs[numGlyphs].h = h;
+ pGlyphs[numGlyphs].a = abc.abcA;
+ pGlyphs[numGlyphs].b = abc.abcB;
+ pGlyphs[numGlyphs].c = abc.abcC;
+ pGlyphs[numGlyphs].fLeft = ((FLOAT)(x+0)) / dwTextureWidth;
+ pGlyphs[numGlyphs].fTop = ((FLOAT)(y+0)) / dwTextureHeight;
+ pGlyphs[numGlyphs].fRight = ((FLOAT)(x+w)) / dwTextureWidth;
+ pGlyphs[numGlyphs].fBottom = ((FLOAT)(y+h)) / dwTextureHeight;
+ numGlyphs++;
+
+ // Advance the cursor to the next position
+ x += w + 1;
+ }
+
+ SelectClipRgn( hDC, NULL );
+ DeleteObject( rgn );
+ DeleteDC( hDC );
+
+ return pGlyphs;
+}
+
+//-----------------------------------------------------------------------------
+// Name: RenderCustomGlyphs()
+// Desc: Draws the list of font glyphs in the scroll view
+//-----------------------------------------------------------------------------
+GLYPH_ATTR* CTextureFont::RenderCustomGlyphs( HBITMAP hBitmap )
+{
+ int i;
+ int w;
+ int h;
+ byte_t *pTGAPixels;
+
+ m_maxCustomCharHeight = 0;
+
+ // Create a DC
+ HDC hDC = CreateCompatibleDC( NULL );
+
+ // Associate the drawing surface
+ SelectObject( hDC, hBitmap );
+
+ // Create a clip region
+ HRGN rgn = CreateRectRgn( 0, 0, m_dwTextureWidth, m_dwTextureHeight );
+ SelectClipRgn( hDC, rgn );
+
+ // clear the background
+ unsigned char *pBGRA = GetTextureBits( hBitmap, m_dwTextureWidth, m_dwTextureHeight, 0, 0, m_dwTextureWidth, m_dwTextureHeight );
+ for (i=0; i<(int)(m_dwTextureHeight*m_dwTextureWidth); i++)
+ {
+ pBGRA[i*4+0] = 0xFF;
+ pBGRA[i*4+1] = 0x00;
+ pBGRA[i*4+2] = 0x00;
+ pBGRA[i*4+3] = 0x00;
+ }
+ SetTextureBits( hBitmap, m_dwTextureWidth, m_dwTextureHeight, 0, 0, m_dwTextureWidth, m_dwTextureHeight, pBGRA );
+
+ // build the glyph table
+ GLYPH_ATTR* pGlyphs = new GLYPH_ATTR[m_dwNumGlyphs];
+ memset( pGlyphs, 0, m_dwNumGlyphs*sizeof( GLYPH_ATTR ) );
+
+ int x = 0;
+ int y = 0;
+ int maxHeight = 0;
+
+ for( DWORD i=0; i<m_dwNumGlyphs; i++ )
+ {
+ if ( !i )
+ {
+ // account for null
+ continue;
+ }
+ else if ( TL_Exists( m_pCustomGlyphFiles[i-1] ) )
+ {
+ TL_LoadTGA( m_pCustomGlyphFiles[i-1], &pTGAPixels, &w, &h );
+
+ // convert to expected order
+ for (int j=0; j<h*w; j++)
+ {
+ int r = pTGAPixels[j*4+0];
+ int g = pTGAPixels[j*4+1];
+ int b = pTGAPixels[j*4+2];
+
+ pTGAPixels[j*4+0] = b;
+ pTGAPixels[j*4+1] = g;
+ pTGAPixels[j*4+2] = r;
+ }
+ }
+ else
+ {
+ // build a "bad" symbol
+ pTGAPixels = (byte_t*)TL_Malloc( 32*32*4 );
+ w = 32;
+ h = 32;
+ for (int j=0; j<32*32; j++)
+ {
+ pTGAPixels[j*4+0] = 0x00;
+ pTGAPixels[j*4+1] = 0x00;
+ pTGAPixels[j*4+2] = 0xFF;
+ pTGAPixels[j*4+3] = 0xFF;
+ }
+ }
+
+ if ( m_maxCustomCharHeight < h )
+ {
+ m_maxCustomCharHeight = h;
+ }
+
+ if ( maxHeight < h )
+ {
+ maxHeight = h;
+ }
+
+ if ( x + w > (int)m_dwTextureWidth )
+ {
+ // skip to new row
+ y += maxHeight;
+ x = 0;
+ maxHeight = h;
+ }
+
+ SetTextureBits( hBitmap, m_dwTextureWidth, m_dwTextureHeight, x, y, w, h, pTGAPixels );
+ TL_Free( pTGAPixels );
+
+ // Store the glyph attributes
+ pGlyphs[i].x = x;
+ pGlyphs[i].y = y;
+ pGlyphs[i].w = w;
+ pGlyphs[i].h = h;
+ pGlyphs[i].a = 0;
+ pGlyphs[i].b = w;
+ pGlyphs[i].c = 0;
+ pGlyphs[i].fLeft = ((FLOAT)(x+0)) / m_dwTextureWidth;
+ pGlyphs[i].fTop = ((FLOAT)(y+0)) / m_dwTextureHeight;
+ pGlyphs[i].fRight = ((FLOAT)(x+w)) / m_dwTextureWidth;
+ pGlyphs[i].fBottom = ((FLOAT)(y+h)) / m_dwTextureHeight;
+
+ x += w;
+ }
+
+ SelectClipRgn( hDC, NULL );
+ DeleteObject( rgn );
+ DeleteDC( hDC );
+ delete [] pBGRA;
+
+ return pGlyphs;
+}
+
+//-----------------------------------------------------------------------------
+// Name: CalculateAndRenderGlyphs()
+// Desc: Draws the list of font glyphs
+//-----------------------------------------------------------------------------
+HRESULT CTextureFont::CalculateAndRenderGlyphs()
+{
+ // Create a bitmap
+ HBITMAP hBitmap = CreateBitmap( m_dwTextureWidth, m_dwTextureHeight, 1, 32, NULL );
+
+ if ( m_pGlyphs )
+ delete[] m_pGlyphs;
+
+ if ( m_pCustomFilename )
+ {
+ m_pGlyphs = RenderCustomGlyphs( hBitmap );
+ }
+ else
+ {
+ // Create a font
+ if ( m_hFont )
+ {
+ DeleteObject( m_hFont );
+ }
+
+ if ( m_bAntialiasEffect )
+ {
+ m_LogFont.lfQuality = ANTIALIASED_QUALITY;
+ }
+ else
+ {
+ m_LogFont.lfQuality = NONANTIALIASED_QUALITY;
+ }
+
+ m_hFont = CreateFontIndirect( &m_LogFont );
+
+ m_pGlyphs = RenderTTFGlyphs(
+ m_hFont,
+ hBitmap,
+ m_dwTextureWidth,
+ m_dwTextureHeight,
+ m_bOutlineEffect,
+ m_bShadowEffect,
+ m_nScanlines,
+ m_nBlur,
+ m_bAntialiasEffect,
+ m_ValidGlyphs,
+ m_dwNumGlyphs );
+ }
+
+ // Store the resulting bits
+ if ( m_pBits )
+ delete[] m_pBits;
+ m_pBits = new DWORD[ m_dwTextureWidth * m_dwTextureHeight ];
+
+ GetBitmapBits2( hBitmap, m_dwTextureWidth, m_dwTextureHeight, m_pBits );
+
+ DeleteObject( hBitmap );
+
+ return S_OK;
+}
diff --git a/utils/xbox/FontMaker/glyphs.h b/utils/xbox/FontMaker/glyphs.h
new file mode 100644
index 0000000..7aaa117
--- /dev/null
+++ b/utils/xbox/FontMaker/glyphs.h
@@ -0,0 +1,104 @@
+//-----------------------------------------------------------------------------
+// Name: Glyphs.cpp
+//
+// Desc: Functions and global variables for keeping track of font glyphs
+//
+// Hist: 09.06.02 - Revised Fontmaker sample
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#ifndef GLYPHS_H
+#define GLYPHS_H
+
+//-----------------------------------------------------------------------------
+// Name: struct GLYPH_ATTR
+// Desc: A structure to hold attributes for one glpyh. The left, right, etc.
+// values are texture coordinate offsets into the resulting texture image
+// (which ends up in the .tga file). The offset, width, etc. values are
+// spacing information, used when rendering the font.
+//-----------------------------------------------------------------------------
+struct FILE_GLYPH_ATTR
+{
+ FLOAT fLeft, fTop, fRight, fBottom;
+};
+
+struct GLYPH_ATTR : public FILE_GLYPH_ATTR
+{
+ int a, b, c;
+ int x, y, w, h;
+};
+
+
+
+
+//-----------------------------------------------------------------------------
+// Name: class CTextureFont
+// Desc: A class to hold all information about a texture-based font
+//-----------------------------------------------------------------------------
+class CTextureFont
+{
+public:
+ // current ttf font
+ LOGFONT m_LogFont;
+ HFONT m_hFont;
+
+ BOOL m_bAntialiasEffect;
+ BOOL m_bShadowEffect;
+ BOOL m_bOutlineEffect;
+ int m_nBlur;
+ int m_nScanlines;
+
+ // Glyph info
+ BYTE* m_ValidGlyphs;
+ WCHAR m_cMaxGlyph;
+ WORD* m_TranslatorTable;
+ BOOL m_bIncludeNullCharacter;
+ DWORD m_dwNumGlyphs;
+ GLYPH_ATTR* m_pGlyphs;
+
+ // Texture info
+ DWORD m_dwTextureWidth;
+ DWORD m_dwTextureHeight;
+ DWORD* m_pBits;
+
+ CHAR m_strFontName[MAX_PATH];
+
+ // current custom font
+ const char *m_pCustomFilename;
+ unsigned char m_customGlyphs[256];
+ char *m_pCustomGlyphFiles[256];
+ int m_maxCustomCharHeight;
+
+public:
+ HRESULT DeleteGlyph( WORD wGlyph );
+ HRESULT InsertGlyph( WORD wGlyph );
+ HRESULT ExtractValidGlyphsFromRange( WORD wStartGlyph, WORD wEndGlyph );
+ HRESULT ExtractValidGlyphsFromFile( const CHAR* strFileName );
+ HRESULT BuildTranslatorTable();
+ HRESULT CalculateAndRenderGlyphs();
+ HRESULT ReadCustomFontFile( CHAR* strFileName );
+ HRESULT ReadFontInfoFile( CHAR* strFileName );
+ HRESULT WriteFontInfoFile( CHAR* strFileName );
+ HRESULT WriteFontImageFile( CHAR* strFileName, bool bAdditiveMode, bool bCustomFont );
+
+ VOID ClearFont();
+ VOID DestroyObjects();
+
+ CTextureFont();
+ ~CTextureFont();
+
+private:
+ GLYPH_ATTR* RenderCustomGlyphs( HBITMAP hBitmap );
+
+ GLYPH_ATTR* RenderTTFGlyphs( HFONT hFont, HBITMAP hBitmap,
+ DWORD dwTextureWidth, DWORD dwTextureHeight,
+ BOOL bOutlineEffect, BOOL bShadowEffect,
+ int nScanlineEffect, int nBlurEffect,
+ BOOL bAntialias,
+ BYTE* ValidGlyphs, DWORD dwNumGlyphs );
+};
+
+
+
+
+#endif // GLYPHS_H
diff --git a/utils/xbox/FontMaker/resource.h b/utils/xbox/FontMaker/resource.h
new file mode 100644
index 0000000..d8b7060
--- /dev/null
+++ b/utils/xbox/FontMaker/resource.h
@@ -0,0 +1,80 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by fontmaker.rc
+//
+#define IDD_DIALOGBAR 103
+#define IDD_TEXTURESIZE 104
+#define IDR_MAINFRAME 128
+#define IDD_ABOUT 132
+#define IDC_GLYPHSFROMRANGE_RADIO 1007
+#define IDC_GLYPHSFROMFILE_RADIO 1008
+#define IDC_GLYPHSFILE_EDIT 1009
+#define IDC_GLYPHSFILESELECTOR_BUTTON 1010
+#define IDC_GLYPHSRANGEFROM_EDIT 1011
+#define IDC_GLYPHSRANGETO_EDIT 1012
+#define IDC_EFFECTSOUTLINED_CHECK 1013
+#define IDC_EFFECTSSHADOWED_CHECK 1014
+#define IDC_EFFECTSBLURRED_CHECK 1015
+#define IDC_EFFECTSSCANLINES_CHECK 1016
+#define IDC_BLUR_EDIT 1017
+#define IDC_SCANLINES_EDIT 1018
+#define IDC_EFFECTSANTIALIAS_CHECK 1019
+#define IDC_GLYPHSCUSTOM_RADIO 1020
+#define IDC_INSERTGLYPH_EDIT 1021
+#define IDC_GLYPH_SPECIAL 1024
+#define IDC_TEXTURESIZE_BUTTON 1026
+#define IDC_FONTNAME_STATIC 1030
+#define IDC_FONT_GROUPBOX 1031
+#define IDC_GLYPHS_GROUPBOX 1032
+#define IDC_FONTSTYLE_STATIC 1033
+#define IDC_FONTSIZE_STATIC 1034
+#define IDC_TEXTUREWIDTH_STATIC 1035
+#define IDC_TEXTURE_GROUPBOX 1036
+#define IDC_SELECTEDGLYPH_GROUPBOX 1037
+#define IDC_FONTNAME_LABEL 1038
+#define IDC_FONTSTYLE_LABEL 1039
+#define IDC_FONTSIZE_LABEL 1040
+#define IDC_INSERTGLYPH_LABEL 1041
+#define IDC_TEXTUREHEIGHT_LABEL 1042
+#define IDC_TEXTUREHEIGHT_STATIC 1043
+#define IDC_GLYPHSRANGEFROM_LABEL 1044
+#define IDC_GLYPHSRANGETO_LABEL 1045
+#define IDC_WIDTH 1046
+#define IDC_GLYPH_X_STATIC 1046
+#define IDC_TEXTUREWIDTH_LABEL 1047
+#define IDC_HEIGHT 1048
+#define IDC_GLYPH_X_LABEL 1048
+#define IDC_GLYPH_Y_LABEL 1049
+#define IDC_GLYPH_W_LABEL 1050
+#define IDC_GLYPH_H_LABEL 1051
+#define IDC_GLYPH_A_LABEL 1052
+#define IDC_GLYPH_B_LABEL 1053
+#define IDC_GLYPH_C_LABEL 1054
+#define IDC_MAGNIFY_BUTTON 1055
+#define IDC_GLYPH_VALUE_LABEL 1056
+#define IDC_USENTSCSAFECOLORS_CHECK 1057
+#define IDC_GLYPH_Y_STATIC 1061
+#define IDC_GLYPH_W_STATIC 1062
+#define IDC_GLYPH_H_STATIC 1063
+#define IDC_GLYPH_A_STATIC 1064
+#define IDC_GLYPH_B_STATIC 1065
+#define IDC_GLYPH_C_STATIC 1066
+#define IDC_GLYPH_VALUE_STATIC 1067
+#define IDM_FILE_EXIT 32778
+#define IDM_FILE_NEWFONT 32782
+#define IDM_FILE_SAVEFONTFILES 32784
+#define ID_FILE_LOADFONTFILE 32788
+#define IDM_FILE_LOADFONTFILE 32790
+#define IDM_FILE_LOADFONTLAYOUT 32792
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_3D_CONTROLS 1
+#define _APS_NEXT_RESOURCE_VALUE 133
+#define _APS_NEXT_COMMAND_VALUE 32793
+#define _APS_NEXT_CONTROL_VALUE 1058
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/utils/xbox/FontMaker/stdafx.cpp b/utils/xbox/FontMaker/stdafx.cpp
new file mode 100644
index 0000000..0087258
--- /dev/null
+++ b/utils/xbox/FontMaker/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// FontMaker.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
+
diff --git a/utils/xbox/FontMaker/stdafx.h b/utils/xbox/FontMaker/stdafx.h
new file mode 100644
index 0000000..b57f9d4
--- /dev/null
+++ b/utils/xbox/FontMaker/stdafx.h
@@ -0,0 +1,27 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__797D2B31_3C16_4BE2_8C81_8C3E74DC9138__INCLUDED_)
+#define AFX_STDAFX_H__797D2B31_3C16_4BE2_8C81_8C3E74DC9138__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include "tier0\wchartypes.h"
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__797D2B31_3C16_4BE2_8C81_8C3E74DC9138__INCLUDED_)